Skip to content

Commit

Permalink
fix: last purchase rate for purchase invoice (backport frappe#43448) (f…
Browse files Browse the repository at this point in the history
…rappe#43452)

* fix: last purchase rate for purchase invoice

(cherry picked from commit fb9d106)

# Conflicts:
#	erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py

* chore: fix conflicts

---------

Co-authored-by: Rohit Waghchaure <rohitw1991@gmail.com>
  • Loading branch information
2 people authored and khalandarsihan committed Oct 6, 2024
1 parent 5b43822 commit 0da64d9
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 30 deletions.
18 changes: 18 additions & 0 deletions erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py
Original file line number Diff line number Diff line change
Expand Up @@ -2292,6 +2292,24 @@ def test_adjust_incoming_rate_from_pi_with_multi_currency(self):

frappe.db.set_single_value("Buying Settings", "maintain_same_rate", 1)

def test_last_purchase_rate(self):
item = create_item("_Test Item For Last Purchase Rate from PI", is_stock_item=1)
pi1 = make_purchase_invoice(item_code=item.item_code, qty=10, rate=100)
item.reload()
self.assertEqual(item.last_purchase_rate, 100)

pi2 = make_purchase_invoice(item_code=item.item_code, qty=10, rate=200)
item.reload()
self.assertEqual(item.last_purchase_rate, 200)

pi2.cancel()
item.reload()
self.assertEqual(item.last_purchase_rate, 100)

pi1.cancel()
item.reload()
self.assertEqual(item.last_purchase_rate, 0)


def set_advance_flag(company, flag, default_account):
frappe.db.set_value(
Expand Down
8 changes: 5 additions & 3 deletions erpnext/controllers/buying_controller.py
Original file line number Diff line number Diff line change
Expand Up @@ -702,9 +702,11 @@ def on_cancel(self):
if self.get("is_return"):
return

if self.doctype in ["Purchase Order", "Purchase Receipt"] and not frappe.db.get_single_value(
"Buying Settings", "disable_last_purchase_rate"
):
if self.doctype in [
"Purchase Order",
"Purchase Receipt",
"Purchase Invoice",
] and not frappe.db.get_single_value("Buying Settings", "disable_last_purchase_rate"):
update_last_purchase_rate(self, is_submit=0)

if self.doctype in ["Purchase Receipt", "Purchase Invoice"]:
Expand Down
4 changes: 4 additions & 0 deletions erpnext/public/js/controllers/transaction.js
Original file line number Diff line number Diff line change
Expand Up @@ -1277,6 +1277,10 @@ erpnext.TransactionController = class TransactionController extends erpnext.taxe
.filter(Boolean).length > 0;
} else if (this.frm.doc?.items) {
let first_row = this.frm.doc.items[0];
if (!first_row) {
return false
};

let mapped_rows = mappped_fields.filter(d => first_row[d])

return mapped_rows?.length > 0;
Expand Down
71 changes: 44 additions & 27 deletions erpnext/stock/doctype/item/item.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
strip_html,
)
from frappe.utils.html_utils import clean_html
from pypika import Order

import erpnext
from erpnext.controllers.item_variant import (
Expand Down Expand Up @@ -1136,34 +1137,10 @@ def get_last_purchase_details(item_code, doc_name=None, conversion_rate=1.0):
"""returns last purchase details in stock uom"""
# get last purchase order item details

last_purchase_order = frappe.db.sql(
"""\
select po.name, po.transaction_date, po.conversion_rate,
po_item.conversion_factor, po_item.base_price_list_rate,
po_item.discount_percentage, po_item.base_rate, po_item.base_net_rate
from `tabPurchase Order` po, `tabPurchase Order Item` po_item
where po.docstatus = 1 and po_item.item_code = %s and po.name != %s and
po.name = po_item.parent
order by po.transaction_date desc, po.name desc
limit 1""",
(item_code, cstr(doc_name)),
as_dict=1,
)
last_purchase_order = get_purchase_voucher_details("Purchase Order", item_code, doc_name)

# get last purchase receipt item details
last_purchase_receipt = frappe.db.sql(
"""\
select pr.name, pr.posting_date, pr.posting_time, pr.conversion_rate,
pr_item.conversion_factor, pr_item.base_price_list_rate, pr_item.discount_percentage,
pr_item.base_rate, pr_item.base_net_rate
from `tabPurchase Receipt` pr, `tabPurchase Receipt Item` pr_item
where pr.docstatus = 1 and pr_item.item_code = %s and pr.name != %s and
pr.name = pr_item.parent
order by pr.posting_date desc, pr.posting_time desc, pr.name desc
limit 1""",
(item_code, cstr(doc_name)),
as_dict=1,
)
last_purchase_receipt = get_purchase_voucher_details("Purchase Receipt", item_code, doc_name)

purchase_order_date = getdate(
last_purchase_order and last_purchase_order[0].transaction_date or "1900-01-01"
Expand All @@ -1184,7 +1161,13 @@ def get_last_purchase_details(item_code, doc_name=None, conversion_rate=1.0):
purchase_date = purchase_receipt_date

else:
return frappe._dict()
last_purchase_invoice = get_purchase_voucher_details("Purchase Invoice", item_code, doc_name)

if last_purchase_invoice:
last_purchase = last_purchase_invoice[0]
purchase_date = getdate(last_purchase.posting_date)
else:
return frappe._dict()

conversion_factor = flt(last_purchase.conversion_factor)
out = frappe._dict(
Expand All @@ -1210,6 +1193,40 @@ def get_last_purchase_details(item_code, doc_name=None, conversion_rate=1.0):
return out


def get_purchase_voucher_details(doctype, item_code, document_name):
parent_doc = frappe.qb.DocType(doctype)
child_doc = frappe.qb.DocType(doctype + " Item")

query = (
frappe.qb.from_(parent_doc)
.inner_join(child_doc)
.on(parent_doc.name == child_doc.parent)
.select(
parent_doc.name,
parent_doc.conversion_rate,
child_doc.conversion_factor,
child_doc.base_price_list_rate,
child_doc.discount_percentage,
child_doc.base_rate,
child_doc.base_net_rate,
)
.where(parent_doc.docstatus == 1)
.where(child_doc.item_code == item_code)
.where(parent_doc.name != document_name)
)

if doctype in ("Purchase Receipt", "Purchase Invoice"):
query = query.select(parent_doc.posting_date, parent_doc.posting_time)
query = query.orderby(
parent_doc.posting_date, parent_doc.posting_time, parent_doc.name, order=Order.desc
)
else:
query = query.select(parent_doc.transaction_date)
query = query.orderby(parent_doc.transaction_date, parent_doc.name, order=Order.desc)

return query.run(as_dict=1)


def check_stock_uom_with_bin(item, stock_uom):
if stock_uom == frappe.db.get_value("Item", item, "stock_uom"):
return
Expand Down

0 comments on commit 0da64d9

Please sign in to comment.