From f1b098e03c150deb3f22518952f6548486aac713 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Thu, 18 Jan 2018 09:23:32 +0530 Subject: [PATCH 1/9] payment terms filter in AR Summary report (#12529) --- .../accounts_receivable_summary.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/erpnext/accounts/report/accounts_receivable_summary/accounts_receivable_summary.js b/erpnext/accounts/report/accounts_receivable_summary/accounts_receivable_summary.js index ceed5e595b..96e5d18093 100644 --- a/erpnext/accounts/report/accounts_receivable_summary/accounts_receivable_summary.js +++ b/erpnext/accounts/report/accounts_receivable_summary/accounts_receivable_summary.js @@ -23,10 +23,10 @@ frappe.query_reports["Accounts Receivable Summary"] = { "options": "Customer Group" }, { - "fieldname":"credit_days_based_on", - "label": __("Credit Days Based On"), - "fieldtype": "Select", - "options": "\nFixed Days\nLast Day of the Next Month" + "fieldname":"payment_terms_template", + "label": __("Payment Terms Template"), + "fieldtype": "Link", + "options": "Payment Terms Template" }, { "fieldtype": "Break", From 00e547d319fa0cbf7fa7652e56d7e2c8d92163a3 Mon Sep 17 00:00:00 2001 From: Faris Ansari Date: Thu, 18 Jan 2018 09:28:13 +0530 Subject: [PATCH 2/9] Encode letterhead filename (#12525) --- erpnext/utilities/user_progress_utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/utilities/user_progress_utils.py b/erpnext/utilities/user_progress_utils.py index 9d5c25879d..18d38c0fe8 100644 --- a/erpnext/utilities/user_progress_utils.py +++ b/erpnext/utilities/user_progress_utils.py @@ -40,7 +40,7 @@ def create_customers(args_data): @frappe.whitelist() def create_letterhead(args_data): args = json.loads(args_data) - letterhead = args.get("letterhead") + letterhead = args.get("letterhead").encode('utf-8') if letterhead: try: frappe.get_doc({ From bd47abdc9aefa7f013da8784fbefccd355cadf73 Mon Sep 17 00:00:00 2001 From: rohitwaghchaure Date: Thu, 18 Jan 2018 09:32:43 +0530 Subject: [PATCH 3/9] [Enhance] Running Balance in GL Report (#12491) * Running Balance in GL Report * Supplier invoice no in GL Report/Print Format --- .../report/general_ledger/general_ledger.html | 60 +++-- .../report/general_ledger/general_ledger.js | 5 + .../report/general_ledger/general_ledger.py | 213 +++++++++++++----- 3 files changed, 212 insertions(+), 66 deletions(-) diff --git a/erpnext/accounts/report/general_ledger/general_ledger.html b/erpnext/accounts/report/general_ledger/general_ledger.html index 91cc3c990e..83325aabed 100644 --- a/erpnext/accounts/report/general_ledger/general_ledger.html +++ b/erpnext/accounts/report/general_ledger/general_ledger.html @@ -19,36 +19,66 @@ {%= __("Date") %} {%= __("Ref") %} - {%= __("Party") %} + {%= __("Party") %} {%= __("Debit") %} {%= __("Credit") %} + {%= __("Balance") %} {% for(var i=0, l=data.length; i - {% if(data[i][__("Posting Date")]) { %} - {%= dateutil.str_to_user(data[i][__("Posting Date")]) %} - {%= data[i][__("Voucher Type")] %} -
{%= data[i][__("Voucher No")] %} + {% if(data[i].posting_date) { %} + {%= dateutil.str_to_user(data[i].posting_date) %} + {%= data[i].voucher_type %} +
{%= data[i].voucher_no %} {% if(!(filters.party || filters.account)) { %} - {%= data[i][__("Party")] || data[i][__("Account")] %} + {%= data[i].party || data[i].account %}
{% } %} - {{ __("Against") }}: {%= data[i][__("Against Account")] %} -
{%= __("Remarks") %}: {%= data[i][__("Remarks")] %} - {%= format_currency(data[i][__("Debit")]) %} - {%= format_currency(data[i][__("Credit")]) %} + {{ __("Against") }}: {%= data[i].against %} +
{%= __("Remarks") %}: {%= data[i].remarks %} + {% if(data[i].bill_no) { %} +
{%= __("Supplier Invoice No") %}: {%= data[i].bill_no %} + {% } %} + + {% if(filters.print_in_account_currency) { %} + + {%= format_currency(data[i].debit_in_account_currency, data[i].account_currency) %} + + + {%= format_currency(data[i].credit_in_account_currency, data[i].account_currency) %} + + {% } else { %} + + {%= format_currency(data[i].debit) %} + + {%= format_currency(data[i].credit) %} + {% } %} {% } else { %} - {%= frappe.format(data[i][__("Account")], {fieldtype: "Link"}) || " " %} - - {%= data[i][__("Account")] && format_currency(data[i][__("Debit")]) %} - - {%= data[i][__("Account")] && format_currency(data[i][__("Credit")]) %} + {%= frappe.format(data[i].account, {fieldtype: "Link"}) || " " %} + {% if(filters.print_in_account_currency) { %} + + {%= data[i].account && format_currency(data[i].debit_in_account_currency, data[i].account_currency) %} + + {%= data[i].account && format_currency(data[i].credit_in_account_currency, data[i].account_currency) %} + {% } else { %} + + {%= data[i].account && format_currency(data[i].debit) %} + + + {%= data[i].account && format_currency(data[i].credit) %} + + {% } %} + {% } %} + {% if(filters.print_in_account_currency) { %} + {%= data[i].balance_in_account_currency %} + {% } else { %} + {%= data[i].balance %} {% } %} {% } %} diff --git a/erpnext/accounts/report/general_ledger/general_ledger.js b/erpnext/accounts/report/general_ledger/general_ledger.js index 282c767b35..adefadd2db 100644 --- a/erpnext/accounts/report/general_ledger/general_ledger.js +++ b/erpnext/accounts/report/general_ledger/general_ledger.js @@ -105,6 +105,11 @@ frappe.query_reports["General Ledger"] = { "fieldname":"group_by_account", "label": __("Group by Account"), "fieldtype": "Check", + }, + { + "fieldname":"print_in_account_currency", + "label": __("Print in Account Currency"), + "fieldtype": "Check", } ] } diff --git a/erpnext/accounts/report/general_ledger/general_ledger.py b/erpnext/accounts/report/general_ledger/general_ledger.py index eefb3d159f..72fe793582 100644 --- a/erpnext/accounts/report/general_ledger/general_ledger.py +++ b/erpnext/accounts/report/general_ledger/general_ledger.py @@ -3,12 +3,17 @@ from __future__ import unicode_literals import frappe -from frappe.utils import getdate, cstr, flt +from frappe.utils import getdate, cstr, flt, fmt_money from frappe import _, _dict from erpnext.accounts.utils import get_account_currency def execute(filters=None): account_details = {} + + if filters and filters.get('print_in_account_currency') and \ + not filters.get('account'): + frappe.throw(_("Select an account to print in account currency")) + for acc in frappe.db.sql("""select name, is_group from tabAccount""", as_dict=1): account_details.setdefault(acc.name, acc) @@ -76,28 +81,6 @@ def set_account_currency(filters): return filters -def get_columns(filters): - columns = [ - _("Posting Date") + ":Date:90", _("Account") + ":Link/Account:200", - _("Debit") + ":Float:100", _("Credit") + ":Float:100" - ] - - if filters.get("show_in_account_currency"): - columns += [ - _("Debit") + " (" + filters.account_currency + ")" + ":Float:100", - _("Credit") + " (" + filters.account_currency + ")" + ":Float:100" - ] - - columns += [ - _("Voucher Type") + "::120", _("Voucher No") + ":Dynamic Link/"+_("Voucher Type")+":160", - _("Against Account") + "::120", _("Party Type") + "::80", _("Party") + "::150", - _("Project") + ":Link/Project:100", _("Cost Center") + ":Link/Cost Center:100", - _("Against Voucher Type") + "::120", _("Against Voucher") + ":Dynamic Link/"+_("Against Voucher Type")+":160", - _("Remarks") + "::400" - ] - - return columns - def get_result(filters, account_details): gl_entries = get_gl_entries(filters) @@ -193,24 +176,6 @@ def get_data_with_opening_closing(filters, account_details, gl_entries): # closing data.append(totals.closing) - #total closing - total_closing = totals.total_closing - total_debit = totals.closing.get('debit', 0) - total_credit = totals.closing.get('credit', 0) - debit_in_account_currency = totals.closing.get('debit_in_account_currency', 0) - credit_in_account_currency = totals.closing.get('credit_in_account_currency', 0) - - total_amount = total_debit - total_credit - - if total_amount > 0: - total_closing['debit'] = total_amount - total_closing['debit_in_account_currency'] = debit_in_account_currency - credit_in_account_currency - else: - total_closing['credit'] = abs(total_amount) - total_closing['credit_in_account_currency'] = abs(debit_in_account_currency - credit_in_account_currency) - - data.append(totals.total_closing) - return data def get_totals_dict(): @@ -225,8 +190,7 @@ def get_totals_dict(): return _dict( opening = _get_debit_credit_dict(_('Opening')), total = _get_debit_credit_dict(_('Total')), - closing = _get_debit_credit_dict(_('Closing (Opening + Total)')), - total_closing = _get_debit_credit_dict(_('Closing Balance (Dr - Cr)')) + closing = _get_debit_credit_dict(_('Closing (Opening + Total)')) ) def initialize_gle_map(gl_entries): @@ -270,17 +234,164 @@ def get_accountwise_gle(filters, gl_entries, gle_map): return totals, entries def get_result_as_list(data, filters): - result = [] + balance, balance_in_account_currency = 0, 0 + inv_details = get_supplier_invoice_details() + for d in data: - row = [d.get("posting_date"), d.get("account"), d.get("debit"), d.get("credit")] + if not d.posting_date: + balance, balance_in_account_currency = 0, 0 + + balance, label = get_balance(d, balance, 'debit', 'credit') + d['balance'] = '{0} {1}'.format(fmt_money(abs(balance)), label) if filters.get("show_in_account_currency"): - row += [d.get("debit_in_account_currency"), d.get("credit_in_account_currency")] + balance_in_account_currency, label = get_balance(d, balance_in_account_currency, + 'debit_in_account_currency', 'credit_in_account_currency') + d['balance_in_account_currency'] = '{0} {1}'.format(fmt_money(abs(balance_in_account_currency)), label) + else: + d['debit_in_account_currency'] = d.get('debit', 0) + d['credit_in_account_currency'] = d.get('credit', 0) + d['balance_in_account_currency'] = d.get('balance') - row += [d.get("voucher_type"), d.get("voucher_no"), d.get("against"), - d.get("party_type"), d.get("party"), d.get("project"), d.get("cost_center"), d.get("against_voucher_type"), d.get("against_voucher"), d.get("remarks") - ] + d['account_currency'] = filters.account_currency + d['bill_no'] = inv_details.get(d.against_voucher, '') - result.append(row) + return data - return result +def get_supplier_invoice_details(): + inv_details = {} + for d in frappe.db.sql(""" select name, bill_no from `tabPurchase Invoice` + where docstatus = 1 and bill_no is not null and bill_no != '' """, as_dict=1): + inv_details[d.name] = d.bill_no + + return inv_details + +def get_balance(row, balance, debit_field, credit_field): + balance += (row.get(debit_field, 0) - row.get(credit_field, 0)) + label = 'DR' if balance > 0 else 'CR' + + return balance, label + +def get_columns(filters): + columns = [ + { + "label": _("Posting Date"), + "fieldname": "posting_date", + "fieldtype": "Date", + "width": 90 + }, + { + "label": _("Account"), + "fieldname": "account", + "fieldtype": "Link", + "options": "Account", + "width": 180 + }, + { + "label": _("Debit"), + "fieldname": "debit", + "fieldtype": "Float", + "width": 100 + }, + { + "label": _("Credit"), + "fieldname": "credit", + "fieldtype": "Float", + "width": 100 + }, + { + "label": _("Balance"), + "fieldname": "balance", + "fieldtype": "Data", + "width": 100 + } + ] + + if filters.get("show_in_account_currency"): + columns.extend([ + { + "label": _("Debit") + " (" + filters.account_currency + ")", + "fieldname": "debit_in_account_currency", + "fieldtype": "Float", + "width": 100 + }, + { + "label": _("Credit") + " (" + filters.account_currency + ")", + "fieldname": "credit_in_account_currency", + "fieldtype": "Float", + "width": 100 + }, + { + "label": _("Balance") + " (" + filters.account_currency + ")", + "fieldname": "balance_in_account_currency", + "fieldtype": "Data", + "width": 100 + } + ]) + + columns.extend([ + { + "label": _("Voucher Type"), + "fieldname": "voucher_type", + "width": 120 + }, + { + "label": _("Voucher No"), + "fieldname": "voucher_no", + "fieldtype": "Dynamic Link", + "options": "voucher_type", + "width": 180 + }, + { + "label": _("Against Account"), + "fieldname": "against", + "width": 120 + }, + { + "label": _("Party Type"), + "fieldname": "party_type", + "width": 100 + }, + { + "label": _("Party"), + "fieldname": "party", + "width": 100 + }, + { + "label": _("Project"), + "options": "Project", + "fieldname": "project", + "width": 100 + }, + { + "label": _("Cost Center"), + "options": "Cost Center", + "fieldname": "cost_center", + "width": 100 + }, + { + "label": _("Against Voucher Type"), + "fieldname": "against_voucher_type", + "width": 100 + }, + { + "label": _("Against Voucher"), + "fieldname": "against_voucher", + "fieldtype": "Dynamic Link", + "options": "against_voucher_type", + "width": 100 + }, + { + "label": _("Supplier Invoice No"), + "fieldname": "bill_no", + "fieldtype": "Data", + "width": 100 + }, + { + "label": _("Remarks"), + "fieldname": "remarks", + "width": 400 + } + ]) + + return columns From 95adb60a8f92f8275316817f9d9b64fce5ffb737 Mon Sep 17 00:00:00 2001 From: Rohit Waghchaure Date: Thu, 18 Jan 2018 15:52:52 +0530 Subject: [PATCH 4/9] Fix patch --- erpnext/patches/v7_0/convert_timelog_to_timesheet.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/patches/v7_0/convert_timelog_to_timesheet.py b/erpnext/patches/v7_0/convert_timelog_to_timesheet.py index 9894c2a6d3..4b6cf74535 100644 --- a/erpnext/patches/v7_0/convert_timelog_to_timesheet.py +++ b/erpnext/patches/v7_0/convert_timelog_to_timesheet.py @@ -16,7 +16,7 @@ def execute(): else: company = frappe.db.get_single_value('Global Defaults', 'default_company') - time_sheet = make_timesheet(data.production_order) + time_sheet = make_timesheet(data.production_order, company) args = get_timelog_data(data) add_timesheet_detail(time_sheet, args) if data.docstatus == 2: From 5c4f52ccf17d7cab1e7a5986ca14ee55ecf3e72c Mon Sep 17 00:00:00 2001 From: Rohit Waghchaure Date: Thu, 18 Jan 2018 15:43:35 +0530 Subject: [PATCH 5/9] [Fix] POS css --- erpnext/public/less/pos.less | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/erpnext/public/less/pos.less b/erpnext/public/less/pos.less index 0fcb654fff..af3008e909 100644 --- a/erpnext/public/less/pos.less +++ b/erpnext/public/less/pos.less @@ -216,6 +216,10 @@ input[type=number]::-webkit-outer-spin-button { } .grand-total-value { - font-size: 24px; + font-size: 18px; } +} + +.rounded-total-value { + font-size: 18px; } \ No newline at end of file From de420322b55539fa2888c910745e4bb76e938ee5 Mon Sep 17 00:00:00 2001 From: Rohit Waghchaure Date: Thu, 18 Jan 2018 17:20:21 +0530 Subject: [PATCH 6/9] [Fix] Sales payment summary issue --- .../report/sales_payment_summary/sales_payment_summary.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/accounts/report/sales_payment_summary/sales_payment_summary.py b/erpnext/accounts/report/sales_payment_summary/sales_payment_summary.py index f38f28d901..6ad36f67d6 100644 --- a/erpnext/accounts/report/sales_payment_summary/sales_payment_summary.py +++ b/erpnext/accounts/report/sales_payment_summary/sales_payment_summary.py @@ -36,7 +36,7 @@ def get_sales_payment_data(filters, columns): return data def get_conditions(filters): - conditions = "" + conditions = "1=1" if filters.get("from_date"): conditions += "a.posting_date >= %(from_date)s" if filters.get("to_date"): conditions += " and a.posting_date <= %(to_date)s" if filters.get("company"): conditions += " and a.company=%(company)s" From 86cbde90571bd85c23f5ed0ddf6b6a17147da9bc Mon Sep 17 00:00:00 2001 From: Rohit Waghchaure Date: Fri, 19 Jan 2018 12:40:27 +0530 Subject: [PATCH 7/9] [Fix] Error in PO. No Permission for Buying Settings --- erpnext/buying/doctype/purchase_order/purchase_order.js | 8 ++++---- erpnext/buying/doctype/purchase_order/purchase_order.py | 6 ++++++ 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/erpnext/buying/doctype/purchase_order/purchase_order.js b/erpnext/buying/doctype/purchase_order/purchase_order.js index fe8642c311..ab8ab03dbf 100644 --- a/erpnext/buying/doctype/purchase_order/purchase_order.js +++ b/erpnext/buying/doctype/purchase_order/purchase_order.js @@ -21,10 +21,10 @@ frappe.ui.form.on("Purchase Order", { return erpnext.queries.warehouse(frm.doc); }); - frappe.db.get_value('Buying Settings', {name: 'Buying Settings'}, 'disable_fetch_last_purchase_rate', (r) => { - value = r && cint(r.disable_fetch_last_purchase_rate); - frm.toggle_display('get_last_purchase_rate', !value); - }); + if (frm.doc.__onload) { + frm.toggle_display('get_last_purchase_rate', + frm.doc.__onload.disable_fetch_last_purchase_rate); + } frm.set_indicator_formatter('item_code', function(doc) { return (doc.qty<=doc.received_qty) ? "green" : "orange" }) diff --git a/erpnext/buying/doctype/purchase_order/purchase_order.py b/erpnext/buying/doctype/purchase_order/purchase_order.py index 1929476cf3..db13bd5520 100644 --- a/erpnext/buying/doctype/purchase_order/purchase_order.py +++ b/erpnext/buying/doctype/purchase_order/purchase_order.py @@ -34,6 +34,12 @@ class PurchaseOrder(BuyingController): 'overflow_type': 'order' }] + def onload(self): + super(PurchaseOrder, self).onload() + + self.set_onload('disable_fetch_last_purchase_rate', + cint(frappe.db.get_single_value("Buying Settings", "disable_fetch_last_purchase_rate"))) + def validate(self): super(PurchaseOrder, self).validate() From 2f3ad64bd69b6582a30b0ab208c44422c904ec69 Mon Sep 17 00:00:00 2001 From: Rohit Waghchaure Date: Thu, 18 Jan 2018 18:20:14 +0530 Subject: [PATCH 8/9] [Fix] Precision issue while making material requests from production planning tool --- .../production_planning_tool/production_planning_tool.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/erpnext/manufacturing/doctype/production_planning_tool/production_planning_tool.py b/erpnext/manufacturing/doctype/production_planning_tool/production_planning_tool.py index 3ef7be1494..16a30230c0 100644 --- a/erpnext/manufacturing/doctype/production_planning_tool/production_planning_tool.py +++ b/erpnext/manufacturing/doctype/production_planning_tool/production_planning_tool.py @@ -310,6 +310,7 @@ class ProductionPlanningTool(Document): } """ item_list = [] + precision = frappe.get_precision("BOM Item", "stock_qty") for bom, so_wise_qty in bom_dict.items(): bom_wise_item_details = {} @@ -334,8 +335,9 @@ class ProductionPlanningTool(Document): for item, item_details in bom_wise_item_details.items(): for so_qty in so_wise_qty: - item_list.append([item, flt(item_details.qty) * so_qty[1], item_details.description, - item_details.stock_uom, item_details.min_order_qty, so_qty[0]]) + item_list.append([item, flt(flt(item_details.qty) * so_qty[1], precision), + item_details.description, item_details.stock_uom, item_details.min_order_qty, + so_qty[0]]) self.make_items_dict(item_list) From e1815f0989f6cf076381eeafaf9408b69bcfc186 Mon Sep 17 00:00:00 2001 From: Rohit Waghchaure Date: Fri, 19 Jan 2018 13:59:56 +0600 Subject: [PATCH 9/9] bumped to version 10.0.11 --- erpnext/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/__init__.py b/erpnext/__init__.py index bd400c0870..7ab6784f3f 100644 --- a/erpnext/__init__.py +++ b/erpnext/__init__.py @@ -5,7 +5,7 @@ import frappe from erpnext.hooks import regional_overrides from frappe.utils import getdate -__version__ = '10.0.10' +__version__ = '10.0.11' def get_default_company(user=None): '''Get default company for user'''