fix: Subcontracting Receipt GL Entries
diff --git a/erpnext/patches.txt b/erpnext/patches.txt
index d92353a..3086829 100644
--- a/erpnext/patches.txt
+++ b/erpnext/patches.txt
@@ -311,4 +311,5 @@
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 0000000..159c6dc
--- /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 021d9aa..b8134d7 100644
--- a/erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.py
+++ b/erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.py
@@ -5,6 +5,8 @@
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 @@
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):