From 869913c96baba6125a93815823de28d93fa5843a Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Fri, 28 Jun 2013 15:00:24 +0530 Subject: [PATCH 01/10] [fixes] setup control --- setup/doctype/setup_control/setup_control.py | 2 +- setup/utils.py | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/setup/doctype/setup_control/setup_control.py b/setup/doctype/setup_control/setup_control.py index 0f4f6a1e703..60d295735a0 100644 --- a/setup/doctype/setup_control/setup_control.py +++ b/setup/doctype/setup_control/setup_control.py @@ -271,7 +271,7 @@ def create_territories(): country = webnotes.conn.get_value("Control Panel", None, "country") root_territory = get_root_of("Territory") for name in (country, "Rest Of The World"): - if not webnotes.conn.exists("Territory", name): + if name and not webnotes.conn.exists("Territory", name): webnotes.bean({ "doctype": "Territory", "territory_name": name, diff --git a/setup/utils.py b/setup/utils.py index 04c4527cecb..c343ed1db1e 100644 --- a/setup/utils.py +++ b/setup/utils.py @@ -32,14 +32,15 @@ def get_company_currency(company): def get_root_of(doctype): """Get root element of a DocType with a tree structure""" result = webnotes.conn.sql_list("""select name from `tab%s` - where lft=1 and rgt=(select max(rgt) from `tab%s`)""" % (doctype, doctype)) + where lft=1 and rgt=(select max(rgt) from `tab%s` where docstatus < 2)""" % + (doctype, doctype)) return result[0] if result else None def get_ancestors_of(doctype, name): """Get ancestor elements of a DocType with a tree structure""" lft, rgt = webnotes.conn.get_value(doctype, name, ["lft", "rgt"]) result = webnotes.conn.sql_list("""select name from `tab%s` - where lft<%s and rgt>%s""" % (doctype, "%s", "%s"), (lft, rgt)) + where lft<%s and rgt>%s and docstatus < 2""" % (doctype, "%s", "%s"), (lft, rgt)) return result or None @webnotes.whitelist() From b5e58ffa26f1f738297374106bd432fb28b080b1 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Mon, 1 Jul 2013 12:20:00 +0530 Subject: [PATCH 02/10] [rename with merge] updated on_rename function for item, warehouse, al tree type documents --- accounts/doctype/account/account.py | 21 +++++++++++++++++---- accounts/doctype/cost_center/cost_center.py | 2 ++ stock/doctype/item/item.py | 10 ++++++++-- stock/doctype/warehouse/warehouse.py | 6 ++++++ 4 files changed, 33 insertions(+), 6 deletions(-) diff --git a/accounts/doctype/account/account.py b/accounts/doctype/account/account.py index 2d49f0dad0e..98808f48a38 100644 --- a/accounts/doctype/account/account.py +++ b/accounts/doctype/account/account.py @@ -18,7 +18,7 @@ from __future__ import unicode_literals import webnotes from webnotes.utils import flt, fmt_money -from webnotes import msgprint +from webnotes import msgprint, _ sql = webnotes.conn.sql get_value = webnotes.conn.get_value @@ -196,10 +196,23 @@ class DocType: if parts[-1].lower() != company_abbr.lower(): parts.append(company_abbr) - + # rename account name - account_name = " - ".join(parts[:-1]) - sql("update `tabAccount` set account_name = %s where name = %s", (account_name, old)) + new_account_name = " - ".join(parts[:-1]) + sql("update `tabAccount` set account_name = %s where name = %s", (new_account_name, old)) + + if merge: + new_name = " - ".join(parts) + val = list(webnotes.conn.get_value("Account", new_name, + ["group_or_ledger", "debit_or_credit", "is_pl_account"])) + + if val != [self.doc.group_or_ledger, self.doc.debit_or_credit, self.doc.is_pl_account]: + msgprint(_("""Merging is only possible if following \ + properties are same in both records. + Group or Ledger, Debit or Credit, Is PL Account"""), raise_exception=1) + + from webnotes.utils.nestedset import rebuild_tree + rebuild_tree("Account", "parent_account") return " - ".join(parts) diff --git a/accounts/doctype/cost_center/cost_center.py b/accounts/doctype/cost_center/cost_center.py index e405b4de267..8be14c78c34 100644 --- a/accounts/doctype/cost_center/cost_center.py +++ b/accounts/doctype/cost_center/cost_center.py @@ -98,5 +98,7 @@ class DocType(DocTypeNestedSet): cost_center_name = " - ".join(parts[:-1]) webnotes.conn.sql("update `tabCost Center` set cost_center_name = %s where name = %s", \ (cost_center_name, old)) + + super(DocType, self).on_rename(new, old, merge, "group_or_ledger") return " - ".join(parts) diff --git a/stock/doctype/item/item.py b/stock/doctype/item/item.py index d743a980057..276f6607fc7 100644 --- a/stock/doctype/item/item.py +++ b/stock/doctype/item/item.py @@ -280,8 +280,14 @@ class DocType(DocListController): from webnotes.webutils import clear_cache clear_cache(self.doc.page_name) - def on_rename(self,newdn,olddn, merge=False): + def on_rename(self, newdn, olddn, merge=False): webnotes.conn.sql("update tabItem set item_code = %s where name = %s", (newdn, olddn)) if self.doc.page_name: from webnotes.webutils import clear_cache - clear_cache(self.doc.page_name) \ No newline at end of file + clear_cache(self.doc.page_name) + + if merge: + from stock.stock_ledger import update_entries_after + for wh in webnotes.conn.sql("""select warehouse from `tabBin` + where item_code=%s""", newdn): + update_entries_after({"item_code": newdn, "warehouse": wh}) \ No newline at end of file diff --git a/stock/doctype/warehouse/warehouse.py b/stock/doctype/warehouse/warehouse.py index 264e459e564..6f32e152edb 100644 --- a/stock/doctype/warehouse/warehouse.py +++ b/stock/doctype/warehouse/warehouse.py @@ -204,3 +204,9 @@ class DocType: else: sql("delete from `tabStock Ledger Entry` where warehouse = %s", self.doc.name) + def on_rename(self, newdn, olddn, merge=False): + if merge: + from stock.stock_ledger import update_entries_after + for item_code in webnotes.conn.sql("""select item_code from `tabBin` + where warehouse=%s""", newdn): + update_entries_after({"item_code": item_code, "warehouse": newdn}) From 3f30e3132bcf5076379cb3742cf082387498778b Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Thu, 4 Jul 2013 14:36:16 +0530 Subject: [PATCH 03/10] [mapper] reload --- patches/patch_list.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/patches/patch_list.py b/patches/patch_list.py index 4955c75e6c9..fc4fd738fef 100644 --- a/patches/patch_list.py +++ b/patches/patch_list.py @@ -243,4 +243,6 @@ patch_list = [ "patches.june_2013.p04_fix_event_for_lead_oppty_project", "patches.june_2013.p05_remove_search_criteria_reports", "execute:webnotes.delete_doc('DocType', 'Update Delivery Date')", + "execute:webnotes.reload_doc('accounts', 'DocType Mapper', 'Purchase Order-Purchase Invoice')", + "execute:webnotes.reload_doc('accounts', 'DocType Mapper', 'Purchase Receipt-Purchase Invoice')", ] \ No newline at end of file From e2dd8009994e2cf67438be56f477870aecaea580 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Thu, 4 Jul 2013 14:37:58 +0530 Subject: [PATCH 04/10] Update purchase_register.py --- accounts/report/purchase_register/purchase_register.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/accounts/report/purchase_register/purchase_register.py b/accounts/report/purchase_register/purchase_register.py index 655cf8ced08..0fbe4510356 100644 --- a/accounts/report/purchase_register/purchase_register.py +++ b/accounts/report/purchase_register/purchase_register.py @@ -58,7 +58,7 @@ def execute(filters=None): row.append(invoice_tax_map.get(inv.name, {}).get(tax_acc)) # total tax, grand total, outstanding amount & rounded total - row += [inv.other_charges_total, inv.grand_total, flt(inv.grand_total, 2), \ + row += [inv.total_tax, inv.grand_total, flt(inv.grand_total, 2), \ inv.outstanding_amount] data.append(row) @@ -164,4 +164,4 @@ def get_account_details(invoice_list): where name in (%s)""" % ", ".join(["%s"]*len(accounts)), tuple(accounts), as_dict=1): account_map[acc.name] = acc.parent_account - return account_map \ No newline at end of file + return account_map From bce622d723f494b7f48b9e58940d3faa9a9061a9 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Thu, 4 Jul 2013 14:40:21 +0530 Subject: [PATCH 05/10] Update patch_list.py --- patches/patch_list.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/patches/patch_list.py b/patches/patch_list.py index fc4fd738fef..9fdf39b5393 100644 --- a/patches/patch_list.py +++ b/patches/patch_list.py @@ -243,6 +243,6 @@ patch_list = [ "patches.june_2013.p04_fix_event_for_lead_oppty_project", "patches.june_2013.p05_remove_search_criteria_reports", "execute:webnotes.delete_doc('DocType', 'Update Delivery Date')", - "execute:webnotes.reload_doc('accounts', 'DocType Mapper', 'Purchase Order-Purchase Invoice')", - "execute:webnotes.reload_doc('accounts', 'DocType Mapper', 'Purchase Receipt-Purchase Invoice')", -] \ No newline at end of file + "execute:webnotes.reload_doc('accounts', 'DocType Mapper', 'Purchase Order-Purchase Invoice') # 2013-07-04", + "execute:webnotes.reload_doc('accounts', 'DocType Mapper', 'Purchase Receipt-Purchase Invoice') # 2013-07-04", +] From 7dc77f764fe19c20f862df1ef5103e05225836c7 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Thu, 4 Jul 2013 14:56:29 +0530 Subject: [PATCH 06/10] Update Purchase Order-Purchase Invoice.txt --- .../Purchase Order-Purchase Invoice.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 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 ce45824e404..031abd216d8 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 @@ -4,7 +4,7 @@ "docstatus": 0, "creation": "2010-08-08 17:09:35", "modified_by": "Administrator", - "modified": "2012-04-03 12:49:50" + "modified": "2013-07-04 12:49:50" }, { "name": "__common__", @@ -120,4 +120,4 @@ "to_table": "Purchase Taxes and Charges", "validation_logic": "docstatus =1" } -] \ No newline at end of file +] From 19f2396f9567004db577d8db2eb0797779f04790 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Thu, 4 Jul 2013 14:56:50 +0530 Subject: [PATCH 07/10] Update Purchase Receipt-Purchase Invoice.txt --- .../Purchase Receipt-Purchase Invoice.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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 f6c87e266c7..5ed4b2aced8 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 @@ -4,7 +4,7 @@ "docstatus": 0, "creation": "2010-08-08 17:09:35", "modified_by": "Administrator", - "modified": "2012-04-03 12:49:50" + "modified": "2013-07-04 12:49:50" }, { "name": "__common__", @@ -141,4 +141,4 @@ "to_table": "Purchase Taxes and Charges", "validation_logic": "docstatus=1" } -] \ No newline at end of file +] From fa8d69c7cabb50a3403b4a87295ef26b6fcf97ff Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Thu, 4 Jul 2013 15:02:23 +0530 Subject: [PATCH 08/10] Update patch_list.py --- patches/patch_list.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/patches/patch_list.py b/patches/patch_list.py index 9fdf39b5393..56cb93c4567 100644 --- a/patches/patch_list.py +++ b/patches/patch_list.py @@ -243,6 +243,6 @@ patch_list = [ "patches.june_2013.p04_fix_event_for_lead_oppty_project", "patches.june_2013.p05_remove_search_criteria_reports", "execute:webnotes.delete_doc('DocType', 'Update Delivery Date')", - "execute:webnotes.reload_doc('accounts', 'DocType Mapper', 'Purchase Order-Purchase Invoice') # 2013-07-04", - "execute:webnotes.reload_doc('accounts', 'DocType Mapper', 'Purchase Receipt-Purchase Invoice') # 2013-07-04", + "execute:webnotes.reload_doc('accounts', 'DocType Mapper', 'Purchase Order-Purchase Invoice') # 2013-07-04 3:00", + "execute:webnotes.reload_doc('accounts', 'DocType Mapper', 'Purchase Receipt-Purchase Invoice') # 2013-07-04 3:00", ] From df1fca9f658f20ccb355e10c2241b836ae466804 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Thu, 4 Jul 2013 17:50:06 +0530 Subject: [PATCH 09/10] [mapper] material request to purchase order --- .../accounts_settings/accounts_settings.py | 1 + selling/doctype/quotation/quotation.py | 3 -- .../material_request/material_request.js | 9 +++--- .../material_request/material_request.py | 32 +++++++++++++++++++ .../material_request/test_material_request.py | 15 +++++++++ 5 files changed, 53 insertions(+), 7 deletions(-) diff --git a/accounts/doctype/accounts_settings/accounts_settings.py b/accounts/doctype/accounts_settings/accounts_settings.py index 4b580488bb9..b5489369d4c 100644 --- a/accounts/doctype/accounts_settings/accounts_settings.py +++ b/accounts/doctype/accounts_settings/accounts_settings.py @@ -2,6 +2,7 @@ from __future__ import unicode_literals import webnotes +from webnotes.utils import cint class DocType: def __init__(self, d, dl): diff --git a/selling/doctype/quotation/quotation.py b/selling/doctype/quotation/quotation.py index 1adce2028e2..7e4ebe0b4d9 100644 --- a/selling/doctype/quotation/quotation.py +++ b/selling/doctype/quotation/quotation.py @@ -254,9 +254,6 @@ class DocType(SellingController): @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": { diff --git a/stock/doctype/material_request/material_request.js b/stock/doctype/material_request/material_request.js index 025f7b5688e..3446b02ad43 100644 --- a/stock/doctype/material_request/material_request.js +++ b/stock/doctype/material_request/material_request.js @@ -102,10 +102,11 @@ 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"]]); -}; + wn.model.open_mapped_doc({ + method: "stock.doctype.material_request.material_request.make_purchase_order", + source_name: cur_frm.doc.name + }) +} cur_frm.cscript.make_supplier_quotation = function() { cur_frm.map([ diff --git a/stock/doctype/material_request/material_request.py b/stock/doctype/material_request/material_request.py index dfed6c4941e..269c4c54d7b 100644 --- a/stock/doctype/material_request/material_request.py +++ b/stock/doctype/material_request/material_request.py @@ -240,3 +240,35 @@ def _update_requested_qty(controller, mr_obj, mr_items): "indented_qty": (se_detail.docstatus==2 and 1 or -1) * add_indented_qty, "posting_date": controller.doc.posting_date, }) + + + +@webnotes.whitelist() +def make_purchase_order(source_name, target_doclist=None): + from webnotes.model.mapper import get_mapped_doclist + + def update_item(obj, target): + target.conversion_factor = 1 + target.qty = flt(obj.qty) - flt(obj.ordered_qty) + + doclist = get_mapped_doclist("Material Request", source_name, { + "Material Request": { + "doctype": "Purchase Order", + "validation": { + "docstatus": ["=", 1], + "material_request_type": ["=", "Purchase"] + } + }, + "Material Request Item": { + "doctype": "Purchase Order Item", + "field_map": { + "name": "prevdoc_detail_docname", + "parent": "prevdoc_docname", + "parenttype": "prevdoc_doctype", + "uom": "stock_uom" + }, + "postprocess": update_item + } + }, target_doclist) + + return [d.fields for d in doclist] \ No newline at end of file diff --git a/stock/doctype/material_request/test_material_request.py b/stock/doctype/material_request/test_material_request.py index f5dbb52bbef..f26773b0c84 100644 --- a/stock/doctype/material_request/test_material_request.py +++ b/stock/doctype/material_request/test_material_request.py @@ -6,6 +6,21 @@ import webnotes, unittest from webnotes.utils import flt class TestMaterialRequest(unittest.TestCase): + def test_make_purchase_order(self): + from stock.doctype.material_request.material_request import make_purchase_order + + mr = webnotes.bean(copy=test_records[0]).insert() + + self.assertRaises(webnotes.ValidationError, make_purchase_order, + mr.doc.name) + + mr = webnotes.bean("Material Request", mr.doc.name) + mr.submit() + po = make_purchase_order(mr.doc.name) + + self.assertEquals(po[0]["doctype"], "Purchase Order") + self.assertEquals(len(po), len(mr.doclist)) + def _test_expected(self, doclist, expected_values): for i, expected in enumerate(expected_values): for fieldname, val in expected.items(): From 2de1cfc1c1e4c9dd7b92cbdb63a08a638b60c1ba Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Fri, 5 Jul 2013 10:23:00 +0530 Subject: [PATCH 10/10] [mapper] material request - PO/supp quote/stock entry --- .../doctype/purchase_order/purchase_order.js | 8 ++- .../doctype/purchase_order/purchase_order.py | 19 ------ .../doctype/purchase_order/purchase_order.txt | 37 +++++++++- .../supplier_quotation/supplier_quotation.js | 6 ++ .../supplier_quotation/supplier_quotation.py | 14 ---- .../supplier_quotation/supplier_quotation.txt | 21 ++++-- .../material_request/material_request.js | 53 ++++++++------- .../material_request/material_request.py | 68 ++++++++++++++++++- .../material_request/test_material_request.py | 32 +++++++++ 9 files changed, 192 insertions(+), 66 deletions(-) diff --git a/buying/doctype/purchase_order/purchase_order.js b/buying/doctype/purchase_order/purchase_order.js index 442925131ab..fd420cae414 100644 --- a/buying/doctype/purchase_order/purchase_order.js +++ b/buying/doctype/purchase_order/purchase_order.js @@ -83,7 +83,13 @@ cur_frm.cscript.get_last_purchase_rate = function(doc, cdt, cdn){ } -//========================= Make Purchase Receipt ======================================================= +cur_frm.cscript.get_items = function(doc, dt, dn) { + wn.model.map_current_doc({ + method: "stock.doctype.material_request.material_request.make_purchase_order", + source_name: cur_frm.doc.indent_no, + }) +} + cur_frm.cscript['Make Purchase Receipt'] = function() { n = wn.model.make_new_doc_and_get_name('Purchase Receipt'); $c('dt_map', args={ diff --git a/buying/doctype/purchase_order/purchase_order.py b/buying/doctype/purchase_order/purchase_order.py index 908df674038..fba448c23d1 100644 --- a/buying/doctype/purchase_order/purchase_order.py +++ b/buying/doctype/purchase_order/purchase_order.py @@ -21,7 +21,6 @@ from webnotes.utils import cstr, flt from webnotes.model.bean import getlist from webnotes.model.code import get_obj from webnotes import msgprint -from buying.utils import get_last_purchase_details sql = webnotes.conn.sql @@ -72,24 +71,6 @@ class DocType(BuyingController): def get_bin_details(self, arg = ''): return get_obj(dt='Purchase Common').get_bin_details(arg) - # Pull Material Request - def get_indent_details(self): - if self.doc.indent_no: - get_obj('DocType Mapper','Material Request-Purchase Order').dt_map('Material Request','Purchase Order',self.doc.indent_no, self.doc, self.doclist, "[['Material Request','Purchase Order'],['Material Request Item', 'Purchase Order Item']]") - for d in getlist(self.doclist, 'po_details'): - if d.item_code and not d.purchase_rate: - last_purchase_details = get_last_purchase_details(d.item_code, self.doc.name) - if last_purchase_details: - conversion_factor = d.conversion_factor or 1.0 - conversion_rate = self.doc.fields.get('conversion_rate') or 1.0 - d.purchase_ref_rate = last_purchase_details['purchase_ref_rate'] * conversion_factor - d.discount_rate = last_purchase_details['discount_rate'] - d.purchase_rate = last_purchase_details['purchase_rate'] * conversion_factor - d.import_ref_rate = d.purchase_ref_rate / conversion_rate - d.import_rate = d.purchase_rate / conversion_rate - else: - d.purchase_ref_rate = d.discount_rate = d.purchase_rate = d.import_ref_rate = d.import_rate = 0.0 - def get_supplier_quotation_items(self): if self.doc.supplier_quotation: get_obj("DocType Mapper", "Supplier Quotation-Purchase Order").dt_map("Supplier Quotation", diff --git a/buying/doctype/purchase_order/purchase_order.txt b/buying/doctype/purchase_order/purchase_order.txt index b2bf1464aac..6fd21613998 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-07-04 10:48:54", + "modified": "2013-07-04 18:10:21", "modified_by": "Administrator", "owner": "Administrator" }, @@ -31,7 +31,6 @@ "parent": "Purchase Order", "parentfield": "permissions", "parenttype": "DocType", - "permlevel": 0, "read": 1, "report": 1 }, @@ -208,7 +207,6 @@ "label": "Get Items", "no_copy": 0, "oldfieldtype": "Button", - "options": "get_indent_details", "print_hide": 1 }, { @@ -789,15 +787,37 @@ "cancel": 0, "create": 0, "doctype": "DocPerm", + "permlevel": 1, "role": "Material User", "submit": 0, "write": 0 }, + { + "amend": 0, + "cancel": 0, + "create": 0, + "doctype": "DocPerm", + "permlevel": 0, + "role": "Material User", + "submit": 0, + "write": 0 + }, + { + "amend": 0, + "cancel": 0, + "create": 0, + "doctype": "DocPerm", + "permlevel": 1, + "role": "Purchase Manager", + "submit": 0, + "write": 0 + }, { "amend": 1, "cancel": 1, "create": 1, "doctype": "DocPerm", + "permlevel": 0, "role": "Purchase Manager", "submit": 1, "write": 1 @@ -807,13 +827,24 @@ "cancel": 1, "create": 1, "doctype": "DocPerm", + "permlevel": 0, "role": "Purchase User", "submit": 1, "write": 1 }, + { + "amend": 0, + "cancel": 0, + "create": 0, + "doctype": "DocPerm", + "permlevel": 1, + "role": "All", + "submit": 0 + }, { "doctype": "DocPerm", "match": "supplier", + "permlevel": 0, "role": "Supplier" } ] \ No newline at end of file diff --git a/buying/doctype/supplier_quotation/supplier_quotation.js b/buying/doctype/supplier_quotation/supplier_quotation.js index 0ed85ff2f9d..92db3022884 100644 --- a/buying/doctype/supplier_quotation/supplier_quotation.js +++ b/buying/doctype/supplier_quotation/supplier_quotation.js @@ -31,6 +31,12 @@ erpnext.buying.SupplierQuotationController = erpnext.buying.BuyingController.ext cur_frm.add_custom_button("Make Purchase Order", cur_frm.cscript.make_purchase_order); } }, + get_items: function() { + wn.model.map_current_doc({ + method: "stock.doctype.material_request.material_request.make_supplier_quotation", + source_name: cur_frm.doc.indent_no, + }) + } }); // for backward compatibility: combine new and previous states diff --git a/buying/doctype/supplier_quotation/supplier_quotation.py b/buying/doctype/supplier_quotation/supplier_quotation.py index 421ecd0d44c..b8cf7cbac81 100644 --- a/buying/doctype/supplier_quotation/supplier_quotation.py +++ b/buying/doctype/supplier_quotation/supplier_quotation.py @@ -17,7 +17,6 @@ from __future__ import unicode_literals import webnotes from webnotes.model.code import get_obj -from setup.utils import get_company_currency from controllers.buying_controller import BuyingController class DocType(BuyingController): @@ -49,19 +48,6 @@ class DocType(BuyingController): def on_trash(self): pass - - def get_indent_details(self): - if self.doc.indent_no: - mapper = get_obj("DocType Mapper", "Material Request-Supplier Quotation") - mapper.dt_map("Material Request", "Supplier Quotation", self.doc.indent_no, - self.doc, self.doclist, """[['Material Request', 'Supplier Quotation'], - ['Material Request Item', 'Supplier Quotation Item']]""") - - from webnotes.model.bean import getlist - for d in getlist(self.doclist, self.fname): - if d.item_code and not d.purchase_rate: - d.purchase_ref_rate = d.discount_rate = d.purchase_rate = 0.0 - d.import_ref_rate = d.import_rate = 0.0 def validate_fiscal_year(self): get_obj(dt = 'Purchase Common').validate_fiscal_year( \ diff --git a/buying/doctype/supplier_quotation/supplier_quotation.txt b/buying/doctype/supplier_quotation/supplier_quotation.txt index d9ecf602deb..5f2e95ee8cf 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-07-04 10:51:05", + "modified": "2013-07-04 18:47:51", "modified_by": "Administrator", "owner": "Administrator" }, @@ -31,7 +31,6 @@ "parent": "Supplier Quotation", "parentfield": "permissions", "parenttype": "DocType", - "permlevel": 0, "read": 1, "report": 1 }, @@ -191,8 +190,7 @@ "fieldtype": "Button", "hidden": 0, "label": "Get Items", - "oldfieldtype": "Button", - "options": "get_indent_details" + "oldfieldtype": "Button" }, { "doctype": "DocField", @@ -644,6 +642,7 @@ "cancel": 1, "create": 1, "doctype": "DocPerm", + "permlevel": 0, "role": "Manufacturing Manager", "submit": 1, "write": 1 @@ -653,6 +652,7 @@ "cancel": 1, "create": 1, "doctype": "DocPerm", + "permlevel": 0, "role": "Purchase Manager", "submit": 1, "write": 1 @@ -662,6 +662,7 @@ "cancel": 0, "create": 1, "doctype": "DocPerm", + "permlevel": 0, "role": "Purchase User", "submit": 0, "write": 1 @@ -671,6 +672,7 @@ "cancel": 0, "create": 0, "doctype": "DocPerm", + "permlevel": 0, "role": "Material User", "submit": 0, "write": 0 @@ -680,8 +682,19 @@ "cancel": 0, "create": 0, "doctype": "DocPerm", + "permlevel": 0, "role": "Supplier", "submit": 0, "write": 0 + }, + { + "amend": 0, + "cancel": 0, + "create": 0, + "doctype": "DocPerm", + "permlevel": 1, + "role": "All", + "submit": 0, + "write": 0 } ] \ No newline at end of file diff --git a/stock/doctype/material_request/material_request.js b/stock/doctype/material_request/material_request.js index 3446b02ad43..6de7a295e77 100644 --- a/stock/doctype/material_request/material_request.js +++ b/stock/doctype/material_request/material_request.js @@ -36,23 +36,27 @@ erpnext.buying.MaterialRequestController = erpnext.buying.BuyingController.exten 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); + cur_frm.add_custom_button("Make Supplier Quotation", + cur_frm.cscript.make_supplier_quotation); if(doc.material_request_type === "Transfer" && doc.status === "Submitted") cur_frm.add_custom_button("Transfer Material", cur_frm.cscript.make_stock_entry); if(flt(doc.per_ordered, 2) < 100) { if(doc.material_request_type === "Purchase") - cur_frm.add_custom_button('Make Purchase Order', cur_frm.cscript['Make Purchase Order']); + cur_frm.add_custom_button('Make Purchase Order', + cur_frm.cscript.make_purchase_order); - cur_frm.add_custom_button('Stop Material Request', cur_frm.cscript['Stop Material Request']); + cur_frm.add_custom_button('Stop Material Request', + cur_frm.cscript['Stop Material Request']); } cur_frm.add_custom_button('Send SMS', cur_frm.cscript.send_sms); } if(doc.docstatus == 1 && doc.status == 'Stopped') - cur_frm.add_custom_button('Unstop Material Request', cur_frm.cscript['Unstop Material Request']); + cur_frm.add_custom_button('Unstop Material Request', + cur_frm.cscript['Unstop Material Request']); if(doc.material_request_type === "Transfer") { cur_frm.toggle_display("sales_order_no", false); @@ -66,6 +70,27 @@ erpnext.buying.MaterialRequestController = erpnext.buying.BuyingController.exten calculate_taxes_and_totals: function() { return; + }, + + make_purchase_order: function() { + wn.model.open_mapped_doc({ + method: "stock.doctype.material_request.material_request.make_purchase_order", + source_name: cur_frm.doc.name + }) + }, + + make_supplier_quotation: function() { + wn.model.open_mapped_doc({ + method: "stock.doctype.material_request.material_request.make_supplier_quotation", + source_name: cur_frm.doc.name + }) + }, + + make_stock_entry: function() { + wn.model.open_mapped_doc({ + method: "stock.doctype.material_request.material_request.make_stock_entry", + source_name: cur_frm.doc.name + }) } }); @@ -96,26 +121,6 @@ cur_frm.cscript['Unstop Material Request'] = function(){ if (check) { $c('runserverobj', args={'method':'update_status', 'arg': 'Submitted','docs': wn.model.compress(make_doclist(doc.doctype, doc.name))}, function(r,rt) { cur_frm.refresh(); - }); } }; - -cur_frm.cscript['Make Purchase Order'] = function() { - wn.model.open_mapped_doc({ - method: "stock.doctype.material_request.material_request.make_purchase_order", - source_name: cur_frm.doc.name - }) -} - -cur_frm.cscript.make_supplier_quotation = function() { - 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"]]); -}; diff --git a/stock/doctype/material_request/material_request.py b/stock/doctype/material_request/material_request.py index 269c4c54d7b..3f3c212b8eb 100644 --- a/stock/doctype/material_request/material_request.py +++ b/stock/doctype/material_request/material_request.py @@ -250,6 +250,10 @@ def make_purchase_order(source_name, target_doclist=None): def update_item(obj, target): target.conversion_factor = 1 target.qty = flt(obj.qty) - flt(obj.ordered_qty) + + def set_missing_values(source, target): + po = webnotes.bean(target) + po.run_method("set_missing_values") doclist = get_mapped_doclist("Material Request", source_name, { "Material Request": { @@ -269,6 +273,68 @@ def make_purchase_order(source_name, target_doclist=None): }, "postprocess": update_item } - }, target_doclist) + }, target_doclist, set_missing_values) + + return [d.fields for d in doclist] + +@webnotes.whitelist() +def make_supplier_quotation(source_name, target_doclist=None): + from webnotes.model.mapper import get_mapped_doclist + + def set_missing_values(source, target): + sq = webnotes.bean(target) + sq.run_method("set_missing_values") + + doclist = get_mapped_doclist("Material Request", source_name, { + "Material Request": { + "doctype": "Supplier Quotation", + "validation": { + "docstatus": ["=", 1], + "material_request_type": ["=", "Purchase"] + } + }, + "Material Request Item": { + "doctype": "Supplier Quotation Item", + "field_map": { + "name": "prevdoc_detail_docname", + "parent": "prevdoc_docname", + "parenttype": "prevdoc_doctype" + } + } + }, target_doclist, set_missing_values) + + return [d.fields for d in doclist] + +@webnotes.whitelist() +def make_stock_entry(source_name, target_doclist=None): + from webnotes.model.mapper import get_mapped_doclist + + def set_purpose(source, target): + target[0].purpose = "Material Transfer" + + def update_item(source, target): + target.conversion_factor = 1 + target.qty = flt(source.qty) - flt(source.ordered_qty) + + + doclist = get_mapped_doclist("Material Request", source_name, { + "Material Request": { + "doctype": "Stock Entry", + "validation": { + "docstatus": ["=", 1], + "material_request_type": ["=", "Transfer"] + } + }, + "Material Request Item": { + "doctype": "Stock Entry Detail", + "field_map": { + "name": "material_request_item", + "parent": "material_request", + "uom": "stock_uom", + "warehouse": "t_warehouse" + }, + "postprocess": update_item + } + }, target_doclist, set_purpose) return [d.fields for d in doclist] \ No newline at end of file diff --git a/stock/doctype/material_request/test_material_request.py b/stock/doctype/material_request/test_material_request.py index f26773b0c84..daf31ad969c 100644 --- a/stock/doctype/material_request/test_material_request.py +++ b/stock/doctype/material_request/test_material_request.py @@ -20,6 +20,38 @@ class TestMaterialRequest(unittest.TestCase): self.assertEquals(po[0]["doctype"], "Purchase Order") self.assertEquals(len(po), len(mr.doclist)) + + def test_make_supplier_quotation(self): + from stock.doctype.material_request.material_request import make_supplier_quotation + + mr = webnotes.bean(copy=test_records[0]).insert() + + self.assertRaises(webnotes.ValidationError, make_supplier_quotation, + mr.doc.name) + + mr = webnotes.bean("Material Request", mr.doc.name) + mr.submit() + sq = make_supplier_quotation(mr.doc.name) + + self.assertEquals(sq[0]["doctype"], "Supplier Quotation") + self.assertEquals(len(sq), len(mr.doclist)) + + + def test_make_stock_entry(self): + from stock.doctype.material_request.material_request import make_stock_entry + + mr = webnotes.bean(copy=test_records[0]).insert() + + self.assertRaises(webnotes.ValidationError, make_stock_entry, + mr.doc.name) + + mr = webnotes.bean("Material Request", mr.doc.name) + mr.doc.material_request_type = "Transfer" + mr.submit() + se = make_stock_entry(mr.doc.name) + + self.assertEquals(se[0]["doctype"], "Stock Entry") + self.assertEquals(len(se), len(mr.doclist)) def _test_expected(self, doclist, expected_values): for i, expected in enumerate(expected_values):