From 2eb7ceabdadcb9f1586305c6b4555521f9de8971 Mon Sep 17 00:00:00 2001 From: Rushabh Mehta Date: Tue, 2 Jul 2013 18:13:26 +0530 Subject: [PATCH 1/8] [forms] cleanup, fixing usability and added form dashboard --- .../production_order/production_order.txt | 17 ++++++++- .../production_planning_tool.py | 1 - selling/doctype/customer/customer.js | 35 +++++++++++++++++-- selling/doctype/customer/customer.py | 23 +++++++++++- selling/doctype/opportunity/opportunity.js | 22 +++++++++--- selling/doctype/opportunity/opportunity.txt | 8 ++++- selling/doctype/quotation/quotation.js | 10 +++++- selling/doctype/quotation/quotation.txt | 8 ++++- selling/page/selling_home/selling_home.js | 10 +++--- 9 files changed, 116 insertions(+), 18 deletions(-) diff --git a/manufacturing/doctype/production_order/production_order.txt b/manufacturing/doctype/production_order/production_order.txt index 53b7f1ceb7..38a98fefab 100644 --- a/manufacturing/doctype/production_order/production_order.txt +++ b/manufacturing/doctype/production_order/production_order.txt @@ -2,7 +2,7 @@ { "creation": "2013-01-10 16:34:16", "docstatus": 0, - "modified": "2013-01-29 17:17:31", + "modified": "2013-07-02 11:56:54", "modified_by": "Administrator", "owner": "Administrator" }, @@ -106,6 +106,14 @@ "read_only": 0, "reqd": 1 }, + { + "doctype": "DocField", + "fieldname": "wip_warehouse", + "fieldtype": "Link", + "label": "Work-in-Progress Warehouse", + "options": "Warehouse", + "reqd": 1 + }, { "doctype": "DocField", "fieldname": "column_break1", @@ -172,6 +180,13 @@ "options": "Sales Order", "read_only": 0 }, + { + "doctype": "DocField", + "fieldname": "description", + "fieldtype": "Small Text", + "label": "Item Description", + "read_only": 1 + }, { "doctype": "DocField", "fieldname": "project_name", diff --git a/manufacturing/doctype/production_planning_tool/production_planning_tool.py b/manufacturing/doctype/production_planning_tool/production_planning_tool.py index ed7f7bfb3f..26644ad787 100644 --- a/manufacturing/doctype/production_planning_tool/production_planning_tool.py +++ b/manufacturing/doctype/production_planning_tool/production_planning_tool.py @@ -210,7 +210,6 @@ class DocType: "wip_warehouse" : "", "fg_warehouse" : "", "status" : "Draft", - "fiscal_year" : webnotes.conn.get_default("fiscal_year") } return bom_dict, item_dict diff --git a/selling/doctype/customer/customer.js b/selling/doctype/customer/customer.js index 35a6f59a03..c0f6eab9cf 100644 --- a/selling/doctype/customer/customer.js +++ b/selling/doctype/customer/customer.js @@ -32,6 +32,7 @@ cur_frm.add_fetch('lead_name', 'company_name', 'customer_name'); cur_frm.add_fetch('default_sales_partner','commission_rate','default_commission_rate'); cur_frm.cscript.refresh = function(doc,dt,dn) { + cur_frm.layout.clear_dashboard(); if(sys_defaults.cust_master_name == 'Customer Name') hide_field('naming_series'); else @@ -39,7 +40,8 @@ cur_frm.cscript.refresh = function(doc,dt,dn) { if(doc.__islocal){ hide_field(['address_html','contact_html']); - }else{ + }else{ + cur_frm.cscript.setup_dashboard(doc); unhide_field(['address_html','contact_html']); // make lists cur_frm.cscript.make_address(doc,dt,dn); @@ -53,6 +55,35 @@ cur_frm.cscript.refresh = function(doc,dt,dn) { } } +cur_frm.cscript.setup_dashboard = function(doc) { + cur_frm.layout.dashboard.toggle(true); + var headline = $('
\ + Loading...
') + .appendTo(cur_frm.layout.dashboard); + + cur_frm.layout.add_doctype_badge(wn._("Opportunities"), "Opportunity", "customer"); + cur_frm.layout.add_doctype_badge(wn._("Quotations"), "Quotation", "customer"); + cur_frm.layout.add_doctype_badge(wn._("Sales Orders"), "Sales Order", "customer"); + cur_frm.layout.add_doctype_badge(wn._("Delivery Notes"), "Delivery Note", "customer"); + cur_frm.layout.add_doctype_badge(wn._("Sales Invoices"), "Sales Invoice", "customer"); + + wn.call({ + type: "GET", + method:"selling.doctype.customer.customer.get_dashboard_info", + args: { + customer: cur_frm.doc.name + }, + callback: function(r) { + cur_frm.layout.dashboard.find(".form-headline") + .html(wn._("Total Billing This Year: ") + "" + + format_currency(r.message.total_billing, cur_frm.doc.default_currency) + + ' / ' + wn._("Unpaid") + ": " + + format_currency(r.message.total_unpaid, cur_frm.doc.default_currency) + ''); + cur_frm.layout.set_badge_count(r.message); + } + }) +} + cur_frm.cscript.make_address = function() { if(!cur_frm.address_list) { cur_frm.address_list = new wn.ui.Listing({ @@ -95,4 +126,4 @@ cur_frm.fields_dict['customer_group'].get_query = function(doc,dt,dn) { } -cur_frm.fields_dict.lead_name.get_query = erpnext.utils.lead_query; +cur_frm.fields_dict.lead_name.get_query = erpnext.utils.lead_query; \ No newline at end of file diff --git a/selling/doctype/customer/customer.py b/selling/doctype/customer/customer.py index 10d2ce52fb..83c10a5452 100644 --- a/selling/doctype/customer/customer.py +++ b/selling/doctype/customer/customer.py @@ -173,4 +173,25 @@ class DocType(TransactionBase): #update master_name in doctype account webnotes.conn.sql("""update `tabAccount` set master_name = %s, - master_type = 'Customer' where master_name = %s""", (new,old)) \ No newline at end of file + master_type = 'Customer' where master_name = %s""", (new,old)) + +@webnotes.whitelist() +def get_dashboard_info(customer): + if not webnotes.has_permission("Customer", customer): + webnotes.msgprint("No Permission", raise_exception=True) + + out = {} + for doctype in ["Opportunity", "Quotation", "Sales Order", "Delivery Note", "Sales Invoice"]: + out[doctype] = webnotes.conn.get_value(doctype, + {"customer": customer, "docstatus": ["!=", 2] }, "count(*)") + + billing = webnotes.conn.sql("""select sum(grand_total), sum(outstanding_amount) + from `tabSales Invoice` + where customer=%s + and docstatus = 1 + and fiscal_year = %s""", (customer, webnotes.conn.get_default("fiscal_year"))) + + out["total_billing"] = billing[0][0] + out["total_unpaid"] = billing[0][1] + + return out \ No newline at end of file diff --git a/selling/doctype/opportunity/opportunity.js b/selling/doctype/opportunity/opportunity.js index 3a56d4dbcb..a4c84af8c5 100644 --- a/selling/doctype/opportunity/opportunity.js +++ b/selling/doctype/opportunity/opportunity.js @@ -34,11 +34,21 @@ cur_frm.cscript.refresh = function(doc, cdt, cdn){ // =============================================================== cur_frm.cscript.onload = function(doc, cdt, cdn) { - if(!doc.enquiry_from) hide_field(['customer', 'customer_address', 'contact_person', 'customer_name','lead', 'address_display', 'contact_display', 'contact_mobile', 'contact_email', 'territory', 'customer_group']); - if(!doc.status) set_multiple(cdt,cdn,{status:'Draft'}); - if(!doc.date) doc.transaction_date = date.obj_to_str(new Date()); - if(!doc.company && sys_defaults.company) set_multiple(cdt,cdn,{company:sys_defaults.company}); - if(!doc.fiscal_year && sys_defaults.fiscal_year) set_multiple(cdt,cdn,{fiscal_year:sys_defaults.fiscal_year}); + if(!doc.enquiry_from && doc.customer) + doc.enquiry_from = "Customer"; + if(!doc.enquiry_from && doc.lead) + doc.enquiry_from = "Lead"; + + if(!doc.enquiry_from) + hide_field(['customer', 'customer_address', 'contact_person', 'customer_name','lead', 'address_display', 'contact_display', 'contact_mobile', 'contact_email', 'territory', 'customer_group']); + if(!doc.status) + set_multiple(cdt,cdn,{status:'Draft'}); + if(!doc.date) + doc.transaction_date = date.obj_to_str(new Date()); + if(!doc.company && sys_defaults.company) + set_multiple(cdt,cdn,{company:sys_defaults.company}); + if(!doc.fiscal_year && sys_defaults.fiscal_year) + set_multiple(cdt,cdn,{fiscal_year:sys_defaults.fiscal_year}); if(doc.enquiry_from) { if(doc.enquiry_from == 'Customer') { @@ -61,6 +71,8 @@ cur_frm.cscript.onload = function(doc, cdt, cdn) { if(cur_frm.fields_dict.contact_by.df.options.match(/^Profile/)) { cur_frm.fields_dict.contact_by.get_query = erpnext.utils.profile_query; } + + if(doc.customer && !doc.customer_name) cur_frm.cscript.customer(doc); } cur_frm.cscript.onload_post_render = function(doc, cdt, cdn) { diff --git a/selling/doctype/opportunity/opportunity.txt b/selling/doctype/opportunity/opportunity.txt index fc4d0412e8..7b86df2d33 100644 --- a/selling/doctype/opportunity/opportunity.txt +++ b/selling/doctype/opportunity/opportunity.txt @@ -2,7 +2,7 @@ { "creation": "2013-03-07 18:50:30", "docstatus": 0, - "modified": "2013-06-11 16:03:41", + "modified": "2013-07-02 17:22:21", "modified_by": "Administrator", "owner": "Administrator" }, @@ -43,6 +43,12 @@ "doctype": "DocType", "name": "Opportunity" }, + { + "doctype": "DocField", + "fieldname": "from_section", + "fieldtype": "Section Break", + "label": "From" + }, { "description": "To manage multiple series please go to Setup > Manage Series", "doctype": "DocField", diff --git a/selling/doctype/quotation/quotation.js b/selling/doctype/quotation/quotation.js index 4276193696..654779ca44 100644 --- a/selling/doctype/quotation/quotation.js +++ b/selling/doctype/quotation/quotation.js @@ -26,8 +26,16 @@ wn.require('app/utilities/doctype/sms_control/sms_control.js'); wn.require('app/selling/doctype/sales_common/sales_common.js'); erpnext.selling.QuotationController = erpnext.selling.SellingController.extend({ + onload: function(doc, dt, dn) { + this._super(doc, dt, dn); + if(doc.customer && !doc.quotation_to) + doc.quotation_to = "Customer"; + else if(doc.lead && !doc.quotation_to) + doc.quotation_to = "Lead"; + + }, refresh: function(doc, dt, dn) { - this._super(); + this._super(doc, dt, dn); if(doc.docstatus == 1 && doc.status!='Order Lost') { cur_frm.add_custom_button('Make Sales Order', cur_frm.cscript['Make Sales Order']); diff --git a/selling/doctype/quotation/quotation.txt b/selling/doctype/quotation/quotation.txt index b9772c8379..433ccf3aa4 100644 --- a/selling/doctype/quotation/quotation.txt +++ b/selling/doctype/quotation/quotation.txt @@ -2,7 +2,7 @@ { "creation": "2013-05-24 19:29:08", "docstatus": 0, - "modified": "2013-06-28 12:47:10", + "modified": "2013-07-02 16:49:52", "modified_by": "Administrator", "owner": "Administrator" }, @@ -42,6 +42,12 @@ "doctype": "DocType", "name": "Quotation" }, + { + "doctype": "DocField", + "fieldname": "customer_section", + "fieldtype": "Section Break", + "label": "Customer" + }, { "doctype": "DocField", "fieldname": "column_break0", diff --git a/selling/page/selling_home/selling_home.js b/selling/page/selling_home/selling_home.js index 8eae737ddb..be0d9dd434 100644 --- a/selling/page/selling_home/selling_home.js +++ b/selling/page/selling_home/selling_home.js @@ -7,6 +7,11 @@ wn.module_page["Selling"] = [ title: wn._("Documents"), icon: "icon-copy", items: [ + { + label: wn._("Customer"), + description: wn._("Customer database."), + doctype:"Customer" + }, { label: wn._("Lead"), description: wn._("Database of potential customers."), @@ -33,11 +38,6 @@ wn.module_page["Selling"] = [ title: wn._("Masters"), icon: "icon-book", items: [ - { - label: wn._("Customer"), - description: wn._("Customer database."), - doctype:"Customer" - }, { label: wn._("Contact"), description: wn._("All Contacts."), From 78979dca9bc6f6f83c437bf85894adeafb6da307 Mon Sep 17 00:00:00 2001 From: Rushabh Mehta Date: Wed, 3 Jul 2013 10:32:33 +0530 Subject: [PATCH 2/8] [form] added icon in section break --- buying/doctype/supplier/supplier.js | 45 +++++++++++++++++---- buying/doctype/supplier/supplier.py | 21 ++++++++++ buying/page/buying_home/buying_home.js | 10 ++--- selling/doctype/customer/customer.js | 17 ++++---- selling/doctype/customer/customer.txt | 8 +++- selling/doctype/lead/lead.txt | 19 +++++++-- selling/doctype/opportunity/opportunity.txt | 10 ++++- 7 files changed, 103 insertions(+), 27 deletions(-) diff --git a/buying/doctype/supplier/supplier.js b/buying/doctype/supplier/supplier.js index d364655610..996f0e0c9f 100644 --- a/buying/doctype/supplier/supplier.js +++ b/buying/doctype/supplier/supplier.js @@ -21,15 +21,16 @@ cur_frm.cscript.onload = function(doc,dt,dn){ } cur_frm.cscript.refresh = function(doc,dt,dn) { - if(sys_defaults.supp_master_name == 'Supplier Name') - hide_field('naming_series'); - else - unhide_field('naming_series'); + cur_frm.cscript.setup_dashboard(doc); + if(sys_defaults.supp_master_name == 'Supplier Name') + hide_field('naming_series'); + else + unhide_field('naming_series'); - if(doc.__islocal){ + if(doc.__islocal){ hide_field(['address_html','contact_html']); - } - else{ + } + else{ unhide_field(['address_html','contact_html']); // make lists cur_frm.cscript.make_address(doc,dt,dn); @@ -43,6 +44,36 @@ cur_frm.cscript.refresh = function(doc,dt,dn) { } } +cur_frm.cscript.setup_dashboard = function(doc) { + cur_frm.layout.dashboard.empty().toggle(doc.__islocal ? false : true); + if(doc.__islocal) + return; + var headline = $('
\ + Loading...
') + .appendTo(cur_frm.layout.dashboard); + + cur_frm.layout.add_doctype_badge("Supplier Quotation", "supplier"); + cur_frm.layout.add_doctype_badge("Purchase Order", "supplier"); + cur_frm.layout.add_doctype_badge("Purchase Receipt", "supplier"); + cur_frm.layout.add_doctype_badge("Purchase Invoice", "supplier"); + + wn.call({ + type: "GET", + method:"buying.doctype.supplier.supplier.get_dashboard_info", + args: { + supplier: cur_frm.doc.name + }, + callback: function(r) { + cur_frm.layout.dashboard.find(".form-headline") + .html(wn._("Total Billing This Year: ") + "" + + format_currency(r.message.total_billing, cur_frm.doc.default_currency) + + ' / ' + wn._("Unpaid") + ": " + + format_currency(r.message.total_unpaid, cur_frm.doc.default_currency) + ''); + cur_frm.layout.set_badge_count(r.message); + } + }) +} + cur_frm.cscript.make_address = function() { if(!cur_frm.address_list) { cur_frm.address_list = new wn.ui.Listing({ diff --git a/buying/doctype/supplier/supplier.py b/buying/doctype/supplier/supplier.py index a03ba339cd..d63d33607c 100644 --- a/buying/doctype/supplier/supplier.py +++ b/buying/doctype/supplier/supplier.py @@ -193,3 +193,24 @@ class DocType(TransactionBase): #update master_name in doctype account webnotes.conn.sql("""update `tabAccount` set master_name = %s, master_type = 'Supplier' where master_name = %s""" , (new,old)) + +@webnotes.whitelist() +def get_dashboard_info(supplier): + if not webnotes.has_permission("Supplier", supplier): + webnotes.msgprint("No Permission", raise_exception=True) + + out = {} + for doctype in ["Supplier Quotation", "Purchase Order", "Purchase Receipt", "Purchase Invoice"]: + out[doctype] = webnotes.conn.get_value(doctype, + {"supplier": supplier, "docstatus": ["!=", 2] }, "count(*)") + + billing = webnotes.conn.sql("""select sum(grand_total), sum(outstanding_amount) + from `tabPurchase Invoice` + where supplier=%s + and docstatus = 1 + and fiscal_year = %s""", (supplier, webnotes.conn.get_default("fiscal_year"))) + + out["total_billing"] = billing[0][0] + out["total_unpaid"] = billing[0][1] + + return out \ No newline at end of file diff --git a/buying/page/buying_home/buying_home.js b/buying/page/buying_home/buying_home.js index 1db8d41d7b..1972ad9589 100644 --- a/buying/page/buying_home/buying_home.js +++ b/buying/page/buying_home/buying_home.js @@ -7,6 +7,11 @@ wn.module_page["Buying"] = [ top: true, icon: "icon-copy", items: [ + { + label: wn._("Supplier"), + description: wn._("Supplier database."), + doctype:"Supplier" + }, { label: wn._("Material Request"), description: wn._("Request for purchase."), @@ -28,11 +33,6 @@ wn.module_page["Buying"] = [ title: wn._("Masters"), icon: "icon-book", items: [ - { - label: wn._("Supplier"), - description: wn._("Supplier database."), - doctype:"Supplier" - }, { label: wn._("Contact"), description: wn._("All Contacts."), diff --git a/selling/doctype/customer/customer.js b/selling/doctype/customer/customer.js index c0f6eab9cf..3ecfa70036 100644 --- a/selling/doctype/customer/customer.js +++ b/selling/doctype/customer/customer.js @@ -32,7 +32,7 @@ cur_frm.add_fetch('lead_name', 'company_name', 'customer_name'); cur_frm.add_fetch('default_sales_partner','commission_rate','default_commission_rate'); cur_frm.cscript.refresh = function(doc,dt,dn) { - cur_frm.layout.clear_dashboard(); + cur_frm.cscript.setup_dashboard(doc); if(sys_defaults.cust_master_name == 'Customer Name') hide_field('naming_series'); else @@ -41,7 +41,6 @@ cur_frm.cscript.refresh = function(doc,dt,dn) { if(doc.__islocal){ hide_field(['address_html','contact_html']); }else{ - cur_frm.cscript.setup_dashboard(doc); unhide_field(['address_html','contact_html']); // make lists cur_frm.cscript.make_address(doc,dt,dn); @@ -56,16 +55,18 @@ cur_frm.cscript.refresh = function(doc,dt,dn) { } cur_frm.cscript.setup_dashboard = function(doc) { - cur_frm.layout.dashboard.toggle(true); + cur_frm.layout.dashboard.empty().toggle(doc.__islocal ? false : true); + if(doc.__islocal) + return; var headline = $('
\ Loading...
') .appendTo(cur_frm.layout.dashboard); - cur_frm.layout.add_doctype_badge(wn._("Opportunities"), "Opportunity", "customer"); - cur_frm.layout.add_doctype_badge(wn._("Quotations"), "Quotation", "customer"); - cur_frm.layout.add_doctype_badge(wn._("Sales Orders"), "Sales Order", "customer"); - cur_frm.layout.add_doctype_badge(wn._("Delivery Notes"), "Delivery Note", "customer"); - cur_frm.layout.add_doctype_badge(wn._("Sales Invoices"), "Sales Invoice", "customer"); + cur_frm.layout.add_doctype_badge("Opportunity", "customer"); + cur_frm.layout.add_doctype_badge("Quotation", "customer"); + cur_frm.layout.add_doctype_badge("Sales Order", "customer"); + cur_frm.layout.add_doctype_badge("Delivery Note", "customer"); + cur_frm.layout.add_doctype_badge("Sales Invoice", "customer"); wn.call({ type: "GET", diff --git a/selling/doctype/customer/customer.txt b/selling/doctype/customer/customer.txt index d7cecdd1bf..86d40f869a 100644 --- a/selling/doctype/customer/customer.txt +++ b/selling/doctype/customer/customer.txt @@ -2,7 +2,7 @@ { "creation": "2013-06-11 14:26:44", "docstatus": 0, - "modified": "2013-06-11 14:27:57", + "modified": "2013-07-03 10:26:04", "modified_by": "Administrator", "owner": "Administrator" }, @@ -43,6 +43,7 @@ "fieldtype": "Section Break", "label": "Basic Info", "oldfieldtype": "Section Break", + "options": "icon-user", "permlevel": 0, "reqd": 0 }, @@ -142,6 +143,7 @@ "fieldname": "address_contacts", "fieldtype": "Section Break", "label": "Address & Contacts", + "options": "icon-map-marker", "permlevel": 0 }, { @@ -190,6 +192,8 @@ "doctype": "DocField", "fieldname": "communication_history", "fieldtype": "Section Break", + "label": "Communication History", + "options": "icon-comments", "permlevel": 0 }, { @@ -205,6 +209,7 @@ "fieldtype": "Section Break", "label": "More Info", "oldfieldtype": "Section Break", + "options": "icon-file-text", "permlevel": 0 }, { @@ -295,6 +300,7 @@ "fieldtype": "Section Break", "label": "Sales Team", "oldfieldtype": "Section Break", + "options": "icon-group", "permlevel": 0 }, { diff --git a/selling/doctype/lead/lead.txt b/selling/doctype/lead/lead.txt index eed87ba399..15f4dc0956 100644 --- a/selling/doctype/lead/lead.txt +++ b/selling/doctype/lead/lead.txt @@ -2,7 +2,7 @@ { "creation": "2013-04-10 11:45:37", "docstatus": 0, - "modified": "2013-06-28 15:08:26", + "modified": "2013-07-03 10:22:31", "modified_by": "Administrator", "owner": "Administrator" }, @@ -40,6 +40,13 @@ "doctype": "DocType", "name": "Lead" }, + { + "doctype": "DocField", + "fieldname": "lead_details", + "fieldtype": "Section Break", + "label": "Lead Details", + "options": "icon-user" + }, { "description": "To manage multiple series please go to Setup > Manage Series", "doctype": "DocField", @@ -149,7 +156,9 @@ { "doctype": "DocField", "fieldname": "communication_history", - "fieldtype": "Section Break" + "fieldtype": "Section Break", + "label": "Communication History", + "options": "icon-comments" }, { "allow_on_submit": 0, @@ -165,7 +174,8 @@ "fieldname": "contact_info", "fieldtype": "Section Break", "label": "Address & Contact", - "oldfieldtype": "Column Break" + "oldfieldtype": "Column Break", + "options": "icon-map-marker" }, { "depends_on": "eval:doc.__islocal", @@ -248,7 +258,8 @@ "fieldname": "more_info", "fieldtype": "Section Break", "label": "More Info", - "oldfieldtype": "Section Break" + "oldfieldtype": "Section Break", + "options": "icon-file-text" }, { "doctype": "DocField", diff --git a/selling/doctype/opportunity/opportunity.txt b/selling/doctype/opportunity/opportunity.txt index 7b86df2d33..c4554409b7 100644 --- a/selling/doctype/opportunity/opportunity.txt +++ b/selling/doctype/opportunity/opportunity.txt @@ -2,7 +2,7 @@ { "creation": "2013-03-07 18:50:30", "docstatus": 0, - "modified": "2013-07-02 17:22:21", + "modified": "2013-07-03 10:29:20", "modified_by": "Administrator", "owner": "Administrator" }, @@ -47,7 +47,8 @@ "doctype": "DocField", "fieldname": "from_section", "fieldtype": "Section Break", - "label": "From" + "label": "From", + "options": "icon-user" }, { "description": "To manage multiple series please go to Setup > Manage Series", @@ -144,6 +145,7 @@ "fieldtype": "Section Break", "label": "Items", "oldfieldtype": "Section Break", + "options": "icon-shopping-cart", "read_only": 0 }, { @@ -162,7 +164,9 @@ "doctype": "DocField", "fieldname": "communication_history", "fieldtype": "Section Break", + "label": "Communication History", "oldfieldtype": "Section Break", + "options": "icon-comments", "read_only": 0 }, { @@ -180,6 +184,7 @@ "fieldname": "contact_info", "fieldtype": "Section Break", "label": "Contact Info", + "options": "icon-bullhorn", "read_only": 0 }, { @@ -284,6 +289,7 @@ "fieldtype": "Section Break", "label": "More Info", "oldfieldtype": "Section Break", + "options": "icon-file-text", "read_only": 0 }, { From 9a04b19160bc7f83bd6a60cfd31a53e4afc6a880 Mon Sep 17 00:00:00 2001 From: Rushabh Mehta Date: Wed, 3 Jul 2013 13:27:39 +0530 Subject: [PATCH 3/8] [form] [legacy-js] removed old Dialog, PageHeader etc., cleanup Opportunity and Quotation --- .../financial_statements.html | 8 -- .../financial_statements.js | 113 ++++++++---------- buying/doctype/supplier/supplier.js | 34 +++--- selling/doctype/customer/customer.js | 29 +++-- selling/doctype/lead/lead.js | 10 ++ selling/doctype/opportunity/opportunity.js | 86 ++++++------- selling/doctype/quotation/quotation.js | 87 +++++++------- selling/doctype/quotation/quotation.py | 2 +- selling/doctype/quotation/quotation.txt | 30 +++-- 9 files changed, 192 insertions(+), 207 deletions(-) delete mode 100644 accounts/page/financial_statements/financial_statements.html diff --git a/accounts/page/financial_statements/financial_statements.html b/accounts/page/financial_statements/financial_statements.html deleted file mode 100644 index bc2fce0ca7..0000000000 --- a/accounts/page/financial_statements/financial_statements.html +++ /dev/null @@ -1,8 +0,0 @@ -
-
- -
diff --git a/accounts/page/financial_statements/financial_statements.js b/accounts/page/financial_statements/financial_statements.js index cc79668405..d562e3229a 100644 --- a/accounts/page/financial_statements/financial_statements.js +++ b/accounts/page/financial_statements/financial_statements.js @@ -14,66 +14,60 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -pscript['onload_Financial Statements'] = function() { - - // header and toolbar - var h = new PageHeader('fs_header','Financial Statements','Profit & Loss and Balance Sheet Builder across multiple years'); - //$y(h.toolbar_area,{padding:'8px'}); - - var dv = $a(h.toolbar_area,'div','',{margin:'4px 0px'}); - - var t = make_table(dv,1,4,'640px', [], {padding:'4px', width:'160px'}); - - var sel = $a($td(t,0,0),'select','',{width:'160px'}); - sel.id = 'stmt_type'; - - var sel = $a($td(t,0,1),'select','',{width:'160px'}); - sel.id = 'stmt_company'; - - var sel = $a($td(t,0,2),'select','',{width:'160px'}); - sel.id = 'stmt_period'; +erpnext.fs = {} - var sel = $a($td(t,0,3),'select','',{width:'160px'}); - sel.id = 'stmt_fiscal_year'; - - h.add_button('Create',function(){ pscript.stmt_new(); },0,'ui-icon-document'); - h.add_button('Print', function(){ _p.go($i('print_html').innerHTML); }, 0, 'ui-icon-print'); -/* - var btn = $a($td(t,1,0),'button'); - btn.onclick = function(){ pscript.stmt_new(); } - btn.innerHTML = 'Create'; +pscript['onload_Financial Statements'] = function(wrapper) { + wn.ui.make_app_page({ + parent: wrapper, + "title": "Financial Statements", + "single_column": true, + }); - var btn = $a($td(t,1,1),'button'); - btn.onclick = function(){ alert('print'); } - btn.innerHTML = 'Print'; + erpnext.fs.stmt_type = wrapper.appframe.add_field({ + fieldtype:"Select", + fieldname:"stmt_type", + options: ['Select Statement...','Balance Sheet','Profit & Loss'] + }) - //Button to create new - var btn = $a('stmt_new', 'button'); - btn.onclick = function() { pscript.stmt_new(); } - btn.innerHTML = 'Create';*/ + erpnext.fs.stmt_company = wrapper.appframe.add_field({ + fieldtype:"Select", + fieldname:"stmt_company", + options: ['Loading Companies...'] + }) - // select for statement - add_sel_options($i('stmt_type'), ['Select Statement...','Balance Sheet','Profit & Loss']); + erpnext.fs.stmt_period = wrapper.appframe.add_field({ + fieldtype:"Select", + fieldname:"stmt_period", + options: ['Select Period...', 'Annual', 'Quarterly', 'Monthly'] + }) - // select for companies - add_sel_options($i('stmt_company'), ['Loading Companies...']); + erpnext.fs.stmt_fiscal_year = wrapper.appframe.add_field({ + fieldtype:"Select", + fieldname:"stmt_fiscal_year", + options: ['Loading...'] + }) + wrapper.appframe.add_button("Create", function() { + pscript.stmt_new(); + }, "icon-refresh") + + wrapper.appframe.add_button("Print", function() { + _p.go($i('print_html').innerHTML); + }, "icon-print") + + $(wrapper).find(".layout-main").html('').css({"min-height": "400px"}); // load companies $c_obj('MIS Control','get_comp','', function(r,rt) { // company - empty_select($i('stmt_company')); - add_sel_options($i('stmt_company'), add_lists(['Select Company...'], r.message.company), 'Select Company...'); - - - // period - empty_select($i('stmt_period')); - //add_sel_options($i('stmt_period'), add_lists(['Select Period...'], r.message.period), 'Select period...'); - add_sel_options($i('stmt_period'), add_lists(['Select Period...'], ['Annual', 'Quarterly', 'Monthly']), 'Select period...'); - - // fiscal-year - empty_select($i('stmt_fiscal_year')); - add_sel_options($i('stmt_fiscal_year'), add_lists(['Select Year...'], r.message.fiscal_year), 'Select fiscal year...'); + erpnext.fs.stmt_company.$input.empty() + .add_options(['Select Company...'].concat(r.message.company)); + erpnext.fs.stmt_fiscal_year.$input.empty() + .add_options(['Select Year...'].concat(r.message.fiscal_year)); }); } @@ -83,26 +77,27 @@ pscript.stmt_new = function(stmt,company_name,level,period,year) { $i('stmt_tree').innerHTML = 'Refreshing....'; $i('stmt_tree').style.display = 'block'; - var company = sel_val($i('stmt_company')) + var company =erpnext.fs.stmt_company.get_value(); var arg = { - statement:sel_val($i('stmt_type')), - company:company, - period:sel_val($i('stmt_period')), - year:sel_val($i('stmt_fiscal_year')) + statement: erpnext.fs.stmt_type.get_value(), + company: company, + period: erpnext.fs.stmt_period.get_value(), + year: erpnext.fs.stmt_fiscal_year.get_value() } $c_obj('MIS Control', 'get_statement', docstring(arg), function(r,rt) { var nl = r.message; var t = $i('stmt_tree'); - var stmt_type = sel_val($i('stmt_type')); + var stmt_type = erpnext.fs.stmt_type.get_value(); t.innerHTML = ''; var tab = $a($a(t, 'div'),'table','stmt_table'); tab.style.tableLayout = 'fixed'; tab.style.width = '100%'; - $i('stmt_title1').innerHTML = sel_val($i('stmt_company')); - $i('stmt_title2').innerHTML = sel_val($i('stmt_type')) + ' - ' + sel_val($i('stmt_fiscal_year')); + $i('stmt_title1').innerHTML = erpnext.fs.stmt_company.get_value() + $i('stmt_title2').innerHTML = erpnext.fs.stmt_type.get_value() + + ' - ' + erpnext.fs.stmt_fiscal_year.get_value(); for(i=0;i\ - Loading...') - .appendTo(cur_frm.layout.dashboard); - - cur_frm.layout.add_doctype_badge("Supplier Quotation", "supplier"); - cur_frm.layout.add_doctype_badge("Purchase Order", "supplier"); - cur_frm.layout.add_doctype_badge("Purchase Receipt", "supplier"); - cur_frm.layout.add_doctype_badge("Purchase Invoice", "supplier"); + cur_frm.dashboard.set_headline('Loading...') + cur_frm.dashboard.add_doctype_badge("Supplier Quotation", "supplier"); + cur_frm.dashboard.add_doctype_badge("Purchase Order", "supplier"); + cur_frm.dashboard.add_doctype_badge("Purchase Receipt", "supplier"); + cur_frm.dashboard.add_doctype_badge("Purchase Invoice", "supplier"); + wn.call({ type: "GET", method:"buying.doctype.supplier.supplier.get_dashboard_info", @@ -64,16 +62,18 @@ cur_frm.cscript.setup_dashboard = function(doc) { supplier: cur_frm.doc.name }, callback: function(r) { - cur_frm.layout.dashboard.find(".form-headline") - .html(wn._("Total Billing This Year: ") + "" - + format_currency(r.message.total_billing, cur_frm.doc.default_currency) - + ' / ' + wn._("Unpaid") + ": " + - format_currency(r.message.total_unpaid, cur_frm.doc.default_currency) + ''); - cur_frm.layout.set_badge_count(r.message); + cur_frm.dashboard.set_headline( + wn._("Total Billing This Year: ") + "" + + format_currency(r.message.total_billing, cur_frm.doc.default_currency) + + ' / ' + wn._("Unpaid") + ": " + + format_currency(r.message.total_unpaid, cur_frm.doc.default_currency) + + ''); + cur_frm.dashboard.set_badge_count(r.message); } }) } + cur_frm.cscript.make_address = function() { if(!cur_frm.address_list) { cur_frm.address_list = new wn.ui.Listing({ diff --git a/selling/doctype/customer/customer.js b/selling/doctype/customer/customer.js index 3ecfa70036..914836c934 100644 --- a/selling/doctype/customer/customer.js +++ b/selling/doctype/customer/customer.js @@ -55,18 +55,16 @@ cur_frm.cscript.refresh = function(doc,dt,dn) { } cur_frm.cscript.setup_dashboard = function(doc) { - cur_frm.layout.dashboard.empty().toggle(doc.__islocal ? false : true); + cur_frm.dashboard.reset(doc); if(doc.__islocal) return; - var headline = $('
\ - Loading...
') - .appendTo(cur_frm.layout.dashboard); + cur_frm.dashboard.set_headline('Loading...') - cur_frm.layout.add_doctype_badge("Opportunity", "customer"); - cur_frm.layout.add_doctype_badge("Quotation", "customer"); - cur_frm.layout.add_doctype_badge("Sales Order", "customer"); - cur_frm.layout.add_doctype_badge("Delivery Note", "customer"); - cur_frm.layout.add_doctype_badge("Sales Invoice", "customer"); + cur_frm.dashboard.add_doctype_badge("Opportunity", "customer"); + cur_frm.dashboard.add_doctype_badge("Quotation", "customer"); + cur_frm.dashboard.add_doctype_badge("Sales Order", "customer"); + cur_frm.dashboard.add_doctype_badge("Delivery Note", "customer"); + cur_frm.dashboard.add_doctype_badge("Sales Invoice", "customer"); wn.call({ type: "GET", @@ -75,12 +73,13 @@ cur_frm.cscript.setup_dashboard = function(doc) { customer: cur_frm.doc.name }, callback: function(r) { - cur_frm.layout.dashboard.find(".form-headline") - .html(wn._("Total Billing This Year: ") + "" - + format_currency(r.message.total_billing, cur_frm.doc.default_currency) - + ' / ' + wn._("Unpaid") + ": " + - format_currency(r.message.total_unpaid, cur_frm.doc.default_currency) + ''); - cur_frm.layout.set_badge_count(r.message); + cur_frm.dashboard.set_headline( + wn._("Total Billing This Year: ") + "" + + format_currency(r.message.total_billing, cur_frm.doc.default_currency) + + ' / ' + wn._("Unpaid") + ": " + + format_currency(r.message.total_unpaid, cur_frm.doc.default_currency) + + ''); + cur_frm.dashboard.set_badge_count(r.message); } }) } diff --git a/selling/doctype/lead/lead.js b/selling/doctype/lead/lead.js index 8fb26c5a89..3aea4c8582 100644 --- a/selling/doctype/lead/lead.js +++ b/selling/doctype/lead/lead.js @@ -40,9 +40,19 @@ erpnext.LeadController = wn.ui.form.Controller.extend({ }, refresh: function() { + var doc = this.frm.doc; erpnext.hide_naming_series(); this.frm.clear_custom_buttons(); + this.frm.dashboard.reset(doc); + if(!doc.__islocal) { + if(doc.status=="Converted") { + this.frm.dashboard.set_headline_alert(wn._("Converted"), "alert-success", "icon-ok-sign"); + } else { + this.frm.dashboard.set_headline_alert(wn._(doc.status), "alert-info", "icon-exclamation-sign"); + } + } + this.frm.__is_customer = this.frm.__is_customer || this.frm.doc.__is_customer; if(!this.frm.doc.__islocal && !this.frm.__is_customer) { this.frm.add_custom_button("Create Customer", this.frm.cscript['Create Customer']); diff --git a/selling/doctype/opportunity/opportunity.js b/selling/doctype/opportunity/opportunity.js index a4c84af8c5..72afeeafda 100644 --- a/selling/doctype/opportunity/opportunity.js +++ b/selling/doctype/opportunity/opportunity.js @@ -18,9 +18,20 @@ wn.require('app/utilities/doctype/sms_control/sms_control.js'); cur_frm.cscript.refresh = function(doc, cdt, cdn){ erpnext.hide_naming_series(); + + cur_frm.dashboard.reset(doc); + if(!doc.__islocal) { + if(doc.status=="Converted" || doc.status=="Order Confirmed") { + cur_frm.dashboard.set_headline_alert(wn._(doc.status), "alert-success", "icon-ok-sign"); + } else if(doc.status=="Opportunity Lost") { + cur_frm.dashboard.set_headline_alert(wn._(doc.status), "alert-danger", "icon-exclamation-sign"); + } else { + cur_frm.dashboard.set_headline_alert(wn._(doc.status), "alert-info", "icon-exclamation-sign"); + } + } cur_frm.clear_custom_buttons(); - if(doc.docstatus == 1) { + if(doc.docstatus === 1 && doc.status!=="Opportunity Lost") { cur_frm.add_custom_button('Create Quotation', cur_frm.cscript['Create Quotation']); cur_frm.add_custom_button('Opportunity Lost', cur_frm.cscript['Declare Opportunity Lost']); cur_frm.add_custom_button('Send SMS', cur_frm.cscript.send_sms); @@ -198,56 +209,35 @@ cur_frm.cscript['Create Quotation'] = function(){ // declare enquiry lost //------------------------- cur_frm.cscript['Declare Opportunity Lost'] = function(){ - var e_lost_dialog; + var dialog = new wn.ui.Dialog({ + title: "Set as Lost", + fields: [ + {"fieldtype": "Text", "label": "Reason for losing", "fieldname": "reason", + "reqd": 1 }, + {"fieldtype": "Button", "label": "Update", "fieldname": "update"}, + ] + }); - set_e_lost_dialog = function(){ - e_lost_dialog = new Dialog(400,150,'Add Opportunity Lost Reason'); - e_lost_dialog.make_body([ - ['HTML', 'Message', '
Please add enquiry lost reason
'], - ['Text', 'Opportunity Lost Reason'], - ['HTML', 'Response', '
'], - ['HTML', 'Add Reason', '
'] - ]); - - var add_reason_btn1 = $a($i(e_lost_dialog.widgets['Add Reason']), 'button', 'button'); - add_reason_btn1.innerHTML = 'Add'; - add_reason_btn1.onclick = function(){ e_lost_dialog.add(); } - - var add_reason_btn2 = $a($i(e_lost_dialog.widgets['Add Reason']), 'button', 'button'); - add_reason_btn2.innerHTML = 'Cancel'; - $y(add_reason_btn2,{marginLeft:'4px'}); - add_reason_btn2.onclick = function(){ e_lost_dialog.hide();} - - e_lost_dialog.onshow = function() { - e_lost_dialog.widgets['Opportunity Lost Reason'].value = ''; - $i('update_enquiry_dialog_response').innerHTML = ''; - } - - e_lost_dialog.add = function() { - // sending... - $i('update_enquiry_dialog_response').innerHTML = 'Processing...'; - var arg = strip(e_lost_dialog.widgets['Opportunity Lost Reason'].value); - var call_back = function(r,rt) { - if(r.message == 'true'){ - $i('update_enquiry_dialog_response').innerHTML = 'Done'; - e_lost_dialog.hide(); - cur_frm.refresh(); + dialog.fields_dict.update.$input.click(function() { + args = dialog.get_values(); + if(!args) return; + cur_frm.call({ + doc: cur_frm.doc, + method: "declare_enquiry_lost", + args: args.reason, + callback: function(r) { + if(r.exc) { + msgprint("There were errors."); + return; } - } - if(arg) { - $c_obj(make_doclist(cur_frm.doc.doctype, cur_frm.doc.name),'declare_enquiry_lost',arg,call_back); - } - else{ - msgprint("Please add enquiry lost reason"); - } - - } - } + dialog.hide(); + cur_frm.refresh(); + }, + btn: this + }) + }); + dialog.show(); - if(!e_lost_dialog){ - set_e_lost_dialog(); - } - e_lost_dialog.show(); } //get query select Territory diff --git a/selling/doctype/quotation/quotation.js b/selling/doctype/quotation/quotation.js index 654779ca44..fd8c706571 100644 --- a/selling/doctype/quotation/quotation.js +++ b/selling/doctype/quotation/quotation.js @@ -36,10 +36,23 @@ erpnext.selling.QuotationController = erpnext.selling.SellingController.extend({ }, refresh: function(doc, dt, dn) { this._super(doc, dt, dn); + + cur_frm.dashboard.reset(doc); + if(!doc.__islocal) { + if(doc.status=="Converted" || doc.status=="Order Confirmed") { + cur_frm.dashboard.set_headline_alert(wn._(doc.status), "alert-success", "icon-ok-sign"); + } else if(doc.status==="Order Lost") { + cur_frm.dashboard.set_headline_alert(wn._(doc.status), "alert-danger", "icon-exclamation-sign"); + } else { + cur_frm.dashboard.set_headline_alert(wn._(doc.status), "alert-info", "icon-exclamation-sign"); + } + } - if(doc.docstatus == 1 && doc.status!='Order Lost') { + if(doc.docstatus == 1 && doc.status!=='Order Lost') { cur_frm.add_custom_button('Make Sales Order', cur_frm.cscript['Make Sales Order']); - cur_frm.add_custom_button('Set as Lost', cur_frm.cscript['Declare Order Lost']); + if(doc.status!=="Order Confirmed") { + cur_frm.add_custom_button('Set as Lost', cur_frm.cscript['Declare Order Lost']); + } cur_frm.add_custom_button('Send SMS', cur_frm.cscript.send_sms); } @@ -150,51 +163,35 @@ cur_frm.cscript.pull_enquiry_detail = function(doc,cdt,cdn){ // declare order lost //------------------------- cur_frm.cscript['Declare Order Lost'] = function(){ - var qtn_lost_dialog; + var dialog = new wn.ui.Dialog({ + title: "Set as Lost", + fields: [ + {"fieldtype": "Text", "label": "Reason for losing", "fieldname": "reason", + "reqd": 1 }, + {"fieldtype": "Button", "label": "Update", "fieldname": "update"}, + ] + }); - set_qtn_lost_dialog = function(){ - qtn_lost_dialog = new Dialog(400,400,'Add Quotation Lost Reason'); - qtn_lost_dialog.make_body([ - ['HTML', 'Message', '
Please add quotation lost reason
'], - ['Text', 'Quotation Lost Reason'], - ['HTML', 'Response', '
'], - ['HTML', 'Add Reason', '
'] - ]); - - var add_reason_btn1 = $a($i(qtn_lost_dialog.widgets['Add Reason']), 'button', 'button'); - add_reason_btn1.innerHTML = 'Add'; - add_reason_btn1.onclick = function(){ qtn_lost_dialog.add(); } - - var add_reason_btn2 = $a($i(qtn_lost_dialog.widgets['Add Reason']), 'button', 'button'); - add_reason_btn2.innerHTML = 'Cancel'; - $y(add_reason_btn2,{marginLeft:'4px'}); - add_reason_btn2.onclick = function(){ qtn_lost_dialog.hide();} - - qtn_lost_dialog.onshow = function() { - qtn_lost_dialog.widgets['Quotation Lost Reason'].value = ''; - $i('update_quotation_dialog_response').innerHTML = ''; - } - - qtn_lost_dialog.add = function() { - // sending... - $i('update_quotation_dialog_response').innerHTML = 'Processing...'; - var arg = strip(qtn_lost_dialog.widgets['Quotation Lost Reason'].value); - var call_back = function(r,rt) { - if(r.message == 'true'){ - $i('update_quotation_dialog_response').innerHTML = 'Done'; - qtn_lost_dialog.hide(); - cur_frm.refresh(); + dialog.fields_dict.update.$input.click(function() { + args = dialog.get_values(); + if(!args) return; + cur_frm.call({ + method: "declare_order_lost", + doc: cur_frm.doc, + args: args.reason, + callback: function(r) { + if(r.exc) { + msgprint("There were errors."); + return; } - } - if(arg) $c_obj(make_doclist(cur_frm.doc.doctype, cur_frm.doc.name),'declare_order_lost',arg,call_back); - else msgprint("Please add Quotation lost reason"); - } - } - - if(!qtn_lost_dialog){ - set_qtn_lost_dialog(); - } - qtn_lost_dialog.show(); + dialog.hide(); + cur_frm.refresh(); + }, + btn: this + }) + }); + dialog.show(); + } //================ Last Quoted Price and Last Sold Price suggestion ====================== diff --git a/selling/doctype/quotation/quotation.py b/selling/doctype/quotation/quotation.py index d33cd6c1f0..0cbc76e1ea 100644 --- a/selling/doctype/quotation/quotation.py +++ b/selling/doctype/quotation/quotation.py @@ -191,7 +191,7 @@ class DocType(SellingController): # declare as order lost #------------------------- - def declare_order_lost(self,arg): + def declare_order_lost(self, arg): chk = sql("select t1.name from `tabSales Order` t1, `tabSales Order Item` t2 where t2.parent = t1.name and t1.docstatus=1 and t2.prevdoc_docname = %s",self.doc.name) if chk: msgprint("Sales Order No. "+cstr(chk[0][0])+" is submitted against this Quotation. Thus 'Order Lost' can not be declared against it.") diff --git a/selling/doctype/quotation/quotation.txt b/selling/doctype/quotation/quotation.txt index 433ccf3aa4..f583dbeeb6 100644 --- a/selling/doctype/quotation/quotation.txt +++ b/selling/doctype/quotation/quotation.txt @@ -2,7 +2,7 @@ { "creation": "2013-05-24 19:29:08", "docstatus": 0, - "modified": "2013-07-02 16:49:52", + "modified": "2013-07-03 11:54:11", "modified_by": "Administrator", "owner": "Administrator" }, @@ -46,7 +46,8 @@ "doctype": "DocField", "fieldname": "customer_section", "fieldtype": "Section Break", - "label": "Customer" + "label": "Customer", + "options": "icon-user" }, { "doctype": "DocField", @@ -117,17 +118,16 @@ "doctype": "DocField", "fieldname": "customer_name", "fieldtype": "Data", - "hidden": 0, + "hidden": 1, "in_list_view": 1, "label": "Customer Name", "read_only": 1 }, { - "depends_on": "customer", "doctype": "DocField", "fieldname": "address_display", "fieldtype": "Small Text", - "hidden": 0, + "hidden": 1, "in_filter": 0, "label": "Address", "oldfieldname": "customer_address", @@ -138,32 +138,29 @@ "search_index": 0 }, { - "depends_on": "customer", "doctype": "DocField", "fieldname": "contact_display", "fieldtype": "Small Text", - "hidden": 0, + "hidden": 1, "in_filter": 0, "label": "Contact", "print_hide": 0, "read_only": 1 }, { - "depends_on": "customer", "doctype": "DocField", "fieldname": "contact_mobile", "fieldtype": "Text", - "hidden": 0, + "hidden": 1, "label": "Mobile No", "print_hide": 0, "read_only": 1 }, { - "depends_on": "customer", "doctype": "DocField", "fieldname": "contact_email", "fieldtype": "Text", - "hidden": 0, + "hidden": 1, "label": "Contact Email", "print_hide": 1, "read_only": 1 @@ -240,6 +237,7 @@ "fieldname": "section_break0", "fieldtype": "Section Break", "label": "Price List and Currency", + "options": "icon-globe", "read_only": 0 }, { @@ -322,6 +320,7 @@ "fieldtype": "Section Break", "label": "Items", "oldfieldtype": "Section Break", + "options": "icon-shopping-cart", "print_hide": 0, "read_only": 0, "search_index": 0 @@ -343,7 +342,6 @@ "doctype": "DocField", "fieldname": "sec_break23", "fieldtype": "Section Break", - "options": "Simple", "read_only": 0 }, { @@ -419,6 +417,7 @@ "fieldtype": "Section Break", "label": "Taxes", "oldfieldtype": "Section Break", + "options": "icon-money", "read_only": 0 }, { @@ -518,6 +517,7 @@ "fieldtype": "Section Break", "label": "Totals", "oldfieldtype": "Section Break", + "options": "icon-money", "print_hide": 1, "read_only": 0 }, @@ -618,6 +618,7 @@ "fieldtype": "Section Break", "label": "Terms and Conditions", "oldfieldtype": "Section Break", + "options": "icon-legal", "print_hide": 0, "read_only": 0 }, @@ -665,6 +666,7 @@ "fieldname": "contact_section", "fieldtype": "Section Break", "label": "Contact Info", + "options": "icon-bullhorn", "read_only": 0 }, { @@ -754,6 +756,7 @@ "fieldtype": "Section Break", "label": "More Info", "oldfieldtype": "Section Break", + "options": "icon-file-text", "print_hide": 1, "read_only": 0 }, @@ -880,8 +883,9 @@ "doctype": "DocField", "fieldname": "communication_history", "fieldtype": "Section Break", + "label": "Communication History", "oldfieldtype": "Section Break", - "options": "Simple", + "options": "icon-comments", "print_hide": 1, "read_only": 0 }, From bcff7dce8ef2ee8861fae6ab7f45a4a2e2197cf9 Mon Sep 17 00:00:00 2001 From: Rushabh Mehta Date: Wed, 3 Jul 2013 18:32:29 +0530 Subject: [PATCH 4/8] [cleanup] [stock entry] [sales order] --- .../Purchase Order-Purchase Invoice.txt | 100 +++++++------- .../Purchase Receipt-Purchase Invoice.txt | 118 ++++++++--------- .../production_order/production_order.js | 19 ++- .../production_order/production_order.txt | 124 ++++++++++-------- projects/doctype/task/task.py | 3 +- selling/doctype/opportunity/opportunity.js | 2 - selling/doctype/quotation/quotation.js | 2 - selling/doctype/quotation/quotation.txt | 4 +- selling/doctype/sales_order/sales_order.js | 8 ++ selling/doctype/sales_order/sales_order.txt | 37 ++++-- stock/doctype/item/item.py | 2 +- stock/doctype/stock_entry/stock_entry.py | 101 ++++++++------ stock/doctype/stock_entry/test_stock_entry.py | 15 +-- 13 files changed, 299 insertions(+), 236 deletions(-) diff --git a/accounts/DocType Mapper/Purchase Order-Purchase Invoice/Purchase Order-Purchase Invoice.txt b/accounts/DocType Mapper/Purchase Order-Purchase Invoice/Purchase Order-Purchase Invoice.txt index ce45824e40..8c11d5070b 100644 --- a/accounts/DocType Mapper/Purchase Order-Purchase Invoice/Purchase Order-Purchase Invoice.txt +++ b/accounts/DocType Mapper/Purchase Order-Purchase Invoice/Purchase Order-Purchase Invoice.txt @@ -1,122 +1,122 @@ [ { - "owner": "Administrator", - "docstatus": 0, "creation": "2010-08-08 17:09:35", + "docstatus": 0, + "modified": "2013-07-03 18:00:40", "modified_by": "Administrator", - "modified": "2012-04-03 12:49:50" + "owner": "Administrator" }, { - "name": "__common__", - "parent": "Purchase Order-Purchase Invoice", "doctype": "Table Mapper Detail", - "parenttype": "DocType Mapper", - "parentfield": "table_mapper_details" - }, - { "name": "__common__", "parent": "Purchase Order-Purchase Invoice", - "doctype": "Field Mapper Detail", - "parenttype": "DocType Mapper", - "parentfield": "field_mapper_details" + "parentfield": "table_mapper_details", + "parenttype": "DocType Mapper" }, { + "doctype": "Field Mapper Detail", "name": "__common__", - "to_doctype": "Purchase Invoice", - "module": "Accounts", + "parent": "Purchase Order-Purchase Invoice", + "parentfield": "field_mapper_details", + "parenttype": "DocType Mapper" + }, + { "doctype": "DocType Mapper", + "from_doctype": "Purchase Order", + "module": "Accounts", + "name": "__common__", "ref_doc_submitted": 1, - "from_doctype": "Purchase Order" + "to_doctype": "Purchase Invoice" }, { - "name": "Purchase Order-Purchase Invoice", - "doctype": "DocType Mapper" + "doctype": "DocType Mapper", + "name": "Purchase Order-Purchase Invoice" }, { + "doctype": "Field Mapper Detail", + "from_field": "eval: (flt(obj.amount) - flt(obj.billed_amt)) / obj.purchase_rate", "map": "Yes", "match_id": 1, - "to_field": "qty", - "doctype": "Field Mapper Detail", - "from_field": "eval: flt(obj.qty) - flt(obj.billed_qty)" + "to_field": "qty" }, { + "doctype": "Field Mapper Detail", + "from_field": "purchase_rate", "map": "Yes", "match_id": 1, - "to_field": "rate", - "doctype": "Field Mapper Detail", - "from_field": "purchase_rate" + "to_field": "rate" }, { + "doctype": "Field Mapper Detail", + "from_field": "eval: flt(obj.amount) - flt(obj.billed_amt)", "map": "Yes", "match_id": 1, - "to_field": "amount", - "doctype": "Field Mapper Detail", - "from_field": "eval: (flt(obj.qty) - flt(obj.billed_qty)) * flt(obj.purchase_rate)" + "to_field": "amount" }, { + "doctype": "Field Mapper Detail", + "from_field": "eval: (flt(obj.amount) - flt(obj.billed_amt)) / flt(obj.conversion_rate)", "map": "Yes", "match_id": 1, - "to_field": "import_amount", - "doctype": "Field Mapper Detail", - "from_field": "eval: (flt(obj.qty) - flt(obj.billed_qty)) * flt(obj.import_rate)" + "to_field": "import_amount" }, { + "doctype": "Field Mapper Detail", + "from_field": "parent", "map": "Yes", "match_id": 1, - "to_field": "purchase_order", - "doctype": "Field Mapper Detail", - "from_field": "parent" + "to_field": "purchase_order" }, { + "doctype": "Field Mapper Detail", + "from_field": "name", "map": "Yes", "match_id": 1, - "to_field": "po_detail", - "doctype": "Field Mapper Detail", - "from_field": "name" + "to_field": "po_detail" }, { + "doctype": "Field Mapper Detail", + "from_field": "naming_series", "map": "No", "match_id": 0, - "to_field": "naming_series", - "doctype": "Field Mapper Detail", - "from_field": "naming_series" + "to_field": "naming_series" }, { + "doctype": "Field Mapper Detail", + "from_field": "total_tax", "map": "Yes", "match_id": 0, - "to_field": "total_tax", - "doctype": "Field Mapper Detail", - "from_field": "total_tax" + "to_field": "total_tax" }, { + "doctype": "Field Mapper Detail", + "from_field": "conversion_rate", "map": "Yes", "match_id": 0, - "to_field": "conversion_rate", - "doctype": "Field Mapper Detail", - "from_field": "conversion_rate" + "to_field": "conversion_rate" }, { - "match_id": 0, "doctype": "Table Mapper Detail", "from_table": "Purchase Order", + "match_id": 0, "to_table": "Purchase Invoice", "validation_logic": "docstatus =1" }, { - "match_id": 1, - "to_field": "entries", "doctype": "Table Mapper Detail", "from_field": "po_details", "from_table": "Purchase Order Item", + "match_id": 1, + "to_field": "entries", "to_table": "Purchase Invoice Item", - "validation_logic": "ifnull(billed_qty,0) < qty and docstatus = 1" + "validation_logic": "ifnull(billed_amt,0) < amount and docstatus = 1" }, { - "match_id": 2, - "to_field": "purchase_tax_details", "doctype": "Table Mapper Detail", "from_field": "purchase_tax_details", "from_table": "Purchase Taxes and Charges", + "match_id": 2, + "to_field": "purchase_tax_details", "to_table": "Purchase Taxes and Charges", "validation_logic": "docstatus =1" } diff --git a/accounts/DocType Mapper/Purchase Receipt-Purchase Invoice/Purchase Receipt-Purchase Invoice.txt b/accounts/DocType Mapper/Purchase Receipt-Purchase Invoice/Purchase Receipt-Purchase Invoice.txt index f6c87e266c..99c74ac818 100644 --- a/accounts/DocType Mapper/Purchase Receipt-Purchase Invoice/Purchase Receipt-Purchase Invoice.txt +++ b/accounts/DocType Mapper/Purchase Receipt-Purchase Invoice/Purchase Receipt-Purchase Invoice.txt @@ -1,143 +1,143 @@ [ { - "owner": "Administrator", - "docstatus": 0, "creation": "2010-08-08 17:09:35", + "docstatus": 0, + "modified": "2013-07-03 17:56:30", "modified_by": "Administrator", - "modified": "2012-04-03 12:49:50" + "owner": "Administrator" }, { - "name": "__common__", - "parent": "Purchase Receipt-Purchase Invoice", "doctype": "Table Mapper Detail", - "parenttype": "DocType Mapper", - "parentfield": "table_mapper_details" - }, - { "name": "__common__", "parent": "Purchase Receipt-Purchase Invoice", - "doctype": "Field Mapper Detail", - "parenttype": "DocType Mapper", - "parentfield": "field_mapper_details" + "parentfield": "table_mapper_details", + "parenttype": "DocType Mapper" }, { + "doctype": "Field Mapper Detail", "name": "__common__", - "to_doctype": "Purchase Invoice", - "module": "Accounts", + "parent": "Purchase Receipt-Purchase Invoice", + "parentfield": "field_mapper_details", + "parenttype": "DocType Mapper" + }, + { "doctype": "DocType Mapper", + "from_doctype": "Purchase Receipt", + "module": "Accounts", + "name": "__common__", "ref_doc_submitted": 1, - "from_doctype": "Purchase Receipt" + "to_doctype": "Purchase Invoice" }, { - "name": "Purchase Receipt-Purchase Invoice", - "doctype": "DocType Mapper" + "doctype": "DocType Mapper", + "name": "Purchase Receipt-Purchase Invoice" }, { + "doctype": "Field Mapper Detail", + "from_field": "eval: (flt(obj.amount) - flt(obj.billed_amt)) / obj.purchase_rate", "map": "Yes", "match_id": 1, - "to_field": "qty", - "doctype": "Field Mapper Detail", - "from_field": "eval: flt(obj.qty) - flt(obj.billed_qty)" + "to_field": "qty" }, { + "doctype": "Field Mapper Detail", + "from_field": "purchase_rate", "map": "Yes", "match_id": 1, - "to_field": "rate", - "doctype": "Field Mapper Detail", - "from_field": "purchase_rate" + "to_field": "rate" }, { + "doctype": "Field Mapper Detail", + "from_field": "eval: flt(obj.amount) - flt(obj.billed_amt)", "map": "Yes", "match_id": 1, - "to_field": "amount", - "doctype": "Field Mapper Detail", - "from_field": "eval: (flt(obj.qty) - flt(obj.billed_qty)) * flt(obj.purchase_rate)" + "to_field": "amount" }, { + "doctype": "Field Mapper Detail", + "from_field": "eval: (flt(obj.amount) - flt(obj.billed_amt)) / flt(obj.conversion_rate)", "map": "Yes", "match_id": 1, - "to_field": "import_amount", - "doctype": "Field Mapper Detail", - "from_field": "eval: (flt(obj.qty) - flt(obj.billed_qty)) * flt(obj.import_rate)" + "to_field": "import_amount" }, { + "doctype": "Field Mapper Detail", + "from_field": "parent", "map": "Yes", "match_id": 1, - "to_field": "purchase_receipt", - "doctype": "Field Mapper Detail", - "from_field": "parent" + "to_field": "purchase_receipt" }, { + "doctype": "Field Mapper Detail", + "from_field": "prevdoc_docname", "map": "Yes", "match_id": 1, - "to_field": "purchase_order", - "doctype": "Field Mapper Detail", - "from_field": "prevdoc_docname" + "to_field": "purchase_order" }, { + "doctype": "Field Mapper Detail", + "from_field": "name", "map": "Yes", "match_id": 1, - "to_field": "pr_detail", - "doctype": "Field Mapper Detail", - "from_field": "name" + "to_field": "pr_detail" }, { + "doctype": "Field Mapper Detail", + "from_field": "prevdoc_detail_docname", "map": "Yes", "match_id": 1, - "to_field": "po_detail", - "doctype": "Field Mapper Detail", - "from_field": "prevdoc_detail_docname" + "to_field": "po_detail" }, { + "doctype": "Field Mapper Detail", + "from_field": "naming_series", "map": "No", "match_id": 0, - "to_field": "naming_series", - "doctype": "Field Mapper Detail", - "from_field": "naming_series" + "to_field": "naming_series" }, { + "doctype": "Field Mapper Detail", + "from_field": "net_total", "map": "Yes", "match_id": 0, - "to_field": "net_total", - "doctype": "Field Mapper Detail", - "from_field": "net_total" + "to_field": "net_total" }, { + "doctype": "Field Mapper Detail", + "from_field": "grand_total", "map": "Yes", "match_id": 0, - "to_field": "grand_total", - "doctype": "Field Mapper Detail", - "from_field": "grand_total" + "to_field": "grand_total" }, { + "doctype": "Field Mapper Detail", + "from_field": "total_tax", "map": "Yes", "match_id": 0, - "to_field": "total_tax", - "doctype": "Field Mapper Detail", - "from_field": "total_tax" + "to_field": "total_tax" }, { - "match_id": 1, - "to_field": "entries", "doctype": "Table Mapper Detail", "from_field": "purchase_receipt_details", "from_table": "Purchase Receipt Item", + "match_id": 1, + "to_field": "entries", "to_table": "Purchase Invoice Item", - "validation_logic": "ifnull(billed_qty,0) < qty" + "validation_logic": "ifnull(billed_amt,0) < amount" }, { - "match_id": 0, "doctype": "Table Mapper Detail", "from_table": "Purchase Receipt", + "match_id": 0, "to_table": "Purchase Invoice", "validation_logic": "docstatus=1" }, { - "match_id": 2, - "to_field": "purchase_tax_details", "doctype": "Table Mapper Detail", "from_field": "purchase_tax_details", "from_table": "Purchase Taxes and Charges", + "match_id": 2, + "to_field": "purchase_tax_details", "to_table": "Purchase Taxes and Charges", "validation_logic": "docstatus=1" } diff --git a/manufacturing/doctype/production_order/production_order.js b/manufacturing/doctype/production_order/production_order.js index 5243026c70..4c41d94715 100644 --- a/manufacturing/doctype/production_order/production_order.js +++ b/manufacturing/doctype/production_order/production_order.js @@ -20,20 +20,19 @@ cur_frm.cscript.onload = function(doc, dt, dn) { } cur_frm.cscript.refresh = function(doc, dt, dn) { + cur_frm.dashboard.reset(); erpnext.hide_naming_series(); cur_frm.set_intro(""); cfn_set_fields(doc, dt, dn); + if(doc.docstatus===0 && !doc.__islocal) { cur_frm.set_intro("Submit this Production Order for further processing."); } else if(doc.docstatus===1) { + var percent = flt(doc.produced_qty) / doc.qty * 100; + cur_frm.dashboard.add_progress(cint(percent) + "% " + wn._("Complete")); + if(doc.status === "Stopped") { - cur_frm.set_intro("This Production Order is Stopped."); - } else { - if(doc.produced_qty == doc.qty) { - cur_frm.set_intro("This Production Order is Completed."); - } else { - cur_frm.set_intro("This Production Order is in progress."); - } + cur_frm.dashboard.set_headline_alert(wn._("Stopped"), "alert-danger", "icon-stop"); } } } @@ -88,6 +87,12 @@ cur_frm.cscript.make_se = function(doc, purpose) { var se = wn.model.get_new_doc("Stock Entry"); se.purpose = purpose; se.production_order = doc.name; + if(purpose==="Material Transfer") { + se.to_warehouse = doc.wip_warehouse; + } else { + se.from_warehouse = doc.wip_warehouse; + se.to_warehouse = doc.fg_warehouse; + } se.company = doc.company; se.fg_completed_qty = doc.qty - doc.produced_qty; se.bom_no = doc.bom_no; diff --git a/manufacturing/doctype/production_order/production_order.txt b/manufacturing/doctype/production_order/production_order.txt index 38a98fefab..08123e8e0b 100644 --- a/manufacturing/doctype/production_order/production_order.txt +++ b/manufacturing/doctype/production_order/production_order.txt @@ -2,7 +2,7 @@ { "creation": "2013-01-10 16:34:16", "docstatus": 0, - "modified": "2013-07-02 11:56:54", + "modified": "2013-07-03 17:00:29", "modified_by": "Administrator", "owner": "Administrator" }, @@ -42,6 +42,13 @@ "doctype": "DocType", "name": "Production Order" }, + { + "doctype": "DocField", + "fieldname": "item", + "fieldtype": "Section Break", + "label": "Item", + "options": "icon-gift" + }, { "default": "PRO", "doctype": "DocField", @@ -51,22 +58,6 @@ "options": "\nPRO", "reqd": 1 }, - { - "depends_on": "eval:!doc.__islocal", - "doctype": "DocField", - "fieldname": "status", - "fieldtype": "Select", - "in_filter": 1, - "in_list_view": 1, - "label": "Status", - "no_copy": 1, - "oldfieldname": "status", - "oldfieldtype": "Select", - "options": "\nDraft\nSubmitted\nStopped\nIn Process\nCompleted\nCancelled", - "read_only": 1, - "reqd": 1, - "search_index": 1 - }, { "doctype": "DocField", "fieldname": "production_item", @@ -95,24 +86,12 @@ "reqd": 1 }, { - "depends_on": "production_item", - "description": "Manufactured quantity will be updated in this warehouse", + "default": "1", + "description": "If checked, BOM for sub-assembly items will be considered for getting raw materials. Otherwise, all sub-assembly items will be treated as a raw material.", "doctype": "DocField", - "fieldname": "fg_warehouse", - "fieldtype": "Link", - "in_list_view": 1, - "label": "For Warehouse", - "options": "Warehouse", - "read_only": 0, - "reqd": 1 - }, - { - "doctype": "DocField", - "fieldname": "wip_warehouse", - "fieldtype": "Link", - "label": "Work-in-Progress Warehouse", - "options": "Warehouse", - "reqd": 1 + "fieldname": "use_multi_level_bom", + "fieldtype": "Check", + "label": "Use Multi-Level BOM" }, { "doctype": "DocField", @@ -122,6 +101,15 @@ "read_only": 0, "width": "50%" }, + { + "description": "Manufacture against Sales Order", + "doctype": "DocField", + "fieldname": "sales_order", + "fieldtype": "Link", + "label": "Sales Order", + "options": "Sales Order", + "read_only": 0 + }, { "depends_on": "production_item", "doctype": "DocField", @@ -147,38 +135,60 @@ "read_only": 1 }, { - "depends_on": "production_item", "doctype": "DocField", - "fieldname": "stock_uom", - "fieldtype": "Data", - "label": "Stock UOM", - "oldfieldname": "stock_uom", - "oldfieldtype": "Data", - "read_only": 1 + "fieldname": "warehouses", + "fieldtype": "Section Break", + "label": "Warehouses", + "options": "icon-building" }, { - "default": "1", - "description": "If checked, BOM for sub-assembly items will be considered for getting raw materials. Otherwise, all sub-assembly items will be treated as a raw material.", + "depends_on": "production_item", + "description": "Manufactured quantity will be updated in this warehouse", "doctype": "DocField", - "fieldname": "use_multi_level_bom", - "fieldtype": "Check", - "label": "Use Multi-Level BOM" + "fieldname": "fg_warehouse", + "fieldtype": "Link", + "in_list_view": 1, + "label": "For Warehouse", + "options": "Warehouse", + "read_only": 0, + "reqd": 1 + }, + { + "doctype": "DocField", + "fieldname": "column_break_12", + "fieldtype": "Column Break" + }, + { + "doctype": "DocField", + "fieldname": "wip_warehouse", + "fieldtype": "Link", + "label": "Work-in-Progress Warehouse", + "options": "Warehouse", + "reqd": 1 }, { "doctype": "DocField", "fieldname": "more_info", "fieldtype": "Section Break", "label": "More Info", + "options": "icon-file-text", "read_only": 0 }, { - "description": "Manufacture against Sales Order", + "depends_on": "eval:!doc.__islocal", "doctype": "DocField", - "fieldname": "sales_order", - "fieldtype": "Link", - "label": "Sales Order", - "options": "Sales Order", - "read_only": 0 + "fieldname": "status", + "fieldtype": "Select", + "in_filter": 1, + "in_list_view": 1, + "label": "Status", + "no_copy": 1, + "oldfieldname": "status", + "oldfieldtype": "Select", + "options": "\nDraft\nSubmitted\nStopped\nIn Process\nCompleted\nCancelled", + "read_only": 1, + "reqd": 1, + "search_index": 1 }, { "doctype": "DocField", @@ -205,6 +215,16 @@ "read_only": 0, "width": "50%" }, + { + "depends_on": "production_item", + "doctype": "DocField", + "fieldname": "stock_uom", + "fieldtype": "Data", + "label": "Stock UOM", + "oldfieldname": "stock_uom", + "oldfieldtype": "Data", + "read_only": 1 + }, { "doctype": "DocField", "fieldname": "company", diff --git a/projects/doctype/task/task.py b/projects/doctype/task/task.py index a76dc9beaa..1df8547690 100644 --- a/projects/doctype/task/task.py +++ b/projects/doctype/task/task.py @@ -63,7 +63,8 @@ class DocType: def on_update(self): """update percent complete in project""" if self.doc.project: - webnotes.bean("Project", self.doc.project).controller.update_percent_complete() + project = webnotes.bean("Project", self.doc.project) + project.run_method("update_percent_complete") @webnotes.whitelist() def get_events(start, end, filters=None): diff --git a/selling/doctype/opportunity/opportunity.js b/selling/doctype/opportunity/opportunity.js index 72afeeafda..583f25adf1 100644 --- a/selling/doctype/opportunity/opportunity.js +++ b/selling/doctype/opportunity/opportunity.js @@ -25,8 +25,6 @@ cur_frm.cscript.refresh = function(doc, cdt, cdn){ cur_frm.dashboard.set_headline_alert(wn._(doc.status), "alert-success", "icon-ok-sign"); } else if(doc.status=="Opportunity Lost") { cur_frm.dashboard.set_headline_alert(wn._(doc.status), "alert-danger", "icon-exclamation-sign"); - } else { - cur_frm.dashboard.set_headline_alert(wn._(doc.status), "alert-info", "icon-exclamation-sign"); } } diff --git a/selling/doctype/quotation/quotation.js b/selling/doctype/quotation/quotation.js index fd8c706571..66d4d0bddd 100644 --- a/selling/doctype/quotation/quotation.js +++ b/selling/doctype/quotation/quotation.js @@ -43,8 +43,6 @@ erpnext.selling.QuotationController = erpnext.selling.SellingController.extend({ cur_frm.dashboard.set_headline_alert(wn._(doc.status), "alert-success", "icon-ok-sign"); } else if(doc.status==="Order Lost") { cur_frm.dashboard.set_headline_alert(wn._(doc.status), "alert-danger", "icon-exclamation-sign"); - } else { - cur_frm.dashboard.set_headline_alert(wn._(doc.status), "alert-info", "icon-exclamation-sign"); } } diff --git a/selling/doctype/quotation/quotation.txt b/selling/doctype/quotation/quotation.txt index f583dbeeb6..cfe0881208 100644 --- a/selling/doctype/quotation/quotation.txt +++ b/selling/doctype/quotation/quotation.txt @@ -2,7 +2,7 @@ { "creation": "2013-05-24 19:29:08", "docstatus": 0, - "modified": "2013-07-03 11:54:11", + "modified": "2013-07-03 16:12:44", "modified_by": "Administrator", "owner": "Administrator" }, @@ -237,7 +237,7 @@ "fieldname": "section_break0", "fieldtype": "Section Break", "label": "Price List and Currency", - "options": "icon-globe", + "options": "icon-tag", "read_only": 0 }, { diff --git a/selling/doctype/sales_order/sales_order.js b/selling/doctype/sales_order/sales_order.js index d9e2d7b047..c4d50cc045 100644 --- a/selling/doctype/sales_order/sales_order.js +++ b/selling/doctype/sales_order/sales_order.js @@ -29,9 +29,16 @@ wn.require('app/utilities/doctype/sms_control/sms_control.js'); erpnext.selling.SalesOrderController = erpnext.selling.SellingController.extend({ refresh: function(doc, dt, dn) { this._super(); + this.frm.dashboard.reset(); if(doc.docstatus==1) { if(doc.status != 'Stopped') { + + cur_frm.dashboard.add_progress(cint(doc.per_delivered) + wn._("% Delivered"), + doc.per_delivered); + cur_frm.dashboard.add_progress(cint(doc.per_delivered) + wn._("% Billed"), + doc.per_billed); + cur_frm.add_custom_button('Send SMS', cur_frm.cscript.send_sms); // delivery note if(flt(doc.per_delivered, 2) < 100 && doc.order_type=='Sales') @@ -56,6 +63,7 @@ erpnext.selling.SalesOrderController = erpnext.selling.SellingController.extend( cur_frm.add_custom_button('Stop!', cur_frm.cscript['Stop Sales Order']); } else { // un-stop + cur_frm.dashboard.set_headline_alert("Stopped", "alert-danger", "icon-stop"); cur_frm.add_custom_button('Unstop', cur_frm.cscript['Unstop Sales Order']); } } diff --git a/selling/doctype/sales_order/sales_order.txt b/selling/doctype/sales_order/sales_order.txt index 6bb1d265f6..2a78bf79b3 100644 --- a/selling/doctype/sales_order/sales_order.txt +++ b/selling/doctype/sales_order/sales_order.txt @@ -2,7 +2,7 @@ { "creation": "2013-06-18 12:39:59", "docstatus": 0, - "modified": "2013-06-27 11:31:02", + "modified": "2013-07-03 16:12:26", "modified_by": "Administrator", "owner": "Administrator" }, @@ -39,6 +39,13 @@ "doctype": "DocType", "name": "Sales Order" }, + { + "doctype": "DocField", + "fieldname": "customer_section", + "fieldtype": "Section Break", + "label": "Customer", + "options": "icon-user" + }, { "doctype": "DocField", "fieldname": "column_break0", @@ -86,38 +93,34 @@ "read_only": 1 }, { - "depends_on": "customer", "doctype": "DocField", "fieldname": "address_display", "fieldtype": "Small Text", - "hidden": 0, + "hidden": 1, "label": "Address", "read_only": 1 }, { - "depends_on": "customer", "doctype": "DocField", "fieldname": "contact_display", "fieldtype": "Small Text", - "hidden": 0, + "hidden": 1, "label": "Contact", "read_only": 1 }, { - "depends_on": "customer", "doctype": "DocField", "fieldname": "contact_mobile", "fieldtype": "Text", - "hidden": 0, + "hidden": 1, "label": "Mobile No", "read_only": 1 }, { - "depends_on": "customer", "doctype": "DocField", "fieldname": "contact_email", "fieldtype": "Text", - "hidden": 0, + "hidden": 1, "label": "Contact Email", "print_hide": 1, "read_only": 1 @@ -252,7 +255,8 @@ "doctype": "DocField", "fieldname": "sec_break45", "fieldtype": "Section Break", - "label": "Price List and Currency" + "label": "Price List and Currency", + "options": "icon-tag" }, { "description": "Customer's currency", @@ -323,7 +327,8 @@ "fieldname": "items", "fieldtype": "Section Break", "label": "Items", - "oldfieldtype": "Section Break" + "oldfieldtype": "Section Break", + "options": "icon-shopping-cart" }, { "allow_on_submit": 1, @@ -345,6 +350,7 @@ "hidden": 0, "label": "Packing List", "oldfieldtype": "Section Break", + "options": "icon-suitcase", "print_hide": 1 }, { @@ -444,6 +450,7 @@ "fieldtype": "Section Break", "label": "Taxes", "oldfieldtype": "Section Break", + "options": "icon-money", "print_hide": 0 }, { @@ -537,6 +544,7 @@ "fieldtype": "Section Break", "label": "Totals", "oldfieldtype": "Section Break", + "options": "icon-money", "print_hide": 1 }, { @@ -626,6 +634,7 @@ "fieldtype": "Section Break", "label": "Terms and Conditions", "oldfieldtype": "Section Break", + "options": "icon-legal", "print_hide": 0 }, { @@ -671,7 +680,8 @@ "doctype": "DocField", "fieldname": "contact_info", "fieldtype": "Section Break", - "label": "Contact Info" + "label": "Contact Info", + "options": "icon-bullhorn" }, { "doctype": "DocField", @@ -734,6 +744,7 @@ "fieldtype": "Section Break", "label": "More Info", "oldfieldtype": "Section Break", + "options": "icon-file-text", "print_hide": 1 }, { @@ -904,6 +915,7 @@ "fieldtype": "Section Break", "label": "Sales Team", "oldfieldtype": "Section Break", + "options": "icon-group", "print_hide": 1 }, { @@ -951,7 +963,6 @@ "doctype": "DocField", "fieldname": "section_break1", "fieldtype": "Section Break", - "options": "Simple", "print_hide": 1 }, { diff --git a/stock/doctype/item/item.py b/stock/doctype/item/item.py index 295bff328f..dc4fde8723 100644 --- a/stock/doctype/item/item.py +++ b/stock/doctype/item/item.py @@ -204,7 +204,7 @@ class DocType(DocListController): if vals and ((self.doc.is_stock_item == "No" and vals.is_stock_item == "Yes") or vals.has_serial_no != self.doc.has_serial_no or - vals.valuation_method != self.doc.valuation_method): + cstr(vals.valuation_method) != cstr(self.doc.valuation_method)): if self.check_if_sle_exists() == "exists": webnotes.msgprint(_("As there are existing stock transactions for this \ item, you can not change the values of 'Has Serial No', \ diff --git a/stock/doctype/stock_entry/stock_entry.py b/stock/doctype/stock_entry/stock_entry.py index d2f25f0e46..4e64089376 100644 --- a/stock/doctype/stock_entry/stock_entry.py +++ b/stock/doctype/stock_entry/stock_entry.py @@ -466,20 +466,23 @@ class DocType(StockController): item_dict = self.get_bom_raw_materials(self.doc.fg_completed_qty) # add raw materials to Stock Entry Detail table - self.add_to_stock_entry_detail(self.doc.from_warehouse, self.doc.to_warehouse, - item_dict) + self.add_to_stock_entry_detail(item_dict) # add finished good item to Stock Entry Detail table -- along with bom_no if self.doc.production_order and self.doc.purpose == "Manufacture/Repack": - self.add_to_stock_entry_detail(None, pro_obj.doc.fg_warehouse, { + self.doc.to_warehouse = pro_obj.doc.fg_warehouse + self.add_to_stock_entry_detail({ cstr(pro_obj.doc.production_item): [self.doc.fg_completed_qty, pro_obj.doc.description, pro_obj.doc.stock_uom] }, bom_no=pro_obj.doc.bom_no) elif self.doc.purpose in ["Material Receipt", "Manufacture/Repack"]: + if self.doc.purpose=="Material Receipt": + self.doc.from_warehouse = "" + item = webnotes.conn.sql("""select item, description, uom from `tabBOM` where name=%s""", (self.doc.bom_no,), as_dict=1) - self.add_to_stock_entry_detail(None, self.doc.to_warehouse, { + self.add_to_stock_entry_detail({ item[0]["item"] : [self.doc.fg_completed_qty, item[0]["description"], item[0]["uom"]] }, bom_no=self.doc.bom_no) @@ -492,36 +495,56 @@ class DocType(StockController): child items of sub-contracted and sub assembly items and sub assembly items itself. """ - # item dict = { item_code: [qty, description, stock_uom] } + # item dict = { item_code: {qty, description, stock_uom} } item_dict = {} def _make_items_dict(items_list): """makes dict of unique items with it's qty""" for item in items_list: if item_dict.has_key(item.item_code): - item_dict[item.item_code][0] += flt(item.qty) + item_dict[item.item_code]["qty"] += flt(item.qty) else: - item_dict[item.item_code] = [flt(item.qty), item.description, item.stock_uom] + item_dict[item.item_code] = { + "qty": flt(item.qty), + "description": item.description, + "stock_uom": item.stock_uom, + "from_warehouse": item.default_warehouse + } if self.doc.use_multi_level_bom: # get all raw materials with sub assembly childs - fl_bom_sa_child_item = sql("""select fb.item_code, - ifnull(sum(fb.qty_consumed_per_unit),0)*%s as qty, fb.description, fb.stock_uom - from `tabBOM Explosion Item` fb,`tabItem` it - where it.name = fb.item_code and ifnull(it.is_pro_applicable, 'No') = 'No' - and ifnull(it.is_sub_contracted_item, 'No') = 'No' and fb.docstatus < 2 - and fb.parent=%s group by item_code, stock_uom""", + fl_bom_sa_child_item = sql("""select + fb.item_code, + ifnull(sum(fb.qty_consumed_per_unit),0)*%s as qty, + fb.description, + fb.stock_uom, + it.default_warehouse + from + `tabBOM Explosion Item` fb,`tabItem` it + where + it.name = fb.item_code + and ifnull(it.is_pro_applicable, 'No') = 'No' + and ifnull(it.is_sub_contracted_item, 'No') = 'No' + and fb.docstatus < 2 + and fb.parent=%s group by item_code, stock_uom""", (qty, self.doc.bom_no), as_dict=1) if fl_bom_sa_child_item: _make_items_dict(fl_bom_sa_child_item) else: - # Get all raw materials considering multi level BOM, - # if multi level bom consider childs of Sub-Assembly items - fl_bom_sa_items = sql("""select item_code, - ifnull(sum(qty_consumed_per_unit), 0) *%s as qty, - description, stock_uom from `tabBOM Item` - where parent = %s and docstatus < 2 + # get only BOM items + fl_bom_sa_items = sql("""select + `tabItem`.item_code, + ifnull(sum(`tabBOM Item`.qty_consumed_per_unit), 0) *%s as qty, + `tabItem`.description, + `tabItem`.stock_uom, + `tabItem`.default_warehouse + from + `tabBOM Item`, `tabItem` + where + `tabBOM Item`.parent = %s and + `tabBOM Item`.item_code = tabItem.name + `tabBOM Item`.docstatus < 2 group by item_code""", (qty, self.doc.bom_no), as_dict=1) if fl_bom_sa_items: @@ -534,30 +557,30 @@ class DocType(StockController): issue (item quantity) that is pending to issue or desire to transfer, whichever is less """ - item_qty = self.get_bom_raw_materials(1) + item_dict = self.get_bom_raw_materials(1) issued_item_qty = self.get_issued_qty() max_qty = flt(pro_obj.doc.qty) only_pending_fetched = [] - for item in item_qty: - pending_to_issue = (max_qty * item_qty[item][0]) - issued_item_qty.get(item, 0) - desire_to_transfer = flt(self.doc.fg_completed_qty) * item_qty[item][0] + for item in item_dict: + pending_to_issue = (max_qty * item_dict[item]["qty"]) - issued_item_qty.get(item, 0) + desire_to_transfer = flt(self.doc.fg_completed_qty) * item_dict[item]["qty"] if desire_to_transfer <= pending_to_issue: - item_qty[item][0] = desire_to_transfer + item_dict[item]["qty"] = desire_to_transfer else: - item_qty[item][0] = pending_to_issue + item_dict[item]["qty"] = pending_to_issue if pending_to_issue: only_pending_fetched.append(item) # delete items with 0 qty - for item in item_qty.keys(): - if not item_qty[item][0]: - del item_qty[item] + for item in item_dict.keys(): + if not item_dict[item]["qty"]: + del item_dict[item] # show some message - if not len(item_qty): + if not len(item_dict): webnotes.msgprint(_("""All items have already been transferred \ for this Production Order.""")) @@ -565,7 +588,7 @@ class DocType(StockController): webnotes.msgprint(_("""Only quantities pending to be transferred \ were fetched for the following items:\n""" + "\n".join(only_pending_fetched))) - return item_qty + return item_dict def get_issued_qty(self): issued_item_qty = {} @@ -579,18 +602,20 @@ class DocType(StockController): return issued_item_qty - def add_to_stock_entry_detail(self, source_wh, target_wh, item_dict, bom_no=None): + def add_to_stock_entry_detail(self, item_dict, bom_no=None): for d in item_dict: se_child = addchild(self.doc, 'mtn_details', 'Stock Entry Detail', self.doclist) - se_child.s_warehouse = source_wh - se_child.t_warehouse = target_wh + se_child.s_warehouse = item_dict[d].get("from_warehouse", self.doc.from_warehouse) + se_child.t_warehouse = item_dict[d].get("to_warehouse", self.doc.to_warehouse) se_child.item_code = cstr(d) - se_child.description = item_dict[d][1] - se_child.uom = item_dict[d][2] - se_child.stock_uom = item_dict[d][2] - se_child.qty = flt(item_dict[d][0]) - se_child.transfer_qty = flt(item_dict[d][0]) + se_child.description = item_dict[d]["description"] + se_child.uom = item_dict[d]["stock_uom"] + se_child.stock_uom = item_dict[d]["stock_uom"] + se_child.qty = flt(item_dict[d]["qty"]) + + # in stock uom + se_child.transfer_qty = flt(item_dict[d]["qty"]) se_child.conversion_factor = 1.00 # to be assigned for finished item diff --git a/stock/doctype/stock_entry/test_stock_entry.py b/stock/doctype/stock_entry/test_stock_entry.py index 345e73c87e..7b058be073 100644 --- a/stock/doctype/stock_entry/test_stock_entry.py +++ b/stock/doctype/stock_entry/test_stock_entry.py @@ -6,6 +6,11 @@ import webnotes, unittest from webnotes.utils import flt class TestStockEntry(unittest.TestCase): + def tearDown(self): + webnotes.defaults.set_global_default("auto_inventory_accounting", 0) + if hasattr(self, "old_default_company"): + webnotes.conn.set_default("company", self.old_default_company) + def test_auto_material_request(self): webnotes.conn.sql("""delete from `tabMaterial Request Item`""") webnotes.conn.sql("""delete from `tabMaterial Request`""") @@ -72,8 +77,6 @@ class TestStockEntry(unittest.TestCase): ["Stock Adjustment - _TC", 5000.0, 0.0] ]) ) - - webnotes.defaults.set_global_default("auto_inventory_accounting", 0) def test_material_issue_gl_entry(self): self._clear_stock() @@ -115,9 +118,6 @@ class TestStockEntry(unittest.TestCase): ]) ) - webnotes.defaults.set_global_default("auto_inventory_accounting", 0) - webnotes.conn.set_default("company", self.old_default_company) - def test_material_transfer_gl_entry(self): self._clear_stock() webnotes.defaults.set_global_default("auto_inventory_accounting", 1) @@ -149,10 +149,7 @@ class TestStockEntry(unittest.TestCase): gl_entries = webnotes.conn.sql("""select * from `tabGL Entry` where voucher_type = 'Stock Entry' and voucher_no=%s""", mtn.doc.name) self.assertFalse(gl_entries) - - webnotes.defaults.set_global_default("auto_inventory_accounting", 0) - webnotes.conn.set_default("company", self.old_default_company) - + def check_stock_ledger_entries(self, voucher_type, voucher_no, expected_sle): # check stock ledger entries sle = webnotes.conn.sql("""select * from `tabStock Ledger Entry` where voucher_type = %s From 8aded138c7e08b2f21d79e7f9c1be30a64f618c0 Mon Sep 17 00:00:00 2001 From: Rushabh Mehta Date: Thu, 4 Jul 2013 12:50:52 +0530 Subject: [PATCH 5/8] [buying] started cleanup, [mapper] started rewrite --- .../purchase_common/purchase_common.js | 6 ++ .../doctype/purchase_order/purchase_order.txt | 44 +++++++++------ buying/doctype/supplier/supplier.js | 2 +- buying/doctype/supplier/supplier.txt | 15 +++-- .../supplier_quotation/supplier_quotation.txt | 56 +++++++++++-------- selling/doctype/lead/lead.js | 36 ++---------- selling/doctype/lead/lead.py | 22 +++++++- selling/doctype/lead/test_lead.py | 16 ++++++ selling/doctype/quotation/quotation.py | 7 ++- selling/doctype/quotation/quotation.txt | 3 +- selling/doctype/quotation/test_quotation.py | 49 ++++++++++++++++ selling/doctype/sales_common/sales_common.js | 6 ++ selling/doctype/sales_order/sales_order.txt | 3 +- stock/doctype/item/item.js | 8 +++ .../material_request/material_request.js | 10 ++++ .../material_request/material_request.txt | 22 +++++--- stock/page/stock_home/stock_home.js | 10 ++-- 17 files changed, 218 insertions(+), 97 deletions(-) create mode 100644 selling/doctype/quotation/test_quotation.py diff --git a/buying/doctype/purchase_common/purchase_common.js b/buying/doctype/purchase_common/purchase_common.js index f9694d0695..c8e4aa3585 100644 --- a/buying/doctype/purchase_common/purchase_common.js +++ b/buying/doctype/purchase_common/purchase_common.js @@ -53,6 +53,12 @@ erpnext.buying.BuyingController = erpnext.TransactionController.extend({ }); }, + refresh: function(doc) { + this.frm.toggle_display("supplier_name", + (this.supplier_name && this.frm.doc.supplier_name!==this.frm.doc.supplier)); + this._super(); + }, + supplier: function() { if(this.frm.doc.supplier || this.frm.doc.credit_to) { if(!this.frm.doc.company) { diff --git a/buying/doctype/purchase_order/purchase_order.txt b/buying/doctype/purchase_order/purchase_order.txt index b78552f49f..b2bf1464aa 100644 --- a/buying/doctype/purchase_order/purchase_order.txt +++ b/buying/doctype/purchase_order/purchase_order.txt @@ -2,7 +2,7 @@ { "creation": "2013-05-21 16:16:39", "docstatus": 0, - "modified": "2013-06-11 16:05:08", + "modified": "2013-07-04 10:48:54", "modified_by": "Administrator", "owner": "Administrator" }, @@ -39,6 +39,13 @@ "doctype": "DocType", "name": "Purchase Order" }, + { + "doctype": "DocField", + "fieldname": "supplier_section", + "fieldtype": "Section Break", + "label": "Supplier", + "options": "icon-user" + }, { "description": "To manage multiple series please go to Setup > Manage Series", "doctype": "DocField", @@ -67,7 +74,6 @@ "search_index": 1 }, { - "depends_on": "supplier", "doctype": "DocField", "fieldname": "supplier_name", "fieldtype": "Data", @@ -77,38 +83,34 @@ "read_only": 1 }, { - "depends_on": "supplier", "doctype": "DocField", "fieldname": "address_display", "fieldtype": "Small Text", - "hidden": 0, + "hidden": 1, "label": "Address", "read_only": 1 }, { - "depends_on": "supplier", "doctype": "DocField", "fieldname": "contact_display", "fieldtype": "Small Text", - "hidden": 0, + "hidden": 1, "label": "Contact", "read_only": 1 }, { - "depends_on": "supplier", "doctype": "DocField", "fieldname": "contact_mobile", "fieldtype": "Text", - "hidden": 0, + "hidden": 1, "label": "Mobile No", "read_only": 1 }, { - "depends_on": "supplier", "doctype": "DocField", "fieldname": "contact_email", "fieldtype": "Text", - "hidden": 0, + "hidden": 1, "label": "Contact Email", "print_hide": 1, "read_only": 1 @@ -139,7 +141,8 @@ "fieldname": "items", "fieldtype": "Section Break", "label": "Items", - "oldfieldtype": "Section Break" + "oldfieldtype": "Section Break", + "options": "icon-shopping-cart" }, { "allow_on_submit": 1, @@ -155,8 +158,7 @@ { "doctype": "DocField", "fieldname": "sb_last_purchase", - "fieldtype": "Section Break", - "options": "Simple" + "fieldtype": "Section Break" }, { "doctype": "DocField", @@ -238,7 +240,8 @@ "doctype": "DocField", "fieldname": "price_list_and_currency", "fieldtype": "Section Break", - "label": "Currency & Price List" + "label": "Currency & Price List", + "options": "icon-tag" }, { "doctype": "DocField", @@ -309,6 +312,7 @@ "fieldtype": "Section Break", "label": "Taxes", "oldfieldtype": "Section Break", + "options": "icon-money", "print_hide": 0 }, { @@ -364,7 +368,8 @@ "fieldname": "totals", "fieldtype": "Section Break", "label": "Totals", - "oldfieldtype": "Section Break" + "oldfieldtype": "Section Break", + "options": "icon-money" }, { "doctype": "DocField", @@ -523,7 +528,8 @@ "fieldname": "terms_section_break", "fieldtype": "Section Break", "label": "Terms and Conditions", - "oldfieldtype": "Section Break" + "oldfieldtype": "Section Break", + "options": "icon-legal" }, { "doctype": "DocField", @@ -555,7 +561,8 @@ "doctype": "DocField", "fieldname": "contact_section", "fieldtype": "Section Break", - "label": "Contact Info" + "label": "Contact Info", + "options": "icon-bullhorn" }, { "doctype": "DocField", @@ -759,8 +766,9 @@ "doctype": "DocField", "fieldname": "raw_material_details", "fieldtype": "Section Break", - "label": "Raw Material Details", + "label": "Raw Materials Supplied", "oldfieldtype": "Section Break", + "options": "icon-truck", "print_hide": 1 }, { diff --git a/buying/doctype/supplier/supplier.js b/buying/doctype/supplier/supplier.js index 901b3cc4fa..5374d506fc 100644 --- a/buying/doctype/supplier/supplier.js +++ b/buying/doctype/supplier/supplier.js @@ -45,7 +45,7 @@ cur_frm.cscript.refresh = function(doc,dt,dn) { } cur_frm.cscript.make_dashboard = function(doc) { - cur_frm.dashboard.wrapper.empty().toggle(doc.__islocal ? false : true); + cur_frm.dashboard.reset(); if(doc.__islocal) return; cur_frm.dashboard.set_headline('Loading...') diff --git a/buying/doctype/supplier/supplier.txt b/buying/doctype/supplier/supplier.txt index 95fa717cfb..3d71e1d1db 100644 --- a/buying/doctype/supplier/supplier.txt +++ b/buying/doctype/supplier/supplier.txt @@ -2,7 +2,7 @@ { "creation": "2013-01-10 16:34:11", "docstatus": 0, - "modified": "2013-01-29 14:35:42", + "modified": "2013-07-04 10:13:19", "modified_by": "Administrator", "owner": "Administrator" }, @@ -46,7 +46,8 @@ "fieldname": "basic_info", "fieldtype": "Section Break", "label": "Basic Info", - "oldfieldtype": "Section Break" + "oldfieldtype": "Section Break", + "options": "icon-user" }, { "doctype": "DocField", @@ -91,7 +92,8 @@ "fieldname": "address_contacts", "fieldtype": "Section Break", "label": "Address & Contacts", - "oldfieldtype": "Column Break" + "oldfieldtype": "Column Break", + "options": "icon-map-marker" }, { "depends_on": "eval:doc.__islocal", @@ -132,7 +134,9 @@ { "doctype": "DocField", "fieldname": "communication_history", - "fieldtype": "Section Break" + "fieldtype": "Section Break", + "label": "Communication History", + "options": "icon-comments" }, { "doctype": "DocField", @@ -145,7 +149,8 @@ "fieldname": "more_info", "fieldtype": "Section Break", "label": "More Info", - "oldfieldtype": "Section Break" + "oldfieldtype": "Section Break", + "options": "icon-file-text" }, { "description": "Enter the company name under which Account Head will be created for this Supplier", diff --git a/buying/doctype/supplier_quotation/supplier_quotation.txt b/buying/doctype/supplier_quotation/supplier_quotation.txt index 072b146871..d9ecf602de 100644 --- a/buying/doctype/supplier_quotation/supplier_quotation.txt +++ b/buying/doctype/supplier_quotation/supplier_quotation.txt @@ -2,7 +2,7 @@ { "creation": "2013-05-21 16:16:45", "docstatus": 0, - "modified": "2013-06-11 16:05:53", + "modified": "2013-07-04 10:51:05", "modified_by": "Administrator", "owner": "Administrator" }, @@ -39,6 +39,13 @@ "doctype": "DocType", "name": "Supplier Quotation" }, + { + "doctype": "DocField", + "fieldname": "supplier_section", + "fieldtype": "Section Break", + "label": "Supplier", + "options": "icon-user" + }, { "description": "To manage multiple series please go to Setup > Manage Series", "doctype": "DocField", @@ -67,7 +74,6 @@ "search_index": 1 }, { - "depends_on": "supplier", "doctype": "DocField", "fieldname": "supplier_name", "fieldtype": "Data", @@ -77,38 +83,34 @@ "read_only": 1 }, { - "depends_on": "supplier", "doctype": "DocField", "fieldname": "address_display", "fieldtype": "Small Text", - "hidden": 0, + "hidden": 1, "label": "Address", "read_only": 1 }, { - "depends_on": "supplier", "doctype": "DocField", "fieldname": "contact_display", "fieldtype": "Small Text", - "hidden": 0, + "hidden": 1, "label": "Contact", "read_only": 1 }, { - "depends_on": "supplier", "doctype": "DocField", "fieldname": "contact_mobile", "fieldtype": "Text", - "hidden": 0, + "hidden": 1, "label": "Mobile No", "read_only": 1 }, { - "depends_on": "supplier", "doctype": "DocField", "fieldname": "contact_email", "fieldtype": "Text", - "hidden": 0, + "hidden": 1, "label": "Contact Email", "print_hide": 1, "read_only": 1 @@ -139,7 +141,8 @@ "fieldname": "items", "fieldtype": "Section Break", "label": "Items", - "oldfieldtype": "Section Break" + "oldfieldtype": "Section Break", + "options": "icon-shopping-cart" }, { "allow_on_submit": 1, @@ -155,8 +158,7 @@ { "doctype": "DocField", "fieldname": "section_break0", - "fieldtype": "Section Break", - "options": "Simple" + "fieldtype": "Section Break" }, { "doctype": "DocField", @@ -168,8 +170,7 @@ { "doctype": "DocField", "fieldname": "section_break_14", - "fieldtype": "Section Break", - "options": "Simple" + "fieldtype": "Section Break" }, { "description": "You can make a purchase order from multiple Material Requests. Select Material Requests one by one and click on the button below.", @@ -197,7 +198,8 @@ "doctype": "DocField", "fieldname": "currency_price_list", "fieldtype": "Section Break", - "label": "Currency & Price List" + "label": "Currency & Price List", + "options": "icon-tag" }, { "description": "Supplier's currency", @@ -264,7 +266,8 @@ "fieldname": "taxes", "fieldtype": "Section Break", "label": "Taxes", - "oldfieldtype": "Section Break" + "oldfieldtype": "Section Break", + "options": "icon-money" }, { "description": "If you have created a standard template in Purchase Taxes and Charges Master, select one and click on the button below.", @@ -319,7 +322,8 @@ "fieldname": "totals", "fieldtype": "Section Break", "label": "Totals", - "oldfieldtype": "Section Break" + "oldfieldtype": "Section Break", + "options": "icon-money" }, { "doctype": "DocField", @@ -478,7 +482,8 @@ "fieldname": "terms_section_break", "fieldtype": "Section Break", "label": "Terms and Conditions", - "oldfieldtype": "Section Break" + "oldfieldtype": "Section Break", + "options": "icon-legal" }, { "allow_on_submit": 1, @@ -512,7 +517,7 @@ "doctype": "DocField", "fieldname": "terms", "fieldtype": "Text Editor", - "label": "Terms and Conditions1", + "label": "Terms and Conditions", "oldfieldname": "terms", "oldfieldtype": "Text Editor" }, @@ -521,7 +526,8 @@ "doctype": "DocField", "fieldname": "contact_section", "fieldtype": "Section Break", - "label": "Contact Info" + "label": "Contact Info", + "options": "icon-bullhorn" }, { "doctype": "DocField", @@ -546,7 +552,8 @@ "fieldname": "more_info", "fieldtype": "Section Break", "label": "More Info", - "oldfieldtype": "Section Break" + "oldfieldtype": "Section Break", + "options": "icon-file-text" }, { "doctype": "DocField", @@ -585,6 +592,11 @@ "read_only": 1, "report_hide": 0 }, + { + "doctype": "DocField", + "fieldname": "column_break_57", + "fieldtype": "Column Break" + }, { "description": "Select the relevant company name if you have multiple companies", "doctype": "DocField", diff --git a/selling/doctype/lead/lead.js b/selling/doctype/lead/lead.js index 3aea4c8582..1b515053b6 100644 --- a/selling/doctype/lead/lead.js +++ b/selling/doctype/lead/lead.js @@ -99,38 +99,10 @@ erpnext.LeadController = wn.ui.form.Controller.extend({ $.extend(cur_frm.cscript, new erpnext.LeadController({frm: cur_frm})); cur_frm.cscript['Create Customer'] = function(){ - var doc = cur_frm.doc; - $c('runserverobj',args={ 'method':'check_status', 'docs':wn.model.compress(make_doclist(doc.doctype, doc.name))}, - function(r,rt){ - if(r.message == 'Converted'){ - msgprint("This lead is already converted to customer"); - } - else{ - n = wn.model.make_new_doc_and_get_name("Customer"); - $c('dt_map', args={ - 'docs':wn.model.compress([locals["Customer"][n]]), - 'from_doctype':'Lead', - 'to_doctype':'Customer', - 'from_docname':doc.name, - 'from_to_list':"[['Lead', 'Customer']]" - }, - function(r,rt) { - wn.model.with_doctype("Customer", function() { - var customer = wn.model.get_doc("Customer", n); - var customer_copy = $.extend({}, customer); - - var updated = wn.model.set_default_values(customer_copy); - $.each(updated, function(i, f) { - if(!customer[f]) customer[f] = customer_copy[f]; - }); - - loaddoc("Customer", n); - }); - } - ); - } - } - ); + wn.model.open_mapped_doc({ + method: "selling.doctype.lead.lead.make_customer", + source_name: cur_frm.doc.name + }) } // Create New Opportunity diff --git a/selling/doctype/lead/lead.py b/selling/doctype/lead/lead.py index 928eda7d85..c702375906 100644 --- a/selling/doctype/lead/lead.py +++ b/selling/doctype/lead/lead.py @@ -95,4 +95,24 @@ class DocType(SellingController): webnotes.conn.sql("""update `tabSupport Ticket` set lead='' where lead=%s""", self.doc.name) - self.delete_events() \ No newline at end of file + self.delete_events() + +@webnotes.whitelist() +def make_customer(source_name, target_doclist=None): + from webnotes.model.mapper import get_mapped_doclist + + if target_doclist: + target_doclist = json.loads(target_doclist) + + doclist = get_mapped_doclist("Lead", source_name, + {"Lead": { + "doctype": "Customer", + "field_map": { + "name": "lead_name", + "company_name": "customer_name", + "contact_no": "phone_1", + "fax": "fax_1" + } + }}) + + return [d.fields for d in doclist] \ No newline at end of file diff --git a/selling/doctype/lead/test_lead.py b/selling/doctype/lead/test_lead.py index e525547c24..3fc177f82d 100644 --- a/selling/doctype/lead/test_lead.py +++ b/selling/doctype/lead/test_lead.py @@ -1,3 +1,5 @@ +from __future__ import unicode_literals + test_records = [ [{"doctype":"Lead", "lead_name": "_Test Lead", "status":"Open", "email_id":"test_lead@example.com"}], @@ -8,3 +10,17 @@ test_records = [ [{"doctype":"Lead", "lead_name": "_Test Lead 3", "status":"Converted", "email_id":"test_lead3@example.com"}], ] + +import webnotes +import unittest + +class TestLead(unittest.TestCase): + def test_make_customer(self): + from selling.doctype.lead.lead import make_customer + + customer = make_customer("_T-Lead-00001") + self.assertEquals(customer[0]["doctype"], "Customer") + self.assertEquals(customer[0]["lead_name"], "_T-Lead-00001") + + webnotes.bean(customer).insert() + \ No newline at end of file diff --git a/selling/doctype/quotation/quotation.py b/selling/doctype/quotation/quotation.py index 0cbc76e1ea..24242dec8e 100644 --- a/selling/doctype/quotation/quotation.py +++ b/selling/doctype/quotation/quotation.py @@ -154,8 +154,11 @@ class DocType(SellingController): super(DocType, self).validate() import utilities - utilities.validate_status(self.doc.status, ["Draft", "Submitted", - "Order Confirmed", "Order Lost", "Cancelled"]) + if not self.doc.status: + self.doc.status = "Draft" + else: + utilities.validate_status(self.doc.status, ["Draft", "Submitted", + "Order Confirmed", "Order Lost", "Cancelled"]) self.validate_fiscal_year() self.set_last_contact_date() diff --git a/selling/doctype/quotation/quotation.txt b/selling/doctype/quotation/quotation.txt index cfe0881208..5aa3aa3c50 100644 --- a/selling/doctype/quotation/quotation.txt +++ b/selling/doctype/quotation/quotation.txt @@ -2,7 +2,7 @@ { "creation": "2013-05-24 19:29:08", "docstatus": 0, - "modified": "2013-07-03 16:12:44", + "modified": "2013-07-04 10:56:10", "modified_by": "Administrator", "owner": "Administrator" }, @@ -114,7 +114,6 @@ "read_only": 0 }, { - "depends_on": "customer", "doctype": "DocField", "fieldname": "customer_name", "fieldtype": "Data", diff --git a/selling/doctype/quotation/test_quotation.py b/selling/doctype/quotation/test_quotation.py new file mode 100644 index 0000000000..2c9264dd07 --- /dev/null +++ b/selling/doctype/quotation/test_quotation.py @@ -0,0 +1,49 @@ +import webnotes +from webnotes.utils import flt +import unittest + +test_dependencies = ["Sales BOM"] + +class TestLead(unittest.TestCase): + def test_make_sales_order(self): + lead = webnotes.bean("Lead", "_T-Lead-00001") + lead.make_controller() + customer = lead.controller.make_customer() + self.assertEquals(customer[0].doctype, "Customer") + self.assertEquals(customer[0].lead_name, lead.doc.name) + webnotes.bean(customer).insert() + + +test_records = [ + [ + { + "company": "_Test Company", + "conversion_rate": 1.0, + "currency": "INR", + "customer": "_Test Customer", + "customer_name": "_Test Customer", + "customer_group": "_Test Customer Group", + "doctype": "Quotation", + "fiscal_year": "_Test Fiscal Year 2013", + "order_type": "Sales", + "plc_conversion_rate": 1.0, + "price_list_currency": "INR", + "price_list_name": "_Test Price List", + "territory": "_Test Territory", + "transaction_date": "2013-02-21", + "grand_total": 1000.0, + "grand_total_export": 1000.0, + }, + { + "description": "CPU", + "doctype": "Quotation Item", + "item_code": "_Test Item Home Desktop 100", + "item_name": "CPU", + "parentfield": "quotation_details", + "qty": 10.0, + "basic_rate": 100.0, + "export_rate": 100.0, + "amount": 1000.0, + } + ], +] \ No newline at end of file diff --git a/selling/doctype/sales_common/sales_common.js b/selling/doctype/sales_common/sales_common.js index 77e77592e9..5534369b54 100644 --- a/selling/doctype/sales_common/sales_common.js +++ b/selling/doctype/sales_common/sales_common.js @@ -37,6 +37,12 @@ erpnext.selling.SellingController = erpnext.TransactionController.extend({ this.toggle_rounded_total(); }, + refresh: function(doc) { + this.frm.toggle_display("customer_name", + (this.customer_name && this.frm.doc.customer_name!==this.frm.doc.customer)); + this._super(); + }, + customer: function() { var me = this; if(this.frm.doc.customer || this.frm.doc.debit_to) { diff --git a/selling/doctype/sales_order/sales_order.txt b/selling/doctype/sales_order/sales_order.txt index 2a78bf79b3..6ac7565042 100644 --- a/selling/doctype/sales_order/sales_order.txt +++ b/selling/doctype/sales_order/sales_order.txt @@ -2,7 +2,7 @@ { "creation": "2013-06-18 12:39:59", "docstatus": 0, - "modified": "2013-07-03 16:12:26", + "modified": "2013-07-04 10:56:35", "modified_by": "Administrator", "owner": "Administrator" }, @@ -84,7 +84,6 @@ "search_index": 1 }, { - "depends_on": "customer", "doctype": "DocField", "fieldname": "customer_name", "fieldtype": "Data", diff --git a/stock/doctype/item/item.js b/stock/doctype/item/item.js index 1dcd038f46..2cc0b07971 100644 --- a/stock/doctype/item/item.js +++ b/stock/doctype/item/item.js @@ -21,6 +21,8 @@ cur_frm.cscript.refresh = function(doc) { // make sensitive fields(has_serial_no, is_stock_item, valuation_method) // read only if any stock ledger entry exists + cur_frm.cscript.make_dashboard() + cur_frm.toggle_display("naming_series", sys_defaults.item_naming_by=="Naming Series" && doc.__islocal) cur_frm.toggle_display("item_code", sys_defaults.item_naming_by!="Naming Series" @@ -36,6 +38,12 @@ cur_frm.cscript.refresh = function(doc) { } } +cur_frm.cscript.make_dashboard = function() { + cur_frm.dashboard.reset(); + if(doc.__islocal) + return; +} + cur_frm.cscript.item_code = function(doc) { if(!doc.item_name) cur_frm.set_value("item_name", doc.item_code); if(!doc.description) cur_frm.set_value("description", doc.item_code); diff --git a/stock/doctype/material_request/material_request.js b/stock/doctype/material_request/material_request.js index 6c7b2a7b88..5c2eed5068 100644 --- a/stock/doctype/material_request/material_request.js +++ b/stock/doctype/material_request/material_request.js @@ -24,6 +24,16 @@ erpnext.buying.MaterialRequestController = erpnext.buying.BuyingController.exten refresh: function(doc) { this._super(); + // dashboard + cur_frm.dashboard.reset(); + if(doc.docstatus===1) { + if(doc.status==="Stopped") { + cur_frm.dashboard.set_headline_alert(wn._("Stopped"), "alert-danger", "icon-stop") + } + cur_frm.dashboard.add_progress(cint(doc.per_ordered) + "% " + + wn._("Fulfilled"), cint(doc.per_ordered)); + } + if(doc.docstatus == 1 && doc.status != 'Stopped'){ if(doc.material_request_type === "Purchase") cur_frm.add_custom_button("Make Supplier Quotation", cur_frm.cscript.make_supplier_quotation); diff --git a/stock/doctype/material_request/material_request.txt b/stock/doctype/material_request/material_request.txt index e7bad7334b..7ebb1974e4 100644 --- a/stock/doctype/material_request/material_request.txt +++ b/stock/doctype/material_request/material_request.txt @@ -2,7 +2,7 @@ { "creation": "2013-03-07 14:48:38", "docstatus": 0, - "modified": "2013-06-11 16:16:36", + "modified": "2013-07-04 10:24:53", "modified_by": "Administrator", "owner": "Administrator" }, @@ -44,6 +44,13 @@ "doctype": "DocType", "name": "Material Request" }, + { + "doctype": "DocField", + "fieldname": "type_section", + "fieldtype": "Section Break", + "label": "Type", + "options": "icon-pushpin" + }, { "doctype": "DocField", "fieldname": "material_request_type", @@ -76,7 +83,8 @@ "fieldname": "items", "fieldtype": "Section Break", "label": "Items", - "oldfieldtype": "Section Break" + "oldfieldtype": "Section Break", + "options": "icon-shopping-cart" }, { "allow_on_submit": 0, @@ -92,8 +100,7 @@ { "doctype": "DocField", "fieldname": "section_break1", - "fieldtype": "Section Break", - "options": "Simple" + "fieldtype": "Section Break" }, { "doctype": "DocField", @@ -131,12 +138,12 @@ }, { "default": "Give additional details about the indent.", - "description": "Filing in Additional Information about the Material Request will help you analyze your data better.", "doctype": "DocField", "fieldname": "more_info", "fieldtype": "Section Break", "label": "More Info", - "oldfieldtype": "Section Break" + "oldfieldtype": "Section Break", + "options": "icon-file-text" }, { "doctype": "DocField", @@ -287,7 +294,8 @@ "fieldname": "terms_section_break", "fieldtype": "Section Break", "label": "Terms and Conditions", - "oldfieldtype": "Section Break" + "oldfieldtype": "Section Break", + "options": "icon-legal" }, { "doctype": "DocField", diff --git a/stock/page/stock_home/stock_home.js b/stock/page/stock_home/stock_home.js index b17784fde4..a59fe07438 100644 --- a/stock/page/stock_home/stock_home.js +++ b/stock/page/stock_home/stock_home.js @@ -7,6 +7,11 @@ wn.module_page["Stock"] = [ top: true, icon: "icon-copy", items: [ + { + label: wn._("Item"), + description: wn._("All Products or Services."), + doctype:"Item" + }, { label: wn._("Material Request"), description: wn._("Requests for items."), @@ -33,11 +38,6 @@ wn.module_page["Stock"] = [ title: wn._("Masters"), icon: "icon-book", items: [ - { - label: wn._("Item"), - description: wn._("All Products or Services."), - doctype:"Item" - }, { label: wn._("Serial No"), description: wn._("Single unit of an Item."), From 080fcc8fcd990c35096f1b3796f4edc0fe3f1449 Mon Sep 17 00:00:00 2001 From: Rushabh Mehta Date: Thu, 4 Jul 2013 15:27:04 +0530 Subject: [PATCH 6/8] [mapper] quotation-sales order for mapping in parent + child items --- controllers/selling_controller.py | 4 ++- selling/doctype/lead/lead.py | 2 +- selling/doctype/quotation/quotation.js | 18 +++-------- selling/doctype/quotation/quotation.py | 34 +++++++++++++++++++++ selling/doctype/quotation/test_quotation.py | 30 +++++++++++++----- selling/doctype/sales_order/sales_order.py | 3 +- 6 files changed, 66 insertions(+), 25 deletions(-) diff --git a/controllers/selling_controller.py b/controllers/selling_controller.py index 087df344c8..140e0c0088 100644 --- a/controllers/selling_controller.py +++ b/controllers/selling_controller.py @@ -262,7 +262,9 @@ class SellingController(StockController): def validate_order_type(self): valid_types = ["Sales", "Maintenance", "Shopping Cart"] - if self.doc.order_type not in valid_types: + if not self.doc.order_type: + self.doc.order_type = "Sales" + elif self.doc.order_type not in valid_types: msgprint(_(self.meta.get_label("order_type")) + " " + _("must be one of") + ": " + comma_or(valid_types), raise_exception=True) diff --git a/selling/doctype/lead/lead.py b/selling/doctype/lead/lead.py index c702375906..3a3d8e504f 100644 --- a/selling/doctype/lead/lead.py +++ b/selling/doctype/lead/lead.py @@ -113,6 +113,6 @@ def make_customer(source_name, target_doclist=None): "contact_no": "phone_1", "fax": "fax_1" } - }}) + }}, target_doclist) return [d.fields for d in doclist] \ No newline at end of file diff --git a/selling/doctype/quotation/quotation.js b/selling/doctype/quotation/quotation.js index 66d4d0bddd..259c8109f2 100644 --- a/selling/doctype/quotation/quotation.js +++ b/selling/doctype/quotation/quotation.js @@ -119,20 +119,10 @@ cur_frm.fields_dict['enq_no'].get_query = function(doc,cdt,cdn){ // Make Sales Order // ===================================================================================== cur_frm.cscript['Make Sales Order'] = function() { - var doc = cur_frm.doc; - - if (doc.docstatus == 1) { - var n = wn.model.make_new_doc_and_get_name("Sales Order"); - $c('dt_map', args={ - 'docs':wn.model.compress([locals["Sales Order"][n]]), - 'from_doctype':'Quotation', - 'to_doctype':'Sales Order', - 'from_docname':doc.name, - 'from_to_list':"[['Quotation', 'Sales Order'], ['Quotation Item', 'Sales Order Item'],['Sales Taxes and Charges','Sales Taxes and Charges'], ['Sales Team', 'Sales Team'], ['TC Detail', 'TC Detail']]" - }, function(r,rt) { - loaddoc("Sales Order", n); - }); - } + wn.model.open_mapped_doc({ + method: "selling.doctype.quotation.quotation.make_sales_order", + source_name: cur_frm.doc.name + }) } //pull enquiry details diff --git a/selling/doctype/quotation/quotation.py b/selling/doctype/quotation/quotation.py index 24242dec8e..1adce2028e 100644 --- a/selling/doctype/quotation/quotation.py +++ b/selling/doctype/quotation/quotation.py @@ -250,3 +250,37 @@ class DocType(SellingController): sql("delete from `tabCommunication Log` where parent = '%s'"%self.doc.name) for d in getlist(self.doclist, 'follow_up'): d.save() + +@webnotes.whitelist() +def make_sales_order(source_name, target_doclist=None): + from webnotes.model.mapper import get_mapped_doclist + + if target_doclist: + target_doclist = json.loads(target_doclist) + + doclist = get_mapped_doclist("Quotation", source_name, { + "Quotation": { + "doctype": "Sales Order", + "field_map": { + "name": "quotation_no", + "transaction_date": "quotation_date" + }, + "validation": { + "docstatus": ["=", 1] + } + }, + "Quotation Item": { + "doctype": "Sales Order Item", + "field_map": { + "parent": "prevdoc_docname" + } + }, + "Sales Taxes and Charges": { + "doctype": "Sales Taxes and Charges", + }, + "Sales Team": { + "doctype": "Sales Team", + } + }, target_doclist) + + return [d.fields for d in doclist] \ No newline at end of file diff --git a/selling/doctype/quotation/test_quotation.py b/selling/doctype/quotation/test_quotation.py index 2c9264dd07..de609b8730 100644 --- a/selling/doctype/quotation/test_quotation.py +++ b/selling/doctype/quotation/test_quotation.py @@ -1,17 +1,31 @@ -import webnotes +import webnotes, json from webnotes.utils import flt import unittest test_dependencies = ["Sales BOM"] -class TestLead(unittest.TestCase): +class TestQuotation(unittest.TestCase): def test_make_sales_order(self): - lead = webnotes.bean("Lead", "_T-Lead-00001") - lead.make_controller() - customer = lead.controller.make_customer() - self.assertEquals(customer[0].doctype, "Customer") - self.assertEquals(customer[0].lead_name, lead.doc.name) - webnotes.bean(customer).insert() + from selling.doctype.quotation.quotation import make_sales_order + + self.assertRaises(webnotes.ValidationError, make_sales_order, "_T-Quotation-00001") + + quotation = webnotes.bean("Quotation","_T-Quotation-00001") + quotation.submit() + + sales_order = make_sales_order("_T-Quotation-00001") + + self.assertEquals(sales_order[0]["doctype"], "Sales Order") + self.assertEquals(len(sales_order), 2) + self.assertEquals(sales_order[1]["doctype"], "Sales Order Item") + self.assertEquals(sales_order[1]["prevdoc_docname"], "_T-Quotation-00001") + self.assertEquals(sales_order[0]["customer"], "_Test Customer") + + sales_order[0]["delivery_date"] = "2014-01-01" + + + webnotes.print_messages = True + webnotes.bean(sales_order).insert() test_records = [ diff --git a/selling/doctype/sales_order/sales_order.py b/selling/doctype/sales_order/sales_order.py index 461965a502..ec365a290c 100644 --- a/selling/doctype/sales_order/sales_order.py +++ b/selling/doctype/sales_order/sales_order.py @@ -167,7 +167,7 @@ class DocType(SellingController): def validate_order_type(self): super(DocType, self).validate_order_type() - #validate delivery date + def validate_delivery_date(self): if self.doc.order_type == 'Sales' and not self.doc.delivery_date: msgprint("Please enter 'Expected Delivery Date'") raise Exception @@ -186,6 +186,7 @@ class DocType(SellingController): self.validate_fiscal_year() self.validate_order_type() + self.validate_delivery_date() self.validate_mandatory() self.validate_proj_cust() self.validate_po() From 212de6a08499b043950cc8801bff9a44a3231147 Mon Sep 17 00:00:00 2001 From: Rushabh Mehta Date: Thu, 4 Jul 2013 16:29:03 +0530 Subject: [PATCH 7/8] [mapper] added sales order > material request, added postprocess function --- selling/doctype/lead/lead.js | 28 +++--------------- selling/doctype/lead/lead.py | 21 +++++++++++--- selling/doctype/sales_order/sales_order.js | 19 +++--------- selling/doctype/sales_order/sales_order.py | 29 ++++++++++++++++++- .../doctype/sales_order/test_sales_order.py | 13 +++++++++ 5 files changed, 66 insertions(+), 44 deletions(-) diff --git a/selling/doctype/lead/lead.js b/selling/doctype/lead/lead.js index 1b515053b6..b3c200de02 100644 --- a/selling/doctype/lead/lead.js +++ b/selling/doctype/lead/lead.js @@ -105,29 +105,9 @@ cur_frm.cscript['Create Customer'] = function(){ }) } -// Create New Opportunity -// =============================================================== cur_frm.cscript['Create Opportunity'] = function(){ - var doc = cur_frm.doc; - $c('runserverobj',args={ 'method':'check_status', 'docs':wn.model.compress(make_doclist(doc.doctype, doc.name))}, - function(r,rt){ - if(r.message == 'Converted'){ - msgprint("This lead is now converted to customer. Please create enquiry on behalf of customer"); - } - else{ - n = wn.model.make_new_doc_and_get_name("Opportunity"); - $c('dt_map', args={ - 'docs':wn.model.compress([locals["Opportunity"][n]]), - 'from_doctype':'Lead', - 'to_doctype':'Opportunity', - 'from_docname':doc.name, - 'from_to_list':"[['Lead', 'Opportunity']]" - } - , function(r,rt) { - loaddoc("Opportunity", n); - } - ); - } - } - ); + wn.model.open_mapped_doc({ + method: "selling.doctype.lead.lead.make_opportunity", + source_name: cur_frm.doc.name + }) } \ No newline at end of file diff --git a/selling/doctype/lead/lead.py b/selling/doctype/lead/lead.py index 3a3d8e504f..4dde84a579 100644 --- a/selling/doctype/lead/lead.py +++ b/selling/doctype/lead/lead.py @@ -100,10 +100,7 @@ class DocType(SellingController): @webnotes.whitelist() def make_customer(source_name, target_doclist=None): from webnotes.model.mapper import get_mapped_doclist - - if target_doclist: - target_doclist = json.loads(target_doclist) - + doclist = get_mapped_doclist("Lead", source_name, {"Lead": { "doctype": "Customer", @@ -115,4 +112,20 @@ def make_customer(source_name, target_doclist=None): } }}, target_doclist) + return [d.fields for d in doclist] + +@webnotes.whitelist() +def make_opportunity(source_name, target_doclist=None): + from webnotes.model.mapper import get_mapped_doclist + + doclist = get_mapped_doclist("Lead", source_name, + {"Lead": { + "doctype": "Opportunity", + "field_map": { + "campaign_name": "campaign", + "doctype": "enquiry_from", + "name": "lead", + } + }}, target_doclist) + return [d.fields for d in doclist] \ No newline at end of file diff --git a/selling/doctype/sales_order/sales_order.js b/selling/doctype/sales_order/sales_order.js index c4d50cc045..6ed5f1cbed 100644 --- a/selling/doctype/sales_order/sales_order.js +++ b/selling/doctype/sales_order/sales_order.js @@ -195,21 +195,10 @@ cur_frm.cscript.make_maintenance_visit = function() { } cur_frm.cscript['Make Material Request'] = function() { - var doc = cur_frm.doc; - if (doc.docstatus == 1) { - n = wn.model.make_new_doc_and_get_name("Material Request"); - $c('dt_map', args={ - 'docs':wn.model.compress([locals["Material Request"][n]]), - 'from_doctype':'Sales Order', - 'to_doctype':'Material Request', - 'from_docname':doc.name, - 'from_to_list':"[['Sales Order', 'Material Request'], ['Sales Order Item', 'Material Request Item']]" - } - , function(r,rt) { - loaddoc("Material Request", n); - } - ); - } + wn.model.open_mapped_doc({ + method: "selling.doctype.sales_order.sales_order.make_material_request", + source_name: cur_frm.doc.name + }) } diff --git a/selling/doctype/sales_order/sales_order.py b/selling/doctype/sales_order/sales_order.py index ec365a290c..0c9237a465 100644 --- a/selling/doctype/sales_order/sales_order.py +++ b/selling/doctype/sales_order/sales_order.py @@ -378,4 +378,31 @@ def get_currency_and_number_format(): "currency": webnotes.conn.get_default("currency"), "currency_symbols": json.dumps(dict(webnotes.conn.sql("""select name, symbol from tabCurrency where ifnull(enabled,0)=1"""))) - } \ No newline at end of file + } + +@webnotes.whitelist() +def make_material_request(source_name, target_doclist=None): + from webnotes.model.mapper import get_mapped_doclist + + def postprocess(source, doclist): + doclist[0].material_request_type = "Purchase" + + doclist = get_mapped_doclist("Sales Order", source_name, { + "Sales Order": { + "doctype": "Material Request", + "validation": { + "docstatus": ["=", 1] + } + }, + "Sales Order Item": { + "doctype": "Material Request Item", + "field_map": { + "parent": "sales_order_no", + "reserved_warehouse": "warehouse", + "stock_uom": "uom" + } + } + }, target_doclist, postprocess) + + return [d.fields for d in doclist] + \ No newline at end of file diff --git a/selling/doctype/sales_order/test_sales_order.py b/selling/doctype/sales_order/test_sales_order.py index 40a10b439c..7678f37c4c 100644 --- a/selling/doctype/sales_order/test_sales_order.py +++ b/selling/doctype/sales_order/test_sales_order.py @@ -3,6 +3,19 @@ from webnotes.utils import flt import unittest class TestSalesOrder(unittest.TestCase): + def test_make_material_request(self): + from selling.doctype.sales_order.sales_order import make_material_request + + self.assertRaises(webnotes.ValidationError, make_material_request, + "_T-Sales Order-00001") + + sales_order = webnotes.bean("Sales Order", "_T-Sales Order-00001") + sales_order.submit() + mr = make_material_request("_T-Sales Order-00001") + + self.assertEquals(mr[0]["material_request_type"], "Purchase") + self.assertEquals(len(mr), len(sales_order.doclist)) + def create_so(self, so_doclist = None): if not so_doclist: so_doclist =test_records[0] From 37805ca4155bfd499c9b9ac38e6635dd727ecfd5 Mon Sep 17 00:00:00 2001 From: Rushabh Mehta Date: Thu, 4 Jul 2013 17:03:02 +0530 Subject: [PATCH 8/8] [mapper] sales order-delivery note, added postprocess function in each doc for mapper.py --- selling/doctype/sales_order/sales_order.js | 19 ++------ selling/doctype/sales_order/sales_order.py | 43 ++++++++++++++++++- .../doctype/sales_order/test_sales_order.py | 25 +++++++++-- stock/doctype/delivery_note/delivery_note.js | 15 ++----- stock/doctype/delivery_note/delivery_note.py | 13 ------ .../material_request/material_request.js | 12 ++++-- 6 files changed, 80 insertions(+), 47 deletions(-) diff --git a/selling/doctype/sales_order/sales_order.js b/selling/doctype/sales_order/sales_order.js index 6ed5f1cbed..daedfab564 100644 --- a/selling/doctype/sales_order/sales_order.js +++ b/selling/doctype/sales_order/sales_order.js @@ -203,21 +203,10 @@ cur_frm.cscript['Make Material Request'] = function() { cur_frm.cscript['Make Delivery Note'] = function() { - var doc = cur_frm.doc; - if (doc.docstatus == 1) { - n = wn.model.make_new_doc_and_get_name("Delivery Note"); - $c('dt_map', args={ - 'docs':wn.model.compress([locals["Delivery Note"][n]]), - 'from_doctype':'Sales Order', - 'to_doctype':'Delivery Note', - 'from_docname':doc.name, - 'from_to_list':"[['Sales Order', 'Delivery Note'], ['Sales Order Item', 'Delivery Note Item'],['Sales Taxes and Charges','Sales Taxes and Charges'],['Sales Team','Sales Team']]" - } - , function(r,rt) { - loaddoc("Delivery Note", n); - } - ); - } + wn.model.open_mapped_doc({ + method: "selling.doctype.sales_order.sales_order.make_delivery_note", + source_name: cur_frm.doc.name + }) } diff --git a/selling/doctype/sales_order/sales_order.py b/selling/doctype/sales_order/sales_order.py index 0c9237a465..019b699c7e 100644 --- a/selling/doctype/sales_order/sales_order.py +++ b/selling/doctype/sales_order/sales_order.py @@ -405,4 +405,45 @@ def make_material_request(source_name, target_doclist=None): }, target_doclist, postprocess) return [d.fields for d in doclist] - \ No newline at end of file + +@webnotes.whitelist() +def make_delivery_note(source_name, target_doclist=None): + from webnotes.model.mapper import get_mapped_doclist + + def update_item(obj, target): + target.amount = (flt(obj.qty) - flt(obj.delivered_qty)) * flt(obj.basic_rate) + target.export_amount = (flt(obj.qty) - flt(obj.delivered_qty)) * flt(obj.export_rate) + target.qty = flt(obj.qty) - flt(obj.delivered_qty) + + doclist = get_mapped_doclist("Sales Order", source_name, { + "Sales Order": { + "doctype": "Delivery Note", + "field_map": { + "name": "sales_order_no", + "shipping_address": "address_display", + "shipping_address_name": "customer_address", + }, + "validation": { + "docstatus": ["=", 1] + } + }, + "Sales Order Item": { + "doctype": "Delivery Note Item", + "field_map": { + "export_rate": "export_rate", + "name": "prevdoc_detail_docname", + "parent": "prevdoc_docname", + "parenttype": "prevdoc_doctype", + "reserved_warehouse": "warehouse" + }, + "postprocess": update_item + }, + "Sales Taxes and Charges": { + "doctype": "Sales Taxes and Charges", + }, + "Sales Team": { + "doctype": "Sales Team", + } + }, target_doclist) + + return [d.fields for d in doclist] diff --git a/selling/doctype/sales_order/test_sales_order.py b/selling/doctype/sales_order/test_sales_order.py index 7678f37c4c..00af81f6d0 100644 --- a/selling/doctype/sales_order/test_sales_order.py +++ b/selling/doctype/sales_order/test_sales_order.py @@ -6,16 +6,33 @@ class TestSalesOrder(unittest.TestCase): def test_make_material_request(self): from selling.doctype.sales_order.sales_order import make_material_request + so = webnotes.bean(copy=test_records[0]).insert() + self.assertRaises(webnotes.ValidationError, make_material_request, - "_T-Sales Order-00001") + so.doc.name) - sales_order = webnotes.bean("Sales Order", "_T-Sales Order-00001") + sales_order = webnotes.bean("Sales Order", so.doc.name) sales_order.submit() - mr = make_material_request("_T-Sales Order-00001") + mr = make_material_request(so.doc.name) self.assertEquals(mr[0]["material_request_type"], "Purchase") self.assertEquals(len(mr), len(sales_order.doclist)) - + + def test_make_delivery_note(self): + from selling.doctype.sales_order.sales_order import make_delivery_note + + so = webnotes.bean(copy=test_records[0]).insert() + + self.assertRaises(webnotes.ValidationError, make_delivery_note, + so.doc.name) + + sales_order = webnotes.bean("Sales Order", so.doc.name) + sales_order.submit() + dn = make_delivery_note(so.doc.name) + + self.assertEquals(dn[0]["doctype"], "Delivery Note") + self.assertEquals(len(dn), len(sales_order.doclist)) + def create_so(self, so_doclist = None): if not so_doclist: so_doclist =test_records[0] diff --git a/stock/doctype/delivery_note/delivery_note.js b/stock/doctype/delivery_note/delivery_note.js index ac2c4e9dba..a0560cf8d2 100644 --- a/stock/doctype/delivery_note/delivery_note.js +++ b/stock/doctype/delivery_note/delivery_note.js @@ -57,17 +57,10 @@ cur_frm.cscript.customer_address = cur_frm.cscript.contact_person = function(doc cur_frm.cscript.get_items = function(doc,dt,dn) { - var callback = function(r,rt){ - var doc = locals[cur_frm.doctype][cur_frm.docname]; - if(r.message){ - doc.sales_order_no = r.message; - if(doc.sales_order_no) { - unhide_field(['customer_address','contact_person','territory','customer_group']); - } - cur_frm.refresh_fields(); - } - } - $c_obj(make_doclist(doc.doctype, doc.name),'pull_sales_order_details','',callback); + wn.model.map_current_doc({ + method: "selling.doctype.sales_order.sales_order.make_delivery_note", + source_name: cur_frm.doc.sales_order_no, + }) } diff --git a/stock/doctype/delivery_note/delivery_note.py b/stock/doctype/delivery_note/delivery_note.py index 30647a1b7a..38cf7bc264 100644 --- a/stock/doctype/delivery_note/delivery_note.py +++ b/stock/doctype/delivery_note/delivery_note.py @@ -63,19 +63,6 @@ class DocType(SellingController): """Get Commission rate of Sales Partner""" return get_obj('Sales Common').get_comm_rate(sales_partner, self) - - def pull_sales_order_details(self): - self.validate_prev_docname() - self.doclist = self.doc.clear_table(self.doclist,'other_charges') - - if self.doc.sales_order_no: - get_obj('DocType Mapper', 'Sales Order-Delivery Note').dt_map('Sales Order', 'Delivery Note', self.doc.sales_order_no, self.doc, self.doclist, "[['Sales Order', 'Delivery Note'],['Sales Order Item', 'Delivery Note Item'],['Sales Taxes and Charges','Sales Taxes and Charges'],['Sales Team','Sales Team']]") - else: - msgprint("Please select Sales Order No. whose details need to be pulled") - - return cstr(self.doc.sales_order_no) - - def validate_prev_docname(self): """Validates that Sales Order is not pulled twice""" for d in getlist(self.doclist, 'delivery_note_details'): diff --git a/stock/doctype/material_request/material_request.js b/stock/doctype/material_request/material_request.js index 5c2eed5068..025f7b5688 100644 --- a/stock/doctype/material_request/material_request.js +++ b/stock/doctype/material_request/material_request.js @@ -102,13 +102,19 @@ cur_frm.cscript['Unstop Material Request'] = function(){ }; cur_frm.cscript['Make Purchase Order'] = function() { - cur_frm.map([["Material Request", "Purchase Order"], ["Material Request Item", "Purchase Order Item"]]); + cur_frm.map([ + ["Material Request", "Purchase Order"], + ["Material Request Item", "Purchase Order Item"]]); }; cur_frm.cscript.make_supplier_quotation = function() { - cur_frm.map([["Material Request", "Supplier Quotation"], ["Material Request Item", "Supplier Quotation Item"]]); + cur_frm.map([ + ["Material Request", "Supplier Quotation"], + ["Material Request Item", "Supplier Quotation Item"]]); }; cur_frm.cscript.make_stock_entry = function() { - cur_frm.map([["Material Request", "Stock Entry"], ["Material Request Item", "Stock Entry Detail"]]); + cur_frm.map([ + ["Material Request", "Stock Entry"], + ["Material Request Item", "Stock Entry Detail"]]); };