From 4a4ce12eb417dcd9208a2f94e29e4a454c7fe2e5 Mon Sep 17 00:00:00 2001 From: deepeshgarg007 Date: Thu, 25 Apr 2019 14:28:19 +0530 Subject: [PATCH] fix: Commonfied code for inter-company-transaction --- .../purchase_invoice/purchase_invoice.py | 12 +- .../doctype/sales_invoice/sales_invoice.py | 91 ++++++++----- .../doctype/purchase_order/purchase_order.py | 12 +- .../doctype/sales_order/sales_order.py | 125 +----------------- 4 files changed, 73 insertions(+), 167 deletions(-) diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py index 0af273c518..95d49a4421 100644 --- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py +++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py @@ -21,8 +21,8 @@ from erpnext.accounts.general_ledger import get_round_off_account_and_cost_cente from erpnext.assets.doctype.asset.asset import get_asset_account, is_cwip_accounting_disabled from frappe.model.mapper import get_mapped_doc from six import iteritems -from erpnext.accounts.doctype.sales_invoice.sales_invoice import validate_inter_company_party, update_linked_invoice,\ - unlink_inter_company_invoice +from erpnext.accounts.doctype.sales_invoice.sales_invoice import validate_inter_company_party, update_linked_doc,\ + unlink_inter_company_doc from erpnext.accounts.doctype.tax_withholding_category.tax_withholding_category import get_party_tax_withholding_details from erpnext.accounts.deferred_revenue import validate_service_stop_date @@ -348,7 +348,7 @@ class PurchaseInvoice(BuyingController): self.make_gl_entries() self.update_project() - update_linked_invoice(self.doctype, self.name, self.inter_company_invoice_reference) + update_linked_doc(self.doctype, self.name, self.inter_company_invoice_reference) def make_gl_entries(self, gl_entries=None, repost_future_gle=True, from_repost=False): if not self.grand_total: @@ -778,7 +778,7 @@ class PurchaseInvoice(BuyingController): self.update_project() frappe.db.set(self, 'status', 'Cancelled') - unlink_inter_company_invoice(self.doctype, self.name, self.inter_company_invoice_reference) + unlink_inter_company_doc(self.doctype, self.name, self.inter_company_invoice_reference) def update_project(self): project_list = [] @@ -917,5 +917,5 @@ def block_invoice(name, hold_comment): @frappe.whitelist() def make_inter_company_sales_invoice(source_name, target_doc=None): - from erpnext.accounts.doctype.sales_invoice.sales_invoice import make_inter_company_invoice - return make_inter_company_invoice("Purchase Invoice", source_name, target_doc) + from erpnext.accounts.doctype.sales_invoice.sales_invoice import make_inter_company_transaction + return make_inter_company_transaction("Purchase Invoice", source_name, target_doc) diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py index 2089f15c7c..31a9c66f6f 100644 --- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py +++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py @@ -179,7 +179,7 @@ class SalesInvoice(SellingController): if frappe.db.get_single_value('Selling Settings', 'sales_update_frequency') == "Each Transaction": update_company_current_month_sales(self.company) self.update_project() - update_linked_invoice(self.doctype, self.name, self.inter_company_invoice_reference) + update_linked_doc(self.doctype, self.name, self.inter_company_invoice_reference) # create the loyalty point ledger entry if the customer is enrolled in any loyalty program if not self.is_return and self.loyalty_program: @@ -243,7 +243,7 @@ class SalesInvoice(SellingController): against_si_doc.delete_loyalty_point_entry() against_si_doc.make_loyalty_point_entry() - unlink_inter_company_invoice(self.doctype, self.name, self.inter_company_invoice_reference) + unlink_inter_company_doc(self.doctype, self.name, self.inter_company_invoice_reference) # Healthcare Service Invoice. domain_settings = frappe.get_doc('Domain Settings') @@ -1165,21 +1165,29 @@ class SalesInvoice(SellingController): self.set_missing_values(for_validate = True) -def validate_inter_company_party(doctype, party, company, inter_company_invoice_reference): - if doctype == "Sales Invoice": +def validate_inter_company_party(doctype, party, company, inter_company_reference): + if doctype in ["Sales Invoice", "Sales Order"]: partytype, ref_partytype, internal = "Customer", "Supplier", "is_internal_customer" - ref_doc = "Purchase Invoice" + + if doctype == "Sales Invoice": + ref_doc = "Purchase Invoice" + else: + ref_doc = "Purchase Order" else: partytype, ref_partytype, internal = "Supplier", "Customer", "is_internal_supplier" - ref_doc = "Sales Invoice" - if inter_company_invoice_reference: - doc = frappe.get_doc(ref_doc, inter_company_invoice_reference) - ref_party = doc.supplier if doctype == "Sales Invoice" else doc.customer + if doctype == "Purchase Invoice": + ref_doc = "Sales Invoice" + else: + ref_doc = "Sales Order" + + if inter_company_reference: + doc = frappe.get_doc(ref_doc, inter_company_reference) + ref_party = doc.supplier if doctype in ["Sales Invoice", "Sales Order"] else doc.customer if not frappe.db.get_value(partytype, {"represents_company": doc.company}, "name") == party: - frappe.throw(_("Invalid {0} for Inter Company Invoice.").format(partytype)) + frappe.throw(_("Invalid {0} for Inter Company Transaction.").format(partytype)) if not frappe.get_cached_value(ref_partytype, ref_party, "represents_company") == company: - frappe.throw(_("Invalid Company for Inter Company Invoice.")) + frappe.throw(_("Invalid Company for Inter Company Transaction.")) elif frappe.db.get_value(partytype, {"name": party, internal: 1}, "name") == party: companies = frappe.db.sql("""select company from `tabAllowed To Transact With` @@ -1188,18 +1196,29 @@ def validate_inter_company_party(doctype, party, company, inter_company_invoice_ if not company in companies: frappe.throw(_("{0} not allowed to transact with {1}. Please change the Company.").format(partytype, company)) -def update_linked_invoice(doctype, name, inter_company_invoice_reference): - if inter_company_invoice_reference: - frappe.db.set_value(doctype, inter_company_invoice_reference,\ - "inter_company_invoice_reference", name) +def update_linked_doc(doctype, name, inter_company_reference): -def unlink_inter_company_invoice(doctype, name, inter_company_invoice_reference): - ref_doc = "Purchase Invoice" if doctype == "Sales Invoice" else "Sales Invoice" - if inter_company_invoice_reference: - frappe.db.set_value(doctype, name,\ - "inter_company_invoice_reference", "") - frappe.db.set_value(ref_doc, inter_company_invoice_reference,\ - "inter_company_invoice_reference", "") + if doctype in ["Sales Invoice", "Purchase Invoice"]: + ref_field = "inter_company_invoice_reference" + else: + ref_field = "inter_company_order_reference" + + if inter_company_reference: + frappe.db.set_value(doctype, inter_company_reference,\ + ref_field, name) + +def unlink_inter_company_doc(doctype, name, inter_company_reference): + + if doctype in ["Sales Invoice", "Purchase Invoice"]: + ref_doc = "Purchase Invoice" if doctype == "Sales Invoice" else "Sales Invoice" + ref_field = "inter_company_invoice_reference" + else: + ref_doc = "Purchase Order" if doctype == "Sales Order" else "Sales Order" + ref_field = "inter_company_order_reference" + + if inter_company_reference: + frappe.db.set_value(doctype, name, ref_field, "") + frappe.db.set_value(ref_doc, inter_company_reference, ref_field, "") def get_list_context(context=None): from erpnext.controllers.website_list_for_contact import get_list_context @@ -1299,7 +1318,7 @@ def set_account_for_mode_of_payment(self): data.account = get_bank_cash_account(data.mode_of_payment, self.company).get("account") def get_inter_company_details(doc, doctype): - if doctype == "Sales Invoice": + if doctype in ["Sales Invoice", "Sales Order"]: party = frappe.db.get_value("Supplier", {"disabled": 0, "is_internal_supplier": 1, "represents_company": doc.company}, "name") company = frappe.get_cached_value("Customer", doc.customer, "represents_company") else: @@ -1312,21 +1331,21 @@ def get_inter_company_details(doc, doctype): } -def validate_inter_company_invoice(doc, doctype): +def validate_inter_company_transaction(doc, doctype): details = get_inter_company_details(doc, doctype) - price_list = doc.selling_price_list if doctype == "Sales Invoice" else doc.buying_price_list + price_list = doc.selling_price_list if doctype in ["Sales Invoice", "Sales Order"] else doc.buying_price_list valid_price_list = frappe.db.get_value("Price List", {"name": price_list, "buying": 1, "selling": 1}) if not valid_price_list: frappe.throw(_("Selected Price List should have buying and selling fields checked.")) party = details.get("party") if not party: - partytype = "Supplier" if doctype == "Sales Invoice" else "Customer" + partytype = "Supplier" if doctype in ["Sales Invoice", "Sales Order"] else "Customer" frappe.throw(_("No {0} found for Inter Company Transactions.").format(partytype)) company = details.get("company") - default_currency = frappe.get_cached_value('Company', company, "default_currency") + default_currency = frappe.get_cached_value('Company', company, "default_currency") if default_currency != doc.currency: frappe.throw(_("Company currencies of both the companies should match for Inter Company Transactions.")) @@ -1334,17 +1353,17 @@ def validate_inter_company_invoice(doc, doctype): @frappe.whitelist() def make_inter_company_purchase_invoice(source_name, target_doc=None): - return make_inter_company_invoice("Sales Invoice", source_name, target_doc) + return make_inter_company_transaction("Sales Invoice", source_name, target_doc) -def make_inter_company_invoice(doctype, source_name, target_doc=None): - if doctype == "Sales Invoice": - source_doc = frappe.get_doc("Sales Invoice", source_name) - target_doctype = "Purchase Invoice" +def make_inter_company_transaction(doctype, source_name, target_doc=None): + if doctype in ["Sales Invoice", "Sales Order"]: + source_doc = frappe.get_doc(doctype, source_name) + target_doctype = "Purchase Invoice" if doctype == "Sales Invoice" else "Purchase Order" else: - source_doc = frappe.get_doc("Purchase Invoice", source_name) - target_doctype = "Sales Invoice" + source_doc = frappe.get_doc(doctype, source_name) + target_doctype = "Sales Invoice" if doctype == "Purchase Invoice" else "Sales Order" - validate_inter_company_invoice(source_doc, doctype) + validate_inter_company_transaction(source_doc, doctype) details = get_inter_company_details(source_doc, doctype) def set_missing_values(source, target): @@ -1352,7 +1371,7 @@ def make_inter_company_invoice(doctype, source_name, target_doc=None): def update_details(source_doc, target_doc, source_parent): target_doc.inter_company_invoice_reference = source_doc.name - if target_doc.doctype == "Purchase Invoice": + if target_doc.doctype in ["Purchase Invoice", "Purchase Order"]: target_doc.company = details.get("company") target_doc.supplier = details.get("party") target_doc.buying_price_list = source_doc.selling_price_list diff --git a/erpnext/buying/doctype/purchase_order/purchase_order.py b/erpnext/buying/doctype/purchase_order/purchase_order.py index ae610f89d5..e5156a32b7 100644 --- a/erpnext/buying/doctype/purchase_order/purchase_order.py +++ b/erpnext/buying/doctype/purchase_order/purchase_order.py @@ -17,8 +17,8 @@ from erpnext.accounts.party import get_party_account_currency from six import string_types from erpnext.stock.doctype.item.item import get_item_defaults from erpnext.setup.doctype.item_group.item_group import get_item_group_defaults -from erpnext.selling.doctype.sales_order.sales_order import validate_inter_company_party, update_linked_order,\ - unlink_inter_company_order +from erpnext.accounts.doctype.sales_invoice.sales_invoice import validate_inter_company_party, update_linked_doc,\ + unlink_inter_company_doc form_grid_templates = { "items": "templates/form_grid/item_grid.html" @@ -222,7 +222,7 @@ class PurchaseOrder(BuyingController): self.update_blanket_order() - update_linked_order(self.doctype, self.name, self.inter_company_order_reference) + update_linked_doc(self.doctype, self.name, self.inter_company_order_reference) def on_cancel(self): super(PurchaseOrder, self).on_cancel() @@ -248,7 +248,7 @@ class PurchaseOrder(BuyingController): self.update_blanket_order() - unlink_inter_company_order(self.doctype, self.name, self.inter_company_order_reference) + unlink_inter_company_doc(self.doctype, self.name, self.inter_company_order_reference) def on_update(self): pass @@ -498,6 +498,6 @@ def update_status(status, name): @frappe.whitelist() def make_inter_company_sales_order(source_name, target_doc=None): - from erpnext.selling.doctype.sales_order.sales_order import make_inter_company_order - return make_inter_company_order("Purchase Order", source_name, target_doc) + from erpnext.accounts.doctype.sales_invoice.sales_invoice import make_inter_company_transaction + return make_inter_company_transaction("Purchase Order", source_name, target_doc) diff --git a/erpnext/selling/doctype/sales_order/sales_order.py b/erpnext/selling/doctype/sales_order/sales_order.py index 6b51b9670c..fc11e11092 100755 --- a/erpnext/selling/doctype/sales_order/sales_order.py +++ b/erpnext/selling/doctype/sales_order/sales_order.py @@ -19,6 +19,8 @@ from erpnext.selling.doctype.customer.customer import check_credit_limit from erpnext.stock.doctype.item.item import get_item_defaults from erpnext.setup.doctype.item_group.item_group import get_item_group_defaults from erpnext.manufacturing.doctype.production_plan.production_plan import get_items_for_material_requests +from erpnext.accounts.doctype.sales_invoice.sales_invoice import validate_inter_company_party, update_linked_doc,\ + unlink_inter_company_doc form_grid_templates = { "items": "templates/form_grid/item_grid.html" @@ -183,7 +185,7 @@ class SalesOrder(SellingController): self.update_blanket_order() - update_linked_order(self.doctype, self.name, self.inter_company_order_reference) + update_linked_doc(self.doctype, self.name, self.inter_company_order_reference) def on_cancel(self): super(SalesOrder, self).on_cancel() @@ -201,7 +203,7 @@ class SalesOrder(SellingController): self.update_blanket_order() - unlink_inter_company_order(self.doctype, self.name, self.inter_company_order_reference) + unlink_inter_company_doc(self.doctype, self.name, self.inter_company_order_reference) def update_project(self): if frappe.db.get_single_value('Selling Settings', 'sales_update_frequency') != "Each Transaction": @@ -460,42 +462,6 @@ class SalesOrder(SellingController): Item {0} is added with and without Ensure Delivery by \ Serial No.").format(item.item_code)) -def validate_inter_company_party(doctype, party, company, inter_company_order_reference): - if doctype == "Sales Order": - partytype, ref_partytype, internal = "Customer", "Supplier", "is_internal_customer" - ref_doc = "Purchase Order" - else: - partytype, ref_partytype, internal = "Supplier", "Customer", "is_internal_supplier" - ref_doc = "Sales Order" - - if inter_company_order_reference: - doc = frappe.get_doc(ref_doc, inter_company_order_reference) - ref_party = doc.supplier if doctype == "Sales Order" else doc.customer - if not frappe.db.get_value(partytype, {"represents_company": doc.company}, "name") == party: - frappe.throw(_("Invalid {0} for Inter Company Order.").format(partytype)) - if not frappe.get_cached_value(ref_partytype, ref_party, "represents_company") == company: - frappe.throw(_("Invalid Company for Inter Company Order.")) - - elif frappe.db.get_value(partytype, {"name": party, internal: 1}, "name") == party: - companies = frappe.db.sql("""select company from `tabAllowed To Transact With` - where parenttype = '{0}' and parent = '{1}'""".format(partytype, party), as_list = 1) #nosec - companies = [d[0] for d in companies] - if not company in companies: - frappe.throw(_("{0} not allowed to transact with {1}. Please change the Company.").format(partytype, company)) - -def update_linked_order(doctype, name, inter_company_order_reference): - if inter_company_order_reference: - frappe.db.set_value(doctype, inter_company_order_reference,\ - "inter_company_order_reference", name) - -def unlink_inter_company_order(doctype, name, inter_company_order_reference): - ref_doc = "Purchase Order" if doctype == "Sales Order" else "Sales Order" - if inter_company_order_reference: - frappe.db.set_value(doctype, name,\ - "inter_company_order_reference", "") - frappe.db.set_value(ref_doc, inter_company_order_reference,\ - "inter_company_order_reference", "") - def get_list_context(context=None): from erpnext.controllers.website_list_for_contact import get_list_context list_context = get_list_context(context) @@ -1014,86 +980,7 @@ def make_raw_material_request(items, company, sales_order, project=None): material_request.submit() return material_request -def get_inter_company_details(doc, doctype): - if doctype == "Sales Order": - party = frappe.db.get_value("Supplier", {"disabled": 0, "is_internal_supplier": 1, "represents_company": doc.company}, "name") - company = frappe.get_cached_value("Customer", doc.customer, "represents_company") - else: - party = frappe.db.get_value("Customer", {"disabled": 0, "is_internal_customer": 1, "represents_company": doc.company}, "name") - company = frappe.get_cached_value("Supplier", doc.supplier, "represents_company") - - return { - "party": party, - "company": company - } - -def validate_inter_company_order(doc, doctype): - - details = get_inter_company_details(doc, doctype) - price_list = doc.selling_price_list if doctype == "Sales Order" else doc.buying_price_list - valid_price_list = frappe.db.get_value("Price List", {"name": price_list, "buying": 1, "selling": 1}) - if not valid_price_list: - frappe.throw(_("Selected Price List should have buying and selling fields checked.")) - - party = details.get("party") - if not party: - partytype = "Supplier" if doctype == "Sales Order" else "Customer" - frappe.throw(_("No {0} found for Inter Company Transactions.").format(partytype)) - - company = details.get("company") - default_currency = frappe.get_cached_value('Company', company, "default_currency") - if default_currency != doc.currency: - frappe.throw(_("Company currencies of both the companies should match for Inter Company Transactions.")) - - return - @frappe.whitelist() def make_inter_company_purchase_order(source_name, target_doc=None): - return make_inter_company_order("Sales Order", source_name, target_doc) - -def make_inter_company_order(doctype, source_name, target_doc=None): - if doctype == "Sales Order": - source_doc = frappe.get_doc("Sales Order", source_name) - target_doctype = "Purchase Order" - else: - source_doc = frappe.get_doc("Purchase Order", source_name) - target_doctype = "Sales Order" - - validate_inter_company_order(source_doc, doctype) - details = get_inter_company_details(source_doc, doctype) - - def set_missing_values(source, target): - target.run_method("set_missing_values") - - def update_details(source_doc, target_doc, source_parent): - target_doc.inter_company_order_reference = source_doc.name - if target_doc.doctype == "Purchase Order": - target_doc.company = details.get("company") - target_doc.supplier = details.get("party") - target_doc.buying_price_list = source_doc.selling_price_list - else: - target_doc.company = details.get("company") - target_doc.customer = details.get("party") - target_doc.selling_price_list = source_doc.buying_price_list - - doclist = get_mapped_doc(doctype, source_name, { - doctype: { - "doctype": target_doctype, - "postprocess": update_details, - "field_no_map": [ - "taxes_and_charges" - ] - }, - doctype +" Item": { - "doctype": target_doctype + " Item", - "field_no_map": [ - "income_account", - "expense_account", - "cost_center", - "warehouse" - ] - } - - }, target_doc, set_missing_values) - - return doclist \ No newline at end of file + from erpnext.accounts.doctype.sales_invoice.sales_invoice import make_inter_company_transaction + return make_inter_company_transaction("Sales Order", source_name, target_doc)