From e888639c7ed175c53a26a38ffa9a22775332096b Mon Sep 17 00:00:00 2001 From: Sagar Sharma Date: Mon, 22 Aug 2022 10:48:21 +0530 Subject: [PATCH] fix: Subcontracting Receipt GL Entries --- erpnext/patches.txt | 3 +- .../fix_subcontracting_receipt_gl_entries.py | 30 ++++ .../subcontracting_receipt.py | 133 ++++++++++++++++++ 3 files changed, 165 insertions(+), 1 deletion(-) create mode 100644 erpnext/patches/v14_0/fix_subcontracting_receipt_gl_entries.py diff --git a/erpnext/patches.txt b/erpnext/patches.txt index d92353aca4..30868298b6 100644 --- a/erpnext/patches.txt +++ b/erpnext/patches.txt @@ -311,4 +311,5 @@ erpnext.patches.v14_0.remove_india_localisation # 14-07-2022 erpnext.patches.v13_0.fix_number_and_frequency_for_monthly_depreciation erpnext.patches.v14_0.remove_hr_and_payroll_modules # 20-07-2022 erpnext.patches.v14_0.fix_crm_no_of_employees -erpnext.patches.v14_0.create_accounting_dimensions_in_subcontracting_doctypes \ No newline at end of file +erpnext.patches.v14_0.create_accounting_dimensions_in_subcontracting_doctypes +erpnext.patches.v14_0.fix_subcontracting_receipt_gl_entries \ No newline at end of file diff --git a/erpnext/patches/v14_0/fix_subcontracting_receipt_gl_entries.py b/erpnext/patches/v14_0/fix_subcontracting_receipt_gl_entries.py new file mode 100644 index 0000000000..159c6dc82d --- /dev/null +++ b/erpnext/patches/v14_0/fix_subcontracting_receipt_gl_entries.py @@ -0,0 +1,30 @@ +# Copyright (c) 2022, Frappe Technologies Pvt. Ltd. and contributors +# For license information, please see license.txt + +import frappe + +from erpnext.stock.report.stock_and_account_value_comparison.stock_and_account_value_comparison import ( + get_data, +) + + +def execute(): + data = [] + + for company in frappe.db.get_list("Company", pluck="name"): + data += get_data( + frappe._dict( + { + "company": company, + } + ) + ) + + if data: + for d in data: + if d and d.get("voucher_type") == "Subcontracting Receipt": + doc = frappe.new_doc("Repost Item Valuation") + doc.voucher_type = d.get("voucher_type") + doc.voucher_no = d.get("voucher_no") + doc.save() + doc.submit() diff --git a/erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.py b/erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.py index 021d9aa854..b8134d7b27 100644 --- a/erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.py +++ b/erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.py @@ -5,6 +5,8 @@ import frappe from frappe import _ from frappe.utils import cint, flt, getdate, nowdate +import erpnext +from erpnext.accounts.utils import get_account_currency from erpnext.controllers.subcontracting_controller import SubcontractingController @@ -181,6 +183,137 @@ class SubcontractingReceipt(SubcontractingController): if status: frappe.db.set_value("Subcontracting Receipt", self.name, "status", status, update_modified) + def get_gl_entries(self, warehouse_account=None): + from erpnext.accounts.general_ledger import process_gl_map + + gl_entries = [] + self.make_item_gl_entries(gl_entries, warehouse_account) + + return process_gl_map(gl_entries) + + def make_item_gl_entries(self, gl_entries, warehouse_account=None): + if erpnext.is_perpetual_inventory_enabled(self.company): + stock_rbnb = self.get_company_default("stock_received_but_not_billed") + expenses_included_in_valuation = self.get_company_default("expenses_included_in_valuation") + + warehouse_with_no_account = [] + + for item in self.items: + if flt(item.rate) and flt(item.qty): + if warehouse_account.get(item.warehouse): + stock_value_diff = frappe.db.get_value( + "Stock Ledger Entry", + { + "voucher_type": "Subcontracting Receipt", + "voucher_no": self.name, + "voucher_detail_no": item.name, + "warehouse": item.warehouse, + "is_cancelled": 0, + }, + "stock_value_difference", + ) + + warehouse_account_name = warehouse_account[item.warehouse]["account"] + warehouse_account_currency = warehouse_account[item.warehouse]["account_currency"] + supplier_warehouse_account = warehouse_account.get(self.supplier_warehouse, {}).get("account") + supplier_warehouse_account_currency = warehouse_account.get(self.supplier_warehouse, {}).get( + "account_currency" + ) + remarks = self.get("remarks") or _("Accounting Entry for Stock") + + # FG Warehouse Account (Debit) + self.add_gl_entry( + gl_entries=gl_entries, + account=warehouse_account_name, + cost_center=item.cost_center, + debit=stock_value_diff, + credit=0.0, + remarks=remarks, + against_account=stock_rbnb, + account_currency=warehouse_account_currency, + item=item, + ) + + # Supplier Warehouse Account (Credit) + if flt(item.rm_supp_cost) and warehouse_account.get(self.supplier_warehouse): + self.add_gl_entry( + gl_entries=gl_entries, + account=supplier_warehouse_account, + cost_center=item.cost_center, + debit=0.0, + credit=flt(item.rm_supp_cost), + remarks=remarks, + against_account=warehouse_account_name, + account_currency=supplier_warehouse_account_currency, + item=item, + ) + + # Expense Account (Credit) + if flt(item.service_cost_per_qty): + self.add_gl_entry( + gl_entries=gl_entries, + account=item.expense_account, + cost_center=item.cost_center, + debit=0.0, + credit=flt(item.service_cost_per_qty) * flt(item.qty), + remarks=remarks, + against_account=warehouse_account_name, + account_currency=get_account_currency(item.expense_account), + item=item, + ) + + # Loss Account (Credit) + divisional_loss = flt(item.amount - stock_value_diff, item.precision("amount")) + + if divisional_loss: + if self.is_return: + loss_account = expenses_included_in_valuation + else: + loss_account = item.expense_account + + self.add_gl_entry( + gl_entries=gl_entries, + account=loss_account, + cost_center=item.cost_center, + debit=divisional_loss, + credit=0.0, + remarks=remarks, + against_account=warehouse_account_name, + account_currency=get_account_currency(loss_account), + project=item.project, + item=item, + ) + elif ( + item.warehouse not in warehouse_with_no_account + or item.rejected_warehouse not in warehouse_with_no_account + ): + warehouse_with_no_account.append(item.warehouse) + + # Additional Costs Expense Accounts (Credit) + for row in self.additional_costs: + credit_amount = ( + flt(row.base_amount) + if (row.base_amount or row.account_currency != self.company_currency) + else flt(row.amount) + ) + + self.add_gl_entry( + gl_entries=gl_entries, + account=row.expense_account, + cost_center=self.cost_center or self.get_company_default("cost_center"), + debit=0.0, + credit=credit_amount, + remarks=remarks, + against_account=None, + ) + + if warehouse_with_no_account: + frappe.msgprint( + _("No accounting entries for the following warehouses") + + ": \n" + + "\n".join(warehouse_with_no_account) + ) + @frappe.whitelist() def make_subcontract_return(source_name, target_doc=None):