mirror of
https://github.com/frappe/erpnext.git
synced 2026-09-19 11:27:55 +00:00
Merge branch 'develop' into mergify/bp/develop/pr-30385
This commit is contained in:
@@ -100,7 +100,8 @@ class Customer(TransactionBase):
|
||||
@frappe.whitelist()
|
||||
def get_customer_group_details(self):
|
||||
doc = frappe.get_doc("Customer Group", self.customer_group)
|
||||
self.accounts = self.credit_limits = []
|
||||
self.accounts = []
|
||||
self.credit_limits = []
|
||||
self.payment_terms = self.default_price_list = ""
|
||||
|
||||
tables = [["accounts", "account"], ["credit_limits", "credit_limit"]]
|
||||
|
||||
@@ -45,7 +45,8 @@ class TestCustomer(FrappeTestCase):
|
||||
c_doc.customer_name = "Testing Customer"
|
||||
c_doc.customer_group = "_Testing Customer Group"
|
||||
c_doc.payment_terms = c_doc.default_price_list = ""
|
||||
c_doc.accounts = c_doc.credit_limits = []
|
||||
c_doc.accounts = []
|
||||
c_doc.credit_limits = []
|
||||
c_doc.insert()
|
||||
c_doc.get_customer_group_details()
|
||||
self.assertEqual(c_doc.payment_terms, "_Test Payment Term Template 3")
|
||||
|
||||
@@ -43,6 +43,8 @@
|
||||
"price_list_currency",
|
||||
"plc_conversion_rate",
|
||||
"ignore_pricing_rule",
|
||||
"section_break_33",
|
||||
"scan_barcode",
|
||||
"items_section",
|
||||
"items",
|
||||
"bundle_items_section",
|
||||
@@ -968,13 +970,23 @@
|
||||
"fieldtype": "Small Text",
|
||||
"label": "Company Address",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "section_break_33",
|
||||
"fieldtype": "Section Break"
|
||||
},
|
||||
{
|
||||
"fieldname": "scan_barcode",
|
||||
"fieldtype": "Data",
|
||||
"label": "Scan Barcode",
|
||||
"options": "Barcode"
|
||||
}
|
||||
],
|
||||
"icon": "fa fa-shopping-cart",
|
||||
"idx": 82,
|
||||
"is_submittable": 1,
|
||||
"links": [],
|
||||
"modified": "2022-04-03 17:21:48.578719",
|
||||
"modified": "2022-04-07 11:01:31.157084",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Selling",
|
||||
"name": "Quotation",
|
||||
|
||||
@@ -721,11 +721,14 @@ erpnext.PointOfSale.Controller = class {
|
||||
|
||||
async save_and_checkout() {
|
||||
if (this.frm.is_dirty()) {
|
||||
let save_error = false;
|
||||
await this.frm.save(null, null, null, () => save_error = true);
|
||||
// only move to payment section if save is successful
|
||||
frappe.route_hooks.after_save = () => this.payment.checkout();
|
||||
return this.frm.save(
|
||||
null, null, null, () => this.cart.toggle_checkout_btn(true) // show checkout button on error
|
||||
);
|
||||
!save_error && this.payment.checkout();
|
||||
// show checkout button on error
|
||||
save_error && setTimeout(() => {
|
||||
this.cart.toggle_checkout_btn(true);
|
||||
}, 300); // wait for save to finish
|
||||
} else {
|
||||
this.payment.checkout();
|
||||
}
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors
|
||||
# License: GNU General Public License v3. See license.txt
|
||||
|
||||
from itertools import groupby
|
||||
|
||||
import frappe
|
||||
import pandas as pd
|
||||
from frappe import _
|
||||
from frappe.utils import flt
|
||||
|
||||
from erpnext.accounts.report.utils import convert
|
||||
|
||||
@@ -89,28 +90,21 @@ def get_opp_by_lead_source(from_date, to_date, company):
|
||||
for x in opportunities
|
||||
]
|
||||
|
||||
df = (
|
||||
pd.DataFrame(cp_opportunities)
|
||||
.groupby(["source", "sales_stage"], as_index=False)
|
||||
.agg({"compound_amount": "sum"})
|
||||
)
|
||||
summary = {}
|
||||
sales_stages = set()
|
||||
group_key = lambda o: (o["source"], o["sales_stage"]) # noqa
|
||||
for (source, sales_stage), rows in groupby(cp_opportunities, group_key):
|
||||
summary.setdefault(source, {})[sales_stage] = sum(r["compound_amount"] for r in rows)
|
||||
sales_stages.add(sales_stage)
|
||||
|
||||
result = {}
|
||||
result["labels"] = list(set(df.source.values))
|
||||
result["datasets"] = []
|
||||
|
||||
for s in set(df.sales_stage.values):
|
||||
result["datasets"].append(
|
||||
{"name": s, "values": [0] * len(result["labels"]), "chartType": "bar"}
|
||||
)
|
||||
|
||||
for row in df.itertuples():
|
||||
source_index = result["labels"].index(row.source)
|
||||
|
||||
for dataset in result["datasets"]:
|
||||
if dataset["name"] == row.sales_stage:
|
||||
dataset["values"][source_index] = row.compound_amount
|
||||
pivot_table = []
|
||||
for sales_stage in sales_stages:
|
||||
row = []
|
||||
for source, sales_stage_values in summary.items():
|
||||
row.append(flt(sales_stage_values.get(sales_stage)))
|
||||
pivot_table.append({"chartType": "bar", "name": sales_stage, "values": row})
|
||||
|
||||
result = {"datasets": pivot_table, "labels": list(summary.keys())}
|
||||
return result
|
||||
|
||||
else:
|
||||
@@ -148,20 +142,14 @@ def get_pipeline_data(from_date, to_date, company):
|
||||
for x in opportunities
|
||||
]
|
||||
|
||||
df = (
|
||||
pd.DataFrame(cp_opportunities)
|
||||
.groupby(["sales_stage"], as_index=True)
|
||||
.agg({"compound_amount": "sum"})
|
||||
.to_dict()
|
||||
)
|
||||
|
||||
result = {}
|
||||
result["labels"] = df["compound_amount"].keys()
|
||||
result["datasets"] = []
|
||||
result["datasets"].append(
|
||||
{"name": _("Total Amount"), "values": df["compound_amount"].values(), "chartType": "bar"}
|
||||
)
|
||||
summary = {}
|
||||
for sales_stage, rows in groupby(cp_opportunities, lambda o: o["sales_stage"]):
|
||||
summary[sales_stage] = sum(flt(r["compound_amount"]) for r in rows)
|
||||
|
||||
result = {
|
||||
"labels": list(summary.keys()),
|
||||
"datasets": [{"name": _("Total Amount"), "values": list(summary.values()), "chartType": "bar"}],
|
||||
}
|
||||
return result
|
||||
|
||||
else:
|
||||
|
||||
@@ -27,28 +27,55 @@ function get_filters() {
|
||||
"default": frappe.datetime.get_today()
|
||||
},
|
||||
{
|
||||
"fieldname":"sales_order",
|
||||
"label": __("Sales Order"),
|
||||
"fieldtype": "MultiSelectList",
|
||||
"fieldname":"customer_group",
|
||||
"label": __("Customer Group"),
|
||||
"fieldtype": "Link",
|
||||
"width": 100,
|
||||
"options": "Sales Order",
|
||||
"get_data": function(txt) {
|
||||
return frappe.db.get_link_options("Sales Order", txt, this.filters());
|
||||
},
|
||||
"filters": () => {
|
||||
return {
|
||||
docstatus: 1,
|
||||
payment_terms_template: ['not in', ['']],
|
||||
company: frappe.query_report.get_filter_value("company"),
|
||||
transaction_date: ['between', [frappe.query_report.get_filter_value("period_start_date"), frappe.query_report.get_filter_value("period_end_date")]]
|
||||
"options": "Customer Group",
|
||||
},
|
||||
{
|
||||
"fieldname":"customer",
|
||||
"label": __("Customer"),
|
||||
"fieldtype": "Link",
|
||||
"width": 100,
|
||||
"options": "Customer",
|
||||
"get_query": () => {
|
||||
var customer_group = frappe.query_report.get_filter_value('customer_group');
|
||||
return{
|
||||
"query": "erpnext.selling.report.payment_terms_status_for_sales_order.payment_terms_status_for_sales_order.get_customers_or_items",
|
||||
"filters": [
|
||||
['Customer', 'disabled', '=', '0'],
|
||||
['Customer Group','name', '=', customer_group]
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"fieldname":"item_group",
|
||||
"label": __("Item Group"),
|
||||
"fieldtype": "Link",
|
||||
"width": 100,
|
||||
"options": "Item Group",
|
||||
|
||||
},
|
||||
{
|
||||
"fieldname":"item",
|
||||
"label": __("Item"),
|
||||
"fieldtype": "Link",
|
||||
"width": 100,
|
||||
"options": "Item",
|
||||
"get_query": () => {
|
||||
var item_group = frappe.query_report.get_filter_value('item_group');
|
||||
return{
|
||||
"query": "erpnext.selling.report.payment_terms_status_for_sales_order.payment_terms_status_for_sales_order.get_customers_or_items",
|
||||
"filters": [
|
||||
['Item', 'disabled', '=', '0'],
|
||||
['Item Group','name', '=', item_group]
|
||||
]
|
||||
}
|
||||
},
|
||||
on_change: function(){
|
||||
frappe.query_report.refresh();
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
return filters;
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
import frappe
|
||||
from frappe import _, qb, query_builder
|
||||
from frappe.query_builder import functions
|
||||
from frappe.query_builder import Criterion, functions
|
||||
|
||||
|
||||
def get_columns():
|
||||
@@ -14,6 +14,12 @@ def get_columns():
|
||||
"fieldtype": "Link",
|
||||
"options": "Sales Order",
|
||||
},
|
||||
{
|
||||
"label": _("Customer"),
|
||||
"fieldname": "customer",
|
||||
"fieldtype": "Link",
|
||||
"options": "Customer",
|
||||
},
|
||||
{
|
||||
"label": _("Posting Date"),
|
||||
"fieldname": "submitted",
|
||||
@@ -67,6 +73,55 @@ def get_columns():
|
||||
return columns
|
||||
|
||||
|
||||
def get_descendants_of(doctype, group_name):
|
||||
group_doc = qb.DocType(doctype)
|
||||
# get lft and rgt of group node
|
||||
lft, rgt = (
|
||||
qb.from_(group_doc).select(group_doc.lft, group_doc.rgt).where(group_doc.name == group_name)
|
||||
).run()[0]
|
||||
|
||||
# get all children of group node
|
||||
query = (
|
||||
qb.from_(group_doc).select(group_doc.name).where((group_doc.lft >= lft) & (group_doc.rgt <= rgt))
|
||||
)
|
||||
|
||||
child_nodes = []
|
||||
for x in query.run():
|
||||
child_nodes.append(x[0])
|
||||
|
||||
return child_nodes
|
||||
|
||||
|
||||
@frappe.whitelist()
|
||||
@frappe.validate_and_sanitize_search_inputs
|
||||
def get_customers_or_items(doctype, txt, searchfield, start, page_len, filters):
|
||||
filter_list = []
|
||||
if isinstance(filters, list):
|
||||
for item in filters:
|
||||
if item[0] == doctype:
|
||||
filter_list.append(item)
|
||||
elif item[0] == "Customer Group":
|
||||
if item[3] != "":
|
||||
filter_list.append(
|
||||
[doctype, "customer_group", "in", get_descendants_of("Customer Group", item[3])]
|
||||
)
|
||||
elif item[0] == "Item Group":
|
||||
if item[3] != "":
|
||||
filter_list.append([doctype, "item_group", "in", get_descendants_of("Item Group", item[3])])
|
||||
|
||||
if searchfield and txt:
|
||||
filter_list.append([doctype, searchfield, "like", "%%%s%%" % txt])
|
||||
|
||||
return frappe.desk.reportview.execute(
|
||||
doctype,
|
||||
filters=filter_list,
|
||||
fields=["name", "customer_group"] if doctype == "Customer" else ["name", "item_group"],
|
||||
limit_start=start,
|
||||
limit_page_length=page_len,
|
||||
as_list=True,
|
||||
)
|
||||
|
||||
|
||||
def get_conditions(filters):
|
||||
"""
|
||||
Convert filter options to conditions used in query
|
||||
@@ -79,11 +134,37 @@ def get_conditions(filters):
|
||||
conditions.start_date = filters.period_start_date or frappe.utils.add_months(
|
||||
conditions.end_date, -1
|
||||
)
|
||||
conditions.sales_order = filters.sales_order or []
|
||||
|
||||
return conditions
|
||||
|
||||
|
||||
def build_filter_criterions(filters):
|
||||
filters = frappe._dict(filters) if filters else frappe._dict({})
|
||||
qb_criterions = []
|
||||
|
||||
if filters.customer_group:
|
||||
qb_criterions.append(
|
||||
qb.DocType("Sales Order").customer_group.isin(
|
||||
get_descendants_of("Customer Group", filters.customer_group)
|
||||
)
|
||||
)
|
||||
|
||||
if filters.customer:
|
||||
qb_criterions.append(qb.DocType("Sales Order").customer == filters.customer)
|
||||
|
||||
if filters.item_group:
|
||||
qb_criterions.append(
|
||||
qb.DocType("Sales Order Item").item_group.isin(
|
||||
get_descendants_of("Item Group", filters.item_group)
|
||||
)
|
||||
)
|
||||
|
||||
if filters.item:
|
||||
qb_criterions.append(qb.DocType("Sales Order Item").item_code == filters.item)
|
||||
|
||||
return qb_criterions
|
||||
|
||||
|
||||
def get_so_with_invoices(filters):
|
||||
"""
|
||||
Get Sales Order with payment terms template with their associated Invoices
|
||||
@@ -92,16 +173,23 @@ def get_so_with_invoices(filters):
|
||||
|
||||
so = qb.DocType("Sales Order")
|
||||
ps = qb.DocType("Payment Schedule")
|
||||
soi = qb.DocType("Sales Order Item")
|
||||
|
||||
conditions = get_conditions(filters)
|
||||
filter_criterions = build_filter_criterions(filters)
|
||||
|
||||
datediff = query_builder.CustomFunction("DATEDIFF", ["cur_date", "due_date"])
|
||||
ifelse = query_builder.CustomFunction("IF", ["condition", "then", "else"])
|
||||
|
||||
conditions = get_conditions(filters)
|
||||
query_so = (
|
||||
qb.from_(so)
|
||||
.join(soi)
|
||||
.on(soi.parent == so.name)
|
||||
.join(ps)
|
||||
.on(ps.parent == so.name)
|
||||
.select(
|
||||
so.name,
|
||||
so.customer,
|
||||
so.transaction_date.as_("submitted"),
|
||||
ifelse(datediff(ps.due_date, functions.CurDate()) < 0, "Overdue", "Unpaid").as_("status"),
|
||||
ps.payment_term,
|
||||
@@ -117,12 +205,10 @@ def get_so_with_invoices(filters):
|
||||
& (so.company == conditions.company)
|
||||
& (so.transaction_date[conditions.start_date : conditions.end_date])
|
||||
)
|
||||
.where(Criterion.all(filter_criterions))
|
||||
.orderby(so.name, so.transaction_date, ps.due_date)
|
||||
)
|
||||
|
||||
if conditions.sales_order != []:
|
||||
query_so = query_so.where(so.name.isin(conditions.sales_order))
|
||||
|
||||
sorders = query_so.run(as_dict=True)
|
||||
|
||||
invoices = []
|
||||
|
||||
@@ -11,10 +11,13 @@ from erpnext.selling.report.payment_terms_status_for_sales_order.payment_terms_s
|
||||
)
|
||||
from erpnext.stock.doctype.item.test_item import create_item
|
||||
|
||||
test_dependencies = ["Sales Order", "Item", "Sales Invoice", "Payment Terms Template"]
|
||||
test_dependencies = ["Sales Order", "Item", "Sales Invoice", "Payment Terms Template", "Customer"]
|
||||
|
||||
|
||||
class TestPaymentTermsStatusForSalesOrder(FrappeTestCase):
|
||||
def tearDown(self):
|
||||
frappe.db.rollback()
|
||||
|
||||
def create_payment_terms_template(self):
|
||||
# create template for 50-50 payments
|
||||
template = None
|
||||
@@ -48,9 +51,9 @@ class TestPaymentTermsStatusForSalesOrder(FrappeTestCase):
|
||||
template.insert()
|
||||
self.template = template
|
||||
|
||||
def test_payment_terms_status(self):
|
||||
def test_01_payment_terms_status(self):
|
||||
self.create_payment_terms_template()
|
||||
item = create_item(item_code="_Test Excavator", is_stock_item=0)
|
||||
item = create_item(item_code="_Test Excavator 1", is_stock_item=0)
|
||||
so = make_sales_order(
|
||||
transaction_date="2021-06-15",
|
||||
delivery_date=add_days("2021-06-15", -30),
|
||||
@@ -78,13 +81,14 @@ class TestPaymentTermsStatusForSalesOrder(FrappeTestCase):
|
||||
"company": "_Test Company",
|
||||
"period_start_date": "2021-06-01",
|
||||
"period_end_date": "2021-06-30",
|
||||
"sales_order": [so.name],
|
||||
"item": item.item_code,
|
||||
}
|
||||
)
|
||||
|
||||
expected_value = [
|
||||
{
|
||||
"name": so.name,
|
||||
"customer": so.customer,
|
||||
"submitted": datetime.date(2021, 6, 15),
|
||||
"status": "Completed",
|
||||
"payment_term": None,
|
||||
@@ -98,6 +102,7 @@ class TestPaymentTermsStatusForSalesOrder(FrappeTestCase):
|
||||
},
|
||||
{
|
||||
"name": so.name,
|
||||
"customer": so.customer,
|
||||
"submitted": datetime.date(2021, 6, 15),
|
||||
"status": "Partly Paid",
|
||||
"payment_term": None,
|
||||
@@ -132,11 +137,11 @@ class TestPaymentTermsStatusForSalesOrder(FrappeTestCase):
|
||||
)
|
||||
doc.insert()
|
||||
|
||||
def test_alternate_currency(self):
|
||||
def test_02_alternate_currency(self):
|
||||
transaction_date = "2021-06-15"
|
||||
self.create_payment_terms_template()
|
||||
self.create_exchange_rate(transaction_date)
|
||||
item = create_item(item_code="_Test Excavator", is_stock_item=0)
|
||||
item = create_item(item_code="_Test Excavator 2", is_stock_item=0)
|
||||
so = make_sales_order(
|
||||
transaction_date=transaction_date,
|
||||
currency="USD",
|
||||
@@ -166,7 +171,7 @@ class TestPaymentTermsStatusForSalesOrder(FrappeTestCase):
|
||||
"company": "_Test Company",
|
||||
"period_start_date": "2021-06-01",
|
||||
"period_end_date": "2021-06-30",
|
||||
"sales_order": [so.name],
|
||||
"item": item.item_code,
|
||||
}
|
||||
)
|
||||
|
||||
@@ -174,6 +179,7 @@ class TestPaymentTermsStatusForSalesOrder(FrappeTestCase):
|
||||
expected_value = [
|
||||
{
|
||||
"name": so.name,
|
||||
"customer": so.customer,
|
||||
"submitted": datetime.date(2021, 6, 15),
|
||||
"status": "Completed",
|
||||
"payment_term": None,
|
||||
@@ -187,6 +193,7 @@ class TestPaymentTermsStatusForSalesOrder(FrappeTestCase):
|
||||
},
|
||||
{
|
||||
"name": so.name,
|
||||
"customer": so.customer,
|
||||
"submitted": datetime.date(2021, 6, 15),
|
||||
"status": "Partly Paid",
|
||||
"payment_term": None,
|
||||
@@ -200,3 +207,134 @@ class TestPaymentTermsStatusForSalesOrder(FrappeTestCase):
|
||||
},
|
||||
]
|
||||
self.assertEqual(data, expected_value)
|
||||
|
||||
def test_03_group_filters(self):
|
||||
transaction_date = "2021-06-15"
|
||||
self.create_payment_terms_template()
|
||||
item1 = create_item(item_code="_Test Excavator 1", is_stock_item=0)
|
||||
item1.item_group = "Products"
|
||||
item1.save()
|
||||
|
||||
so1 = make_sales_order(
|
||||
transaction_date=transaction_date,
|
||||
delivery_date=add_days(transaction_date, -30),
|
||||
item=item1.item_code,
|
||||
qty=1,
|
||||
rate=1000000,
|
||||
do_not_save=True,
|
||||
)
|
||||
so1.po_no = ""
|
||||
so1.taxes_and_charges = ""
|
||||
so1.taxes = ""
|
||||
so1.payment_terms_template = self.template.name
|
||||
so1.save()
|
||||
so1.submit()
|
||||
|
||||
item2 = create_item(item_code="_Test Steel", is_stock_item=0)
|
||||
item2.item_group = "Raw Material"
|
||||
item2.save()
|
||||
|
||||
so2 = make_sales_order(
|
||||
customer="_Test Customer 1",
|
||||
transaction_date=transaction_date,
|
||||
delivery_date=add_days(transaction_date, -30),
|
||||
item=item2.item_code,
|
||||
qty=100,
|
||||
rate=1000,
|
||||
do_not_save=True,
|
||||
)
|
||||
so2.po_no = ""
|
||||
so2.taxes_and_charges = ""
|
||||
so2.taxes = ""
|
||||
so2.payment_terms_template = self.template.name
|
||||
so2.save()
|
||||
so2.submit()
|
||||
|
||||
base_filters = {
|
||||
"company": "_Test Company",
|
||||
"period_start_date": "2021-06-01",
|
||||
"period_end_date": "2021-06-30",
|
||||
}
|
||||
|
||||
expected_value_so1 = [
|
||||
{
|
||||
"name": so1.name,
|
||||
"customer": so1.customer,
|
||||
"submitted": datetime.date(2021, 6, 15),
|
||||
"status": "Overdue",
|
||||
"payment_term": None,
|
||||
"description": "_Test 50-50",
|
||||
"due_date": datetime.date(2021, 6, 30),
|
||||
"invoice_portion": 50.0,
|
||||
"currency": "INR",
|
||||
"base_payment_amount": 500000.0,
|
||||
"paid_amount": 0.0,
|
||||
"invoices": "",
|
||||
},
|
||||
{
|
||||
"name": so1.name,
|
||||
"customer": so1.customer,
|
||||
"submitted": datetime.date(2021, 6, 15),
|
||||
"status": "Overdue",
|
||||
"payment_term": None,
|
||||
"description": "_Test 50-50",
|
||||
"due_date": datetime.date(2021, 7, 15),
|
||||
"invoice_portion": 50.0,
|
||||
"currency": "INR",
|
||||
"base_payment_amount": 500000.0,
|
||||
"paid_amount": 0.0,
|
||||
"invoices": "",
|
||||
},
|
||||
]
|
||||
|
||||
expected_value_so2 = [
|
||||
{
|
||||
"name": so2.name,
|
||||
"customer": so2.customer,
|
||||
"submitted": datetime.date(2021, 6, 15),
|
||||
"status": "Overdue",
|
||||
"payment_term": None,
|
||||
"description": "_Test 50-50",
|
||||
"due_date": datetime.date(2021, 6, 30),
|
||||
"invoice_portion": 50.0,
|
||||
"currency": "INR",
|
||||
"base_payment_amount": 50000.0,
|
||||
"paid_amount": 0.0,
|
||||
"invoices": "",
|
||||
},
|
||||
{
|
||||
"name": so2.name,
|
||||
"customer": so2.customer,
|
||||
"submitted": datetime.date(2021, 6, 15),
|
||||
"status": "Overdue",
|
||||
"payment_term": None,
|
||||
"description": "_Test 50-50",
|
||||
"due_date": datetime.date(2021, 7, 15),
|
||||
"invoice_portion": 50.0,
|
||||
"currency": "INR",
|
||||
"base_payment_amount": 50000.0,
|
||||
"paid_amount": 0.0,
|
||||
"invoices": "",
|
||||
},
|
||||
]
|
||||
|
||||
group_filters = [
|
||||
{"customer_group": "All Customer Groups"},
|
||||
{"item_group": "All Item Groups"},
|
||||
{"item_group": "Products"},
|
||||
{"item_group": "Raw Material"},
|
||||
]
|
||||
|
||||
expected_values_for_group_filters = [
|
||||
expected_value_so1 + expected_value_so2,
|
||||
expected_value_so1 + expected_value_so2,
|
||||
expected_value_so1,
|
||||
expected_value_so2,
|
||||
]
|
||||
|
||||
for idx, g in enumerate(group_filters, 0):
|
||||
# build filter
|
||||
filters = frappe._dict({}).update(base_filters).update(g)
|
||||
with self.subTest(filters=filters):
|
||||
columns, data, message, chart = execute(filters)
|
||||
self.assertEqual(data, expected_values_for_group_filters[idx])
|
||||
|
||||
Reference in New Issue
Block a user