mirror of
https://github.com/frappe/erpnext.git
synced 2026-09-09 23:39:28 +00:00
fix(stock): carry accounting dimensions from landed cost voucher charges into gl entries
This commit is contained in:
@@ -1023,6 +1023,10 @@ class PurchaseInvoice(BuyingController):
|
|||||||
gl_entries.append(self.get_gl_dict(gl, self.party_account_currency, item=self))
|
gl_entries.append(self.get_gl_dict(gl, self.party_account_currency, item=self))
|
||||||
|
|
||||||
def make_item_gl_entries(self, gl_entries):
|
def make_item_gl_entries(self, gl_entries):
|
||||||
|
from erpnext.stock.doctype.landed_cost_voucher.landed_cost_voucher import (
|
||||||
|
get_custom_dimension_overrides,
|
||||||
|
)
|
||||||
|
|
||||||
# item gl entries
|
# item gl entries
|
||||||
stock_items = self.get_stock_items()
|
stock_items = self.get_stock_items()
|
||||||
if self.update_stock and self.auto_accounting_for_stock:
|
if self.update_stock and self.auto_accounting_for_stock:
|
||||||
@@ -1164,25 +1168,34 @@ class PurchaseInvoice(BuyingController):
|
|||||||
|
|
||||||
# Amount added through landed-cost-voucher
|
# Amount added through landed-cost-voucher
|
||||||
if landed_cost_entries:
|
if landed_cost_entries:
|
||||||
if (item.item_code, item.name) in landed_cost_entries:
|
for entry in landed_cost_entries.get((item.item_code, item.name), []):
|
||||||
for account, base_amount in landed_cost_entries[
|
if not (entry.amount or entry.base_amount):
|
||||||
(item.item_code, item.name)
|
continue
|
||||||
].items():
|
|
||||||
gl_entries.append(
|
lcv_account_currency = get_account_currency(entry.expense_account)
|
||||||
self.get_gl_dict(
|
credit_in_transaction_currency = (
|
||||||
{
|
flt(entry.amount)
|
||||||
"account": account,
|
if lcv_account_currency == self.currency
|
||||||
"against": item.expense_account,
|
else flt(
|
||||||
"cost_center": item.cost_center,
|
entry.base_amount / self.conversion_rate, item.precision("net_amount")
|
||||||
"remarks": self.get("remarks") or _("Accounting Entry for Stock"),
|
|
||||||
"credit": flt(base_amount["base_amount"]),
|
|
||||||
"credit_in_account_currency": flt(base_amount["amount"]),
|
|
||||||
"credit_in_transaction_currency": item.net_amount,
|
|
||||||
"project": item.project or self.project,
|
|
||||||
},
|
|
||||||
item=item,
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
gl_dict = self.get_gl_dict(
|
||||||
|
{
|
||||||
|
"account": entry.expense_account,
|
||||||
|
"against": item.expense_account,
|
||||||
|
"cost_center": entry.dimensions.cost_center or item.cost_center,
|
||||||
|
"remarks": self.get("remarks") or _("Accounting Entry for Stock"),
|
||||||
|
"credit": flt(entry.base_amount),
|
||||||
|
"credit_in_account_currency": flt(entry.amount),
|
||||||
|
"credit_in_transaction_currency": credit_in_transaction_currency,
|
||||||
|
"project": entry.dimensions.project or item.project or self.project,
|
||||||
|
},
|
||||||
|
item=item,
|
||||||
|
)
|
||||||
|
gl_dict.update(get_custom_dimension_overrides(entry))
|
||||||
|
gl_entries.append(gl_dict)
|
||||||
|
|
||||||
# sub-contracting warehouse
|
# sub-contracting warehouse
|
||||||
if flt(item.rm_supp_cost):
|
if flt(item.rm_supp_cost):
|
||||||
|
|||||||
@@ -1248,7 +1248,13 @@ class StockController(AccountsController):
|
|||||||
if not landed_cost_vouchers:
|
if not landed_cost_vouchers:
|
||||||
return
|
return
|
||||||
|
|
||||||
|
from erpnext.stock.doctype.landed_cost_voucher.landed_cost_voucher import (
|
||||||
|
get_lcv_dimension_fields,
|
||||||
|
get_row_dimensions,
|
||||||
|
)
|
||||||
|
|
||||||
item_account_wise_cost = {}
|
item_account_wise_cost = {}
|
||||||
|
dimension_fields = get_lcv_dimension_fields()
|
||||||
|
|
||||||
row_fieldname = "purchase_receipt_item"
|
row_fieldname = "purchase_receipt_item"
|
||||||
if self.doctype == "Stock Entry":
|
if self.doctype == "Stock Entry":
|
||||||
@@ -1270,28 +1276,36 @@ class StockController(AccountsController):
|
|||||||
|
|
||||||
for item in landed_cost_voucher_doc.items:
|
for item in landed_cost_voucher_doc.items:
|
||||||
if item.receipt_document == self.name:
|
if item.receipt_document == self.name:
|
||||||
|
charges = item_account_wise_cost.setdefault((item.item_code, item.get(row_fieldname)), {})
|
||||||
|
|
||||||
for account in landed_cost_voucher_doc.taxes:
|
for account in landed_cost_voucher_doc.taxes:
|
||||||
exchange_rate = account.exchange_rate or 1
|
exchange_rate = account.exchange_rate or 1
|
||||||
item_account_wise_cost.setdefault((item.item_code, item.get(row_fieldname)), {})
|
dimensions = get_row_dimensions(account, item, dimension_fields)
|
||||||
item_account_wise_cost[(item.item_code, item.get(row_fieldname))].setdefault(
|
group_key = (
|
||||||
account.expense_account, {"amount": 0.0, "base_amount": 0.0}
|
account.expense_account,
|
||||||
|
tuple(dimensions.get(field) for field in dimension_fields),
|
||||||
)
|
)
|
||||||
|
|
||||||
item_row = item_account_wise_cost[(item.item_code, item.get(row_fieldname))][
|
item_row = charges.get(group_key)
|
||||||
account.expense_account
|
if item_row is None:
|
||||||
]
|
item_row = charges[group_key] = frappe._dict(
|
||||||
|
expense_account=account.expense_account,
|
||||||
|
amount=0.0,
|
||||||
|
base_amount=0.0,
|
||||||
|
dimensions=dimensions,
|
||||||
|
)
|
||||||
|
|
||||||
if total_item_cost > 0:
|
if total_item_cost > 0:
|
||||||
item_row["amount"] += account.amount * item.get(based_on_field) / total_item_cost
|
item_row.amount += account.amount * item.get(based_on_field) / total_item_cost
|
||||||
|
|
||||||
item_row["base_amount"] += (
|
item_row.base_amount += (
|
||||||
account.base_amount * item.get(based_on_field) / total_item_cost
|
account.base_amount * item.get(based_on_field) / total_item_cost
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
item_row["amount"] += item.applicable_charges / exchange_rate
|
item_row.amount += item.applicable_charges / exchange_rate
|
||||||
item_row["base_amount"] += item.applicable_charges
|
item_row.base_amount += item.applicable_charges
|
||||||
|
|
||||||
return item_account_wise_cost
|
return {key: list(charges.values()) for key, charges in item_account_wise_cost.items()}
|
||||||
|
|
||||||
def validate_inventory_dimension_mandatory(self):
|
def validate_inventory_dimension_mandatory(self):
|
||||||
# Mandatory inventory dimensions are enforced here (instead of via field-level `reqd`)
|
# Mandatory inventory dimensions are enforced here (instead of via field-level `reqd`)
|
||||||
@@ -1978,6 +1992,7 @@ class StockController(AccountsController):
|
|||||||
voucher_detail_no=None,
|
voucher_detail_no=None,
|
||||||
item=None,
|
item=None,
|
||||||
posting_date=None,
|
posting_date=None,
|
||||||
|
dimensions=None,
|
||||||
):
|
):
|
||||||
gl_entry = {
|
gl_entry = {
|
||||||
"account": account,
|
"account": account,
|
||||||
@@ -2003,6 +2018,9 @@ class StockController(AccountsController):
|
|||||||
if posting_date:
|
if posting_date:
|
||||||
gl_entry.update({"posting_date": posting_date})
|
gl_entry.update({"posting_date": posting_date})
|
||||||
|
|
||||||
|
if dimensions:
|
||||||
|
gl_entry.update(dimensions)
|
||||||
|
|
||||||
gl_entries.append(self.get_gl_dict(gl_entry, item=item))
|
gl_entries.append(self.get_gl_dict(gl_entry, item=item))
|
||||||
|
|
||||||
def update_stock_reservation_entries(self):
|
def update_stock_reservation_entries(self):
|
||||||
|
|||||||
@@ -559,6 +559,7 @@ accounting_dimension_doctypes = [
|
|||||||
"Purchase Taxes and Charges",
|
"Purchase Taxes and Charges",
|
||||||
"Shipping Rule",
|
"Shipping Rule",
|
||||||
"Landed Cost Item",
|
"Landed Cost Item",
|
||||||
|
"Landed Cost Taxes and Charges",
|
||||||
"Asset Value Adjustment",
|
"Asset Value Adjustment",
|
||||||
"Asset Repair",
|
"Asset Repair",
|
||||||
"Asset Capitalization",
|
"Asset Capitalization",
|
||||||
|
|||||||
@@ -490,6 +490,7 @@ erpnext.patches.v15_0.backfill_sla_link_filters_on_custom_field
|
|||||||
erpnext.patches.v15_0.backfill_sla_link_filters_on_docfield
|
erpnext.patches.v15_0.backfill_sla_link_filters_on_docfield
|
||||||
erpnext.patches.v16_0.crm_settings_handle_allowed_users_for_frappe_crm
|
erpnext.patches.v16_0.crm_settings_handle_allowed_users_for_frappe_crm
|
||||||
erpnext.patches.v16_0.backfill_pick_list_transferred_qty
|
erpnext.patches.v16_0.backfill_pick_list_transferred_qty
|
||||||
|
erpnext.patches.v16_0.create_accounting_dimensions_in_landed_cost_taxes_and_charges
|
||||||
erpnext.patches.v16_0.access_control_for_project_users
|
erpnext.patches.v16_0.access_control_for_project_users
|
||||||
erpnext.patches.v16_0.enable_book_stock_expense_gl_entries
|
erpnext.patches.v16_0.enable_book_stock_expense_gl_entries
|
||||||
erpnext.patches.v16_0.rename_ar_ap_ageing_filter
|
erpnext.patches.v16_0.rename_ar_ap_ageing_filter
|
||||||
|
|||||||
@@ -0,0 +1,11 @@
|
|||||||
|
from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import (
|
||||||
|
get_dimensions,
|
||||||
|
make_dimension_in_accounting_doctypes,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def execute():
|
||||||
|
dimensions_and_defaults = get_dimensions()
|
||||||
|
if dimensions_and_defaults:
|
||||||
|
for dimension in dimensions_and_defaults[0]:
|
||||||
|
make_dimension_in_accounting_doctypes(dimension, ["Landed Cost Taxes and Charges"])
|
||||||
@@ -17,7 +17,11 @@
|
|||||||
"has_operating_cost",
|
"has_operating_cost",
|
||||||
"operation_id",
|
"operation_id",
|
||||||
"qty",
|
"qty",
|
||||||
"operating_component"
|
"operating_component",
|
||||||
|
"accounting_dimensions_section",
|
||||||
|
"cost_center",
|
||||||
|
"dimension_col_break",
|
||||||
|
"project"
|
||||||
],
|
],
|
||||||
"fields": [
|
"fields": [
|
||||||
{
|
{
|
||||||
@@ -107,13 +111,34 @@
|
|||||||
"label": "Operating Component",
|
"label": "Operating Component",
|
||||||
"no_copy": 1,
|
"no_copy": 1,
|
||||||
"read_only": 1
|
"read_only": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "accounting_dimensions_section",
|
||||||
|
"fieldtype": "Section Break",
|
||||||
|
"label": "Accounting Dimensions"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "cost_center",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"label": "Cost Center",
|
||||||
|
"options": "Cost Center"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "dimension_col_break",
|
||||||
|
"fieldtype": "Column Break"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "project",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"label": "Project",
|
||||||
|
"options": "Project"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"grid_page_length": 50,
|
"grid_page_length": 50,
|
||||||
"index_web_pages_for_search": 1,
|
"index_web_pages_for_search": 1,
|
||||||
"istable": 1,
|
"istable": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2026-05-19 12:21:07.953801",
|
"modified": "2026-08-04 10:00:00.000000",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Stock",
|
"module": "Stock",
|
||||||
"name": "Landed Cost Taxes and Charges",
|
"name": "Landed Cost Taxes and Charges",
|
||||||
|
|||||||
@@ -88,6 +88,7 @@ class LandedCostVoucher(Document):
|
|||||||
|
|
||||||
self.set_applicable_charges_on_item()
|
self.set_applicable_charges_on_item()
|
||||||
self.set_total_vendor_invoices_cost()
|
self.set_total_vendor_invoices_cost()
|
||||||
|
self.validate_mandatory_dimensions()
|
||||||
|
|
||||||
def set_total_vendor_invoices_cost(self):
|
def set_total_vendor_invoices_cost(self):
|
||||||
self.total_vendor_invoices_cost = 0.0
|
self.total_vendor_invoices_cost = 0.0
|
||||||
@@ -196,6 +197,92 @@ class LandedCostVoucher(Document):
|
|||||||
exc=IncorrectCompanyValidationError,
|
exc=IncorrectCompanyValidationError,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def validate_mandatory_dimensions(self):
|
||||||
|
from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import (
|
||||||
|
get_accounting_dimensions,
|
||||||
|
get_checks_for_pl_and_bs_accounts,
|
||||||
|
)
|
||||||
|
from erpnext.accounts.doctype.accounting_dimension_filter.accounting_dimension_filter import (
|
||||||
|
get_dimension_filter_map,
|
||||||
|
)
|
||||||
|
|
||||||
|
if not is_perpetual_inventory_enabled(self.company):
|
||||||
|
return
|
||||||
|
|
||||||
|
company_checks = [
|
||||||
|
check
|
||||||
|
for check in get_checks_for_pl_and_bs_accounts()
|
||||||
|
if check.company == self.company and (check.mandatory_for_pl or check.mandatory_for_bs)
|
||||||
|
]
|
||||||
|
dimension_filter_map = get_dimension_filter_map()
|
||||||
|
|
||||||
|
if not company_checks and not dimension_filter_map:
|
||||||
|
return
|
||||||
|
|
||||||
|
labels = {d.fieldname: d.label for d in get_accounting_dimensions(as_list=False)}
|
||||||
|
receipts = {}
|
||||||
|
|
||||||
|
for tax in self.get("taxes"):
|
||||||
|
if not tax.expense_account:
|
||||||
|
continue
|
||||||
|
|
||||||
|
report_type = frappe.get_cached_value("Account", tax.expense_account, "report_type")
|
||||||
|
|
||||||
|
mandatory = {}
|
||||||
|
for check in company_checks:
|
||||||
|
is_mandatory = (
|
||||||
|
check.mandatory_for_pl if report_type == "Profit and Loss" else check.mandatory_for_bs
|
||||||
|
)
|
||||||
|
if is_mandatory:
|
||||||
|
mandatory[check.fieldname] = check.label
|
||||||
|
|
||||||
|
for (fieldname, account), dimension_filter in dimension_filter_map.items():
|
||||||
|
if account == tax.expense_account and dimension_filter.get("is_mandatory"):
|
||||||
|
mandatory.setdefault(fieldname, labels.get(fieldname) or frappe.unscrub(fieldname))
|
||||||
|
|
||||||
|
for fieldname, label in mandatory.items():
|
||||||
|
if tax.get(fieldname):
|
||||||
|
continue
|
||||||
|
|
||||||
|
for item in self.get("items"):
|
||||||
|
if self.get_receipt_dimension(receipts, item, fieldname):
|
||||||
|
continue
|
||||||
|
|
||||||
|
frappe.throw(
|
||||||
|
_(
|
||||||
|
"Row {0}: Accounting Dimension {1} is mandatory for account {2}."
|
||||||
|
" Set it on this Taxes and Charges row, or on Item Row {3} ({4})."
|
||||||
|
).format(
|
||||||
|
tax.idx,
|
||||||
|
frappe.bold(label),
|
||||||
|
frappe.bold(tax.expense_account),
|
||||||
|
item.idx,
|
||||||
|
frappe.bold(item.item_code),
|
||||||
|
),
|
||||||
|
title=_("Missing Accounting Dimension"),
|
||||||
|
)
|
||||||
|
|
||||||
|
def get_receipt_dimension(self, receipts, item, fieldname):
|
||||||
|
if item.get(fieldname):
|
||||||
|
return item.get(fieldname)
|
||||||
|
|
||||||
|
key = (item.receipt_document_type, item.receipt_document)
|
||||||
|
if key not in receipts:
|
||||||
|
receipts[key] = frappe.get_doc(*key) if item.receipt_document else None
|
||||||
|
|
||||||
|
receipt = receipts[key]
|
||||||
|
if not receipt:
|
||||||
|
return None
|
||||||
|
|
||||||
|
row_fieldname = "stock_entry_item" if receipt.doctype == "Stock Entry" else "purchase_receipt_item"
|
||||||
|
receipt_row_name = item.get(row_fieldname)
|
||||||
|
|
||||||
|
for row in receipt.get("items") or []:
|
||||||
|
if row.name == receipt_row_name and row.get(fieldname):
|
||||||
|
return row.get(fieldname)
|
||||||
|
|
||||||
|
return receipt.get(fieldname)
|
||||||
|
|
||||||
def set_total_taxes_and_charges(self):
|
def set_total_taxes_and_charges(self):
|
||||||
self.total_taxes_and_charges = sum(flt(d.base_amount) for d in self.get("taxes"))
|
self.total_taxes_and_charges = sum(flt(d.base_amount) for d in self.get("taxes"))
|
||||||
|
|
||||||
@@ -519,3 +606,25 @@ def get_vendor_invoice_query(filters):
|
|||||||
query = query.where(doctype.name == filters.get("name"))
|
query = query.where(doctype.name == filters.get("name"))
|
||||||
|
|
||||||
return query
|
return query
|
||||||
|
|
||||||
|
|
||||||
|
def get_lcv_dimension_fields():
|
||||||
|
from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import (
|
||||||
|
get_accounting_dimensions,
|
||||||
|
)
|
||||||
|
|
||||||
|
return ["cost_center", "project", *get_accounting_dimensions()]
|
||||||
|
|
||||||
|
|
||||||
|
def get_row_dimensions(tax_row, lcv_item, dimension_fields):
|
||||||
|
return frappe._dict(
|
||||||
|
{field: (tax_row.get(field) or lcv_item.get(field) or None) for field in dimension_fields}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def get_custom_dimension_overrides(entry):
|
||||||
|
return {
|
||||||
|
dimension: value
|
||||||
|
for dimension, value in (entry.dimensions or {}).items()
|
||||||
|
if value and dimension not in ("cost_center", "project")
|
||||||
|
}
|
||||||
|
|||||||
@@ -481,6 +481,9 @@ class PurchaseReceipt(BuyingController):
|
|||||||
from erpnext.accounts.doctype.purchase_invoice.purchase_invoice import (
|
from erpnext.accounts.doctype.purchase_invoice.purchase_invoice import (
|
||||||
get_purchase_document_details,
|
get_purchase_document_details,
|
||||||
)
|
)
|
||||||
|
from erpnext.stock.doctype.landed_cost_voucher.landed_cost_voucher import (
|
||||||
|
get_custom_dimension_overrides,
|
||||||
|
)
|
||||||
|
|
||||||
provisional_accounting_for_non_stock_items = cint(
|
provisional_accounting_for_non_stock_items = cint(
|
||||||
frappe.db.get_value("Company", self.company, "enable_provisional_accounting_for_non_stock_items")
|
frappe.db.get_value("Company", self.company, "enable_provisional_accounting_for_non_stock_items")
|
||||||
@@ -607,32 +610,38 @@ class PurchaseReceipt(BuyingController):
|
|||||||
|
|
||||||
def make_landed_cost_gl_entries(item):
|
def make_landed_cost_gl_entries(item):
|
||||||
# Amount added through landed-cost-voucher
|
# Amount added through landed-cost-voucher
|
||||||
if item.landed_cost_voucher_amount and landed_cost_entries:
|
if not (item.landed_cost_voucher_amount and landed_cost_entries):
|
||||||
if (item.item_code, item.name) in landed_cost_entries:
|
return
|
||||||
for account, amount in landed_cost_entries[(item.item_code, item.name)].items():
|
|
||||||
account_currency = get_account_currency(account)
|
|
||||||
credit_amount = (
|
|
||||||
flt(amount["base_amount"])
|
|
||||||
if (amount["base_amount"] or account_currency != self.company_currency)
|
|
||||||
else flt(amount["amount"])
|
|
||||||
)
|
|
||||||
|
|
||||||
if not account:
|
for entry in landed_cost_entries.get((item.item_code, item.name), []):
|
||||||
validate_account("Landed Cost Account")
|
if not (entry.amount or entry.base_amount):
|
||||||
|
continue
|
||||||
|
|
||||||
self.add_gl_entry(
|
account = entry.expense_account
|
||||||
gl_entries=gl_entries,
|
if not account:
|
||||||
account=account,
|
validate_account("Landed Cost Account")
|
||||||
cost_center=item.cost_center,
|
|
||||||
debit=0.0,
|
account_currency = get_account_currency(account)
|
||||||
credit=credit_amount,
|
credit_amount = (
|
||||||
remarks=remarks,
|
flt(entry.base_amount)
|
||||||
against_account=stock_asset_account_name,
|
if (entry.base_amount or account_currency != self.company_currency)
|
||||||
credit_in_account_currency=flt(amount["amount"]),
|
else flt(entry.amount)
|
||||||
account_currency=account_currency,
|
)
|
||||||
project=item.project,
|
|
||||||
item=item,
|
self.add_gl_entry(
|
||||||
)
|
gl_entries=gl_entries,
|
||||||
|
account=account,
|
||||||
|
cost_center=entry.dimensions.cost_center or item.cost_center,
|
||||||
|
debit=0.0,
|
||||||
|
credit=credit_amount,
|
||||||
|
remarks=remarks,
|
||||||
|
against_account=stock_asset_account_name,
|
||||||
|
credit_in_account_currency=flt(entry.amount),
|
||||||
|
account_currency=account_currency,
|
||||||
|
project=entry.dimensions.project or item.project,
|
||||||
|
item=item,
|
||||||
|
dimensions=get_custom_dimension_overrides(entry),
|
||||||
|
)
|
||||||
|
|
||||||
def make_expenses_added_to_stock_entries(item):
|
def make_expenses_added_to_stock_entries(item):
|
||||||
if not self.book_stock_expense_enabled():
|
if not self.book_stock_expense_enabled():
|
||||||
|
|||||||
@@ -2498,6 +2498,10 @@ class StockEntry(StockController, SubcontractingInwardController):
|
|||||||
return process_gl_map(gl_entries, from_repost=frappe.flags.through_repost_item_valuation)
|
return process_gl_map(gl_entries, from_repost=frappe.flags.through_repost_item_valuation)
|
||||||
|
|
||||||
def set_gl_entries_for_landed_cost_voucher(self, gl_entries, inventory_account_map):
|
def set_gl_entries_for_landed_cost_voucher(self, gl_entries, inventory_account_map):
|
||||||
|
from erpnext.stock.doctype.landed_cost_voucher.landed_cost_voucher import (
|
||||||
|
get_custom_dimension_overrides,
|
||||||
|
)
|
||||||
|
|
||||||
landed_cost_entries = self.get_item_account_wise_lcv_entries()
|
landed_cost_entries = self.get_item_account_wise_lcv_entries()
|
||||||
if not landed_cost_entries:
|
if not landed_cost_entries:
|
||||||
return
|
return
|
||||||
@@ -2506,52 +2510,53 @@ class StockEntry(StockController, SubcontractingInwardController):
|
|||||||
if item.s_warehouse:
|
if item.s_warehouse:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if (item.item_code, item.name) in landed_cost_entries:
|
for entry in landed_cost_entries.get((item.item_code, item.name), []):
|
||||||
for account, amount in landed_cost_entries[(item.item_code, item.name)].items():
|
if not (entry.amount or entry.base_amount):
|
||||||
account_currency = get_account_currency(account)
|
continue
|
||||||
credit_amount = (
|
|
||||||
flt(amount["base_amount"])
|
|
||||||
if (amount["base_amount"] or account_currency != self.company_currency)
|
|
||||||
else flt(amount["amount"])
|
|
||||||
)
|
|
||||||
|
|
||||||
_inv_dict = self.get_inventory_account_dict(item, inventory_account_map, "t_warehouse")
|
account_currency = get_account_currency(entry.expense_account)
|
||||||
gl_entries.append(
|
credit_amount = (
|
||||||
self.get_gl_dict(
|
flt(entry.base_amount)
|
||||||
{
|
if (entry.base_amount or account_currency != self.company_currency)
|
||||||
"account": account,
|
else flt(entry.amount)
|
||||||
"against": _inv_dict["account"],
|
)
|
||||||
"cost_center": item.cost_center,
|
|
||||||
"debit": 0.0,
|
|
||||||
"credit": credit_amount,
|
|
||||||
"remarks": _("Accounting Entry for LCV in Stock Entry {0}").format(self.name),
|
|
||||||
"credit_in_account_currency": flt(amount["amount"]),
|
|
||||||
"account_currency": account_currency,
|
|
||||||
"project": item.project,
|
|
||||||
},
|
|
||||||
item=item,
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
account_currency = get_account_currency(item.expense_account)
|
_inv_dict = self.get_inventory_account_dict(item, inventory_account_map, "t_warehouse")
|
||||||
|
gl_dict = self.get_gl_dict(
|
||||||
|
{
|
||||||
|
"account": entry.expense_account,
|
||||||
|
"against": _inv_dict["account"],
|
||||||
|
"cost_center": entry.dimensions.cost_center or item.cost_center,
|
||||||
|
"debit": 0.0,
|
||||||
|
"credit": credit_amount,
|
||||||
|
"remarks": _("Accounting Entry for LCV in Stock Entry {0}").format(self.name),
|
||||||
|
"credit_in_account_currency": flt(entry.amount),
|
||||||
|
"account_currency": account_currency,
|
||||||
|
"project": entry.dimensions.project or item.project,
|
||||||
|
},
|
||||||
|
item=item,
|
||||||
|
)
|
||||||
|
gl_dict.update(get_custom_dimension_overrides(entry))
|
||||||
|
gl_entries.append(gl_dict)
|
||||||
|
|
||||||
# credit amount in negative to knock off the debit entry
|
account_currency = get_account_currency(item.expense_account)
|
||||||
gl_entries.append(
|
|
||||||
self.get_gl_dict(
|
gl_entries.append(
|
||||||
{
|
self.get_gl_dict(
|
||||||
"account": item.expense_account,
|
{
|
||||||
"against": _inv_dict["account"],
|
"account": item.expense_account,
|
||||||
"cost_center": item.cost_center,
|
"against": _inv_dict["account"],
|
||||||
"debit": 0.0,
|
"cost_center": item.cost_center,
|
||||||
"credit": credit_amount * -1,
|
"debit": 0.0,
|
||||||
"remarks": _("Accounting Entry for LCV in Stock Entry {0}").format(self.name),
|
"credit": credit_amount * -1,
|
||||||
"debit_in_account_currency": flt(amount["amount"]),
|
"remarks": _("Accounting Entry for LCV in Stock Entry {0}").format(self.name),
|
||||||
"account_currency": account_currency,
|
"debit_in_account_currency": flt(entry.amount),
|
||||||
"project": item.project,
|
"account_currency": account_currency,
|
||||||
},
|
"project": item.project,
|
||||||
item=item,
|
},
|
||||||
)
|
item=item,
|
||||||
)
|
)
|
||||||
|
)
|
||||||
|
|
||||||
def update_work_order(self):
|
def update_work_order(self):
|
||||||
def _validate_work_order(pro_doc):
|
def _validate_work_order(pro_doc):
|
||||||
|
|||||||
@@ -908,55 +908,63 @@ class SubcontractingReceipt(SubcontractingController):
|
|||||||
)
|
)
|
||||||
|
|
||||||
def make_item_gl_entries_for_lcv(self, gl_entries, inventory_account_map):
|
def make_item_gl_entries_for_lcv(self, gl_entries, inventory_account_map):
|
||||||
|
from erpnext.stock.doctype.landed_cost_voucher.landed_cost_voucher import (
|
||||||
|
get_custom_dimension_overrides,
|
||||||
|
)
|
||||||
|
|
||||||
landed_cost_entries = self.get_item_account_wise_lcv_entries()
|
landed_cost_entries = self.get_item_account_wise_lcv_entries()
|
||||||
|
|
||||||
if not landed_cost_entries:
|
if not landed_cost_entries:
|
||||||
return
|
return
|
||||||
|
|
||||||
for item in self.items:
|
for item in self.items:
|
||||||
if item.landed_cost_voucher_amount and landed_cost_entries:
|
item_entries = landed_cost_entries.get((item.item_code, item.name), [])
|
||||||
|
|
||||||
|
if item.landed_cost_voucher_amount and item_entries:
|
||||||
remarks = _("Accounting Entry for Landed Cost Voucher for SCR {0}").format(self.name)
|
remarks = _("Accounting Entry for Landed Cost Voucher for SCR {0}").format(self.name)
|
||||||
if (item.item_code, item.name) in landed_cost_entries:
|
_inv_dict = self.get_inventory_account_dict(item, inventory_account_map)
|
||||||
_inv_dict = self.get_inventory_account_dict(item, inventory_account_map)
|
|
||||||
|
|
||||||
for account, amount in landed_cost_entries[(item.item_code, item.name)].items():
|
for entry in item_entries:
|
||||||
account_currency = get_account_currency(account)
|
if not (entry.amount or entry.base_amount):
|
||||||
credit_amount = (
|
continue
|
||||||
flt(amount["base_amount"])
|
|
||||||
if (amount["base_amount"] or account_currency != self.company_currency)
|
|
||||||
else flt(amount["amount"])
|
|
||||||
)
|
|
||||||
|
|
||||||
self.add_gl_entry(
|
account_currency = get_account_currency(entry.expense_account)
|
||||||
gl_entries=gl_entries,
|
credit_amount = (
|
||||||
account=account,
|
flt(entry.base_amount)
|
||||||
cost_center=item.cost_center,
|
if (entry.base_amount or account_currency != self.company_currency)
|
||||||
debit=0.0,
|
else flt(entry.amount)
|
||||||
credit=credit_amount,
|
)
|
||||||
remarks=remarks,
|
|
||||||
against_account=_inv_dict["account"],
|
|
||||||
credit_in_account_currency=flt(amount["amount"]),
|
|
||||||
account_currency=account_currency,
|
|
||||||
project=item.project,
|
|
||||||
item=item,
|
|
||||||
)
|
|
||||||
|
|
||||||
account_currency = get_account_currency(item.expense_account)
|
self.add_gl_entry(
|
||||||
|
gl_entries=gl_entries,
|
||||||
|
account=entry.expense_account,
|
||||||
|
cost_center=entry.dimensions.cost_center or item.cost_center,
|
||||||
|
debit=0.0,
|
||||||
|
credit=credit_amount,
|
||||||
|
remarks=remarks,
|
||||||
|
against_account=_inv_dict["account"],
|
||||||
|
credit_in_account_currency=flt(entry.amount),
|
||||||
|
account_currency=account_currency,
|
||||||
|
project=entry.dimensions.project or item.project,
|
||||||
|
item=item,
|
||||||
|
dimensions=get_custom_dimension_overrides(entry),
|
||||||
|
)
|
||||||
|
|
||||||
# credit amount in negative to knock off the debit entry
|
account_currency = get_account_currency(item.expense_account)
|
||||||
self.add_gl_entry(
|
|
||||||
gl_entries=gl_entries,
|
self.add_gl_entry(
|
||||||
account=item.expense_account,
|
gl_entries=gl_entries,
|
||||||
cost_center=item.cost_center,
|
account=item.expense_account,
|
||||||
debit=0.0,
|
cost_center=item.cost_center,
|
||||||
credit=credit_amount * -1,
|
debit=0.0,
|
||||||
remarks=remarks,
|
credit=credit_amount * -1,
|
||||||
against_account=_inv_dict["account"],
|
remarks=remarks,
|
||||||
debit_in_account_currency=flt(amount["amount"]),
|
against_account=_inv_dict["account"],
|
||||||
account_currency=account_currency,
|
debit_in_account_currency=flt(entry.amount),
|
||||||
project=item.project,
|
account_currency=account_currency,
|
||||||
item=item,
|
project=item.project,
|
||||||
)
|
item=item,
|
||||||
|
)
|
||||||
|
|
||||||
def auto_create_purchase_receipt(self):
|
def auto_create_purchase_receipt(self):
|
||||||
if frappe.db.get_single_value("Buying Settings", "auto_create_purchase_receipt"):
|
if frappe.db.get_single_value("Buying Settings", "auto_create_purchase_receipt"):
|
||||||
|
|||||||
Reference in New Issue
Block a user