Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: GL Entries for receiving non CWIP assets using Purchase Receipt #37660

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
cfee650
fix: GL Entries for receiving non CWIP assets using Purchase Receipt
deepeshgarg007 Oct 17, 2023
4542626
fix: rearrange functions
deepeshgarg007 Oct 17, 2023
8579325
chore: rearrange functions
deepeshgarg007 Oct 17, 2023
249b432
chore: rearrange functions
deepeshgarg007 Oct 18, 2023
acf96d7
fix: Purchase Invoice GL entires for assets
deepeshgarg007 Oct 20, 2023
ff75be6
test: cwip accounting unit tests
deepeshgarg007 Oct 21, 2023
ab65414
chore: Attribute error
deepeshgarg007 Oct 21, 2023
b1d178c
chore: Purchase Invoice tests
deepeshgarg007 Oct 21, 2023
d986347
chore: Missing asset account
deepeshgarg007 Oct 21, 2023
22a19e9
chore: Missing asset account
deepeshgarg007 Oct 21, 2023
71247ef
chore: update tests
deepeshgarg007 Oct 22, 2023
0ea4c98
fix: Internal transfer GL Entries
deepeshgarg007 Oct 22, 2023
edd4550
test: Deprecate tests
deepeshgarg007 Oct 23, 2023
2bbd3dc
test: Depricate tests
deepeshgarg007 Oct 23, 2023
e86647e
test: Depricate tests
deepeshgarg007 Oct 23, 2023
c9edac1
chore: make `Reserve Stock` checkbox visible in SO
s-aga-r Oct 18, 2023
c8fb2cf
refactor: rename field `Auto Reserve Stock for Sales Order`
s-aga-r Oct 18, 2023
5e1dd9d
Merge branch 'version-14-hotfix' of https://github.com/frappe/erpnext…
deepeshgarg007 Oct 24, 2023
19a4517
feat: add fields to hold SO and SO Item ref in PR Item
s-aga-r Oct 19, 2023
3fc856e
test: Deprecate tests
deepeshgarg007 Oct 23, 2023
662b6ec
test: Depricate tests
deepeshgarg007 Oct 23, 2023
af8beb3
test: Depricate tests
deepeshgarg007 Oct 23, 2023
3bb92ca
Merge branch 'version-14-hotfix' of https://github.com/frappe/erpnext…
deepeshgarg007 Oct 24, 2023
c58185c
refactor: Remove expense included in valuation accounts
deepeshgarg007 Oct 23, 2023
bbb2433
chore: Add back default in transit warehousefield
deepeshgarg007 Oct 24, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
239 changes: 33 additions & 206 deletions erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
)
from erpnext.accounts.party import get_due_date, get_party_account
from erpnext.accounts.utils import get_account_currency, get_fiscal_year
from erpnext.assets.doctype.asset.asset import get_asset_account, is_cwip_accounting_enabled
from erpnext.assets.doctype.asset.asset import is_cwip_accounting_enabled
from erpnext.assets.doctype.asset_category.asset_category import get_asset_category_account
from erpnext.buying.utils import check_on_hold_or_closed_status
from erpnext.controllers.accounts_controller import validate_account_head
Expand Down Expand Up @@ -284,9 +284,6 @@ def set_expense_account(self, for_validate=False):
# in case of auto inventory accounting,
# expense account is always "Stock Received But Not Billed" for a stock item
# except opening entry, drop-ship entry and fixed asset items
if item.item_code:
asset_category = frappe.get_cached_value("Item", item.item_code, "asset_category")

if (
auto_accounting_for_stock
and item.item_code in stock_items
Expand Down Expand Up @@ -353,22 +350,26 @@ def set_expense_account(self, for_validate=False):
frappe.msgprint(msg, title=_("Expense Head Changed"))

item.expense_account = stock_not_billed_account

elif item.is_fixed_asset and not is_cwip_accounting_enabled(asset_category):
elif item.is_fixed_asset and item.pr_detail:
if not asset_received_but_not_billed:
asset_received_but_not_billed = self.get_company_default("asset_received_but_not_billed")
item.expense_account = asset_received_but_not_billed
elif item.is_fixed_asset:
account_type = (
"capital_work_in_progress_account"
if is_cwip_accounting_enabled(item.asset_category)
else "fixed_asset_account"
)
asset_category_account = get_asset_category_account(
"fixed_asset_account", item=item.item_code, company=self.company
account_type, item=item.item_code, company=self.company
)
if not asset_category_account:
form_link = get_link_to_form("Asset Category", asset_category)
form_link = get_link_to_form("Asset Category", item.asset_category)
throw(
_("Please set Fixed Asset Account in {} against {}.").format(form_link, self.company),
title=_("Missing Account"),
)
item.expense_account = asset_category_account
elif item.is_fixed_asset and item.pr_detail:
if not asset_received_but_not_billed:
asset_received_but_not_billed = self.get_company_default("asset_received_but_not_billed")
item.expense_account = asset_received_but_not_billed
elif not item.expense_account and for_validate:
throw(_("Expense account is mandatory for item {0}").format(item.item_code or item.item_name))

Expand Down Expand Up @@ -591,12 +592,12 @@ def make_gl_entries(self, gl_entries=None, from_repost=False):

def get_gl_entries(self, warehouse_account=None):
self.auto_accounting_for_stock = erpnext.is_perpetual_inventory_enabled(self.company)
self.asset_received_but_not_billed = self.get_company_default("asset_received_but_not_billed")

if self.auto_accounting_for_stock:
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")
else:
self.stock_received_but_not_billed = None
self.expenses_included_in_valuation = None

self.negative_expense_to_be_booked = 0.0
gl_entries = []
Expand All @@ -605,9 +606,6 @@ def get_gl_entries(self, warehouse_account=None):
self.make_item_gl_entries(gl_entries)
self.make_precision_loss_gl_entry(gl_entries)

if self.check_asset_cwip_enabled():
self.get_asset_gl_entry(gl_entries)

self.make_tax_gl_entries(gl_entries)
self.make_internal_transfer_gl_entries(gl_entries)

Expand Down Expand Up @@ -711,7 +709,11 @@ def make_item_gl_entries(self, gl_entries):
if item.item_code:
asset_category = frappe.get_cached_value("Item", item.item_code, "asset_category")

if self.update_stock and self.auto_accounting_for_stock and item.item_code in stock_items:
if (
self.update_stock
and self.auto_accounting_for_stock
and (item.item_code in stock_items or item.is_fixed_asset)
):
# warehouse account
warehouse_debit_amount = self.make_stock_adjustment_entry(
gl_entries, item, voucher_wise_stock_value, account_currency
Expand Down Expand Up @@ -826,9 +828,7 @@ def make_item_gl_entries(self, gl_entries):
)
)

elif not item.is_fixed_asset or (
item.is_fixed_asset and not is_cwip_accounting_enabled(asset_category)
):
else:
expense_account = (
item.expense_account
if (not item.enable_deferred_expense or self.is_return)
Expand Down Expand Up @@ -921,40 +921,6 @@ def make_item_gl_entries(self, gl_entries):
)
)

# If asset is bought through this document and not linked to PR
if self.update_stock and item.landed_cost_voucher_amount:
expenses_included_in_asset_valuation = self.get_company_default(
"expenses_included_in_asset_valuation"
)
# Amount added through landed-cost-voucher
gl_entries.append(
self.get_gl_dict(
{
"account": expenses_included_in_asset_valuation,
"against": expense_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": expense_account,
"against": expenses_included_in_asset_valuation,
"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 asset bought through this document
assets = frappe.db.get_all(
"Asset", filters={"purchase_invoice": self.name, "item_code": item.item_code}
Expand All @@ -979,11 +945,16 @@ def make_item_gl_entries(self, gl_entries):
(item.purchase_receipt, valuation_tax_accounts),
)

stock_rbnb = (
self.asset_received_but_not_billed
if item.is_fixed_asset
else self.stock_received_but_not_billed
)
if not negative_expense_booked_in_pr:
gl_entries.append(
self.get_gl_dict(
{
"account": self.stock_received_but_not_billed,
"account": stock_rbnb,
"against": self.supplier,
"debit": flt(item.item_tax_amount, item.precision("item_tax_amount")),
"remarks": self.remarks or _("Accounting Entry for Stock"),
Expand All @@ -998,156 +969,12 @@ def make_item_gl_entries(self, gl_entries):
item.item_tax_amount, item.precision("item_tax_amount")
)

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.db.get_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": 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
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 make_stock_adjustment_entry(
self, gl_entries, item, voucher_wise_stock_value, account_currency
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2497,12 +2497,6 @@ def test_inter_company_transaction_without_default_warehouse(self):
"stock_received_but_not_billed",
"Stock Received But Not Billed - _TC1",
)
frappe.db.set_value(
"Company",
"_Test Company 1",
"expenses_included_in_valuation",
"Expenses Included In Valuation - _TC1",
)

# begin test
si = create_sales_invoice(
Expand Down Expand Up @@ -2540,7 +2534,7 @@ def test_inter_company_transaction_without_default_warehouse(self):

# tear down
frappe.local.enable_perpetual_inventory["_Test Company 1"] = old_perpetual_inventory
frappe.db.set_value("Stock Settings", None, "allow_negative_stock", old_negative_stock)
frappe.db.set_single_value("Stock Settings", "allow_negative_stock", old_negative_stock)

def test_sle_for_target_warehouse(self):
se = make_stock_entry(
Expand Down
2 changes: 1 addition & 1 deletion erpnext/accounts/general_ledger.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ def make_gl_entries(
from_repost=from_repost,
)
save_entries(gl_map, adv_adj, update_outstanding, from_repost)
# Post GL Map proccess there may no be any GL Entries
# Post GL Map process there may no be any GL Entries
elif gl_map:
frappe.throw(
_(
Expand Down
9 changes: 5 additions & 4 deletions erpnext/assets/doctype/asset/test_asset.py
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,7 @@ def test_purchase_of_grouped_asset(self):
def test_is_fixed_asset_set(self):
asset = create_asset(is_existing_asset=1)
doc = frappe.new_doc("Purchase Invoice")
doc.company = "_Test Company"
doc.supplier = "_Test Supplier"
doc.append("items", {"item_code": "Macbook Pro", "qty": 1, "asset": asset.name})

Expand Down Expand Up @@ -487,7 +488,7 @@ def test_expense_head(self):

self.assertEqual("Asset Received But Not Billed - _TC", doc.items[0].expense_account)

# CWIP: Capital Work In Progress
# Capital Work In Progress
def test_cwip_accounting(self):
pr = make_purchase_receipt(
item_code="Macbook Pro", qty=1, rate=5000, do_not_submit=True, location="Test Location"
Expand Down Expand Up @@ -520,7 +521,8 @@ def test_cwip_accounting(self):
pr.submit()

expected_gle = (
("Asset Received But Not Billed - _TC", 0.0, 5250.0),
("_Test Account Shipping Charges - _TC", 0.0, 250.0),
("Asset Received But Not Billed - _TC", 0.0, 5000.0),
("CWIP Account - _TC", 5250.0, 0.0),
)

Expand All @@ -539,9 +541,8 @@ def test_cwip_accounting(self):
expected_gle = (
("_Test Account Service Tax - _TC", 250.0, 0.0),
("_Test Account Shipping Charges - _TC", 250.0, 0.0),
("Asset Received But Not Billed - _TC", 5250.0, 0.0),
("Asset Received But Not Billed - _TC", 5000.0, 0.0),
("Creditors - _TC", 0.0, 5500.0),
("Expenses Included In Asset Valuation - _TC", 0.0, 250.0),
)

pi_gle = frappe.db.sql(
Expand Down
Loading
Loading