feat: two new groupby mode: Monthly, Payment Term
This commit is contained in:
parent
a1b7a7983a
commit
c4af63ad98
@ -35,7 +35,7 @@ frappe.query_reports["Gross Profit"] = {
|
|||||||
"fieldname":"group_by",
|
"fieldname":"group_by",
|
||||||
"label": __("Group By"),
|
"label": __("Group By"),
|
||||||
"fieldtype": "Select",
|
"fieldtype": "Select",
|
||||||
"options": "Invoice\nItem Code\nItem Group\nBrand\nWarehouse\nCustomer\nCustomer Group\nTerritory\nSales Person\nProject",
|
"options": "Invoice\nItem Code\nItem Group\nBrand\nWarehouse\nCustomer\nCustomer Group\nTerritory\nSales Person\nProject\nMonthly\nPayment Term",
|
||||||
"default": "Invoice"
|
"default": "Invoice"
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
|||||||
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
import frappe
|
import frappe
|
||||||
from frappe import _, scrub
|
from frappe import _, scrub
|
||||||
from frappe.utils import cint, flt
|
from frappe.utils import cint, flt, formatdate
|
||||||
|
|
||||||
from erpnext.controllers.queries import get_match_cond
|
from erpnext.controllers.queries import get_match_cond
|
||||||
from erpnext.stock.utils import get_incoming_rate
|
from erpnext.stock.utils import get_incoming_rate
|
||||||
@ -124,6 +124,23 @@ def execute(filters=None):
|
|||||||
"gross_profit",
|
"gross_profit",
|
||||||
"gross_profit_percent",
|
"gross_profit_percent",
|
||||||
],
|
],
|
||||||
|
"monthly": [
|
||||||
|
"monthly",
|
||||||
|
"qty",
|
||||||
|
"base_rate",
|
||||||
|
"buying_rate",
|
||||||
|
"base_amount",
|
||||||
|
"buying_amount",
|
||||||
|
"gross_profit",
|
||||||
|
"gross_profit_percent",
|
||||||
|
],
|
||||||
|
"payment_term": [
|
||||||
|
"payment_term",
|
||||||
|
"base_amount",
|
||||||
|
"buying_amount",
|
||||||
|
"gross_profit",
|
||||||
|
"gross_profit_percent",
|
||||||
|
],
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -317,6 +334,19 @@ def get_columns(group_wise_columns, filters):
|
|||||||
"options": "territory",
|
"options": "territory",
|
||||||
"width": 100,
|
"width": 100,
|
||||||
},
|
},
|
||||||
|
"monthly": {
|
||||||
|
"label": _("Monthly"),
|
||||||
|
"fieldname": "monthly",
|
||||||
|
"fieldtype": "Data",
|
||||||
|
"width": 100,
|
||||||
|
},
|
||||||
|
"payment_term": {
|
||||||
|
"label": _("Payment Term"),
|
||||||
|
"fieldname": "payment_term",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"options": "Payment Term",
|
||||||
|
"width": 170,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -390,6 +420,9 @@ class GrossProfitGenerator(object):
|
|||||||
buying_amount = 0
|
buying_amount = 0
|
||||||
|
|
||||||
for row in reversed(self.si_list):
|
for row in reversed(self.si_list):
|
||||||
|
if self.filters.get("group_by") == "Monthly":
|
||||||
|
row.monthly = formatdate(row.posting_date, "MMM YYYY")
|
||||||
|
|
||||||
if self.skip_row(row):
|
if self.skip_row(row):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
@ -445,17 +478,7 @@ class GrossProfitGenerator(object):
|
|||||||
|
|
||||||
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):
|
||||||
if self.filters.get("group_by") != "Invoice":
|
if self.filters.get("group_by") == "Invoice":
|
||||||
for i, row in enumerate(self.grouped[key]):
|
|
||||||
if i == 0:
|
|
||||||
new_row = row
|
|
||||||
else:
|
|
||||||
new_row.qty += flt(row.qty)
|
|
||||||
new_row.buying_amount += flt(row.buying_amount, self.currency_precision)
|
|
||||||
new_row.base_amount += flt(row.base_amount, self.currency_precision)
|
|
||||||
new_row = self.set_average_rate(new_row)
|
|
||||||
self.grouped_data.append(new_row)
|
|
||||||
else:
|
|
||||||
for i, row in enumerate(self.grouped[key]):
|
for i, row in enumerate(self.grouped[key]):
|
||||||
if row.indent == 1.0:
|
if row.indent == 1.0:
|
||||||
if (
|
if (
|
||||||
@ -469,6 +492,44 @@ class GrossProfitGenerator(object):
|
|||||||
if flt(row.qty) or row.base_amount:
|
if flt(row.qty) or row.base_amount:
|
||||||
row = self.set_average_rate(row)
|
row = self.set_average_rate(row)
|
||||||
self.grouped_data.append(row)
|
self.grouped_data.append(row)
|
||||||
|
elif self.filters.get("group_by") == "Payment Term":
|
||||||
|
for i, row in enumerate(self.grouped[key]):
|
||||||
|
invoice_portion = 0
|
||||||
|
|
||||||
|
if row.is_return:
|
||||||
|
invoice_portion = 100
|
||||||
|
elif row.invoice_portion:
|
||||||
|
invoice_portion = row.invoice_portion
|
||||||
|
else:
|
||||||
|
invoice_portion = row.payment_amount * 100 / row.base_net_amount
|
||||||
|
|
||||||
|
if i == 0:
|
||||||
|
new_row = row
|
||||||
|
self.set_average_based_on_payment_term_portion(new_row, row, invoice_portion)
|
||||||
|
else:
|
||||||
|
new_row.qty += flt(row.qty)
|
||||||
|
self.set_average_based_on_payment_term_portion(new_row, row, invoice_portion, True)
|
||||||
|
|
||||||
|
new_row = self.set_average_rate(new_row)
|
||||||
|
self.grouped_data.append(new_row)
|
||||||
|
else:
|
||||||
|
for i, row in enumerate(self.grouped[key]):
|
||||||
|
if i == 0:
|
||||||
|
new_row = row
|
||||||
|
else:
|
||||||
|
new_row.qty += flt(row.qty)
|
||||||
|
new_row.buying_amount += flt(row.buying_amount, self.currency_precision)
|
||||||
|
new_row.base_amount += flt(row.base_amount, self.currency_precision)
|
||||||
|
new_row = self.set_average_rate(new_row)
|
||||||
|
self.grouped_data.append(new_row)
|
||||||
|
|
||||||
|
def set_average_based_on_payment_term_portion(self, new_row, row, invoice_portion, aggr=False):
|
||||||
|
cols = ["base_amount", "buying_amount", "gross_profit"]
|
||||||
|
for col in cols:
|
||||||
|
if aggr:
|
||||||
|
new_row[col] += row[col] * invoice_portion / 100
|
||||||
|
else:
|
||||||
|
new_row[col] = row[col] * invoice_portion / 100
|
||||||
|
|
||||||
def is_not_invoice_row(self, row):
|
def is_not_invoice_row(self, row):
|
||||||
return (self.filters.get("group_by") == "Invoice" and row.indent != 0.0) or self.filters.get(
|
return (self.filters.get("group_by") == "Invoice" and row.indent != 0.0) or self.filters.get(
|
||||||
@ -622,6 +683,20 @@ class GrossProfitGenerator(object):
|
|||||||
sales_person_cols = ""
|
sales_person_cols = ""
|
||||||
sales_team_table = ""
|
sales_team_table = ""
|
||||||
|
|
||||||
|
if self.filters.group_by == "Payment Term":
|
||||||
|
payment_term_cols = """,if(`tabSales Invoice`.is_return = 1,
|
||||||
|
'{0}',
|
||||||
|
coalesce(schedule.payment_term, '{1}')) as payment_term,
|
||||||
|
schedule.invoice_portion,
|
||||||
|
schedule.payment_amount """.format(
|
||||||
|
_("Sales Return"), _("No Terms")
|
||||||
|
)
|
||||||
|
payment_term_table = """ left join `tabPayment Schedule` schedule on schedule.parent = `tabSales Invoice`.name and
|
||||||
|
`tabSales Invoice`.is_return = 0 """
|
||||||
|
else:
|
||||||
|
payment_term_cols = ""
|
||||||
|
payment_term_table = ""
|
||||||
|
|
||||||
if self.filters.get("sales_invoice"):
|
if self.filters.get("sales_invoice"):
|
||||||
conditions += " and `tabSales Invoice`.name = %(sales_invoice)s"
|
conditions += " and `tabSales Invoice`.name = %(sales_invoice)s"
|
||||||
|
|
||||||
@ -644,10 +719,12 @@ class GrossProfitGenerator(object):
|
|||||||
`tabSales Invoice Item`.name as "item_row", `tabSales Invoice`.is_return,
|
`tabSales Invoice Item`.name as "item_row", `tabSales Invoice`.is_return,
|
||||||
`tabSales Invoice Item`.cost_center
|
`tabSales Invoice Item`.cost_center
|
||||||
{sales_person_cols}
|
{sales_person_cols}
|
||||||
|
{payment_term_cols}
|
||||||
from
|
from
|
||||||
`tabSales Invoice` inner join `tabSales Invoice Item`
|
`tabSales Invoice` inner join `tabSales Invoice Item`
|
||||||
on `tabSales Invoice Item`.parent = `tabSales Invoice`.name
|
on `tabSales Invoice Item`.parent = `tabSales Invoice`.name
|
||||||
{sales_team_table}
|
{sales_team_table}
|
||||||
|
{payment_term_table}
|
||||||
where
|
where
|
||||||
`tabSales Invoice`.docstatus=1 and `tabSales Invoice`.is_opening!='Yes' {conditions} {match_cond}
|
`tabSales Invoice`.docstatus=1 and `tabSales Invoice`.is_opening!='Yes' {conditions} {match_cond}
|
||||||
order by
|
order by
|
||||||
@ -655,6 +732,8 @@ class GrossProfitGenerator(object):
|
|||||||
conditions=conditions,
|
conditions=conditions,
|
||||||
sales_person_cols=sales_person_cols,
|
sales_person_cols=sales_person_cols,
|
||||||
sales_team_table=sales_team_table,
|
sales_team_table=sales_team_table,
|
||||||
|
payment_term_cols=payment_term_cols,
|
||||||
|
payment_term_table=payment_term_table,
|
||||||
match_cond=get_match_cond("Sales Invoice"),
|
match_cond=get_match_cond("Sales Invoice"),
|
||||||
),
|
),
|
||||||
self.filters,
|
self.filters,
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user