From 94514ffee90943b2892d22aedc6d51f96670c0b0 Mon Sep 17 00:00:00 2001 From: Anurag Mishra Date: Mon, 11 Mar 2019 10:37:28 +0530 Subject: [PATCH 01/23] feat: timesheet Employee Summary Report --- .../employee_billing_summary/__init__.py | 0 .../employee_billing_summary.js | 27 ++++ .../employee_billing_summary.json | 36 ++++++ .../employee_billing_summary.py | 119 ++++++++++++++++++ erpnext/public/node_modules | 1 + 5 files changed, 183 insertions(+) create mode 100644 erpnext/projects/report/employee_billing_summary/__init__.py create mode 100644 erpnext/projects/report/employee_billing_summary/employee_billing_summary.js create mode 100644 erpnext/projects/report/employee_billing_summary/employee_billing_summary.json create mode 100644 erpnext/projects/report/employee_billing_summary/employee_billing_summary.py create mode 120000 erpnext/public/node_modules diff --git a/erpnext/projects/report/employee_billing_summary/__init__.py b/erpnext/projects/report/employee_billing_summary/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/erpnext/projects/report/employee_billing_summary/employee_billing_summary.js b/erpnext/projects/report/employee_billing_summary/employee_billing_summary.js new file mode 100644 index 00000000000..e6e674666d2 --- /dev/null +++ b/erpnext/projects/report/employee_billing_summary/employee_billing_summary.js @@ -0,0 +1,27 @@ +// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors +// For license information, please see license.txt +/* eslint-disable */ + +frappe.query_reports["Employee Billing Summary"] = { + "filters": [ + { + fieldname: "employee", + label: __("Employee"), + fieldtype: "Link", + options: "Employee", + }, + { + fieldname:"from_date", + label: __("From Date"), + fieldtype: "Date", + default: frappe.datetime.get_today() + }, + { + fieldname:"to_date", + label: __("To Date"), + fieldtype: "Date", + default: frappe.datetime.add_days(frappe.datetime.get_today(), 30) + }, + + ] +} diff --git a/erpnext/projects/report/employee_billing_summary/employee_billing_summary.json b/erpnext/projects/report/employee_billing_summary/employee_billing_summary.json new file mode 100644 index 00000000000..433ebac5ddf --- /dev/null +++ b/erpnext/projects/report/employee_billing_summary/employee_billing_summary.json @@ -0,0 +1,36 @@ +{ + "add_total_row": 0, + "creation": "2019-03-08 15:08:19.929728", + "disable_prepared_report": 0, + "disabled": 0, + "docstatus": 0, + "doctype": "Report", + "idx": 0, + "is_standard": "Yes", + "modified": "2019-03-08 15:08:19.929728", + "modified_by": "Administrator", + "module": "Projects", + "name": "Employee Billing Summary", + "owner": "Administrator", + "prepared_report": 0, + "ref_doctype": "Timesheet", + "report_name": "Employee Billing Summary", + "report_type": "Script Report", + "roles": [ + { + "role": "Projects User" + }, + { + "role": "HR User" + }, + { + "role": "Manufacturing User" + }, + { + "role": "Employee" + }, + { + "role": "Accounts User" + } + ] +} \ No newline at end of file diff --git a/erpnext/projects/report/employee_billing_summary/employee_billing_summary.py b/erpnext/projects/report/employee_billing_summary/employee_billing_summary.py new file mode 100644 index 00000000000..47323efabe5 --- /dev/null +++ b/erpnext/projects/report/employee_billing_summary/employee_billing_summary.py @@ -0,0 +1,119 @@ +# Copyright (c) 2013, Frappe Technologies Pvt. Ltd. and contributors +# For license information, please see license.txt + +from __future__ import unicode_literals +import frappe +from frappe import _ +from frappe.utils import time_diff_in_hours + +def execute(filters=None): + filters = frappe._dict(filters or {}) + print(filters) + + columns = get_columns() + + data = get_data(filters) + return columns, data + +def get_columns(): + return [ + { + "label": _("Employee ID"), + "fieldtype": "Link", + "fieldname": "employee", + "options": "Employee", + "width": 300 + }, + { + "label": _("Employee Name"), + "fieldtype": "data", + "fieldname": "employee_name", + "hidden": 1, + "width": 200 + }, + { + "label": _("Timesheet"), + "fieldtype": "Link", + "fieldname": "timesheet", + "options": "Timesheet", + "width": 150 + }, + { + "label": _("Date"), + "fieldtype": "Date", + "fieldname": "date", + "width": 150 + }, + { + "label": _("Total Billable Hours"), + "fieldtype": "Int", + "fieldname": "total_billable_hours", + "width": 50 + }, + { + "label": _("Total Hours"), + "fieldtype": "Int", + "fieldname": "total_hours", + "width": 50 + }, + { + "label": _("Amount"), + "fieldtype": "Int", + "fieldname": "amount", + "width": 50 + } + ] + +def get_data(filters): + data = [] + if "employee" in filters: + record= frappe.db.sql('''SELECT + employee, employee_name, name, total_billable_hours, total_hours, total_billable_amount + FROM + `tabTimesheet` + WHERE + employee = %s and (start_date <= %s and end_date >= %s)''',(filters.employee, filters.to_date, filters.from_date), + as_dict=1 + ) + for entries in record: + + timesheet_details = frappe.get_all( + "Timesheet Detail", + filters={"parent": entries.name}, + fields=["*"] + ) + + total_hours = 0 + total_billable_hours = 0 + print("-------------------------------------------->>>>>>>") + for time in timesheet_details: + time_start = time.from_time + time_end = frappe.utils.add_to_date(time.from_time, hours=time.hours) + + from_date = frappe.utils.get_datetime(filters.from_date) + to_date = frappe.utils.get_datetime(filters.to_date) + + if time_start <= from_date and time_end <= to_date: + total_hours += abs(time_diff_in_hours(time_end, from_date)) + print(from_date, time_end) + print("case 1", entries.name,time_diff_in_hours(time_end, from_date)) + elif time_start >= from_date and time_end >= to_date: + total_hours += abs(time_diff_in_hours(to_date, time_start)) + print(time_start, to_date) + print("case 2", entries.name,time_diff_in_hours(to_date, time_start)) + elif time_start >= from_date and time_end <= to_date: + total_hours = entries.total_hours + print("case 3 all set", entries.name) + + print(total_hours) + print("-------------------------------------------->>>>>>>") + row = { + "employee": entries.employee, + "employee_name": entries.employee_name, + "timesheet": entries.name, + "total_billable_hours": entries.total_billable_hours, + "total_hours": entries.total_hours, + "amount": 1 + } + data.append(row) + return data \ No newline at end of file diff --git a/erpnext/public/node_modules b/erpnext/public/node_modules new file mode 120000 index 00000000000..229573e0576 --- /dev/null +++ b/erpnext/public/node_modules @@ -0,0 +1 @@ +/Users/anuragmishra/test/apps/erpnext/node_modules \ No newline at end of file From 3d27aabdeb4dee973c5142a8580636fafa6cc22d Mon Sep 17 00:00:00 2001 From: Anurag Mishra Date: Mon, 11 Mar 2019 11:46:01 +0530 Subject: [PATCH 02/23] Commonify code --- .../employee_billing_summary.js | 1 - .../employee_billing_summary.py | 35 ++++++++++--------- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/erpnext/projects/report/employee_billing_summary/employee_billing_summary.js b/erpnext/projects/report/employee_billing_summary/employee_billing_summary.js index e6e674666d2..b792e818d81 100644 --- a/erpnext/projects/report/employee_billing_summary/employee_billing_summary.js +++ b/erpnext/projects/report/employee_billing_summary/employee_billing_summary.js @@ -22,6 +22,5 @@ frappe.query_reports["Employee Billing Summary"] = { fieldtype: "Date", default: frappe.datetime.add_days(frappe.datetime.get_today(), 30) }, - ] } diff --git a/erpnext/projects/report/employee_billing_summary/employee_billing_summary.py b/erpnext/projects/report/employee_billing_summary/employee_billing_summary.py index 47323efabe5..491fa764d96 100644 --- a/erpnext/projects/report/employee_billing_summary/employee_billing_summary.py +++ b/erpnext/projects/report/employee_billing_summary/employee_billing_summary.py @@ -8,8 +8,6 @@ from frappe.utils import time_diff_in_hours def execute(filters=None): filters = frappe._dict(filters or {}) - print(filters) - columns = get_columns() data = get_data(filters) @@ -85,7 +83,8 @@ def get_data(filters): total_hours = 0 total_billable_hours = 0 - print("-------------------------------------------->>>>>>>") + total_amount = 0 + for time in timesheet_details: time_start = time.from_time time_end = frappe.utils.add_to_date(time.from_time, hours=time.hours) @@ -94,26 +93,28 @@ def get_data(filters): to_date = frappe.utils.get_datetime(filters.to_date) if time_start <= from_date and time_end <= to_date: - total_hours += abs(time_diff_in_hours(time_end, from_date)) - print(from_date, time_end) - print("case 1", entries.name,time_diff_in_hours(time_end, from_date)) + total_hours, total_billable_hours, total_amount = get_billable_and_total_hours(time, time_end, from_date, total_hours, total_billable_hours, total_amount) elif time_start >= from_date and time_end >= to_date: - total_hours += abs(time_diff_in_hours(to_date, time_start)) - print(time_start, to_date) - print("case 2", entries.name,time_diff_in_hours(to_date, time_start)) + total_hours, total_billable_hours, total_amount = get_billable_and_total_hours(time, to_date, time_start, total_hours, total_billable_hours, total_amount) elif time_start >= from_date and time_end <= to_date: - total_hours = entries.total_hours - print("case 3 all set", entries.name) + total_hours, total_billable_hours, total_amount = get_billable_and_total_hours(time, time_end, time_start, total_hours, total_billable_hours, total_amount) - print(total_hours) - print("-------------------------------------------->>>>>>>") row = { "employee": entries.employee, "employee_name": entries.employee_name, "timesheet": entries.name, - "total_billable_hours": entries.total_billable_hours, - "total_hours": entries.total_hours, - "amount": 1 + "total_billable_hours": total_billable_hours, + "total_hours": total_hours, + "amount": total_amount } + data.append(row) - return data \ No newline at end of file + return data + +def get_billable_and_total_hours(time, end, start, total_hours, total_billable_hours, total_amount): + total_hours += abs(time_diff_in_hours(end, start)) + if time.billable: + total_billable_hours += abs(time_diff_in_hours(end, start)) + total_amount += total_billable_hours * time.billing_rate + + return total_hours, total_billable_hours, total_amount From 61aab377b67d2feb09ab31b1655806f4bc9b49d5 Mon Sep 17 00:00:00 2001 From: Anurag Mishra <32095923+Anurag810@users.noreply.github.com> Date: Mon, 11 Mar 2019 12:02:25 +0530 Subject: [PATCH 03/23] Minor Fixes --- erpnext/public/node_modules | 1 - 1 file changed, 1 deletion(-) delete mode 120000 erpnext/public/node_modules diff --git a/erpnext/public/node_modules b/erpnext/public/node_modules deleted file mode 120000 index 229573e0576..00000000000 --- a/erpnext/public/node_modules +++ /dev/null @@ -1 +0,0 @@ -/Users/anuragmishra/test/apps/erpnext/node_modules \ No newline at end of file From b57c024ff7954a08d169bbdf84e016064ca3fcdd Mon Sep 17 00:00:00 2001 From: Anurag Mishra Date: Mon, 11 Mar 2019 17:43:44 +0530 Subject: [PATCH 04/23] feat: Project Billing Summary for timesheet --- erpnext/projects/report/billing_summary.py | 137 ++++++++++++++++++ .../employee_billing_summary.py | 110 +------------- .../project_billing_summary/__init__.py | 0 .../project_billing_summary.js | 26 ++++ .../project_billing_summary.json | 36 +++++ .../project_billing_summary.py | 14 ++ 6 files changed, 215 insertions(+), 108 deletions(-) create mode 100644 erpnext/projects/report/billing_summary.py create mode 100644 erpnext/projects/report/project_billing_summary/__init__.py create mode 100644 erpnext/projects/report/project_billing_summary/project_billing_summary.js create mode 100644 erpnext/projects/report/project_billing_summary/project_billing_summary.json create mode 100644 erpnext/projects/report/project_billing_summary/project_billing_summary.py diff --git a/erpnext/projects/report/billing_summary.py b/erpnext/projects/report/billing_summary.py new file mode 100644 index 00000000000..e34e90b1a44 --- /dev/null +++ b/erpnext/projects/report/billing_summary.py @@ -0,0 +1,137 @@ +# Copyright (c) 2013, Frappe Technologies Pvt. Ltd. and contributors +# For license information, please see license.txt + + +from __future__ import unicode_literals +import frappe +from frappe import _ +from frappe.utils import time_diff_in_hours + + +def get_columns(): + return [ + { + "label": _("Employee ID"), + "fieldtype": "Link", + "fieldname": "employee", + "options": "Employee", + "width": 300 + }, + { + "label": _("Employee Name"), + "fieldtype": "data", + "fieldname": "employee_name", + "hidden": 1, + "width": 200 + }, + { + "label": _("Timesheet"), + "fieldtype": "Link", + "fieldname": "timesheet", + "options": "Timesheet", + "width": 150 + }, + { + "label": _("Total Billable Hours"), + "fieldtype": "Int", + "fieldname": "total_billable_hours", + "width": 50 + }, + { + "label": _("Total Hours"), + "fieldtype": "Int", + "fieldname": "total_hours", + "width": 50 + }, + { + "label": _("Amount"), + "fieldtype": "Int", + "fieldname": "amount", + "width": 100 + } + ] + +def get_data(filters): + data = [] + + if "employee" in filters: + record= frappe.db.sql('''SELECT + employee, employee_name, name, total_billable_hours, total_hours, total_billable_amount + FROM + `tabTimesheet` + WHERE + employee = %s and (start_date <= %s and end_date >= %s)''',(filters.employee, filters.to_date, filters.from_date), + as_dict=1 + ) + + elif "project" in filters: + record= frappe.db.sql('''SELECT + employee, employee_name, name, total_billable_hours, total_hours, total_billable_amount + FROM + `tabTimesheet` + WHERE + start_date <= %s and end_date >= %s''',(filters.to_date, filters.from_date), + as_dict=1 + ) + else: + record = {} + + + for entries in record: + + timesheet_details_filter = {"parent": entries.name} + + if "project" in filters: + timesheet_details_filter["project"] = filters.project + + timesheet_details = frappe.get_all( + "Timesheet Detail", + filters = timesheet_details_filter, + fields=["*"] + ) + + total_hours = 0 + total_billable_hours = 0 + total_amount = 0 + check_entries = False + + for time in timesheet_details: + + check_entries = True + + time_start = time.from_time + time_end = frappe.utils.add_to_date(time.from_time, hours=time.hours) + + from_date = frappe.utils.get_datetime(filters.from_date) + to_date = frappe.utils.get_datetime(filters.to_date) + + if time_start <= from_date and time_end <= to_date: + total_hours, total_billable_hours, total_amount = get_billable_and_total_hours(time, time_end, from_date, total_hours, total_billable_hours, total_amount) + elif time_start >= from_date and time_end >= to_date: + total_hours, total_billable_hours, total_amount = get_billable_and_total_hours(time, to_date, time_start, total_hours, total_billable_hours, total_amount) + elif time_start >= from_date and time_end <= to_date: + total_hours, total_billable_hours, total_amount = get_billable_and_total_hours(time, time_end, time_start, total_hours, total_billable_hours, total_amount) + + row = { + "employee": entries.employee, + "employee_name": entries.employee_name, + "timesheet": entries.name, + "total_billable_hours": total_billable_hours, + "total_hours": total_hours, + "amount": total_amount + } + + if check_entries: + data.append(row) + check_entries = False + + return data + + +def get_billable_and_total_hours(time, end, start, total_hours, total_billable_hours, total_amount): + total_hours += abs(time_diff_in_hours(end, start)) + if time.billable: + total_billable_hours += abs(time_diff_in_hours(end, start)) + total_amount += total_billable_hours * time.billing_rate + + return total_hours, total_billable_hours, total_amount \ No newline at end of file diff --git a/erpnext/projects/report/employee_billing_summary/employee_billing_summary.py b/erpnext/projects/report/employee_billing_summary/employee_billing_summary.py index 491fa764d96..cd5ad7803a5 100644 --- a/erpnext/projects/report/employee_billing_summary/employee_billing_summary.py +++ b/erpnext/projects/report/employee_billing_summary/employee_billing_summary.py @@ -4,117 +4,11 @@ from __future__ import unicode_literals import frappe from frappe import _ -from frappe.utils import time_diff_in_hours +from erpnext.projects.report.billing_summary import get_columns, get_data def execute(filters=None): filters = frappe._dict(filters or {}) columns = get_columns() data = get_data(filters) - return columns, data - -def get_columns(): - return [ - { - "label": _("Employee ID"), - "fieldtype": "Link", - "fieldname": "employee", - "options": "Employee", - "width": 300 - }, - { - "label": _("Employee Name"), - "fieldtype": "data", - "fieldname": "employee_name", - "hidden": 1, - "width": 200 - }, - { - "label": _("Timesheet"), - "fieldtype": "Link", - "fieldname": "timesheet", - "options": "Timesheet", - "width": 150 - }, - { - "label": _("Date"), - "fieldtype": "Date", - "fieldname": "date", - "width": 150 - }, - { - "label": _("Total Billable Hours"), - "fieldtype": "Int", - "fieldname": "total_billable_hours", - "width": 50 - }, - { - "label": _("Total Hours"), - "fieldtype": "Int", - "fieldname": "total_hours", - "width": 50 - }, - { - "label": _("Amount"), - "fieldtype": "Int", - "fieldname": "amount", - "width": 50 - } - ] - -def get_data(filters): - data = [] - if "employee" in filters: - record= frappe.db.sql('''SELECT - employee, employee_name, name, total_billable_hours, total_hours, total_billable_amount - FROM - `tabTimesheet` - WHERE - employee = %s and (start_date <= %s and end_date >= %s)''',(filters.employee, filters.to_date, filters.from_date), - as_dict=1 - ) - for entries in record: - - timesheet_details = frappe.get_all( - "Timesheet Detail", - filters={"parent": entries.name}, - fields=["*"] - ) - - total_hours = 0 - total_billable_hours = 0 - total_amount = 0 - - for time in timesheet_details: - time_start = time.from_time - time_end = frappe.utils.add_to_date(time.from_time, hours=time.hours) - - from_date = frappe.utils.get_datetime(filters.from_date) - to_date = frappe.utils.get_datetime(filters.to_date) - - if time_start <= from_date and time_end <= to_date: - total_hours, total_billable_hours, total_amount = get_billable_and_total_hours(time, time_end, from_date, total_hours, total_billable_hours, total_amount) - elif time_start >= from_date and time_end >= to_date: - total_hours, total_billable_hours, total_amount = get_billable_and_total_hours(time, to_date, time_start, total_hours, total_billable_hours, total_amount) - elif time_start >= from_date and time_end <= to_date: - total_hours, total_billable_hours, total_amount = get_billable_and_total_hours(time, time_end, time_start, total_hours, total_billable_hours, total_amount) - - row = { - "employee": entries.employee, - "employee_name": entries.employee_name, - "timesheet": entries.name, - "total_billable_hours": total_billable_hours, - "total_hours": total_hours, - "amount": total_amount - } - - data.append(row) - return data - -def get_billable_and_total_hours(time, end, start, total_hours, total_billable_hours, total_amount): - total_hours += abs(time_diff_in_hours(end, start)) - if time.billable: - total_billable_hours += abs(time_diff_in_hours(end, start)) - total_amount += total_billable_hours * time.billing_rate - - return total_hours, total_billable_hours, total_amount + return columns, data \ No newline at end of file diff --git a/erpnext/projects/report/project_billing_summary/__init__.py b/erpnext/projects/report/project_billing_summary/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/erpnext/projects/report/project_billing_summary/project_billing_summary.js b/erpnext/projects/report/project_billing_summary/project_billing_summary.js new file mode 100644 index 00000000000..18dbbd19bbd --- /dev/null +++ b/erpnext/projects/report/project_billing_summary/project_billing_summary.js @@ -0,0 +1,26 @@ +// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors +// For license information, please see license.txt +/* eslint-disable */ + +frappe.query_reports["Project Billing Summary"] = { + "filters": [ + { + fieldname: "project", + label: __("Project"), + fieldtype: "Link", + options: "Project", + }, + { + fieldname:"from_date", + label: __("From Date"), + fieldtype: "Date", + default: frappe.datetime.get_today() + }, + { + fieldname:"to_date", + label: __("To Date"), + fieldtype: "Date", + default: frappe.datetime.add_days(frappe.datetime.get_today(), 30) + }, + ] +} diff --git a/erpnext/projects/report/project_billing_summary/project_billing_summary.json b/erpnext/projects/report/project_billing_summary/project_billing_summary.json new file mode 100644 index 00000000000..a3f91c802d5 --- /dev/null +++ b/erpnext/projects/report/project_billing_summary/project_billing_summary.json @@ -0,0 +1,36 @@ +{ + "add_total_row": 0, + "creation": "2019-03-11 16:22:39.460524", + "disable_prepared_report": 0, + "disabled": 0, + "docstatus": 0, + "doctype": "Report", + "idx": 0, + "is_standard": "Yes", + "modified": "2019-03-11 16:22:39.460524", + "modified_by": "Administrator", + "module": "Projects", + "name": "Project Billing Summary", + "owner": "Administrator", + "prepared_report": 0, + "ref_doctype": "Timesheet", + "report_name": "Project Billing Summary", + "report_type": "Script Report", + "roles": [ + { + "role": "Projects User" + }, + { + "role": "HR User" + }, + { + "role": "Manufacturing User" + }, + { + "role": "Employee" + }, + { + "role": "Accounts User" + } + ] +} \ No newline at end of file diff --git a/erpnext/projects/report/project_billing_summary/project_billing_summary.py b/erpnext/projects/report/project_billing_summary/project_billing_summary.py new file mode 100644 index 00000000000..cd5ad7803a5 --- /dev/null +++ b/erpnext/projects/report/project_billing_summary/project_billing_summary.py @@ -0,0 +1,14 @@ +# Copyright (c) 2013, Frappe Technologies Pvt. Ltd. and contributors +# For license information, please see license.txt + +from __future__ import unicode_literals +import frappe +from frappe import _ +from erpnext.projects.report.billing_summary import get_columns, get_data + +def execute(filters=None): + filters = frappe._dict(filters or {}) + columns = get_columns() + + data = get_data(filters) + return columns, data \ No newline at end of file From 5c17e7760bb0c4f3ab58c668d5ab130743ea8b05 Mon Sep 17 00:00:00 2001 From: Anurag Mishra Date: Mon, 11 Mar 2019 18:17:22 +0530 Subject: [PATCH 05/23] fix: readability --- erpnext/projects/report/billing_summary.py | 104 +++++++++++---------- 1 file changed, 56 insertions(+), 48 deletions(-) diff --git a/erpnext/projects/report/billing_summary.py b/erpnext/projects/report/billing_summary.py index e34e90b1a44..cbea5f5c40c 100644 --- a/erpnext/projects/report/billing_summary.py +++ b/erpnext/projects/report/billing_summary.py @@ -54,63 +54,37 @@ def get_columns(): def get_data(filters): data = [] - if "employee" in filters: - record= frappe.db.sql('''SELECT - employee, employee_name, name, total_billable_hours, total_hours, total_billable_amount - FROM - `tabTimesheet` - WHERE - employee = %s and (start_date <= %s and end_date >= %s)''',(filters.employee, filters.to_date, filters.from_date), - as_dict=1 - ) - - elif "project" in filters: - record= frappe.db.sql('''SELECT - employee, employee_name, name, total_billable_hours, total_hours, total_billable_amount - FROM - `tabTimesheet` - WHERE - start_date <= %s and end_date >= %s''',(filters.to_date, filters.from_date), - as_dict=1 - ) - else: - record = {} - + record = get_records(filters) for entries in record: - - timesheet_details_filter = {"parent": entries.name} - - if "project" in filters: - timesheet_details_filter["project"] = filters.project - - timesheet_details = frappe.get_all( - "Timesheet Detail", - filters = timesheet_details_filter, - fields=["*"] - ) - total_hours = 0 total_billable_hours = 0 total_amount = 0 - check_entries = False + entries_exists = False - for time in timesheet_details: + timesheet_details = get_timesheet_details(filters, entries.name) - check_entries = True + for activity in timesheet_details: - time_start = time.from_time - time_end = frappe.utils.add_to_date(time.from_time, hours=time.hours) + entries_exists = True + + time_start = activity.from_time + time_end = frappe.utils.add_to_date(activity.from_time, hours=activity.hours) from_date = frappe.utils.get_datetime(filters.from_date) to_date = frappe.utils.get_datetime(filters.to_date) if time_start <= from_date and time_end <= to_date: - total_hours, total_billable_hours, total_amount = get_billable_and_total_hours(time, time_end, from_date, total_hours, total_billable_hours, total_amount) + total_hours, total_billable_hours, total_amount = get_billable_and_total_hours(activity, + time_end, from_date, total_hours, total_billable_hours, total_amount) + elif time_start >= from_date and time_end >= to_date: - total_hours, total_billable_hours, total_amount = get_billable_and_total_hours(time, to_date, time_start, total_hours, total_billable_hours, total_amount) + total_hours, total_billable_hours, total_amount = get_billable_and_total_hours(activity, + to_date, time_start, total_hours, total_billable_hours, total_amount) + elif time_start >= from_date and time_end <= to_date: - total_hours, total_billable_hours, total_amount = get_billable_and_total_hours(time, time_end, time_start, total_hours, total_billable_hours, total_amount) + total_hours, total_billable_hours, total_amount = get_billable_and_total_hours(activity, + time_end, time_start, total_hours, total_billable_hours, total_amount) row = { "employee": entries.employee, @@ -121,17 +95,51 @@ def get_data(filters): "amount": total_amount } - if check_entries: + if entries_exists: data.append(row) - check_entries = False + entries_exists = False return data +def get_records(filters): + if "employee" in filters: + return frappe.db.sql('''SELECT + employee, employee_name, name, total_billable_hours, total_hours, total_billable_amount + FROM + `tabTimesheet` + WHERE + employee = %s and (start_date <= %s and end_date >= %s)''', + (filters.employee, filters.to_date, filters.from_date), + as_dict=1 + ) -def get_billable_and_total_hours(time, end, start, total_hours, total_billable_hours, total_amount): + elif "project" in filters: + return frappe.db.sql('''SELECT + employee, employee_name, name, total_billable_hours, total_hours, total_billable_amount + FROM + `tabTimesheet` + WHERE + start_date <= %s and end_date >= %s''',(filters.to_date, filters.from_date), + as_dict=1 + ) + else: + return {} + +def get_billable_and_total_hours(activity, end, start, total_hours, total_billable_hours, total_amount): total_hours += abs(time_diff_in_hours(end, start)) - if time.billable: + if activity.billable: total_billable_hours += abs(time_diff_in_hours(end, start)) - total_amount += total_billable_hours * time.billing_rate + total_amount += total_billable_hours * activity.billing_rate + return total_hours, total_billable_hours, total_amount - return total_hours, total_billable_hours, total_amount \ No newline at end of file +def get_timesheet_details(filters, parent): + timesheet_details_filter = {"parent": parent} + + if "project" in filters: + timesheet_details_filter["project"] = filters.project + + return frappe.get_all( + "Timesheet Detail", + filters = timesheet_details_filter, + fields=["*"] + ) \ No newline at end of file From f71c147ea8dbcd70cbf66cfbaee79667907996f6 Mon Sep 17 00:00:00 2001 From: Anurag Mishra Date: Tue, 12 Mar 2019 11:00:02 +0530 Subject: [PATCH 06/23] Added mandatory feilds to the report --- .../employee_billing_summary/employee_billing_summary.js | 7 +++++-- .../project_billing_summary/project_billing_summary.js | 7 +++++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/erpnext/projects/report/employee_billing_summary/employee_billing_summary.js b/erpnext/projects/report/employee_billing_summary/employee_billing_summary.js index b792e818d81..65c2a690cf2 100644 --- a/erpnext/projects/report/employee_billing_summary/employee_billing_summary.js +++ b/erpnext/projects/report/employee_billing_summary/employee_billing_summary.js @@ -9,18 +9,21 @@ frappe.query_reports["Employee Billing Summary"] = { label: __("Employee"), fieldtype: "Link", options: "Employee", + reqd: 1 }, { fieldname:"from_date", label: __("From Date"), fieldtype: "Date", - default: frappe.datetime.get_today() + default: frappe.datetime.get_today(), + reqd: 1 }, { fieldname:"to_date", label: __("To Date"), fieldtype: "Date", - default: frappe.datetime.add_days(frappe.datetime.get_today(), 30) + default: frappe.datetime.add_days(frappe.datetime.get_today(), 30), + reqd: 1 }, ] } diff --git a/erpnext/projects/report/project_billing_summary/project_billing_summary.js b/erpnext/projects/report/project_billing_summary/project_billing_summary.js index 18dbbd19bbd..62362c35cff 100644 --- a/erpnext/projects/report/project_billing_summary/project_billing_summary.js +++ b/erpnext/projects/report/project_billing_summary/project_billing_summary.js @@ -9,18 +9,21 @@ frappe.query_reports["Project Billing Summary"] = { label: __("Project"), fieldtype: "Link", options: "Project", + reqd: 1 }, { fieldname:"from_date", label: __("From Date"), fieldtype: "Date", - default: frappe.datetime.get_today() + default: frappe.datetime.get_today(), + reqd: 1 }, { fieldname:"to_date", label: __("To Date"), fieldtype: "Date", - default: frappe.datetime.add_days(frappe.datetime.get_today(), 30) + default: frappe.datetime.add_days(frappe.datetime.get_today(), 30), + reqd: 1 }, ] } From 0dc62e8747b18d0f2cffe0daa85ae3e4d1bd09d3 Mon Sep 17 00:00:00 2001 From: Anurag Mishra Date: Tue, 12 Mar 2019 13:12:31 +0530 Subject: [PATCH 07/23] fix: Removed raw query and used frappe.get_all --- erpnext/projects/report/billing_summary.py | 40 +++++----------------- 1 file changed, 9 insertions(+), 31 deletions(-) diff --git a/erpnext/projects/report/billing_summary.py b/erpnext/projects/report/billing_summary.py index cbea5f5c40c..214dcef8fdb 100644 --- a/erpnext/projects/report/billing_summary.py +++ b/erpnext/projects/report/billing_summary.py @@ -7,7 +7,6 @@ import frappe from frappe import _ from frappe.utils import time_diff_in_hours - def get_columns(): return [ { @@ -53,7 +52,6 @@ def get_columns(): def get_data(filters): data = [] - record = get_records(filters) for entries in record: @@ -61,27 +59,20 @@ def get_data(filters): total_billable_hours = 0 total_amount = 0 entries_exists = False - timesheet_details = get_timesheet_details(filters, entries.name) - for activity in timesheet_details: - entries_exists = True - time_start = activity.from_time time_end = frappe.utils.add_to_date(activity.from_time, hours=activity.hours) - from_date = frappe.utils.get_datetime(filters.from_date) to_date = frappe.utils.get_datetime(filters.to_date) if time_start <= from_date and time_end <= to_date: total_hours, total_billable_hours, total_amount = get_billable_and_total_hours(activity, time_end, from_date, total_hours, total_billable_hours, total_amount) - elif time_start >= from_date and time_end >= to_date: total_hours, total_billable_hours, total_amount = get_billable_and_total_hours(activity, to_date, time_start, total_hours, total_billable_hours, total_amount) - elif time_start >= from_date and time_end <= to_date: total_hours, total_billable_hours, total_amount = get_billable_and_total_hours(activity, time_end, time_start, total_hours, total_billable_hours, total_amount) @@ -102,28 +93,15 @@ def get_data(filters): return data def get_records(filters): - if "employee" in filters: - return frappe.db.sql('''SELECT - employee, employee_name, name, total_billable_hours, total_hours, total_billable_amount - FROM - `tabTimesheet` - WHERE - employee = %s and (start_date <= %s and end_date >= %s)''', - (filters.employee, filters.to_date, filters.from_date), - as_dict=1 - ) + record_filters = [ + ["start_date", "<=", filters.to_date], + ["end_date", ">=", filters.from_date] + ] - elif "project" in filters: - return frappe.db.sql('''SELECT - employee, employee_name, name, total_billable_hours, total_hours, total_billable_amount - FROM - `tabTimesheet` - WHERE - start_date <= %s and end_date >= %s''',(filters.to_date, filters.from_date), - as_dict=1 - ) - else: - return {} + if "employee" in filters: + record_filters.append(["employee", "=", filters.employee]) + + return frappe.get_all("Timesheet", filters=record_filters, fields=[" * "] ) def get_billable_and_total_hours(activity, end, start, total_hours, total_billable_hours, total_amount): total_hours += abs(time_diff_in_hours(end, start)) @@ -142,4 +120,4 @@ def get_timesheet_details(filters, parent): "Timesheet Detail", filters = timesheet_details_filter, fields=["*"] - ) \ No newline at end of file + ) From 3771db92b85dd9ffdfaa2a4d327fd42e3cae0db3 Mon Sep 17 00:00:00 2001 From: Rohit Waghchaure Date: Sat, 6 Apr 2019 17:34:40 +0530 Subject: [PATCH 08/23] fix: sales return not working for bundle items --- erpnext/controllers/sales_and_purchase_return.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/erpnext/controllers/sales_and_purchase_return.py b/erpnext/controllers/sales_and_purchase_return.py index 15294f633f5..810aab68b2d 100644 --- a/erpnext/controllers/sales_and_purchase_return.py +++ b/erpnext/controllers/sales_and_purchase_return.py @@ -239,6 +239,10 @@ def make_return_doc(doctype, source_name, target_doc=None): doc.paid_amount = -1 * source.paid_amount doc.base_paid_amount = -1 * source.base_paid_amount + if doc.get("is_return") and hasattr(doc, "packed_items"): + for d in doc.get("packed_items"): + d.qty = d.qty * -1 + doc.discount_amount = -1 * source.discount_amount doc.run_method("calculate_taxes_and_totals") From f1698bb2df66db32891471d849c098d2275e6999 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Mon, 8 Apr 2019 14:59:43 +0530 Subject: [PATCH 09/23] fix: unique variant based on --- erpnext/stock/doctype/item/item.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/stock/doctype/item/item.py b/erpnext/stock/doctype/item/item.py index 8761f4e75c7..e93e7d9b615 100644 --- a/erpnext/stock/doctype/item/item.py +++ b/erpnext/stock/doctype/item/item.py @@ -725,7 +725,7 @@ class Item(WebsiteGenerator): _('Cannot change Attributes after stock transaction. Make a new Item and transfer stock to the new Item')) def validate_variant_based_on_change(self): - if self.variant_of or (self.has_variants and frappe.get_all("Item", {"variant_of": self.name})): + if not self.is_new() and (self.variant_of or (self.has_variants and frappe.get_all("Item", {"variant_of": self.name}))): if self.variant_based_on != frappe.db.get_value("Item", self.name, "variant_based_on"): frappe.throw(_("Variant Based On cannot be changed")) From 00a5e7a1d0e320c0ae5facfebbd2da8e52068541 Mon Sep 17 00:00:00 2001 From: Saurabh Date: Mon, 8 Apr 2019 15:39:03 +0600 Subject: [PATCH 10/23] bumped to version 11.1.20 --- erpnext/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/__init__.py b/erpnext/__init__.py index 6dbdab860dc..21abfaf360c 100644 --- a/erpnext/__init__.py +++ b/erpnext/__init__.py @@ -5,7 +5,7 @@ import frappe from erpnext.hooks import regional_overrides from frappe.utils import getdate -__version__ = '11.1.19' +__version__ = '11.1.20' def get_default_company(user=None): '''Get default company for user''' From 1412a681f3747909ded4b406755955defa19c42d Mon Sep 17 00:00:00 2001 From: Rushabh Mehta Date: Mon, 8 Apr 2019 17:10:56 +0530 Subject: [PATCH 11/23] Revert "fix: Raise exception if apps are on incompatible branches" --- erpnext/__init__.py | 13 +------------ erpnext/hooks.py | 2 -- 2 files changed, 1 insertion(+), 14 deletions(-) diff --git a/erpnext/__init__.py b/erpnext/__init__.py index 21abfaf360c..993a4e60386 100644 --- a/erpnext/__init__.py +++ b/erpnext/__init__.py @@ -144,15 +144,4 @@ def is_member(): last_membership = get_last_membership() if last_membership and getdate(last_membership.to_date) > getdate(): return True - return False - -def check_branch_compatibility_with_frappe(): - from frappe.utils.change_log import get_versions - versions = get_versions() - frappe_branch = versions["frappe"]["branch"] - erpnext_branch = versions["erpnext"]["branch"] - - if frappe_branch in ("hotfix", "master") and erpnext_branch == "develop": - raise frappe.IncompatibleApp("Frappe is on branch: {} and ERPNext is on branch: {}".format(frappe_branch, erpnext_branch)) - if erpnext_branch in ("hotfix", "master") and frappe_branch == "develop": - raise frappe.IncompatibleApp("Frappe is on branch: {} and ERPNext is on branch: {}".format(frappe_branch, erpnext_branch)) + return False \ No newline at end of file diff --git a/erpnext/hooks.py b/erpnext/hooks.py index dbb5aff3d9f..ccdd412c181 100644 --- a/erpnext/hooks.py +++ b/erpnext/hooks.py @@ -27,8 +27,6 @@ doctype_js = { welcome_email = "erpnext.setup.utils.welcome_email" -connect = "erpnext.check_branch_compatibility_with_frappe" - # setup wizard setup_wizard_requires = "assets/erpnext/js/setup_wizard.js" setup_wizard_stages = "erpnext.setup.setup_wizard.setup_wizard.get_setup_stages" From aac7719dd907b7c2c554b3a6bf1b54cc104999d0 Mon Sep 17 00:00:00 2001 From: Faris Ansari Date: Mon, 8 Apr 2019 21:50:58 +0530 Subject: [PATCH 12/23] fix: Translated string method in Jinja (#17174) --- erpnext/templates/pages/cart.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/templates/pages/cart.html b/erpnext/templates/pages/cart.html index fb0c05fcddb..04d737f0557 100644 --- a/erpnext/templates/pages/cart.html +++ b/erpnext/templates/pages/cart.html @@ -60,7 +60,7 @@ {{doc.terms}} {% endif %} From 17fbafa390b806b0053da1c713b07743033e956d Mon Sep 17 00:00:00 2001 From: Anurag Mishra Date: Tue, 9 Apr 2019 11:31:11 +0530 Subject: [PATCH 13/23] fix: filters,added total,only submitted doc,considered fraction --- erpnext/projects/report/billing_summary.py | 36 +++++++++++++++---- .../employee_billing_summary.js | 4 +-- .../project_billing_summary.js | 4 +-- 3 files changed, 34 insertions(+), 10 deletions(-) diff --git a/erpnext/projects/report/billing_summary.py b/erpnext/projects/report/billing_summary.py index 214dcef8fdb..e17a88951d4 100644 --- a/erpnext/projects/report/billing_summary.py +++ b/erpnext/projects/report/billing_summary.py @@ -31,20 +31,20 @@ def get_columns(): "width": 150 }, { - "label": _("Total Billable Hours"), - "fieldtype": "Int", + "label": _("Billable Hours"), + "fieldtype": "Float", "fieldname": "total_billable_hours", "width": 50 }, { - "label": _("Total Hours"), - "fieldtype": "Int", + "label": _("Working Hours"), + "fieldtype": "Float", "fieldname": "total_hours", "width": 50 }, { "label": _("Amount"), - "fieldtype": "Int", + "fieldtype": "Float", "fieldname": "amount", "width": 100 } @@ -54,12 +54,16 @@ def get_data(filters): data = [] record = get_records(filters) + billable_hours_worked = 0 + hours_worked = 0 + working_cost = 0 for entries in record: total_hours = 0 total_billable_hours = 0 total_amount = 0 entries_exists = False timesheet_details = get_timesheet_details(filters, entries.name) + for activity in timesheet_details: entries_exists = True time_start = activity.from_time @@ -70,13 +74,25 @@ def get_data(filters): if time_start <= from_date and time_end <= to_date: total_hours, total_billable_hours, total_amount = get_billable_and_total_hours(activity, time_end, from_date, total_hours, total_billable_hours, total_amount) + + billable_hours_worked += total_billable_hours + hours_worked += total_hours + working_cost += total_amount elif time_start >= from_date and time_end >= to_date: total_hours, total_billable_hours, total_amount = get_billable_and_total_hours(activity, to_date, time_start, total_hours, total_billable_hours, total_amount) + + billable_hours_worked += total_billable_hours + hours_worked += total_hours + working_cost += total_amount elif time_start >= from_date and time_end <= to_date: total_hours, total_billable_hours, total_amount = get_billable_and_total_hours(activity, time_end, time_start, total_hours, total_billable_hours, total_amount) + billable_hours_worked += total_billable_hours + hours_worked += total_hours + working_cost += total_amount + row = { "employee": entries.employee, "employee_name": entries.employee_name, @@ -90,12 +106,20 @@ def get_data(filters): data.append(row) entries_exists = False + total = { + "total_billable_hours": billable_hours_worked, + "total_hours": hours_worked, + "amount": working_cost + } + if billable_hours_worked !=0 or hours_worked !=0 or working_cost !=0: + data.append(total) return data def get_records(filters): record_filters = [ ["start_date", "<=", filters.to_date], - ["end_date", ">=", filters.from_date] + ["end_date", ">=", filters.from_date], + ["docstatus", "=", 1] ] if "employee" in filters: diff --git a/erpnext/projects/report/employee_billing_summary/employee_billing_summary.js b/erpnext/projects/report/employee_billing_summary/employee_billing_summary.js index 65c2a690cf2..87a043c80d5 100644 --- a/erpnext/projects/report/employee_billing_summary/employee_billing_summary.js +++ b/erpnext/projects/report/employee_billing_summary/employee_billing_summary.js @@ -15,14 +15,14 @@ frappe.query_reports["Employee Billing Summary"] = { fieldname:"from_date", label: __("From Date"), fieldtype: "Date", - default: frappe.datetime.get_today(), + default: frappe.datetime.add_months(frappe.datetime.month_start(), -1), reqd: 1 }, { fieldname:"to_date", label: __("To Date"), fieldtype: "Date", - default: frappe.datetime.add_days(frappe.datetime.get_today(), 30), + default: frappe.datetime.month_start(), reqd: 1 }, ] diff --git a/erpnext/projects/report/project_billing_summary/project_billing_summary.js b/erpnext/projects/report/project_billing_summary/project_billing_summary.js index 62362c35cff..614903c0329 100644 --- a/erpnext/projects/report/project_billing_summary/project_billing_summary.js +++ b/erpnext/projects/report/project_billing_summary/project_billing_summary.js @@ -15,14 +15,14 @@ frappe.query_reports["Project Billing Summary"] = { fieldname:"from_date", label: __("From Date"), fieldtype: "Date", - default: frappe.datetime.get_today(), + default: frappe.datetime.add_months(frappe.datetime.month_start(), -1), reqd: 1 }, { fieldname:"to_date", label: __("To Date"), fieldtype: "Date", - default: frappe.datetime.add_days(frappe.datetime.get_today(), 30), + default: frappe.datetime.month_start(), reqd: 1 }, ] From 3e8b8a4359415cc2741c1a37e5ece45fae5c27cd Mon Sep 17 00:00:00 2001 From: Anurag Mishra Date: Tue, 9 Apr 2019 14:34:56 +0530 Subject: [PATCH 14/23] fix: filters and some conditions --- erpnext/projects/report/billing_summary.py | 2 +- .../report/employee_billing_summary/employee_billing_summary.js | 2 +- .../report/project_billing_summary/project_billing_summary.js | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/erpnext/projects/report/billing_summary.py b/erpnext/projects/report/billing_summary.py index e17a88951d4..d6801c87c3c 100644 --- a/erpnext/projects/report/billing_summary.py +++ b/erpnext/projects/report/billing_summary.py @@ -71,7 +71,7 @@ def get_data(filters): from_date = frappe.utils.get_datetime(filters.from_date) to_date = frappe.utils.get_datetime(filters.to_date) - if time_start <= from_date and time_end <= to_date: + if time_start <= from_date and time_end >= from_date: total_hours, total_billable_hours, total_amount = get_billable_and_total_hours(activity, time_end, from_date, total_hours, total_billable_hours, total_amount) diff --git a/erpnext/projects/report/employee_billing_summary/employee_billing_summary.js b/erpnext/projects/report/employee_billing_summary/employee_billing_summary.js index 87a043c80d5..13f49ed6bed 100644 --- a/erpnext/projects/report/employee_billing_summary/employee_billing_summary.js +++ b/erpnext/projects/report/employee_billing_summary/employee_billing_summary.js @@ -22,7 +22,7 @@ frappe.query_reports["Employee Billing Summary"] = { fieldname:"to_date", label: __("To Date"), fieldtype: "Date", - default: frappe.datetime.month_start(), + default: frappe.datetime.add_days(frappe.datetime.month_start(), -1), reqd: 1 }, ] diff --git a/erpnext/projects/report/project_billing_summary/project_billing_summary.js b/erpnext/projects/report/project_billing_summary/project_billing_summary.js index 614903c0329..caac1d86b45 100644 --- a/erpnext/projects/report/project_billing_summary/project_billing_summary.js +++ b/erpnext/projects/report/project_billing_summary/project_billing_summary.js @@ -22,7 +22,7 @@ frappe.query_reports["Project Billing Summary"] = { fieldname:"to_date", label: __("To Date"), fieldtype: "Date", - default: frappe.datetime.month_start(), + default: frappe.datetime.add_days(frappe.datetime.month_start(),-1), reqd: 1 }, ] From 22867f7fa5ee6a3c9e3c1768ece6d2f14197e58f Mon Sep 17 00:00:00 2001 From: Anurag Mishra Date: Tue, 9 Apr 2019 15:06:49 +0530 Subject: [PATCH 15/23] fix: added currency --- erpnext/projects/report/billing_summary.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/projects/report/billing_summary.py b/erpnext/projects/report/billing_summary.py index d6801c87c3c..80bf926a54c 100644 --- a/erpnext/projects/report/billing_summary.py +++ b/erpnext/projects/report/billing_summary.py @@ -44,7 +44,7 @@ def get_columns(): }, { "label": _("Amount"), - "fieldtype": "Float", + "fieldtype": "Currency", "fieldname": "amount", "width": 100 } From b305f38869613e4034510023b8260548fff958fe Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Tue, 9 Apr 2019 20:06:11 +0530 Subject: [PATCH 16/23] fix: Made employee optional in sales person --- .../doctype/sales_person/sales_person.json | 21 ++++++++++++++++--- .../doctype/sales_person/sales_person.py | 21 +++++++++---------- 2 files changed, 28 insertions(+), 14 deletions(-) diff --git a/erpnext/setup/doctype/sales_person/sales_person.json b/erpnext/setup/doctype/sales_person/sales_person.json index 73f7623ba04..1c34657c54c 100644 --- a/erpnext/setup/doctype/sales_person/sales_person.json +++ b/erpnext/setup/doctype/sales_person/sales_person.json @@ -22,6 +22,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "name_and_employee_id", "fieldtype": "Section Break", "hidden": 0, @@ -54,6 +55,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "sales_person_name", "fieldtype": "Data", "hidden": 0, @@ -88,6 +90,7 @@ "collapsible": 0, "columns": 0, "description": "Select company name first.", + "fetch_if_empty": 0, "fieldname": "parent_sales_person", "fieldtype": "Link", "hidden": 0, @@ -122,6 +125,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "commission_rate", "fieldtype": "Data", "hidden": 0, @@ -154,6 +158,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "is_group", "fieldtype": "Check", "hidden": 0, @@ -189,6 +194,7 @@ "collapsible": 0, "columns": 0, "default": "1", + "fetch_if_empty": 0, "fieldname": "enabled", "fieldtype": "Check", "hidden": 0, @@ -221,6 +227,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "cb0", "fieldtype": "Column Break", "hidden": 0, @@ -251,6 +258,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "employee", "fieldtype": "Link", "hidden": 0, @@ -270,7 +278,7 @@ "read_only": 0, "remember_last_selected_value": 0, "report_hide": 0, - "reqd": 1, + "reqd": 0, "search_index": 0, "set_only_once": 0, "translatable": 0, @@ -284,6 +292,7 @@ "collapsible": 0, "columns": 0, "fetch_from": "employee.department", + "fetch_if_empty": 0, "fieldname": "department", "fieldtype": "Link", "hidden": 0, @@ -317,6 +326,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "lft", "fieldtype": "Int", "hidden": 1, @@ -350,6 +360,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "rgt", "fieldtype": "Int", "hidden": 1, @@ -383,6 +394,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "old_parent", "fieldtype": "Data", "hidden": 1, @@ -417,6 +429,7 @@ "collapsible": 0, "columns": 0, "description": "Set targets Item Group-wise for this Sales Person.", + "fetch_if_empty": 0, "fieldname": "target_details_section_break", "fieldtype": "Section Break", "hidden": 0, @@ -450,6 +463,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "targets", "fieldtype": "Table", "hidden": 0, @@ -485,6 +499,7 @@ "collapsible": 0, "columns": 0, "description": "Select Monthly Distribution to unevenly distribute targets across months.", + "fetch_if_empty": 0, "fieldname": "distribution_id", "fieldtype": "Link", "hidden": 0, @@ -524,7 +539,7 @@ "issingle": 0, "istable": 0, "max_attachments": 0, - "modified": "2019-01-30 11:28:16.966735", + "modified": "2019-04-09 20:03:35.967037", "modified_by": "Administrator", "module": "Setup", "name": "Sales Person", @@ -594,7 +609,7 @@ "search_fields": "parent_sales_person", "show_name_in_global_search": 1, "sort_order": "ASC", - "track_changes": 1, + "track_changes": 0, "track_seen": 0, "track_views": 0 } \ No newline at end of file diff --git a/erpnext/setup/doctype/sales_person/sales_person.py b/erpnext/setup/doctype/sales_person/sales_person.py index ab65f7455e2..3379534cf82 100644 --- a/erpnext/setup/doctype/sales_person/sales_person.py +++ b/erpnext/setup/doctype/sales_person/sales_person.py @@ -21,18 +21,18 @@ class SalesPerson(NestedSet): self.load_dashboard_info() def load_dashboard_info(self): - company_default_currency = get_default_currency() + company_default_currency = get_default_currency() allocated_amount = frappe.db.sql(""" select sum(allocated_amount) - from `tabSales Team` + from `tabSales Team` where sales_person = %s and docstatus=1 and parenttype = 'Sales Order' """,(self.sales_person_name)) info = {} info["allocated_amount"] = flt(allocated_amount[0][0]) if allocated_amount else 0 info["currency"] = company_default_currency - + self.set_onload('dashboard_info', info) def on_update(self): @@ -48,10 +48,11 @@ class SalesPerson(NestedSet): return frappe.db.get_value("User", user, "email") or user def validate_employee_id(self): - sales_person = frappe.db.get_value("Sales Person", {"employee": self.employee}) - - if sales_person and sales_person != self.name: - frappe.throw(_("Another Sales Person {0} exists with the same Employee id").format(sales_person)) + if self.employee: + sales_person = frappe.db.get_value("Sales Person", {"employee": self.employee}) + + if sales_person and sales_person != self.name: + frappe.throw(_("Another Sales Person {0} exists with the same Employee id").format(sales_person)) def on_doctype_update(): frappe.db.add_index("Sales Person", ["lft", "rgt"]) @@ -65,7 +66,7 @@ def get_timeline_data(doctype, name): from `tabSales Order` dt, `tabSales Team` st where - st.sales_person = %s and st.parent = dt.name and dt.transaction_date > date_sub(curdate(), interval 1 year) + st.sales_person = %s and st.parent = dt.name and dt.transaction_date > date_sub(curdate(), interval 1 year) group by dt.transaction_date ''', name))) sales_invoice = dict(frappe.db.sql('''select @@ -75,7 +76,7 @@ def get_timeline_data(doctype, name): where st.sales_person = %s and st.parent = dt.name and dt.posting_date > date_sub(curdate(), interval 1 year) group by dt.posting_date ''', name)) - + for key in sales_invoice: if out.get(key): out[key] += sales_invoice[key] @@ -97,5 +98,3 @@ def get_timeline_data(doctype, name): out[key] = delivery_note[key] return out - - From bb0d4e37b984f35d9e7c57a40a7666cd50048fa3 Mon Sep 17 00:00:00 2001 From: Rohit Waghchaure Date: Tue, 9 Apr 2019 23:41:33 +0530 Subject: [PATCH 17/23] fix: Asset depreciation formula for WDV method, user was not able to edit schedule table for Manula method --- erpnext/assets/doctype/asset/asset.js | 52 ++++++++++++-- erpnext/assets/doctype/asset/asset.py | 58 ++++++++++++---- .../asset_finance_book.json | 68 +++++++++++++++++-- 3 files changed, 154 insertions(+), 24 deletions(-) diff --git a/erpnext/assets/doctype/asset/asset.js b/erpnext/assets/doctype/asset/asset.js index ed02d87e446..5d15cab5a28 100644 --- a/erpnext/assets/doctype/asset/asset.js +++ b/erpnext/assets/doctype/asset/asset.js @@ -31,7 +31,7 @@ frappe.ui.form.on('Asset', { } }; }); - + frm.set_query("cost_center", function() { return { "filters": { @@ -206,12 +206,10 @@ frappe.ui.form.on('Asset', { erpnext.asset.set_accululated_depreciation(frm); }, - depreciation_method: function(frm) { - frm.events.make_schedules_editable(frm); - }, - make_schedules_editable: function(frm) { - var is_editable = frm.doc.depreciation_method==="Manual" ? true : false; + var is_editable = frm.doc.finance_books.filter(d => d.depreciation_method == "Manual").length > 0 + ? true : false; + frm.toggle_enable("schedules", is_editable); frm.fields_dict["schedules"].grid.toggle_enable("schedule_date", is_editable); frm.fields_dict["schedules"].grid.toggle_enable("depreciation_amount", is_editable); @@ -296,6 +294,48 @@ frappe.ui.form.on('Asset', { }) frm.toggle_reqd("finance_books", frm.doc.calculate_depreciation); + }, + + set_depreciation_rate: function(frm, row) { + if (row.total_number_of_depreciations && row.frequency_of_depreciation) { + frappe.call({ + method: "erpnext.assets.doctype.asset.asset.get_depreciation_rate", + args: { + args: row, + asset_cost: frm.doc.gross_purchase_amount, + number_of_depreciations_booked: frm.doc.is_existing_asset ? + frm.doc.number_of_depreciations_booked : 0 + }, + callback: function(r) { + if (r.message) { + frappe.model.set_value(row.doctype, row.name, "rate_of_depreciation", r.message); + } + } + }); + } + } +}); + +frappe.ui.form.on('Asset Finance Book', { + depreciation_method: function(frm, cdt, cdn) { + const row = locals[cdt][cdn]; + frm.events.set_depreciation_rate(frm, row); + frm.events.make_schedules_editable(frm); + }, + + expected_value_after_useful_life: function(frm, cdt, cdn) { + const row = locals[cdt][cdn]; + frm.events.set_depreciation_rate(frm, row); + }, + + frequency_of_depreciation: function(frm, cdt, cdn) { + const row = locals[cdt][cdn]; + frm.events.set_depreciation_rate(frm, row); + }, + + total_number_of_depreciations: function(frm, cdt, cdn) { + const row = locals[cdt][cdn]; + frm.events.set_depreciation_rate(frm, row); } }); diff --git a/erpnext/assets/doctype/asset/asset.py b/erpnext/assets/doctype/asset/asset.py index cfacb5ab494..b703bca7727 100644 --- a/erpnext/assets/doctype/asset/asset.py +++ b/erpnext/assets/doctype/asset/asset.py @@ -3,8 +3,9 @@ # For license information, please see license.txt from __future__ import unicode_literals -import frappe, erpnext +import frappe, erpnext, math, json from frappe import _ +from six import string_types from frappe.utils import flt, add_months, cint, nowdate, getdate, today, date_diff from frappe.model.document import Document from erpnext.assets.doctype.asset_category.asset_category import get_asset_category_account @@ -20,6 +21,7 @@ class Asset(AccountsController): self.validate_item() self.set_missing_values() if self.calculate_depreciation: + self.set_depreciation_rate() self.make_depreciation_schedule() self.set_accumulated_depreciation() else: @@ -89,17 +91,24 @@ class Asset(AccountsController): if self.is_existing_asset: return - date = nowdate() docname = self.purchase_receipt or self.purchase_invoice if docname: doctype = 'Purchase Receipt' if self.purchase_receipt else 'Purchase Invoice' date = frappe.db.get_value(doctype, docname, 'posting_date') - if self.available_for_use_date and getdate(self.available_for_use_date) < getdate(date): + if self.available_for_use_date and getdate(self.available_for_use_date) < getdate(self.purchase_date): frappe.throw(_("Available-for-use Date should be after purchase date")) + def set_depreciation_rate(self): + for d in self.get("finance_books"): + if not d.rate_of_depreciation: + d.rate_of_depreciation = get_depreciation_rate(d, self.gross_purchase_amount, + self.number_of_depreciations_booked) + def make_depreciation_schedule(self): - if self.depreciation_method != 'Manual': + depreciation_method = [d.depreciation_method for d in self.finance_books] + + if 'Manual' not in depreciation_method: self.schedules = [] if not self.get("schedules") and self.available_for_use_date: @@ -254,14 +263,16 @@ class Asset(AccountsController): return flt(self.get('finance_books')[cint(idx)-1].value_after_depreciation) def get_depreciation_amount(self, depreciable_value, total_number_of_depreciations, row): - percentage_value = 100.0 if row.depreciation_method == 'Written Down Value' else 200.0 + if row.depreciation_method in ["Straight Line", "Manual"]: + amt = (flt(self.gross_purchase_amount) - flt(row.expected_value_after_useful_life) - + flt(self.opening_accumulated_depreciation)) - factor = percentage_value / cint(total_number_of_depreciations) - depreciation_amount = flt(depreciable_value * factor / 100, 0) - - value_after_depreciation = flt(depreciable_value) - depreciation_amount - if value_after_depreciation < flt(row.expected_value_after_useful_life): - depreciation_amount = flt(depreciable_value) - flt(row.expected_value_after_useful_life) + depreciation_amount = amt * row.rate_of_depreciation + else: + depreciation_amount = flt(depreciable_value) * (flt(row.rate_of_depreciation) / 100) + value_after_depreciation = flt(depreciable_value) - depreciation_amount + if value_after_depreciation < flt(row.expected_value_after_useful_life): + depreciation_amount = flt(depreciable_value) - flt(row.expected_value_after_useful_life) return depreciation_amount @@ -480,7 +491,6 @@ def create_asset_adjustment(asset, asset_category, company): @frappe.whitelist() def transfer_asset(args): - import json args = json.loads(args) if args.get('serial_no'): @@ -557,4 +567,26 @@ def make_journal_entry(asset_name): return je def is_cwip_accounting_disabled(): - return cint(frappe.db.get_single_value("Asset Settings", "disable_cwip_accounting")) \ No newline at end of file + return cint(frappe.db.get_single_value("Asset Settings", "disable_cwip_accounting")) + +@frappe.whitelist() +def get_depreciation_rate(args, asset_cost, number_of_depreciations_booked=0): + if isinstance(args, string_types): + args = json.loads(args) + + float_precision = cint(frappe.db.get_default("float_precision")) or 2 + + if args.get("depreciation_method") == 'Double Declining Balance': + return 200.0 / flt(args.get("total_number_of_depreciations")) + + if args.get("depreciation_method") in ["Straight Line", "Manual"]: + return 1.0 / (flt(args.get("total_number_of_depreciations")) - flt(number_of_depreciations_booked)) + + if args.get("depreciation_method") == "Written Down Value": + no_of_years = flt(flt(args.get("total_number_of_depreciations")) * flt(args.get("frequency_of_depreciation"))) / 12 + value = flt(args.get("expected_value_after_useful_life")) / flt(asset_cost) + + # square root of flt(salvage_value) / flt(asset_cost) + depreciation_rate = math.pow(value, 1.0/flt(no_of_years, 2)) + + return 100 * (1 - flt(depreciation_rate, float_precision)) \ No newline at end of file diff --git a/erpnext/assets/doctype/asset_finance_book/asset_finance_book.json b/erpnext/assets/doctype/asset_finance_book/asset_finance_book.json index f75c8510dcb..c80f95e1555 100644 --- a/erpnext/assets/doctype/asset_finance_book/asset_finance_book.json +++ b/erpnext/assets/doctype/asset_finance_book/asset_finance_book.json @@ -1,5 +1,6 @@ { "allow_copy": 0, + "allow_events_in_timeline": 0, "allow_guest_to_view": 0, "allow_import": 0, "allow_rename": 0, @@ -14,11 +15,13 @@ "fields": [ { "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, "columns": 0, "depends_on": "", + "fetch_if_empty": 0, "fieldname": "finance_book", "fieldtype": "Link", "hidden": 0, @@ -42,14 +45,17 @@ "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": "depreciation_method", "fieldtype": "Select", "hidden": 0, @@ -73,14 +79,17 @@ "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, + "fetch_if_empty": 0, "fieldname": "total_number_of_depreciations", "fieldtype": "Int", "hidden": 0, @@ -103,14 +112,17 @@ "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, + "fetch_if_empty": 0, "fieldname": "column_break_5", "fieldtype": "Column Break", "hidden": 0, @@ -133,14 +145,17 @@ "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": "frequency_of_depreciation", "fieldtype": "Int", "hidden": 0, @@ -163,15 +178,18 @@ "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, "depends_on": "eval:parent.doctype == 'Asset'", + "fetch_if_empty": 0, "fieldname": "depreciation_start_date", "fieldtype": "Date", "hidden": 0, @@ -194,16 +212,19 @@ "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": "0", "depends_on": "eval:parent.doctype == 'Asset'", + "fetch_if_empty": 0, "fieldname": "expected_value_after_useful_life", "fieldtype": "Currency", "hidden": 0, @@ -227,14 +248,17 @@ "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": "value_after_depreciation", "fieldtype": "Currency", "hidden": 1, @@ -258,20 +282,54 @@ "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.depreciation_method == 'Written Down Value'", + "description": "In Percentage", + "fetch_if_empty": 0, + "fieldname": "rate_of_depreciation", + "fieldtype": "Percent", + "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": "Rate of Depreciation", + "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 } ], "has_web_view": 0, - "hide_heading": 0, "hide_toolbar": 0, "idx": 0, - "image_view": 0, "in_create": 0, "is_submittable": 0, "issingle": 0, "istable": 1, "max_attachments": 0, - "modified": "2018-05-12 14:56:44.800046", + "modified": "2019-04-09 19:45:14.523488", "modified_by": "Administrator", "module": "Assets", "name": "Asset Finance Book", @@ -280,10 +338,10 @@ "permissions": [], "quick_entry": 1, "read_only": 0, - "read_only_onload": 0, "show_name_in_global_search": 0, "sort_field": "modified", "sort_order": "DESC", "track_changes": 1, - "track_seen": 0 + "track_seen": 0, + "track_views": 0 } \ No newline at end of file From c8c678f7474daca8f2247ccaf7824e3ccea15c91 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Wed, 10 Apr 2019 15:56:16 +0530 Subject: [PATCH 18/23] fix: training feedback code cleanup --- erpnext/hr/doctype/training_feedback/training_feedback.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/erpnext/hr/doctype/training_feedback/training_feedback.py b/erpnext/hr/doctype/training_feedback/training_feedback.py index b7eae38ae48..b47e2b4be88 100644 --- a/erpnext/hr/doctype/training_feedback/training_feedback.py +++ b/erpnext/hr/doctype/training_feedback/training_feedback.py @@ -15,9 +15,11 @@ class TrainingFeedback(Document): def on_submit(self): training_event = frappe.get_doc("Training Event", self.training_event) + status = None for e in training_event.employees: if e.employee == self.employee: - training_event.status = 'Feedback Submitted' + status = 'Feedback Submitted' break - training_event.save() + if status: + frappe.db.set_value("Training Event", self.training_event, "status", status) From b286fc99b854bbe45034ffe19e8641c88a397653 Mon Sep 17 00:00:00 2001 From: Rohit Waghchaure Date: Wed, 10 Apr 2019 16:16:30 +0530 Subject: [PATCH 19/23] fix: don't assign the advance payment entries if Allocate Advances Automatically is disabled --- .../purchase_invoice/purchase_invoice.json | 146 ++++++++++++++- .../doctype/sales_invoice/sales_invoice.json | 174 +++++++++++++++++- .../doctype/purchase_order/purchase_order.py | 4 +- .../doctype/sales_order/sales_order.py | 3 +- 4 files changed, 323 insertions(+), 4 deletions(-) diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json index 41b3c13a3b9..9ee9c1ecc86 100755 --- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json +++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json @@ -21,6 +21,7 @@ "collapsible": 0, "columns": 0, "default": "{supplier_name}", + "fetch_if_empty": 0, "fieldname": "title", "fieldtype": "Data", "hidden": 1, @@ -54,6 +55,7 @@ "collapsible": 0, "columns": 0, "default": "", + "fetch_if_empty": 0, "fieldname": "naming_series", "fieldtype": "Select", "hidden": 0, @@ -88,6 +90,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "supplier", "fieldtype": "Link", "hidden": 0, @@ -124,6 +127,7 @@ "columns": 0, "depends_on": "supplier", "fetch_from": "supplier.supplier_name", + "fetch_if_empty": 0, "fieldname": "supplier_name", "fieldtype": "Data", "hidden": 0, @@ -159,6 +163,7 @@ "collapsible": 0, "columns": 0, "fetch_from": "supplier.tax_id", + "fetch_if_empty": 0, "fieldname": "tax_id", "fieldtype": "Read Only", "hidden": 0, @@ -192,6 +197,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "due_date", "fieldtype": "Date", "hidden": 0, @@ -225,6 +231,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "is_paid", "fieldtype": "Check", "hidden": 0, @@ -258,6 +265,7 @@ "collapsible": 0, "columns": 0, "default": "0", + "fetch_if_empty": 0, "fieldname": "is_return", "fieldtype": "Check", "hidden": 0, @@ -291,6 +299,7 @@ "collapsible": 0, "columns": 0, "default": "", + "fetch_if_empty": 0, "fieldname": "apply_tds", "fieldtype": "Check", "hidden": 0, @@ -323,6 +332,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "column_break1", "fieldtype": "Column Break", "hidden": 0, @@ -355,6 +365,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "company", "fieldtype": "Link", "hidden": 0, @@ -387,6 +398,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "cost_center", "fieldtype": "Link", "hidden": 0, @@ -421,6 +433,7 @@ "collapsible": 0, "columns": 0, "default": "Today", + "fetch_if_empty": 0, "fieldname": "posting_date", "fieldtype": "Date", "hidden": 0, @@ -454,6 +467,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "posting_time", "fieldtype": "Time", "hidden": 0, @@ -489,6 +503,7 @@ "collapsible": 0, "columns": 0, "depends_on": "eval:doc.docstatus==0", + "fetch_if_empty": 0, "fieldname": "set_posting_time", "fieldtype": "Check", "hidden": 0, @@ -521,6 +536,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "amended_from", "fieldtype": "Link", "hidden": 0, @@ -556,6 +572,7 @@ "collapsible": 1, "collapsible_depends_on": "eval:doc.on_hold", "columns": 0, + "fetch_if_empty": 0, "fieldname": "sb_14", "fieldtype": "Section Break", "hidden": 0, @@ -589,6 +606,7 @@ "collapsible": 0, "columns": 0, "default": "0", + "fetch_if_empty": 0, "fieldname": "on_hold", "fieldtype": "Check", "hidden": 0, @@ -623,6 +641,7 @@ "columns": 0, "depends_on": "eval:doc.on_hold", "description": "Once set, this invoice will be on hold till the set date", + "fetch_if_empty": 0, "fieldname": "release_date", "fieldtype": "Date", "hidden": 0, @@ -655,6 +674,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "cb_17", "fieldtype": "Column Break", "hidden": 0, @@ -687,6 +707,7 @@ "collapsible": 0, "columns": 0, "depends_on": "eval:doc.on_hold", + "fetch_if_empty": 0, "fieldname": "hold_comment", "fieldtype": "Small Text", "hidden": 0, @@ -720,6 +741,7 @@ "collapsible": 1, "collapsible_depends_on": "bill_no", "columns": 0, + "fetch_if_empty": 0, "fieldname": "supplier_invoice_details", "fieldtype": "Section Break", "hidden": 0, @@ -753,6 +775,7 @@ "collapsible": 0, "columns": 0, "description": "", + "fetch_if_empty": 0, "fieldname": "bill_no", "fieldtype": "Data", "hidden": 0, @@ -786,6 +809,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "column_break_15", "fieldtype": "Column Break", "hidden": 0, @@ -817,6 +841,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "bill_date", "fieldtype": "Date", "hidden": 0, @@ -851,6 +876,7 @@ "collapsible": 0, "columns": 0, "depends_on": "return_against", + "fetch_if_empty": 0, "fieldname": "returns", "fieldtype": "Section Break", "hidden": 0, @@ -884,6 +910,7 @@ "collapsible": 0, "columns": 0, "depends_on": "return_against", + "fetch_if_empty": 0, "fieldname": "return_against", "fieldtype": "Link", "hidden": 0, @@ -917,6 +944,7 @@ "bold": 0, "collapsible": 1, "columns": 0, + "fetch_if_empty": 0, "fieldname": "section_addresses", "fieldtype": "Section Break", "hidden": 0, @@ -949,6 +977,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "supplier_address", "fieldtype": "Link", "hidden": 0, @@ -982,6 +1011,7 @@ "collapsible": 0, "columns": 0, "depends_on": "", + "fetch_if_empty": 0, "fieldname": "address_display", "fieldtype": "Small Text", "hidden": 0, @@ -1013,6 +1043,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "contact_person", "fieldtype": "Link", "hidden": 0, @@ -1045,6 +1076,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "contact_display", "fieldtype": "Small Text", "hidden": 0, @@ -1076,6 +1108,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "contact_mobile", "fieldtype": "Small Text", "hidden": 0, @@ -1107,6 +1140,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "contact_email", "fieldtype": "Small Text", "hidden": 0, @@ -1138,6 +1172,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "col_break_address", "fieldtype": "Column Break", "hidden": 0, @@ -1170,6 +1205,7 @@ "collapsible": 0, "columns": 0, "depends_on": "", + "fetch_if_empty": 0, "fieldname": "shipping_address", "fieldtype": "Link", "hidden": 0, @@ -1203,6 +1239,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "shipping_address_display", "fieldtype": "Small Text", "hidden": 0, @@ -1235,6 +1272,7 @@ "bold": 0, "collapsible": 1, "columns": 0, + "fetch_if_empty": 0, "fieldname": "currency_and_price_list", "fieldtype": "Section Break", "hidden": 0, @@ -1267,6 +1305,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "currency", "fieldtype": "Link", "hidden": 0, @@ -1302,6 +1341,7 @@ "collapsible": 0, "columns": 0, "description": "", + "fetch_if_empty": 0, "fieldname": "conversion_rate", "fieldtype": "Float", "hidden": 0, @@ -1336,6 +1376,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "column_break2", "fieldtype": "Column Break", "hidden": 0, @@ -1366,6 +1407,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "buying_price_list", "fieldtype": "Link", "hidden": 0, @@ -1398,6 +1440,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "price_list_currency", "fieldtype": "Link", "hidden": 0, @@ -1430,6 +1473,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "plc_conversion_rate", "fieldtype": "Float", "hidden": 0, @@ -1462,6 +1506,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "ignore_pricing_rule", "fieldtype": "Check", "hidden": 0, @@ -1493,6 +1538,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "sec_warehouse", "fieldtype": "Section Break", "hidden": 0, @@ -1525,6 +1571,7 @@ "collapsible": 0, "columns": 0, "depends_on": "update_stock", + "fetch_if_empty": 0, "fieldname": "set_warehouse", "fieldtype": "Link", "hidden": 0, @@ -1560,6 +1607,7 @@ "columns": 0, "depends_on": "update_stock", "description": "Warehouse where you are maintaining stock of rejected items", + "fetch_if_empty": 0, "fieldname": "rejected_warehouse", "fieldtype": "Link", "hidden": 0, @@ -1593,6 +1641,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "col_break_warehouse", "fieldtype": "Column Break", "hidden": 0, @@ -1625,6 +1674,7 @@ "collapsible": 0, "columns": 0, "default": "No", + "fetch_if_empty": 0, "fieldname": "is_subcontracted", "fieldtype": "Select", "hidden": 0, @@ -1659,6 +1709,7 @@ "collapsible": 0, "columns": 0, "depends_on": "eval:doc.is_subcontracted==\"Yes\"", + "fetch_if_empty": 0, "fieldname": "supplier_warehouse", "fieldtype": "Link", "hidden": 0, @@ -1694,6 +1745,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "items_section", "fieldtype": "Section Break", "hidden": 0, @@ -1728,6 +1780,7 @@ "collapsible": 0, "columns": 0, "default": "0", + "fetch_if_empty": 0, "fieldname": "update_stock", "fieldtype": "Check", "hidden": 0, @@ -1760,6 +1813,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "scan_barcode", "fieldtype": "Data", "hidden": 0, @@ -1792,6 +1846,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "items", "fieldtype": "Table", "hidden": 0, @@ -1828,6 +1883,7 @@ "collapsible_depends_on": "supplied_items", "columns": 0, "depends_on": "", + "fetch_if_empty": 0, "fieldname": "raw_materials_supplied", "fieldtype": "Section Break", "hidden": 0, @@ -1860,6 +1916,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "supplied_items", "fieldtype": "Table", "hidden": 0, @@ -1893,6 +1950,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "section_break_26", "fieldtype": "Section Break", "hidden": 0, @@ -1923,6 +1981,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "total_qty", "fieldtype": "Float", "hidden": 0, @@ -1955,6 +2014,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "base_total", "fieldtype": "Currency", "hidden": 0, @@ -1989,6 +2049,7 @@ "collapsible": 0, "columns": 0, "description": "", + "fetch_if_empty": 0, "fieldname": "base_net_total", "fieldtype": "Currency", "hidden": 0, @@ -2023,6 +2084,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "column_break_28", "fieldtype": "Column Break", "hidden": 0, @@ -2053,6 +2115,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "total", "fieldtype": "Currency", "hidden": 0, @@ -2086,6 +2149,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "net_total", "fieldtype": "Currency", "hidden": 0, @@ -2120,6 +2184,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "total_net_weight", "fieldtype": "Float", "hidden": 0, @@ -2152,6 +2217,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "taxes_section", "fieldtype": "Section Break", "hidden": 0, @@ -2185,6 +2251,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "taxes_and_charges", "fieldtype": "Link", "hidden": 0, @@ -2219,6 +2286,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "column_break_49", "fieldtype": "Column Break", "hidden": 0, @@ -2250,6 +2318,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "shipping_rule", "fieldtype": "Link", "hidden": 0, @@ -2283,6 +2352,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "section_break_51", "fieldtype": "Section Break", "hidden": 0, @@ -2314,6 +2384,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "taxes", "fieldtype": "Table", "hidden": 0, @@ -2348,6 +2419,7 @@ "bold": 0, "collapsible": 1, "columns": 0, + "fetch_if_empty": 0, "fieldname": "sec_tax_breakup", "fieldtype": "Section Break", "hidden": 0, @@ -2380,6 +2452,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "other_charges_calculation", "fieldtype": "Text", "hidden": 0, @@ -2412,6 +2485,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "totals", "fieldtype": "Section Break", "hidden": 0, @@ -2445,6 +2519,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "base_taxes_and_charges_added", "fieldtype": "Currency", "hidden": 0, @@ -2479,6 +2554,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "base_taxes_and_charges_deducted", "fieldtype": "Currency", "hidden": 0, @@ -2513,6 +2589,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "base_total_taxes_and_charges", "fieldtype": "Currency", "hidden": 0, @@ -2547,6 +2624,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "column_break_40", "fieldtype": "Column Break", "hidden": 0, @@ -2578,6 +2656,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "taxes_and_charges_added", "fieldtype": "Currency", "hidden": 0, @@ -2612,6 +2691,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "taxes_and_charges_deducted", "fieldtype": "Currency", "hidden": 0, @@ -2646,6 +2726,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "total_taxes_and_charges", "fieldtype": "Currency", "hidden": 0, @@ -2680,6 +2761,7 @@ "collapsible": 1, "collapsible_depends_on": "discount_amount", "columns": 0, + "fetch_if_empty": 0, "fieldname": "section_break_44", "fieldtype": "Section Break", "hidden": 0, @@ -2713,6 +2795,7 @@ "collapsible": 0, "columns": 0, "default": "Grand Total", + "fetch_if_empty": 0, "fieldname": "apply_discount_on", "fieldtype": "Select", "hidden": 0, @@ -2746,6 +2829,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "base_discount_amount", "fieldtype": "Currency", "hidden": 0, @@ -2779,6 +2863,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "column_break_46", "fieldtype": "Column Break", "hidden": 0, @@ -2810,6 +2895,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "additional_discount_percentage", "fieldtype": "Float", "hidden": 0, @@ -2842,6 +2928,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "discount_amount", "fieldtype": "Currency", "hidden": 0, @@ -2875,6 +2962,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "section_break_49", "fieldtype": "Section Break", "hidden": 0, @@ -2906,6 +2994,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "base_grand_total", "fieldtype": "Currency", "hidden": 0, @@ -2940,6 +3029,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "base_rounding_adjustment", "fieldtype": "Currency", "hidden": 0, @@ -2974,6 +3064,7 @@ "collapsible": 0, "columns": 0, "depends_on": "eval:!doc.disable_rounded_total", + "fetch_if_empty": 0, "fieldname": "base_rounded_total", "fieldtype": "Currency", "hidden": 0, @@ -3008,6 +3099,7 @@ "collapsible": 0, "columns": 0, "description": "", + "fetch_if_empty": 0, "fieldname": "base_in_words", "fieldtype": "Data", "hidden": 0, @@ -3041,6 +3133,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "column_break8", "fieldtype": "Column Break", "hidden": 0, @@ -3073,6 +3166,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "grand_total", "fieldtype": "Currency", "hidden": 0, @@ -3107,6 +3201,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "rounding_adjustment", "fieldtype": "Currency", "hidden": 0, @@ -3141,6 +3236,7 @@ "collapsible": 0, "columns": 0, "depends_on": "eval:!doc.disable_rounded_total", + "fetch_if_empty": 0, "fieldname": "rounded_total", "fieldtype": "Currency", "hidden": 0, @@ -3174,6 +3270,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "in_words", "fieldtype": "Data", "hidden": 0, @@ -3207,6 +3304,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "total_advance", "fieldtype": "Currency", "hidden": 0, @@ -3241,6 +3339,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "outstanding_amount", "fieldtype": "Currency", "hidden": 0, @@ -3276,6 +3375,7 @@ "collapsible": 0, "columns": 0, "depends_on": "grand_total", + "fetch_if_empty": 0, "fieldname": "disable_rounded_total", "fieldtype": "Check", "hidden": 0, @@ -3310,6 +3410,7 @@ "collapsible_depends_on": "paid_amount", "columns": 0, "depends_on": "eval:doc.is_paid===1||(doc.advances && doc.advances.length>0)", + "fetch_if_empty": 0, "fieldname": "payments_section", "fieldtype": "Section Break", "hidden": 0, @@ -3342,6 +3443,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "mode_of_payment", "fieldtype": "Link", "hidden": 0, @@ -3375,6 +3477,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "cash_bank_account", "fieldtype": "Link", "hidden": 0, @@ -3408,6 +3511,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "col_br_payments", "fieldtype": "Column Break", "hidden": 0, @@ -3440,6 +3544,7 @@ "collapsible": 0, "columns": 0, "depends_on": "is_paid", + "fetch_if_empty": 0, "fieldname": "paid_amount", "fieldtype": "Currency", "hidden": 0, @@ -3473,6 +3578,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "base_paid_amount", "fieldtype": "Currency", "hidden": 0, @@ -3508,6 +3614,7 @@ "collapsible_depends_on": "write_off_amount", "columns": 0, "depends_on": "grand_total", + "fetch_if_empty": 0, "fieldname": "write_off", "fieldtype": "Section Break", "hidden": 0, @@ -3540,6 +3647,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "write_off_amount", "fieldtype": "Currency", "hidden": 0, @@ -3572,6 +3680,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "base_write_off_amount", "fieldtype": "Currency", "hidden": 0, @@ -3605,6 +3714,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "column_break_61", "fieldtype": "Column Break", "hidden": 0, @@ -3637,6 +3747,7 @@ "collapsible": 0, "columns": 0, "depends_on": "eval:flt(doc.write_off_amount)!=0", + "fetch_if_empty": 0, "fieldname": "write_off_account", "fieldtype": "Link", "hidden": 0, @@ -3670,6 +3781,7 @@ "collapsible": 0, "columns": 0, "depends_on": "eval:flt(doc.write_off_amount)!=0", + "fetch_if_empty": 0, "fieldname": "write_off_cost_center", "fieldtype": "Link", "hidden": 0, @@ -3703,6 +3815,7 @@ "collapsible": 1, "collapsible_depends_on": "advances", "columns": 0, + "fetch_if_empty": 0, "fieldname": "advances_section", "fieldtype": "Section Break", "hidden": 0, @@ -3736,6 +3849,8 @@ "bold": 0, "collapsible": 0, "columns": 0, + "default": "1", + "fetch_if_empty": 0, "fieldname": "allocate_advances_automatically", "fieldtype": "Check", "hidden": 0, @@ -3769,6 +3884,7 @@ "collapsible": 0, "columns": 0, "depends_on": "eval:!doc.allocate_advances_automatically", + "fetch_if_empty": 0, "fieldname": "get_advances", "fieldtype": "Button", "hidden": 0, @@ -3802,6 +3918,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "advances", "fieldtype": "Table", "hidden": 0, @@ -3837,6 +3954,7 @@ "collapsible": 1, "collapsible_depends_on": "eval:(!doc.is_return)", "columns": 0, + "fetch_if_empty": 0, "fieldname": "payment_schedule_section", "fieldtype": "Section Break", "hidden": 0, @@ -3869,6 +3987,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "payment_terms_template", "fieldtype": "Link", "hidden": 0, @@ -3902,6 +4021,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "payment_schedule", "fieldtype": "Table", "hidden": 0, @@ -3936,6 +4056,7 @@ "collapsible": 1, "collapsible_depends_on": "terms", "columns": 0, + "fetch_if_empty": 0, "fieldname": "terms_section_break", "fieldtype": "Section Break", "hidden": 0, @@ -3968,6 +4089,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "tc_name", "fieldtype": "Link", "hidden": 0, @@ -4000,6 +4122,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "terms", "fieldtype": "Text Editor", "hidden": 0, @@ -4031,6 +4154,7 @@ "bold": 0, "collapsible": 1, "columns": 0, + "fetch_if_empty": 0, "fieldname": "printing_settings", "fieldtype": "Section Break", "hidden": 0, @@ -4063,6 +4187,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "letter_head", "fieldtype": "Link", "hidden": 0, @@ -4096,6 +4221,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "group_same_items", "fieldtype": "Check", "hidden": 0, @@ -4128,6 +4254,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "column_break_112", "fieldtype": "Column Break", "hidden": 0, @@ -4159,6 +4286,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "select_print_heading", "fieldtype": "Link", "hidden": 0, @@ -4193,6 +4321,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "language", "fieldtype": "Data", "hidden": 0, @@ -4225,6 +4354,7 @@ "bold": 0, "collapsible": 1, "columns": 0, + "fetch_if_empty": 0, "fieldname": "more_info", "fieldtype": "Section Break", "hidden": 0, @@ -4259,6 +4389,7 @@ "collapsible": 0, "columns": 0, "description": "", + "fetch_if_empty": 0, "fieldname": "credit_to", "fieldtype": "Link", "hidden": 0, @@ -4293,6 +4424,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "party_account_currency", "fieldtype": "Link", "hidden": 1, @@ -4328,6 +4460,7 @@ "columns": 0, "default": "No", "description": "", + "fetch_if_empty": 0, "fieldname": "is_opening", "fieldtype": "Select", "hidden": 0, @@ -4362,6 +4495,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "against_expense_account", "fieldtype": "Small Text", "hidden": 1, @@ -4395,6 +4529,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "column_break_63", "fieldtype": "Column Break", "hidden": 0, @@ -4426,6 +4561,7 @@ "collapsible": 0, "columns": 0, "default": "Draft", + "fetch_if_empty": 0, "fieldname": "status", "fieldtype": "Select", "hidden": 0, @@ -4459,6 +4595,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "inter_company_invoice_reference", "fieldtype": "Link", "hidden": 0, @@ -4492,6 +4629,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "remarks", "fieldtype": "Small Text", "hidden": 0, @@ -4525,6 +4663,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "subscription_section", "fieldtype": "Section Break", "hidden": 0, @@ -4559,6 +4698,7 @@ "columns": 0, "depends_on": "", "description": "Start date of current invoice's period", + "fetch_if_empty": 0, "fieldname": "from_date", "fieldtype": "Date", "hidden": 0, @@ -4592,6 +4732,7 @@ "columns": 0, "depends_on": "", "description": "End date of current invoice's period", + "fetch_if_empty": 0, "fieldname": "to_date", "fieldtype": "Date", "hidden": 0, @@ -4623,6 +4764,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "column_break_114", "fieldtype": "Column Break", "hidden": 0, @@ -4654,6 +4796,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "auto_repeat", "fieldtype": "Link", "hidden": 0, @@ -4688,6 +4831,7 @@ "collapsible": 0, "columns": 0, "depends_on": "eval: doc.auto_repeat", + "fetch_if_empty": 0, "fieldname": "update_auto_repeat_reference", "fieldtype": "Button", "hidden": 0, @@ -4726,7 +4870,7 @@ "istable": 0, "max_attachments": 0, "menu_index": 0, - "modified": "2019-01-07 16:51:59.800081", + "modified": "2019-04-10 16:08:22.288425", "modified_by": "Administrator", "module": "Accounts", "name": "Purchase Invoice", diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.json b/erpnext/accounts/doctype/sales_invoice/sales_invoice.json index 077d99512ac..7f7e6f981a9 100644 --- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.json +++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.json @@ -22,6 +22,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "customer_section", "fieldtype": "Section Break", "hidden": 0, @@ -55,6 +56,7 @@ "collapsible": 0, "columns": 0, "default": "{customer_name}", + "fetch_if_empty": 0, "fieldname": "title", "fieldtype": "Data", "hidden": 1, @@ -88,6 +90,7 @@ "collapsible": 0, "columns": 0, "default": "", + "fetch_if_empty": 0, "fieldname": "naming_series", "fieldtype": "Select", "hidden": 0, @@ -122,6 +125,7 @@ "bold": 1, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "customer", "fieldtype": "Link", "hidden": 0, @@ -158,6 +162,7 @@ "columns": 0, "depends_on": "customer", "fetch_from": "customer.customer_name", + "fetch_if_empty": 0, "fieldname": "customer_name", "fieldtype": "Data", "hidden": 0, @@ -192,6 +197,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "tax_id", "fieldtype": "Data", "hidden": 0, @@ -224,6 +230,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "project", "fieldtype": "Link", "hidden": 0, @@ -258,6 +265,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "is_pos", "fieldtype": "Check", "hidden": 0, @@ -292,6 +300,7 @@ "collapsible": 0, "columns": 0, "depends_on": "is_pos", + "fetch_if_empty": 0, "fieldname": "pos_profile", "fieldtype": "Link", "hidden": 0, @@ -325,6 +334,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "offline_pos_name", "fieldtype": "Data", "hidden": 1, @@ -358,6 +368,7 @@ "collapsible": 0, "columns": 0, "depends_on": "", + "fetch_if_empty": 0, "fieldname": "is_return", "fieldtype": "Check", "hidden": 0, @@ -390,6 +401,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "column_break1", "fieldtype": "Column Break", "hidden": 0, @@ -421,6 +433,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "company", "fieldtype": "Link", "hidden": 0, @@ -455,6 +468,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "cost_center", "fieldtype": "Link", "hidden": 0, @@ -489,6 +503,7 @@ "collapsible": 0, "columns": 0, "default": "Today", + "fetch_if_empty": 0, "fieldname": "posting_date", "fieldtype": "Date", "hidden": 0, @@ -522,6 +537,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "posting_time", "fieldtype": "Time", "hidden": 0, @@ -556,6 +572,7 @@ "collapsible": 0, "columns": 0, "depends_on": "eval:doc.docstatus==0", + "fetch_if_empty": 0, "fieldname": "set_posting_time", "fieldtype": "Check", "hidden": 0, @@ -588,6 +605,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "due_date", "fieldtype": "Date", "hidden": 0, @@ -621,6 +639,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "amended_from", "fieldtype": "Link", "hidden": 0, @@ -656,6 +675,7 @@ "collapsible": 0, "columns": 0, "depends_on": "return_against", + "fetch_if_empty": 0, "fieldname": "returns", "fieldtype": "Section Break", "hidden": 0, @@ -689,6 +709,7 @@ "collapsible": 0, "columns": 0, "depends_on": "return_against", + "fetch_if_empty": 0, "fieldname": "return_against", "fieldtype": "Link", "hidden": 0, @@ -722,6 +743,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "column_break_21", "fieldtype": "Column Break", "hidden": 0, @@ -754,6 +776,7 @@ "collapsible": 0, "columns": 0, "depends_on": "eval: doc.is_return && doc.return_against", + "fetch_if_empty": 0, "fieldname": "update_billed_amount_in_sales_order", "fieldtype": "Check", "hidden": 0, @@ -787,6 +810,7 @@ "collapsible": 1, "collapsible_depends_on": "po_no", "columns": 0, + "fetch_if_empty": 0, "fieldname": "customer_po_details", "fieldtype": "Section Break", "hidden": 0, @@ -819,6 +843,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "po_no", "fieldtype": "Data", "hidden": 0, @@ -851,6 +876,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "column_break_23", "fieldtype": "Column Break", "hidden": 0, @@ -882,6 +908,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "po_date", "fieldtype": "Date", "hidden": 0, @@ -915,6 +942,7 @@ "collapsible": 1, "columns": 0, "depends_on": "", + "fetch_if_empty": 0, "fieldname": "address_and_contact", "fieldtype": "Section Break", "hidden": 0, @@ -947,6 +975,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "customer_address", "fieldtype": "Link", "hidden": 0, @@ -979,6 +1008,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "address_display", "fieldtype": "Small Text", "hidden": 0, @@ -1010,6 +1040,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "contact_person", "fieldtype": "Link", "hidden": 0, @@ -1042,6 +1073,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "contact_display", "fieldtype": "Small Text", "hidden": 0, @@ -1073,6 +1105,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "contact_mobile", "fieldtype": "Small Text", "hidden": 1, @@ -1104,6 +1137,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "contact_email", "fieldtype": "Data", "hidden": 1, @@ -1136,6 +1170,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "territory", "fieldtype": "Link", "hidden": 0, @@ -1169,6 +1204,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "col_break4", "fieldtype": "Column Break", "hidden": 0, @@ -1200,6 +1236,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "shipping_address_name", "fieldtype": "Link", "hidden": 0, @@ -1233,6 +1270,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "shipping_address", "fieldtype": "Small Text", "hidden": 0, @@ -1265,6 +1303,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "company_address", "fieldtype": "Link", "hidden": 0, @@ -1298,6 +1337,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "company_address_display", "fieldtype": "Small Text", "hidden": 1, @@ -1331,6 +1371,7 @@ "collapsible": 1, "columns": 0, "depends_on": "customer", + "fetch_if_empty": 0, "fieldname": "currency_and_price_list", "fieldtype": "Section Break", "hidden": 0, @@ -1363,6 +1404,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "currency", "fieldtype": "Link", "hidden": 0, @@ -1398,6 +1440,7 @@ "collapsible": 0, "columns": 0, "description": "Rate at which Customer Currency is converted to customer's base currency", + "fetch_if_empty": 0, "fieldname": "conversion_rate", "fieldtype": "Float", "hidden": 0, @@ -1432,6 +1475,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "column_break2", "fieldtype": "Column Break", "hidden": 0, @@ -1463,6 +1507,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "selling_price_list", "fieldtype": "Link", "hidden": 0, @@ -1497,6 +1542,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "price_list_currency", "fieldtype": "Link", "hidden": 0, @@ -1530,6 +1576,7 @@ "collapsible": 0, "columns": 0, "description": "Rate at which Price list currency is converted to customer's base currency", + "fetch_if_empty": 0, "fieldname": "plc_conversion_rate", "fieldtype": "Float", "hidden": 0, @@ -1562,6 +1609,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "ignore_pricing_rule", "fieldtype": "Check", "hidden": 0, @@ -1593,6 +1641,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "sec_warehouse", "fieldtype": "Section Break", "hidden": 0, @@ -1625,6 +1674,7 @@ "collapsible": 0, "columns": 0, "depends_on": "update_stock", + "fetch_if_empty": 0, "fieldname": "set_warehouse", "fieldtype": "Link", "hidden": 0, @@ -1658,6 +1708,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "items_section", "fieldtype": "Section Break", "hidden": 0, @@ -1691,6 +1742,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "update_stock", "fieldtype": "Check", "hidden": 0, @@ -1724,6 +1776,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "scan_barcode", "fieldtype": "Data", "hidden": 0, @@ -1756,6 +1809,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "items", "fieldtype": "Table", "hidden": 0, @@ -1790,6 +1844,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "packing_list", "fieldtype": "Section Break", "hidden": 0, @@ -1822,6 +1877,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "packed_items", "fieldtype": "Table", "hidden": 0, @@ -1854,6 +1910,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "product_bundle_help", "fieldtype": "HTML", "hidden": 0, @@ -1887,6 +1944,7 @@ "collapsible_depends_on": "eval:doc.total_billing_amount > 0", "columns": 0, "depends_on": "", + "fetch_if_empty": 0, "fieldname": "time_sheet_list", "fieldtype": "Section Break", "hidden": 0, @@ -1919,6 +1977,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "timesheets", "fieldtype": "Table", "hidden": 0, @@ -1953,6 +2012,7 @@ "collapsible": 0, "columns": 0, "default": "0", + "fetch_if_empty": 0, "fieldname": "total_billing_amount", "fieldtype": "Currency", "hidden": 0, @@ -1985,6 +2045,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "section_break_30", "fieldtype": "Section Break", "hidden": 0, @@ -2015,6 +2076,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "total_qty", "fieldtype": "Float", "hidden": 0, @@ -2047,6 +2109,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "base_total", "fieldtype": "Currency", "hidden": 0, @@ -2080,6 +2143,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "base_net_total", "fieldtype": "Currency", "hidden": 0, @@ -2114,6 +2178,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "column_break_32", "fieldtype": "Column Break", "hidden": 0, @@ -2144,6 +2209,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "total", "fieldtype": "Currency", "hidden": 0, @@ -2177,6 +2243,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "net_total", "fieldtype": "Currency", "hidden": 0, @@ -2209,6 +2276,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "total_net_weight", "fieldtype": "Float", "hidden": 0, @@ -2241,6 +2309,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "taxes_section", "fieldtype": "Section Break", "hidden": 0, @@ -2274,6 +2343,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "taxes_and_charges", "fieldtype": "Link", "hidden": 0, @@ -2308,6 +2378,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "column_break_38", "fieldtype": "Column Break", "hidden": 0, @@ -2338,6 +2409,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "shipping_rule", "fieldtype": "Link", "hidden": 0, @@ -2371,6 +2443,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "section_break_40", "fieldtype": "Section Break", "hidden": 0, @@ -2401,6 +2474,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "taxes", "fieldtype": "Table", "hidden": 0, @@ -2435,6 +2509,7 @@ "bold": 0, "collapsible": 1, "columns": 0, + "fetch_if_empty": 0, "fieldname": "sec_tax_breakup", "fieldtype": "Section Break", "hidden": 0, @@ -2467,6 +2542,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "other_charges_calculation", "fieldtype": "Text", "hidden": 0, @@ -2499,6 +2575,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "section_break_43", "fieldtype": "Section Break", "hidden": 0, @@ -2529,6 +2606,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "base_total_taxes_and_charges", "fieldtype": "Currency", "hidden": 0, @@ -2563,6 +2641,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "column_break_47", "fieldtype": "Column Break", "hidden": 0, @@ -2594,6 +2673,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "total_taxes_and_charges", "fieldtype": "Currency", "hidden": 0, @@ -2628,6 +2708,7 @@ "collapsible_depends_on": "", "columns": 0, "depends_on": "", + "fetch_if_empty": 0, "fieldname": "loyalty_points_redemption", "fieldtype": "Section Break", "hidden": 0, @@ -2661,6 +2742,7 @@ "collapsible": 0, "columns": 0, "depends_on": "redeem_loyalty_points", + "fetch_if_empty": 0, "fieldname": "loyalty_points", "fieldtype": "Int", "hidden": 0, @@ -2694,6 +2776,7 @@ "collapsible": 0, "columns": 0, "depends_on": "redeem_loyalty_points", + "fetch_if_empty": 0, "fieldname": "loyalty_amount", "fieldtype": "Currency", "hidden": 0, @@ -2727,6 +2810,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "redeem_loyalty_points", "fieldtype": "Check", "hidden": 0, @@ -2759,6 +2843,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "column_break_77", "fieldtype": "Column Break", "hidden": 0, @@ -2792,6 +2877,7 @@ "columns": 0, "depends_on": "", "fetch_from": "customer.loyalty_program", + "fetch_if_empty": 0, "fieldname": "loyalty_program", "fieldtype": "Link", "hidden": 0, @@ -2826,6 +2912,7 @@ "collapsible": 0, "columns": 0, "depends_on": "redeem_loyalty_points", + "fetch_if_empty": 0, "fieldname": "loyalty_redemption_account", "fieldtype": "Link", "hidden": 0, @@ -2860,6 +2947,7 @@ "collapsible": 0, "columns": 0, "depends_on": "redeem_loyalty_points", + "fetch_if_empty": 0, "fieldname": "loyalty_redemption_cost_center", "fieldtype": "Link", "hidden": 0, @@ -2894,6 +2982,7 @@ "collapsible": 1, "collapsible_depends_on": "discount_amount", "columns": 0, + "fetch_if_empty": 0, "fieldname": "section_break_49", "fieldtype": "Section Break", "hidden": 0, @@ -2927,6 +3016,7 @@ "collapsible": 0, "columns": 0, "default": "Grand Total", + "fetch_if_empty": 0, "fieldname": "apply_discount_on", "fieldtype": "Select", "hidden": 0, @@ -2960,6 +3050,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "base_discount_amount", "fieldtype": "Currency", "hidden": 0, @@ -2993,6 +3084,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "column_break_51", "fieldtype": "Column Break", "hidden": 0, @@ -3023,6 +3115,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "additional_discount_percentage", "fieldtype": "Float", "hidden": 0, @@ -3055,6 +3148,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "discount_amount", "fieldtype": "Currency", "hidden": 0, @@ -3087,6 +3181,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "totals", "fieldtype": "Section Break", "hidden": 0, @@ -3120,6 +3215,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "base_grand_total", "fieldtype": "Currency", "hidden": 0, @@ -3154,6 +3250,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "base_rounding_adjustment", "fieldtype": "Currency", "hidden": 0, @@ -3187,6 +3284,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "base_rounded_total", "fieldtype": "Currency", "hidden": 0, @@ -3222,6 +3320,7 @@ "collapsible": 0, "columns": 0, "description": "In Words will be visible once you save the Sales Invoice.", + "fetch_if_empty": 0, "fieldname": "base_in_words", "fieldtype": "Data", "hidden": 0, @@ -3255,6 +3354,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "column_break5", "fieldtype": "Column Break", "hidden": 0, @@ -3287,6 +3387,7 @@ "bold": 1, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "grand_total", "fieldtype": "Currency", "hidden": 0, @@ -3321,6 +3422,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "rounding_adjustment", "fieldtype": "Currency", "hidden": 0, @@ -3354,6 +3456,7 @@ "bold": 1, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "rounded_total", "fieldtype": "Currency", "hidden": 0, @@ -3388,6 +3491,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "in_words", "fieldtype": "Data", "hidden": 0, @@ -3421,6 +3525,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "total_advance", "fieldtype": "Currency", "hidden": 0, @@ -3455,6 +3560,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "outstanding_amount", "fieldtype": "Currency", "hidden": 0, @@ -3490,6 +3596,7 @@ "collapsible": 1, "collapsible_depends_on": "advances", "columns": 0, + "fetch_if_empty": 0, "fieldname": "advances_section", "fieldtype": "Section Break", "hidden": 0, @@ -3523,6 +3630,8 @@ "bold": 0, "collapsible": 0, "columns": 0, + "default": "1", + "fetch_if_empty": 0, "fieldname": "allocate_advances_automatically", "fieldtype": "Check", "hidden": 0, @@ -3556,6 +3665,7 @@ "collapsible": 0, "columns": 0, "depends_on": "eval:!doc.allocate_advances_automatically", + "fetch_if_empty": 0, "fieldname": "get_advances", "fieldtype": "Button", "hidden": 0, @@ -3589,6 +3699,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "advances", "fieldtype": "Table", "hidden": 0, @@ -3624,6 +3735,7 @@ "collapsible": 1, "collapsible_depends_on": "eval:(!doc.is_pos && !doc.is_return)", "columns": 0, + "fetch_if_empty": 0, "fieldname": "payment_schedule_section", "fieldtype": "Section Break", "hidden": 0, @@ -3657,6 +3769,7 @@ "collapsible": 0, "columns": 0, "depends_on": "eval:(!doc.is_pos && !doc.is_return)", + "fetch_if_empty": 0, "fieldname": "payment_terms_template", "fieldtype": "Link", "hidden": 0, @@ -3691,6 +3804,7 @@ "collapsible": 0, "columns": 0, "depends_on": "eval:(!doc.is_pos && !doc.is_return)", + "fetch_if_empty": 0, "fieldname": "payment_schedule", "fieldtype": "Table", "hidden": 0, @@ -3726,6 +3840,7 @@ "collapsible_depends_on": "", "columns": 0, "depends_on": "eval:doc.is_pos===1||(doc.advances && doc.advances.length>0)", + "fetch_if_empty": 0, "fieldname": "payments_section", "fieldtype": "Section Break", "hidden": 0, @@ -3759,6 +3874,7 @@ "collapsible": 0, "columns": 0, "depends_on": "is_pos", + "fetch_if_empty": 0, "fieldname": "cash_bank_account", "fieldtype": "Link", "hidden": 1, @@ -3794,6 +3910,7 @@ "collapsible": 0, "columns": 0, "depends_on": "eval:doc.is_pos===1", + "fetch_if_empty": 0, "fieldname": "payments", "fieldtype": "Table", "hidden": 0, @@ -3827,6 +3944,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "section_break_84", "fieldtype": "Section Break", "hidden": 0, @@ -3858,6 +3976,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "base_paid_amount", "fieldtype": "Currency", "hidden": 0, @@ -3891,6 +4010,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "column_break_86", "fieldtype": "Column Break", "hidden": 0, @@ -3923,6 +4043,7 @@ "collapsible": 0, "columns": 0, "depends_on": "eval: doc.is_pos || doc.redeem_loyalty_points", + "fetch_if_empty": 0, "fieldname": "paid_amount", "fieldtype": "Currency", "hidden": 0, @@ -3957,6 +4078,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "section_break_88", "fieldtype": "Section Break", "hidden": 0, @@ -3989,6 +4111,7 @@ "collapsible": 0, "columns": 0, "depends_on": "is_pos", + "fetch_if_empty": 0, "fieldname": "base_change_amount", "fieldtype": "Currency", "hidden": 0, @@ -4022,6 +4145,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "column_break_90", "fieldtype": "Column Break", "hidden": 0, @@ -4054,6 +4178,7 @@ "collapsible": 0, "columns": 0, "depends_on": "is_pos", + "fetch_if_empty": 0, "fieldname": "change_amount", "fieldtype": "Currency", "hidden": 0, @@ -4088,6 +4213,7 @@ "collapsible": 0, "columns": 0, "depends_on": "is_pos", + "fetch_if_empty": 0, "fieldname": "account_for_change_amount", "fieldtype": "Link", "hidden": 0, @@ -4123,6 +4249,7 @@ "collapsible_depends_on": "write_off_amount", "columns": 0, "depends_on": "grand_total", + "fetch_if_empty": 0, "fieldname": "column_break4", "fieldtype": "Section Break", "hidden": 0, @@ -4156,6 +4283,7 @@ "collapsible": 0, "columns": 0, "depends_on": "", + "fetch_if_empty": 0, "fieldname": "write_off_amount", "fieldtype": "Currency", "hidden": 0, @@ -4188,6 +4316,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "base_write_off_amount", "fieldtype": "Currency", "hidden": 0, @@ -4222,6 +4351,7 @@ "collapsible": 0, "columns": 0, "depends_on": "is_pos", + "fetch_if_empty": 0, "fieldname": "write_off_outstanding_amount_automatically", "fieldtype": "Check", "hidden": 0, @@ -4254,6 +4384,7 @@ "collapsible": 0, "columns": 0, "depends_on": "", + "fetch_if_empty": 0, "fieldname": "column_break_74", "fieldtype": "Column Break", "hidden": 0, @@ -4286,6 +4417,7 @@ "collapsible": 0, "columns": 0, "depends_on": "", + "fetch_if_empty": 0, "fieldname": "write_off_account", "fieldtype": "Link", "hidden": 0, @@ -4319,6 +4451,7 @@ "collapsible": 0, "columns": 0, "depends_on": "", + "fetch_if_empty": 0, "fieldname": "write_off_cost_center", "fieldtype": "Link", "hidden": 0, @@ -4352,6 +4485,7 @@ "collapsible": 1, "collapsible_depends_on": "terms", "columns": 0, + "fetch_if_empty": 0, "fieldname": "terms_section_break", "fieldtype": "Section Break", "hidden": 0, @@ -4385,6 +4519,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "tc_name", "fieldtype": "Link", "hidden": 0, @@ -4419,6 +4554,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "terms", "fieldtype": "Text Editor", "hidden": 0, @@ -4452,6 +4588,7 @@ "bold": 0, "collapsible": 1, "columns": 0, + "fetch_if_empty": 0, "fieldname": "edit_printing_settings", "fieldtype": "Section Break", "hidden": 0, @@ -4484,6 +4621,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "letter_head", "fieldtype": "Link", "hidden": 0, @@ -4518,6 +4656,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "group_same_items", "fieldtype": "Check", "hidden": 0, @@ -4550,6 +4689,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "language", "fieldtype": "Data", "hidden": 0, @@ -4582,6 +4722,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "column_break_84", "fieldtype": "Column Break", "hidden": 0, @@ -4613,6 +4754,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "select_print_heading", "fieldtype": "Link", "hidden": 0, @@ -4648,6 +4790,7 @@ "collapsible": 1, "columns": 0, "depends_on": "customer", + "fetch_if_empty": 0, "fieldname": "more_information", "fieldtype": "Section Break", "hidden": 0, @@ -4680,6 +4823,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "inter_company_invoice_reference", "fieldtype": "Link", "hidden": 0, @@ -4714,6 +4858,7 @@ "collapsible": 0, "columns": 0, "description": "", + "fetch_if_empty": 0, "fieldname": "customer_group", "fieldtype": "Link", "hidden": 1, @@ -4747,6 +4892,7 @@ "collapsible": 0, "columns": 0, "depends_on": "", + "fetch_if_empty": 0, "fieldname": "campaign", "fieldtype": "Link", "hidden": 0, @@ -4781,6 +4927,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "col_break23", "fieldtype": "Column Break", "hidden": 0, @@ -4813,6 +4960,7 @@ "collapsible": 0, "columns": 0, "default": "Draft", + "fetch_if_empty": 0, "fieldname": "status", "fieldtype": "Select", "hidden": 0, @@ -4846,6 +4994,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "source", "fieldtype": "Link", "hidden": 0, @@ -4880,6 +5029,7 @@ "bold": 0, "collapsible": 1, "columns": 0, + "fetch_if_empty": 0, "fieldname": "more_info", "fieldtype": "Section Break", "hidden": 0, @@ -4914,6 +5064,7 @@ "collapsible": 0, "columns": 0, "description": "", + "fetch_if_empty": 0, "fieldname": "debit_to", "fieldtype": "Link", "hidden": 0, @@ -4948,6 +5099,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "party_account_currency", "fieldtype": "Link", "hidden": 1, @@ -4983,6 +5135,7 @@ "columns": 0, "default": "No", "description": "", + "fetch_if_empty": 0, "fieldname": "is_opening", "fieldtype": "Select", "hidden": 0, @@ -5017,6 +5170,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "c_form_applicable", "fieldtype": "Select", "hidden": 0, @@ -5049,6 +5203,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "c_form_no", "fieldtype": "Link", "hidden": 0, @@ -5081,6 +5236,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "column_break8", "fieldtype": "Column Break", "hidden": 0, @@ -5112,6 +5268,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "remarks", "fieldtype": "Small Text", "hidden": 0, @@ -5146,6 +5303,7 @@ "collapsible": 1, "collapsible_depends_on": "sales_partner", "columns": 0, + "fetch_if_empty": 0, "fieldname": "sales_team_section_break", "fieldtype": "Section Break", "hidden": 0, @@ -5179,6 +5337,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "sales_partner", "fieldtype": "Link", "hidden": 0, @@ -5213,6 +5372,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "column_break10", "fieldtype": "Column Break", "hidden": 0, @@ -5245,6 +5405,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "commission_rate", "fieldtype": "Float", "hidden": 0, @@ -5278,6 +5439,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "total_commission", "fieldtype": "Currency", "hidden": 0, @@ -5313,6 +5475,7 @@ "collapsible": 1, "collapsible_depends_on": "sales_team", "columns": 0, + "fetch_if_empty": 0, "fieldname": "section_break2", "fieldtype": "Section Break", "hidden": 0, @@ -5344,6 +5507,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "sales_team", "fieldtype": "Table", "hidden": 0, @@ -5378,6 +5542,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "subscription_section", "fieldtype": "Section Break", "hidden": 0, @@ -5412,6 +5577,7 @@ "columns": 0, "depends_on": "", "description": "", + "fetch_if_empty": 0, "fieldname": "from_date", "fieldtype": "Date", "hidden": 0, @@ -5445,6 +5611,7 @@ "columns": 0, "depends_on": "", "description": "", + "fetch_if_empty": 0, "fieldname": "to_date", "fieldtype": "Date", "hidden": 0, @@ -5476,6 +5643,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "column_break_140", "fieldtype": "Column Break", "hidden": 0, @@ -5507,6 +5675,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "auto_repeat", "fieldtype": "Link", "hidden": 0, @@ -5541,6 +5710,7 @@ "collapsible": 0, "columns": 0, "depends_on": "eval: doc.auto_repeat", + "fetch_if_empty": 0, "fieldname": "update_auto_repeat_reference", "fieldtype": "Button", "hidden": 0, @@ -5573,6 +5743,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "against_income_account", "fieldtype": "Small Text", "hidden": 1, @@ -5606,6 +5777,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "pos_total_qty", "fieldtype": "Float", "hidden": 1, @@ -5644,7 +5816,7 @@ "istable": 0, "max_attachments": 0, "menu_index": 0, - "modified": "2019-02-18 18:56:51.265257", + "modified": "2019-04-10 16:10:34.266458", "modified_by": "Administrator", "module": "Accounts", "name": "Sales Invoice", diff --git a/erpnext/buying/doctype/purchase_order/purchase_order.py b/erpnext/buying/doctype/purchase_order/purchase_order.py index 720160676f2..e259c04acec 100644 --- a/erpnext/buying/doctype/purchase_order/purchase_order.py +++ b/erpnext/buying/doctype/purchase_order/purchase_order.py @@ -379,7 +379,9 @@ def make_purchase_invoice(source_name, target_doc=None): def postprocess(source, target): set_missing_values(source, target) #Get the advance paid Journal Entries in Purchase Invoice Advance - target.set_advances() + + if target.get("allocate_advances_automatically"): + target.set_advances() def update_item(obj, target, source_parent): target.amount = flt(obj.amount) - flt(obj.billed_amt) diff --git a/erpnext/selling/doctype/sales_order/sales_order.py b/erpnext/selling/doctype/sales_order/sales_order.py index 2345762233f..8e81c13357c 100755 --- a/erpnext/selling/doctype/sales_order/sales_order.py +++ b/erpnext/selling/doctype/sales_order/sales_order.py @@ -612,7 +612,8 @@ def make_sales_invoice(source_name, target_doc=None, ignore_permissions=False): def postprocess(source, target): set_missing_values(source, target) #Get the advance paid Journal Entries in Sales Invoice Advance - target.set_advances() + if target.get("allocate_advances_automatically"): + target.set_advances() def set_missing_values(source, target): target.is_pos = 0 From 45d0b31d44b37ca848e5ffcab6dc46272092303e Mon Sep 17 00:00:00 2001 From: Rohit Waghchaure Date: Wed, 10 Apr 2019 12:24:24 +0530 Subject: [PATCH 20/23] fix: test cases --- erpnext/assets/doctype/asset/asset.js | 10 ++--- erpnext/assets/doctype/asset/asset.py | 52 +++++++++++----------- erpnext/assets/doctype/asset/test_asset.py | 45 ++++++++++++++++--- 3 files changed, 68 insertions(+), 39 deletions(-) diff --git a/erpnext/assets/doctype/asset/asset.js b/erpnext/assets/doctype/asset/asset.js index 5d15cab5a28..18ba8f9b5cb 100644 --- a/erpnext/assets/doctype/asset/asset.js +++ b/erpnext/assets/doctype/asset/asset.js @@ -299,13 +299,9 @@ frappe.ui.form.on('Asset', { set_depreciation_rate: function(frm, row) { if (row.total_number_of_depreciations && row.frequency_of_depreciation) { frappe.call({ - method: "erpnext.assets.doctype.asset.asset.get_depreciation_rate", - args: { - args: row, - asset_cost: frm.doc.gross_purchase_amount, - number_of_depreciations_booked: frm.doc.is_existing_asset ? - frm.doc.number_of_depreciations_booked : 0 - }, + method: "get_depreciation_rate", + doc: frm.doc, + args: row, callback: function(r) { if (r.message) { frappe.model.set_value(row.doctype, row.name, "rate_of_depreciation", r.message); diff --git a/erpnext/assets/doctype/asset/asset.py b/erpnext/assets/doctype/asset/asset.py index b703bca7727..8011038b1b1 100644 --- a/erpnext/assets/doctype/asset/asset.py +++ b/erpnext/assets/doctype/asset/asset.py @@ -101,9 +101,7 @@ class Asset(AccountsController): def set_depreciation_rate(self): for d in self.get("finance_books"): - if not d.rate_of_depreciation: - d.rate_of_depreciation = get_depreciation_rate(d, self.gross_purchase_amount, - self.number_of_depreciations_booked) + d.rate_of_depreciation = self.get_depreciation_rate(d) def make_depreciation_schedule(self): depreciation_method = [d.depreciation_method for d in self.finance_books] @@ -405,6 +403,32 @@ class Asset(AccountsController): make_gl_entries(gl_entries) self.db_set('booked_fixed_asset', 1) + def get_depreciation_rate(self, args): + if isinstance(args, string_types): + args = json.loads(args) + + number_of_depreciations_booked = 0 + if self.is_existing_asset: + number_of_depreciations_booked = self.number_of_depreciations_booked + + float_precision = cint(frappe.db.get_default("float_precision")) or 2 + tot_no_of_depreciation = flt(args.get("total_number_of_depreciations")) - flt(number_of_depreciations_booked) + + if args.get("depreciation_method") in ["Straight Line", "Manual"]: + return 1.0 / tot_no_of_depreciation + + if args.get("depreciation_method") == 'Double Declining Balance': + return 200.0 / args.get("total_number_of_depreciations") + + if args.get("depreciation_method") == "Written Down Value" and not args.get("rate_of_depreciation"): + no_of_years = flt(args.get("total_number_of_depreciations") * flt(args.get("frequency_of_depreciation"))) / 12 + value = flt(args.get("expected_value_after_useful_life")) / flt(self.gross_purchase_amount) + + # square root of flt(salvage_value) / flt(asset_cost) + depreciation_rate = math.pow(value, 1.0/flt(no_of_years, 2)) + + return 100 * (1 - flt(depreciation_rate, float_precision)) + def update_maintenance_status(): assets = frappe.get_all('Asset', filters = {'docstatus': 1, 'maintenance_required': 1}) @@ -568,25 +592,3 @@ def make_journal_entry(asset_name): def is_cwip_accounting_disabled(): return cint(frappe.db.get_single_value("Asset Settings", "disable_cwip_accounting")) - -@frappe.whitelist() -def get_depreciation_rate(args, asset_cost, number_of_depreciations_booked=0): - if isinstance(args, string_types): - args = json.loads(args) - - float_precision = cint(frappe.db.get_default("float_precision")) or 2 - - if args.get("depreciation_method") == 'Double Declining Balance': - return 200.0 / flt(args.get("total_number_of_depreciations")) - - if args.get("depreciation_method") in ["Straight Line", "Manual"]: - return 1.0 / (flt(args.get("total_number_of_depreciations")) - flt(number_of_depreciations_booked)) - - if args.get("depreciation_method") == "Written Down Value": - no_of_years = flt(flt(args.get("total_number_of_depreciations")) * flt(args.get("frequency_of_depreciation"))) / 12 - value = flt(args.get("expected_value_after_useful_life")) / flt(asset_cost) - - # square root of flt(salvage_value) / flt(asset_cost) - depreciation_rate = math.pow(value, 1.0/flt(no_of_years, 2)) - - return 100 * (1 - flt(depreciation_rate, float_precision)) \ No newline at end of file diff --git a/erpnext/assets/doctype/asset/test_asset.py b/erpnext/assets/doctype/asset/test_asset.py index a12348e451b..985097b447d 100644 --- a/erpnext/assets/doctype/asset/test_asset.py +++ b/erpnext/assets/doctype/asset/test_asset.py @@ -160,9 +160,9 @@ class TestAsset(unittest.TestCase): asset.save() expected_schedules = [ - ["2020-06-06", 66667.0, 66667.0], - ["2021-04-06", 22222.0, 88889.0], - ["2022-02-06", 1111.0, 90000.0] + ["2020-06-06", 66666.67, 66666.67], + ["2021-04-06", 22222.22, 88888.89], + ["2022-02-06", 1111.11, 90000.0] ] schedules = [[cstr(d.schedule_date), d.depreciation_amount, d.accumulated_depreciation_amount] @@ -192,8 +192,8 @@ class TestAsset(unittest.TestCase): asset.save() expected_schedules = [ - ["2020-06-06", 33333.0, 83333.0], - ["2021-04-06", 6667.0, 90000.0] + ["2020-06-06", 33333.33, 83333.33], + ["2021-04-06", 6666.67, 90000.0] ] schedules = [[cstr(d.schedule_date), d.depreciation_amount, d.accumulated_depreciation_amount] @@ -209,7 +209,7 @@ class TestAsset(unittest.TestCase): asset_name = frappe.db.get_value("Asset", {"purchase_receipt": pr.name}, 'name') asset = frappe.get_doc('Asset', asset_name) asset.calculate_depreciation = 1 - asset.purchase_date = '2020-06-06' + asset.purchase_date = '2020-01-30' asset.is_existing_asset = 0 asset.available_for_use_date = "2020-01-30" asset.append("finance_books", { @@ -244,7 +244,7 @@ class TestAsset(unittest.TestCase): asset_name = frappe.db.get_value("Asset", {"purchase_receipt": pr.name}, 'name') asset = frappe.get_doc('Asset', asset_name) asset.calculate_depreciation = 1 - asset.purchase_date = '2020-06-06' + asset.purchase_date = '2020-01-30' asset.available_for_use_date = "2020-01-30" asset.append("finance_books", { "expected_value_after_useful_life": 10000, @@ -277,6 +277,37 @@ class TestAsset(unittest.TestCase): self.assertEqual(gle, expected_gle) self.assertEqual(asset.get("value_after_depreciation"), 0) + def test_depreciation_entry_for_wdv(self): + pr = make_purchase_receipt(item_code="Macbook Pro", + qty=1, rate=8000.0, location="Test Location") + + asset_name = frappe.db.get_value("Asset", {"purchase_receipt": pr.name}, 'name') + asset = frappe.get_doc('Asset', asset_name) + asset.calculate_depreciation = 1 + asset.available_for_use_date = '2030-06-06' + asset.purchase_date = '2030-06-06' + asset.append("finance_books", { + "expected_value_after_useful_life": 1000, + "depreciation_method": "Written Down Value", + "total_number_of_depreciations": 3, + "frequency_of_depreciation": 12, + "depreciation_start_date": "2030-12-31" + }) + asset.save(ignore_permissions=True) + + self.assertEqual(asset.finance_books[0].rate_of_depreciation, 50.0) + + expected_schedules = [ + ["2030-12-31", 4000.0, 4000.0], + ["2031-12-31", 2000.0, 6000.0], + ["2032-12-31", 1000.0, 7000.0], + ] + + schedules = [[cstr(d.schedule_date), flt(d.depreciation_amount, 2), flt(d.accumulated_depreciation_amount, 2)] + for d in asset.get("schedules")] + + self.assertEqual(schedules, expected_schedules) + def test_depreciation_entry_cancellation(self): pr = make_purchase_receipt(item_code="Macbook Pro", qty=1, rate=100000.0, location="Test Location") From 49907e746b26a3f8df73e87b6e6fa3a211907a86 Mon Sep 17 00:00:00 2001 From: Rohit Waghchaure Date: Wed, 10 Apr 2019 17:33:32 +0530 Subject: [PATCH 21/23] fix: test cases --- .../purchase_invoice/test_purchase_invoice.py | 18 ++++++++++-------- .../sales_invoice/test_sales_invoice.py | 1 + 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py b/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py index c8c23c74e9c..dde12d79c7a 100644 --- a/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py +++ b/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py @@ -344,6 +344,7 @@ class TestPurchaseInvoice(unittest.TestCase): pi = frappe.copy_doc(test_records[0]) pi.disable_rounded_total = 1 + pi.allocate_advances_automatically = 0 pi.append("advances", { "reference_type": "Journal Entry", "reference_name": jv.name, @@ -383,6 +384,7 @@ class TestPurchaseInvoice(unittest.TestCase): pi = frappe.copy_doc(test_records[0]) pi.disable_rounded_total = 1 + pi.allocate_advances_automatically = 0 pi.append("advances", { "reference_type": "Journal Entry", "reference_name": jv.name, @@ -551,7 +553,7 @@ class TestPurchaseInvoice(unittest.TestCase): sum(credit) as credit, debit_in_account_currency, credit_in_account_currency from `tabGL Entry` where voucher_type='Purchase Invoice' and voucher_no=%s group by account, voucher_no order by account asc;""", pi.name, as_dict=1) - + stock_in_hand_account = get_inventory_account(pi.company, pi.get("items")[0].warehouse) self.assertTrue(gl_entries) @@ -634,7 +636,7 @@ class TestPurchaseInvoice(unittest.TestCase): self.assertEqual(frappe.db.get_value("Serial No", pi.get("items")[0].rejected_serial_no, "warehouse"), pi.get("items")[0].rejected_warehouse) - + def test_outstanding_amount_after_advance_jv_cancelation(self): from erpnext.accounts.doctype.journal_entry.test_journal_entry \ import test_records as jv_test_records @@ -656,14 +658,14 @@ class TestPurchaseInvoice(unittest.TestCase): pi.insert() pi.submit() pi.load_from_db() - + #check outstanding after advance allocation self.assertEqual(flt(pi.outstanding_amount), flt(pi.rounded_total - pi.total_advance)) - + #added to avoid Document has been modified exception jv = frappe.get_doc("Journal Entry", jv.name) jv.cancel() - + pi.load_from_db() #check outstanding after advance cancellation self.assertEqual(flt(pi.outstanding_amount), flt(pi.rounded_total + pi.total_advance)) @@ -722,7 +724,7 @@ class TestPurchaseInvoice(unittest.TestCase): shipping_rule = create_shipping_rule(shipping_rule_type = "Buying", shipping_rule_name = "Shipping Rule - Purchase Invoice Test") pi = frappe.copy_doc(test_records[0]) - + pi.shipping_rule = shipping_rule.name pi.insert() @@ -740,14 +742,14 @@ class TestPurchaseInvoice(unittest.TestCase): "tax_amount": shipping_amount, "description": shipping_rule.name, "add_deduct_tax": "Add" - } + } pi.append("taxes", shipping_charge) pi.save() self.assertEqual(pi.net_total, 1250) self.assertEqual(pi.total_taxes_and_charges, 462.3) - self.assertEqual(pi.grand_total, 1712.3) + self.assertEqual(pi.grand_total, 1712.3) def test_make_pi_without_terms(self): pi = make_purchase_invoice(do_not_save=1) diff --git a/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py index 45a29505fc0..b39da3c4af4 100644 --- a/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py +++ b/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py @@ -855,6 +855,7 @@ class TestSalesInvoice(unittest.TestCase): jv.submit() si = frappe.copy_doc(test_records[0]) + si.allocate_advances_automatically = 0 si.append("advances", { "doctype": "Sales Invoice Advance", "reference_type": "Journal Entry", From 5ab5f77fd47e68ea3e667d8104e8bccf40778849 Mon Sep 17 00:00:00 2001 From: Anurag Mishra Date: Wed, 10 Apr 2019 17:49:53 +0530 Subject: [PATCH 22/23] fix: order by idx --- erpnext/selling/page/point_of_sale/point_of_sale.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/erpnext/selling/page/point_of_sale/point_of_sale.py b/erpnext/selling/page/point_of_sale/point_of_sale.py index 56d91518d8c..e088679917b 100644 --- a/erpnext/selling/page/point_of_sale/point_of_sale.py +++ b/erpnext/selling/page/point_of_sale/point_of_sale.py @@ -39,7 +39,7 @@ def get_items(start, page_length, price_list, item_group, search_value="", pos_p if display_items_in_stock == 0: - res = frappe.db.sql("""select i.name as item_code, i.item_name, i.image as item_image, + res = frappe.db.sql("""select i.name as item_code, i.item_name, i.image as item_image, i.idx as idx, i.is_stock_item, item_det.price_list_rate, item_det.currency from `tabItem` i LEFT JOIN (select item_code, price_list_rate, currency from @@ -49,7 +49,7 @@ def get_items(start, page_length, price_list, item_group, search_value="", pos_p where i.disabled = 0 and i.has_variants = 0 and i.is_sales_item = 1 and i.item_group in (select name from `tabItem Group` where lft >= {lft} and rgt <= {rgt}) - and {condition} limit {start}, {page_length}""".format(start=start,page_length=page_length,lft=lft, rgt=rgt, condition=condition), + and {condition} order by idx desc limit {start}, {page_length}""".format(start=start,page_length=page_length,lft=lft, rgt=rgt, condition=condition), { 'item_code': item_code, 'price_list': price_list @@ -60,7 +60,7 @@ def get_items(start, page_length, price_list, item_group, search_value="", pos_p } elif display_items_in_stock == 1: - query = """select i.name as item_code, i.item_name, i.image as item_image, + query = """select i.name as item_code, i.item_name, i.image as item_image, i.idx as idx, i.is_stock_item, item_det.price_list_rate, item_det.currency from `tabItem` i LEFT JOIN (select item_code, price_list_rate, currency from @@ -79,7 +79,7 @@ def get_items(start, page_length, price_list, item_group, search_value="", pos_p where i.disabled = 0 and i.has_variants = 0 and i.is_sales_item = 1 and i.item_group in (select name from `tabItem Group` where lft >= {lft} and rgt <= {rgt}) - and {condition} limit {start}, {page_length}""".format + and {condition} order by idx desc limit {start}, {page_length}""".format (start=start,page_length=page_length,lft=lft, rgt=rgt, condition=condition), { 'item_code': item_code, From f3a9552e48525e63fe895052444ab6aabc163ed8 Mon Sep 17 00:00:00 2001 From: Rohit Waghchaure Date: Wed, 10 Apr 2019 17:55:59 +0530 Subject: [PATCH 23/23] fix: item variant test cases --- erpnext/controllers/tests/test_item_variant.py | 8 ++++---- erpnext/stock/doctype/item_attribute/test_records.json | 3 ++- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/erpnext/controllers/tests/test_item_variant.py b/erpnext/controllers/tests/test_item_variant.py index d4b5dd2e1ef..c257215e718 100644 --- a/erpnext/controllers/tests/test_item_variant.py +++ b/erpnext/controllers/tests/test_item_variant.py @@ -42,10 +42,10 @@ def create_variant_with_tables(item, args): return variant def make_item_variant(): - frappe.delete_doc_if_exists("Item", "_Test Variant Item-S", force=1) - variant = create_variant_with_tables("_Test Variant Item", '{"Test Size": "Small"}') - variant.item_code = "_Test Variant Item-S" - variant.item_name = "_Test Variant Item-S" + frappe.delete_doc_if_exists("Item", "_Test Variant Item-XSL", force=1) + variant = create_variant_with_tables("_Test Variant Item", '{"Test Size": "Extra Small"}') + variant.item_code = "_Test Variant Item-XSL" + variant.item_name = "_Test Variant Item-XSL" variant.save() return variant diff --git a/erpnext/stock/doctype/item_attribute/test_records.json b/erpnext/stock/doctype/item_attribute/test_records.json index 0208c176d32..d346979496f 100644 --- a/erpnext/stock/doctype/item_attribute/test_records.json +++ b/erpnext/stock/doctype/item_attribute/test_records.json @@ -6,7 +6,8 @@ "item_attribute_values": [ {"attribute_value": "Small", "abbr": "S"}, {"attribute_value": "Medium", "abbr": "M"}, - {"attribute_value": "Large", "abbr": "L"} + {"attribute_value": "Large", "abbr": "L"}, + {"attribute_value": "Extra Small", "abbr": "XSL"} ] }, {