fix: GP incorrect buying amount if no upd on SI and Delivery Note
This commit is contained in:
parent
8d30ebb12b
commit
e4d16c31da
@ -3,7 +3,8 @@
|
|||||||
|
|
||||||
|
|
||||||
import frappe
|
import frappe
|
||||||
from frappe import _, scrub
|
from frappe import _, qb, scrub
|
||||||
|
from frappe.query_builder import Order
|
||||||
from frappe.utils import cint, flt, formatdate
|
from frappe.utils import cint, flt, formatdate
|
||||||
|
|
||||||
from erpnext.controllers.queries import get_match_cond
|
from erpnext.controllers.queries import get_match_cond
|
||||||
@ -398,6 +399,7 @@ class GrossProfitGenerator(object):
|
|||||||
self.average_buying_rate = {}
|
self.average_buying_rate = {}
|
||||||
self.filters = frappe._dict(filters)
|
self.filters = frappe._dict(filters)
|
||||||
self.load_invoice_items()
|
self.load_invoice_items()
|
||||||
|
self.get_delivery_notes()
|
||||||
|
|
||||||
if filters.group_by == "Invoice":
|
if filters.group_by == "Invoice":
|
||||||
self.group_items_by_invoice()
|
self.group_items_by_invoice()
|
||||||
@ -591,6 +593,21 @@ class GrossProfitGenerator(object):
|
|||||||
|
|
||||||
return flt(buying_amount, self.currency_precision)
|
return flt(buying_amount, self.currency_precision)
|
||||||
|
|
||||||
|
def calculate_buying_amount_from_sle(self, row, my_sle, parenttype, parent, item_row, item_code):
|
||||||
|
for i, sle in enumerate(my_sle):
|
||||||
|
# find the stock valution rate from stock ledger entry
|
||||||
|
if (
|
||||||
|
sle.voucher_type == parenttype
|
||||||
|
and parent == sle.voucher_no
|
||||||
|
and sle.voucher_detail_no == item_row
|
||||||
|
):
|
||||||
|
previous_stock_value = len(my_sle) > i + 1 and flt(my_sle[i + 1].stock_value) or 0.0
|
||||||
|
|
||||||
|
if previous_stock_value:
|
||||||
|
return abs(previous_stock_value - flt(sle.stock_value)) * flt(row.qty) / abs(flt(sle.qty))
|
||||||
|
else:
|
||||||
|
return flt(row.qty) * self.get_average_buying_rate(row, item_code)
|
||||||
|
|
||||||
def get_buying_amount(self, row, item_code):
|
def get_buying_amount(self, row, item_code):
|
||||||
# IMP NOTE
|
# IMP NOTE
|
||||||
# stock_ledger_entries should already be filtered by item_code and warehouse and
|
# stock_ledger_entries should already be filtered by item_code and warehouse and
|
||||||
@ -607,19 +624,22 @@ class GrossProfitGenerator(object):
|
|||||||
if row.dn_detail:
|
if row.dn_detail:
|
||||||
parenttype, parent = "Delivery Note", row.delivery_note
|
parenttype, parent = "Delivery Note", row.delivery_note
|
||||||
|
|
||||||
for i, sle in enumerate(my_sle):
|
return self.calculate_buying_amount_from_sle(
|
||||||
# find the stock valution rate from stock ledger entry
|
row, my_sle, parenttype, parent, row.item_row, item_code
|
||||||
if (
|
)
|
||||||
sle.voucher_type == parenttype
|
elif self.delivery_notes.get((row.parent, row.item_code), None):
|
||||||
and parent == sle.voucher_no
|
# check if Invoice has delivery notes
|
||||||
and sle.voucher_detail_no == row.item_row
|
dn = self.delivery_notes.get((row.parent, row.item_code))
|
||||||
):
|
parenttype, parent, item_row, warehouse = (
|
||||||
previous_stock_value = len(my_sle) > i + 1 and flt(my_sle[i + 1].stock_value) or 0.0
|
"Delivery Note",
|
||||||
|
dn["delivery_note"],
|
||||||
if previous_stock_value:
|
dn["item_row"],
|
||||||
return abs(previous_stock_value - flt(sle.stock_value)) * flt(row.qty) / abs(flt(sle.qty))
|
dn["warehouse"],
|
||||||
else:
|
)
|
||||||
return flt(row.qty) * self.get_average_buying_rate(row, item_code)
|
my_sle = self.sle.get((item_code, warehouse))
|
||||||
|
return self.calculate_buying_amount_from_sle(
|
||||||
|
row, my_sle, parenttype, parent, item_row, item_code
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
return flt(row.qty) * self.get_average_buying_rate(row, item_code)
|
return flt(row.qty) * self.get_average_buying_rate(row, item_code)
|
||||||
|
|
||||||
@ -753,6 +773,29 @@ class GrossProfitGenerator(object):
|
|||||||
as_dict=1,
|
as_dict=1,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def get_delivery_notes(self):
|
||||||
|
self.delivery_notes = frappe._dict({})
|
||||||
|
if self.si_list:
|
||||||
|
invoices = [x.parent for x in self.si_list]
|
||||||
|
dni = qb.DocType("Delivery Note Item")
|
||||||
|
delivery_notes = (
|
||||||
|
qb.from_(dni)
|
||||||
|
.select(
|
||||||
|
dni.against_sales_invoice.as_("sales_invoice"),
|
||||||
|
dni.item_code,
|
||||||
|
dni.warehouse,
|
||||||
|
dni.parent.as_("delivery_note"),
|
||||||
|
dni.name.as_("item_row"),
|
||||||
|
)
|
||||||
|
.where((dni.docstatus == 1) & (dni.against_sales_invoice.isin(invoices)))
|
||||||
|
.groupby(dni.against_sales_invoice, dni.item_code)
|
||||||
|
.orderby(dni.creation, order=Order.desc)
|
||||||
|
.run(as_dict=True)
|
||||||
|
)
|
||||||
|
|
||||||
|
for entry in delivery_notes:
|
||||||
|
self.delivery_notes[(entry.sales_invoice, entry.item_code)] = entry
|
||||||
|
|
||||||
def group_items_by_invoice(self):
|
def group_items_by_invoice(self):
|
||||||
"""
|
"""
|
||||||
Turns list of Sales Invoice Items to a tree of Sales Invoices with their Items as children.
|
Turns list of Sales Invoice Items to a tree of Sales Invoices with their Items as children.
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user