diff --git a/erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.js b/erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.js index e936a173734..f88906a0f1f 100644 --- a/erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.js +++ b/erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.js @@ -34,6 +34,20 @@ frappe.query_reports["Item-wise Purchase Register"] = { "label": __("Mode of Payment"), "fieldtype": "Link", "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; + } } diff --git a/erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py b/erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py index 380b208548c..3a5a4548f5a 100644 --- a/erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py +++ b/erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py @@ -5,7 +5,9 @@ from __future__ import unicode_literals import frappe, erpnext from frappe import _ 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, update_total_row, + get_group_by_conditions) def execute(filters=None): return _execute(filters) @@ -13,7 +15,7 @@ def execute(filters=None): def _execute(filters=None, additional_table_columns=None, additional_query_columns=None): if not filters: filters = {} 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) @@ -23,16 +25,15 @@ def _execute(filters=None, additional_table_columns=None, additional_query_colum itemised_tax, tax_columns = get_tax_accounts(item_list, columns, company_currency, 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) data = [] + total_row_map = {} + prev_group_by_value = '' + + if filters.get('group_by'): + grand_total = get_grand_total(filters, 'Purchase Invoice') + for d in item_list: if not d.stock_qty: continue @@ -44,51 +45,240 @@ def _execute(filters=None, additional_table_columns=None, additional_query_colum purchase_receipt = ", ".join(po_pr_map.get(d.po_detail, [])) 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: for col in additional_query_columns: - row.append(d.get(col)) + row.update({ + col: d.get(col) + }) - row += [ - d.credit_to, d.mode_of_payment, d.project, d.company, d.purchase_order, - purchase_receipt, expense_account, d.stock_qty, d.stock_uom, d.base_net_amount / d.stock_qty, d.base_net_amount - ] + row.update({ + 'credit_to': d.credit_to, + '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 for tax in tax_columns: 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")) - 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) + update_total_row(row, total_row_map, d.get(group_by_field, ''), tax_columns) data.append(row) + 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({}) + return columns, data -def get_columns(additional_table_columns): - columns = [ - _("Item Code") + ":Link/Item:120", _("Item Name") + "::120", - _("Item Group") + ":Link/Item Group:100", "Description::150", _("Invoice") + ":Link/Purchase Invoice:120", - _("Posting Date") + ":Date:80", _("Supplier") + ":Link/Supplier:120", - "Supplier Name::120" - ] +def get_columns(additional_table_columns, filters): + + columns = [] + + if filters.get('group_by') != ('Item'): + 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: columns += additional_table_columns columns += [ - "Payable Account:Link/Account:120", - _("Mode of Payment") + ":Link/Mode of Payment:80", _("Project") + ":Link/Project:80", - _("Company") + ":Link/Company:100", _("Purchase Order") + ":Link/Purchase Order:100", - _("Purchase Receipt") + ":Link/Purchase Receipt:100", _("Expense Account") + ":Link/Account:140", - _("Stock Qty") + ":Float:120", _("Stock UOM") + "::100", - _("Rate") + ":Currency/currency:120", _("Amount") + ":Currency/currency:120" + { + 'label': _('Payable Account'), + 'fieldname': 'credit_to', + 'fieldtype': 'Link', + 'options': 'Account', + '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 def get_conditions(filters): @@ -103,6 +293,11 @@ def get_conditions(filters): if filters.get(opts[0]): 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 def get_items(filters, additional_query_columns): @@ -129,7 +324,6 @@ def get_items(filters, additional_query_columns): from `tabPurchase Invoice`, `tabPurchase Invoice Item` where `tabPurchase Invoice`.name = `tabPurchase Invoice Item`.`parent` and `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) def get_aii_accounts():