Merge pull request #20252 from deepeshgarg007/group_by_sales_v12

feat: Group by item wise sales register
This commit is contained in:
Deepesh Garg
2020-02-10 22:20:21 +05:30
committed by GitHub
5 changed files with 674 additions and 94 deletions

View File

@@ -34,6 +34,20 @@ frappe.query_reports["Item-wise Purchase Register"] = {
"label": __("Mode of Payment"), "label": __("Mode of Payment"),
"fieldtype": "Link", "fieldtype": "Link",
"options": "Mode of Payment" "options": "Mode of Payment"
},
{
"label": __("Group By"),
"fieldname": "group_by",
"fieldtype": "Select",
"options": ["Supplier", "Item Group", "Item", "Invoice"]
} }
] ],
"formatter": function(value, row, column, data, default_formatter) {
value = default_formatter(value, row, column, data);
if (data && data.bold) {
value = value.bold();
}
return value;
}
} }

View File

@@ -5,7 +5,9 @@ from __future__ import unicode_literals
import frappe, erpnext import frappe, erpnext
from frappe import _ from frappe import _
from frappe.utils import flt from frappe.utils import flt
from erpnext.accounts.report.item_wise_sales_register.item_wise_sales_register import get_tax_accounts from erpnext.accounts.report.item_wise_sales_register.item_wise_sales_register import (get_tax_accounts,
get_grand_total, add_total_row, get_display_value, get_group_by_and_display_fields, add_sub_total_row,
get_group_by_conditions)
def execute(filters=None): def execute(filters=None):
return _execute(filters) return _execute(filters)
@@ -13,7 +15,7 @@ def execute(filters=None):
def _execute(filters=None, additional_table_columns=None, additional_query_columns=None): def _execute(filters=None, additional_table_columns=None, additional_query_columns=None):
if not filters: filters = {} if not filters: filters = {}
filters.update({"from_date": filters.get("date_range")[0], "to_date": filters.get("date_range")[1]}) filters.update({"from_date": filters.get("date_range")[0], "to_date": filters.get("date_range")[1]})
columns = get_columns(additional_table_columns) columns = get_columns(additional_table_columns, filters)
company_currency = erpnext.get_company_currency(filters.company) company_currency = erpnext.get_company_currency(filters.company)
@@ -23,16 +25,16 @@ def _execute(filters=None, additional_table_columns=None, additional_query_colum
itemised_tax, tax_columns = get_tax_accounts(item_list, columns, company_currency, itemised_tax, tax_columns = get_tax_accounts(item_list, columns, company_currency,
doctype="Purchase Invoice", tax_doctype="Purchase Taxes and Charges") doctype="Purchase Invoice", tax_doctype="Purchase Taxes and Charges")
columns.append({
"fieldname": "currency",
"label": _("Currency"),
"fieldtype": "Data",
"width": 80
})
po_pr_map = get_purchase_receipts_against_purchase_order(item_list) po_pr_map = get_purchase_receipts_against_purchase_order(item_list)
data = [] data = []
total_row_map = {}
skip_total_row = 0
prev_group_by_value = ''
if filters.get('group_by'):
grand_total = get_grand_total(filters, 'Purchase Invoice')
for d in item_list: for d in item_list:
if not d.stock_qty: if not d.stock_qty:
continue continue
@@ -44,51 +46,243 @@ def _execute(filters=None, additional_table_columns=None, additional_query_colum
purchase_receipt = ", ".join(po_pr_map.get(d.po_detail, [])) purchase_receipt = ", ".join(po_pr_map.get(d.po_detail, []))
expense_account = d.expense_account or aii_account_map.get(d.company) expense_account = d.expense_account or aii_account_map.get(d.company)
row = [d.item_code, d.item_name, d.item_group, d.description, d.parent, d.posting_date, d.supplier,
d.supplier_name] row = {
'item_code': d.item_code,
'item_name': d.item_name,
'item_group': d.item_group,
'description': d.description,
'invoice': d.parent,
'posting_date': d.posting_date,
'customer': d.supplier,
'customer_name': d.supplier_name
}
if additional_query_columns: if additional_query_columns:
for col in additional_query_columns: for col in additional_query_columns:
row.append(d.get(col)) row.update({
col: d.get(col)
})
row += [ row.update({
d.credit_to, d.mode_of_payment, d.project, d.company, d.purchase_order, 'credit_to': d.credit_to,
purchase_receipt, expense_account, d.stock_qty, d.stock_uom, d.base_net_amount / d.stock_qty, d.base_net_amount 'mode_of_payment': d.mode_of_payment,
] 'project': d.project,
'company': d.company,
'purchase_order': d.purchase_order,
'purchase_receipt': d.purchase_receipt,
'expense_account': expense_account,
'stock_qty': d.stock_qty,
'stock_uom': d.stock_uom,
'rate': d.base_net_amount / d.stock_qty,
'amount': d.base_net_amount
})
total_tax = 0 total_tax = 0
for tax in tax_columns: for tax in tax_columns:
item_tax = itemised_tax.get(d.name, {}).get(tax, {}) item_tax = itemised_tax.get(d.name, {}).get(tax, {})
row += [item_tax.get("tax_rate", 0), item_tax.get("tax_amount", 0)] row.update({
frappe.scrub(tax + ' Rate'): item_tax.get("tax_rate", 0),
frappe.scrub(tax + ' Amount'): item_tax.get("tax_amount", 0),
})
total_tax += flt(item_tax.get("tax_amount")) total_tax += flt(item_tax.get("tax_amount"))
row += [total_tax, d.base_net_amount + total_tax, company_currency] row.update({
'total_tax': total_tax,
'total': d.base_net_amount + total_tax,
'currency': company_currency
})
if filters.get('group_by'):
row.update({'percent_gt': flt(row['total']/grand_total) * 100})
group_by_field, subtotal_display_field = get_group_by_and_display_fields(filters)
data, prev_group_by_value = add_total_row(data, filters, prev_group_by_value, d, total_row_map,
group_by_field, subtotal_display_field, grand_total, tax_columns)
add_sub_total_row(row, total_row_map, d.get(group_by_field, ''), tax_columns)
data.append(row) data.append(row)
return columns, data if filters.get('group_by'):
total_row = total_row_map.get(prev_group_by_value or d.get('item_name'))
total_row['percent_gt'] = flt(total_row['total']/grand_total * 100)
data.append(total_row)
data.append({})
add_sub_total_row(total_row, total_row_map, 'total_row', tax_columns)
data.append(total_row_map.get('total_row'))
skip_total_row = 1
return columns, data, None, None, None, skip_total_row
def get_columns(additional_table_columns): def get_columns(additional_table_columns, filters):
columns = [
_("Item Code") + ":Link/Item:120", _("Item Name") + "::120", columns = []
_("Item Group") + ":Link/Item Group:100", "Description::150", _("Invoice") + ":Link/Purchase Invoice:120",
_("Posting Date") + ":Date:80", _("Supplier") + ":Link/Supplier:120", if filters.get('group_by') != ('Item'):
"Supplier Name::120" columns.extend(
] [
{
'label': _('Item Code'),
'fieldname': 'item_code',
'fieldtype': 'Link',
'options': 'Item',
'width': 120
},
{
'label': _('Item Name'),
'fieldname': 'item_name',
'fieldtype': 'Data',
'width': 120
}
]
)
if filters.get('group_by') not in ('Item', 'Item Group'):
columns.extend([
{
'label': _('Item Group'),
'fieldname': 'item_group',
'fieldtype': 'Link',
'options': 'Item Group',
'width': 120
}
])
columns.extend([
{
'label': _('Description'),
'fieldname': 'description',
'fieldtype': 'Data',
'width': 150
},
{
'label': _('Invoice'),
'fieldname': 'invoice',
'fieldtype': 'Link',
'options': 'Purchase Invoice',
'width': 120
},
{
'label': _('Posting Date'),
'fieldname': 'posting_date',
'fieldtype': 'Date',
'width': 120
}
])
if filters.get('group_by') != 'Supplier':
columns.extend([
{
'label': _('Supplier'),
'fieldname': 'supplier',
'fieldtype': 'Link',
'options': 'Supplier',
'width': 120
},
{
'label': _('Supplier Name'),
'fieldname': 'supplier_name',
'fieldtype': 'Data',
'width': 120
}
])
if additional_table_columns: if additional_table_columns:
columns += additional_table_columns columns += additional_table_columns
columns += [ columns += [
"Payable Account:Link/Account:120", {
_("Mode of Payment") + ":Link/Mode of Payment:80", _("Project") + ":Link/Project:80", 'label': _('Payable Account'),
_("Company") + ":Link/Company:100", _("Purchase Order") + ":Link/Purchase Order:100", 'fieldname': 'credit_to',
_("Purchase Receipt") + ":Link/Purchase Receipt:100", _("Expense Account") + ":Link/Account:140", 'fieldtype': 'Link',
_("Stock Qty") + ":Float:120", _("Stock UOM") + "::100", 'options': 'Account',
_("Rate") + ":Currency/currency:120", _("Amount") + ":Currency/currency:120" 'width': 80
},
{
'label': _('Mode Of Payment'),
'fieldname': 'mode_of_payment',
'fieldtype': 'Data',
'width': 120
},
{
'label': _('Project'),
'fieldname': 'project',
'fieldtype': 'Link',
'options': 'Project',
'width': 80
},
{
'label': _('Company'),
'fieldname': 'company',
'fieldtype': 'Link',
'options': 'Company',
'width': 80
},
{
'label': _('Purchase Order'),
'fieldname': 'purchase_order',
'fieldtype': 'Link',
'options': 'Purchase Order',
'width': 100
},
{
'label': _("Purchase Receipt"),
'fieldname': 'Purchase Receipt',
'fieldtype': 'Link',
'options': 'Purchase Receipt',
'width': 100
},
{
'label': _('Expense Account'),
'fieldname': 'expense_account',
'fieldtype': 'Link',
'options': 'Account',
'width': 100
},
{
'label': _('Stock Qty'),
'fieldname': 'stock_qty',
'fieldtype': 'Float',
'width': 100
},
{
'label': _('Stock UOM'),
'fieldname': 'stock_uom',
'fieldtype': 'Link',
'options': 'UOM',
'width': 100
},
{
'label': _('Rate'),
'fieldname': 'rate',
'fieldtype': 'Float',
'options': 'currency',
'width': 100
},
{
'label': _('Amount'),
'fieldname': 'amount',
'fieldtype': 'Currency',
'options': 'currency',
'width': 100
},
{
'fieldname': 'currency',
'label': _('Currency'),
'fieldtype': 'Currency',
'width': 80,
'hidden': 1
}
] ]
if filters.get('group_by'):
columns.append({
'label': _('% Of Grand Total'),
'fieldname': 'percent_gt',
'fieldtype': 'Float',
'width': 80
})
return columns return columns
def get_conditions(filters): def get_conditions(filters):
@@ -103,6 +297,11 @@ def get_conditions(filters):
if filters.get(opts[0]): if filters.get(opts[0]):
conditions += opts[1] conditions += opts[1]
if not filters.get("group_by"):
conditions += "ORDER BY `tabPurchase Invoice`.posting_date desc, `tabPurchase Invoice Item`.item_code desc"
else:
conditions += get_group_by_conditions(filters, 'Purchase Invoice')
return conditions return conditions
def get_items(filters, additional_query_columns): def get_items(filters, additional_query_columns):
@@ -129,7 +328,6 @@ def get_items(filters, additional_query_columns):
from `tabPurchase Invoice`, `tabPurchase Invoice Item` from `tabPurchase Invoice`, `tabPurchase Invoice Item`
where `tabPurchase Invoice`.name = `tabPurchase Invoice Item`.`parent` and where `tabPurchase Invoice`.name = `tabPurchase Invoice Item`.`parent` and
`tabPurchase Invoice`.docstatus = 1 %s %s `tabPurchase Invoice`.docstatus = 1 %s %s
order by `tabPurchase Invoice`.posting_date desc, `tabPurchase Invoice Item`.item_code desc
""".format(additional_query_columns) % (conditions, match_conditions), filters, as_dict=1) """.format(additional_query_columns) % (conditions, match_conditions), filters, as_dict=1)
def get_aii_accounts(): def get_aii_accounts():

View File

@@ -4,48 +4,62 @@
frappe.query_reports["Item-wise Sales Register"] = { frappe.query_reports["Item-wise Sales Register"] = {
"filters": [ "filters": [
{ {
"fieldname":"date_range", "fieldname": "date_range",
"label": __("Date Range"), "label": __("Date Range"),
"fieldtype": "DateRange", "fieldtype": "DateRange",
"default": [frappe.datetime.add_months(frappe.datetime.get_today(),-1), frappe.datetime.get_today()], "default": [frappe.datetime.add_months(frappe.datetime.get_today(),-1), frappe.datetime.get_today()],
"reqd": 1 "reqd": 1
}, },
{ {
"fieldname":"customer", "fieldname": "customer",
"label": __("Customer"), "label": __("Customer"),
"fieldtype": "Link", "fieldtype": "Link",
"options": "Customer" "options": "Customer"
}, },
{ {
"fieldname":"company", "fieldname": "company",
"label": __("Company"), "label": __("Company"),
"fieldtype": "Link", "fieldtype": "Link",
"options": "Company", "options": "Company",
"default": frappe.defaults.get_user_default("Company") "default": frappe.defaults.get_user_default("Company")
}, },
{ {
"fieldname":"mode_of_payment", "fieldname": "mode_of_payment",
"label": __("Mode of Payment"), "label": __("Mode of Payment"),
"fieldtype": "Link", "fieldtype": "Link",
"options": "Mode of Payment" "options": "Mode of Payment"
}, },
{ {
"fieldname":"warehouse", "fieldname": "warehouse",
"label": __("Warehouse"), "label": __("Warehouse"),
"fieldtype": "Link", "fieldtype": "Link",
"options": "Warehouse" "options": "Warehouse"
}, },
{ {
"fieldname":"brand", "fieldname": "brand",
"label": __("Brand"), "label": __("Brand"),
"fieldtype": "Link", "fieldtype": "Link",
"options": "Brand" "options": "Brand"
}, },
{ {
"fieldname":"item_group", "fieldname": "item_group",
"label": __("Item Group"), "label": __("Item Group"),
"fieldtype": "Link", "fieldtype": "Link",
"options": "Item Group" "options": "Item Group"
},
{
"label": __("Group By"),
"fieldname": "group_by",
"fieldtype": "Select",
"options": ["Customer Group", "Customer", "Item Group", "Item", "Territory", "Invoice"]
} }
] ],
"formatter": function(value, row, column, data, default_formatter) {
value = default_formatter(value, row, column, data);
if (data && data.bold) {
value = value.bold();
}
return value;
}
} }

View File

@@ -4,7 +4,7 @@
from __future__ import unicode_literals from __future__ import unicode_literals
import frappe, erpnext import frappe, erpnext
from frappe import _ from frappe import _
from frappe.utils import flt from frappe.utils import flt, cstr
from frappe.model.meta import get_field_precision from frappe.model.meta import get_field_precision
from frappe.utils.xlsxutils import handle_html from frappe.utils.xlsxutils import handle_html
from erpnext.accounts.report.sales_register.sales_register import get_mode_of_payments from erpnext.accounts.report.sales_register.sales_register import get_mode_of_payments
@@ -15,23 +15,25 @@ def execute(filters=None):
def _execute(filters=None, additional_table_columns=None, additional_query_columns=None): def _execute(filters=None, additional_table_columns=None, additional_query_columns=None):
if not filters: filters = {} if not filters: filters = {}
filters.update({"from_date": filters.get("date_range") and filters.get("date_range")[0], "to_date": filters.get("date_range") and filters.get("date_range")[1]}) filters.update({"from_date": filters.get("date_range") and filters.get("date_range")[0], "to_date": filters.get("date_range") and filters.get("date_range")[1]})
columns = get_columns(additional_table_columns) columns = get_columns(additional_table_columns, filters)
company_currency = frappe.get_cached_value('Company', filters.get("company"), "default_currency") company_currency = frappe.get_cached_value('Company', filters.get("company"), "default_currency")
item_list = get_items(filters, additional_query_columns) item_list = get_items(filters, additional_query_columns)
if item_list: if item_list:
itemised_tax, tax_columns = get_tax_accounts(item_list, columns, company_currency) itemised_tax, tax_columns = get_tax_accounts(item_list, columns, company_currency)
columns.append({
"fieldname": "currency",
"label": _("Currency"),
"fieldtype": "Data",
"width": 80
})
mode_of_payments = get_mode_of_payments(set([d.parent for d in item_list])) mode_of_payments = get_mode_of_payments(set([d.parent for d in item_list]))
so_dn_map = get_delivery_notes_against_sales_order(item_list) so_dn_map = get_delivery_notes_against_sales_order(item_list)
data = [] data = []
total_row_map = {}
skip_total_row = 0
prev_group_by_value = ''
if filters.get('group_by'):
grand_total = get_grand_total(filters, 'Sales Invoice')
for d in item_list: for d in item_list:
delivery_note = None delivery_note = None
if d.delivery_note: if d.delivery_note:
@@ -42,57 +44,285 @@ def _execute(filters=None, additional_table_columns=None, additional_query_colum
if not delivery_note and d.update_stock: if not delivery_note and d.update_stock:
delivery_note = d.parent delivery_note = d.parent
row = [d.item_code, d.item_name, d.item_group, d.description, d.parent, d.posting_date, d.customer, d.customer_name] row = {
'item_code': d.item_code,
'item_name': d.item_name,
'item_group': d.item_group,
'description': d.description,
'invoice': d.parent,
'posting_date': d.posting_date,
'customer': d.customer,
'customer_name': d.customer_name,
'customer_group': d.customer_group,
}
if additional_query_columns: if additional_query_columns:
for col in additional_query_columns: for col in additional_query_columns:
row.append(d.get(col)) row.update({
col: d.get(col)
})
row += [ row.update({
d.customer_group, d.debit_to, ", ".join(mode_of_payments.get(d.parent, [])), 'debit_to': d.debit_to,
d.territory, d.project, d.company, d.sales_order, 'mode_of_payment': ", ".join(mode_of_payments.get(d.parent, [])),
delivery_note, d.income_account, d.cost_center, d.stock_qty, d.stock_uom 'territory': d.territory,
] 'project': d.project,
'company': d.company,
'sales_order': d.sales_order,
'delivery_note': d.delivery_note,
'income_account': d.income_account,
'cost_center': d.cost_center,
'stock_qty': d.stock_qty,
'stock_uom': d.stock_uom
})
if d.stock_uom != d.uom and d.stock_qty: if d.stock_uom != d.uom and d.stock_qty:
row += [(d.base_net_rate * d.qty)/d.stock_qty, d.base_net_amount] row.update({
'rate': (d.base_net_rate * d.qty)/d.stock_qty,
'amount': d.base_net_amount
})
else: else:
row += [d.base_net_rate, d.base_net_amount] row.update({
'rate': d.base_net_rate,
'amount': d.base_net_amount
})
total_tax = 0 total_tax = 0
for tax in tax_columns: for tax in tax_columns:
item_tax = itemised_tax.get(d.name, {}).get(tax, {}) item_tax = itemised_tax.get(d.name, {}).get(tax, {})
row += [item_tax.get("tax_rate", 0), item_tax.get("tax_amount", 0)] row.update({
frappe.scrub(tax + ' Rate'): item_tax.get("tax_rate", 0),
frappe.scrub(tax + ' Amount'): item_tax.get("tax_amount", 0),
})
total_tax += flt(item_tax.get("tax_amount")) total_tax += flt(item_tax.get("tax_amount"))
row += [total_tax, d.base_net_amount + total_tax, company_currency] row.update({
'total_tax': total_tax,
'total': d.base_net_amount + total_tax,
'currency': company_currency
})
if filters.get('group_by'):
row.update({'percent_gt': flt(row['total']/grand_total) * 100})
group_by_field, subtotal_display_field = get_group_by_and_display_fields(filters)
data, prev_group_by_value = add_total_row(data, filters, prev_group_by_value, d, total_row_map,
group_by_field, subtotal_display_field, grand_total, tax_columns)
add_sub_total_row(row, total_row_map, d.get(group_by_field, ''), tax_columns)
data.append(row) data.append(row)
return columns, data if filters.get('group_by'):
total_row = total_row_map.get(prev_group_by_value or d.get('item_name'))
total_row['percent_gt'] = flt(total_row['total']/grand_total * 100)
data.append(total_row)
data.append({})
add_sub_total_row(total_row, total_row_map, 'total_row', tax_columns)
data.append(total_row_map.get('total_row'))
skip_total_row = 1
return columns, data, None, None, None, skip_total_row
def get_columns(additional_table_columns): def get_columns(additional_table_columns, filters):
columns = [ columns = []
_("Item Code") + ":Link/Item:120", _("Item Name") + "::120",
_("Item Group") + ":Link/Item Group:100", "Description::150", _("Invoice") + ":Link/Sales Invoice:120", if filters.get('group_by') != ('Item'):
_("Posting Date") + ":Date:80", _("Customer") + ":Link/Customer:120", columns.extend(
_("Customer Name") + "::120"] [
{
'label': _('Item Code'),
'fieldname': 'item_code',
'fieldtype': 'Link',
'options': 'Item',
'width': 120
},
{
'label': _('Item Name'),
'fieldname': 'item_name',
'fieldtype': 'Data',
'width': 120
}
]
)
if filters.get('group_by') not in ('Item', 'Item Group'):
columns.extend([
{
'label': _('Item Group'),
'fieldname': 'item_group',
'fieldtype': 'Link',
'options': 'Item Group',
'width': 120
}
])
columns.extend([
{
'label': _('Description'),
'fieldname': 'description',
'fieldtype': 'Data',
'width': 150
},
{
'label': _('Invoice'),
'fieldname': 'invoice',
'fieldtype': 'Link',
'options': 'Sales Invoice',
'width': 120
},
{
'label': _('Posting Date'),
'fieldname': 'posting_date',
'fieldtype': 'Date',
'width': 120
}
])
if filters.get('group_by') != 'Customer':
columns.extend([
{
'label': _('Customer Group'),
'fieldname': 'customer_group',
'fieldtype': 'Link',
'options': 'Customer Group',
'width': 120
}
])
if filters.get('group_by') not in ('Customer', 'Customer Group'):
columns.extend([
{
'label': _('Customer'),
'fieldname': 'customer',
'fieldtype': 'Link',
'options': 'Customer',
'width': 120
},
{
'label': _('Customer Name'),
'fieldname': 'customer_name',
'fieldtype': 'Data',
'width': 120
}
])
if additional_table_columns: if additional_table_columns:
columns += additional_table_columns columns += additional_table_columns
columns += [ columns += [
_("Customer Group") + ":Link/Customer Group:120", {
_("Receivable Account") + ":Link/Account:120", 'label': _('Receivable Account'),
_("Mode of Payment") + "::120", _("Territory") + ":Link/Territory:80", 'fieldname': 'debit_to',
_("Project") + ":Link/Project:80", _("Company") + ":Link/Company:100", 'fieldtype': 'Link',
_("Sales Order") + ":Link/Sales Order:100", _("Delivery Note") + ":Link/Delivery Note:100", 'options': 'Account',
_("Income Account") + ":Link/Account:140", _("Cost Center") + ":Link/Cost Center:140", 'width': 80
_("Stock Qty") + ":Float:120", _("Stock UOM") + "::100", },
_("Rate") + ":Currency/currency:120", {
_("Amount") + ":Currency/currency:120" 'label': _('Mode Of Payment'),
'fieldname': 'mode_of_payment',
'fieldtype': 'Data',
'width': 120
}
] ]
if filters.get('group_by') != 'Terriotory':
columns.extend([
{
'label': _("Territory"),
'fieldname': 'territory',
'fieldtype': 'Link',
'options': 'Territory',
'width': 80
}
])
columns += [
{
'label': _('Project'),
'fieldname': 'project',
'fieldtype': 'Link',
'options': 'Project',
'width': 80
},
{
'label': _('Company'),
'fieldname': 'company',
'fieldtype': 'Link',
'options': 'Company',
'width': 80
},
{
'label': _('Sales Order'),
'fieldname': 'sales_order',
'fieldtype': 'Link',
'options': 'Sales Order',
'width': 100
},
{
'label': _("Delivery Note"),
'fieldname': 'delivery_note',
'fieldtype': 'Link',
'options': 'Delivery Note',
'width': 100
},
{
'label': _('Income Account'),
'fieldname': 'income_account',
'fieldtype': 'Link',
'options': 'Account',
'width': 100
},
{
'label': _("Cost Center"),
'fieldname': 'cost_center',
'fieldtype': 'Link',
'options': 'Cost Center',
'width': 100
},
{
'label': _('Stock Qty'),
'fieldname': 'stock_qty',
'fieldtype': 'Float',
'width': 100
},
{
'label': _('Stock UOM'),
'fieldname': 'stock_uom',
'fieldtype': 'Link',
'options': 'UOM',
'width': 100
},
{
'label': _('Rate'),
'fieldname': 'rate',
'fieldtype': 'Float',
'options': 'currency',
'width': 100
},
{
'label': _('Amount'),
'fieldname': 'amount',
'fieldtype': 'Currency',
'options': 'currency',
'width': 100
},
{
'fieldname': 'currency',
'label': _('Currency'),
'fieldtype': 'Currency',
'width': 80,
'hidden': 1
}
]
if filters.get('group_by'):
columns.append({
'label': _('% Of Grand Total'),
'fieldname': 'percent_gt',
'fieldtype': 'Float',
'width': 80
})
return columns return columns
def get_conditions(filters): def get_conditions(filters):
@@ -112,24 +342,32 @@ def get_conditions(filters):
and ifnull(`tabSales Invoice Payment`.mode_of_payment, '') = %(mode_of_payment)s)""" and ifnull(`tabSales Invoice Payment`.mode_of_payment, '') = %(mode_of_payment)s)"""
if filters.get("warehouse"): if filters.get("warehouse"):
conditions += """ and exists(select name from `tabSales Invoice Item` conditions += """and ifnull(`tabSales Invoice Item`.warehouse, '') = %(warehouse)s"""
where parent=`tabSales Invoice`.name
and ifnull(`tabSales Invoice Item`.warehouse, '') = %(warehouse)s)"""
if filters.get("brand"): if filters.get("brand"):
conditions += """ and exists(select name from `tabSales Invoice Item` conditions += """and ifnull(`tabSales Invoice Item`.brand, '') = %(brand)s"""
where parent=`tabSales Invoice`.name
and ifnull(`tabSales Invoice Item`.brand, '') = %(brand)s)"""
if filters.get("item_group"): if filters.get("item_group"):
conditions += """ and exists(select name from `tabSales Invoice Item` conditions += """and ifnull(`tabSales Invoice Item`.item_group, '') = %(item_group)s"""
where parent=`tabSales Invoice`.name
and ifnull(`tabSales Invoice Item`.item_group, '') = %(item_group)s)"""
if not filters.get("group_by"):
conditions += "ORDER BY `tabSales Invoice`.posting_date desc, `tabSales Invoice Item`.item_group desc"
else:
conditions += get_group_by_conditions(filters, 'Sales Invoice')
return conditions return conditions
def get_group_by_conditions(filters, doctype):
if filters.get("group_by") == 'Invoice':
return "ORDER BY `tab{0} Item`.parent desc".format(doctype)
elif filters.get("group_by") == 'Item':
return "ORDER BY `tab{0} Item`.`item_code`".format(doctype)
elif filters.get("group_by") == 'Item Group':
return "ORDER BY `tab{0} Item`.{1}".format(doctype, frappe.scrub(filters.get('group_by')))
elif filters.get("group_by") in ('Customer', 'Customer Group', 'Territory', 'Supplier'):
return "ORDER BY `tab{0}`.{1}".format(doctype, frappe.scrub(filters.get('group_by')))
def get_items(filters, additional_query_columns): def get_items(filters, additional_query_columns):
conditions = get_conditions(filters) conditions = get_conditions(filters)
match_conditions = frappe.build_match_conditions("Sales Invoice") match_conditions = frappe.build_match_conditions("Sales Invoice")
@@ -156,9 +394,8 @@ def get_items(filters, additional_query_columns):
`tabSales Invoice`.update_stock, `tabSales Invoice Item`.uom, `tabSales Invoice Item`.qty {0} `tabSales Invoice`.update_stock, `tabSales Invoice Item`.uom, `tabSales Invoice Item`.qty {0}
from `tabSales Invoice`, `tabSales Invoice Item` from `tabSales Invoice`, `tabSales Invoice Item`
where `tabSales Invoice`.name = `tabSales Invoice Item`.parent where `tabSales Invoice`.name = `tabSales Invoice Item`.parent
and `tabSales Invoice`.docstatus = 1 %s %s and `tabSales Invoice`.docstatus = 1 {1} {2}
order by `tabSales Invoice`.posting_date desc, `tabSales Invoice Item`.item_code desc """.format(additional_query_columns or '', conditions, match_conditions), filters, as_dict=1) #nosec
""".format(additional_query_columns or '') % (conditions, match_conditions), filters, as_dict=1)
def get_delivery_notes_against_sales_order(item_list): def get_delivery_notes_against_sales_order(item_list):
so_dn_map = frappe._dict() so_dn_map = frappe._dict()
@@ -177,6 +414,15 @@ def get_delivery_notes_against_sales_order(item_list):
return so_dn_map return so_dn_map
def get_grand_total(filters, doctype):
return frappe.db.sql(""" SELECT
SUM(`tab{0}`.base_grand_total)
FROM `tab{0}`
WHERE `tab{0}`.docstatus = 1
and posting_date between %s and %s
""".format(doctype), (filters.get('from_date'), filters.get('to_date')))[0][0] #nosec
def get_deducted_taxes(): def get_deducted_taxes():
return frappe.db.sql_list("select name from `tabPurchase Taxes and Charges` where add_deduct_tax = 'Deduct'") return frappe.db.sql_list("select name from `tabPurchase Taxes and Charges` where add_deduct_tax = 'Deduct'")
@@ -264,9 +510,117 @@ def get_tax_accounts(item_list, columns, company_currency,
tax_columns.sort() tax_columns.sort()
for desc in tax_columns: for desc in tax_columns:
columns.append(desc + " Rate:Data:80") columns.append({
columns.append(desc + " Amount:Currency/currency:100") 'label': _(desc + ' Rate'),
'fieldname': frappe.scrub(desc + ' Rate'),
'fieldtype': 'Float',
'width': 100
})
columns += ["Total Tax:Currency/currency:80", "Total:Currency/currency:100"] columns.append({
'label': _(desc + ' Amount'),
'fieldname': frappe.scrub(desc + ' Amount'),
'fieldtype': 'Currency',
'options': 'currency',
'width': 100
})
columns += [
{
'label': _('Total Tax'),
'fieldname': 'total_tax',
'fieldtype': 'Currency',
'options': 'currency',
'width': 100
},
{
'label': _('Total'),
'fieldname': 'total',
'fieldtype': 'Currency',
'options': 'currency',
'width': 100
}
]
return itemised_tax, tax_columns return itemised_tax, tax_columns
def add_total_row(data, filters, prev_group_by_value, item, total_row_map,
group_by_field, subtotal_display_field, grand_total, tax_columns):
if prev_group_by_value != item.get(group_by_field, ''):
if prev_group_by_value:
total_row = total_row_map.get(prev_group_by_value)
data.append(total_row)
data.append({})
add_sub_total_row(total_row, total_row_map, 'total_row', tax_columns)
prev_group_by_value = item.get(group_by_field, '')
total_row_map.setdefault(item.get(group_by_field, ''), {
subtotal_display_field: get_display_value(filters, group_by_field, item),
'stock_qty': 0.0,
'amount': 0.0,
'bold': 1,
'total_tax': 0.0,
'total': 0.0,
'percent_gt': 0.0
})
total_row_map.setdefault('total_row', {
subtotal_display_field: "Total",
'stock_qty': 0.0,
'amount': 0.0,
'bold': 1,
'total_tax': 0.0,
'total': 0.0,
'percent_gt': 0.0
})
return data, prev_group_by_value
def get_display_value(filters, group_by_field, item):
if filters.get('group_by') == 'Item':
if item.get('item_code') != item.get('item_name'):
value = cstr(item.get('item_code')) + "<br><br>" + \
"<span style='font-weight: normal'>" + cstr(item.get('item_name')) + "</span>"
else:
value = item.get('item_code', '')
elif filters.get('group_by') in ('Customer', 'Supplier'):
party = frappe.scrub(filters.get('group_by'))
if item.get(party) != item.get(party+'_name'):
value = item.get(party) + "<br><br>" + \
"<span style='font-weight: normal'>" + item.get(party+'_name') + "</span>"
else:
value = item.get(party)
else:
value = item.get(group_by_field)
return value
def get_group_by_and_display_fields(filters):
if filters.get('group_by') == 'Item':
group_by_field = 'item_code'
subtotal_display_field = 'invoice'
elif filters.get('group_by') == 'Invoice':
group_by_field = 'parent'
subtotal_display_field = 'item_code'
else:
group_by_field = frappe.scrub(filters.get('group_by'))
subtotal_display_field = 'item_code'
return group_by_field, subtotal_display_field
def add_sub_total_row(item, total_row_map, group_by_value, tax_columns):
total_row = total_row_map.get(group_by_value)
total_row['stock_qty'] += item['stock_qty']
total_row['amount'] += item['amount']
total_row['total_tax'] += item['total_tax']
total_row['total'] += item['total']
total_row['percent_gt'] += item['percent_gt']
for tax in tax_columns:
total_row.setdefault(frappe.scrub(tax + ' Amount'), 0.0)
total_row[frappe.scrub(tax + ' Amount')] += flt(item[frappe.scrub(tax + ' Amount')])

View File

@@ -139,7 +139,7 @@ def get_columns(invoice_list, additional_table_columns):
columns +=[ columns +=[
{ {
'label': _("Custmer Group"), 'label': _("Customer Group"),
'fieldname': 'customer_group', 'fieldname': 'customer_group',
'fieldtype': 'Link', 'fieldtype': 'Link',
'options': 'Customer Group', 'options': 'Customer Group',
@@ -175,7 +175,7 @@ def get_columns(invoice_list, additional_table_columns):
'label': _("Project"), 'label': _("Project"),
'fieldname': 'project', 'fieldname': 'project',
'fieldtype': 'Link', 'fieldtype': 'Link',
'options': 'project', 'options': 'Project',
'width': 80 'width': 80
}, },
{ {