Skip to content

Commit

Permalink
Merge pull request #40205 from frappe/mergify/bp/version-15-hotfix/pr…
Browse files Browse the repository at this point in the history
…-39584

fix: use receipt amount for reverse provisional entry (backport #39584)
  • Loading branch information
GursheenK authored Mar 3, 2024
2 parents 1d42171 + 823abfd commit d130aad
Show file tree
Hide file tree
Showing 3 changed files with 135 additions and 22 deletions.
20 changes: 15 additions & 5 deletions erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py
Original file line number Diff line number Diff line change
Expand Up @@ -1023,9 +1023,14 @@ def make_item_gl_entries(self, gl_entries):

if provisional_accounting_for_non_stock_items:
if item.purchase_receipt:
provisional_account = frappe.db.get_value(
"Purchase Receipt Item", item.pr_detail, "provisional_expense_account"
) or self.get_company_default("default_provisional_account")
provisional_account, pr_qty, pr_base_rate = frappe.get_cached_value(
"Purchase Receipt Item",
item.pr_detail,
["provisional_expense_account", "qty", "base_rate"],
)
provisional_account = provisional_account or self.get_company_default(
"default_provisional_account"
)
purchase_receipt_doc = purchase_receipt_doc_map.get(item.purchase_receipt)

if not purchase_receipt_doc:
Expand All @@ -1042,13 +1047,18 @@ def make_item_gl_entries(self, gl_entries):
"voucher_detail_no": item.pr_detail,
"account": provisional_account,
},
["name"],
"name",
)

if expense_booked_in_pr:
# Intentionally passing purchase invoice item to handle partial billing
purchase_receipt_doc.add_provisional_gl_entry(
item, gl_entries, self.posting_date, provisional_account, reverse=1
item,
gl_entries,
self.posting_date,
provisional_account,
reverse=1,
item_amount=(min(item.qty, pr_qty) * pr_base_rate),
)

if not self.is_internal_transfer():
Expand Down
128 changes: 114 additions & 14 deletions erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py
Original file line number Diff line number Diff line change
Expand Up @@ -1529,18 +1529,7 @@ def test_purchase_invoice_advance_taxes(self):
self.assertEqual(payment_entry.taxes[0].allocated_amount, 0)

def test_provisional_accounting_entry(self):
create_item("_Test Non Stock Item", is_stock_item=0)

provisional_account = create_account(
account_name="Provision Account",
parent_account="Current Liabilities - _TC",
company="_Test Company",
)

company = frappe.get_doc("Company", "_Test Company")
company.enable_provisional_accounting_for_non_stock_items = 1
company.default_provisional_account = provisional_account
company.save()
setup_provisional_accounting()

pr = make_purchase_receipt(
item_code="_Test Non Stock Item", posting_date=add_days(nowdate(), -2)
Expand Down Expand Up @@ -1584,8 +1573,97 @@ def test_provisional_accounting_entry(self):
self, pr.name, expected_gle_for_purchase_receipt_post_pi_cancel, pr.posting_date
)

company.enable_provisional_accounting_for_non_stock_items = 0
company.save()
toggle_provisional_accounting_setting()

def test_provisional_accounting_entry_for_over_billing(self):
setup_provisional_accounting()

# Configure Buying Settings to allow rate change
frappe.db.set_single_value("Buying Settings", "maintain_same_rate", 0)

# Create PR: rate = 1000, qty = 5
pr = make_purchase_receipt(
item_code="_Test Non Stock Item", rate=1000, posting_date=add_days(nowdate(), -2)
)

# Overbill PR: rate = 2000, qty = 10
pi = create_purchase_invoice_from_receipt(pr.name)
pi.set_posting_time = 1
pi.posting_date = add_days(pr.posting_date, -1)
pi.items[0].qty = 10
pi.items[0].rate = 2000
pi.items[0].expense_account = "Cost of Goods Sold - _TC"
pi.save()
pi.submit()

expected_gle = [
["Cost of Goods Sold - _TC", 20000, 0, add_days(pr.posting_date, -1)],
["Creditors - _TC", 0, 20000, add_days(pr.posting_date, -1)],
]

check_gl_entries(self, pi.name, expected_gle, pi.posting_date)

expected_gle_for_purchase_receipt = [
["Provision Account - _TC", 5000, 0, pr.posting_date],
["_Test Account Cost for Goods Sold - _TC", 0, 5000, pr.posting_date],
["Provision Account - _TC", 0, 5000, pi.posting_date],
["_Test Account Cost for Goods Sold - _TC", 5000, 0, pi.posting_date],
]

check_gl_entries(self, pr.name, expected_gle_for_purchase_receipt, pr.posting_date)

# Cancel purchase invoice to check reverse provisional entry cancellation
pi.cancel()

expected_gle_for_purchase_receipt_post_pi_cancel = [
["Provision Account - _TC", 0, 5000, pi.posting_date],
["_Test Account Cost for Goods Sold - _TC", 5000, 0, pi.posting_date],
]

check_gl_entries(
self, pr.name, expected_gle_for_purchase_receipt_post_pi_cancel, pr.posting_date
)

toggle_provisional_accounting_setting()

def test_provisional_accounting_entry_for_partial_billing(self):
setup_provisional_accounting()

# Configure Buying Settings to allow rate change
frappe.db.set_single_value("Buying Settings", "maintain_same_rate", 0)

# Create PR: rate = 1000, qty = 5
pr = make_purchase_receipt(
item_code="_Test Non Stock Item", rate=1000, posting_date=add_days(nowdate(), -2)
)

# Partially bill PR: rate = 500, qty = 2
pi = create_purchase_invoice_from_receipt(pr.name)
pi.set_posting_time = 1
pi.posting_date = add_days(pr.posting_date, -1)
pi.items[0].qty = 2
pi.items[0].rate = 500
pi.items[0].expense_account = "Cost of Goods Sold - _TC"
pi.save()
pi.submit()

expected_gle = [
["Cost of Goods Sold - _TC", 1000, 0, add_days(pr.posting_date, -1)],
["Creditors - _TC", 0, 1000, add_days(pr.posting_date, -1)],
]

check_gl_entries(self, pi.name, expected_gle, pi.posting_date)

expected_gle_for_purchase_receipt = [
["Provision Account - _TC", 5000, 0, pr.posting_date],
["_Test Account Cost for Goods Sold - _TC", 0, 5000, pr.posting_date],
["Provision Account - _TC", 0, 1000, pi.posting_date],
["_Test Account Cost for Goods Sold - _TC", 1000, 0, pi.posting_date],
]

check_gl_entries(self, pr.name, expected_gle_for_purchase_receipt, pr.posting_date)

toggle_provisional_accounting_setting()

def test_adjust_incoming_rate(self):
frappe.db.set_single_value("Buying Settings", "maintain_same_rate", 0)
Expand Down Expand Up @@ -2264,4 +2342,26 @@ def make_purchase_invoice_against_cost_center(**args):
return pi


def setup_provisional_accounting(**args):
args = frappe._dict(args)
create_item("_Test Non Stock Item", is_stock_item=0)
company = args.company or "_Test Company"
provisional_account = create_account(
account_name=args.account_name or "Provision Account",
parent_account=args.parent_account or "Current Liabilities - _TC",
company=company,
)
toggle_provisional_accounting_setting(
enable=1, company=company, provisional_account=provisional_account
)


def toggle_provisional_accounting_setting(**args):
args = frappe._dict(args)
company = frappe.get_doc("Company", args.company or "_Test Company")
company.enable_provisional_accounting_for_non_stock_items = args.enable or 0
company.default_provisional_account = args.provisional_account
company.save()


test_records = frappe.get_test_records("Purchase Invoice")
9 changes: 6 additions & 3 deletions erpnext/stock/doctype/purchase_receipt/purchase_receipt.py
Original file line number Diff line number Diff line change
Expand Up @@ -727,16 +727,19 @@ def make_divisional_loss_gl_entry(item, outgoing_amount):
)

def add_provisional_gl_entry(
self, item, gl_entries, posting_date, provisional_account, reverse=0
self, item, gl_entries, posting_date, provisional_account, reverse=0, item_amount=None
):
credit_currency = get_account_currency(provisional_account)
expense_account = item.expense_account
debit_currency = get_account_currency(item.expense_account)
remarks = self.get("remarks") or _("Accounting Entry for Service")
multiplication_factor = 1
amount = item.base_amount

if reverse:
multiplication_factor = -1
# Post reverse entry for previously posted amount
amount = item_amount
expense_account = frappe.db.get_value(
"Purchase Receipt Item", {"name": item.get("pr_detail")}, ["expense_account"]
)
Expand All @@ -746,7 +749,7 @@ def add_provisional_gl_entry(
account=provisional_account,
cost_center=item.cost_center,
debit=0.0,
credit=multiplication_factor * item.base_amount,
credit=multiplication_factor * amount,
remarks=remarks,
against_account=expense_account,
account_currency=credit_currency,
Expand All @@ -760,7 +763,7 @@ def add_provisional_gl_entry(
gl_entries=gl_entries,
account=expense_account,
cost_center=item.cost_center,
debit=multiplication_factor * item.base_amount,
debit=multiplication_factor * amount,
credit=0.0,
remarks=remarks,
against_account=provisional_account,
Expand Down

0 comments on commit d130aad

Please sign in to comment.