From 560f822dbf82ada8616d08abef635e20548a3e86 Mon Sep 17 00:00:00 2001 From: Rohit Waghchaure Date: Mon, 6 Apr 2020 15:02:43 +0530 Subject: [PATCH 01/13] fix: get serial nos based on posting date and time --- .../stock_reconciliation.py | 34 +++------------ .../stock_and_account_value_comparison.py | 2 +- erpnext/stock/utils.py | 43 +++++++++++++++++-- 3 files changed, 47 insertions(+), 32 deletions(-) diff --git a/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py b/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py index afa239466b5..0a49c26b629 100644 --- a/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py +++ b/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py @@ -488,12 +488,14 @@ def get_stock_balance_for(item_code, warehouse, ["has_serial_no", "has_batch_no"], as_dict=1) serial_nos = "" - if item_dict.get("has_serial_no"): - qty, rate, serial_nos = get_qty_rate_for_serial_nos(item_code, - warehouse, posting_date, posting_time, item_dict) + with_serial_no = True if item_dict.get("has_serial_no") else False + data = get_stock_balance(item_code, warehouse, posting_date, posting_time, + with_valuation_rate=with_valuation_rate, with_serial_no=with_serial_no) + + if with_serial_no: + qty, rate, serial_nos = data else: - qty, rate = get_stock_balance(item_code, warehouse, - posting_date, posting_time, with_valuation_rate=with_valuation_rate) + qty, rate = data if item_dict.get("has_batch_no"): qty = get_batch_qty(batch_no, warehouse) or 0 @@ -504,28 +506,6 @@ def get_stock_balance_for(item_code, warehouse, 'serial_nos': serial_nos } -def get_qty_rate_for_serial_nos(item_code, warehouse, posting_date, posting_time, item_dict): - args = { - "item_code": item_code, - "warehouse": warehouse, - "posting_date": posting_date, - "posting_time": posting_time, - } - - serial_nos_list = [serial_no.get("name") - for serial_no in get_available_serial_nos(args)] - - qty = len(serial_nos_list) - serial_nos = '\n'.join(serial_nos_list) - args.update({ - 'qty': qty, - "serial_nos": serial_nos - }) - - rate = get_incoming_rate(args, raise_error_if_no_rate=False) or 0 - - return qty, rate, serial_nos - @frappe.whitelist() def get_difference_account(purpose, company): if purpose == 'Stock Reconciliation': diff --git a/erpnext/stock/report/stock_and_account_value_comparison/stock_and_account_value_comparison.py b/erpnext/stock/report/stock_and_account_value_comparison/stock_and_account_value_comparison.py index 94ec314e8c9..1af68dd7f22 100644 --- a/erpnext/stock/report/stock_and_account_value_comparison/stock_and_account_value_comparison.py +++ b/erpnext/stock/report/stock_and_account_value_comparison/stock_and_account_value_comparison.py @@ -35,7 +35,7 @@ def get_data(report_filters): gl_data = voucher_wise_gl_data.get(key) or {} d.account_value = gl_data.get("account_value", 0) d.difference_value = (d.stock_value - d.account_value) - if abs(d.difference_value) > 1.0/10 ** currency_precision: + if abs(d.difference_value) > 0.1: data.append(d) return data diff --git a/erpnext/stock/utils.py b/erpnext/stock/utils.py index f3381c76091..7f32b8d8bb8 100644 --- a/erpnext/stock/utils.py +++ b/erpnext/stock/utils.py @@ -74,7 +74,8 @@ def get_stock_value_on(warehouse=None, posting_date=None, item_code=None): return sum(sle_map.values()) @frappe.whitelist() -def get_stock_balance(item_code, warehouse, posting_date=None, posting_time=None, with_valuation_rate=False): +def get_stock_balance(item_code, warehouse, posting_date=None, posting_time=None, + with_valuation_rate=False, with_serial_no=False): """Returns stock balance quantity at given warehouse on given posting date or current date. If `with_valuation_rate` is True, will return tuple (qty, rate)""" @@ -84,17 +85,51 @@ def get_stock_balance(item_code, warehouse, posting_date=None, posting_time=None if not posting_date: posting_date = nowdate() if not posting_time: posting_time = nowtime() - last_entry = get_previous_sle({ + args = { "item_code": item_code, "warehouse":warehouse, "posting_date": posting_date, - "posting_time": posting_time }) + "posting_time": posting_time + } + + last_entry = get_previous_sle(args) if with_valuation_rate: - return (last_entry.qty_after_transaction, last_entry.valuation_rate) if last_entry else (0.0, 0.0) + if with_serial_no: + serial_nos = last_entry.get("serial_no") + + if (serial_nos and + len(get_serial_nos_data(serial_nos)) < last_entry.qty_after_transaction): + serial_nos = get_serial_nos_data_after_transactions(args) + + return ((last_entry.qty_after_transaction, last_entry.valuation_rate, serial_nos) + if last_entry else (0.0, 0.0, 0.0)) + else: + return (last_entry.qty_after_transaction, last_entry.valuation_rate) if last_entry else (0.0, 0.0) else: return last_entry.qty_after_transaction if last_entry else 0.0 +def get_serial_nos_data_after_transactions(args): + serial_nos = [] + data = frappe.db.sql(""" SELECT serial_no, actual_qty + FROM `tabStock Ledger Entry` + WHERE + item_code = %(item_code)s and warehouse = %(warehouse)s + and timestamp(posting_date, posting_time) < timestamp(%(posting_date)s, %(posting_time)s) + order by posting_date, posting_time asc """, args, as_dict=1) + + for d in data: + if d.actual_qty > 0: + serial_nos.extend(get_serial_nos_data(d.serial_no)) + else: + serial_nos = list(set(serial_nos) - set(get_serial_nos_data(d.serial_no))) + + return '\n'.join(serial_nos) + +def get_serial_nos_data(serial_nos): + from erpnext.stock.doctype.serial_no.serial_no import get_serial_nos + return get_serial_nos(serial_nos) + @frappe.whitelist() def get_latest_stock_qty(item_code, warehouse=None): values, condition = [item_code], "" From 658ed14e40b4c3aeec11152d8c7517878fe49b59 Mon Sep 17 00:00:00 2001 From: Rohan Bansal Date: Tue, 9 Apr 2019 16:47:10 +0530 Subject: [PATCH 02/13] feat(batch): Add total quantity and dashboard to Batch --- erpnext/patches.txt | 1 + .../patches/v12_0/set_total_batch_quantity.py | 7 + erpnext/stock/doctype/batch/batch.json | 1213 ++++++++++------- erpnext/stock/doctype/batch/batch.py | 4 + .../stock/doctype/batch/batch_dashboard.py | 27 + erpnext/stock/doctype/batch/batch_list.js | 22 +- 6 files changed, 751 insertions(+), 523 deletions(-) create mode 100644 erpnext/patches/v12_0/set_total_batch_quantity.py create mode 100644 erpnext/stock/doctype/batch/batch_dashboard.py diff --git a/erpnext/patches.txt b/erpnext/patches.txt index ff93681ba74..d6b33cc1755 100644 --- a/erpnext/patches.txt +++ b/erpnext/patches.txt @@ -663,3 +663,4 @@ erpnext.patches.v12_0.move_bank_account_swift_number_to_bank erpnext.patches.v12_0.rename_bank_reconciliation_fields # 2020-01-22 erpnext.patches.v12_0.set_received_qty_in_material_request_as_per_stock_uom erpnext.patches.v12_0.recalculate_requested_qty_in_bin +erpnext.patches.v12_0.set_total_batch_quantity diff --git a/erpnext/patches/v12_0/set_total_batch_quantity.py b/erpnext/patches/v12_0/set_total_batch_quantity.py new file mode 100644 index 00000000000..b0be0361dee --- /dev/null +++ b/erpnext/patches/v12_0/set_total_batch_quantity.py @@ -0,0 +1,7 @@ +import frappe + + +def execute(): + for batch in frappe.get_all("Batch", fields=["name", "batch_id"]): + batch_qty = frappe.db.get_value("Stock Ledger Entry", {"docstatus": 1, "batch_no": batch.batch_id}, "sum(actual_qty)") + frappe.db.set_value("Batch", batch.name, "batch_qty", batch_qty, update_modified=False) diff --git a/erpnext/stock/doctype/batch/batch.json b/erpnext/stock/doctype/batch/batch.json index e6d4e9d8b1b..7736e7be263 100644 --- a/erpnext/stock/doctype/batch/batch.json +++ b/erpnext/stock/doctype/batch/batch.json @@ -1,554 +1,737 @@ { - "allow_copy": 0, - "allow_guest_to_view": 0, - "allow_import": 1, - "allow_rename": 0, - "autoname": "field:batch_id", - "beta": 0, - "creation": "2013-03-05 14:50:38", - "custom": 0, - "docstatus": 0, - "doctype": "DocType", - "document_type": "Setup", - "editable_grid": 0, - "engine": "InnoDB", + "allow_copy": 0, + "allow_events_in_timeline": 0, + "allow_guest_to_view": 0, + "allow_import": 1, + "allow_rename": 0, + "autoname": "field:batch_id", + "beta": 0, + "creation": "2013-03-05 14:50:38", + "custom": 0, + "docstatus": 0, + "doctype": "DocType", + "document_type": "Setup", + "editable_grid": 0, + "engine": "InnoDB", "fields": [ { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "depends_on": "eval:doc.__islocal", - "fieldname": "batch_id", - "fieldtype": "Data", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Batch ID", - "length": 0, - "no_copy": 1, - "oldfieldname": "batch_id", - "oldfieldtype": "Data", - "permlevel": 0, - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 1, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fetch_if_empty": 0, + "fieldname": "sb_disabled", + "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, + "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, + "translatable": 0, + "unique": 0 + }, + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fetch_if_empty": 0, + "fieldname": "disabled", + "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": "Disabled", + "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, + "translatable": 0, + "unique": 0 + }, + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fetch_if_empty": 0, + "fieldname": "sb_batch", + "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": "Batch Details", + "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, + "translatable": 0, + "unique": 0 + }, + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "depends_on": "eval:doc.__islocal", + "fetch_if_empty": 0, + "fieldname": "batch_id", + "fieldtype": "Data", + "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": "Batch ID", + "length": 0, + "no_copy": 1, + "oldfieldname": "batch_id", + "oldfieldtype": "Data", + "permlevel": 0, + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 1, + "search_index": 0, + "set_only_once": 0, + "translatable": 0, "unique": 1 - }, + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "item", - "fieldtype": "Link", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 1, - "label": "Item", - "length": 0, - "no_copy": 0, - "oldfieldname": "item", - "oldfieldtype": "Link", - "options": "Item", - "permlevel": 0, - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 1, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fetch_if_empty": 0, + "fieldname": "item", + "fieldtype": "Link", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 1, + "in_standard_filter": 1, + "label": "Item", + "length": 0, + "no_copy": 0, + "oldfieldname": "item", + "oldfieldtype": "Link", + "options": "Item", + "permlevel": 0, + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 1, + "search_index": 0, + "set_only_once": 0, + "translatable": 0, "unique": 0 - }, + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "image", - "fieldtype": "Attach Image", - "hidden": 1, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "image", - "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, - "translatable": 0, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fetch_from": "item.item_name", + "fetch_if_empty": 0, + "fieldname": "item_name", + "fieldtype": "Data", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 1, + "in_standard_filter": 0, + "label": "Item Name", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 1, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "translatable": 0, "unique": 0 - }, + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "depends_on": "eval:doc.parent_batch", - "fieldname": "parent_batch", - "fieldtype": "Link", - "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": "Parent Batch", - "length": 0, - "no_copy": 0, - "options": "Batch", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 1, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fetch_if_empty": 0, + "fieldname": "image", + "fieldtype": "Attach Image", + "hidden": 1, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "label": "image", + "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, + "translatable": 0, "unique": 0 - }, + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "column_break_3", - "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, - "translatable": 0, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "depends_on": "eval:doc.parent_batch", + "fetch_if_empty": 0, + "fieldname": "parent_batch", + "fieldtype": "Link", + "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": "Parent Batch", + "length": 0, + "no_copy": 0, + "options": "Batch", + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 1, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "translatable": 0, "unique": 0 - }, + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "disabled", - "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": "Disabled", - "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, - "translatable": 0, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "default": "Today", + "fetch_if_empty": 0, + "fieldname": "manufacturing_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": "Manufacturing 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, + "translatable": 0, "unique": 0 - }, + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "default": "Today", - "fieldname": "manufacturing_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": "Manufacturing 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, - "translatable": 0, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fetch_if_empty": 0, + "fieldname": "column_break_3", + "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, + "translatable": 0, "unique": 0 - }, + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "expiry_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": "Expiry Date", - "length": 0, - "no_copy": 0, - "oldfieldname": "expiry_date", - "oldfieldtype": "Date", - "permlevel": 0, - "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, - "translatable": 0, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fetch_if_empty": 0, + "fieldname": "batch_qty", + "fieldtype": "Float", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 1, + "in_standard_filter": 0, + "label": "Batch Quantity", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 1, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "translatable": 0, "unique": 0 - }, + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "source", - "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": "Source", - "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, - "translatable": 0, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fetch_from": "item.stock_uom", + "fetch_if_empty": 0, + "fieldname": "stock_uom", + "fieldtype": "Link", + "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": "Batch UOM", + "length": 0, + "no_copy": 0, + "options": "UOM", + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 1, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "translatable": 0, "unique": 0 - }, + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "supplier", - "fieldtype": "Link", - "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": "Supplier", - "length": 0, - "no_copy": 0, - "options": "Supplier", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 1, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fetch_if_empty": 0, + "fieldname": "expiry_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": "Expiry Date", + "length": 0, + "no_copy": 0, + "oldfieldname": "expiry_date", + "oldfieldtype": "Date", + "permlevel": 0, + "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, + "translatable": 0, "unique": 0 - }, + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "column_break_9", - "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, - "translatable": 0, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fetch_if_empty": 0, + "fieldname": "source", + "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": "Source", + "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, + "translatable": 0, "unique": 0 - }, + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "reference_doctype", - "fieldtype": "Link", - "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": "Source Document Type", - "length": 0, - "no_copy": 0, - "options": "DocType", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 1, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fetch_if_empty": 0, + "fieldname": "supplier", + "fieldtype": "Link", + "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": "Supplier", + "length": 0, + "no_copy": 0, + "options": "Supplier", + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 1, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "translatable": 0, "unique": 0 - }, + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "reference_name", - "fieldtype": "Dynamic Link", - "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": "Source Document Name", - "length": 0, - "no_copy": 0, - "options": "reference_doctype", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 1, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fetch_if_empty": 0, + "fieldname": "column_break_9", + "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, + "translatable": 0, "unique": 0 - }, + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "section_break_7", - "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, - "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, - "translatable": 0, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fetch_if_empty": 0, + "fieldname": "reference_doctype", + "fieldtype": "Link", + "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": "Source Document Type", + "length": 0, + "no_copy": 0, + "options": "DocType", + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 1, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "translatable": 0, "unique": 0 - }, + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "description", - "fieldtype": "Small Text", - "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": "Batch Description", - "length": 0, - "no_copy": 0, - "oldfieldname": "description", - "oldfieldtype": "Small Text", - "permlevel": 0, - "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, - "translatable": 0, - "unique": 0, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fetch_if_empty": 0, + "fieldname": "reference_name", + "fieldtype": "Dynamic Link", + "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": "Source Document Name", + "length": 0, + "no_copy": 0, + "options": "reference_doctype", + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 1, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "translatable": 0, + "unique": 0 + }, + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fetch_if_empty": 0, + "fieldname": "section_break_7", + "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, + "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, + "translatable": 0, + "unique": 0 + }, + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fetch_if_empty": 0, + "fieldname": "description", + "fieldtype": "Small Text", + "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": "Batch Description", + "length": 0, + "no_copy": 0, + "oldfieldname": "description", + "oldfieldtype": "Small Text", + "permlevel": 0, + "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, + "translatable": 0, + "unique": 0, "width": "300px" } - ], - "has_web_view": 0, - "hide_heading": 0, - "hide_toolbar": 0, - "icon": "fa fa-archive", - "idx": 1, - "image_field": "image", - "image_view": 0, - "in_create": 0, - "is_submittable": 0, - "issingle": 0, - "istable": 0, - "max_attachments": 5, - "modified": "2018-08-29 06:28:57.985997", - "modified_by": "Administrator", - "module": "Stock", - "name": "Batch", - "owner": "harshada@webnotestech.com", + ], + "has_web_view": 0, + "hide_heading": 0, + "hide_toolbar": 0, + "icon": "fa fa-archive", + "idx": 1, + "image_field": "image", + "image_view": 0, + "in_create": 0, + "is_submittable": 0, + "issingle": 0, + "istable": 0, + "max_attachments": 5, + "modified": "2019-04-09 04:36:56.169832", + "modified_by": "Administrator", + "module": "Stock", + "name": "Batch", + "owner": "harshada@webnotestech.com", "permissions": [ { - "amend": 0, - "cancel": 0, - "create": 1, - "delete": 1, - "email": 1, - "export": 1, - "if_owner": 0, - "import": 1, - "permlevel": 0, - "print": 1, - "read": 1, - "report": 1, - "role": "Item Manager", - "set_user_permissions": 1, - "share": 1, - "submit": 0, + "amend": 0, + "cancel": 0, + "create": 1, + "delete": 1, + "email": 1, + "export": 1, + "if_owner": 0, + "import": 1, + "permlevel": 0, + "print": 1, + "read": 1, + "report": 1, + "role": "Item Manager", + "set_user_permissions": 1, + "share": 1, + "submit": 0, "write": 1 } - ], - "quick_entry": 1, - "read_only": 0, - "read_only_onload": 0, - "show_name_in_global_search": 0, - "sort_order": "DESC", - "title_field": "item", - "track_changes": 0, - "track_seen": 0, + ], + "quick_entry": 1, + "read_only": 0, + "read_only_onload": 0, + "show_name_in_global_search": 0, + "sort_order": "DESC", + "title_field": "item", + "track_changes": 0, + "track_seen": 0, "track_views": 0 } \ No newline at end of file diff --git a/erpnext/stock/doctype/batch/batch.py b/erpnext/stock/doctype/batch/batch.py index 9b7249e66b9..3de720580a6 100644 --- a/erpnext/stock/doctype/batch/batch.py +++ b/erpnext/stock/doctype/batch/batch.py @@ -111,11 +111,15 @@ class Batch(Document): def validate(self): self.item_has_batch_enabled() + self.calculate_batch_qty() def item_has_batch_enabled(self): if frappe.db.get_value("Item", self.item, "has_batch_no") == 0: frappe.throw(_("The selected item cannot have Batch")) + def calculate_batch_qty(self): + self.batch_qty = frappe.db.get_value("Stock Ledger Entry", {"batch_no": self.batch_id}, "sum(actual_qty)") + def before_save(self): has_expiry_date, shelf_life_in_days = frappe.db.get_value('Item', self.item, ['has_expiry_date', 'shelf_life_in_days']) if not self.expiry_date and has_expiry_date and shelf_life_in_days: diff --git a/erpnext/stock/doctype/batch/batch_dashboard.py b/erpnext/stock/doctype/batch/batch_dashboard.py new file mode 100644 index 00000000000..eb6a97ecfd8 --- /dev/null +++ b/erpnext/stock/doctype/batch/batch_dashboard.py @@ -0,0 +1,27 @@ +from __future__ import unicode_literals + +from frappe import _ + + +def get_data(): + return { + 'fieldname': 'batch_no', + 'transactions': [ + { + 'label': _('Buy'), + 'items': ['Purchase Invoice', 'Purchase Receipt'] + }, + { + 'label': _('Sell'), + 'items': ['Sales Invoice', 'Delivery Note'] + }, + { + 'label': _('Move'), + 'items': ['Stock Entry'] + }, + { + 'label': _('Quality'), + 'items': ['Quality Inspection'] + } + ] + } diff --git a/erpnext/stock/doctype/batch/batch_list.js b/erpnext/stock/doctype/batch/batch_list.js index 7ee81aa7e9f..08ad9bc6733 100644 --- a/erpnext/stock/doctype/batch/batch_list.js +++ b/erpnext/stock/doctype/batch/batch_list.js @@ -1,12 +1,18 @@ frappe.listview_settings['Batch'] = { - add_fields: ["item", "expiry_date"], - get_indicator: function(doc) { - if(doc.expiry_date && frappe.datetime.get_diff(doc.expiry_date, frappe.datetime.nowdate()) <= 0) { - return [__("Expired"), "red", "expiry_date,>=,Today"] - } else if(doc.expiry_date) { - return [__("Not Expired"), "green", "expiry_date,<,Today"] + add_fields: ["item", "expiry_date", "batch_qty"], + get_indicator: function (doc) { + if (!doc.batch_qty) { + return ["Empty", "darkgrey", "batch_qty,=,0"]; } else { - return ["Not Set", "darkgrey", ""]; - } + if (doc.expiry_date) { + if (frappe.datetime.get_diff(doc.expiry_date, frappe.datetime.nowdate()) <= 0) { + return [__("Expired"), "red", "expiry_date,>=,Today|batch_qty,>,0"] + } else { + return [__("Not Expired"), "green", "expiry_date,<,Today|batch_qty,>,0"] + } + } else { + return ["Active", "green", "batch_qty,>,0"]; + }; + }; } }; From 56827a372cb4f49a0166ed9f8060e50cbbc31ebd Mon Sep 17 00:00:00 2001 From: Rohan Bansal Date: Thu, 11 Apr 2019 15:03:53 +0530 Subject: [PATCH 03/13] fix(patch): Reload Batch doctype before update query --- erpnext/patches/v12_0/set_total_batch_quantity.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/erpnext/patches/v12_0/set_total_batch_quantity.py b/erpnext/patches/v12_0/set_total_batch_quantity.py index b0be0361dee..4f649deb54e 100644 --- a/erpnext/patches/v12_0/set_total_batch_quantity.py +++ b/erpnext/patches/v12_0/set_total_batch_quantity.py @@ -2,6 +2,8 @@ import frappe def execute(): + frappe.reload_doc("stock", "doctype", "batch") + for batch in frappe.get_all("Batch", fields=["name", "batch_id"]): batch_qty = frappe.db.get_value("Stock Ledger Entry", {"docstatus": 1, "batch_no": batch.batch_id}, "sum(actual_qty)") frappe.db.set_value("Batch", batch.name, "batch_qty", batch_qty, update_modified=False) From 40611080da6f6563b99a10b2d8f3daa6a8d1fae8 Mon Sep 17 00:00:00 2001 From: Rohan Bansal Date: Thu, 11 Apr 2019 15:57:13 +0530 Subject: [PATCH 04/13] fix(patch): Fix edge cases for Batch --- erpnext/patches/v12_0/set_total_batch_quantity.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/patches/v12_0/set_total_batch_quantity.py b/erpnext/patches/v12_0/set_total_batch_quantity.py index 4f649deb54e..b02da305ac9 100644 --- a/erpnext/patches/v12_0/set_total_batch_quantity.py +++ b/erpnext/patches/v12_0/set_total_batch_quantity.py @@ -5,5 +5,5 @@ def execute(): frappe.reload_doc("stock", "doctype", "batch") for batch in frappe.get_all("Batch", fields=["name", "batch_id"]): - batch_qty = frappe.db.get_value("Stock Ledger Entry", {"docstatus": 1, "batch_no": batch.batch_id}, "sum(actual_qty)") + batch_qty = frappe.db.get_value("Stock Ledger Entry", {"docstatus": 1, "batch_no": batch.batch_id}, "sum(actual_qty)") or 0.0 frappe.db.set_value("Batch", batch.name, "batch_qty", batch_qty, update_modified=False) From 1bd7ea99f42a277268b23beda5a6faf9fee02a36 Mon Sep 17 00:00:00 2001 From: Rohan Bansal Date: Mon, 15 Apr 2019 17:03:09 +0530 Subject: [PATCH 05/13] fix(batch): Only consider valid stock ledger entries --- erpnext/stock/doctype/batch/batch.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/stock/doctype/batch/batch.py b/erpnext/stock/doctype/batch/batch.py index 3de720580a6..9c532096c6c 100644 --- a/erpnext/stock/doctype/batch/batch.py +++ b/erpnext/stock/doctype/batch/batch.py @@ -118,7 +118,7 @@ class Batch(Document): frappe.throw(_("The selected item cannot have Batch")) def calculate_batch_qty(self): - self.batch_qty = frappe.db.get_value("Stock Ledger Entry", {"batch_no": self.batch_id}, "sum(actual_qty)") + self.batch_qty = frappe.db.get_value("Stock Ledger Entry", {"docstatus": 1, "batch_no": self.batch_id}, "sum(actual_qty)") def before_save(self): has_expiry_date, shelf_life_in_days = frappe.db.get_value('Item', self.item, ['has_expiry_date', 'shelf_life_in_days']) From 4a50c99867d62380e97abcb92428753188969738 Mon Sep 17 00:00:00 2001 From: Rohan Bansal Date: Fri, 26 Apr 2019 17:10:44 +0530 Subject: [PATCH 06/13] fix(stock): Update batch quantity whenever stock in it is moved --- .../stock/doctype/stock_ledger_entry/stock_ledger_entry.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/erpnext/stock/doctype/stock_ledger_entry/stock_ledger_entry.py b/erpnext/stock/doctype/stock_ledger_entry/stock_ledger_entry.py index 5fe89d6e227..74f18797702 100644 --- a/erpnext/stock/doctype/stock_ledger_entry/stock_ledger_entry.py +++ b/erpnext/stock/doctype/stock_ledger_entry/stock_ledger_entry.py @@ -38,6 +38,11 @@ class StockLedgerEntry(Document): self.check_stock_frozen_date() self.actual_amt_check() + if self.batch_no: + batch = frappe.get_doc("Batch", self.batch_no) + batch.calculate_batch_qty() + batch.save() + if not self.get("via_landed_cost_voucher"): from erpnext.stock.doctype.serial_no.serial_no import process_serial_no process_serial_no(self) @@ -139,4 +144,3 @@ def on_doctype_update(): frappe.db.add_index("Stock Ledger Entry", ["voucher_no", "voucher_type"]) frappe.db.add_index("Stock Ledger Entry", ["batch_no", "item_code", "warehouse"]) - From 92669eae66815707299fef022132b5eb95129534 Mon Sep 17 00:00:00 2001 From: Rohan Bansal Date: Wed, 17 Jul 2019 13:03:29 +0530 Subject: [PATCH 07/13] fix(stock): batch list view statuses --- erpnext/stock/doctype/batch/batch_list.js | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/erpnext/stock/doctype/batch/batch_list.js b/erpnext/stock/doctype/batch/batch_list.js index 08ad9bc6733..05bf37f0f4a 100644 --- a/erpnext/stock/doctype/batch/batch_list.js +++ b/erpnext/stock/doctype/batch/batch_list.js @@ -1,18 +1,14 @@ frappe.listview_settings['Batch'] = { - add_fields: ["item", "expiry_date", "batch_qty"], - get_indicator: function (doc) { - if (!doc.batch_qty) { - return ["Empty", "darkgrey", "batch_qty,=,0"]; + add_fields: ["item", "expiry_date", "batch_qty", "disabled"], + get_indicator: (doc) => { + if (doc.disabled) { + return [__("Disabled"), "darkgrey", "disabled,=,1"]; + } else if (doc.expiry_date && frappe.datetime.get_diff(doc.expiry_date, frappe.datetime.nowdate()) <= 0) { + return [__("Expired"), "red", "expiry_date,not in,|expiry_date,<=,Today|batch_qty,>,0|disabled,=,0"] + } else if (!doc.batch_qty) { + return [__("Empty"), "darkgrey", "batch_qty,=,0|disabled,=,0"]; } else { - if (doc.expiry_date) { - if (frappe.datetime.get_diff(doc.expiry_date, frappe.datetime.nowdate()) <= 0) { - return [__("Expired"), "red", "expiry_date,>=,Today|batch_qty,>,0"] - } else { - return [__("Not Expired"), "green", "expiry_date,<,Today|batch_qty,>,0"] - } - } else { - return ["Active", "green", "batch_qty,>,0"]; - }; + return [__("Active"), "green", "batch_qty,>,0|disabled,=,0"]; }; } }; From ced78cf116d9f5cafa81039a3e08d6fc3b832050 Mon Sep 17 00:00:00 2001 From: Rohan Bansal Date: Wed, 17 Jul 2019 13:50:16 +0530 Subject: [PATCH 08/13] fix(stock): make requested changes --- erpnext/stock/doctype/batch/batch.json | 845 +++--------------- .../stock_ledger_entry/stock_ledger_entry.py | 14 +- 2 files changed, 142 insertions(+), 717 deletions(-) diff --git a/erpnext/stock/doctype/batch/batch.json b/erpnext/stock/doctype/batch/batch.json index 7736e7be263..ab96746fdbb 100644 --- a/erpnext/stock/doctype/batch/batch.json +++ b/erpnext/stock/doctype/batch/batch.json @@ -1,737 +1,158 @@ { - "allow_copy": 0, - "allow_events_in_timeline": 0, - "allow_guest_to_view": 0, - "allow_import": 1, - "allow_rename": 0, - "autoname": "field:batch_id", - "beta": 0, - "creation": "2013-03-05 14:50:38", - "custom": 0, - "docstatus": 0, - "doctype": "DocType", - "document_type": "Setup", - "editable_grid": 0, - "engine": "InnoDB", + "allow_import": 1, + "autoname": "field:batch_id", + "creation": "2013-03-05 14:50:38", + "doctype": "DocType", + "document_type": "Setup", + "engine": "InnoDB", + "field_order": [ + "batch_id", + "item", + "image", + "parent_batch", + "column_break_3", + "disabled", + "manufacturing_date", + "expiry_date", + "source", + "supplier", + "column_break_9", + "reference_doctype", + "reference_name", + "section_break_7", + "description" + ], "fields": [ { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fetch_if_empty": 0, - "fieldname": "sb_disabled", - "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, - "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, - "translatable": 0, - "unique": 0 - }, + "default": "0", + "fieldname": "disabled", + "fieldtype": "Check", + "label": "Disabled" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fetch_if_empty": 0, - "fieldname": "disabled", - "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": "Disabled", - "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, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fetch_if_empty": 0, - "fieldname": "sb_batch", - "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": "Batch Details", - "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, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "depends_on": "eval:doc.__islocal", - "fetch_if_empty": 0, - "fieldname": "batch_id", - "fieldtype": "Data", - "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": "Batch ID", - "length": 0, - "no_copy": 1, - "oldfieldname": "batch_id", - "oldfieldtype": "Data", - "permlevel": 0, - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 1, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, + "depends_on": "eval:doc.__islocal", + "fieldname": "batch_id", + "fieldtype": "Data", + "in_list_view": 1, + "label": "Batch ID", + "no_copy": 1, + "oldfieldname": "batch_id", + "oldfieldtype": "Data", + "reqd": 1, "unique": 1 - }, + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fetch_if_empty": 0, - "fieldname": "item", - "fieldtype": "Link", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 1, - "label": "Item", - "length": 0, - "no_copy": 0, - "oldfieldname": "item", - "oldfieldtype": "Link", - "options": "Item", - "permlevel": 0, - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 1, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, + "fieldname": "item", + "fieldtype": "Link", + "in_list_view": 1, + "in_standard_filter": 1, + "label": "Item", + "oldfieldname": "item", + "oldfieldtype": "Link", + "options": "Item", + "reqd": 1 + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fetch_from": "item.item_name", - "fetch_if_empty": 0, - "fieldname": "item_name", - "fieldtype": "Data", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Item Name", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 1, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, + "fieldname": "image", + "fieldtype": "Attach Image", + "hidden": 1, + "label": "image" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fetch_if_empty": 0, - "fieldname": "image", - "fieldtype": "Attach Image", - "hidden": 1, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "image", - "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, - "translatable": 0, - "unique": 0 - }, + "depends_on": "eval:doc.parent_batch", + "fieldname": "parent_batch", + "fieldtype": "Link", + "label": "Parent Batch", + "options": "Batch", + "read_only": 1 + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "depends_on": "eval:doc.parent_batch", - "fetch_if_empty": 0, - "fieldname": "parent_batch", - "fieldtype": "Link", - "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": "Parent Batch", - "length": 0, - "no_copy": 0, - "options": "Batch", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 1, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, + "default": "Today", + "fieldname": "manufacturing_date", + "fieldtype": "Date", + "label": "Manufacturing Date" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "default": "Today", - "fetch_if_empty": 0, - "fieldname": "manufacturing_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": "Manufacturing 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, - "translatable": 0, - "unique": 0 - }, + "fieldname": "column_break_3", + "fieldtype": "Column Break" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fetch_if_empty": 0, - "fieldname": "column_break_3", - "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, - "translatable": 0, - "unique": 0 - }, + "fieldname": "expiry_date", + "fieldtype": "Date", + "label": "Expiry Date", + "oldfieldname": "expiry_date", + "oldfieldtype": "Date" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fetch_if_empty": 0, - "fieldname": "batch_qty", - "fieldtype": "Float", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Batch Quantity", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 1, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, + "fieldname": "source", + "fieldtype": "Section Break", + "label": "Source" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fetch_from": "item.stock_uom", - "fetch_if_empty": 0, - "fieldname": "stock_uom", - "fieldtype": "Link", - "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": "Batch UOM", - "length": 0, - "no_copy": 0, - "options": "UOM", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 1, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, + "fieldname": "supplier", + "fieldtype": "Link", + "label": "Supplier", + "options": "Supplier", + "read_only": 1 + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fetch_if_empty": 0, - "fieldname": "expiry_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": "Expiry Date", - "length": 0, - "no_copy": 0, - "oldfieldname": "expiry_date", - "oldfieldtype": "Date", - "permlevel": 0, - "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, - "translatable": 0, - "unique": 0 - }, + "fieldname": "column_break_9", + "fieldtype": "Column Break" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fetch_if_empty": 0, - "fieldname": "source", - "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": "Source", - "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, - "translatable": 0, - "unique": 0 - }, + "fieldname": "reference_doctype", + "fieldtype": "Link", + "label": "Source Document Type", + "options": "DocType", + "read_only": 1 + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fetch_if_empty": 0, - "fieldname": "supplier", - "fieldtype": "Link", - "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": "Supplier", - "length": 0, - "no_copy": 0, - "options": "Supplier", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 1, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, + "fieldname": "reference_name", + "fieldtype": "Dynamic Link", + "label": "Source Document Name", + "options": "reference_doctype", + "read_only": 1 + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fetch_if_empty": 0, - "fieldname": "column_break_9", - "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, - "translatable": 0, - "unique": 0 - }, + "fieldname": "section_break_7", + "fieldtype": "Section Break" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fetch_if_empty": 0, - "fieldname": "reference_doctype", - "fieldtype": "Link", - "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": "Source Document Type", - "length": 0, - "no_copy": 0, - "options": "DocType", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 1, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fetch_if_empty": 0, - "fieldname": "reference_name", - "fieldtype": "Dynamic Link", - "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": "Source Document Name", - "length": 0, - "no_copy": 0, - "options": "reference_doctype", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 1, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fetch_if_empty": 0, - "fieldname": "section_break_7", - "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, - "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, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fetch_if_empty": 0, - "fieldname": "description", - "fieldtype": "Small Text", - "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": "Batch Description", - "length": 0, - "no_copy": 0, - "oldfieldname": "description", - "oldfieldtype": "Small Text", - "permlevel": 0, - "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, - "translatable": 0, - "unique": 0, + "fieldname": "description", + "fieldtype": "Small Text", + "label": "Batch Description", + "oldfieldname": "description", + "oldfieldtype": "Small Text", "width": "300px" } - ], - "has_web_view": 0, - "hide_heading": 0, - "hide_toolbar": 0, - "icon": "fa fa-archive", - "idx": 1, - "image_field": "image", - "image_view": 0, - "in_create": 0, - "is_submittable": 0, - "issingle": 0, - "istable": 0, - "max_attachments": 5, - "modified": "2019-04-09 04:36:56.169832", - "modified_by": "Administrator", - "module": "Stock", - "name": "Batch", - "owner": "harshada@webnotestech.com", + ], + "icon": "fa fa-archive", + "idx": 1, + "image_field": "image", + "max_attachments": 5, + "modified": "2019-07-16 23:04:47.554387", + "modified_by": "Administrator", + "module": "Stock", + "name": "Batch", + "owner": "harshada@webnotestech.com", "permissions": [ { - "amend": 0, - "cancel": 0, - "create": 1, - "delete": 1, - "email": 1, - "export": 1, - "if_owner": 0, - "import": 1, - "permlevel": 0, - "print": 1, - "read": 1, - "report": 1, - "role": "Item Manager", - "set_user_permissions": 1, - "share": 1, - "submit": 0, + "create": 1, + "delete": 1, + "email": 1, + "export": 1, + "import": 1, + "print": 1, + "read": 1, + "report": 1, + "role": "Item Manager", + "set_user_permissions": 1, + "share": 1, "write": 1 } - ], - "quick_entry": 1, - "read_only": 0, - "read_only_onload": 0, - "show_name_in_global_search": 0, - "sort_order": "DESC", - "title_field": "item", - "track_changes": 0, - "track_seen": 0, - "track_views": 0 + ], + "quick_entry": 1, + "sort_field": "modified", + "sort_order": "DESC", + "title_field": "item" } \ No newline at end of file diff --git a/erpnext/stock/doctype/stock_ledger_entry/stock_ledger_entry.py b/erpnext/stock/doctype/stock_ledger_entry/stock_ledger_entry.py index 74f18797702..19394cedb4f 100644 --- a/erpnext/stock/doctype/stock_ledger_entry/stock_ledger_entry.py +++ b/erpnext/stock/doctype/stock_ledger_entry/stock_ledger_entry.py @@ -37,16 +37,20 @@ class StockLedgerEntry(Document): def on_submit(self): self.check_stock_frozen_date() self.actual_amt_check() - - if self.batch_no: - batch = frappe.get_doc("Batch", self.batch_no) - batch.calculate_batch_qty() - batch.save() + self.calculate_batch_qty() if not self.get("via_landed_cost_voucher"): from erpnext.stock.doctype.serial_no.serial_no import process_serial_no process_serial_no(self) + def on_cancel(self): + self.calculate_batch_qty() + + def calculate_batch_qty(self): + if self.batch_no: + batch_qty = frappe.db.get_value("Stock Ledger Entry", {"docstatus": 1, "batch_no": self.batch_no}, "sum(actual_qty)") + frappe.db.set_value("Batch", self.batch_no, "batch_qty", batch_qty) + #check for item quantity available in stock def actual_amt_check(self): if self.batch_no and not self.get("allow_negative_stock"): From ba03853b2aad8f0f82142cb068898ffee5dd1bc5 Mon Sep 17 00:00:00 2001 From: Rohan Bansal Date: Thu, 1 Aug 2019 18:05:03 +0530 Subject: [PATCH 09/13] fix: update Batch schema --- erpnext/stock/doctype/batch/batch.json | 44 +++++++++++++++++++++++--- 1 file changed, 40 insertions(+), 4 deletions(-) diff --git a/erpnext/stock/doctype/batch/batch.json b/erpnext/stock/doctype/batch/batch.json index ab96746fdbb..47b0a8dec4d 100644 --- a/erpnext/stock/doctype/batch/batch.json +++ b/erpnext/stock/doctype/batch/batch.json @@ -6,13 +6,18 @@ "document_type": "Setup", "engine": "InnoDB", "field_order": [ + "sb_disabled", + "disabled", + "sb_batch", "batch_id", "item", + "item_name", "image", "parent_batch", - "column_break_3", - "disabled", "manufacturing_date", + "column_break_3", + "batch_qty", + "stock_uom", "expiry_date", "source", "supplier", @@ -33,7 +38,6 @@ "depends_on": "eval:doc.__islocal", "fieldname": "batch_id", "fieldtype": "Data", - "in_list_view": 1, "label": "Batch ID", "no_copy": 1, "oldfieldname": "batch_id", @@ -124,13 +128,45 @@ "oldfieldname": "description", "oldfieldtype": "Small Text", "width": "300px" + }, + { + "fieldname": "sb_disabled", + "fieldtype": "Section Break" + }, + { + "fieldname": "sb_batch", + "fieldtype": "Section Break", + "label": "Batch Details" + }, + { + "fetch_from": "item.item_name", + "fieldname": "item_name", + "fieldtype": "Data", + "in_list_view": 1, + "label": "Item Name", + "read_only": 1 + }, + { + "fieldname": "batch_qty", + "fieldtype": "Float", + "in_list_view": 1, + "label": "Batch Quantity", + "read_only": 1 + }, + { + "fetch_from": "item.stock_uom", + "fieldname": "stock_uom", + "fieldtype": "Link", + "label": "Batch UOM", + "options": "UOM", + "read_only": 1 } ], "icon": "fa fa-archive", "idx": 1, "image_field": "image", "max_attachments": 5, - "modified": "2019-07-16 23:04:47.554387", + "modified": "2019-08-01 03:33:52.900790", "modified_by": "Administrator", "module": "Stock", "name": "Batch", From d2d73e6cb7049ee40fb3bab779e4aab94713d9f6 Mon Sep 17 00:00:00 2001 From: Rohan Bansal Date: Wed, 28 Aug 2019 13:21:01 +0530 Subject: [PATCH 10/13] fix: prioritize empty over expired as batch status --- erpnext/stock/doctype/batch/batch_list.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/erpnext/stock/doctype/batch/batch_list.js b/erpnext/stock/doctype/batch/batch_list.js index 05bf37f0f4a..d4f74c3a217 100644 --- a/erpnext/stock/doctype/batch/batch_list.js +++ b/erpnext/stock/doctype/batch/batch_list.js @@ -3,10 +3,10 @@ frappe.listview_settings['Batch'] = { get_indicator: (doc) => { if (doc.disabled) { return [__("Disabled"), "darkgrey", "disabled,=,1"]; - } else if (doc.expiry_date && frappe.datetime.get_diff(doc.expiry_date, frappe.datetime.nowdate()) <= 0) { - return [__("Expired"), "red", "expiry_date,not in,|expiry_date,<=,Today|batch_qty,>,0|disabled,=,0"] } else if (!doc.batch_qty) { return [__("Empty"), "darkgrey", "batch_qty,=,0|disabled,=,0"]; + } else if (doc.expiry_date && frappe.datetime.get_diff(doc.expiry_date, frappe.datetime.nowdate()) <= 0) { + return [__("Expired"), "red", "expiry_date,not in,|expiry_date,<=,Today|batch_qty,>,0|disabled,=,0"] } else { return [__("Active"), "green", "batch_qty,>,0|disabled,=,0"]; }; From f92a5f32bd2e0efc898748d7b266d12fae436f8e Mon Sep 17 00:00:00 2001 From: Rohan Bansal Date: Fri, 4 Oct 2019 13:10:57 +0530 Subject: [PATCH 11/13] fix: set batch ID as title instead of item code --- erpnext/stock/doctype/batch/batch.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/erpnext/stock/doctype/batch/batch.json b/erpnext/stock/doctype/batch/batch.json index 47b0a8dec4d..1eb457734e0 100644 --- a/erpnext/stock/doctype/batch/batch.json +++ b/erpnext/stock/doctype/batch/batch.json @@ -38,6 +38,7 @@ "depends_on": "eval:doc.__islocal", "fieldname": "batch_id", "fieldtype": "Data", + "in_list_view": 1, "label": "Batch ID", "no_copy": 1, "oldfieldname": "batch_id", @@ -48,7 +49,6 @@ { "fieldname": "item", "fieldtype": "Link", - "in_list_view": 1, "in_standard_filter": 1, "label": "Item", "oldfieldname": "item", @@ -166,7 +166,7 @@ "idx": 1, "image_field": "image", "max_attachments": 5, - "modified": "2019-08-01 03:33:52.900790", + "modified": "2019-10-03 22:38:45.104056", "modified_by": "Administrator", "module": "Stock", "name": "Batch", @@ -190,5 +190,5 @@ "quick_entry": 1, "sort_field": "modified", "sort_order": "DESC", - "title_field": "item" + "title_field": "batch_id" } \ No newline at end of file From c9f08bed2b334b484f06a7d065b1981157aff700 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Tue, 7 Apr 2020 17:29:06 +0530 Subject: [PATCH 12/13] fix: set batch qty in batch master and test cases --- .../patches/v12_0/set_total_batch_quantity.py | 4 +++- erpnext/stock/doctype/batch/batch.py | 4 ---- erpnext/stock/doctype/batch/test_batch.py | 19 +++++++++++++++++-- .../stock_ledger_entry/stock_ledger_entry.py | 7 +++---- 4 files changed, 23 insertions(+), 11 deletions(-) diff --git a/erpnext/patches/v12_0/set_total_batch_quantity.py b/erpnext/patches/v12_0/set_total_batch_quantity.py index b02da305ac9..d373275c253 100644 --- a/erpnext/patches/v12_0/set_total_batch_quantity.py +++ b/erpnext/patches/v12_0/set_total_batch_quantity.py @@ -5,5 +5,7 @@ def execute(): frappe.reload_doc("stock", "doctype", "batch") for batch in frappe.get_all("Batch", fields=["name", "batch_id"]): - batch_qty = frappe.db.get_value("Stock Ledger Entry", {"docstatus": 1, "batch_no": batch.batch_id}, "sum(actual_qty)") or 0.0 + batch_qty = frappe.db.get_value("Stock Ledger Entry", + {"docstatus": 1, "batch_no": batch.batch_id, "is_cancelled": "No"}, + "sum(actual_qty)") or 0.0 frappe.db.set_value("Batch", batch.name, "batch_qty", batch_qty, update_modified=False) diff --git a/erpnext/stock/doctype/batch/batch.py b/erpnext/stock/doctype/batch/batch.py index 9c532096c6c..9b7249e66b9 100644 --- a/erpnext/stock/doctype/batch/batch.py +++ b/erpnext/stock/doctype/batch/batch.py @@ -111,15 +111,11 @@ class Batch(Document): def validate(self): self.item_has_batch_enabled() - self.calculate_batch_qty() def item_has_batch_enabled(self): if frappe.db.get_value("Item", self.item, "has_batch_no") == 0: frappe.throw(_("The selected item cannot have Batch")) - def calculate_batch_qty(self): - self.batch_qty = frappe.db.get_value("Stock Ledger Entry", {"docstatus": 1, "batch_no": self.batch_id}, "sum(actual_qty)") - def before_save(self): has_expiry_date, shelf_life_in_days = frappe.db.get_value('Item', self.item, ['has_expiry_date', 'shelf_life_in_days']) if not self.expiry_date and has_expiry_date and shelf_life_in_days: diff --git a/erpnext/stock/doctype/batch/test_batch.py b/erpnext/stock/doctype/batch/test_batch.py index 32445a618d1..1fce5046f91 100644 --- a/erpnext/stock/doctype/batch/test_batch.py +++ b/erpnext/stock/doctype/batch/test_batch.py @@ -7,7 +7,7 @@ from frappe.exceptions import ValidationError import unittest from erpnext.stock.doctype.batch.batch import get_batch_qty, UnableToSelectBatchError, get_batch_no -from frappe.utils import cint +from frappe.utils import cint, flt from erpnext.stock.doctype.purchase_receipt.test_purchase_receipt import set_perpetual_inventory class TestBatch(unittest.TestCase): @@ -35,12 +35,13 @@ class TestBatch(unittest.TestCase): receipt = frappe.get_doc(dict( doctype='Purchase Receipt', supplier='_Test Supplier', + company='_Test Company', items=[ dict( item_code='ITEM-BATCH-1', qty=batch_qty, rate=10, - warehouse= 'Stores - WP' + warehouse= 'Stores - _TC' ) ] )).insert() @@ -175,6 +176,18 @@ class TestBatch(unittest.TestCase): self.assertEqual(get_batch_qty('batch a', '_Test Warehouse - _TC'), 90) + def test_total_batch_qty(self): + self.make_batch_item('ITEM-BATCH-3') + existing_batch_qty = flt(frappe.db.get_value("Batch", "B100", "batch_qty")) + stock_entry = self.make_new_batch_and_entry('ITEM-BATCH-3', 'B100', '_Test Warehouse - _TC') + + current_batch_qty = flt(frappe.db.get_value("Batch", "B100", "batch_qty")) + self.assertEqual(current_batch_qty, existing_batch_qty + 90) + + stock_entry.cancel() + current_batch_qty = flt(frappe.db.get_value("Batch", "B100", "batch_qty")) + self.assertEqual(current_batch_qty, existing_batch_qty) + @classmethod def make_new_batch_and_entry(cls, item_name, batch_name, warehouse): '''Make a new stock entry for given target warehouse and batch name of item''' @@ -208,6 +221,8 @@ class TestBatch(unittest.TestCase): stock_entry.insert() stock_entry.submit() + return stock_entry + def test_batch_name_with_naming_series(self): stock_settings = frappe.get_single('Stock Settings') use_naming_series = cint(stock_settings.use_naming_series) diff --git a/erpnext/stock/doctype/stock_ledger_entry/stock_ledger_entry.py b/erpnext/stock/doctype/stock_ledger_entry/stock_ledger_entry.py index 19394cedb4f..45ed498a28e 100644 --- a/erpnext/stock/doctype/stock_ledger_entry/stock_ledger_entry.py +++ b/erpnext/stock/doctype/stock_ledger_entry/stock_ledger_entry.py @@ -43,12 +43,11 @@ class StockLedgerEntry(Document): from erpnext.stock.doctype.serial_no.serial_no import process_serial_no process_serial_no(self) - def on_cancel(self): - self.calculate_batch_qty() - def calculate_batch_qty(self): if self.batch_no: - batch_qty = frappe.db.get_value("Stock Ledger Entry", {"docstatus": 1, "batch_no": self.batch_no}, "sum(actual_qty)") + batch_qty = frappe.db.get_value("Stock Ledger Entry", + {"docstatus": 1, "batch_no": self.batch_no, "is_cancelled": "No"}, + "sum(actual_qty)") or 0 frappe.db.set_value("Batch", self.batch_no, "batch_qty", batch_qty) #check for item quantity available in stock From 9aae0c27c2e528030ee7a25a848707f3bd3f9463 Mon Sep 17 00:00:00 2001 From: Raffael Meyer Date: Wed, 8 Apr 2020 05:26:57 +0200 Subject: [PATCH 13/13] feat(regional): a central place for regional address templates (#19862) * feat: a central place for regional address templates * set up address templates during install * why don't the tests run? * fix: remove unused variables, fix cwd * fix: .get() dicts contents * fix: choose the right default * fix: fieldname is template, not html * fix: import unittest * fix: remove unnecessary code * fix: ensure country exists * fix: ensure country exists * feat: test updating an existing template * fix(regional): DuplicateEntryError in test_update_address_template * refactor and set 'is_default' * fix codacy * fix: patch gst_fixes * fix: patch update_address_template_for_india Co-authored-by: Nabin Hait --- .../update_address_template_for_india.py | 4 +- erpnext/patches/v8_1/gst_fixes.py | 7 ++- erpnext/regional/address_template/README.md | 18 +++++++ erpnext/regional/address_template/__init__.py | 0 erpnext/regional/address_template/setup.py | 53 +++++++++++++++++++ .../templates/germany.html} | 0 .../templates/india.html} | 2 +- .../templates/united_states.html} | 0 .../test_regional_address_template.py | 45 ++++++++++++++++ erpnext/regional/germany/setup.py | 27 +--------- erpnext/regional/india/setup.py | 16 ------ erpnext/regional/united_states/setup.py | 18 ------- .../operations/install_fixtures.py | 11 ++-- 13 files changed, 131 insertions(+), 70 deletions(-) create mode 100644 erpnext/regional/address_template/README.md create mode 100644 erpnext/regional/address_template/__init__.py create mode 100644 erpnext/regional/address_template/setup.py rename erpnext/regional/{germany/address_template.html => address_template/templates/germany.html} (100%) rename erpnext/regional/{india/address_template.html => address_template/templates/india.html} (89%) rename erpnext/regional/{united_states/address_template.html => address_template/templates/united_states.html} (100%) create mode 100644 erpnext/regional/address_template/test_regional_address_template.py diff --git a/erpnext/patches/v10_0/update_address_template_for_india.py b/erpnext/patches/v10_0/update_address_template_for_india.py index 145ed452e9c..1ddca937609 100644 --- a/erpnext/patches/v10_0/update_address_template_for_india.py +++ b/erpnext/patches/v10_0/update_address_template_for_india.py @@ -3,10 +3,10 @@ from __future__ import unicode_literals import frappe -from erpnext.regional.india.setup import update_address_template +from erpnext.regional.address_template.setup import set_up_address_templates def execute(): if frappe.db.get_value('Company', {'country': 'India'}, 'name'): address_template = frappe.db.get_value('Address Template', 'India', 'template') if not address_template or "gstin" not in address_template: - update_address_template() + set_up_address_templates(default_country='India') diff --git a/erpnext/patches/v8_1/gst_fixes.py b/erpnext/patches/v8_1/gst_fixes.py index 22fa53ba373..34255eb0a42 100644 --- a/erpnext/patches/v8_1/gst_fixes.py +++ b/erpnext/patches/v8_1/gst_fixes.py @@ -1,7 +1,8 @@ from __future__ import unicode_literals import frappe from frappe.custom.doctype.custom_field.custom_field import create_custom_field -from erpnext.regional.india.setup import update_address_template +from erpnext.regional.address_template.setup import set_up_address_templates + def execute(): company = frappe.get_all('Company', filters = {'country': 'India'}) @@ -10,9 +11,10 @@ def execute(): update_existing_custom_fields() add_custom_fields() - update_address_template() + set_up_address_templates(default_country='India') frappe.reload_doc("regional", "print_format", "gst_tax_invoice") + def update_existing_custom_fields(): frappe.db.sql("""update `tabCustom Field` set label = 'HSN/SAC' where fieldname='gst_hsn_code' and label='GST HSN Code' @@ -34,6 +36,7 @@ def update_existing_custom_fields(): where fieldname='gst_hsn_code' and dt in ('Sales Invoice Item', 'Purchase Invoice Item') """) + def add_custom_fields(): hsn_sac_field = dict(fieldname='gst_hsn_code', label='HSN/SAC', fieldtype='Data', options='item_code.gst_hsn_code', insert_after='description') diff --git a/erpnext/regional/address_template/README.md b/erpnext/regional/address_template/README.md new file mode 100644 index 00000000000..991573448e1 --- /dev/null +++ b/erpnext/regional/address_template/README.md @@ -0,0 +1,18 @@ +To add an **Address Template** for your country, place a new file in this directory: + + * File name: `your_country.html` (lower case with underscores) + * File content: a [Jinja Template](http://jinja.pocoo.org/docs/templates/). + +All the fields of **Address** (including Custom Fields, if any) will be available to the template. Example: + +```jinja +{{ address_line1 }}
+{% if address_line2 %}{{ address_line2 }}
{% endif -%} +{{ city }}
+{% if state %}{{ state }}
{% endif -%} +{% if pincode %} PIN: {{ pincode }}
{% endif -%} +{{ country }}
+{% if phone %}Phone: {{ phone }}
{% endif -%} +{% if fax %}Fax: {{ fax }}
{% endif -%} +{% if email_id %}Email: {{ email_id }}
{% endif -%} +``` diff --git a/erpnext/regional/address_template/__init__.py b/erpnext/regional/address_template/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/erpnext/regional/address_template/setup.py b/erpnext/regional/address_template/setup.py new file mode 100644 index 00000000000..9f318de3451 --- /dev/null +++ b/erpnext/regional/address_template/setup.py @@ -0,0 +1,53 @@ +"""Import Address Templates from ./templates directory.""" +import os +import frappe + +def set_up_address_templates(default_country=None): + for country, html in get_address_templates(): + is_default = 1 if country == default_country else 0 + update_address_template(country, html, is_default) + +def get_address_templates(): + """ + Return country and path for all HTML files in this directory. + + Returns a list of dicts. + """ + def country(file_name): + """Convert 'united_states.html' to 'United States'.""" + suffix_pos = file_name.find(".html") + country_snake_case = file_name[:suffix_pos] + country_title_case = " ".join(country_snake_case.split("_")).title() + return country_title_case + + def get_file_content(file_name): + """Convert 'united_states.html' to '/path/to/united_states.html'.""" + full_path = os.path.join(template_dir, file_name) + with open(full_path, "r") as f: + content = f.read() + return content + + dir_name = os.path.dirname(__file__) + template_dir = os.path.join(dir_name, "templates") + file_names = os.listdir(template_dir) + html_files = [file for file in file_names if file.endswith(".html")] + + return [(country(file_name), get_file_content(file_name)) for file_name in html_files] + + +def update_address_template(country, html, is_default=0): + """Update existing Address Template or create a new one.""" + if not frappe.db.exists("Country", country): + frappe.log_error("Country {} for regional Address Template does not exist.".format(country)) + return + + if frappe.db.exists("Address Template", country): + frappe.db.set_value("Address Template", country, "template", html) + frappe.db.set_value("Address Template", country, "is_default", is_default) + else: + frappe.get_doc(dict( + doctype="Address Template", + country=country, + is_default=is_default, + template=html + )).insert() diff --git a/erpnext/regional/germany/address_template.html b/erpnext/regional/address_template/templates/germany.html similarity index 100% rename from erpnext/regional/germany/address_template.html rename to erpnext/regional/address_template/templates/germany.html diff --git a/erpnext/regional/india/address_template.html b/erpnext/regional/address_template/templates/india.html similarity index 89% rename from erpnext/regional/india/address_template.html rename to erpnext/regional/address_template/templates/india.html index 55cc9af0d16..ffb9d0547e0 100644 --- a/erpnext/regional/india/address_template.html +++ b/erpnext/regional/address_template/templates/india.html @@ -6,4 +6,4 @@ {% if phone %}Phone: {{ phone }}
{% endif -%} {% if fax %}Fax: {{ fax }}
{% endif -%} {% if email_id %}Email: {{ email_id }}
{% endif -%} -{% if gstin %}GSTIN: {{ gstin }}
{% endif -%} \ No newline at end of file +{% if gstin %}GSTIN: {{ gstin }}
{% endif -%} diff --git a/erpnext/regional/united_states/address_template.html b/erpnext/regional/address_template/templates/united_states.html similarity index 100% rename from erpnext/regional/united_states/address_template.html rename to erpnext/regional/address_template/templates/united_states.html diff --git a/erpnext/regional/address_template/test_regional_address_template.py b/erpnext/regional/address_template/test_regional_address_template.py new file mode 100644 index 00000000000..8a05ea26f45 --- /dev/null +++ b/erpnext/regional/address_template/test_regional_address_template.py @@ -0,0 +1,45 @@ +from __future__ import unicode_literals +from unittest import TestCase + +import frappe +from erpnext.regional.address_template.setup import get_address_templates +from erpnext.regional.address_template.setup import update_address_template + +def ensure_country(country): + if frappe.db.exists("Country", country): + return frappe.get_doc("Country", country) + else: + c = frappe.get_doc({ + "doctype": "Country", + "country_name": country + }) + c.insert() + return c + +class TestRegionalAddressTemplate(TestCase): + def test_get_address_templates(self): + """Get the countries and paths from the templates directory.""" + templates = get_address_templates() + self.assertIsInstance(templates, list) + self.assertIsInstance(templates[0], tuple) + + def test_create_address_template(self): + """Create a new Address Template.""" + country = ensure_country("Germany") + update_address_template(country.name, "TEST") + doc = frappe.get_doc("Address Template", country.name) + self.assertEqual(doc.template, "TEST") + + def test_update_address_template(self): + """Update an existing Address Template.""" + country = ensure_country("Germany") + if not frappe.db.exists("Address Template", country.name): + template = frappe.get_doc({ + "doctype": "Address Template", + "country": country.name, + "template": "EXISTING" + }).insert() + + update_address_template(country.name, "NEW") + doc = frappe.get_doc("Address Template", country.name) + self.assertEqual(doc.template, "NEW") diff --git a/erpnext/regional/germany/setup.py b/erpnext/regional/germany/setup.py index a5471366ca2..d6047e863ce 100644 --- a/erpnext/regional/germany/setup.py +++ b/erpnext/regional/germany/setup.py @@ -3,29 +3,4 @@ import frappe def setup(company=None, patch=True): - if not patch: - update_address_template() - - -def update_address_template(): - """ - Read address template from file. Update existing Address Template or create a - new one. - """ - dir_name = os.path.dirname(__file__) - template_path = os.path.join(dir_name, 'address_template.html') - - with open(template_path, 'r') as template_file: - template_html = template_file.read() - - address_template = frappe.db.get_value('Address Template', 'Germany') - - if address_template: - frappe.db.set_value('Address Template', 'Germany', 'template', template_html) - else: - # make new html template for Germany - frappe.get_doc(dict( - doctype='Address Template', - country='Germany', - template=template_html - )).insert() + pass diff --git a/erpnext/regional/india/setup.py b/erpnext/regional/india/setup.py index 75f29b8380b..28b1f8ffb8b 100644 --- a/erpnext/regional/india/setup.py +++ b/erpnext/regional/india/setup.py @@ -13,7 +13,6 @@ from frappe.utils import today def setup(company=None, patch=True): setup_company_independent_fixtures() if not patch: - update_address_template() make_fixtures(company) # TODO: for all countries @@ -24,21 +23,6 @@ def setup_company_independent_fixtures(): frappe.enqueue('erpnext.regional.india.setup.add_hsn_sac_codes', now=frappe.flags.in_test) add_print_formats() -def update_address_template(): - with open(os.path.join(os.path.dirname(__file__), 'address_template.html'), 'r') as f: - html = f.read() - - address_template = frappe.db.get_value('Address Template', 'India') - if address_template: - frappe.db.set_value('Address Template', 'India', 'template', html) - else: - # make new html template for India - frappe.get_doc(dict( - doctype='Address Template', - country='India', - template=html - )).insert() - def add_hsn_sac_codes(): # HSN codes with open(os.path.join(os.path.dirname(__file__), 'hsn_code_data.json'), 'r') as f: diff --git a/erpnext/regional/united_states/setup.py b/erpnext/regional/united_states/setup.py index cb82b639ba8..6d344025d26 100644 --- a/erpnext/regional/united_states/setup.py +++ b/erpnext/regional/united_states/setup.py @@ -5,12 +5,9 @@ from __future__ import unicode_literals import frappe from frappe.custom.doctype.custom_field.custom_field import create_custom_fields - def setup(company=None, patch=True): make_custom_fields() add_print_formats() - update_address_template() - def make_custom_fields(): custom_fields = { @@ -21,22 +18,7 @@ def make_custom_fields(): } create_custom_fields(custom_fields) - def add_print_formats(): frappe.reload_doc("regional", "print_format", "irs_1099_form") frappe.db.sql(""" update `tabPrint Format` set disabled = 0 where name in('IRS 1099 Form') """) - - -def update_address_template(): - html = """{{ address_line1 }}
- {% if address_line2 %}{{ address_line2 }}
{% endif -%} - {{ city }}, {% if state %}{{ state }}{% endif -%}{% if pincode %} {{ pincode }}
{% endif -%} - {% if country != "United States" %}{{ country|upper }}{% endif -%} - """ - - address_template = frappe.db.get_value('Address Template', 'United States') - if address_template: - frappe.db.set_value('Address Template', 'United States', 'template', html) - else: - frappe.get_doc(dict(doctype='Address Template', country='United States', template=html)).insert() diff --git a/erpnext/setup/setup_wizard/operations/install_fixtures.py b/erpnext/setup/setup_wizard/operations/install_fixtures.py index ebd7b509396..e4986e36b7b 100644 --- a/erpnext/setup/setup_wizard/operations/install_fixtures.py +++ b/erpnext/setup/setup_wizard/operations/install_fixtures.py @@ -8,9 +8,11 @@ import frappe, os, json from frappe import _ from frappe.desk.page.setup_wizard.setup_wizard import make_records from frappe.utils import cstr, getdate -from erpnext.accounts.doctype.account.account import RootNotEditable from frappe.desk.doctype.global_search_settings.global_search_settings import update_global_search_doctypes +from erpnext.accounts.doctype.account.account import RootNotEditable +from erpnext.regional.address_template.setup import set_up_address_templates + default_lead_sources = ["Existing Customer", "Reference", "Advertisement", "Cold Calling", "Exhibition", "Supplier Reference", "Mass Mailing", "Customer's Vendor", "Campaign", "Walk In"] @@ -30,7 +32,7 @@ def install(country=None): { 'doctype': 'Domain', 'domain': 'Agriculture'}, { 'doctype': 'Domain', 'domain': 'Non Profit'}, - # address template + # ensure at least an empty Address Template exists for this Country {'doctype':"Address Template", "country": country}, # item group @@ -269,12 +271,11 @@ def install(country=None): # Records for the Supplier Scorecard from erpnext.buying.doctype.supplier_scorecard.supplier_scorecard import make_default_records + make_default_records() - make_records(records) - + set_up_address_templates(default_country=country) set_more_defaults() - update_global_search_doctypes() # path = frappe.get_app_path('erpnext', 'regional', frappe.scrub(country))