From 745c2658ebdd0b7898c99ecf981c9e661864a05e Mon Sep 17 00:00:00 2001 From: Zlash65 Date: Mon, 8 Jan 2018 11:53:52 +0530 Subject: [PATCH 01/10] delete root node allow --- erpnext/accounts/doctype/account/account.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/accounts/doctype/account/account.py b/erpnext/accounts/doctype/account/account.py index b0a59d00cd..448cc83dfb 100644 --- a/erpnext/accounts/doctype/account/account.py +++ b/erpnext/accounts/doctype/account/account.py @@ -163,7 +163,7 @@ class Account(NestedSet): if self.check_gle_exists(): throw(_("Account with existing transaction can not be deleted")) - super(Account, self).on_trash() + super(Account, self).on_trash(True) def before_rename(self, old, new, merge=False): # Add company abbr if not provided From 3a972c4d8569bfb57b77b1db70d85ececfa93532 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Mon, 8 Jan 2018 12:35:05 +0530 Subject: [PATCH 02/10] Precision issue in stock reconciliation --- .../stock_reconciliation/stock_reconciliation.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py b/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py index 8c6e12ea94..73a7ef3931 100644 --- a/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py +++ b/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py @@ -55,7 +55,9 @@ class StockReconciliation(StockController): item.current_qty = qty item.current_valuation_rate = rate - self.difference_amount += (flt(item.qty) * flt(item.valuation_rate or rate) - (flt(qty) * flt(rate))) + self.difference_amount += (flt(item.qty, item.precision("qty")) * \ + flt(item.valuation_rate or rate, item.precision("valuation_rate")) \ + - flt(qty) * flt(rate)) return True items = filter(lambda d: _changed(d), self.items) @@ -197,8 +199,8 @@ class StockReconciliation(StockController): "company": self.company, "stock_uom": frappe.db.get_value("Item", row.item_code, "stock_uom"), "is_cancelled": "No", - "qty_after_transaction": row.qty, - "valuation_rate": row.valuation_rate + "qty_after_transaction": flt(row.qty, row.precision("qty")), + "valuation_rate": flt(row.valuation_rate, row.precision("valuation_rate")) }) self.make_sl_entries([args]) @@ -242,7 +244,7 @@ class StockReconciliation(StockController): def set_total_qty_and_amount(self): for d in self.get("items"): - d.amount = flt(d.qty) * flt(d.valuation_rate) + d.amount = flt(d.qty, d.precision("qty")) * flt(d.valuation_rate, d.precision("valuation_rate")) d.current_amount = flt(d.current_qty) * flt(d.current_valuation_rate) d.quantity_difference = flt(d.qty) - flt(d.current_qty) d.amount_difference = flt(d.amount) - flt(d.current_amount) From 44fa9a6d9db1eca9c50085f6cd1783f5e74b8aae Mon Sep 17 00:00:00 2001 From: Shreya Shah Date: Mon, 8 Jan 2018 14:58:20 +0530 Subject: [PATCH 03/10] Last purchase rate button added back (#12135) * last purchase rate button added * triggers to update rate on button * updated modified column in buying settings * moved trigger to get_item_details.py * hide get_last_rate button depending on buying settings --- .../buying_settings/buying_settings.json | 2 +- .../doctype/purchase_order/purchase_order.js | 15 +-- .../purchase_order/purchase_order.json | 107 +++++++++++------- .../doctype/purchase_order/purchase_order.py | 52 +++++---- erpnext/stock/get_item_details.py | 5 + 5 files changed, 113 insertions(+), 68 deletions(-) diff --git a/erpnext/buying/doctype/buying_settings/buying_settings.json b/erpnext/buying/doctype/buying_settings/buying_settings.json index 25e9c15376..bb2b47def7 100644 --- a/erpnext/buying/doctype/buying_settings/buying_settings.json +++ b/erpnext/buying/doctype/buying_settings/buying_settings.json @@ -225,7 +225,7 @@ "is_submittable": 0, "issingle": 1, "istable": 0, - "modified": "2015-08-25 04:55:06.052342", + "modified": "2017-12-27 15:20:06.052342", "modified_by": "Administrator", "module": "Buying", "name": "Buying Settings", diff --git a/erpnext/buying/doctype/purchase_order/purchase_order.js b/erpnext/buying/doctype/purchase_order/purchase_order.js index 0394f74b71..fe8642c311 100644 --- a/erpnext/buying/doctype/purchase_order/purchase_order.js +++ b/erpnext/buying/doctype/purchase_order/purchase_order.js @@ -21,22 +21,17 @@ 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); + }); + frm.set_indicator_formatter('item_code', function(doc) { return (doc.qty<=doc.received_qty) ? "green" : "orange" }) }, }); frappe.ui.form.on("Purchase Order Item", { - item_code: function(frm) { - frappe.call({ - method: "get_last_purchase_rate", - doc: frm.doc, - callback: function(r, rt) { - frm.trigger('calculate_taxes_and_totals'); - } - }) - }, - schedule_date: function(frm, cdt, cdn) { var row = locals[cdt][cdn]; if (row.schedule_date) { diff --git a/erpnext/buying/doctype/purchase_order/purchase_order.json b/erpnext/buying/doctype/purchase_order/purchase_order.json index 2191a556c4..a895a54a79 100644 --- a/erpnext/buying/doctype/purchase_order/purchase_order.json +++ b/erpnext/buying/doctype/purchase_order/purchase_order.json @@ -41,11 +41,11 @@ "search_index": 0, "set_only_once": 0, "unique": 0 - }, + }, { - "allow_bulk_edit": 0, - "allow_on_submit": 1, - "bold": 0, + "allow_bulk_edit": 0, + "allow_on_submit": 1, + "bold": 0, "collapsible": 0, "columns": 0, "default": "{supplier_name}", @@ -292,40 +292,40 @@ "search_index": 1, "set_only_once": 0, "unique": 0 - }, + }, { - "allow_bulk_edit": 0, - "allow_on_submit": 1, - "bold": 0, - "collapsible": 0, - "columns": 0, - "default": "", - "fieldname": "schedule_date", - "fieldtype": "Date", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Reqd By Date", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, + "allow_bulk_edit": 0, + "allow_on_submit": 1, + "bold": 0, + "collapsible": 0, + "columns": 0, + "default": "", + "fieldname": "schedule_date", + "fieldtype": "Date", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "label": "Reqd By Date", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, "unique": 0 - }, + }, { - "allow_bulk_edit": 0, + "allow_bulk_edit": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -1238,6 +1238,37 @@ "set_only_once": 0, "unique": 0 }, + { + "allow_bulk_edit": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "depends_on": "eval:doc.docstatus===0 && (doc.items && doc.items.length)", + "fieldname": "get_last_purchase_rate", + "fieldtype": "Button", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "label": "Get last purchase rate", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, { "allow_bulk_edit": 0, "allow_on_submit": 0, @@ -3260,9 +3291,9 @@ "is_submittable": 1, "issingle": 0, "istable": 0, - "max_attachments": 0, - "modified": "2017-12-19 14:53:03.986840", - "modified_by": "nabinhait@gmail.com", + "max_attachments": 0, + "modified": "2017-12-21 14:45:34.140128", + "modified_by": "Administrator", "module": "Buying", "name": "Purchase Order", "owner": "Administrator", diff --git a/erpnext/buying/doctype/purchase_order/purchase_order.py b/erpnext/buying/doctype/purchase_order/purchase_order.py index df65ef9297..1929476cf3 100644 --- a/erpnext/buying/doctype/purchase_order/purchase_order.py +++ b/erpnext/buying/doctype/purchase_order/purchase_order.py @@ -111,27 +111,26 @@ class PurchaseOrder(BuyingController): def get_last_purchase_rate(self): """get last purchase rates for all items""" + if cint(frappe.db.get_single_value("Buying Settings", "disable_fetch_last_purchase_rate")): return - if not cint(frappe.db.get_single_value("Buying Settings", "disable_fetch_last_purchase_rate")): - conversion_rate = flt(self.get('conversion_rate')) or 1.0 + conversion_rate = flt(self.get('conversion_rate')) or 1.0 + for d in self.get("items"): + if d.item_code: + last_purchase_details = get_last_purchase_details(d.item_code, self.name) + if last_purchase_details: + d.base_price_list_rate = (last_purchase_details['base_price_list_rate'] * + (flt(d.conversion_factor) or 1.0)) + d.discount_percentage = last_purchase_details['discount_percentage'] + d.base_rate = last_purchase_details['base_rate'] * (flt(d.conversion_factor) or 1.0) + d.price_list_rate = d.base_price_list_rate / conversion_rate + d.rate = d.base_rate / conversion_rate + d.last_purchase_rate = d.rate + else: - for d in self.get("items"): - if d.item_code: - last_purchase_details = get_last_purchase_details(d.item_code, self.name) - - if last_purchase_details: - d.base_price_list_rate = (last_purchase_details['base_price_list_rate'] * - (flt(d.conversion_factor) or 1.0)) - d.discount_percentage = last_purchase_details['discount_percentage'] - d.base_rate = last_purchase_details['base_rate'] * (flt(d.conversion_factor) or 1.0) - d.price_list_rate = d.base_price_list_rate / conversion_rate - d.last_purchase_rate = d.base_rate / conversion_rate - else: - - item_last_purchase_rate = frappe.db.get_value("Item", d.item_code, "last_purchase_rate") - if item_last_purchase_rate: - d.base_price_list_rate = d.base_rate = d.price_list_rate \ - = d.last_purchase_rate = item_last_purchase_rate + item_last_purchase_rate = frappe.db.get_value("Item", d.item_code, "last_purchase_rate") + if item_last_purchase_rate: + d.base_price_list_rate = d.base_rate = d.price_list_rate \ + = d.rate = d.last_purchase_rate = item_last_purchase_rate # Check for Closed status def check_for_closed_status(self): @@ -256,6 +255,21 @@ class PurchaseOrder(BuyingController): if item.delivered_by_supplier == 1: item.received_qty = item.qty +def item_last_purchase_rate(name, conversion_rate, item_code, conversion_factor= 1.0): + """get last purchase rate for an item""" + if cint(frappe.db.get_single_value("Buying Settings", "disable_fetch_last_purchase_rate")): return + + conversion_rate = flt(conversion_rate) or 1.0 + + last_purchase_details = get_last_purchase_details(item_code, name) + if last_purchase_details: + last_purchase_rate = (last_purchase_details['base_rate'] * (flt(conversion_factor) or 1.0)) / conversion_rate + return last_purchase_rate + else: + item_last_purchase_rate = frappe.db.get_value("Item", item_code, "last_purchase_rate") + if item_last_purchase_rate: + return item_last_purchase_rate + @frappe.whitelist() def close_or_unclose_purchase_orders(names, status): if not frappe.has_permission("Purchase Order", "write"): diff --git a/erpnext/stock/get_item_details.py b/erpnext/stock/get_item_details.py index 0c9d0c74bd..a7638b4169 100644 --- a/erpnext/stock/get_item_details.py +++ b/erpnext/stock/get_item_details.py @@ -246,6 +246,7 @@ def get_basic_details(args, item): "is_fixed_asset": item.is_fixed_asset, "weight_per_unit":item.weight_per_unit, "weight_uom":item.weight_uom, + "last_purchase_rate": item.last_purchase_rate if args.get("doctype") in ["Purchase Order"] else 0 }) # calculate conversion factor @@ -258,6 +259,10 @@ def get_basic_details(args, item): args.conversion_factor = out.conversion_factor out.stock_qty = out.qty * out.conversion_factor + # calculate last purchase rate + from erpnext.buying.doctype.purchase_order.purchase_order import item_last_purchase_rate + out.last_purchase_rate = item_last_purchase_rate(args.name, args.conversion_rate, item.item_code, out.conversion_factor) + # if default specified in item is for another company, fetch from company for d in [ ["Account", "income_account", "default_income_account"], From bf4c114c58f71ef5276e1da0fc6684bc249b320b Mon Sep 17 00:00:00 2001 From: rohitwaghchaure Date: Mon, 8 Jan 2018 15:20:15 +0530 Subject: [PATCH 04/10] [Enhance] Provision to show inclusive tax in print (#12345) * [Enhance] Provision to show inclusive tax in print * POS Print format --- .../accounts_settings/accounts_settings.json | 91 ++++++++++++++++++- .../gst_pos_invoice/gst_pos_invoice.json | 4 +- .../print_format/pos_invoice/pos_invoice.json | 10 +- erpnext/controllers/accounts_controller.py | 11 +++ erpnext/controllers/buying_controller.py | 3 + erpnext/controllers/selling_controller.py | 3 + .../print_formats/includes/taxes.html | 2 +- .../print_formats/includes/total.html | 15 +++ 8 files changed, 133 insertions(+), 6 deletions(-) create mode 100644 erpnext/templates/print_formats/includes/total.html diff --git a/erpnext/accounts/doctype/accounts_settings/accounts_settings.json b/erpnext/accounts/doctype/accounts_settings/accounts_settings.json index f80bd74943..30b1eed2f5 100644 --- a/erpnext/accounts/doctype/accounts_settings/accounts_settings.json +++ b/erpnext/accounts/doctype/accounts_settings/accounts_settings.json @@ -287,6 +287,95 @@ "set_only_once": 0, "unique": 0 }, + { + "allow_bulk_edit": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "print_settings", + "fieldtype": "Section Break", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "label": "Print Settings", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_bulk_edit": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "show_inclusive_tax_in_print", + "fieldtype": "Check", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "label": "Show Inclusive Tax In Print", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_bulk_edit": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "column_break_12", + "fieldtype": "Column Break", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, { "allow_bulk_edit": 0, "allow_on_submit": 0, @@ -422,7 +511,7 @@ "issingle": 1, "istable": 0, "max_attachments": 0, - "modified": "2017-12-25 13:28:05.067615", + "modified": "2018-01-05 15:26:10.357085", "modified_by": "Administrator", "module": "Accounts", "name": "Accounts Settings", diff --git a/erpnext/accounts/print_format/gst_pos_invoice/gst_pos_invoice.json b/erpnext/accounts/print_format/gst_pos_invoice/gst_pos_invoice.json index 009ed4da0a..6aec7e3f23 100644 --- a/erpnext/accounts/print_format/gst_pos_invoice/gst_pos_invoice.json +++ b/erpnext/accounts/print_format/gst_pos_invoice/gst_pos_invoice.json @@ -7,10 +7,10 @@ "docstatus": 0, "doctype": "Print Format", "font": "Default", - "html": "\n\n

\n\t{{ doc.company }}
\n\t{% if doc.company_address_display %}\n\t\t{% set company_address = doc.company_address_display.replace(\"\\n\", \" \").replace(\"
\", \" \") %}\n\t\t{% if \"GSTIN\" not in company_address %}\n\t\t\t{{ company_address }}\n\t\t\t{{ _(\"GSTIN\") }}:{{ doc.company_gstin }}\n\t\t{% else %}\n\t\t\t{{ company_address.replace(\"GSTIN\", \"
GSTIN\") }}\n\t\t{% endif %}\n\t{% endif %}\n\t
\n\t{{ doc.select_print_heading or _(\"Invoice\") }}
\n

\n

\n\t{{ _(\"Receipt No\") }}: {{ doc.name }}
\n\t{{ _(\"Date\") }}: {{ doc.get_formatted(\"posting_date\") }}
\n\t{% if doc.grand_total > 50000 %}\n\t\t{% set customer_address = doc.address_display.replace(\"\\n\", \" \").replace(\"
\", \" \") %}\n\t\t{{ _(\"Customer\") }}:
\n\t\t{{ doc.customer_name }}
\n\t\t{{ customer_address }}\n\t{% endif %}\n

\n\n
\n\n\t\n\t\t\n\t\t\t\n\t\t\t\n\t\t\t\n\t\t\n\t\n\t\n\t\t{%- for item in doc.items -%}\n\t\t\n\t\t\t\n\t\t\t\n\t\t\t\n\t\t\n\t\t{%- endfor -%}\n\t\n
{{ _(\"Item\") }}{{ _(\"Qty\") }}{{ _(\"Amount\") }}
\n\t\t\t\t{{ item.item_code }}\n\t\t\t\t{%- if item.item_name != item.item_code -%}\n\t\t\t\t\t
{{ item.item_name }}\n\t\t\t\t{%- endif -%}\n\t\t\t\t{%- if item.gst_hsn_code -%}\n\t\t\t\t\t
{{ _(\"HSN/SAC\") }}: {{ item.gst_hsn_code }}\n\t\t\t\t{%- endif -%}\n\t\t\t\t{%- if item.serial_no -%}\n\t\t\t\t\t
{{ _(\"Serial No\") }}: {{ item.serial_no }}\n\t\t\t\t{%- endif -%}\n\t\t\t
{{ item.qty }}
@ {{ item.rate }}
{{ item.get_formatted(\"amount\") }}
\n\n\t\n\t\t\n\t\t\t\n\t\t\t\n\t\t\n\t\t{%- for row in doc.taxes -%}\n\t\t{%- if not row.included_in_print_rate -%}\n\t\t\n\t\t\t\n\t\t\t\n\t\t\n\t\t{%- endif -%}\n\t\t{%- endfor -%}\n\t\t{%- if doc.discount_amount -%}\n\t\t\n\t\t\t\n\t\t\t\n\t\t\n\t\t{%- endif -%}\n\t\t\n\t\t\t\n\t\t\t\n\t\t\n\t\n
\n\t\t\t\t{{ _(\"Net Total\") }}\n\t\t\t\n\t\t\t\t{{ doc.get_formatted(\"net_total\") }}\n\t\t\t
\n\t\t\t\t{{ row.description }}\n\t\t\t\n\t\t\t\t{{ row.get_formatted(\"tax_amount\", doc) }}\n\t\t\t
\n\t\t\t\t{{ _(\"Discount\") }}\n\t\t\t\n\t\t\t\t{{ doc.get_formatted(\"discount_amount\") }}\n\t\t\t
\n\t\t\t\t{{ _(\"Grand Total\") }}\n\t\t\t\n\t\t\t\t{{ doc.get_formatted(\"grand_total\") }}\n\t\t\t
\n

Tax Breakup:

\n
\n\t{{ doc.other_charges_calculation }}\n
\n

{{ doc.terms or \"\" }}

\n

{{ _(\"Thank you, please visit again.\") }}

", + "html": "\n\n

\n\t{{ doc.company }}
\n\t{% if doc.company_address_display %}\n\t\t{% set company_address = doc.company_address_display.replace(\"\\n\", \" \").replace(\"
\", \" \") %}\n\t\t{% if \"GSTIN\" not in company_address %}\n\t\t\t{{ company_address }}\n\t\t\t{{ _(\"GSTIN\") }}:{{ doc.company_gstin }}\n\t\t{% else %}\n\t\t\t{{ company_address.replace(\"GSTIN\", \"
GSTIN\") }}\n\t\t{% endif %}\n\t{% endif %}\n\t
\n\t{{ doc.select_print_heading or _(\"Invoice\") }}
\n

\n

\n\t{{ _(\"Receipt No\") }}: {{ doc.name }}
\n\t{{ _(\"Date\") }}: {{ doc.get_formatted(\"posting_date\") }}
\n\t{% if doc.grand_total > 50000 %}\n\t\t{% set customer_address = doc.address_display.replace(\"\\n\", \" \").replace(\"
\", \" \") %}\n\t\t{{ _(\"Customer\") }}:
\n\t\t{{ doc.customer_name }}
\n\t\t{{ customer_address }}\n\t{% endif %}\n

\n\n
\n\n\t\n\t\t\n\t\t\t\n\t\t\t\n\t\t\t\n\t\t\n\t\n\t\n\t\t{%- for item in doc.items -%}\n\t\t\n\t\t\t\n\t\t\t\n\t\t\t\n\t\t\n\t\t{%- endfor -%}\n\t\n
{{ _(\"Item\") }}{{ _(\"Qty\") }}{{ _(\"Amount\") }}
\n\t\t\t\t{{ item.item_code }}\n\t\t\t\t{%- if item.item_name != item.item_code -%}\n\t\t\t\t\t
{{ item.item_name }}\n\t\t\t\t{%- endif -%}\n\t\t\t\t{%- if item.gst_hsn_code -%}\n\t\t\t\t\t
{{ _(\"HSN/SAC\") }}: {{ item.gst_hsn_code }}\n\t\t\t\t{%- endif -%}\n\t\t\t\t{%- if item.serial_no -%}\n\t\t\t\t\t
{{ _(\"Serial No\") }}: {{ item.serial_no }}\n\t\t\t\t{%- endif -%}\n\t\t\t
{{ item.qty }}
@ {{ item.rate }}
{{ item.get_formatted(\"amount\") }}
\n\n\t\n\t\t\n\t\t\t{% if doc.flags.show_inclusive_tax_in_print %}\n\t\t\t\t\n\t\t\t\t\n\t\t\t{% else %}\n\t\t\t\t\n\t\t\t\t\n\t\t\t{% endif %}\n\t\t\n\t\t{%- for row in doc.taxes -%}\n\t\t {%- if not row.included_in_print_rate or doc.flags.show_inclusive_tax_in_print -%}\n\t\t\t\n\t\t\t\t\n\t\t\t\t\n\t\t\t\n\t\t {%- endif -%}\n\t\t{%- endfor -%}\n\t\t{%- if doc.discount_amount -%}\n\t\t\n\t\t\t\n\t\t\t\n\t\t\n\t\t{%- endif -%}\n\t\t\n\t\t\t\n\t\t\t\n\t\t\n\t\n
\n\t\t\t\t\t{{ _(\"Total Excl. Tax\") }}\n\t\t\t\t\n\t\t\t\t\t{{ doc.get_formatted(\"net_total\", doc) }}\n\t\t\t\t\n\t\t\t\t\t{{ _(\"Total\") }}\n\t\t\t\t\n\t\t\t\t\t{{ doc.get_formatted(\"total\", doc) }}\n\t\t\t\t
\n\t\t\t\t\t{{ row.description }}\n\t\t\t\t\n\t\t\t\t\t{{ row.get_formatted(\"tax_amount\", doc) }}\n\t\t\t\t
\n\t\t\t\t{{ _(\"Discount\") }}\n\t\t\t\n\t\t\t\t{{ doc.get_formatted(\"discount_amount\") }}\n\t\t\t
\n\t\t\t\t{{ _(\"Grand Total\") }}\n\t\t\t\n\t\t\t\t{{ doc.get_formatted(\"grand_total\") }}\n\t\t\t
\n

Tax Breakup:

\n
\n\t{{ doc.other_charges_calculation }}\n
\n

{{ doc.terms or \"\" }}

\n

{{ _(\"Thank you, please visit again.\") }}

", "idx": 0, "line_breaks": 0, - "modified": "2017-12-15 11:57:11.712191", + "modified": "2018-01-05 17:25:59.181985", "modified_by": "Administrator", "module": "Accounts", "name": "GST POS Invoice", diff --git a/erpnext/accounts/print_format/pos_invoice/pos_invoice.json b/erpnext/accounts/print_format/pos_invoice/pos_invoice.json index 3ee0d057a8..112f0646a5 100644 --- a/erpnext/accounts/print_format/pos_invoice/pos_invoice.json +++ b/erpnext/accounts/print_format/pos_invoice/pos_invoice.json @@ -1,15 +1,21 @@ { + "align_labels_right": 0, "creation": "2011-12-21 11:08:55", "custom_format": 1, + "disabled": 0, "doc_type": "Sales Invoice", "docstatus": 0, "doctype": "Print Format", - "html": "\n\n

\n\t{{ doc.company }}
\n\t{{ doc.select_print_heading or _(\"Invoice\") }}
\n

\n

\n\t{{ _(\"Receipt No\") }}: {{ doc.name }}
\n\t{{ _(\"Date\") }}: {{ doc.get_formatted(\"posting_date\") }}
\n\t{{ _(\"Customer\") }}: {{ doc.customer_name }}\n

\n\n
\n\n\t\n\t\t\n\t\t\t\n\t\t\t\n\t\t\t\n\t\t\n\t\n\t\n\t\t{%- for item in doc.items -%}\n\t\t\n\t\t\t\n\t\t\t\n\t\t\t\n\t\t\n\t\t{%- endfor -%}\n\t\n
{{ _(\"Item\") }}{{ _(\"Qty\") }}{{ _(\"Amount\") }}
\n\t\t\t\t{{ item.item_code }}\n\t\t\t\t{%- if item.item_name != item.item_code -%}\n\t\t\t\t\t
{{ item.item_name }}{%- endif -%}\n\t\t\t
{{ item.qty }}
@ {{ item.get_formatted(\"rate\") }}
{{ item.get_formatted(\"amount\") }}
\n\n\t\n\t\t\n\t\t\t\n\t\t\t\n\t\t\n\t\t{%- for row in doc.taxes -%}\n\t\t{%- if not row.included_in_print_rate -%}\n\t\t\n\t\t\t\n\t\t\t\n\t\t\n\t\t{%- endif -%}\n\t\t{%- endfor -%}\n\t\t{%- if doc.discount_amount -%}\n\t\t\n\t\t\t\n\t\t\t\n\t\t\n\t\t{%- endif -%}\n\t\t\n\t\t\t\n\t\t\t\n\t\t\n\t\n
\n\t\t\t\t{{ _(\"Net Total\") }}\n\t\t\t\n\t\t\t\t{{ doc.get_formatted(\"net_total\") }}\n\t\t\t
\n\t\t\t\t{{ row.description }}\n\t\t\t\n\t\t\t\t{{ row.get_formatted(\"tax_amount\", doc) }}\n\t\t\t
\n\t\t\t\t{{ _(\"Discount\") }}\n\t\t\t\n\t\t\t\t{{ doc.get_formatted(\"discount_amount\") }}\n\t\t\t
\n\t\t\t\t{{ _(\"Grand Total\") }}\n\t\t\t\n\t\t\t\t{{ doc.get_formatted(\"grand_total\") }}\n\t\t\t
\n{% if doc.get(\"taxes\", filters={\"included_in_print_rate\": 1}) %}\n
\n

Taxes Included:

\n\n\t\n\t\t{%- for row in doc.taxes -%}\n\t\t{%- if row.included_in_print_rate -%}\n\t\t\n\t\t\t\n\t\t\t\n\t\t\n\t\t{%- endif -%}\n\t\t{%- endfor -%}\n\t\n
\n\t\t\t\t{{ row.description }}\n\t\t\t\n\t\t\t\t{{ row.get_formatted(\"tax_amount_after_discount_amount\", doc) }}\n\t\t\t
\n{%- endif -%}\n
\n

{{ doc.terms or \"\" }}

\n

{{ _(\"Thank you, please visit again.\") }}

", + "html": "\n\n

\n\t{{ doc.company }}
\n\t{{ doc.select_print_heading or _(\"Invoice\") }}
\n

\n

\n\t{{ _(\"Receipt No\") }}: {{ doc.name }}
\n\t{{ _(\"Date\") }}: {{ doc.get_formatted(\"posting_date\") }}
\n\t{{ _(\"Customer\") }}: {{ doc.customer_name }}\n

\n\n
\n\n\t\n\t\t\n\t\t\t\n\t\t\t\n\t\t\t\n\t\t\n\t\n\t\n\t\t{%- for item in doc.items -%}\n\t\t\n\t\t\t\n\t\t\t\n\t\t\t\n\t\t\n\t\t{%- endfor -%}\n\t\n
{{ _(\"Item\") }}{{ _(\"Qty\") }}{{ _(\"Amount\") }}
\n\t\t\t\t{{ item.item_code }}\n\t\t\t\t{%- if item.item_name != item.item_code -%}\n\t\t\t\t\t
{{ item.item_name }}{%- endif -%}\n\t\t\t
{{ item.qty }}
@ {{ item.get_formatted(\"rate\") }}
{{ item.get_formatted(\"amount\") }}
\n\n\t\n\t\t\n\t\t\t{% if doc.flags.show_inclusive_tax_in_print %}\n\t\t\t\t\n\t\t\t\t\n\t\t\t{% else %}\n\t\t\t\t\n\t\t\t\t\n\t\t\t{% endif %}\n\t\t\n\t\t{%- for row in doc.taxes -%}\n\t\t {%- if not row.included_in_print_rate or doc.flags.show_inclusive_tax_in_print -%}\n\t\t\t\n\t\t\t\t\n\t\t\t\t\n\t\t\t\n\t\t {%- endif -%}\n\t\t{%- endfor -%}\n\n\t\t{%- if doc.discount_amount -%}\n\t\t\n\t\t\t\n\t\t\t\n\t\t\n\t\t{%- endif -%}\n\t\t\n\t\t\t\n\t\t\t\n\t\t\n\t\n
\n\t\t\t\t\t{{ _(\"Total Excl. Tax\") }}\n\t\t\t\t\n\t\t\t\t\t{{ doc.get_formatted(\"net_total\", doc) }}\n\t\t\t\t\n\t\t\t\t\t{{ _(\"Total\") }}\n\t\t\t\t\n\t\t\t\t\t{{ doc.get_formatted(\"total\", doc) }}\n\t\t\t\t
\n\t\t\t\t\t{{ row.description }}\n\t\t\t\t\n\t\t\t\t\t{{ row.get_formatted(\"tax_amount\", doc) }}\n\t\t\t\t
\n\t\t\t\t{{ _(\"Discount\") }}\n\t\t\t\n\t\t\t\t{{ doc.get_formatted(\"discount_amount\") }}\n\t\t\t
\n\t\t\t\t{{ _(\"Grand Total\") }}\n\t\t\t\n\t\t\t\t{{ doc.get_formatted(\"grand_total\") }}\n\t\t\t
\n
\n

{{ doc.terms or \"\" }}

\n

{{ _(\"Thank you, please visit again.\") }}

", "idx": 1, - "modified": "2015-04-21 05:06:29.380856", + "line_breaks": 0, + "modified": "2018-01-05 17:23:40.403289", "modified_by": "Administrator", + "module": "Accounts", "name": "POS Invoice", "owner": "Administrator", + "print_format_builder": 0, "print_format_type": "Server", + "show_section_headings": 0, "standard": "Yes" } \ No newline at end of file diff --git a/erpnext/controllers/accounts_controller.py b/erpnext/controllers/accounts_controller.py index c55f7d65ab..e1764720a0 100644 --- a/erpnext/controllers/accounts_controller.py +++ b/erpnext/controllers/accounts_controller.py @@ -375,6 +375,17 @@ class AccountsController(TransactionBase): return res + def is_inclusive_tax(self): + is_inclusive = cint(frappe.db.get_single_value("Accounts Settings", + "show_inclusive_tax_in_print")) + + if is_inclusive: + is_inclusive = 0 + if self.get("taxes", filters={"included_in_print_rate": 1}): + is_inclusive = 1 + + return is_inclusive + def validate_advance_entries(self): order_field = "sales_order" if self.doctype == "Sales Invoice" else "purchase_order" order_list = list(set([d.get(order_field) diff --git a/erpnext/controllers/buying_controller.py b/erpnext/controllers/buying_controller.py index f00f6cca4f..9ece2ab120 100644 --- a/erpnext/controllers/buying_controller.py +++ b/erpnext/controllers/buying_controller.py @@ -18,7 +18,10 @@ class BuyingController(StockController): if hasattr(self, "taxes"): self.flags.print_taxes_with_zero_amount = cint(frappe.db.get_single_value("Print Settings", "print_taxes_with_zero_amount")) + self.flags.show_inclusive_tax_in_print = self.is_inclusive_tax() + self.print_templates = { + "total": "templates/print_formats/includes/total.html", "taxes": "templates/print_formats/includes/taxes.html" } diff --git a/erpnext/controllers/selling_controller.py b/erpnext/controllers/selling_controller.py index 0cd5a07058..2ec6b83861 100644 --- a/erpnext/controllers/selling_controller.py +++ b/erpnext/controllers/selling_controller.py @@ -16,7 +16,10 @@ class SellingController(StockController): if hasattr(self, "taxes"): self.flags.print_taxes_with_zero_amount = cint(frappe.db.get_single_value("Print Settings", "print_taxes_with_zero_amount")) + self.flags.show_inclusive_tax_in_print = self.is_inclusive_tax() + self.print_templates = { + "total": "templates/print_formats/includes/total.html", "taxes": "templates/print_formats/includes/taxes.html" } diff --git a/erpnext/templates/print_formats/includes/taxes.html b/erpnext/templates/print_formats/includes/taxes.html index 41f216e7b4..db17c6597c 100644 --- a/erpnext/templates/print_formats/includes/taxes.html +++ b/erpnext/templates/print_formats/includes/taxes.html @@ -17,7 +17,7 @@ {{ render_discount_amount(doc) }} {%- endif -%} {%- for charge in data -%} - {%- if (charge.tax_amount or doc.flags.print_taxes_with_zero_amount) and not charge.included_in_print_rate -%} + {%- if (charge.tax_amount or doc.flags.print_taxes_with_zero_amount) and (not charge.included_in_print_rate or doc.flags.show_inclusive_tax_in_print) -%}
diff --git a/erpnext/templates/print_formats/includes/total.html b/erpnext/templates/print_formats/includes/total.html new file mode 100644 index 0000000000..df3f49e024 --- /dev/null +++ b/erpnext/templates/print_formats/includes/total.html @@ -0,0 +1,15 @@ +
+ {% if doc.flags.show_inclusive_tax_in_print %} +
+
+
+ {{ doc.get_formatted("net_total", doc) }} +
+ {% else %} +
+
+
+ {{ doc.get_formatted("total", doc) }} +
+ {% endif %} +
\ No newline at end of file From 7fcc21bc8bc2b7fef809f1a60af54fb51cb41236 Mon Sep 17 00:00:00 2001 From: rohitwaghchaure Date: Mon, 8 Jan 2018 15:22:22 +0530 Subject: [PATCH 05/10] [Fix] Cart remain same even if pos profile change (#12371) --- .../page/point_of_sale/point_of_sale.js | 22 ++++++++++++------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/erpnext/selling/page/point_of_sale/point_of_sale.js b/erpnext/selling/page/point_of_sale/point_of_sale.js index e2fc10cba7..1e121d84db 100644 --- a/erpnext/selling/page/point_of_sale/point_of_sale.js +++ b/erpnext/selling/page/point_of_sale/point_of_sale.js @@ -320,7 +320,7 @@ erpnext.pos.PointOfSale = class PointOfSale { return new Promise((resolve) => { const on_submit = ({ pos_profile, set_as_default }) => { if (pos_profile) { - this.frm.doc.pos_profile = pos_profile; + this.pos_profile = pos_profile; } if (set_as_default) { @@ -346,13 +346,19 @@ erpnext.pos.PointOfSale = class PointOfSale { } on_change_pos_profile() { - this.set_pos_profile_data() - .then(() => { - this.reset_cart(); - if (this.items) { - this.items.reset_items(); - } - }); + return frappe.run_serially([ + () => this.make_sales_invoice_frm(), + () => { + this.frm.doc.pos_profile = this.pos_profile; + this.set_pos_profile_data() + .then(() => { + this.reset_cart(); + if (this.items) { + this.items.reset_items(); + } + }); + } + ]); } get_promopt_fields() { From 8b94f1b553504174634a5527d67e9f4878608625 Mon Sep 17 00:00:00 2001 From: Prateeksha Singh Date: Mon, 8 Jan 2018 16:46:39 +0530 Subject: [PATCH 06/10] [minor][buying] fix schedule date check (#12375) --- erpnext/controllers/buying_controller.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/erpnext/controllers/buying_controller.py b/erpnext/controllers/buying_controller.py index 9ece2ab120..63e55ee9a7 100644 --- a/erpnext/controllers/buying_controller.py +++ b/erpnext/controllers/buying_controller.py @@ -433,7 +433,8 @@ class BuyingController(StockController): if not d.schedule_date: d.schedule_date = self.schedule_date - if d.schedule_date and getdate(d.schedule_date) < getdate(self.transaction_date): + if (d.schedule_date and self.transaction_date and + getdate(d.schedule_date) < getdate(self.transaction_date)): frappe.throw(_("Row #{0}: Reqd by Date cannot be before Transaction Date").format(d.idx)) else: frappe.throw(_("Please enter Reqd by Date")) From da22167741da89a7f4104cc0068452e419a524b5 Mon Sep 17 00:00:00 2001 From: tundebabzy Date: Tue, 9 Jan 2018 06:28:44 +0100 Subject: [PATCH 07/10] Purchase Invoice - Due Date reverts to first time value on save #12340 (#12382) * add handler for due_date: if due_date is changed and payment terms template or payment schedule is set, ask user to clear them. * ui test cases * cleanup --- .../purchase_invoice/test_purchase_invoice.js | 29 ++++++++++++++++++- .../sales_invoice/test_sales_invoice.js | 29 ++++++++++++++++++- erpnext/public/js/controllers/transaction.js | 28 ++++++++++++++++-- 3 files changed, 82 insertions(+), 4 deletions(-) diff --git a/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.js b/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.js index 8fac32d95e..b470051b51 100644 --- a/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.js +++ b/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.js @@ -1,7 +1,7 @@ QUnit.module('Purchase Invoice'); QUnit.test("test purchase invoice", function(assert) { - assert.expect(6); + assert.expect(9); let done = assert.async(); frappe.run_serially([ () => { @@ -39,6 +39,33 @@ QUnit.test("test purchase invoice", function(assert) { assert.ok(cur_frm.doc.payment_schedule.length > 0, "Payment Term Schedule is not empty"); }, + () => { + let date = cur_frm.doc.due_date; + frappe.tests.set_control('due_date', frappe.datetime.add_days(date, 1)); + frappe.timeout(0.5); + assert.ok(cur_dialog && cur_dialog.is_visible, 'Message is displayed to user'); + }, + () => frappe.timeout(1), + () => frappe.tests.click_button('Close'), + () => frappe.timeout(0.5), + () => frappe.tests.set_form_values(cur_frm, [{'payment_terms_schedule': ''}]), + () => { + let date = cur_frm.doc.due_date; + frappe.tests.set_control('due_date', frappe.datetime.add_days(date, 1)); + frappe.timeout(0.5); + assert.ok(cur_dialog && cur_dialog.is_visible, 'Message is displayed to user'); + }, + () => frappe.timeout(1), + () => frappe.tests.click_button('Close'), + () => frappe.timeout(0.5), + () => frappe.tests.set_form_values(cur_frm, [{'payment_schedule': []}]), + () => { + let date = cur_frm.doc.due_date; + frappe.tests.set_control('due_date', frappe.datetime.add_days(date, 1)); + frappe.timeout(0.5); + assert.ok(!cur_dialog, 'Message is not shown'); + }, + () => cur_frm.save(), () => frappe.tests.click_button('Submit'), () => frappe.tests.click_button('Yes'), () => frappe.timeout(1), diff --git a/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.js b/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.js index 0c92c3739a..1c052bd3fc 100644 --- a/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.js +++ b/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.js @@ -1,7 +1,7 @@ QUnit.module('Sales Invoice'); QUnit.test("test sales Invoice", function(assert) { - assert.expect(6); + assert.expect(9); let done = assert.async(); frappe.run_serially([ () => { @@ -38,6 +38,33 @@ QUnit.test("test sales Invoice", function(assert) { assert.ok(cur_frm.doc.payment_schedule.length > 0, "Payment Term Schedule is not empty"); }, + () => { + let date = cur_frm.doc.due_date; + frappe.tests.set_control('due_date', frappe.datetime.add_days(date, 1)); + frappe.timeout(0.5); + assert.ok(cur_dialog && cur_dialog.is_visible, 'Message is displayed to user'); + }, + () => frappe.timeout(1), + () => frappe.tests.click_button('Close'), + () => frappe.timeout(0.5), + () => frappe.tests.set_form_values(cur_frm, [{'payment_terms_schedule': ''}]), + () => { + let date = cur_frm.doc.due_date; + frappe.tests.set_control('due_date', frappe.datetime.add_days(date, 1)); + frappe.timeout(0.5); + assert.ok(cur_dialog && cur_dialog.is_visible, 'Message is displayed to user'); + }, + () => frappe.timeout(1), + () => frappe.tests.click_button('Close'), + () => frappe.timeout(0.5), + () => frappe.tests.set_form_values(cur_frm, [{'payment_schedule': []}]), + () => { + let date = cur_frm.doc.due_date; + frappe.tests.set_control('due_date', frappe.datetime.add_days(date, 1)); + frappe.timeout(0.5); + assert.ok(!cur_dialog, 'Message is not shown'); + }, + () => cur_frm.save(), () => frappe.tests.click_button('Submit'), () => frappe.tests.click_button('Yes'), () => frappe.timeout(0.3), diff --git a/erpnext/public/js/controllers/transaction.js b/erpnext/public/js/controllers/transaction.js index 503f1526ed..b7ad866982 100644 --- a/erpnext/public/js/controllers/transaction.js +++ b/erpnext/public/js/controllers/transaction.js @@ -228,7 +228,6 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({ erpnext.hide_company(); this.set_dynamic_labels(); this.setup_sms(); - }, apply_default_taxes: function() { @@ -535,6 +534,32 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({ } }, + due_date: function() { + // due_date is to be changed, payment terms template and/or payment schedule must + // be removed as due_date is automatically changed based on payment terms + if (this.frm.doc.due_date) { + if (this.frm.doc.payment_terms_template || this.frm.doc.payment_schedule.length) { + var message1 = ""; + var message2 = ""; + var final_message = "Please clear the "; + + if (this.frm.doc.payment_terms_template) { + message1 = "selected Payment Terms Template"; + final_message = final_message + message1; + } + + if (this.frm.doc.payment_schedule.length) { + message2 = "Payment Schedule Table"; + if (message1.length !== 0) message2 = " and " + message2; + final_message = final_message + message2; + } + + frappe.msgprint(final_message); + } + + } + }, + recalculate_terms: function() { const doc = this.frm.doc; @@ -542,7 +567,6 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({ this.payment_terms_template(); } else if (doc.payment_schedule) { const me = this; - doc.payment_schedule.forEach( function(term) { if (term.payment_term) { From 0f458b1260ee38cb90405b443177a0105eb33d3c Mon Sep 17 00:00:00 2001 From: Zarrar Date: Tue, 9 Jan 2018 11:27:14 +0530 Subject: [PATCH 08/10] show balance if permitted to view gl entry (#12385) --- .../accounts/doctype/account/account_tree.js | 20 ++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/erpnext/accounts/doctype/account/account_tree.js b/erpnext/accounts/doctype/account/account_tree.js index 2f4e09b53c..9f06ada260 100644 --- a/erpnext/accounts/doctype/account/account_tree.js +++ b/erpnext/accounts/doctype/account/account_tree.js @@ -79,15 +79,17 @@ frappe.treeview_settings["Account"] = { }, onrender: function(node) { - var dr_or_cr = node.data.balance < 0 ? "Cr" : "Dr"; - if (node.data && node.data.balance!==undefined) { - $('' - + (node.data.balance_in_account_currency ? - (format_currency(Math.abs(node.data.balance_in_account_currency), - node.data.account_currency) + " / ") : "") - + format_currency(Math.abs(node.data.balance), node.data.company_currency) - + " " + dr_or_cr - + '').insertBefore(node.$ul); + if(frappe.boot.user.can_read.indexOf("GL Entry") !== -1){ + var dr_or_cr = node.data.balance < 0 ? "Cr" : "Dr"; + if (node.data && node.data.balance!==undefined) { + $('' + + (node.data.balance_in_account_currency ? + (format_currency(Math.abs(node.data.balance_in_account_currency), + node.data.account_currency) + " / ") : "") + + format_currency(Math.abs(node.data.balance), node.data.company_currency) + + " " + dr_or_cr + + '').insertBefore(node.$ul); + } } }, toolbar: [ From 412e044e8f5f0e1c6d6751ae288db53acc3d43b4 Mon Sep 17 00:00:00 2001 From: rohitwaghchaure Date: Tue, 9 Jan 2018 11:27:35 +0530 Subject: [PATCH 09/10] [Fix] Error in stock move from batch dashboard (#12377) --- erpnext/stock/doctype/stock_entry/stock_entry_utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/stock/doctype/stock_entry/stock_entry_utils.py b/erpnext/stock/doctype/stock_entry/stock_entry_utils.py index 446f718f59..29e3eb1ab8 100644 --- a/erpnext/stock/doctype/stock_entry/stock_entry_utils.py +++ b/erpnext/stock/doctype/stock_entry/stock_entry_utils.py @@ -23,7 +23,7 @@ def make_stock_entry(**args): def process_serial_numbers(serial_nos_list): serial_nos_list = [ - '\n'.join(serial_num['serial_no'] for serial_num in serial_nos_list) + '\n'.join(serial_num['serial_no'] for serial_num in serial_nos_list if serial_num.serial_no) ] uniques = list(set(serial_nos_list[0].split('\n'))) From 0b3b63a9afd9da6ad1dc3689a592a9cd6b30cf18 Mon Sep 17 00:00:00 2001 From: Saurabh Date: Tue, 9 Jan 2018 12:25:38 +0600 Subject: [PATCH 10/10] bumped to version 10.0.7 --- erpnext/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/__init__.py b/erpnext/__init__.py index 85ad4367bf..63ade1228b 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.6' +__version__ = '10.0.7' def get_default_company(user=None): '''Get default company for user'''