From 7e03e046ec8749ab62ca65f2ff71722065b675d0 Mon Sep 17 00:00:00 2001 From: "Chinmay D. Pai" Date: Sat, 5 Oct 2019 10:18:21 +0530 Subject: [PATCH 01/12] chore: check if discount_percentage exists fixes TypeError: '>' not supported between instances of 'NoneType' and 'float' Signed-off-by: Chinmay D. Pai --- erpnext/regional/italy/e-invoice.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/regional/italy/e-invoice.xml b/erpnext/regional/italy/e-invoice.xml index 0a5bb296a5f..049a7eba61a 100644 --- a/erpnext/regional/italy/e-invoice.xml +++ b/erpnext/regional/italy/e-invoice.xml @@ -19,7 +19,7 @@ {%- endmacro %} {%- macro render_discount_or_margin(item) -%} -{%- if item.discount_percentage > 0.0 or item.margin_type %} +{%- if (item.discount_percentage and item.discount_percentage > 0.0) or item.margin_type %} {%- if item.discount_percentage > 0.0 %} SC From 382735ad2f4989abfffe6ea7676c3e5730f62710 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Thu, 10 Oct 2019 16:40:10 +0530 Subject: [PATCH 02/12] fix: Set incoming rate for standalone sales return (#19264) --- erpnext/controllers/selling_controller.py | 5 +++-- erpnext/controllers/stock_controller.py | 5 ++++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/erpnext/controllers/selling_controller.py b/erpnext/controllers/selling_controller.py index abac43570e4..8b406f27f38 100644 --- a/erpnext/controllers/selling_controller.py +++ b/erpnext/controllers/selling_controller.py @@ -306,8 +306,9 @@ class SellingController(StockController): if flt(d.conversion_factor)==0.0: d.conversion_factor = get_conversion_factor(d.item_code, d.uom).get("conversion_factor") or 1.0 return_rate = 0 - if cint(self.is_return) and self.return_against and self.docstatus==1: - return_rate = self.get_incoming_rate_for_sales_return(d.item_code, self.return_against) + if cint(self.is_return) and self.docstatus==1: + return_rate = self.get_incoming_rate_for_sales_return(d.item_code, + d.warehouse, self.return_against) # On cancellation or if return entry submission, make stock ledger entry for # target warehouse first, to update serial no values properly diff --git a/erpnext/controllers/stock_controller.py b/erpnext/controllers/stock_controller.py index 0c7629defb8..4a468205276 100644 --- a/erpnext/controllers/stock_controller.py +++ b/erpnext/controllers/stock_controller.py @@ -299,7 +299,7 @@ class StockController(AccountsController): return serialized_items - def get_incoming_rate_for_sales_return(self, item_code, against_document): + def get_incoming_rate_for_sales_return(self, item_code, warehouse, against_document): incoming_rate = 0.0 if against_document and item_code: incoming_rate = frappe.db.sql("""select abs(stock_value_difference / actual_qty) @@ -308,6 +308,9 @@ class StockController(AccountsController): and item_code = %s limit 1""", (self.doctype, against_document, item_code)) incoming_rate = incoming_rate[0][0] if incoming_rate else 0.0 + else: + incoming_rate = get_valuation_rate(item_code, warehouse, + self.doctype, against_document, company=self.company, currency=self.currency) return incoming_rate From aa3d6ed11e870726eb4c679aa1a4b2081c98345f Mon Sep 17 00:00:00 2001 From: Marica Date: Fri, 11 Oct 2019 11:52:29 +0530 Subject: [PATCH 03/12] fix: Margin and Discount percentage set correctly via 'Update Items' (#19173) --- erpnext/controllers/accounts_controller.py | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/erpnext/controllers/accounts_controller.py b/erpnext/controllers/accounts_controller.py index 372d5412bb8..4d6e22e1915 100644 --- a/erpnext/controllers/accounts_controller.py +++ b/erpnext/controllers/accounts_controller.py @@ -1114,8 +1114,22 @@ def update_child_qty_rate(parent_doctype, trans_items, parent_doctype_name): else: child_item.rate = flt(d.get("rate")) if flt(child_item.price_list_rate): - child_item.discount_percentage = flt((1 - flt(child_item.rate) / flt(child_item.price_list_rate)) * 100.0, \ - child_item.precision("discount_percentage")) + if flt(child_item.rate) > flt(child_item.price_list_rate): + # if rate is greater than price_list_rate, set margin + # or set discount + child_item.discount_percentage = 0 + child_item.margin_type = "Amount" + child_item.margin_rate_or_amount = flt(child_item.rate - child_item.price_list_rate, + child_item.precision("margin_rate_or_amount")) + child_item.rate_with_margin = child_item.rate + else: + child_item.discount_percentage = flt((1 - flt(child_item.rate) / flt(child_item.price_list_rate)) * 100.0, + child_item.precision("discount_percentage")) + child_item.discount_amount = flt( + child_item.price_list_rate) - flt(child_item.rate) + child_item.margin_type = "" + child_item.margin_rate_or_amount = 0 + child_item.rate_with_margin = 0 child_item.flags.ignore_validate_update_after_submit = True child_item.save() From b4e61e19bb1e0d611f4ae815b03e3a532176dda9 Mon Sep 17 00:00:00 2001 From: deepeshgarg007 Date: Sat, 12 Oct 2019 23:02:53 +0530 Subject: [PATCH 04/12] fix: Chart fix in Analytics report --- erpnext/selling/report/sales_analytics/sales_analytics.js | 6 +++++- erpnext/selling/report/sales_analytics/sales_analytics.py | 8 +++++--- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/erpnext/selling/report/sales_analytics/sales_analytics.js b/erpnext/selling/report/sales_analytics/sales_analytics.js index fbe045bf35c..52135166648 100644 --- a/erpnext/selling/report/sales_analytics/sales_analytics.js +++ b/erpnext/selling/report/sales_analytics/sales_analytics.js @@ -80,10 +80,14 @@ frappe.query_reports["Sales Analytics"] = { var tree_type = frappe.query_report.filters[0].value; - if(tree_type == "Customer" || tree_type == "Item") { + if(tree_type == "Customer") { row_values = data.slice(4,length-1).map(function (column) { return column.content; }) + } else if (tree_type == "Item") { + row_values = data.slice(5,length-1).map(function (column) { + return column.content; + }) } else { row_values = data.slice(3,length-1).map(function (column) { diff --git a/erpnext/selling/report/sales_analytics/sales_analytics.py b/erpnext/selling/report/sales_analytics/sales_analytics.py index 55941d12149..1013373bec5 100644 --- a/erpnext/selling/report/sales_analytics/sales_analytics.py +++ b/erpnext/selling/report/sales_analytics/sales_analytics.py @@ -114,7 +114,7 @@ class Analytics(object): if self.filters["value_quantity"] == 'Value': value_field = 'base_amount' else: - value_field = 'qty' + value_field = 'stock_qty' self.entries = frappe.db.sql(""" select i.item_code as entity, i.item_name as entity_name, i.stock_uom, i.{value_field} as value_field, s.{date_field} @@ -301,8 +301,10 @@ class Analytics(object): def get_chart_data(self): length = len(self.columns) - if self.filters.tree_type in ["Customer", "Supplier", "Item"]: - labels = [d.get("label") for d in self.columns[2:length-1]] + if self.filters.tree_type in ["Customer", "Supplier"]: + labels = [d.get("label") for d in self.columns[2:length - 1]] + elif self.filters.tree_type == "Item": + labels = [d.get("label") for d in self.columns[3:length - 1]] else: labels = [d.get("label") for d in self.columns[1:length-1]] self.chart = { From 675e2670b29bf9f567fef49da3bc53e389fb8449 Mon Sep 17 00:00:00 2001 From: Deepesh Garg <42651287+deepeshgarg007@users.noreply.github.com> Date: Mon, 14 Oct 2019 15:50:19 +0530 Subject: [PATCH 05/12] fix: Show Create Loan button only if loan is not created (#19291) --- erpnext/hr/doctype/loan/loan.py | 8 +++++ .../loan_application/loan_application.js | 33 +++++++++++-------- 2 files changed, 27 insertions(+), 14 deletions(-) diff --git a/erpnext/hr/doctype/loan/loan.py b/erpnext/hr/doctype/loan/loan.py index a803863124d..6cf0c2fc7f8 100644 --- a/erpnext/hr/doctype/loan/loan.py +++ b/erpnext/hr/doctype/loan/loan.py @@ -13,6 +13,7 @@ class Loan(AccountsController): def validate(self): validate_repayment_method(self.repayment_method, self.loan_amount, self.monthly_repayment_amount, self.repayment_periods) self.set_missing_fields() + self.validate_loan_application() self.make_repayment_schedule() self.set_repayment_period() self.calculate_totals() @@ -33,6 +34,13 @@ class Loan(AccountsController): if self.status == "Repaid/Closed": self.total_amount_paid = self.total_payment + def validate_loan_application(self): + if self.loan_application: + loan = frappe.db.get_value("Loan", {"loan_application": self.loan_application}, "name") + + if loan and loan != self.name: + frappe.throw(_("Loan {0} already created for Loan Application {1}").format(frappe.bold(loan), + frappe.bold(self.loan_application))) def make_jv_entry(self): self.check_permission('write') diff --git a/erpnext/hr/doctype/loan_application/loan_application.js b/erpnext/hr/doctype/loan_application/loan_application.js index a73b62a894e..e1cc4af6421 100644 --- a/erpnext/hr/doctype/loan_application/loan_application.js +++ b/erpnext/hr/doctype/loan_application/loan_application.js @@ -23,20 +23,25 @@ frappe.ui.form.on('Loan Application', { }, add_toolbar_buttons: function(frm) { if (frm.doc.status == "Approved") { - frm.add_custom_button(__('Create Loan'), function() { - frappe.call({ - method: "erpnext.hr.doctype.loan_application.loan_application.make_loan", - args: { - "source_name": frm.doc.name - }, - callback: function(r) { - if(!r.exc) { - var doc = frappe.model.sync(r.message); - frappe.set_route("Form", r.message.doctype, r.message.name); - } - } - }); - }).addClass("btn-primary"); + // show create loan button if loan not created against loan aplication + frappe.db.get_value("Loan", {"loan_application": frm.doc.name}, "name", (r) => { + if (!r) { + frm.add_custom_button(__('Create Loan'), function() { + frappe.call({ + method: "erpnext.hr.doctype.loan_application.loan_application.make_loan", + args: { + "source_name": frm.doc.name + }, + callback: function(r) { + if(!r.exc) { + var doc = frappe.model.sync(r.message); + frappe.set_route("Form", r.message.doctype, r.message.name); + } + } + }); + }).addClass("btn-primary"); + } + }); } } }); From baecc7fd31ebf7703b93f25aec1f3c203e7b5648 Mon Sep 17 00:00:00 2001 From: Rohit Waghchaure Date: Wed, 16 Oct 2019 18:40:27 +0530 Subject: [PATCH 06/12] fix: not able to save journal entry for disbursement amount --- erpnext/hr/doctype/loan/loan.py | 1 + 1 file changed, 1 insertion(+) diff --git a/erpnext/hr/doctype/loan/loan.py b/erpnext/hr/doctype/loan/loan.py index 6cf0c2fc7f8..d83fbb7fed0 100644 --- a/erpnext/hr/doctype/loan/loan.py +++ b/erpnext/hr/doctype/loan/loan.py @@ -124,6 +124,7 @@ def update_disbursement_status(doc): """, (doc.payment_account, doc.name), as_dict=1)[0] disbursement_date = None + status = '' if not disbursement or disbursement.disbursed_amount == 0: status = "Sanctioned" elif disbursement.disbursed_amount == doc.loan_amount: From ef567eac37656cb61470ba3a8861a420a4a2d592 Mon Sep 17 00:00:00 2001 From: Deepesh Garg <42651287+deepeshgarg007@users.noreply.github.com> Date: Mon, 21 Oct 2019 13:27:34 +0530 Subject: [PATCH 07/12] fix: Item Price changes are not persistent after updating cost on submitted BOM (#19357) --- erpnext/manufacturing/doctype/bom/bom.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/manufacturing/doctype/bom/bom.js b/erpnext/manufacturing/doctype/bom/bom.js index 9248ac0fe85..b9591d6054b 100644 --- a/erpnext/manufacturing/doctype/bom/bom.js +++ b/erpnext/manufacturing/doctype/bom/bom.js @@ -117,7 +117,7 @@ frappe.ui.form.on("BOM", { args: { update_parent: true, from_child_bom:false, - save: false + save: frm.doc.docstatus === 1 ? true : false }, callback: function(r) { refresh_field("items"); From e27d1aebd58f7f0304509359a64a8ac676bddfd2 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Tue, 15 Oct 2019 14:51:16 +0530 Subject: [PATCH 08/12] fix: Positive qty in sales return print --- .../sales_invoice_return/sales_invoice_return.html | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/erpnext/accounts/print_format/sales_invoice_return/sales_invoice_return.html b/erpnext/accounts/print_format/sales_invoice_return/sales_invoice_return.html index 2c015192c4b..1d758e89355 100644 --- a/erpnext/accounts/print_format/sales_invoice_return/sales_invoice_return.html +++ b/erpnext/accounts/print_format/sales_invoice_return/sales_invoice_return.html @@ -9,7 +9,7 @@
{% if doc.get(df.fieldname) != None -%} - {{ frappe.utils.fmt_money((doc[df.fieldname])|int|abs, currency=doc.currency) }} + {{ frappe.utils.fmt_money((doc[df.fieldname])|abs, currency=doc.currency) }} {% endif %}
@@ -26,7 +26,7 @@
- {{ frappe.utils.fmt_money((charge.tax_amount)|int|abs, currency=doc.currency) }} + {{ frappe.utils.fmt_money((charge.tax_amount)|abs, currency=doc.currency) }}
{%- endif -%} @@ -65,8 +65,10 @@ {% for tdf in visible_columns %} {% if not d.flags.compact_item_print or tdf.fieldname in doc.get(df.fieldname)[0].flags.compact_item_fields %} - {% if tdf.fieldtype == 'Currency' %} -
{{ frappe.utils.fmt_money((d[tdf.fieldname])|int|abs, currency=doc.currency) }}
+ {% if tdf.fieldname == 'qty' %} +
{{ (d[tdf.fieldname])|abs }}
+ {% elif tdf.fieldtype == 'Currency' %} +
{{ frappe.utils.fmt_money((d[tdf.fieldname])|abs, currency=doc.currency) }}
{% else %}
{{ print_value(tdf, d, doc, visible_columns) }}
{% endif %} @@ -117,7 +119,7 @@ {{ render_currency(df, doc) }} {% elif df.fieldtype =='Table' %} {{ render_table(df, doc)}} - {% elif doc[df.fieldname] %} + {% elif doc[df.fieldname] and df.fieldname != 'total_qty' %} {{ render_field(df, doc) }} {% endif %} {% endfor %} From 507c435dee78ca14e641665a90818a0eea4f4843 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Mon, 21 Oct 2019 16:01:51 +0530 Subject: [PATCH 09/12] Reorder level report fix v11 (#19367) * fix: Fixed consumed qty based on Stock Ledger Entry * Update itemwise_recommended_reorder_level.py --- .../itemwise_recommended_reorder_level.py | 24 ++++++++++--------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/erpnext/stock/report/itemwise_recommended_reorder_level/itemwise_recommended_reorder_level.py b/erpnext/stock/report/itemwise_recommended_reorder_level/itemwise_recommended_reorder_level.py index 618fd152ff0..9a972104a27 100644 --- a/erpnext/stock/report/itemwise_recommended_reorder_level/itemwise_recommended_reorder_level.py +++ b/erpnext/stock/report/itemwise_recommended_reorder_level/itemwise_recommended_reorder_level.py @@ -24,7 +24,7 @@ def execute(filters=None): data = [] for item in items: - total_outgoing = consumed_item_map.get(item.name, 0) + delivered_item_map.get(item.name,0) + total_outgoing = flt(consumed_item_map.get(item.name, 0)) + flt(delivered_item_map.get(item.name,0)) avg_daily_outgoing = flt(total_outgoing / diff, float_preceision) reorder_level = (avg_daily_outgoing * flt(item.lead_time_days)) + flt(item.safety_stock) @@ -55,18 +55,20 @@ def get_item_info(filters): def get_consumed_items(condition): - cn_items = frappe.db.sql("""select se_item.item_code, - sum(se_item.transfer_qty) as 'consume_qty' - from `tabStock Entry` se, `tabStock Entry Detail` se_item - where se.name = se_item.parent and se.docstatus = 1 - and (ifnull(se_item.t_warehouse, '') = '' or se.purpose = 'Subcontract') %s - group by se_item.item_code""" % (condition), as_dict=1) + consumed_items = frappe.db.sql(""" + select item_code, abs(sum(actual_qty)) as consumed_qty + from `tabStock Ledger Entry` + where actual_qty < 0 + and voucher_type not in ('Delivery Note', 'Sales Invoice') + %s + group by item_code + """ % condition, as_dict=1) - cn_items_map = {} - for item in cn_items: - cn_items_map.setdefault(item.item_code, item.consume_qty) + consumed_items_map = {} + for item in consumed_items: + consumed_items_map.setdefault(item.item_code, item.consumed_qty) - return cn_items_map + return consumed_items_map def get_delivered_items(condition): dn_items = frappe.db.sql("""select dn_item.item_code, sum(dn_item.stock_qty) as dn_qty From 89570934394c63e5551fe11d4dedd841532a3d13 Mon Sep 17 00:00:00 2001 From: Saurabh Date: Mon, 21 Oct 2019 16:02:47 +0530 Subject: [PATCH 10/12] fix: Don't show make jv button if equity or liability account and asset account not specified (#19349) --- erpnext/accounts/doctype/share_transfer/share_transfer.js | 3 ++- erpnext/accounts/doctype/share_transfer/share_transfer.py | 3 +++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/erpnext/accounts/doctype/share_transfer/share_transfer.js b/erpnext/accounts/doctype/share_transfer/share_transfer.js index af23b2656de..7ef47de9dfc 100644 --- a/erpnext/accounts/doctype/share_transfer/share_transfer.js +++ b/erpnext/accounts/doctype/share_transfer/share_transfer.js @@ -16,7 +16,7 @@ frappe.ui.form.on('Share Transfer', { }; }; }); - if (frm.doc.docstatus == 1) { + if (frm.doc.docstatus == 1 && frm.doc.equity_or_liability_account && frm.doc.asset_account ) { frm.add_custom_button(__('Make Journal Entry'), function () { erpnext.share_transfer.make_jv(frm); }); @@ -92,6 +92,7 @@ erpnext.share_transfer.make_jv = function (frm) { debit_applicant_type = "Shareholder"; debit_applicant = frm.doc.from_shareholder; } + frappe.call({ args: { "company": frm.doc.company, diff --git a/erpnext/accounts/doctype/share_transfer/share_transfer.py b/erpnext/accounts/doctype/share_transfer/share_transfer.py index 1a1f036278d..45de30c68b4 100644 --- a/erpnext/accounts/doctype/share_transfer/share_transfer.py +++ b/erpnext/accounts/doctype/share_transfer/share_transfer.py @@ -292,11 +292,14 @@ def make_jv_entry( company, account, amount, payment_account,\ "party_type": debit_applicant_type, "party": debit_applicant, }) + account_amt_list.append({ "account": payment_account, "credit_in_account_currency": amount, "party_type": credit_applicant_type, "party": credit_applicant, }) + journal_entry.set("accounts", account_amt_list) + return journal_entry.as_dict() \ No newline at end of file From 5a2ea528e8fac6c2ef3ca8e97215807eaacdfb1c Mon Sep 17 00:00:00 2001 From: Anurag Mishra <32095923+Anurag810@users.noreply.github.com> Date: Tue, 22 Oct 2019 11:46:42 +0530 Subject: [PATCH 11/12] fix: if naming if item-code and index both are same (#19372) --- erpnext/manufacturing/doctype/bom/bom.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/erpnext/manufacturing/doctype/bom/bom.py b/erpnext/manufacturing/doctype/bom/bom.py index 3ad16e5b65d..437f1694b91 100644 --- a/erpnext/manufacturing/doctype/bom/bom.py +++ b/erpnext/manufacturing/doctype/bom/bom.py @@ -34,7 +34,8 @@ class BOM(WebsiteGenerator): # name can be BOM/ITEM/001, BOM/ITEM/001-1, BOM-ITEM-001, BOM-ITEM-001-1 # split by item - names = [name.split(self.item)[-1][1:] for name in names] + names = [name.split(self.item, 1) for name in names] + names = [d[-1][1:] for d in filter(lambda x: len(x) > 1 and x[-1], names)] # split by (-) if cancelled names = [cint(name.split('-')[-1]) for name in names] From 0e7ca6ada79d0030cc032e1ffcdce6455e309597 Mon Sep 17 00:00:00 2001 From: Sahil Khan Date: Tue, 22 Oct 2019 17:23:12 +0550 Subject: [PATCH 12/12] bumped to version 11.1.67 --- erpnext/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/__init__.py b/erpnext/__init__.py index aae6c4f199f..be77f546fec 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__ = '11.1.66' +__version__ = '11.1.67' def get_default_company(user=None): '''Get default company for user'''