mirror of
https://github.com/frappe/erpnext.git
synced 2026-04-23 16:48:30 +00:00
Co-authored-by: Mihir Kandoi <kandoimihir@gmail.com> fix: add drop ship logic in gross profit report (#54220)
This commit is contained in:
@@ -578,7 +578,11 @@ class GrossProfitGenerator:
|
|||||||
|
|
||||||
# get buying rate
|
# get buying rate
|
||||||
if flt(row.qty):
|
if flt(row.qty):
|
||||||
row.buying_rate = flt(row.buying_amount / flt(row.qty), self.float_precision)
|
row.buying_rate = (
|
||||||
|
flt(row.buying_amount / flt(row.qty), self.float_precision)
|
||||||
|
if not row.delivered_by_supplier
|
||||||
|
else None
|
||||||
|
)
|
||||||
row.base_rate = flt(row.base_amount / flt(row.qty), self.float_precision)
|
row.base_rate = flt(row.base_amount / flt(row.qty), self.float_precision)
|
||||||
else:
|
else:
|
||||||
if self.is_not_invoice_row(row):
|
if self.is_not_invoice_row(row):
|
||||||
@@ -630,7 +634,8 @@ class GrossProfitGenerator:
|
|||||||
returned_item_row.qty += row.qty
|
returned_item_row.qty += row.qty
|
||||||
returned_item_row.base_amount += row.base_amount
|
returned_item_row.base_amount += row.base_amount
|
||||||
|
|
||||||
row.buying_amount = flt(flt(row.qty) * flt(row.buying_rate), self.currency_precision)
|
if not row.delivered_by_supplier:
|
||||||
|
row.buying_amount = flt(flt(row.qty) * flt(row.buying_rate), self.currency_precision)
|
||||||
|
|
||||||
def get_average_rate_based_on_group_by(self):
|
def get_average_rate_based_on_group_by(self):
|
||||||
for key in list(self.grouped):
|
for key in list(self.grouped):
|
||||||
@@ -799,6 +804,26 @@ class GrossProfitGenerator:
|
|||||||
return self.calculate_buying_amount_from_sle(
|
return self.calculate_buying_amount_from_sle(
|
||||||
row, my_sle, parenttype, parent, item_row, item_code
|
row, my_sle, parenttype, parent, item_row, item_code
|
||||||
)
|
)
|
||||||
|
elif (
|
||||||
|
row.delivered_by_supplier
|
||||||
|
and row.so_detail
|
||||||
|
and (
|
||||||
|
po_details := frappe.get_all(
|
||||||
|
"Purchase Order Item",
|
||||||
|
filters={"sales_order_item": row.so_detail, "docstatus": 1},
|
||||||
|
pluck="name",
|
||||||
|
)
|
||||||
|
)
|
||||||
|
):
|
||||||
|
from frappe.query_builder.functions import Sum
|
||||||
|
|
||||||
|
table = frappe.qb.DocType("Purchase Invoice Item")
|
||||||
|
query = (
|
||||||
|
frappe.qb.from_(table)
|
||||||
|
.select(Sum(table.stock_qty * table.base_net_rate))
|
||||||
|
.where((table.po_detail.isin(po_details)) & (table.docstatus == 1))
|
||||||
|
)
|
||||||
|
return flt(query.run()[0][0])
|
||||||
elif row.sales_order and row.so_detail:
|
elif row.sales_order and row.so_detail:
|
||||||
incoming_amount = self.get_buying_amount_from_so_dn(row.sales_order, row.so_detail, item_code)
|
incoming_amount = self.get_buying_amount_from_so_dn(row.sales_order, row.so_detail, item_code)
|
||||||
if incoming_amount:
|
if incoming_amount:
|
||||||
@@ -951,6 +976,7 @@ class GrossProfitGenerator:
|
|||||||
SalesInvoice.is_return,
|
SalesInvoice.is_return,
|
||||||
SalesInvoiceItem.cost_center,
|
SalesInvoiceItem.cost_center,
|
||||||
SalesInvoiceItem.serial_and_batch_bundle,
|
SalesInvoiceItem.serial_and_batch_bundle,
|
||||||
|
SalesInvoiceItem.delivered_by_supplier,
|
||||||
)
|
)
|
||||||
|
|
||||||
if self.filters.group_by == "Sales Person":
|
if self.filters.group_by == "Sales Person":
|
||||||
|
|||||||
@@ -731,6 +731,31 @@ class TestGrossProfit(ERPNextTestSuite):
|
|||||||
self.assertEqual(total[7], 1000.0)
|
self.assertEqual(total[7], 1000.0)
|
||||||
self.assertEqual(total[8], 100.0)
|
self.assertEqual(total[8], 100.0)
|
||||||
|
|
||||||
|
def test_drop_ship(self):
|
||||||
|
from erpnext.buying.doctype.purchase_order.purchase_order import make_purchase_invoice
|
||||||
|
from erpnext.selling.doctype.sales_order.sales_order import make_purchase_order, make_sales_invoice
|
||||||
|
from erpnext.selling.doctype.sales_order.test_sales_order import make_sales_order
|
||||||
|
from erpnext.stock.doctype.item.test_item import make_item
|
||||||
|
|
||||||
|
item = make_item("_Test Drop Ship Item", properties={"is_stock_item": 1, "delivered_by_supplier": 1})
|
||||||
|
|
||||||
|
so = make_sales_order(item=item.name, qty=10, rate=100)
|
||||||
|
po = make_purchase_order(so.name, selected_items=[so.items[0]])[0]
|
||||||
|
po.items[0].rate = 80
|
||||||
|
po.supplier = "_Test Supplier"
|
||||||
|
po.submit()
|
||||||
|
make_purchase_invoice(po.name).submit()
|
||||||
|
si = make_sales_invoice(so.name).submit()
|
||||||
|
|
||||||
|
filters = frappe._dict(
|
||||||
|
company=si.company, from_date=si.posting_date, to_date=si.posting_date, group_by="Invoice"
|
||||||
|
)
|
||||||
|
|
||||||
|
_, data = execute(filters=filters)
|
||||||
|
self.assertEqual(data[1].buying_amount, 800)
|
||||||
|
self.assertIsNone(data[1].buying_rate)
|
||||||
|
self.assertEqual(data[1]["gross_profit_%"], 20)
|
||||||
|
|
||||||
|
|
||||||
def make_sales_person(sales_person_name="_Test Sales Person"):
|
def make_sales_person(sales_person_name="_Test Sales Person"):
|
||||||
if not frappe.db.exists("Sales Person", {"sales_person_name": sales_person_name}):
|
if not frappe.db.exists("Sales Person", {"sales_person_name": sales_person_name}):
|
||||||
|
|||||||
Reference in New Issue
Block a user