From 224737b9ed38b2423eb298771451e7e6704bc37e Mon Sep 17 00:00:00 2001 From: Saurabh Date: Mon, 11 Apr 2016 14:43:30 +0530 Subject: [PATCH] [fixes] split make gl entry function into chuncks as per SI --- .../purchase_invoice/purchase_invoice.json | 20 +- .../purchase_invoice/purchase_invoice.py | 268 ++++++++++-------- erpnext/accounts/general_ledger.py | 2 +- .../test_landed_cost_voucher.py | 3 +- 4 files changed, 157 insertions(+), 136 deletions(-) diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json index d47bedb45c..90a0053331 100755 --- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json +++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json @@ -1718,7 +1718,7 @@ "bold": 0, "collapsible": 1, "collapsible_depends_on": "paid_amount", - "depends_on": "eval:doc.is_paid===1", + "depends_on": "eval:doc.is_paid===1||(doc.advances && doc.advances.length>0)", "fieldname": "payments_section", "fieldtype": "Section Break", "hidden": 0, @@ -1754,11 +1754,10 @@ "label": "Mode of Payment", "length": 0, "no_copy": 0, - "oldfieldname": "mode_of_payment", - "oldfieldtype": "Select", "options": "Mode of Payment", "permlevel": 0, - "print_hide": 0, + "precision": "", + "print_hide": 1, "print_hide_if_no_value": 0, "read_only": 0, "report_hide": 0, @@ -1821,6 +1820,7 @@ "allow_on_submit": 0, "bold": 0, "collapsible": 0, + "depends_on": "is_paid", "fieldname": "paid_amount", "fieldtype": "Currency", "hidden": 0, @@ -1830,11 +1830,11 @@ "in_list_view": 0, "label": "Paid Amount", "length": 0, - "no_copy": 0, + "no_copy": 1, "options": "currency", "permlevel": 0, "precision": "", - "print_hide": 0, + "print_hide": 1, "print_hide_if_no_value": 0, "read_only": 0, "report_hide": 0, @@ -1856,13 +1856,13 @@ "in_list_view": 0, "label": "Paid Amount (Company Currency)", "length": 0, - "no_copy": 0, + "no_copy": 1, "options": "Company:company:default_currency", "permlevel": 0, "precision": "", - "print_hide": 0, + "print_hide": 1, "print_hide_if_no_value": 0, - "read_only": 0, + "read_only": 1, "report_hide": 0, "reqd": 0, "search_index": 0, @@ -3004,7 +3004,7 @@ "istable": 0, "max_attachments": 0, "menu_index": 0, - "modified": "2016-04-06 05:39:45.475873", + "modified": "2016-04-11 14:37:27.243253", "modified_by": "Administrator", "module": "Accounts", "name": "Purchase Invoice", diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py index a8a0d84191..8c4db50458 100644 --- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py +++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py @@ -335,14 +335,153 @@ class PurchaseInvoice(BuyingController): frappe.db.set_value("Asset", asset.name, "supplier", self.supplier) def make_gl_entries(self): - auto_accounting_for_stock = \ + self.auto_accounting_for_stock = \ cint(frappe.defaults.get_global_default("auto_accounting_for_stock")) - stock_received_but_not_billed = self.get_company_default("stock_received_but_not_billed") - expenses_included_in_valuation = self.get_company_default("expenses_included_in_valuation") - + self.stock_received_but_not_billed = self.get_company_default("stock_received_but_not_billed") + self.expenses_included_in_valuation = self.get_company_default("expenses_included_in_valuation") + self.negative_expense_to_be_booked = 0.0 gl_entries = [] + + + self.make_supplier_gl_entry(gl_entries) + self.make_item_gl_entries(gl_entries) + self.make_tax_gl_entries(gl_entries) + + from erpnext.accounts.general_ledger import merge_similar_entries + gl_entries = merge_similar_entries(gl_entries) + + self.make_payment_gl_entries(gl_entries) + self.make_write_off_gl_entry(gl_entries) + if gl_entries: + from erpnext.accounts.general_ledger import make_gl_entries + update_outstanding = "No" if (cint(self.is_paid) or self.write_off_account) else "Yes" + + make_gl_entries(gl_entries, cancel=(self.docstatus == 2), + update_outstanding=update_outstanding, merge_entries=False) + + def make_supplier_gl_entry(self, gl_entries): + # parent's gl entry + if self.grand_total: + # Didnot use base_grand_total to book rounding loss gle + grand_total_in_company_currency = flt(self.grand_total * self.conversion_rate, + self.precision("grand_total")) + gl_entries.append( + self.get_gl_dict({ + "account": self.credit_to, + "party_type": "Supplier", + "party": self.supplier, + "against": self.against_expense_account, + "credit": grand_total_in_company_currency, + "credit_in_account_currency": grand_total_in_company_currency \ + if self.party_account_currency==self.company_currency else self.grand_total, + "against_voucher": self.return_against if cint(self.is_return) else self.name, + "against_voucher_type": self.doctype, + }, self.party_account_currency) + ) + + def make_item_gl_entries(self, gl_entries): + # item gl entries + stock_items = self.get_stock_items() + warehouse_account = get_warehouse_account() + + for item in self.get("items"): + if flt(item.base_net_amount): + account_currency = get_account_currency(item.expense_account) + + if self.auto_accounting_for_stock and self.update_stock: + expense_account = warehouse_account[item.warehouse]["name"] + else: + expense_account = item.expense_account + + gl_entries.append( + self.get_gl_dict({ + "account": expense_account, + "against": self.supplier, + "debit": item.base_net_amount, + "debit_in_account_currency": item.base_net_amount \ + if account_currency==self.company_currency else item.net_amount, + "cost_center": item.cost_center + }, account_currency) + ) + + if self.auto_accounting_for_stock and self.is_opening == "No" and \ + item.item_code in stock_items and item.item_tax_amount: + # Post reverse entry for Stock-Received-But-Not-Billed if it is booked in Purchase Receipt + if item.purchase_receipt: + negative_expense_booked_in_pr = frappe.db.sql("""select name from `tabGL Entry` + where voucher_type='Purchase Receipt' and voucher_no=%s and account=%s""", + (item.purchase_receipt, self.expenses_included_in_valuation)) + + if not negative_expense_booked_in_pr: + gl_entries.append( + self.get_gl_dict({ + "account": self.stock_received_but_not_billed, + "against": self.supplier, + "debit": flt(item.item_tax_amount, self.precision("item_tax_amount", item)), + "remarks": self.remarks or "Accounting Entry for Stock" + }) + ) + + self.negative_expense_to_be_booked += flt(item.item_tax_amount, \ + self.precision("item_tax_amount", item)) + + def make_tax_gl_entries(self, gl_entries): + # tax table gl entries + valuation_tax = {} + for tax in self.get("taxes"): + if tax.category in ("Total", "Valuation and Total") and flt(tax.base_tax_amount_after_discount_amount): + account_currency = get_account_currency(tax.account_head) + + dr_or_cr = "debit" if tax.add_deduct_tax == "Add" else "credit" + + gl_entries.append( + self.get_gl_dict({ + "account": tax.account_head, + "against": self.supplier, + dr_or_cr: tax.base_tax_amount_after_discount_amount, + dr_or_cr + "_in_account_currency": tax.base_tax_amount_after_discount_amount \ + if account_currency==self.company_currency \ + else tax.tax_amount_after_discount_amount, + "cost_center": tax.cost_center + }, account_currency) + ) + # accumulate valuation tax + if self.is_opening == "No" and tax.category in ("Valuation", "Valuation and Total") and flt(tax.base_tax_amount_after_discount_amount): + if self.auto_accounting_for_stock and not tax.cost_center: + frappe.throw(_("Cost Center is required in row {0} in Taxes table for type {1}").format(tax.idx, _(tax.category))) + valuation_tax.setdefault(tax.cost_center, 0) + valuation_tax[tax.cost_center] += \ + (tax.add_deduct_tax == "Add" and 1 or -1) * flt(tax.base_tax_amount_after_discount_amount) + + if self.is_opening == "No" and self.negative_expense_to_be_booked and valuation_tax: + # credit valuation tax amount in "Expenses Included In Valuation" + # this will balance out valuation amount included in cost of goods sold + + total_valuation_amount = sum(valuation_tax.values()) + amount_including_divisional_loss = self.negative_expense_to_be_booked + i = 1 + for cost_center, amount in valuation_tax.items(): + if i == len(valuation_tax): + applicable_amount = amount_including_divisional_loss + else: + applicable_amount = self.negative_expense_to_be_booked * (amount / total_valuation_amount) + amount_including_divisional_loss -= applicable_amount + + gl_entries.append( + self.get_gl_dict({ + "account": self.expenses_included_in_valuation, + "cost_center": cost_center, + "against": self.supplier, + "credit": applicable_amount, + "remarks": self.remarks or "Accounting Entry for Stock" + }) + ) + + i += 1 + + def make_payment_gl_entries(self, gl_entries): # Make Cash GL Entries if cint(self.is_paid) and self.cash_bank_account and self.paid_amount: bank_account_currency = get_account_currency(self.cash_bank_account) @@ -370,123 +509,8 @@ class PurchaseInvoice(BuyingController): if bank_account_currency==self.company_currency else self.paid_amount }, bank_account_currency) ) - - # parent's gl entry - if self.grand_total: - # Didnot use base_grand_total to book rounding loss gle - grand_total_in_company_currency = flt(self.grand_total * self.conversion_rate, - self.precision("grand_total")) - - gl_entries.append( - self.get_gl_dict({ - "account": self.credit_to, - "party_type": "Supplier", - "party": self.supplier, - "against": self.against_expense_account, - "credit": grand_total_in_company_currency, - "credit_in_account_currency": grand_total_in_company_currency \ - if self.party_account_currency==self.company_currency else self.grand_total, - "against_voucher": self.return_against if cint(self.is_return) else self.name, - "against_voucher_type": self.doctype, - }, self.party_account_currency) - ) - # tax table gl entries - valuation_tax = {} - for tax in self.get("taxes"): - if tax.category in ("Total", "Valuation and Total") and flt(tax.base_tax_amount_after_discount_amount): - account_currency = get_account_currency(tax.account_head) - - dr_or_cr = "debit" if tax.add_deduct_tax == "Add" else "credit" - - gl_entries.append( - self.get_gl_dict({ - "account": tax.account_head, - "against": self.supplier, - dr_or_cr: tax.base_tax_amount_after_discount_amount, - dr_or_cr + "_in_account_currency": tax.base_tax_amount_after_discount_amount \ - if account_currency==self.company_currency \ - else tax.tax_amount_after_discount_amount, - "cost_center": tax.cost_center - }, account_currency) - ) - # accumulate valuation tax - if self.is_opening == "No" and tax.category in ("Valuation", "Valuation and Total") and flt(tax.base_tax_amount_after_discount_amount): - if auto_accounting_for_stock and not tax.cost_center: - frappe.throw(_("Cost Center is required in row {0} in Taxes table for type {1}").format(tax.idx, _(tax.category))) - valuation_tax.setdefault(tax.cost_center, 0) - valuation_tax[tax.cost_center] += \ - (tax.add_deduct_tax == "Add" and 1 or -1) * flt(tax.base_tax_amount_after_discount_amount) - # item gl entries - negative_expense_to_be_booked = 0.0 - stock_items = self.get_stock_items() - warehouse_account = get_warehouse_account() - - for item in self.get("items"): - if flt(item.base_net_amount): - account_currency = get_account_currency(item.expense_account) - - if auto_accounting_for_stock and self.update_stock: - expense_account = warehouse_account[item.warehouse]["name"] - else: - expense_account = item.expense_account - - gl_entries.append( - self.get_gl_dict({ - "account": expense_account, - "against": self.supplier, - "debit": item.base_net_amount, - "debit_in_account_currency": item.base_net_amount \ - if account_currency==self.company_currency else item.net_amount, - "cost_center": item.cost_center - }, account_currency) - ) - - if auto_accounting_for_stock and self.is_opening == "No" and \ - item.item_code in stock_items and item.item_tax_amount: - # Post reverse entry for Stock-Received-But-Not-Billed if it is booked in Purchase Receipt - if item.purchase_receipt: - negative_expense_booked_in_pr = frappe.db.sql("""select name from `tabGL Entry` - where voucher_type='Purchase Receipt' and voucher_no=%s and account=%s""", - (item.purchase_receipt, expenses_included_in_valuation)) - - if not negative_expense_booked_in_pr: - gl_entries.append( - self.get_gl_dict({ - "account": stock_received_but_not_billed, - "against": self.supplier, - "debit": flt(item.item_tax_amount, self.precision("item_tax_amount", item)), - "remarks": self.remarks or "Accounting Entry for Stock" - }) - ) - - negative_expense_to_be_booked += flt(item.item_tax_amount, self.precision("item_tax_amount", item)) - - if self.is_opening == "No" and negative_expense_to_be_booked and valuation_tax: - # credit valuation tax amount in "Expenses Included In Valuation" - # this will balance out valuation amount included in cost of goods sold - - total_valuation_amount = sum(valuation_tax.values()) - amount_including_divisional_loss = negative_expense_to_be_booked - i = 1 - for cost_center, amount in valuation_tax.items(): - if i == len(valuation_tax): - applicable_amount = amount_including_divisional_loss - else: - applicable_amount = negative_expense_to_be_booked * (amount / total_valuation_amount) - amount_including_divisional_loss -= applicable_amount - - gl_entries.append( - self.get_gl_dict({ - "account": expenses_included_in_valuation, - "cost_center": cost_center, - "against": self.supplier, - "credit": applicable_amount, - "remarks": self.remarks or "Accounting Entry for Stock" - }) - ) - - i += 1 + def make_write_off_gl_entry(self, gl_entries): # writeoff account includes petty difference in the invoice amount # and the amount that is paid if self.write_off_account and flt(self.write_off_amount): @@ -515,10 +539,6 @@ class PurchaseInvoice(BuyingController): "cost_center": self.write_off_cost_center }) ) - - if gl_entries: - from erpnext.accounts.general_ledger import make_gl_entries - make_gl_entries(gl_entries, cancel=(self.docstatus == 2)) def on_cancel(self): self.check_for_closed_status() diff --git a/erpnext/accounts/general_ledger.py b/erpnext/accounts/general_ledger.py index 2063edf30e..cf9f4fc819 100644 --- a/erpnext/accounts/general_ledger.py +++ b/erpnext/accounts/general_ledger.py @@ -25,7 +25,7 @@ def make_gl_entries(gl_map, cancel=False, adv_adj=False, merge_entries=True, upd def process_gl_map(gl_map, merge_entries=True): if merge_entries: gl_map = merge_similar_entries(gl_map) - + print gl_map for entry in gl_map: # toggle debit, credit if negative entry if flt(entry.debit) < 0: diff --git a/erpnext/stock/doctype/landed_cost_voucher/test_landed_cost_voucher.py b/erpnext/stock/doctype/landed_cost_voucher/test_landed_cost_voucher.py index 7f190d2edc..8323460902 100644 --- a/erpnext/stock/doctype/landed_cost_voucher/test_landed_cost_voucher.py +++ b/erpnext/stock/doctype/landed_cost_voucher/test_landed_cost_voucher.py @@ -88,7 +88,8 @@ class TestLandedCostVoucher(unittest.TestCase): lcv = frappe.new_doc("Landed Cost Voucher") lcv.company = "_Test Company" lcv.set("purchase_receipts", [{ - "purchase_receipt": pr.name, + "receipt_document_type": "Purchase Receipt", + "receipt_document": pr.name, "supplier": pr.supplier, "posting_date": pr.posting_date, "grand_total": pr.base_grand_total