feat: adjust purchase receipt valuation rate as per purchase invoice rate

This commit is contained in:
Rohit Waghchaure 2023-02-22 12:30:09 +05:30
parent 9cd42dd60f
commit eab775ef32
5 changed files with 103 additions and 6 deletions

View File

@ -528,6 +528,32 @@ class PurchaseInvoice(BuyingController):
self.update_advance_tax_references()
self.process_common_party_accounting()
self.adjust_incoming_rate_of_purchase_receipt()
def adjust_incoming_rate_of_purchase_receipt(self):
if (
not frappe.db.get_single_value(
"Buying Settings", "adjust_incoming_rate_based_on_purchase_invoice_rate"
)
and self.is_subcontracted
):
return
purchase_receipts = []
for item in self.items:
if item.purchase_receipt and item.purchase_receipt not in purchase_receipts:
purchase_receipts.append(item.purchase_receipt)
for purchase_receipt in purchase_receipts:
doc = frappe.get_doc("Purchase Receipt", purchase_receipt)
doc.docstatus = 2
doc.update_stock_ledger(allow_negative_stock=True, via_landed_cost_voucher=True)
doc.make_gl_entries_on_cancel()
doc.docstatus = 1
doc.update_stock_ledger(allow_negative_stock=True, via_landed_cost_voucher=True)
doc.make_gl_entries()
doc.repost_future_sle_and_gle()
def make_gl_entries(self, gl_entries=None, from_repost=False):
if not gl_entries:
@ -1423,6 +1449,7 @@ class PurchaseInvoice(BuyingController):
"Tax Withheld Vouchers",
)
self.update_advance_tax_references(cancel=1)
self.adjust_incoming_rate_of_purchase_receipt()
def update_project(self):
project_list = []
@ -1485,11 +1512,17 @@ class PurchaseInvoice(BuyingController):
if po_details:
updated_pr += update_billed_amount_based_on_po(po_details, update_modified)
adjust_incoming_rate = frappe.db.get_single_value(
"Buying Settings", "adjust_incoming_rate_based_on_purchase_invoice_rate"
)
for pr in set(updated_pr):
from erpnext.stock.doctype.purchase_receipt.purchase_receipt import update_billing_percentage
pr_doc = frappe.get_doc("Purchase Receipt", pr)
update_billing_percentage(pr_doc, update_modified=update_modified)
update_billing_percentage(
pr_doc, update_modified=update_modified, adjust_incoming_rate=adjust_incoming_rate
)
def get_pr_details_billed_amt(self):
# Get billed amount based on purchase receipt item reference (pr_detail) in purchase invoice

View File

@ -18,6 +18,7 @@
"pr_required",
"column_break_12",
"maintain_same_rate",
"adjust_incoming_rate_based_on_purchase_invoice_rate",
"allow_multiple_items",
"bill_for_rejected_quantity_in_purchase_invoice",
"disable_last_purchase_rate",
@ -147,6 +148,14 @@
"fieldname": "show_pay_button",
"fieldtype": "Check",
"label": "Show Pay Button in Purchase Order Portal"
},
{
"default": "0",
"depends_on": "eval: !doc.maintain_same_rate",
"description": "Users can enable the checkbox If they want to adjust the incoming rate (set using purchase receipt) based on the purchase invoice rate.",
"fieldname": "adjust_incoming_rate_based_on_purchase_invoice_rate",
"fieldtype": "Check",
"label": "Adjust Incoming Rate Based on Purchase Invoice Rate"
}
],
"icon": "fa fa-cog",
@ -154,7 +163,7 @@
"index_web_pages_for_search": 1,
"issingle": 1,
"links": [],
"modified": "2023-02-15 14:42:10.200679",
"modified": "2023-02-20 14:25:58.544143",
"modified_by": "Administrator",
"module": "Buying",
"name": "Buying Settings",

View File

@ -265,7 +265,10 @@ class BuyingController(SubcontractingController):
) / qty_in_stock_uom
else:
item.valuation_rate = (
item.base_net_amount + item.item_tax_amount + flt(item.landed_cost_voucher_amount)
item.base_net_amount
+ item.item_tax_amount
+ flt(item.landed_cost_voucher_amount)
+ flt(item.get("adjust_incoming_rate"))
) / qty_in_stock_uom
else:
item.valuation_rate = 0.0

View File

@ -293,6 +293,7 @@ class PurchaseReceipt(BuyingController):
get_purchase_document_details,
)
stock_rbnb = None
if erpnext.is_perpetual_inventory_enabled(self.company):
stock_rbnb = self.get_company_default("stock_received_but_not_billed")
landed_cost_entries = get_item_account_wise_additional_cost(self.name)
@ -450,6 +451,21 @@ class PurchaseReceipt(BuyingController):
item=d,
)
if d.adjust_incoming_rate and stock_rbnb:
account_currency = get_account_currency(stock_rbnb)
self.add_gl_entry(
gl_entries=gl_entries,
account=stock_rbnb,
cost_center=d.cost_center,
debit=0.0,
credit=flt(d.adjust_incoming_rate),
remarks=_("Adjustment based on Purchase Invoice rate"),
against_account=warehouse_account_name,
account_currency=account_currency,
project=d.project,
item=d,
)
# sub-contracting warehouse
if flt(d.rm_supp_cost) and warehouse_account.get(self.supplier_warehouse):
self.add_gl_entry(
@ -470,6 +486,7 @@ class PurchaseReceipt(BuyingController):
+ flt(d.landed_cost_voucher_amount)
+ flt(d.rm_supp_cost)
+ flt(d.item_tax_amount)
+ flt(d.adjust_incoming_rate)
)
divisional_loss = flt(
@ -765,7 +782,7 @@ class PurchaseReceipt(BuyingController):
updated_pr += update_billed_amount_based_on_po(po_details, update_modified)
for pr in set(updated_pr):
pr_doc = self if (pr == self.name) else frappe.get_cached_doc("Purchase Receipt", pr)
pr_doc = self if (pr == self.name) else frappe.get_doc("Purchase Receipt", pr)
update_billing_percentage(pr_doc, update_modified=update_modified)
self.load_from_db()
@ -881,7 +898,7 @@ def get_billed_amount_against_po(po_items):
return {d.po_detail: flt(d.billed_amt) for d in query}
def update_billing_percentage(pr_doc, update_modified=True):
def update_billing_percentage(pr_doc, update_modified=True, adjust_incoming_rate=False):
# Reload as billed amount was set in db directly
pr_doc.load_from_db()
@ -897,6 +914,12 @@ def update_billing_percentage(pr_doc, update_modified=True):
total_amount += total_billable_amount
total_billed_amount += flt(item.billed_amt)
if adjust_incoming_rate:
adjusted_amt = 0.0
if item.billed_amt and item.amount:
adjusted_amt = flt(item.billed_amt) - flt(item.amount)
item.db_set("adjust_incoming_rate", adjusted_amt, update_modified=False)
percent_billed = round(100 * (total_billed_amount / (total_amount or 1)), 6)
pr_doc.db_set("per_billed", percent_billed)
@ -906,6 +929,26 @@ def update_billing_percentage(pr_doc, update_modified=True):
pr_doc.set_status(update=True)
pr_doc.notify_update()
if adjust_incoming_rate:
adjust_incoming_rate_for_pr(pr_doc)
def adjust_incoming_rate_for_pr(doc):
doc.update_valuation_rate(reset_outgoing_rate=False)
for item in doc.get("items"):
item.db_update()
doc.docstatus = 2
doc.update_stock_ledger(allow_negative_stock=True, via_landed_cost_voucher=True)
doc.make_gl_entries_on_cancel()
# update stock & gl entries for submit state of PR
doc.docstatus = 1
doc.update_stock_ledger(allow_negative_stock=True, via_landed_cost_voucher=True)
doc.make_gl_entries()
doc.repost_future_sle_and_gle()
def get_item_wise_returned_qty(pr_doc):
items = [d.name for d in pr_doc.items]

View File

@ -69,6 +69,7 @@
"item_tax_amount",
"rm_supp_cost",
"landed_cost_voucher_amount",
"adjust_incoming_rate",
"billed_amt",
"warehouse_and_reference",
"warehouse",
@ -1007,12 +1008,20 @@
"fieldtype": "Check",
"label": "Has Item Scanned",
"read_only": 1
},
{
"fieldname": "adjust_incoming_rate",
"fieldtype": "Currency",
"label": "Adjust Incoming Rate (Purchase Invoice)",
"no_copy": 1,
"print_hide": 1,
"read_only": 1
}
],
"idx": 1,
"istable": 1,
"links": [],
"modified": "2023-01-18 15:48:58.114923",
"modified": "2023-02-28 12:05:59.732266",
"modified_by": "Administrator",
"module": "Stock",
"name": "Purchase Receipt Item",