From d02ebd621504ac04737cc283ee6d06e2c6eb92c2 Mon Sep 17 00:00:00 2001 From: Smit Vora Date: Thu, 19 Oct 2023 22:35:55 +0530 Subject: [PATCH] fix: add regional support to extend purchase gl entries (cherry picked from commit 77cc91d06b9ea1e5758546a78bbcbb2ef97f549b) # Conflicts: # erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py # erpnext/controllers/stock_controller.py # erpnext/stock/doctype/purchase_receipt/purchase_receipt.py --- .../purchase_invoice/purchase_invoice.py | 153 +++++++++++++++++ erpnext/controllers/stock_controller.py | 162 ++++++++++++++++++ .../purchase_receipt/purchase_receipt.py | 16 +- 3 files changed, 325 insertions(+), 6 deletions(-) diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py index 306208603c0..a20117f0ec2 100644 --- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py +++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py @@ -969,12 +969,165 @@ class PurchaseInvoice(BuyingController): item.item_tax_amount, item.precision("item_tax_amount") ) +<<<<<<< HEAD assets = frappe.db.get_all( "Asset", filters={"purchase_invoice": self.name, "item_code": item.item_code} ) for asset in assets: frappe.db.set_value("Asset", asset.name, "gross_purchase_amount", flt(item.valuation_rate)) frappe.db.set_value("Asset", asset.name, "purchase_receipt_amount", flt(item.valuation_rate)) +======= + def get_asset_gl_entry(self, gl_entries): + arbnb_account = None + eiiav_account = None + asset_eiiav_currency = None + + for item in self.get("items"): + if item.is_fixed_asset: + asset_amount = flt(item.net_amount) + flt(item.item_tax_amount / self.conversion_rate) + base_asset_amount = flt(item.base_net_amount + item.item_tax_amount) + + item_exp_acc_type = frappe.get_cached_value("Account", item.expense_account, "account_type") + if not item.expense_account or item_exp_acc_type not in [ + "Asset Received But Not Billed", + "Fixed Asset", + ]: + if not arbnb_account: + arbnb_account = self.get_company_default("asset_received_but_not_billed") + item.expense_account = arbnb_account + + if not self.update_stock: + arbnb_currency = get_account_currency(item.expense_account) + gl_entries.append( + self.get_gl_dict( + { + "account": item.expense_account, + "against": self.supplier, + "remarks": self.get("remarks") or _("Accounting Entry for Asset"), + "debit": base_asset_amount, + "debit_in_account_currency": ( + base_asset_amount if arbnb_currency == self.company_currency else asset_amount + ), + "cost_center": item.cost_center, + "project": item.project or self.project, + }, + item=item, + ) + ) + + if item.item_tax_amount: + if not eiiav_account or not asset_eiiav_currency: + eiiav_account = self.get_company_default("expenses_included_in_asset_valuation") + asset_eiiav_currency = get_account_currency(eiiav_account) + + gl_entries.append( + self.get_gl_dict( + { + "account": eiiav_account, + "against": self.supplier, + "remarks": self.get("remarks") or _("Accounting Entry for Asset"), + "cost_center": item.cost_center, + "project": item.project or self.project, + "credit": item.item_tax_amount, + "credit_in_account_currency": ( + item.item_tax_amount + if asset_eiiav_currency == self.company_currency + else item.item_tax_amount / self.conversion_rate + ), + }, + item=item, + ) + ) + else: + cwip_account = get_asset_account( + "capital_work_in_progress_account", asset_category=item.asset_category, company=self.company + ) + + cwip_account_currency = get_account_currency(cwip_account) + gl_entries.append( + self.get_gl_dict( + { + "account": cwip_account, + "against": self.supplier, + "remarks": self.get("remarks") or _("Accounting Entry for Asset"), + "debit": base_asset_amount, + "debit_in_account_currency": ( + base_asset_amount if cwip_account_currency == self.company_currency else asset_amount + ), + "cost_center": item.cost_center or self.cost_center, + "project": item.project or self.project, + }, + item=item, + ) + ) + + if item.item_tax_amount and not cint(erpnext.is_perpetual_inventory_enabled(self.company)): + if not eiiav_account or not asset_eiiav_currency: + eiiav_account = self.get_company_default("expenses_included_in_asset_valuation") + asset_eiiav_currency = get_account_currency(eiiav_account) + + gl_entries.append( + self.get_gl_dict( + { + "account": eiiav_account, + "against": self.supplier, + "remarks": self.get("remarks") or _("Accounting Entry for Asset"), + "cost_center": item.cost_center, + "credit": item.item_tax_amount, + "project": item.project or self.project, + "credit_in_account_currency": ( + item.item_tax_amount + if asset_eiiav_currency == self.company_currency + else item.item_tax_amount / self.conversion_rate + ), + }, + item=item, + ) + ) + + # Assets are bought through this document then it will be linked to this document + if flt(item.landed_cost_voucher_amount): + if not eiiav_account: + eiiav_account = self.get_company_default("expenses_included_in_asset_valuation") + + gl_entries.append( + self.get_gl_dict( + { + "account": eiiav_account, + "against": cwip_account, + "cost_center": item.cost_center, + "remarks": self.get("remarks") or _("Accounting Entry for Stock"), + "credit": flt(item.landed_cost_voucher_amount), + "project": item.project or self.project, + }, + item=item, + ) + ) + + gl_entries.append( + self.get_gl_dict( + { + "account": cwip_account, + "against": eiiav_account, + "cost_center": item.cost_center, + "remarks": self.get("remarks") or _("Accounting Entry for Stock"), + "debit": flt(item.landed_cost_voucher_amount), + "project": item.project or self.project, + }, + item=item, + ) + ) + + # update gross amount of assets bought through this document + assets = frappe.db.get_all( + "Asset", filters={"purchase_invoice": self.name, "item_code": item.item_code} + ) + for asset in assets: + frappe.db.set_value("Asset", asset.name, "gross_purchase_amount", flt(item.valuation_rate)) + frappe.db.set_value("Asset", asset.name, "purchase_receipt_amount", flt(item.valuation_rate)) + + return gl_entries +>>>>>>> 77cc91d06b (fix: add regional support to extend purchase gl entries) def make_stock_adjustment_entry( self, gl_entries, item, voucher_wise_stock_value, account_currency diff --git a/erpnext/controllers/stock_controller.py b/erpnext/controllers/stock_controller.py index a72cc667399..3e766f4a7f1 100644 --- a/erpnext/controllers/stock_controller.py +++ b/erpnext/controllers/stock_controller.py @@ -76,6 +76,15 @@ class StockController(AccountsController): gl_entries = self.get_gl_entries(warehouse_account) make_gl_entries(gl_entries, from_repost=from_repost) +<<<<<<< HEAD +======= + elif self.doctype in ["Purchase Receipt", "Purchase Invoice"] and self.docstatus == 1: + gl_entries = [] + gl_entries = self.get_asset_gl_entry(gl_entries) + update_regional_gl_entries(gl_entries, self) + make_gl_entries(gl_entries, from_repost=from_repost) + +>>>>>>> 77cc91d06b (fix: add regional support to extend purchase gl entries) def validate_serialized_batch(self): from erpnext.stock.doctype.serial_no.serial_no import get_serial_nos @@ -837,6 +846,154 @@ class StockController(AccountsController): gl_entries.append(self.get_gl_dict(gl_entry, item=item)) +<<<<<<< HEAD +======= +@frappe.whitelist() +def show_accounting_ledger_preview(company, doctype, docname): + filters = frappe._dict(company=company, include_dimensions=1) + doc = frappe.get_doc(doctype, docname) + doc.run_method("before_gl_preview") + + gl_columns, gl_data = get_accounting_ledger_preview(doc, filters) + + frappe.db.rollback() + + return {"gl_columns": gl_columns, "gl_data": gl_data} + + +@frappe.whitelist() +def show_stock_ledger_preview(company, doctype, docname): + filters = frappe._dict(company=company) + doc = frappe.get_doc(doctype, docname) + doc.run_method("before_sl_preview") + + sl_columns, sl_data = get_stock_ledger_preview(doc, filters) + + frappe.db.rollback() + + return { + "sl_columns": sl_columns, + "sl_data": sl_data, + } + + +def get_accounting_ledger_preview(doc, filters): + from erpnext.accounts.report.general_ledger.general_ledger import get_columns as get_gl_columns + + gl_columns, gl_data = [], [] + fields = [ + "posting_date", + "account", + "debit", + "credit", + "against", + "party", + "party_type", + "cost_center", + "against_voucher_type", + "against_voucher", + ] + + doc.docstatus = 1 + + if doc.get("update_stock") or doc.doctype in ("Purchase Receipt", "Delivery Note"): + doc.update_stock_ledger() + + doc.make_gl_entries() + columns = get_gl_columns(filters) + gl_entries = get_gl_entries_for_preview(doc.doctype, doc.name, fields) + + gl_columns = get_columns(columns, fields) + gl_data = get_data(fields, gl_entries) + + return gl_columns, gl_data + + +def get_stock_ledger_preview(doc, filters): + from erpnext.stock.report.stock_ledger.stock_ledger import get_columns as get_sl_columns + + sl_columns, sl_data = [], [] + fields = [ + "item_code", + "stock_uom", + "actual_qty", + "qty_after_transaction", + "warehouse", + "incoming_rate", + "valuation_rate", + "stock_value", + "stock_value_difference", + ] + columns_fields = [ + "item_code", + "stock_uom", + "in_qty", + "out_qty", + "qty_after_transaction", + "warehouse", + "incoming_rate", + "in_out_rate", + "stock_value", + "stock_value_difference", + ] + + if doc.get("update_stock") or doc.doctype in ("Purchase Receipt", "Delivery Note"): + doc.docstatus = 1 + doc.update_stock_ledger() + columns = get_sl_columns(filters) + sl_entries = get_sl_entries_for_preview(doc.doctype, doc.name, fields) + + sl_columns = get_columns(columns, columns_fields) + sl_data = get_data(columns_fields, sl_entries) + + return sl_columns, sl_data + + +def get_sl_entries_for_preview(doctype, docname, fields): + sl_entries = frappe.get_all( + "Stock Ledger Entry", filters={"voucher_type": doctype, "voucher_no": docname}, fields=fields + ) + + for entry in sl_entries: + if entry.actual_qty > 0: + entry["in_qty"] = entry.actual_qty + entry["out_qty"] = 0 + else: + entry["out_qty"] = abs(entry.actual_qty) + entry["in_qty"] = 0 + + entry["in_out_rate"] = entry["valuation_rate"] + + return sl_entries + + +def get_gl_entries_for_preview(doctype, docname, fields): + return frappe.get_all( + "GL Entry", filters={"voucher_type": doctype, "voucher_no": docname}, fields=fields + ) + + +def get_columns(raw_columns, fields): + return [ + {"name": d.get("label"), "editable": False, "width": 110} + for d in raw_columns + if not d.get("hidden") and d.get("fieldname") in fields + ] + + +def get_data(raw_columns, raw_data): + datatable_data = [] + for row in raw_data: + data_row = [] + for column in raw_columns: + data_row.append(row.get(column) or "") + + datatable_data.append(data_row) + + return datatable_data + + +>>>>>>> 77cc91d06b (fix: add regional support to extend purchase gl entries) def repost_required_for_queue(doc: StockController) -> bool: """check if stock document contains repeated item-warehouse with queue based valuation. @@ -1057,3 +1214,8 @@ def create_item_wise_repost_entries(voucher_type, voucher_no, allow_zero_rate=Fa repost_entries.append(repost_entry) return repost_entries + + +@erpnext.allow_regional +def update_regional_gl_entries(gl_list, doc): + return diff --git a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py index 964ce0b7218..1e4ccc8b6ec 100644 --- a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py +++ b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py @@ -314,6 +314,11 @@ class PurchaseReceipt(BuyingController): self.make_item_gl_entries(gl_entries, warehouse_account=warehouse_account) self.make_tax_gl_entries(gl_entries) +<<<<<<< HEAD +======= + self.get_asset_gl_entry(gl_entries) + update_regional_gl_entries(gl_entries, self) +>>>>>>> 77cc91d06b (fix: add regional support to extend purchase gl entries) return process_gl_map(gl_entries) @@ -758,8 +763,6 @@ class PurchaseReceipt(BuyingController): pr_doc = self if (pr == self.name) else frappe.get_doc("Purchase Receipt", pr) update_billing_percentage(pr_doc, update_modified=update_modified) - self.load_from_db() - def get_stock_value_difference(voucher_no, voucher_detail_no, warehouse): return frappe.db.get_value( @@ -886,9 +889,6 @@ def get_billed_amount_against_po(po_items): def update_billing_percentage(pr_doc, update_modified=True, adjust_incoming_rate=False): - # Reload as billed amount was set in db directly - pr_doc.load_from_db() - # Update Billing % based on pending accepted qty total_amount, total_billed_amount = 0, 0 item_wise_returned_qty = get_item_wise_returned_qty(pr_doc) @@ -914,7 +914,6 @@ def update_billing_percentage(pr_doc, update_modified=True, adjust_incoming_rate percent_billed = round(100 * (total_billed_amount / (total_amount or 1)), 6) pr_doc.db_set("per_billed", percent_billed) - pr_doc.load_from_db() if update_modified: pr_doc.set_status(update=True) @@ -1193,3 +1192,8 @@ def get_item_account_wise_additional_cost(purchase_document): def on_doctype_update(): frappe.db.add_index("Purchase Receipt", ["supplier", "is_return", "return_against"]) + + +@erpnext.allow_regional +def update_regional_gl_entries(gl_list, doc): + return