From 1358efe896c2f1279a29189c185738f6bcb0822c Mon Sep 17 00:00:00 2001 From: Shivam Mishra Date: Mon, 6 Jul 2020 14:09:33 +0530 Subject: [PATCH 001/477] feat: update icons --- .../desk_page/accounting/accounting.json | 3 +- .../desk_page/agriculture/agriculture.json | 4 +- erpnext/assets/desk_page/assets/assets.json | 3 +- erpnext/buying/desk_page/buying/buying.json | 9 ++-- erpnext/crm/desk_page/crm/crm.json | 7 +-- .../desk_page/education/education.json | 4 +- erpnext/hr/desk_page/hr/hr.json | 43 +++++++++++++------ .../loan_management/desk_page/loan/loan.json | 6 ++- .../manufacturing/manufacturing.json | 11 ++--- .../desk_page/non_profit/non_profit.json | 4 +- .../payroll/desk_page/payroll/payroll.json | 3 +- .../projects/desk_page/projects/projects.json | 7 +-- .../desk_page/quality/quality.json | 5 ++- erpnext/selling/desk_page/retail/retail.json | 4 +- .../selling/desk_page/selling/selling.json | 9 ++-- .../erpnext_settings/erpnext_settings.json | 4 +- erpnext/setup/desk_page/home/home.json | 4 +- erpnext/stock/desk_page/stock/stock.json | 11 ++--- .../support/desk_page/support/support.json | 5 ++- 19 files changed, 94 insertions(+), 52 deletions(-) diff --git a/erpnext/accounts/desk_page/accounting/accounting.json b/erpnext/accounts/desk_page/accounting/accounting.json index 31315e4c710..46e426784d0 100644 --- a/erpnext/accounts/desk_page/accounting/accounting.json +++ b/erpnext/accounts/desk_page/accounting/accounting.json @@ -95,10 +95,11 @@ "doctype": "Desk Page", "extends_another_page": 0, "hide_custom": 0, + "icon": "accounting", "idx": 0, "is_standard": 1, "label": "Accounting", - "modified": "2020-06-19 12:42:44.054598", + "modified": "2020-06-30 18:33:06.526514", "modified_by": "Administrator", "module": "Accounts", "name": "Accounting", diff --git a/erpnext/agriculture/desk_page/agriculture/agriculture.json b/erpnext/agriculture/desk_page/agriculture/agriculture.json index e0d2c9ca25a..094e1652b33 100644 --- a/erpnext/agriculture/desk_page/agriculture/agriculture.json +++ b/erpnext/agriculture/desk_page/agriculture/agriculture.json @@ -24,10 +24,12 @@ "docstatus": 0, "doctype": "Desk Page", "extends_another_page": 0, + "hide_custom": 0, + "icon": "agriculture", "idx": 0, "is_standard": 1, "label": "Agriculture", - "modified": "2020-04-01 11:28:51.032822", + "modified": "2020-06-30 18:35:25.350213", "modified_by": "Administrator", "module": "Agriculture", "name": "Agriculture", diff --git a/erpnext/assets/desk_page/assets/assets.json b/erpnext/assets/desk_page/assets/assets.json index 449a5facb08..515fc22f052 100644 --- a/erpnext/assets/desk_page/assets/assets.json +++ b/erpnext/assets/desk_page/assets/assets.json @@ -30,10 +30,11 @@ "doctype": "Desk Page", "extends_another_page": 0, "hide_custom": 0, + "icon": "assets", "idx": 0, "is_standard": 1, "label": "Assets", - "modified": "2020-05-20 18:05:23.994795", + "modified": "2020-06-30 18:36:11.169586", "modified_by": "Administrator", "module": "Assets", "name": "Assets", diff --git a/erpnext/buying/desk_page/buying/buying.json b/erpnext/buying/desk_page/buying/buying.json index 565d39c3c83..af95b931ad0 100644 --- a/erpnext/buying/desk_page/buying/buying.json +++ b/erpnext/buying/desk_page/buying/buying.json @@ -57,10 +57,11 @@ "doctype": "Desk Page", "extends_another_page": 0, "hide_custom": 0, + "icon": "buying", "idx": 0, "is_standard": 1, "label": "Buying", - "modified": "2020-06-29 19:30:24.983050", + "modified": "2020-06-30 18:36:53.390498", "modified_by": "Administrator", "module": "Buying", "name": "Buying", @@ -70,7 +71,7 @@ "pin_to_top": 0, "shortcuts": [ { - "color": "#cef6d1", + "color": "Green", "format": "{} Available", "label": "Item", "link_to": "Item", @@ -78,7 +79,7 @@ "type": "DocType" }, { - "color": "#ffe8cd", + "color": "Yellow", "format": "{} Pending", "label": "Material Request", "link_to": "Material Request", @@ -86,7 +87,7 @@ "type": "DocType" }, { - "color": "#ffe8cd", + "color": "Yellow", "format": "{} To Receive", "label": "Purchase Order", "link_to": "Purchase Order", diff --git a/erpnext/crm/desk_page/crm/crm.json b/erpnext/crm/desk_page/crm/crm.json index eb69dc06b65..234008d38fc 100644 --- a/erpnext/crm/desk_page/crm/crm.json +++ b/erpnext/crm/desk_page/crm/crm.json @@ -39,10 +39,11 @@ "doctype": "Desk Page", "extends_another_page": 0, "hide_custom": 0, + "icon": "crm", "idx": 0, "is_standard": 1, "label": "CRM", - "modified": "2020-05-28 13:33:52.906750", + "modified": "2020-06-30 18:37:48.961922", "modified_by": "Administrator", "module": "CRM", "name": "CRM", @@ -52,7 +53,7 @@ "pin_to_top": 0, "shortcuts": [ { - "color": "#ffe8cd", + "color": "Blue", "format": "{} Open", "label": "Lead", "link_to": "Lead", @@ -60,7 +61,7 @@ "type": "DocType" }, { - "color": "#cef6d1", + "color": "Blue", "format": "{} Assigned", "label": "Opportunity", "link_to": "Opportunity", diff --git a/erpnext/education/desk_page/education/education.json b/erpnext/education/desk_page/education/education.json index b341ec4b99b..b8f87d34b74 100644 --- a/erpnext/education/desk_page/education/education.json +++ b/erpnext/education/desk_page/education/education.json @@ -79,10 +79,12 @@ "docstatus": 0, "doctype": "Desk Page", "extends_another_page": 0, + "hide_custom": 0, + "icon": "education", "idx": 0, "is_standard": 1, "label": "Education", - "modified": "2020-05-22 01:09:13.058482", + "modified": "2020-06-30 18:36:17.013044", "modified_by": "Administrator", "module": "Education", "name": "Education", diff --git a/erpnext/hr/desk_page/hr/hr.json b/erpnext/hr/desk_page/hr/hr.json index 0fed8d322f5..bcc4ac57c9a 100644 --- a/erpnext/hr/desk_page/hr/hr.json +++ b/erpnext/hr/desk_page/hr/hr.json @@ -20,6 +20,11 @@ "label": "Leaves", "links": "[\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"label\": \"Leave Application\",\n \"name\": \"Leave Application\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"label\": \"Leave Allocation\",\n \"name\": \"Leave Allocation\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Leave Type\"\n ],\n \"label\": \"Leave Policy\",\n \"name\": \"Leave Policy\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Leave Period\",\n \"name\": \"Leave Period\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Leave Type\",\n \"name\": \"Leave Type\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Holiday List\",\n \"name\": \"Holiday List\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"label\": \"Compensatory Leave Request\",\n \"name\": \"Compensatory Leave Request\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"label\": \"Leave Encashment\",\n \"name\": \"Leave Encashment\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Leave Block List\",\n \"name\": \"Leave Block List\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Leave Application\"\n ],\n \"doctype\": \"Leave Application\",\n \"is_query_report\": true,\n \"label\": \"Employee Leave Balance\",\n \"name\": \"Employee Leave Balance\",\n \"type\": \"report\"\n }\n]" }, + { + "hidden": 0, + "label": "Payroll", + "links": "[\n {\n \"label\": \"Salary Structure\",\n \"name\": \"Salary Structure\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Salary Structure\",\n \"Employee\"\n ],\n \"label\": \"Salary Structure Assignment\",\n \"name\": \"Salary Structure Assignment\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Payroll Entry\",\n \"name\": \"Payroll Entry\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Salary Slip\",\n \"name\": \"Salary Slip\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Payroll Period\",\n \"name\": \"Payroll Period\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Income Tax Slab\",\n \"name\": \"Income Tax Slab\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Salary Component\",\n \"name\": \"Salary Component\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Additional Salary\",\n \"name\": \"Additional Salary\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"label\": \"Retention Bonus\",\n \"name\": \"Retention Bonus\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"label\": \"Employee Incentive\",\n \"name\": \"Employee Incentive\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Salary Slip\"\n ],\n \"doctype\": \"Salary Slip\",\n \"is_query_report\": true,\n \"label\": \"Salary Register\",\n \"name\": \"Salary Register\",\n \"type\": \"report\"\n }\n]" + }, { "hidden": 0, "label": "Attendance", @@ -45,6 +50,11 @@ "label": "Recruitment", "links": "[\n {\n \"label\": \"Job Opening\",\n \"name\": \"Job Opening\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Job Applicant\",\n \"name\": \"Job Applicant\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Job Offer\",\n \"name\": \"Job Offer\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Staffing Plan\",\n \"name\": \"Staffing Plan\",\n \"type\": \"doctype\"\n }\n]" }, + { + "hidden": 0, + "label": "Loans", + "links": "[\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"label\": \"Loan Application\",\n \"name\": \"Loan Application\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Loan\",\n \"name\": \"Loan\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Loan Type\",\n \"name\": \"Loan Type\",\n \"type\": \"doctype\"\n }\n]" + }, { "hidden": 0, "label": "Training", @@ -59,13 +69,18 @@ "hidden": 0, "label": "Performance", "links": "[\n {\n \"label\": \"Appraisal\",\n \"name\": \"Appraisal\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Appraisal Template\",\n \"name\": \"Appraisal Template\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Energy Point Rule\",\n \"name\": \"Energy Point Rule\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Energy Point Log\",\n \"name\": \"Energy Point Log\",\n \"type\": \"doctype\"\n }\n]" + }, + { + "hidden": 0, + "label": "Employee Tax and Benefits", + "links": "[\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"label\": \"Employee Tax Exemption Declaration\",\n \"name\": \"Employee Tax Exemption Declaration\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"label\": \"Employee Tax Exemption Proof Submission\",\n \"name\": \"Employee Tax Exemption Proof Submission\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Employee\",\n \"Payroll Period\"\n ],\n \"label\": \"Employee Other Income\",\n \"name\": \"Employee Other Income\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"label\": \"Employee Benefit Application\",\n \"name\": \"Employee Benefit Application\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"label\": \"Employee Benefit Claim\",\n \"name\": \"Employee Benefit Claim\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"label\": \"Employee Tax Exemption Category\",\n \"name\": \"Employee Tax Exemption Category\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"label\": \"Employee Tax Exemption Sub Category\",\n \"name\": \"Employee Tax Exemption Sub Category\",\n \"type\": \"doctype\"\n }\n]" } ], "category": "Modules", "charts": [ { - "chart_name": "Attendance Count", - "label": "Attendance Count" + "chart_name": "Outgoing Salary", + "label": "Outgoing Salary" } ], "creation": "2020-03-02 15:48:58.322521", @@ -75,10 +90,11 @@ "doctype": "Desk Page", "extends_another_page": 0, "hide_custom": 0, + "icon": "hr", "idx": 0, "is_standard": 1, "label": "HR", - "modified": "2020-06-16 19:20:50.976045", + "modified": "2020-06-30 18:34:39.966096", "modified_by": "Administrator", "module": "HR", "name": "HR", @@ -88,13 +104,21 @@ "pin_to_top": 0, "shortcuts": [ { - "color": "#9deca2", + "color": "Green", "format": "{} Active", "label": "Employee", "link_to": "Employee", "stats_filter": "{\"status\":\"Active\"}", "type": "DocType" }, + { + "color": "Yellow", + "format": "{} Open", + "label": "Leave Application", + "link_to": "Leave Application", + "stats_filter": "{\"status\":\"Open\"}", + "type": "DocType" + }, { "label": "Attendance", "link_to": "Attendance", @@ -102,15 +126,8 @@ "type": "DocType" }, { - "format": "{} Open", - "label": "Leave Application", - "link_to": "Leave Application", - "stats_filter": "{\"status\":\"Open\"}", - "type": "DocType" - }, - { - "label": "Job Applicant", - "link_to": "Job Applicant", + "label": "Salary Structure", + "link_to": "Salary Structure", "type": "DocType" }, { diff --git a/erpnext/loan_management/desk_page/loan/loan.json b/erpnext/loan_management/desk_page/loan/loan.json index 48193b0a0d8..95fa22bd698 100644 --- a/erpnext/loan_management/desk_page/loan/loan.json +++ b/erpnext/loan_management/desk_page/loan/loan.json @@ -34,10 +34,12 @@ "docstatus": 0, "doctype": "Desk Page", "extends_another_page": 0, + "hide_custom": 0, + "icon": "loan", "idx": 0, "is_standard": 1, "label": "Loan", - "modified": "2020-06-07 19:42:14.947902", + "modified": "2020-06-30 18:33:53.854122", "modified_by": "Administrator", "module": "Loan Management", "name": "Loan", @@ -46,7 +48,7 @@ "pin_to_top": 0, "shortcuts": [ { - "color": "#ffe8cd", + "color": "Green", "format": "{} Open", "label": "Loan Application", "link_to": "Loan Application", diff --git a/erpnext/manufacturing/desk_page/manufacturing/manufacturing.json b/erpnext/manufacturing/desk_page/manufacturing/manufacturing.json index 8d11294164f..3dd86a38bf7 100644 --- a/erpnext/manufacturing/desk_page/manufacturing/manufacturing.json +++ b/erpnext/manufacturing/desk_page/manufacturing/manufacturing.json @@ -44,10 +44,11 @@ "doctype": "Desk Page", "extends_another_page": 0, "hide_custom": 0, + "icon": "organization", "idx": 0, "is_standard": 1, "label": "Manufacturing", - "modified": "2020-05-28 13:54:02.048419", + "modified": "2020-06-30 18:40:04.454826", "modified_by": "Administrator", "module": "Manufacturing", "name": "Manufacturing", @@ -58,7 +59,7 @@ "restrict_to_domain": "Manufacturing", "shortcuts": [ { - "color": "#cef6d1", + "color": "Green", "format": "{} Active", "label": "Item", "link_to": "Item", @@ -67,7 +68,7 @@ "type": "DocType" }, { - "color": "#cef6d1", + "color": "Green", "format": "{} Active", "label": "BOM", "link_to": "BOM", @@ -76,7 +77,7 @@ "type": "DocType" }, { - "color": "#ffe8cd", + "color": "Yellow", "format": "{} Open", "label": "Work Order", "link_to": "Work Order", @@ -85,7 +86,7 @@ "type": "DocType" }, { - "color": "#ffe8cd", + "color": "Yellow", "format": "{} Open", "label": "Production Plan", "link_to": "Production Plan", diff --git a/erpnext/non_profit/desk_page/non_profit/non_profit.json b/erpnext/non_profit/desk_page/non_profit/non_profit.json index ebe61948935..24d655ad6f6 100644 --- a/erpnext/non_profit/desk_page/non_profit/non_profit.json +++ b/erpnext/non_profit/desk_page/non_profit/non_profit.json @@ -39,10 +39,12 @@ "docstatus": 0, "doctype": "Desk Page", "extends_another_page": 0, + "hide_custom": 0, + "icon": "non-profit", "idx": 0, "is_standard": 1, "label": "Non Profit", - "modified": "2020-04-13 13:41:52.373705", + "modified": "2020-06-30 18:35:52.770917", "modified_by": "Administrator", "module": "Non Profit", "name": "Non Profit", diff --git a/erpnext/payroll/desk_page/payroll/payroll.json b/erpnext/payroll/desk_page/payroll/payroll.json index b5eac465c82..cb063c105c8 100644 --- a/erpnext/payroll/desk_page/payroll/payroll.json +++ b/erpnext/payroll/desk_page/payroll/payroll.json @@ -35,10 +35,11 @@ "doctype": "Desk Page", "extends_another_page": 0, "hide_custom": 0, + "icon": "money-coins-1", "idx": 0, "is_standard": 1, "label": "Payroll", - "modified": "2020-06-19 12:23:06.034046", + "modified": "2020-06-30 18:33:29.072946", "modified_by": "Administrator", "module": "Payroll", "name": "Payroll", diff --git a/erpnext/projects/desk_page/projects/projects.json b/erpnext/projects/desk_page/projects/projects.json index e24cf3081cb..3756c5bb507 100644 --- a/erpnext/projects/desk_page/projects/projects.json +++ b/erpnext/projects/desk_page/projects/projects.json @@ -30,10 +30,11 @@ "doctype": "Desk Page", "extends_another_page": 0, "hide_custom": 0, + "icon": "project", "idx": 0, "is_standard": 1, "label": "Projects", - "modified": "2020-05-28 13:38:19.934937", + "modified": "2020-06-30 18:38:40.130763", "modified_by": "Administrator", "module": "Projects", "name": "Projects", @@ -42,7 +43,7 @@ "pin_to_top": 0, "shortcuts": [ { - "color": "#cef6d1", + "color": "Blue", "format": "{} Assigned", "label": "Task", "link_to": "Task", @@ -50,7 +51,7 @@ "type": "DocType" }, { - "color": "#ffe8cd", + "color": "Blue", "format": "{} Open", "label": "Project", "link_to": "Project", diff --git a/erpnext/quality_management/desk_page/quality/quality.json b/erpnext/quality_management/desk_page/quality/quality.json index 5ee70008dd8..7e5a966df2d 100644 --- a/erpnext/quality_management/desk_page/quality/quality.json +++ b/erpnext/quality_management/desk_page/quality/quality.json @@ -29,11 +29,12 @@ "docstatus": 0, "doctype": "Desk Page", "extends_another_page": 0, - "icon": "", + "hide_custom": 0, + "icon": "quality", "idx": 0, "is_standard": 1, "label": "Quality", - "modified": "2020-04-01 11:28:51.095012", + "modified": "2020-06-30 18:35:36.017107", "modified_by": "Administrator", "module": "Quality Management", "name": "Quality", diff --git a/erpnext/selling/desk_page/retail/retail.json b/erpnext/selling/desk_page/retail/retail.json index 7b30af20ccb..ea62091ffd1 100644 --- a/erpnext/selling/desk_page/retail/retail.json +++ b/erpnext/selling/desk_page/retail/retail.json @@ -14,10 +14,12 @@ "docstatus": 0, "doctype": "Desk Page", "extends_another_page": 0, + "hide_custom": 0, + "icon": "retail", "idx": 0, "is_standard": 1, "label": "Retail", - "modified": "2020-04-26 22:42:39.346750", + "modified": "2020-06-30 18:35:58.987449", "modified_by": "Administrator", "module": "Selling", "name": "Retail", diff --git a/erpnext/selling/desk_page/selling/selling.json b/erpnext/selling/desk_page/selling/selling.json index 225238233a3..7dcb71f5f0e 100644 --- a/erpnext/selling/desk_page/selling/selling.json +++ b/erpnext/selling/desk_page/selling/selling.json @@ -41,10 +41,11 @@ "doctype": "Desk Page", "extends_another_page": 0, "hide_custom": 1, + "icon": "sell", "idx": 0, "is_standard": 1, "label": "Selling", - "modified": "2020-06-29 19:26:35.139097", + "modified": "2020-06-30 18:32:50.587478", "modified_by": "Administrator", "module": "Selling", "name": "Selling", @@ -54,7 +55,7 @@ "pin_to_top": 0, "shortcuts": [ { - "color": "#cef6d1", + "color": "Grey", "format": "{} Available", "label": "Item", "link_to": "Item", @@ -62,7 +63,7 @@ "type": "DocType" }, { - "color": "#ffe8cd", + "color": "Yellow", "format": "{} To Deliver", "label": "Sales Order", "link_to": "Sales Order", @@ -70,7 +71,7 @@ "type": "DocType" }, { - "color": "#cef6d1", + "color": "Grey", "format": "{} Open", "label": "Sales Analytics", "link_to": "Sales Analytics", diff --git a/erpnext/setup/desk_page/erpnext_settings/erpnext_settings.json b/erpnext/setup/desk_page/erpnext_settings/erpnext_settings.json index 253d711b322..92b34b06ac9 100644 --- a/erpnext/setup/desk_page/erpnext_settings/erpnext_settings.json +++ b/erpnext/setup/desk_page/erpnext_settings/erpnext_settings.json @@ -9,10 +9,12 @@ "doctype": "Desk Page", "extends": "Settings", "extends_another_page": 1, + "hide_custom": 0, + "icon": "settings", "idx": 0, "is_standard": 1, "label": "ERPNext Settings", - "modified": "2020-04-01 11:28:51.400851", + "modified": "2020-06-30 18:35:41.160158", "modified_by": "Administrator", "module": "Setup", "name": "ERPNext Settings", diff --git a/erpnext/setup/desk_page/home/home.json b/erpnext/setup/desk_page/home/home.json index 63cd5c5ceca..19e6f62202d 100644 --- a/erpnext/setup/desk_page/home/home.json +++ b/erpnext/setup/desk_page/home/home.json @@ -54,10 +54,12 @@ "docstatus": 0, "doctype": "Desk Page", "extends_another_page": 0, + "hide_custom": 0, + "icon": "getting-started", "idx": 0, "is_standard": 1, "label": "Home", - "modified": "2020-05-11 10:20:37.358701", + "modified": "2020-06-30 18:36:05.637904", "modified_by": "Administrator", "module": "Setup", "name": "Home", diff --git a/erpnext/stock/desk_page/stock/stock.json b/erpnext/stock/desk_page/stock/stock.json index 1bf81f7f0e8..89f40f01424 100644 --- a/erpnext/stock/desk_page/stock/stock.json +++ b/erpnext/stock/desk_page/stock/stock.json @@ -55,10 +55,11 @@ "doctype": "Desk Page", "extends_another_page": 0, "hide_custom": 0, + "icon": "stock", "idx": 0, "is_standard": 1, "label": "Stock", - "modified": "2020-05-30 17:32:11.062681", + "modified": "2020-06-30 18:41:21.822817", "modified_by": "Administrator", "module": "Stock", "name": "Stock", @@ -68,7 +69,7 @@ "pin_to_top": 0, "shortcuts": [ { - "color": "#cef6d1", + "color": "Green", "format": "{} Available", "label": "Item", "link_to": "Item", @@ -76,7 +77,7 @@ "type": "DocType" }, { - "color": "#ffe8cd", + "color": "Yellow", "format": "{} Pending", "label": "Material Request", "link_to": "Material Request", @@ -89,7 +90,7 @@ "type": "DocType" }, { - "color": "#ffe8cd", + "color": "Yellow", "format": "{} To Bill", "label": "Purchase Receipt", "link_to": "Purchase Receipt", @@ -97,7 +98,7 @@ "type": "DocType" }, { - "color": "#ffe8cd", + "color": "Yellow", "format": "{} To Bill", "label": "Delivery Note", "link_to": "Delivery Note", diff --git a/erpnext/support/desk_page/support/support.json b/erpnext/support/desk_page/support/support.json index b1ad7c8aa0a..1a73e05ca3a 100644 --- a/erpnext/support/desk_page/support/support.json +++ b/erpnext/support/desk_page/support/support.json @@ -40,10 +40,11 @@ "doctype": "Desk Page", "extends_another_page": 0, "hide_custom": 0, + "icon": "support", "idx": 0, "is_standard": 1, "label": "Support", - "modified": "2020-06-04 11:54:56.124219", + "modified": "2020-06-30 18:41:35.683929", "modified_by": "Administrator", "module": "Support", "name": "Support", @@ -52,7 +53,7 @@ "pin_to_top": 0, "shortcuts": [ { - "color": "#ffc4c4", + "color": "Yellow", "format": "{} Assigned", "label": "Issue", "link_to": "Issue", From be5e129259490586c8e7b3f94b222a0c5b87b93e Mon Sep 17 00:00:00 2001 From: Shivam Mishra Date: Wed, 8 Jul 2020 12:56:28 +0530 Subject: [PATCH 002/477] feat: update icons for erpnext settings shortcuts --- .../erpnext_settings/erpnext_settings.json | 30 +++++++++---------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/erpnext/setup/desk_page/erpnext_settings/erpnext_settings.json b/erpnext/setup/desk_page/erpnext_settings/erpnext_settings.json index 92b34b06ac9..5c8cd6977b8 100644 --- a/erpnext/setup/desk_page/erpnext_settings/erpnext_settings.json +++ b/erpnext/setup/desk_page/erpnext_settings/erpnext_settings.json @@ -14,7 +14,7 @@ "idx": 0, "is_standard": 1, "label": "ERPNext Settings", - "modified": "2020-06-30 18:35:41.160158", + "modified": "2020-07-08 12:53:44.904241", "modified_by": "Administrator", "module": "Setup", "name": "ERPNext Settings", @@ -23,89 +23,89 @@ "pin_to_top": 0, "shortcuts": [ { - "icon": "octicon octicon-rocket", + "icon": "project", "label": "Projects Settings", "link_to": "Projects Settings", "type": "DocType" }, { - "icon": "octicon octicon-repo", + "icon": "accounting", "label": "Accounts Settings", "link_to": "Accounts Settings", "type": "DocType" }, { - "icon": "octicon octicon-package", + "icon": "stock", "label": "Stock Settings", "link_to": "Stock Settings", "type": "DocType" }, { - "icon": "octicon octicon-organization", + "icon": "hr", "label": "HR Settings", "link_to": "HR Settings", "type": "DocType" }, { - "icon": "octicon octicon-tag", + "icon": "sell", "label": "Selling Settings", "link_to": "Selling Settings", "type": "DocType" }, { - "icon": "octicon octicon-briefcase", + "icon": "buying", "label": "Buying Settings", "link_to": "Buying Settings", "type": "DocType" }, { - "icon": "fa fa-life-ring", + "icon": "support", "label": "Support Settings", "link_to": "Support Settings", "type": "DocType" }, { - "icon": "fa fa-shopping-cart", + "icon": "retail", "label": "Shopping Cart Settings", "link_to": "Shopping Cart Settings", "type": "DocType" }, { - "icon": "fa fa-globe", + "icon": "website", "label": "Portal Settings", "link_to": "Portal Settings", "type": "DocType" }, { - "icon": "octicon octicon-tools", + "icon": "organization", "label": "Manufacturing Settings", "link_to": "Manufacturing Settings", "restrict_to_domain": "Manufacturing", "type": "DocType" }, { - "icon": "octicon octicon-mortar-board", + "icon": "education", "label": "Education Settings", "link_to": "Education Settings", "restrict_to_domain": "Education", "type": "DocType" }, { - "icon": "fa fa-bed", + "icon": "organization", "label": "Hotel Settings", "link_to": "Hotel Settings", "restrict_to_domain": "Hospitality", "type": "DocType" }, { - "icon": "fa fa-heartbeat", + "icon": "non-profit", "label": "Healthcare Settings", "link_to": "Healthcare Settings", "restrict_to_domain": "Healthcare", "type": "DocType" }, { - "icon": "fa fa-cog", + "icon": "setting", "label": "Domain Settings", "link_to": "Domain Settings", "type": "DocType" From 840550e25feac445f213a0cd5d7d6f7d5a5b07a5 Mon Sep 17 00:00:00 2001 From: Shivam Mishra Date: Wed, 8 Jul 2020 15:53:35 +0530 Subject: [PATCH 003/477] refactor: change sequence for profit and loss statement --- .../profit_and_loss_statement.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/erpnext/accounts/report/profit_and_loss_statement/profit_and_loss_statement.py b/erpnext/accounts/report/profit_and_loss_statement/profit_and_loss_statement.py index 7caa7648b12..37af5607165 100644 --- a/erpnext/accounts/report/profit_and_loss_statement/profit_and_loss_statement.py +++ b/erpnext/accounts/report/profit_and_loss_statement/profit_and_loss_statement.py @@ -59,13 +59,6 @@ def get_report_summary(period_list, periodicity, income, expense, net_profit_los expense_label = _("Total Expense") return [ - { - "value": net_profit, - "indicator": "Green" if net_profit > 0 else "Red", - "label": profit_label, - "datatype": "Currency", - "currency": net_profit_loss.get("currency") if net_profit_loss else default_currency - }, { "value": net_income, "label": income_label, @@ -77,6 +70,13 @@ def get_report_summary(period_list, periodicity, income, expense, net_profit_los "label": expense_label, "datatype": "Currency", "currency": expense[-1].get('currency') if expense else default_currency + }, + { + "value": net_profit, + "indicator": "Green" if net_profit > 0 else "Red", + "label": profit_label, + "datatype": "Currency", + "currency": net_profit_loss.get("currency") if net_profit_loss else default_currency } ] From f59d927f73a44dcb683659fd54d757391e752823 Mon Sep 17 00:00:00 2001 From: Shivam Mishra Date: Thu, 9 Jul 2020 10:58:05 +0530 Subject: [PATCH 004/477] feat: update summary items --- erpnext/accounts/report/balance_sheet/balance_sheet.py | 3 --- .../profit_and_loss_statement/profit_and_loss_statement.py | 2 ++ 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/erpnext/accounts/report/balance_sheet/balance_sheet.py b/erpnext/accounts/report/balance_sheet/balance_sheet.py index a858c1998f5..1729abce9ef 100644 --- a/erpnext/accounts/report/balance_sheet/balance_sheet.py +++ b/erpnext/accounts/report/balance_sheet/balance_sheet.py @@ -147,7 +147,6 @@ def get_report_summary(period_list, asset, liability, equity, provisional_profit { "value": net_asset, "label": "Total Asset", - "indicator": "Green", "datatype": "Currency", "currency": currency }, @@ -155,14 +154,12 @@ def get_report_summary(period_list, asset, liability, equity, provisional_profit "value": net_liability, "label": "Total Liability", "datatype": "Currency", - "indicator": "Red", "currency": currency }, { "value": net_equity, "label": "Total Equity", "datatype": "Currency", - "indicator": "Blue", "currency": currency }, { diff --git a/erpnext/accounts/report/profit_and_loss_statement/profit_and_loss_statement.py b/erpnext/accounts/report/profit_and_loss_statement/profit_and_loss_statement.py index 37af5607165..01e1b3ffc3f 100644 --- a/erpnext/accounts/report/profit_and_loss_statement/profit_and_loss_statement.py +++ b/erpnext/accounts/report/profit_and_loss_statement/profit_and_loss_statement.py @@ -65,12 +65,14 @@ def get_report_summary(period_list, periodicity, income, expense, net_profit_los "datatype": "Currency", "currency": income[-1].get('currency') if income else default_currency }, + { "type": "separator", "value": "-"}, { "value": net_expense, "label": expense_label, "datatype": "Currency", "currency": expense[-1].get('currency') if expense else default_currency }, + { "type": "separator", "value": "=", "color": "blue"}, { "value": net_profit, "indicator": "Green" if net_profit > 0 else "Red", From b6fb13258fec75b963656d8cae77cb78ac4a4eb4 Mon Sep 17 00:00:00 2001 From: Shivam Mishra Date: Thu, 9 Jul 2020 16:51:36 +0530 Subject: [PATCH 005/477] feat: move financial statement switcher to page toolbar --- erpnext/public/js/financial_statements.js | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/erpnext/public/js/financial_statements.js b/erpnext/public/js/financial_statements.js index 459c01b269b..b2f7afe53f3 100644 --- a/erpnext/public/js/financial_statements.js +++ b/erpnext/public/js/financial_statements.js @@ -57,18 +57,22 @@ erpnext.financial_statements = { }); }); - report.page.add_inner_button(__("Balance Sheet"), function() { + const views_menu = report.page.add_custom_button_group(__('Financial Statements')); + + report.page.add_custom_menu_item(views_menu, __("Balance Sheet"), function() { var filters = report.get_values(); frappe.set_route('query-report', 'Balance Sheet', {company: filters.company}); - }, __('Financial Statements')); - report.page.add_inner_button(__("Profit and Loss"), function() { + }); + + report.page.add_custom_menu_item(views_menu, __("Profit and Loss"), function() { var filters = report.get_values(); frappe.set_route('query-report', 'Profit and Loss Statement', {company: filters.company}); - }, __('Financial Statements')); - report.page.add_inner_button(__("Cash Flow Statement"), function() { + }); + + report.page.add_custom_menu_item(views_menu, __("Cash Flow Statement"), function() { var filters = report.get_values(); frappe.set_route('query-report', 'Cash Flow', {company: filters.company}); - }, __('Financial Statements')); + }); } }; From 9d829532420689bb2d4692b77180f3c47c54e3b5 Mon Sep 17 00:00:00 2001 From: Anupam K Date: Thu, 6 Aug 2020 23:58:56 +0530 Subject: [PATCH 006/477] fix: Opportunity Status fix --- erpnext/selling/doctype/quotation/quotation.py | 17 ++++++++--------- .../selling/doctype/sales_order/sales_order.py | 1 - 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/erpnext/selling/doctype/quotation/quotation.py b/erpnext/selling/doctype/quotation/quotation.py index 449a968a4f9..01479a16540 100644 --- a/erpnext/selling/doctype/quotation/quotation.py +++ b/erpnext/selling/doctype/quotation/quotation.py @@ -25,7 +25,6 @@ class Quotation(SellingController): def validate(self): super(Quotation, self).validate() self.set_status() - self.update_opportunity() self.validate_uom_is_integer("stock_uom", "qty") self.validate_valid_till() self.set_customer_name() @@ -50,20 +49,20 @@ class Quotation(SellingController): lead_name, company_name = frappe.db.get_value("Lead", self.party_name, ["lead_name", "company_name"]) self.customer_name = company_name or lead_name - def update_opportunity(self): + def update_opportunity(self, status): for opportunity in list(set([d.prevdoc_docname for d in self.get("items")])): if opportunity: - self.update_opportunity_status(opportunity) + self.update_opportunity_status(status, opportunity) if self.opportunity: - self.update_opportunity_status() + self.update_opportunity_status(status) - def update_opportunity_status(self, opportunity=None): + def update_opportunity_status(self, status, opportunity=None): if not opportunity: opportunity = self.opportunity opp = frappe.get_doc("Opportunity", opportunity) - opp.status = None + opp.status = status opp.set_status(update=True) def declare_enquiry_lost(self, lost_reasons_list, detailed_reason=None): @@ -82,7 +81,7 @@ class Quotation(SellingController): else: frappe.throw(_("Invalid lost reason {0}, please create a new lost reason").format(frappe.bold(reason.get('lost_reason')))) - self.update_opportunity() + self.update_opportunity('Lost') self.update_lead() self.save() @@ -95,7 +94,7 @@ class Quotation(SellingController): self.company, self.base_grand_total, self) #update enquiry status - self.update_opportunity() + self.update_opportunity('Quotation') self.update_lead() def on_cancel(self): @@ -105,7 +104,7 @@ class Quotation(SellingController): #update enquiry status self.set_status(update=True) - self.update_opportunity() + self.update_opportunity('Open') self.update_lead() def print_other_charges(self,docname): diff --git a/erpnext/selling/doctype/sales_order/sales_order.py b/erpnext/selling/doctype/sales_order/sales_order.py index ffb66354fa0..f17af69e5be 100755 --- a/erpnext/selling/doctype/sales_order/sales_order.py +++ b/erpnext/selling/doctype/sales_order/sales_order.py @@ -159,7 +159,6 @@ class SalesOrder(SellingController): frappe.throw(_("Quotation {0} is cancelled").format(quotation)) doc.set_status(update=True) - doc.update_opportunity() def validate_drop_ship(self): for d in self.get('items'): From ecc7eedd101f03bbfeb47b78bbdf46e75e28b02c Mon Sep 17 00:00:00 2001 From: Suraj Shetty Date: Sun, 23 Aug 2020 16:35:39 +0530 Subject: [PATCH 007/477] fix: Update erpnext logo --- erpnext/hooks.py | 2 +- erpnext/public/images/erpnext_logo.svg | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) create mode 100644 erpnext/public/images/erpnext_logo.svg diff --git a/erpnext/hooks.py b/erpnext/hooks.py index 463ad6c94b4..1c36c2a30b2 100644 --- a/erpnext/hooks.py +++ b/erpnext/hooks.py @@ -10,7 +10,7 @@ app_color = "#e74c3c" app_email = "info@erpnext.com" app_license = "GNU General Public License (v3)" source_link = "https://github.com/frappe/erpnext" -app_logo_url = '/assets/erpnext/images/erp-icon.svg' +app_logo_url = '/assets/erpnext/images/erpnext_logo.svg' develop_version = '13.x.x-develop' diff --git a/erpnext/public/images/erpnext_logo.svg b/erpnext/public/images/erpnext_logo.svg new file mode 100644 index 00000000000..af3a84953b0 --- /dev/null +++ b/erpnext/public/images/erpnext_logo.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file From a43e760703afc80d5b37f51fe881379b1cdaee3a Mon Sep 17 00:00:00 2001 From: Suraj Shetty Date: Sun, 23 Aug 2020 16:36:28 +0530 Subject: [PATCH 008/477] fix: Item dashboard style --- erpnext/public/less/erpnext.less | 5 +++-- erpnext/stock/dashboard/item_dashboard_list.html | 8 ++++---- erpnext/stock/doctype/item/item_dashboard.py | 8 ++++---- 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/erpnext/public/less/erpnext.less b/erpnext/public/less/erpnext.less index 8685837d33d..1488bdd9c70 100644 --- a/erpnext/public/less/erpnext.less +++ b/erpnext/public/less/erpnext.less @@ -39,8 +39,9 @@ .dashboard-list-item { background-color: inherit; - padding: 5px 0px; - border-bottom: 1px solid @border-color; + border-bottom: 1px solid var(--border-color); + font-size: var(--text-md); + color: var(--text-color); } #page-stock-balance .dashboard-list-item { diff --git a/erpnext/stock/dashboard/item_dashboard_list.html b/erpnext/stock/dashboard/item_dashboard_list.html index e1914ed76a2..0c10be462a1 100644 --- a/erpnext/stock/dashboard/item_dashboard_list.html +++ b/erpnext/stock/dashboard/item_dashboard_list.html @@ -1,10 +1,10 @@ {% for d in data %}
-
+ -
+
{% if show_item %} {{ d.item_code }} @@ -12,7 +12,7 @@ {% endif %}
-
+
{{ d.total_reserved }} @@ -40,7 +40,7 @@
{% if can_write %} -
+
{% if d.actual_qty %}
diff --git a/erpnext/education/doctype/student_admission/templates/student_admission_row.html b/erpnext/education/doctype/student_admission/templates/student_admission_row.html index e0497730377..726602d21c7 100644 --- a/erpnext/education/doctype/student_admission/templates/student_admission_row.html +++ b/erpnext/education/doctype/student_admission/templates/student_admission_row.html @@ -11,7 +11,7 @@ {% elif frappe.utils.getdate(doc.admission_start_date) > today %} blue {% else %} - darkgrey + darkgray {% endif %} ">{{ doc.title }}
diff --git a/erpnext/hr/doctype/employee/employee_list.js b/erpnext/hr/doctype/employee/employee_list.js index 7a66d12bf5e..1a82dd8be7d 100644 --- a/erpnext/hr/doctype/employee/employee_list.js +++ b/erpnext/hr/doctype/employee/employee_list.js @@ -3,7 +3,7 @@ frappe.listview_settings['Employee'] = { filters: [["status","=", "Active"]], get_indicator: function(doc) { var indicator = [__(doc.status), frappe.utils.guess_colour(doc.status), "status,=," + doc.status]; - indicator[1] = {"Active": "green", "Temporary Leave": "red", "Left": "darkgrey"}[doc.status]; + indicator[1] = {"Active": "green", "Temporary Leave": "red", "Left": "darkgray"}[doc.status]; return indicator; } }; diff --git a/erpnext/hr/doctype/leave_allocation/leave_allocation_list.js b/erpnext/hr/doctype/leave_allocation/leave_allocation_list.js index 93f7b8356b3..1af05bde692 100644 --- a/erpnext/hr/doctype/leave_allocation/leave_allocation_list.js +++ b/erpnext/hr/doctype/leave_allocation/leave_allocation_list.js @@ -5,7 +5,7 @@ frappe.listview_settings['Leave Allocation'] = { get_indicator: function(doc) { if(doc.status==="Expired") { - return [__("Expired"), "darkgrey", "expired, =, 1"]; + return [__("Expired"), "darkgray", "expired, =, 1"]; } }, }; diff --git a/erpnext/hr/page/team_updates/team_updates.js b/erpnext/hr/page/team_updates/team_updates.js index da1f5316a0f..030fa66549b 100644 --- a/erpnext/hr/page/team_updates/team_updates.js +++ b/erpnext/hr/page/team_updates/team_updates.js @@ -41,7 +41,7 @@ frappe.team_updates = { me.add_row(d); }); } else { - frappe.show_alert({message:__('No more updates'), indicator:'darkgrey'}); + frappe.show_alert({message:__('No more updates'), indicator:'darkgray'}); me.more.parent().addClass('hidden'); } } diff --git a/erpnext/manufacturing/doctype/bom/bom_list.js b/erpnext/manufacturing/doctype/bom/bom_list.js index 94cb466bd8a..90d1d82528f 100644 --- a/erpnext/manufacturing/doctype/bom/bom_list.js +++ b/erpnext/manufacturing/doctype/bom/bom_list.js @@ -8,7 +8,7 @@ frappe.listview_settings['BOM'] = { } else if(doc.is_active) { return [__("Active"), "blue", "is_active,=,Yes"]; } else if(!doc.is_active) { - return [__("Not active"), "darkgrey", "is_active,=,No"]; + return [__("Not active"), "darkgray", "is_active,=,No"]; } } }; diff --git a/erpnext/manufacturing/doctype/production_plan/production_plan_list.js b/erpnext/manufacturing/doctype/production_plan/production_plan_list.js index d377ef0af76..f5a491402a9 100644 --- a/erpnext/manufacturing/doctype/production_plan/production_plan_list.js +++ b/erpnext/manufacturing/doctype/production_plan/production_plan_list.js @@ -9,8 +9,8 @@ frappe.listview_settings['Production Plan'] = { "Draft": "red", "In Process": "orange", "Completed": "green", - "Material Requested": "darkgrey", - "Cancelled": "darkgrey" + "Material Requested": "darkgray", + "Cancelled": "darkgray" }[doc.status], "status,=," + doc.status]; } } diff --git a/erpnext/manufacturing/doctype/work_order/work_order_list.js b/erpnext/manufacturing/doctype/work_order/work_order_list.js index 8d18395acd4..6959a347c48 100644 --- a/erpnext/manufacturing/doctype/work_order/work_order_list.js +++ b/erpnext/manufacturing/doctype/work_order/work_order_list.js @@ -12,7 +12,7 @@ frappe.listview_settings['Work Order'] = { "Not Started": "red", "In Process": "orange", "Completed": "green", - "Cancelled": "darkgrey" + "Cancelled": "darkgray" }[doc.status], "status,=," + doc.status]; } } diff --git a/erpnext/selling/doctype/quotation/quotation.py b/erpnext/selling/doctype/quotation/quotation.py index ab095ebfe08..af34fe8a04d 100644 --- a/erpnext/selling/doctype/quotation/quotation.py +++ b/erpnext/selling/doctype/quotation/quotation.py @@ -19,7 +19,7 @@ class Quotation(SellingController): self.indicator_color = 'blue' self.indicator_title = 'Submitted' if self.valid_till and getdate(self.valid_till) < getdate(nowdate()): - self.indicator_color = 'darkgrey' + self.indicator_color = 'darkgray' self.indicator_title = 'Expired' def validate(self): diff --git a/erpnext/selling/doctype/quotation/quotation_list.js b/erpnext/selling/doctype/quotation/quotation_list.js index f425acf180a..41a9397e541 100644 --- a/erpnext/selling/doctype/quotation/quotation_list.js +++ b/erpnext/selling/doctype/quotation/quotation_list.js @@ -20,9 +20,9 @@ frappe.listview_settings['Quotation'] = { } else if(doc.status==="Ordered") { return [__("Ordered"), "green", "status,=,Ordered"]; } else if(doc.status==="Lost") { - return [__("Lost"), "darkgrey", "status,=,Lost"]; + return [__("Lost"), "darkgray", "status,=,Lost"]; } else if(doc.status==="Expired") { - return [__("Expired"), "darkgrey", "status,=,Expired"]; + return [__("Expired"), "darkgray", "status,=,Expired"]; } } }; diff --git a/erpnext/stock/doctype/batch/batch_list.js b/erpnext/stock/doctype/batch/batch_list.js index d4f74c3a217..f4ab50c3123 100644 --- a/erpnext/stock/doctype/batch/batch_list.js +++ b/erpnext/stock/doctype/batch/batch_list.js @@ -2,9 +2,9 @@ frappe.listview_settings['Batch'] = { add_fields: ["item", "expiry_date", "batch_qty", "disabled"], get_indicator: (doc) => { if (doc.disabled) { - return [__("Disabled"), "darkgrey", "disabled,=,1"]; + return [__("Disabled"), "darkgray", "disabled,=,1"]; } else if (!doc.batch_qty) { - return [__("Empty"), "darkgrey", "batch_qty,=,0|disabled,=,0"]; + return [__("Empty"), "darkgray", "batch_qty,=,0|disabled,=,0"]; } else if (doc.expiry_date && frappe.datetime.get_diff(doc.expiry_date, frappe.datetime.nowdate()) <= 0) { return [__("Expired"), "red", "expiry_date,not in,|expiry_date,<=,Today|batch_qty,>,0|disabled,=,0"] } else { diff --git a/erpnext/stock/doctype/delivery_note/delivery_note_list.js b/erpnext/stock/doctype/delivery_note/delivery_note_list.js index 0ae7c37b3f8..1fd12f187a9 100644 --- a/erpnext/stock/doctype/delivery_note/delivery_note_list.js +++ b/erpnext/stock/doctype/delivery_note/delivery_note_list.js @@ -3,7 +3,7 @@ frappe.listview_settings['Delivery Note'] = { "transporter_name", "grand_total", "is_return", "status", "currency"], get_indicator: function(doc) { if(cint(doc.is_return)==1) { - return [__("Return"), "darkgrey", "is_return,=,Yes"]; + return [__("Return"), "darkgray", "is_return,=,Yes"]; } else if (doc.status === "Closed") { return [__("Closed"), "green", "status,=,Closed"]; } else if (flt(doc.per_billed, 2) < 100) { diff --git a/erpnext/stock/doctype/purchase_receipt/purchase_receipt_list.js b/erpnext/stock/doctype/purchase_receipt/purchase_receipt_list.js index e81f323a461..f294ce9fcc3 100644 --- a/erpnext/stock/doctype/purchase_receipt/purchase_receipt_list.js +++ b/erpnext/stock/doctype/purchase_receipt/purchase_receipt_list.js @@ -3,7 +3,7 @@ frappe.listview_settings['Purchase Receipt'] = { "transporter_name", "is_return", "status", "per_billed", "currency"], get_indicator: function(doc) { if(cint(doc.is_return)==1) { - return [__("Return"), "darkgrey", "is_return,=,Yes"]; + return [__("Return"), "darkgray", "is_return,=,Yes"]; } else if (doc.status === "Closed") { return [__("Closed"), "green", "status,=,Closed"]; } else if (flt(doc.grand_total) !== 0 && flt(doc.per_billed, 2) < 100) { diff --git a/erpnext/support/doctype/issue/issue_list.js b/erpnext/support/doctype/issue/issue_list.js index 513a8dca222..2a8f05dc426 100644 --- a/erpnext/support/doctype/issue/issue_list.js +++ b/erpnext/support/doctype/issue/issue_list.js @@ -28,7 +28,7 @@ frappe.listview_settings['Issue'] = { } else if (doc.status === 'Closed') { return [__(doc.status), "green", "status,=," + doc.status]; } else { - return [__(doc.status), "darkgrey", "status,=," + doc.status]; + return [__(doc.status), "darkgray", "status,=," + doc.status]; } } } diff --git a/erpnext/templates/includes/address_row.html b/erpnext/templates/includes/address_row.html index dadd2dff103..01aea9100a3 100644 --- a/erpnext/templates/includes/address_row.html +++ b/erpnext/templates/includes/address_row.html @@ -2,7 +2,7 @@
- {{ doc.address_title }} + {{ doc.address_title }}
{{ _(doc.address_type) }}
{{ doc.city }}
diff --git a/erpnext/templates/includes/issue_row.html b/erpnext/templates/includes/issue_row.html index ff868fabb51..e41e78abc66 100644 --- a/erpnext/templates/includes/issue_row.html +++ b/erpnext/templates/includes/issue_row.html @@ -2,7 +2,7 @@
- {% set indicator = 'red' if doc.status == 'Open' else 'darkgrey' %} + {% set indicator = 'red' if doc.status == 'Open' else 'darkgray' %} {% set indicator = 'green' if doc.status == 'Closed' else indicator %} {{ doc.name }} @@ -10,7 +10,7 @@
{{ doc.subject }}
- {% set indicator = 'red' if doc.status == 'Open' else 'darkgrey' %} + {% set indicator = 'red' if doc.status == 'Open' else 'darkgray' %} {% set indicator = 'green' if doc.status == 'Closed' else indicator %} {% set indicator = 'orange' if doc.status == 'Open' and doc.priority == 'Medium' else indicator %} {% set indicator = 'yellow' if doc.status == 'Open' and doc.priority == 'Low' else indicator %} diff --git a/erpnext/templates/includes/projects/project_row.html b/erpnext/templates/includes/projects/project_row.html index 73c83ef560b..3fd102a7370 100644 --- a/erpnext/templates/includes/projects/project_row.html +++ b/erpnext/templates/includes/projects/project_row.html @@ -15,7 +15,7 @@
{% else %} - + {{ doc.status }} {% endif %}
diff --git a/erpnext/templates/includes/projects/project_tasks.html b/erpnext/templates/includes/projects/project_tasks.html index 94c692cdd27..2f148dd58d8 100644 --- a/erpnext/templates/includes/projects/project_tasks.html +++ b/erpnext/templates/includes/projects/project_tasks.html @@ -3,7 +3,7 @@
- {{ task.subject }} + {{ task.subject }}
{{ _("modified") }} {{ frappe.utils.pretty_date(task.modified) }} @@ -16,9 +16,9 @@ {% else %} - + - {% endif %} + {% endif %} {% endif %}
diff --git a/erpnext/templates/includes/timesheet/timesheet_row.html b/erpnext/templates/includes/timesheet/timesheet_row.html index 4852f59b5d2..12bbbfb3ae9 100644 --- a/erpnext/templates/includes/timesheet/timesheet_row.html +++ b/erpnext/templates/includes/timesheet/timesheet_row.html @@ -1,7 +1,7 @@
- + {{ doc.name }}
diff --git a/erpnext/templates/includes/transaction_row.html b/erpnext/templates/includes/transaction_row.html index 80a542f74bf..1f5cb4e92d4 100644 --- a/erpnext/templates/includes/transaction_row.html +++ b/erpnext/templates/includes/transaction_row.html @@ -1,7 +1,7 @@
- + {{ doc.name }}
diff --git a/erpnext/templates/pages/material_request_info.html b/erpnext/templates/pages/material_request_info.html index 9d189895b63..fce4a40498a 100644 --- a/erpnext/templates/pages/material_request_info.html +++ b/erpnext/templates/pages/material_request_info.html @@ -20,7 +20,7 @@
- + {{ _(doc.get('indicator_title')) or _(doc.status) or _("Submitted") }}
diff --git a/erpnext/templates/pages/order.html b/erpnext/templates/pages/order.html index 9e3c58b45be..99414466854 100644 --- a/erpnext/templates/pages/order.html +++ b/erpnext/templates/pages/order.html @@ -34,7 +34,7 @@
- + {{ _(doc.get('indicator_title')) or _(doc.status) or _("Submitted") }}
diff --git a/erpnext/templates/pages/rfq.html b/erpnext/templates/pages/rfq.html index 5b27a94553a..7e7e7f4266a 100644 --- a/erpnext/templates/pages/rfq.html +++ b/erpnext/templates/pages/rfq.html @@ -77,13 +77,13 @@
- {{d.name}} + {{d.name}}
- {{d.status}} + {{d.status}}
- {{d.transaction_date}} + {{d.transaction_date}}
Link From b6ebcd7559b42caa99e06cc8bc1be2055c6fe82d Mon Sep 17 00:00:00 2001 From: Suraj Shetty Date: Thu, 27 Aug 2020 18:57:18 +0530 Subject: [PATCH 012/477] refactor: Replace darkgray indicator with gray indicator --- .../doctype/payment_request/payment_request_list.js | 2 +- .../doctype/purchase_invoice/purchase_invoice_list.js | 8 ++++---- erpnext/accounts/doctype/sales_invoice/sales_invoice.py | 4 ++-- .../accounts/doctype/sales_invoice/sales_invoice_list.js | 4 ++-- .../accounts/doctype/subscription/subscription_list.js | 2 +- .../doctype/supplier_quotation/supplier_quotation_list.js | 4 ++-- .../doctype/supplier_scorecard/supplier_scorecard_list.js | 2 +- erpnext/crm/doctype/contract/contract_list.js | 2 +- .../student_admission/templates/student_admission.html | 2 +- .../templates/student_admission_row.html | 2 +- erpnext/hr/doctype/employee/employee_list.js | 2 +- .../hr/doctype/leave_allocation/leave_allocation_list.js | 2 +- erpnext/hr/page/team_updates/team_updates.js | 2 +- erpnext/manufacturing/doctype/bom/bom_list.js | 2 +- .../doctype/production_plan/production_plan_list.js | 4 ++-- .../manufacturing/doctype/work_order/work_order_list.js | 2 +- erpnext/selling/doctype/quotation/quotation.py | 2 +- erpnext/selling/doctype/quotation/quotation_list.js | 4 ++-- erpnext/stock/doctype/batch/batch_list.js | 4 ++-- erpnext/stock/doctype/delivery_note/delivery_note_list.js | 2 +- .../doctype/purchase_receipt/purchase_receipt_list.js | 2 +- erpnext/support/doctype/issue/issue_list.js | 2 +- erpnext/templates/includes/address_row.html | 2 +- erpnext/templates/includes/issue_row.html | 4 ++-- erpnext/templates/includes/projects/project_row.html | 2 +- erpnext/templates/includes/projects/project_tasks.html | 2 +- .../templates/includes/projects/project_timesheets.html | 2 +- erpnext/templates/includes/timesheet/timesheet_row.html | 2 +- erpnext/templates/includes/transaction_row.html | 2 +- erpnext/templates/pages/material_request_info.html | 2 +- erpnext/templates/pages/order.html | 2 +- erpnext/templates/pages/rfq.html | 6 +++--- 32 files changed, 44 insertions(+), 44 deletions(-) diff --git a/erpnext/accounts/doctype/payment_request/payment_request_list.js b/erpnext/accounts/doctype/payment_request/payment_request_list.js index 4137dfa3dc7..85d729cd61c 100644 --- a/erpnext/accounts/doctype/payment_request/payment_request_list.js +++ b/erpnext/accounts/doctype/payment_request/payment_request_list.js @@ -2,7 +2,7 @@ frappe.listview_settings['Payment Request'] = { add_fields: ["status"], get_indicator: function(doc) { if(doc.status == "Draft") { - return [__("Draft"), "darkgray", "status,=,Draft"]; + return [__("Draft"), "gray", "status,=,Draft"]; } if(doc.status == "Requested") { return [__("Requested"), "green", "status,=,Requested"]; diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice_list.js b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice_list.js index 613d661e08c..661559a6054 100644 --- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice_list.js +++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice_list.js @@ -7,19 +7,19 @@ frappe.listview_settings['Purchase Invoice'] = { "currency", "is_return", "release_date", "on_hold"], get_indicator: function(doc) { if( (flt(doc.outstanding_amount) <= 0) && doc.docstatus == 1 && doc.status == 'Debit Note Issued') { - return [__("Debit Note Issued"), "darkgray", "outstanding_amount,<=,0"]; + return [__("Debit Note Issued"), "gray", "outstanding_amount,<=,0"]; } else if(flt(doc.outstanding_amount) > 0 && doc.docstatus==1) { if(cint(doc.on_hold) && !doc.release_date) { - return [__("On Hold"), "darkgray"]; + return [__("On Hold"), "gray"]; } else if(cint(doc.on_hold) && doc.release_date && frappe.datetime.get_diff(doc.release_date, frappe.datetime.nowdate()) > 0) { - return [__("Temporarily on Hold"), "darkgray"]; + return [__("Temporarily on Hold"), "gray"]; } else if(frappe.datetime.get_diff(doc.due_date) < 0) { return [__("Overdue"), "red", "outstanding_amount,>,0|due_date,<,Today"]; } else { return [__("Unpaid"), "orange", "outstanding_amount,>,0|due_date,>=,Today"]; } } else if(cint(doc.is_return)) { - return [__("Return"), "darkgray", "is_return,=,Yes"]; + return [__("Return"), "gray", "is_return,=,Yes"]; } else if(flt(doc.outstanding_amount)==0 && doc.docstatus==1) { return [__("Paid"), "green", "outstanding_amount,=,0"]; } diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py index 89cdf853e28..cd394384422 100644 --- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py +++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py @@ -53,7 +53,7 @@ class SalesInvoice(SellingController): """Set indicator for portal""" if self.outstanding_amount < 0: self.indicator_title = _("Credit Note Issued") - self.indicator_color = "darkgray" + self.indicator_color = "gray" elif self.outstanding_amount > 0 and getdate(self.due_date) >= getdate(nowdate()): self.indicator_color = "orange" self.indicator_title = _("Unpaid") @@ -62,7 +62,7 @@ class SalesInvoice(SellingController): self.indicator_title = _("Overdue") elif cint(self.is_return) == 1: self.indicator_title = _("Return") - self.indicator_color = "darkgray" + self.indicator_color = "gray" else: self.indicator_color = "green" self.indicator_title = _("Paid") diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice_list.js b/erpnext/accounts/doctype/sales_invoice/sales_invoice_list.js index c85773a31b3..5ac86d6f25a 100644 --- a/erpnext/accounts/doctype/sales_invoice/sales_invoice_list.js +++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice_list.js @@ -10,8 +10,8 @@ frappe.listview_settings['Sales Invoice'] = { "Draft": "grey", "Unpaid": "orange", "Paid": "green", - "Return": "darkgray", - "Credit Note Issued": "darkgray", + "Return": "gray", + "Credit Note Issued": "gray", "Unpaid and Discounted": "orange", "Overdue and Discounted": "red", "Overdue": "red" diff --git a/erpnext/accounts/doctype/subscription/subscription_list.js b/erpnext/accounts/doctype/subscription/subscription_list.js index 4670c6b6bb3..c7325fb9f74 100644 --- a/erpnext/accounts/doctype/subscription/subscription_list.js +++ b/erpnext/accounts/doctype/subscription/subscription_list.js @@ -11,7 +11,7 @@ frappe.listview_settings['Subscription'] = { } else if(doc.status === 'Unpaid') { return [__("Unpaid"), "red"]; } else if(doc.status === 'Cancelled') { - return [__("Cancelled"), "darkgray"]; + return [__("Cancelled"), "gray"]; } } }; \ No newline at end of file diff --git a/erpnext/buying/doctype/supplier_quotation/supplier_quotation_list.js b/erpnext/buying/doctype/supplier_quotation/supplier_quotation_list.js index ede154f9c86..5ab6c980d00 100644 --- a/erpnext/buying/doctype/supplier_quotation/supplier_quotation_list.js +++ b/erpnext/buying/doctype/supplier_quotation/supplier_quotation_list.js @@ -4,9 +4,9 @@ frappe.listview_settings['Supplier Quotation'] = { if(doc.status==="Ordered") { return [__("Ordered"), "green", "status,=,Ordered"]; } else if(doc.status==="Rejected") { - return [__("Lost"), "darkgray", "status,=,Lost"]; + return [__("Lost"), "gray", "status,=,Lost"]; } else if(doc.status==="Expired") { - return [__("Expired"), "darkgray", "status,=,Expired"]; + return [__("Expired"), "gray", "status,=,Expired"]; } } }; diff --git a/erpnext/buying/doctype/supplier_scorecard/supplier_scorecard_list.js b/erpnext/buying/doctype/supplier_scorecard/supplier_scorecard_list.js index aa1e5c37f4f..dc5474e3b43 100644 --- a/erpnext/buying/doctype/supplier_scorecard/supplier_scorecard_list.js +++ b/erpnext/buying/doctype/supplier_scorecard/supplier_scorecard_list.js @@ -10,7 +10,7 @@ frappe.listview_settings["Supplier Scorecard"] = { if (doc.indicator_color) { return [__(doc.status), doc.indicator_color.toLowerCase(), "status,=," + doc.status]; } else { - return [__("Unknown"), "darkgray", "status,=,''"]; + return [__("Unknown"), "gray", "status,=,''"]; } }, diff --git a/erpnext/crm/doctype/contract/contract_list.js b/erpnext/crm/doctype/contract/contract_list.js index ff580455f71..a09d123ed26 100644 --- a/erpnext/crm/doctype/contract/contract_list.js +++ b/erpnext/crm/doctype/contract/contract_list.js @@ -6,7 +6,7 @@ frappe.listview_settings['Contract'] = { } else if (doc.status == "Active") { return [__(doc.status), "green", "status,=," + doc.status]; } else if (doc.status == "Inactive") { - return [__(doc.status), "darkgray", "status,=," + doc.status]; + return [__(doc.status), "gray", "status,=," + doc.status]; } }, }; \ No newline at end of file diff --git a/erpnext/education/doctype/student_admission/templates/student_admission.html b/erpnext/education/doctype/student_admission/templates/student_admission.html index 6fc79b60547..5cbf36a293c 100644 --- a/erpnext/education/doctype/student_admission/templates/student_admission.html +++ b/erpnext/education/doctype/student_admission/templates/student_admission.html @@ -21,7 +21,7 @@ {% elif frappe.utils.getdate(doc.admission_start_date) > today %} blue"> Application will open {% else %} - darkgray + gray {% endif %}
diff --git a/erpnext/education/doctype/student_admission/templates/student_admission_row.html b/erpnext/education/doctype/student_admission/templates/student_admission_row.html index 726602d21c7..288e542ab17 100644 --- a/erpnext/education/doctype/student_admission/templates/student_admission_row.html +++ b/erpnext/education/doctype/student_admission/templates/student_admission_row.html @@ -11,7 +11,7 @@ {% elif frappe.utils.getdate(doc.admission_start_date) > today %} blue {% else %} - darkgray + gray {% endif %} ">{{ doc.title }}
diff --git a/erpnext/hr/doctype/employee/employee_list.js b/erpnext/hr/doctype/employee/employee_list.js index 1a82dd8be7d..44837030be8 100644 --- a/erpnext/hr/doctype/employee/employee_list.js +++ b/erpnext/hr/doctype/employee/employee_list.js @@ -3,7 +3,7 @@ frappe.listview_settings['Employee'] = { filters: [["status","=", "Active"]], get_indicator: function(doc) { var indicator = [__(doc.status), frappe.utils.guess_colour(doc.status), "status,=," + doc.status]; - indicator[1] = {"Active": "green", "Temporary Leave": "red", "Left": "darkgray"}[doc.status]; + indicator[1] = {"Active": "green", "Temporary Leave": "red", "Left": "gray"}[doc.status]; return indicator; } }; diff --git a/erpnext/hr/doctype/leave_allocation/leave_allocation_list.js b/erpnext/hr/doctype/leave_allocation/leave_allocation_list.js index 1af05bde692..3ab176f8099 100644 --- a/erpnext/hr/doctype/leave_allocation/leave_allocation_list.js +++ b/erpnext/hr/doctype/leave_allocation/leave_allocation_list.js @@ -5,7 +5,7 @@ frappe.listview_settings['Leave Allocation'] = { get_indicator: function(doc) { if(doc.status==="Expired") { - return [__("Expired"), "darkgray", "expired, =, 1"]; + return [__("Expired"), "gray", "expired, =, 1"]; } }, }; diff --git a/erpnext/hr/page/team_updates/team_updates.js b/erpnext/hr/page/team_updates/team_updates.js index 030fa66549b..29780b81619 100644 --- a/erpnext/hr/page/team_updates/team_updates.js +++ b/erpnext/hr/page/team_updates/team_updates.js @@ -41,7 +41,7 @@ frappe.team_updates = { me.add_row(d); }); } else { - frappe.show_alert({message:__('No more updates'), indicator:'darkgray'}); + frappe.show_alert({message:__('No more updates'), indicator:'gray'}); me.more.parent().addClass('hidden'); } } diff --git a/erpnext/manufacturing/doctype/bom/bom_list.js b/erpnext/manufacturing/doctype/bom/bom_list.js index 90d1d82528f..4b5887f180c 100644 --- a/erpnext/manufacturing/doctype/bom/bom_list.js +++ b/erpnext/manufacturing/doctype/bom/bom_list.js @@ -8,7 +8,7 @@ frappe.listview_settings['BOM'] = { } else if(doc.is_active) { return [__("Active"), "blue", "is_active,=,Yes"]; } else if(!doc.is_active) { - return [__("Not active"), "darkgray", "is_active,=,No"]; + return [__("Not active"), "gray", "is_active,=,No"]; } } }; diff --git a/erpnext/manufacturing/doctype/production_plan/production_plan_list.js b/erpnext/manufacturing/doctype/production_plan/production_plan_list.js index f5a491402a9..5c814942151 100644 --- a/erpnext/manufacturing/doctype/production_plan/production_plan_list.js +++ b/erpnext/manufacturing/doctype/production_plan/production_plan_list.js @@ -9,8 +9,8 @@ frappe.listview_settings['Production Plan'] = { "Draft": "red", "In Process": "orange", "Completed": "green", - "Material Requested": "darkgray", - "Cancelled": "darkgray" + "Material Requested": "gray", + "Cancelled": "gray" }[doc.status], "status,=," + doc.status]; } } diff --git a/erpnext/manufacturing/doctype/work_order/work_order_list.js b/erpnext/manufacturing/doctype/work_order/work_order_list.js index 6959a347c48..81c23bb7104 100644 --- a/erpnext/manufacturing/doctype/work_order/work_order_list.js +++ b/erpnext/manufacturing/doctype/work_order/work_order_list.js @@ -12,7 +12,7 @@ frappe.listview_settings['Work Order'] = { "Not Started": "red", "In Process": "orange", "Completed": "green", - "Cancelled": "darkgray" + "Cancelled": "gray" }[doc.status], "status,=," + doc.status]; } } diff --git a/erpnext/selling/doctype/quotation/quotation.py b/erpnext/selling/doctype/quotation/quotation.py index af34fe8a04d..4fb19f88b85 100644 --- a/erpnext/selling/doctype/quotation/quotation.py +++ b/erpnext/selling/doctype/quotation/quotation.py @@ -19,7 +19,7 @@ class Quotation(SellingController): self.indicator_color = 'blue' self.indicator_title = 'Submitted' if self.valid_till and getdate(self.valid_till) < getdate(nowdate()): - self.indicator_color = 'darkgray' + self.indicator_color = 'gray' self.indicator_title = 'Expired' def validate(self): diff --git a/erpnext/selling/doctype/quotation/quotation_list.js b/erpnext/selling/doctype/quotation/quotation_list.js index 41a9397e541..b631685bd19 100644 --- a/erpnext/selling/doctype/quotation/quotation_list.js +++ b/erpnext/selling/doctype/quotation/quotation_list.js @@ -20,9 +20,9 @@ frappe.listview_settings['Quotation'] = { } else if(doc.status==="Ordered") { return [__("Ordered"), "green", "status,=,Ordered"]; } else if(doc.status==="Lost") { - return [__("Lost"), "darkgray", "status,=,Lost"]; + return [__("Lost"), "gray", "status,=,Lost"]; } else if(doc.status==="Expired") { - return [__("Expired"), "darkgray", "status,=,Expired"]; + return [__("Expired"), "gray", "status,=,Expired"]; } } }; diff --git a/erpnext/stock/doctype/batch/batch_list.js b/erpnext/stock/doctype/batch/batch_list.js index f4ab50c3123..0de9fd01503 100644 --- a/erpnext/stock/doctype/batch/batch_list.js +++ b/erpnext/stock/doctype/batch/batch_list.js @@ -2,9 +2,9 @@ frappe.listview_settings['Batch'] = { add_fields: ["item", "expiry_date", "batch_qty", "disabled"], get_indicator: (doc) => { if (doc.disabled) { - return [__("Disabled"), "darkgray", "disabled,=,1"]; + return [__("Disabled"), "gray", "disabled,=,1"]; } else if (!doc.batch_qty) { - return [__("Empty"), "darkgray", "batch_qty,=,0|disabled,=,0"]; + return [__("Empty"), "gray", "batch_qty,=,0|disabled,=,0"]; } else if (doc.expiry_date && frappe.datetime.get_diff(doc.expiry_date, frappe.datetime.nowdate()) <= 0) { return [__("Expired"), "red", "expiry_date,not in,|expiry_date,<=,Today|batch_qty,>,0|disabled,=,0"] } else { diff --git a/erpnext/stock/doctype/delivery_note/delivery_note_list.js b/erpnext/stock/doctype/delivery_note/delivery_note_list.js index 1fd12f187a9..98ababa075a 100644 --- a/erpnext/stock/doctype/delivery_note/delivery_note_list.js +++ b/erpnext/stock/doctype/delivery_note/delivery_note_list.js @@ -3,7 +3,7 @@ frappe.listview_settings['Delivery Note'] = { "transporter_name", "grand_total", "is_return", "status", "currency"], get_indicator: function(doc) { if(cint(doc.is_return)==1) { - return [__("Return"), "darkgray", "is_return,=,Yes"]; + return [__("Return"), "gray", "is_return,=,Yes"]; } else if (doc.status === "Closed") { return [__("Closed"), "green", "status,=,Closed"]; } else if (flt(doc.per_billed, 2) < 100) { diff --git a/erpnext/stock/doctype/purchase_receipt/purchase_receipt_list.js b/erpnext/stock/doctype/purchase_receipt/purchase_receipt_list.js index f294ce9fcc3..aed2e4968ff 100644 --- a/erpnext/stock/doctype/purchase_receipt/purchase_receipt_list.js +++ b/erpnext/stock/doctype/purchase_receipt/purchase_receipt_list.js @@ -3,7 +3,7 @@ frappe.listview_settings['Purchase Receipt'] = { "transporter_name", "is_return", "status", "per_billed", "currency"], get_indicator: function(doc) { if(cint(doc.is_return)==1) { - return [__("Return"), "darkgray", "is_return,=,Yes"]; + return [__("Return"), "gray", "is_return,=,Yes"]; } else if (doc.status === "Closed") { return [__("Closed"), "green", "status,=,Closed"]; } else if (flt(doc.grand_total) !== 0 && flt(doc.per_billed, 2) < 100) { diff --git a/erpnext/support/doctype/issue/issue_list.js b/erpnext/support/doctype/issue/issue_list.js index 2a8f05dc426..e04498e29ee 100644 --- a/erpnext/support/doctype/issue/issue_list.js +++ b/erpnext/support/doctype/issue/issue_list.js @@ -28,7 +28,7 @@ frappe.listview_settings['Issue'] = { } else if (doc.status === 'Closed') { return [__(doc.status), "green", "status,=," + doc.status]; } else { - return [__(doc.status), "darkgray", "status,=," + doc.status]; + return [__(doc.status), "gray", "status,=," + doc.status]; } } } diff --git a/erpnext/templates/includes/address_row.html b/erpnext/templates/includes/address_row.html index 01aea9100a3..6d4dd5444cd 100644 --- a/erpnext/templates/includes/address_row.html +++ b/erpnext/templates/includes/address_row.html @@ -2,7 +2,7 @@
- {{ doc.address_title }} + {{ doc.address_title }}
{{ _(doc.address_type) }}
{{ doc.city }}
diff --git a/erpnext/templates/includes/issue_row.html b/erpnext/templates/includes/issue_row.html index e41e78abc66..d909c5feea2 100644 --- a/erpnext/templates/includes/issue_row.html +++ b/erpnext/templates/includes/issue_row.html @@ -2,7 +2,7 @@
- {% set indicator = 'red' if doc.status == 'Open' else 'darkgray' %} + {% set indicator = 'red' if doc.status == 'Open' else 'gray' %} {% set indicator = 'green' if doc.status == 'Closed' else indicator %} {{ doc.name }} @@ -10,7 +10,7 @@
{{ doc.subject }}
- {% set indicator = 'red' if doc.status == 'Open' else 'darkgray' %} + {% set indicator = 'red' if doc.status == 'Open' else 'gray' %} {% set indicator = 'green' if doc.status == 'Closed' else indicator %} {% set indicator = 'orange' if doc.status == 'Open' and doc.priority == 'Medium' else indicator %} {% set indicator = 'yellow' if doc.status == 'Open' and doc.priority == 'Low' else indicator %} diff --git a/erpnext/templates/includes/projects/project_row.html b/erpnext/templates/includes/projects/project_row.html index 3fd102a7370..4c8c40db003 100644 --- a/erpnext/templates/includes/projects/project_row.html +++ b/erpnext/templates/includes/projects/project_row.html @@ -15,7 +15,7 @@
{% else %} - + {{ doc.status }} {% endif %}
diff --git a/erpnext/templates/includes/projects/project_tasks.html b/erpnext/templates/includes/projects/project_tasks.html index 2f148dd58d8..50b9f4b2597 100644 --- a/erpnext/templates/includes/projects/project_tasks.html +++ b/erpnext/templates/includes/projects/project_tasks.html @@ -3,7 +3,7 @@
- {{ task.subject }} + {{ task.subject }}
{{ _("modified") }} {{ frappe.utils.pretty_date(task.modified) }} diff --git a/erpnext/templates/includes/projects/project_timesheets.html b/erpnext/templates/includes/projects/project_timesheets.html index e2a9c60069e..05a07c12e8b 100644 --- a/erpnext/templates/includes/projects/project_timesheets.html +++ b/erpnext/templates/includes/projects/project_timesheets.html @@ -3,7 +3,7 @@
- {{ timesheet.info.name }} + {{ timesheet.info.name }}
{{ _("From") }} {{ frappe.format_date(timesheet.from_time) }} {{ _("to") }} {{ frappe.format_date(timesheet.to_time) }}
diff --git a/erpnext/templates/includes/timesheet/timesheet_row.html b/erpnext/templates/includes/timesheet/timesheet_row.html index 12bbbfb3ae9..0f9cc77e89d 100644 --- a/erpnext/templates/includes/timesheet/timesheet_row.html +++ b/erpnext/templates/includes/timesheet/timesheet_row.html @@ -1,7 +1,7 @@
- + {{ doc.name }}
diff --git a/erpnext/templates/includes/transaction_row.html b/erpnext/templates/includes/transaction_row.html index 1f5cb4e92d4..383413103e1 100644 --- a/erpnext/templates/includes/transaction_row.html +++ b/erpnext/templates/includes/transaction_row.html @@ -1,7 +1,7 @@
- + {{ doc.name }}
diff --git a/erpnext/templates/pages/material_request_info.html b/erpnext/templates/pages/material_request_info.html index fce4a40498a..b6399e74816 100644 --- a/erpnext/templates/pages/material_request_info.html +++ b/erpnext/templates/pages/material_request_info.html @@ -20,7 +20,7 @@
- + {{ _(doc.get('indicator_title')) or _(doc.status) or _("Submitted") }}
diff --git a/erpnext/templates/pages/order.html b/erpnext/templates/pages/order.html index 99414466854..3db05bdeab1 100644 --- a/erpnext/templates/pages/order.html +++ b/erpnext/templates/pages/order.html @@ -34,7 +34,7 @@
- + {{ _(doc.get('indicator_title')) or _(doc.status) or _("Submitted") }}
diff --git a/erpnext/templates/pages/rfq.html b/erpnext/templates/pages/rfq.html index 7e7e7f4266a..6e2edb6391b 100644 --- a/erpnext/templates/pages/rfq.html +++ b/erpnext/templates/pages/rfq.html @@ -77,13 +77,13 @@
- {{d.name}} + {{d.name}}
- {{d.status}} + {{d.status}}
- {{d.transaction_date}} + {{d.transaction_date}}
Link From a49af09705f96fc44464b8fc766d43d4210c82c3 Mon Sep 17 00:00:00 2001 From: Suraj Shetty Date: Thu, 27 Aug 2020 18:57:43 +0530 Subject: [PATCH 013/477] fix: Primary button icon --- erpnext/accounts/doctype/account/account_tree.js | 2 +- erpnext/support/doctype/issue/issue.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/erpnext/accounts/doctype/account/account_tree.js b/erpnext/accounts/doctype/account/account_tree.js index 28b090bdadb..ea8ca0b7d8f 100644 --- a/erpnext/accounts/doctype/account/account_tree.js +++ b/erpnext/accounts/doctype/account/account_tree.js @@ -120,7 +120,7 @@ frappe.treeview_settings["Account"] = { } else { treeview.new_node(); } - }, "octicon octicon-plus"); + }, "add"); }, onrender: function(node) { if(frappe.boot.user.can_read.indexOf("GL Entry") !== -1){ diff --git a/erpnext/support/doctype/issue/issue.js b/erpnext/support/doctype/issue/issue.js index 9e15757ce08..95ff197802e 100644 --- a/erpnext/support/doctype/issue/issue.js +++ b/erpnext/support/doctype/issue/issue.js @@ -164,7 +164,7 @@ frappe.ui.form.on("Issue", { ${split_issue} `) .appendTo(frm.timeline.wrapper.find('.comment-header .asset-details:not([data-communication-type="Comment"])')) - if (!frm.timeline.wrapper.data("split-issue-event-attached")){ + if (!frm.timeline.wrapper.data("split-issue-event-attached")) { frm.timeline.wrapper.on('click', '.btn-split-issue', (e) => { var dialog = new frappe.ui.Dialog({ title: __("Split Issue"), From a324e9bd1252da3abadb0c2ae556c34d593d14d1 Mon Sep 17 00:00:00 2001 From: prssanna Date: Thu, 27 Aug 2020 19:26:14 +0530 Subject: [PATCH 014/477] fix: remove text-muted and small class fromtree items --- erpnext/accounts/doctype/account/account_tree.js | 2 +- .../healthcare_service_unit/healthcare_service_unit_tree.js | 6 +++--- erpnext/stock/doctype/warehouse/warehouse_tree.js | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/erpnext/accounts/doctype/account/account_tree.js b/erpnext/accounts/doctype/account/account_tree.js index ea8ca0b7d8f..e7539f86ed5 100644 --- a/erpnext/accounts/doctype/account/account_tree.js +++ b/erpnext/accounts/doctype/account/account_tree.js @@ -130,7 +130,7 @@ frappe.treeview_settings["Account"] = { let dr_or_cr = balance > 0 ? "Dr": "Cr"; if (node.data && node.data.balance!==undefined) { - $('' + $('' + (node.data.balance_in_account_currency ? (format_currency(Math.abs(node.data.balance_in_account_currency), node.data.account_currency) + " / ") : "") diff --git a/erpnext/healthcare/doctype/healthcare_service_unit/healthcare_service_unit_tree.js b/erpnext/healthcare/doctype/healthcare_service_unit/healthcare_service_unit_tree.js index a03b579c507..bfb0ba13ceb 100644 --- a/erpnext/healthcare/doctype/healthcare_service_unit/healthcare_service_unit_tree.js +++ b/erpnext/healthcare/doctype/healthcare_service_unit/healthcare_service_unit_tree.js @@ -13,19 +13,19 @@ frappe.treeview_settings["Healthcare Service Unit"] = { ignore_fields:["parent_healthcare_service_unit"], onrender: function(node) { if (node.data.occupied_out_of_vacant!==undefined){ - $('' + $('' + " " + node.data.occupied_out_of_vacant + '').insertBefore(node.$ul); } if (node.data && node.data.inpatient_occupancy!==undefined) { if (node.data.inpatient_occupancy == 1){ if (node.data.occupancy_status == "Occupied"){ - $('' + $('' + " " + node.data.occupancy_status + '').insertBefore(node.$ul); } if (node.data.occupancy_status == "Vacant"){ - $('' + $('' + " " + node.data.occupancy_status + '').insertBefore(node.$ul); } diff --git a/erpnext/stock/doctype/warehouse/warehouse_tree.js b/erpnext/stock/doctype/warehouse/warehouse_tree.js index 918d2f15593..3665c0530f2 100644 --- a/erpnext/stock/doctype/warehouse/warehouse_tree.js +++ b/erpnext/stock/doctype/warehouse/warehouse_tree.js @@ -19,7 +19,7 @@ frappe.treeview_settings['Warehouse'] = { ignore_fields:["parent_warehouse"], onrender: function(node) { if (node.data && node.data.balance!==undefined) { - $('' + $('' + format_currency(Math.abs(node.data.balance), node.data.company_currency) + '').insertBefore(node.$ul); } From fa400820bb619ffd7c95e23a8208e2003226aa6d Mon Sep 17 00:00:00 2001 From: prssanna Date: Fri, 28 Aug 2020 15:02:04 +0530 Subject: [PATCH 016/477] fix: move leaderboard style to frappe --- erpnext/public/less/erpnext.less | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/erpnext/public/less/erpnext.less b/erpnext/public/less/erpnext.less index 1488bdd9c70..4076ebec1fd 100644 --- a/erpnext/public/less/erpnext.less +++ b/erpnext/public/less/erpnext.less @@ -447,20 +447,6 @@ body[data-route="pos"] { } -// Leaderboard - -.leaderboard { - .result { - border-top: 1px solid #d1d8dd; - } - .list-item { - padding-left: 45px; - } - .list-item_content { - padding-right: 45px; - } -} - // Healthcare .exercise-card { From 288ced24dbf771988b1c601d2e6d5f0fde07bd12 Mon Sep 17 00:00:00 2001 From: michellealva Date: Sun, 30 Aug 2020 19:33:27 +0530 Subject: [PATCH 017/477] feat: Add Naming Series for Project DocType --- erpnext/projects/doctype/project/project.json | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/erpnext/projects/doctype/project/project.json b/erpnext/projects/doctype/project/project.json index f3cecd9059b..122a1a96f4e 100644 --- a/erpnext/projects/doctype/project/project.json +++ b/erpnext/projects/doctype/project/project.json @@ -2,12 +2,13 @@ "actions": [], "allow_import": 1, "allow_rename": 1, - "autoname": "field:project_name", + "autoname": "naming_series:", "creation": "2013-03-07 11:55:07", "doctype": "DocType", "document_type": "Setup", "engine": "InnoDB", "field_order": [ + "naming_series", "project_name", "status", "project_type", @@ -440,13 +441,22 @@ "fieldtype": "Text", "label": "Message", "mandatory_depends_on": "collect_progress" + }, + { + "fieldname": "naming_series", + "fieldtype": "Select", + "hidden": 1, + "label": "Series", + "options": "PROJ.####", + "set_only_once": 1 } ], "icon": "fa fa-puzzle-piece", "idx": 29, + "index_web_pages_for_search": 1, "links": [], "max_attachments": 4, - "modified": "2020-04-08 22:11:14.552615", + "modified": "2020-08-30 19:32:40.050707", "modified_by": "Administrator", "module": "Projects", "name": "Project", @@ -488,5 +498,6 @@ "sort_field": "modified", "sort_order": "DESC", "timeline_field": "customer", + "title_field": "project_name", "track_seen": 1 -} +} \ No newline at end of file From f46c1c5164b44e7f8ce3ad65a90189688f291740 Mon Sep 17 00:00:00 2001 From: michellealva Date: Sun, 30 Aug 2020 21:37:45 +0530 Subject: [PATCH 018/477] fix: Change property of field --- erpnext/projects/doctype/project/project.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/erpnext/projects/doctype/project/project.json b/erpnext/projects/doctype/project/project.json index 122a1a96f4e..c91b01eaa9f 100644 --- a/erpnext/projects/doctype/project/project.json +++ b/erpnext/projects/doctype/project/project.json @@ -445,9 +445,9 @@ { "fieldname": "naming_series", "fieldtype": "Select", - "hidden": 1, "label": "Series", "options": "PROJ.####", + "reqd": 1, "set_only_once": 1 } ], @@ -456,7 +456,7 @@ "index_web_pages_for_search": 1, "links": [], "max_attachments": 4, - "modified": "2020-08-30 19:32:40.050707", + "modified": "2020-08-30 21:36:45.915818", "modified_by": "Administrator", "module": "Projects", "name": "Project", From df00c5c84601e9a7b3ccf5f423671c1fcb59a9d3 Mon Sep 17 00:00:00 2001 From: Suraj Shetty Date: Tue, 1 Sep 2020 13:55:34 +0530 Subject: [PATCH 019/477] fix: Update erpnext logo --- erpnext/hooks.py | 2 +- erpnext/public/images/erpnext-logo.svg | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) create mode 100644 erpnext/public/images/erpnext-logo.svg diff --git a/erpnext/hooks.py b/erpnext/hooks.py index 1c36c2a30b2..b71c4652d1c 100644 --- a/erpnext/hooks.py +++ b/erpnext/hooks.py @@ -10,7 +10,7 @@ app_color = "#e74c3c" app_email = "info@erpnext.com" app_license = "GNU General Public License (v3)" source_link = "https://github.com/frappe/erpnext" -app_logo_url = '/assets/erpnext/images/erpnext_logo.svg' +app_logo_url = '/assets/erpnext/images/erpnext-logo.svg' develop_version = '13.x.x-develop' diff --git a/erpnext/public/images/erpnext-logo.svg b/erpnext/public/images/erpnext-logo.svg new file mode 100644 index 00000000000..a3ac3bb2ce2 --- /dev/null +++ b/erpnext/public/images/erpnext-logo.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file From f51cf9f23e0e41e6db5b5538ba2c4f75b24bfe74 Mon Sep 17 00:00:00 2001 From: marination Date: Wed, 2 Sep 2020 11:43:36 +0530 Subject: [PATCH 020/477] fix: Crop Cycle Test --- erpnext/agriculture/doctype/crop_cycle/crop_cycle.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/agriculture/doctype/crop_cycle/crop_cycle.py b/erpnext/agriculture/doctype/crop_cycle/crop_cycle.py index cae150c428a..afbd9b4e6e0 100644 --- a/erpnext/agriculture/doctype/crop_cycle/crop_cycle.py +++ b/erpnext/agriculture/doctype/crop_cycle/crop_cycle.py @@ -48,7 +48,7 @@ class CropCycle(Document): def import_disease_tasks(self, disease, start_date): disease_doc = frappe.get_doc('Disease', disease) - self.create_task(disease_doc.treatment_task, self.name, start_date) + self.create_task(disease_doc.treatment_task, self.project, start_date) def create_project(self, period, crop_tasks): project = frappe.get_doc({ From 099d6718c914198475153bf6498cc57ed6fd6396 Mon Sep 17 00:00:00 2001 From: marination Date: Wed, 2 Sep 2020 11:54:55 +0530 Subject: [PATCH 021/477] fix: Dont Copy or Print Naming Series --- erpnext/projects/doctype/project/project.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/erpnext/projects/doctype/project/project.json b/erpnext/projects/doctype/project/project.json index c91b01eaa9f..8ed68888541 100644 --- a/erpnext/projects/doctype/project/project.json +++ b/erpnext/projects/doctype/project/project.json @@ -446,7 +446,9 @@ "fieldname": "naming_series", "fieldtype": "Select", "label": "Series", + "no_copy": 1, "options": "PROJ.####", + "print_hide": 1, "reqd": 1, "set_only_once": 1 } @@ -456,7 +458,7 @@ "index_web_pages_for_search": 1, "links": [], "max_attachments": 4, - "modified": "2020-08-30 21:36:45.915818", + "modified": "2020-09-02 11:54:01.223620", "modified_by": "Administrator", "module": "Projects", "name": "Project", From d8c38249e03e2206c41cd86c64d31cae431845e5 Mon Sep 17 00:00:00 2001 From: Michelle Alva <50285544+michellealva@users.noreply.github.com> Date: Thu, 3 Sep 2020 09:04:21 +0530 Subject: [PATCH 022/477] fix: Change naming series Co-authored-by: Himanshu --- erpnext/projects/doctype/project/project.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/erpnext/projects/doctype/project/project.json b/erpnext/projects/doctype/project/project.json index 8ed68888541..3cdfcb212f5 100644 --- a/erpnext/projects/doctype/project/project.json +++ b/erpnext/projects/doctype/project/project.json @@ -447,7 +447,7 @@ "fieldtype": "Select", "label": "Series", "no_copy": 1, - "options": "PROJ.####", + "options": "PROJ-.####", "print_hide": 1, "reqd": 1, "set_only_once": 1 @@ -502,4 +502,4 @@ "timeline_field": "customer", "title_field": "project_name", "track_seen": 1 -} \ No newline at end of file +} From 2b405b9bb3118f15f9a68de383fed878fed5a05d Mon Sep 17 00:00:00 2001 From: Shivam Mishra Date: Thu, 10 Sep 2020 15:37:54 +0530 Subject: [PATCH 023/477] feat: add icon to healthcare desk page --- erpnext/healthcare/desk_page/healthcare/healthcare.json | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/erpnext/healthcare/desk_page/healthcare/healthcare.json b/erpnext/healthcare/desk_page/healthcare/healthcare.json index 6546b08db99..353d86f4d7f 100644 --- a/erpnext/healthcare/desk_page/healthcare/healthcare.json +++ b/erpnext/healthcare/desk_page/healthcare/healthcare.json @@ -61,10 +61,11 @@ "doctype": "Desk Page", "extends_another_page": 0, "hide_custom": 0, + "icon": "healthcare", "idx": 0, "is_standard": 1, "label": "Healthcare", - "modified": "2020-06-25 23:50:56.951698", + "modified": "2020-09-10 15:37:23.666787", "modified_by": "Administrator", "module": "Healthcare", "name": "Healthcare", @@ -75,7 +76,7 @@ "restrict_to_domain": "Healthcare", "shortcuts": [ { - "color": "#ffe8cd", + "color": "Orange", "format": "{} Open", "label": "Patient Appointment", "link_to": "Patient Appointment", @@ -83,7 +84,7 @@ "type": "DocType" }, { - "color": "#ffe8cd", + "color": "Orange", "format": "{} Active", "label": "Patient", "link_to": "Patient", @@ -91,7 +92,7 @@ "type": "DocType" }, { - "color": "#cef6d1", + "color": "Green", "format": "{} Vacant", "label": "Healthcare Service Unit", "link_to": "Healthcare Service Unit", From 67095d239f27e2e18ae3c61f183b84dcba911976 Mon Sep 17 00:00:00 2001 From: Suraj Shetty Date: Thu, 10 Sep 2020 17:15:52 +0530 Subject: [PATCH 024/477] fix: Custom dashboard sections --- .../opening_invoice_creation_tool.js | 3 ++- .../opening_invoice_creation_tool_dashboard.html | 1 - .../assets/doctype/asset_maintenance/asset_maintenance.js | 5 ++--- erpnext/hr/doctype/leave_application/leave_application.js | 3 ++- .../leave_application/leave_application_dashboard.html | 1 - erpnext/stock/doctype/batch/batch.js | 3 +-- erpnext/stock/doctype/item/item.js | 3 +-- 7 files changed, 8 insertions(+), 11 deletions(-) diff --git a/erpnext/accounts/doctype/opening_invoice_creation_tool/opening_invoice_creation_tool.js b/erpnext/accounts/doctype/opening_invoice_creation_tool/opening_invoice_creation_tool.js index 699eb08e178..08e30b52e27 100644 --- a/erpnext/accounts/doctype/opening_invoice_creation_tool/opening_invoice_creation_tool.js +++ b/erpnext/accounts/doctype/opening_invoice_creation_tool/opening_invoice_creation_tool.js @@ -101,7 +101,8 @@ frappe.ui.form.on('Opening Invoice Creation Tool', { frappe.render_template('opening_invoice_creation_tool_dashboard', { data: opening_invoices_summary, max_count: max_count - }) + }), + __("Opening Invoices Summary") ); section.on('click', '.invoice-link', function() { diff --git a/erpnext/accounts/doctype/opening_invoice_creation_tool/opening_invoice_creation_tool_dashboard.html b/erpnext/accounts/doctype/opening_invoice_creation_tool/opening_invoice_creation_tool_dashboard.html index 5b136d4f666..afbcfa5602a 100644 --- a/erpnext/accounts/doctype/opening_invoice_creation_tool/opening_invoice_creation_tool_dashboard.html +++ b/erpnext/accounts/doctype/opening_invoice_creation_tool/opening_invoice_creation_tool_dashboard.html @@ -1,4 +1,3 @@ -
{{ __("Opening Invoices Summary") }}
{% $.each(data, (company, summary) => { %}
{{ company }}
diff --git a/erpnext/assets/doctype/asset_maintenance/asset_maintenance.js b/erpnext/assets/doctype/asset_maintenance/asset_maintenance.js index 001fc26ffe7..70b8654509f 100644 --- a/erpnext/assets/doctype/asset_maintenance/asset_maintenance.js +++ b/erpnext/assets/doctype/asset_maintenance/asset_maintenance.js @@ -40,14 +40,13 @@ frappe.ui.form.on('Asset Maintenance', { if(!r.message) { return; } - var section = frm.dashboard.add_section(`
- ${ __("Maintenance Log") }
`); + const section = frm.dashboard.add_section('', __("Maintenance Log")); var rows = $('
').appendTo(section); // show (r.message || []).forEach(function(d) { $(`
- ${d.maintenance_status} ${d.count} diff --git a/erpnext/hr/doctype/leave_application/leave_application.js b/erpnext/hr/doctype/leave_application/leave_application.js index d62e418b17e..9ccb915908f 100755 --- a/erpnext/hr/doctype/leave_application/leave_application.js +++ b/erpnext/hr/doctype/leave_application/leave_application.js @@ -75,7 +75,8 @@ frappe.ui.form.on("Leave Application", { frm.dashboard.add_section( frappe.render_template('leave_application_dashboard', { data: leave_details - }) + }), + __("Allocated Leaves") ); frm.dashboard.show(); let allowed_leave_types = Object.keys(leave_details); diff --git a/erpnext/hr/doctype/leave_application/leave_application_dashboard.html b/erpnext/hr/doctype/leave_application/leave_application_dashboard.html index d30e3b9f9c6..6324b049272 100644 --- a/erpnext/hr/doctype/leave_application/leave_application_dashboard.html +++ b/erpnext/hr/doctype/leave_application/leave_application_dashboard.html @@ -1,6 +1,5 @@ {% if not jQuery.isEmptyObject(data) %} -
{{ __("Allocated Leaves") }}
diff --git a/erpnext/stock/doctype/batch/batch.js b/erpnext/stock/doctype/batch/batch.js index e2ea7f992ce..71a3e7abcab 100644 --- a/erpnext/stock/doctype/batch/batch.js +++ b/erpnext/stock/doctype/batch/batch.js @@ -47,8 +47,7 @@ frappe.ui.form.on('Batch', { return; } - var section = frm.dashboard.add_section(`
- ${ __("Stock Levels") }
`); + const section = frm.dashboard.add_section('', __("Stock Levels")); // sort by qty r.message.sort(function(a, b) { a.qty > b.qty ? 1 : -1 }); diff --git a/erpnext/stock/doctype/item/item.js b/erpnext/stock/doctype/item/item.js index 38e5fe53a7c..e07e653703b 100644 --- a/erpnext/stock/doctype/item/item.js +++ b/erpnext/stock/doctype/item/item.js @@ -380,8 +380,7 @@ $.extend(erpnext.item, { // Show Stock Levels only if is_stock_item if (frm.doc.is_stock_item) { frappe.require('assets/js/item-dashboard.min.js', function() { - var section = frm.dashboard.add_section('
\ - ' + __("Stock Levels") + '
'); + const section = frm.dashboard.add_section('', __("Stock Levels")); erpnext.item.item_dashboard = new erpnext.stock.ItemDashboard({ parent: section, item_code: frm.doc.name From 1323a9a990ec8f4f05dcd997e52216a55eb93b34 Mon Sep 17 00:00:00 2001 From: Shivam Mishra Date: Wed, 30 Sep 2020 16:33:14 +0530 Subject: [PATCH 025/477] feat: set app name for ERPNext in install and patch --- erpnext/patches.txt | 1 + erpnext/patches/v13_0/set_app_name.py | 8 ++++++++ erpnext/setup/install.py | 5 +++++ 3 files changed, 14 insertions(+) create mode 100644 erpnext/patches/v13_0/set_app_name.py diff --git a/erpnext/patches.txt b/erpnext/patches.txt index 6087ce29aa5..95dfff797a1 100644 --- a/erpnext/patches.txt +++ b/erpnext/patches.txt @@ -729,3 +729,4 @@ erpnext.patches.v13_0.setting_custom_roles_for_some_regional_reports erpnext.patches.v13_0.rename_issue_doctype_fields erpnext.patches.v13_0.change_default_pos_print_format erpnext.patches.v13_0.set_youtube_video_id +erpnext.patches.v13_0.set_app_name diff --git a/erpnext/patches/v13_0/set_app_name.py b/erpnext/patches/v13_0/set_app_name.py new file mode 100644 index 00000000000..0c78b657704 --- /dev/null +++ b/erpnext/patches/v13_0/set_app_name.py @@ -0,0 +1,8 @@ +import frappe +from frappe import _ + +def execute(): + frappe.reload_doctype("System Settings") + settings = frappe.get_doc("System Settings") + settings.app_name = _("ERPNext") + settings.save() \ No newline at end of file diff --git a/erpnext/setup/install.py b/erpnext/setup/install.py index 2225fe169f5..0bb480bd4b6 100644 --- a/erpnext/setup/install.py +++ b/erpnext/setup/install.py @@ -28,6 +28,7 @@ def after_install(): create_default_energy_point_rules() add_company_to_session_defaults() add_standard_navbar_items() + add_app_name() frappe.db.commit() @@ -158,3 +159,7 @@ def add_standard_navbar_items(): }) navbar_settings.save() + +def add_app_name(): + settings = frappe.get_doc("System Settings") + settings.app_name = _("ERPNext") \ No newline at end of file From 6a506b63bf5b4928481c9f5768bc847d30c464d6 Mon Sep 17 00:00:00 2001 From: Shivam Mishra Date: Mon, 5 Oct 2020 12:41:30 +0530 Subject: [PATCH 026/477] fix: variables path --- erpnext/public/scss/website.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/public/scss/website.scss b/erpnext/public/scss/website.scss index 617e916724d..24a1b3780c1 100644 --- a/erpnext/public/scss/website.scss +++ b/erpnext/public/scss/website.scss @@ -1,4 +1,4 @@ -@import "frappe/public/scss/variables"; +@import "frappe/public/scss/website/variables"; .product-image img { min-height: 20rem; From 73d944da21045d1f6387b5fc583e37e37850c30d Mon Sep 17 00:00:00 2001 From: Anupam Date: Tue, 13 Oct 2020 18:11:05 +0530 Subject: [PATCH 027/477] fix: review changes --- erpnext/selling/doctype/quotation/quotation.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/selling/doctype/quotation/quotation.py b/erpnext/selling/doctype/quotation/quotation.py index 7c55d7742f8..3157982d528 100644 --- a/erpnext/selling/doctype/quotation/quotation.py +++ b/erpnext/selling/doctype/quotation/quotation.py @@ -62,7 +62,7 @@ class Quotation(SellingController): opportunity = self.opportunity opp = frappe.get_doc("Opportunity", opportunity) - opp.status = status + opp.set_status(status=status) opp.set_status(update=True) def declare_enquiry_lost(self, lost_reasons_list, detailed_reason=None): From cb8457b9ae8de30522b132cbc97f8e3326227602 Mon Sep 17 00:00:00 2001 From: Shivam Mishra Date: Thu, 15 Oct 2020 13:53:12 +0530 Subject: [PATCH 028/477] feat: add description to Accounts onboarding --- erpnext/accounts/module_onboarding/accounts/accounts.json | 2 +- .../chart_of_accounts/chart_of_accounts.json | 6 +++++- .../configure_account_settings.json | 3 ++- .../create_a_customer/create_a_customer.json | 4 +++- .../onboarding_step/create_a_product/create_a_product.json | 3 ++- .../create_a_supplier/create_a_supplier.json | 3 ++- .../create_your_first_purchase_invoice.json | 3 ++- .../create_your_first_sales_invoice.json | 3 ++- .../accounts/onboarding_step/setup_taxes/setup_taxes.json | 3 ++- erpnext/stock/module_onboarding/stock/stock.json | 2 +- .../onboarding_step/create_a_product/create_a_product.json | 2 +- .../create_a_purchase_receipt.json | 2 +- .../create_a_stock_entry/create_a_stock_entry.json | 2 +- .../create_a_supplier/create_a_supplier.json | 2 +- .../introduction_to_stock_entry.json | 2 +- .../setup_your_warehouse/setup_your_warehouse.json | 2 +- .../onboarding_step/stock_settings/stock_settings.json | 2 +- 17 files changed, 29 insertions(+), 17 deletions(-) diff --git a/erpnext/accounts/module_onboarding/accounts/accounts.json b/erpnext/accounts/module_onboarding/accounts/accounts.json index ba1a779b4c1..98272c38912 100644 --- a/erpnext/accounts/module_onboarding/accounts/accounts.json +++ b/erpnext/accounts/module_onboarding/accounts/accounts.json @@ -13,7 +13,7 @@ "documentation_url": "https://docs.erpnext.com/docs/user/manual/en/accounts", "idx": 0, "is_complete": 0, - "modified": "2020-07-08 14:06:09.033880", + "modified": "2020-10-15 13:52:40.068450", "modified_by": "Administrator", "module": "Accounts", "name": "Accounts", diff --git a/erpnext/accounts/onboarding_step/chart_of_accounts/chart_of_accounts.json b/erpnext/accounts/onboarding_step/chart_of_accounts/chart_of_accounts.json index cbd022bfdbe..a1532302a16 100644 --- a/erpnext/accounts/onboarding_step/chart_of_accounts/chart_of_accounts.json +++ b/erpnext/accounts/onboarding_step/chart_of_accounts/chart_of_accounts.json @@ -1,14 +1,18 @@ { "action": "Go to Page", + "callback_message": "Great! Let's move to the next step!", + "callback_title": "Awesome Work", "creation": "2020-05-13 19:58:20.928127", + "description": "# Chart Of Accounts\n\n**The Chart of Accounts is the blueprint of the accounts in your organization.**\n\nThe overall structure of your Chart of Accounts is based on a system of double entry\naccounting that has become a standard all over the world to quantify how a\ncompany is doing financially.\n\nChart of Accounts is a tree view of the names of the Accounts (Ledgers and\nGroups) that a Company requires to manage its books of accounts. ERPNext sets\nup a simple chart of accounts for each Company you create, but you can\nmodify it according to your needs and legal requirements.\n\nFor each company, Chart of Accounts signifies the way to classify the accounting entries, mostly\nbased on statutory (tax, compliance to government regulations) requirements.\n\nThe Chart of Accounts helps you to answer questions like:\n\n * What is your organization worth?\n * How much debt have you taken?\n * How much profit are you making (and hence paying tax)?\n * How much are you selling?\n * What is your expense break-up?\n", "docstatus": 0, "doctype": "Onboarding Step", "idx": 0, + "intro_video_url": "https://www.youtube.com/embed/AcfMCT7wLLo", "is_complete": 0, "is_mandatory": 0, "is_single": 0, "is_skipped": 0, - "modified": "2020-05-14 17:40:28.410447", + "modified": "2020-10-15 13:12:04.771355", "modified_by": "Administrator", "name": "Chart Of Accounts", "owner": "Administrator", diff --git a/erpnext/accounts/onboarding_step/configure_account_settings/configure_account_settings.json b/erpnext/accounts/onboarding_step/configure_account_settings/configure_account_settings.json index c8be357de0a..1e8f1034a36 100644 --- a/erpnext/accounts/onboarding_step/configure_account_settings/configure_account_settings.json +++ b/erpnext/accounts/onboarding_step/configure_account_settings/configure_account_settings.json @@ -1,6 +1,7 @@ { "action": "Create Entry", "creation": "2020-05-14 17:53:00.876946", + "description": "# Account Settings\n\nThis is a crucial piece of configuration. There are various account settings in ERPNext to restrict and configure actions in the Accounting module.\n\nThe following settings are avaialble for you to configure\n\n1. Account Freezing \n2. Credit and Overbilling\n3. Invoicing and Tax Automations\n4. Balance Sheet configurations\n\nThere's much more, you can check it all out in this step", "docstatus": 0, "doctype": "Onboarding Step", "idx": 0, @@ -8,7 +9,7 @@ "is_mandatory": 0, "is_single": 1, "is_skipped": 0, - "modified": "2020-05-14 18:06:25.212923", + "modified": "2020-10-15 13:45:14.687458", "modified_by": "Administrator", "name": "Configure Account Settings", "owner": "Administrator", diff --git a/erpnext/accounts/onboarding_step/create_a_customer/create_a_customer.json b/erpnext/accounts/onboarding_step/create_a_customer/create_a_customer.json index 5a403b06cf0..02434a09bf6 100644 --- a/erpnext/accounts/onboarding_step/create_a_customer/create_a_customer.json +++ b/erpnext/accounts/onboarding_step/create_a_customer/create_a_customer.json @@ -1,14 +1,16 @@ { "action": "Create Entry", "creation": "2020-05-14 17:46:41.831517", + "description": "# Customer\n\nA customer, who is sometimes known as a client, buyer, or purchaser is the one who receives goods, services, products, or ideas, from a seller for a monetary consideration.\n\n### Creating a customer is easy and can be done in the following steps\n\n1. Go to the Customer list and click on New.\n2. Enter Full Name of the customer.\n3. Select **Company** if the customer represents a company or **Individual** otherwise in Type field.\n4. Select a Customer Group. A few groups are included by default, you can create additional groups if you need.\n5. Select the Territory.\n6. If the customer is being created against a lead, you can select the same in From Lead field.\n7. Save.\n\nUp next is a video about customers and suppliers that will give you more clarity on these concepts in ERPNext", "docstatus": 0, "doctype": "Onboarding Step", "idx": 0, + "intro_video_url": "https://www.youtube.com/watch?v=zsrrVDk6VBs", "is_complete": 0, "is_mandatory": 0, "is_single": 0, "is_skipped": 0, - "modified": "2020-06-01 13:16:19.731719", + "modified": "2020-10-15 13:37:59.699228", "modified_by": "Administrator", "name": "Create a Customer", "owner": "Administrator", diff --git a/erpnext/accounts/onboarding_step/create_a_product/create_a_product.json b/erpnext/accounts/onboarding_step/create_a_product/create_a_product.json index d2068e167b7..3214d8ecf1b 100644 --- a/erpnext/accounts/onboarding_step/create_a_product/create_a_product.json +++ b/erpnext/accounts/onboarding_step/create_a_product/create_a_product.json @@ -1,6 +1,7 @@ { "action": "Create Entry", "creation": "2020-05-12 18:16:06.624554", + "description": "## Creating Products\n\nIn ERPNext, any product or a service offered by your company is called an Item. The term Item is also applicable to raw materials or components of products yet to be produced (before they can be sold to customers). ERPNext allows you to manage all sorts of items like raw-materials, sub-assemblies, finished goods, item variants, and service items.\n\nERPNext is optimized for itemized management of your sales and purchase. If you are in services, you can create an Item for each service that you offer. Completing the Item Master is very essential for the successful implementation of ERPNext.\n\nYou can access the Item section\n\n`Desk > Stock > Item`\n\n\n", "docstatus": 0, "doctype": "Onboarding Step", "idx": 0, @@ -8,7 +9,7 @@ "is_mandatory": 0, "is_single": 0, "is_skipped": 0, - "modified": "2020-05-12 18:30:02.489949", + "modified": "2020-10-15 13:30:46.817174", "modified_by": "Administrator", "name": "Create a Product", "owner": "Administrator", diff --git a/erpnext/accounts/onboarding_step/create_a_supplier/create_a_supplier.json b/erpnext/accounts/onboarding_step/create_a_supplier/create_a_supplier.json index 7a64224bd43..62d643aa72e 100644 --- a/erpnext/accounts/onboarding_step/create_a_supplier/create_a_supplier.json +++ b/erpnext/accounts/onboarding_step/create_a_supplier/create_a_supplier.json @@ -1,6 +1,7 @@ { "action": "Create Entry", "creation": "2020-05-14 22:09:10.043554", + "description": "## Let's add your Suppliers\n\nSuppliers are companies or individuals who provide you with products or services. A supplier may be distinguished from a contractor or subcontractor, who commonly adds specialized input to deliverables. A supplier is also known as a vendor. There are different types of suppliers based on the goods and products they supply.\n\nERPNext allows you to create your own categories of suppliers. These categories are known as Supplier Groups. For example, if your suppliers are mainly pharmaceutical companies and FMCG distributors, you can create a new Supplier Groups for them and name the groups accordingly.", "docstatus": 0, "doctype": "Onboarding Step", "idx": 0, @@ -8,7 +9,7 @@ "is_mandatory": 0, "is_single": 0, "is_skipped": 0, - "modified": "2020-05-14 22:09:10.043554", + "modified": "2020-10-15 13:32:39.651700", "modified_by": "Administrator", "name": "Create a Supplier", "owner": "Administrator", diff --git a/erpnext/accounts/onboarding_step/create_your_first_purchase_invoice/create_your_first_purchase_invoice.json b/erpnext/accounts/onboarding_step/create_your_first_purchase_invoice/create_your_first_purchase_invoice.json index 3a2b8d39253..2e753d63b3b 100644 --- a/erpnext/accounts/onboarding_step/create_your_first_purchase_invoice/create_your_first_purchase_invoice.json +++ b/erpnext/accounts/onboarding_step/create_your_first_purchase_invoice/create_your_first_purchase_invoice.json @@ -1,6 +1,7 @@ { "action": "Create Entry", "creation": "2020-05-14 22:10:07.049704", + "description": "# What's a Purchase Invoice?\n\nA Purchase Invoice is a bill you receive from your Suppliers against which you need to make the payment.\nPurchase Invoice is the exact opposite of your Sales Invoice. Here you accrue expenses to your Supplier. Making a Purchase Invoice is very similar to making a Purchase Order.\n\n![Purchase Flow](https://docs.erpnext.com/docs/assets/img/accounts/pi-flow.png)\n\n", "docstatus": 0, "doctype": "Onboarding Step", "idx": 0, @@ -8,7 +9,7 @@ "is_mandatory": 0, "is_single": 0, "is_skipped": 0, - "modified": "2020-05-14 22:10:07.049704", + "modified": "2020-10-15 13:33:56.079882", "modified_by": "Administrator", "name": "Create Your First Purchase Invoice", "owner": "Administrator", diff --git a/erpnext/accounts/onboarding_step/create_your_first_sales_invoice/create_your_first_sales_invoice.json b/erpnext/accounts/onboarding_step/create_your_first_sales_invoice/create_your_first_sales_invoice.json index 473de5079f5..bcf2c56dad7 100644 --- a/erpnext/accounts/onboarding_step/create_your_first_sales_invoice/create_your_first_sales_invoice.json +++ b/erpnext/accounts/onboarding_step/create_your_first_sales_invoice/create_your_first_sales_invoice.json @@ -1,6 +1,7 @@ { "action": "Create Entry", "creation": "2020-05-14 17:48:21.019019", + "description": "# All about sales invoice\n\nA Sales Invoice is a bill that you send to your Customers against which the Customer makes the payment. Sales Invoice is an accounting transaction. On submission of Sales Invoice, the system updates the receivable and books income against a Customer Account.\n\nHere's the flow of how a sales invoice is generally created\n\n\n![Sales Flow](https://docs.erpnext.com/docs/assets/img/accounts/so-flow.png)", "docstatus": 0, "doctype": "Onboarding Step", "idx": 0, @@ -8,7 +9,7 @@ "is_mandatory": 0, "is_single": 0, "is_skipped": 0, - "modified": "2020-05-14 17:48:21.019019", + "modified": "2020-10-15 13:39:43.970254", "modified_by": "Administrator", "name": "Create Your First Sales Invoice", "owner": "Administrator", diff --git a/erpnext/accounts/onboarding_step/setup_taxes/setup_taxes.json b/erpnext/accounts/onboarding_step/setup_taxes/setup_taxes.json index 8e0006762d1..2eedf56a839 100644 --- a/erpnext/accounts/onboarding_step/setup_taxes/setup_taxes.json +++ b/erpnext/accounts/onboarding_step/setup_taxes/setup_taxes.json @@ -1,6 +1,7 @@ { "action": "Create Entry", "creation": "2020-05-13 19:29:43.844463", + "description": "# Setting up Taxes\n\nOne of the primary motivators for compulsory use of accounting tools is the calculation of taxes. ERPNext allows you to make configurable tax templates that you can apply to your sales or purchase transactions.\n\nThe templates created from this form can be used in Sales Orders and Sales Invoices. The way ERPNext sets up taxes is via templates. Other types of charges that may apply to your invoices (like shipping, insurance etc.) can also be configured as taxes.\n\nFor Tax Accounts that you want to use in the tax templates, go to:\n\n`> Home > Accounting > Chart of Accounts`\n\nSelect an account and click on edit. Select the 'Account Type' as 'Tax' for the account.\nIn this step we will guide you towards making the sales and taxes template.", "docstatus": 0, "doctype": "Onboarding Step", "idx": 0, @@ -8,7 +9,7 @@ "is_mandatory": 0, "is_single": 0, "is_skipped": 0, - "modified": "2020-05-14 17:40:16.014413", + "modified": "2020-10-15 13:21:17.333438", "modified_by": "Administrator", "name": "Setup Taxes", "owner": "Administrator", diff --git a/erpnext/stock/module_onboarding/stock/stock.json b/erpnext/stock/module_onboarding/stock/stock.json index 1d5bf8c97ca..847464822b4 100644 --- a/erpnext/stock/module_onboarding/stock/stock.json +++ b/erpnext/stock/module_onboarding/stock/stock.json @@ -19,7 +19,7 @@ "documentation_url": "https://docs.erpnext.com/docs/user/manual/en/stock", "idx": 0, "is_complete": 0, - "modified": "2020-07-08 14:22:07.951891", + "modified": "2020-10-14 14:54:42.741971", "modified_by": "Administrator", "module": "Stock", "name": "Stock", diff --git a/erpnext/stock/onboarding_step/create_a_product/create_a_product.json b/erpnext/stock/onboarding_step/create_a_product/create_a_product.json index d2068e167b7..335137d8528 100644 --- a/erpnext/stock/onboarding_step/create_a_product/create_a_product.json +++ b/erpnext/stock/onboarding_step/create_a_product/create_a_product.json @@ -8,7 +8,7 @@ "is_mandatory": 0, "is_single": 0, "is_skipped": 0, - "modified": "2020-05-12 18:30:02.489949", + "modified": "2020-10-14 14:53:00.133574", "modified_by": "Administrator", "name": "Create a Product", "owner": "Administrator", diff --git a/erpnext/stock/onboarding_step/create_a_purchase_receipt/create_a_purchase_receipt.json b/erpnext/stock/onboarding_step/create_a_purchase_receipt/create_a_purchase_receipt.json index b7811a46df4..9012493f57e 100644 --- a/erpnext/stock/onboarding_step/create_a_purchase_receipt/create_a_purchase_receipt.json +++ b/erpnext/stock/onboarding_step/create_a_purchase_receipt/create_a_purchase_receipt.json @@ -8,7 +8,7 @@ "is_mandatory": 0, "is_single": 0, "is_skipped": 0, - "modified": "2020-05-19 18:59:13.266713", + "modified": "2020-10-14 14:53:25.618434", "modified_by": "Administrator", "name": "Create a Purchase Receipt", "owner": "Administrator", diff --git a/erpnext/stock/onboarding_step/create_a_stock_entry/create_a_stock_entry.json b/erpnext/stock/onboarding_step/create_a_stock_entry/create_a_stock_entry.json index 2b83f657d6e..09902b8844e 100644 --- a/erpnext/stock/onboarding_step/create_a_stock_entry/create_a_stock_entry.json +++ b/erpnext/stock/onboarding_step/create_a_stock_entry/create_a_stock_entry.json @@ -8,7 +8,7 @@ "is_mandatory": 0, "is_single": 0, "is_skipped": 0, - "modified": "2020-05-15 03:30:58.047696", + "modified": "2020-10-14 14:53:00.105905", "modified_by": "Administrator", "name": "Create a Stock Entry", "owner": "Administrator", diff --git a/erpnext/stock/onboarding_step/create_a_supplier/create_a_supplier.json b/erpnext/stock/onboarding_step/create_a_supplier/create_a_supplier.json index 7a64224bd43..ef61fa3b2e2 100644 --- a/erpnext/stock/onboarding_step/create_a_supplier/create_a_supplier.json +++ b/erpnext/stock/onboarding_step/create_a_supplier/create_a_supplier.json @@ -8,7 +8,7 @@ "is_mandatory": 0, "is_single": 0, "is_skipped": 0, - "modified": "2020-05-14 22:09:10.043554", + "modified": "2020-10-14 14:53:00.120455", "modified_by": "Administrator", "name": "Create a Supplier", "owner": "Administrator", diff --git a/erpnext/stock/onboarding_step/introduction_to_stock_entry/introduction_to_stock_entry.json b/erpnext/stock/onboarding_step/introduction_to_stock_entry/introduction_to_stock_entry.json index 009a44f6e4d..212e5055eda 100644 --- a/erpnext/stock/onboarding_step/introduction_to_stock_entry/introduction_to_stock_entry.json +++ b/erpnext/stock/onboarding_step/introduction_to_stock_entry/introduction_to_stock_entry.json @@ -8,7 +8,7 @@ "is_mandatory": 0, "is_single": 0, "is_skipped": 0, - "modified": "2020-05-26 15:55:41.457289", + "modified": "2020-10-14 14:53:00.075177", "modified_by": "Administrator", "name": "Introduction to Stock Entry", "owner": "Administrator", diff --git a/erpnext/stock/onboarding_step/setup_your_warehouse/setup_your_warehouse.json b/erpnext/stock/onboarding_step/setup_your_warehouse/setup_your_warehouse.json index 9457deee262..75940ed2a6c 100644 --- a/erpnext/stock/onboarding_step/setup_your_warehouse/setup_your_warehouse.json +++ b/erpnext/stock/onboarding_step/setup_your_warehouse/setup_your_warehouse.json @@ -8,7 +8,7 @@ "is_mandatory": 0, "is_single": 0, "is_skipped": 0, - "modified": "2020-07-04 12:33:16.970031", + "modified": "2020-10-14 14:53:25.538900", "modified_by": "Administrator", "name": "Setup your Warehouse", "owner": "Administrator", diff --git a/erpnext/stock/onboarding_step/stock_settings/stock_settings.json b/erpnext/stock/onboarding_step/stock_settings/stock_settings.json index 7591bff5386..ae34afa695f 100644 --- a/erpnext/stock/onboarding_step/stock_settings/stock_settings.json +++ b/erpnext/stock/onboarding_step/stock_settings/stock_settings.json @@ -8,7 +8,7 @@ "is_mandatory": 0, "is_single": 1, "is_skipped": 0, - "modified": "2020-05-15 03:55:15.444151", + "modified": "2020-10-14 14:53:00.092504", "modified_by": "Administrator", "name": "Stock Settings", "owner": "Administrator", From 12d4be7f3f9303f7ad42596cf26b1b2aaf159424 Mon Sep 17 00:00:00 2001 From: prssanna Date: Fri, 16 Oct 2020 11:31:47 +0530 Subject: [PATCH 029/477] feat: icons in leaderboard --- erpnext/startup/leaderboard.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/erpnext/startup/leaderboard.py b/erpnext/startup/leaderboard.py index ef238f1165d..8819a55c0ab 100644 --- a/erpnext/startup/leaderboard.py +++ b/erpnext/startup/leaderboard.py @@ -12,6 +12,7 @@ def get_leaderboards(): {'fieldname': 'outstanding_amount', 'fieldtype': 'Currency'} ], "method": "erpnext.startup.leaderboard.get_all_customers", + "icon": "customer" }, "Item": { "fields": [ @@ -23,6 +24,7 @@ def get_leaderboards(): {'fieldname': 'available_stock_value', 'fieldtype': 'Currency'} ], "method": "erpnext.startup.leaderboard.get_all_items", + "icon": "stock" }, "Supplier": { "fields": [ @@ -31,6 +33,7 @@ def get_leaderboards(): {'fieldname': 'outstanding_amount', 'fieldtype': 'Currency'} ], "method": "erpnext.startup.leaderboard.get_all_suppliers", + "icon": "buying" }, "Sales Partner": { "fields": [ @@ -38,12 +41,14 @@ def get_leaderboards(): {'fieldname': 'total_commission', 'fieldtype': 'Currency'} ], "method": "erpnext.startup.leaderboard.get_all_sales_partner", + "icon": "hr" }, "Sales Person": { "fields": [ {'fieldname': 'total_sales_amount', 'fieldtype': 'Currency'} ], "method": "erpnext.startup.leaderboard.get_all_sales_person", + "icon": "customer" } } From 5418818683fb1d211772cb1e0467e7355c30eb3a Mon Sep 17 00:00:00 2001 From: Shivam Mishra Date: Fri, 16 Oct 2020 14:24:00 +0530 Subject: [PATCH 030/477] feat: add tour for account settings --- .../accounts_settings/accounts_settings.js | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/erpnext/accounts/doctype/accounts_settings/accounts_settings.js b/erpnext/accounts/doctype/accounts_settings/accounts_settings.js index 0627675de79..541901c9abf 100644 --- a/erpnext/accounts/doctype/accounts_settings/accounts_settings.js +++ b/erpnext/accounts/doctype/accounts_settings/accounts_settings.js @@ -6,3 +6,46 @@ frappe.ui.form.on('Accounts Settings', { } }); + +frappe.tour['Accounts Settings'] = [ + { + fieldname: "acc_frozen_upto", + title: "Accounts Frozen Upto", + description: __("Freeze accounting transactions up to specified date, nobody can make/modify entry except the specified Role."), + }, + { + fieldname: "frozen_accounts_modifier", + title: "Role Allowed to Set Frozen Accounts & Edit Frozen Entries", + description: __("Users with this Role are allowed to set frozen accounts and create/modify accounting entries against frozen accounts.") + }, + { + fieldname: "determine_address_tax_category_from", + title: "Determine Address Tax Category From", + description: __("Tax category can be set on Addresses. An address can be Shipping or Billing address. Set which addres to select when applying Tax Category.") + }, + { + fieldname: "over_billing_allowance", + title: "Over Billing Allowance Percentage", + description: __("The percentage by which you can overbill transactions. For example, if the order value is $100 for an Item and percentage here is set as 10% then you are allowed to bill for $110.") + }, + { + fieldname: "credit_controller", + title: "Credit Controller", + description: __("Select the role that is allowed to submit transactions that exceed credit limits set. The credit limit can be set in the Customer form.") + }, + { + fieldname: "make_payment_via_journal_entry", + title: "Make Payment via Journal Entry", + description: __("When checked, if user proceeds to make payment from an invoice, the system will open a Journal Entry instead of a Payment Entry.") + }, + { + fieldname: "unlink_payment_on_cancellation_of_invoice", + title: "Unlink Payment on Cancellation of Invoice", + description: __("If checked, system will unlink the payment against the respective invoice.") + }, + { + fieldname: "unlink_advance_payment_on_cancelation_of_order", + title: "Unlink Advance Payment on Cancellation of Order", + description: __("Similar to the previous option, this unlinks any advance payments made against Purchase/Sales Orders.") + } +]; \ No newline at end of file From 8261df29c4f35fce8109d5df2258d263bcd64642 Mon Sep 17 00:00:00 2001 From: Shivam Mishra Date: Mon, 19 Oct 2020 13:52:35 +0530 Subject: [PATCH 031/477] feat: update splash logo --- erpnext/hooks.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/erpnext/hooks.py b/erpnext/hooks.py index b510208720d..9fa60742bd1 100644 --- a/erpnext/hooks.py +++ b/erpnext/hooks.py @@ -10,7 +10,7 @@ app_color = "#e74c3c" app_email = "info@erpnext.com" app_license = "GNU General Public License (v3)" source_link = "https://github.com/frappe/erpnext" -app_logo_url = '/assets/erpnext/images/erpnext-logo.svg' +app_logo_url = "/assets/erpnext/images/erpnext-logo.svg" develop_version = '13.x.x-develop' @@ -73,7 +73,7 @@ website_generators = ["Item Group", "Item", "BOM", "Sales Partner", website_context = { "favicon": "/assets/erpnext/images/favicon.png", - "splash_image": "/assets/erpnext/images/erp-icon.svg" + "splash_image": "/assets/erpnext/images/erpnext-logo.svg" } website_route_rules = [ From 2c2e7297ae254ee9f9c43fa5ddb5eb25b86c05d6 Mon Sep 17 00:00:00 2001 From: Shivam Mishra Date: Mon, 19 Oct 2020 14:44:02 +0530 Subject: [PATCH 032/477] feat: update accounts onboarding --- erpnext/accounts/module_onboarding/accounts/accounts.json | 2 +- .../onboarding_step/chart_of_accounts/chart_of_accounts.json | 4 ++-- .../configure_account_settings.json | 4 ++-- .../onboarding_step/create_a_customer/create_a_customer.json | 2 +- .../onboarding_step/create_a_product/create_a_product.json | 2 +- .../onboarding_step/create_a_supplier/create_a_supplier.json | 2 +- .../create_your_first_purchase_invoice.json | 2 +- .../create_your_first_sales_invoice.json | 2 +- erpnext/accounts/onboarding_step/setup_taxes/setup_taxes.json | 2 +- 9 files changed, 11 insertions(+), 11 deletions(-) diff --git a/erpnext/accounts/module_onboarding/accounts/accounts.json b/erpnext/accounts/module_onboarding/accounts/accounts.json index 98272c38912..dc5c3207b05 100644 --- a/erpnext/accounts/module_onboarding/accounts/accounts.json +++ b/erpnext/accounts/module_onboarding/accounts/accounts.json @@ -13,7 +13,7 @@ "documentation_url": "https://docs.erpnext.com/docs/user/manual/en/accounts", "idx": 0, "is_complete": 0, - "modified": "2020-10-15 13:52:40.068450", + "modified": "2020-10-19 14:43:45.080823", "modified_by": "Administrator", "module": "Accounts", "name": "Accounts", diff --git a/erpnext/accounts/onboarding_step/chart_of_accounts/chart_of_accounts.json b/erpnext/accounts/onboarding_step/chart_of_accounts/chart_of_accounts.json index a1532302a16..ef20c19d565 100644 --- a/erpnext/accounts/onboarding_step/chart_of_accounts/chart_of_accounts.json +++ b/erpnext/accounts/onboarding_step/chart_of_accounts/chart_of_accounts.json @@ -1,6 +1,6 @@ { "action": "Go to Page", - "callback_message": "Great! Let's move to the next step!", + "callback_message": "You can continue with the onboarding after exploring this page", "callback_title": "Awesome Work", "creation": "2020-05-13 19:58:20.928127", "description": "# Chart Of Accounts\n\n**The Chart of Accounts is the blueprint of the accounts in your organization.**\n\nThe overall structure of your Chart of Accounts is based on a system of double entry\naccounting that has become a standard all over the world to quantify how a\ncompany is doing financially.\n\nChart of Accounts is a tree view of the names of the Accounts (Ledgers and\nGroups) that a Company requires to manage its books of accounts. ERPNext sets\nup a simple chart of accounts for each Company you create, but you can\nmodify it according to your needs and legal requirements.\n\nFor each company, Chart of Accounts signifies the way to classify the accounting entries, mostly\nbased on statutory (tax, compliance to government regulations) requirements.\n\nThe Chart of Accounts helps you to answer questions like:\n\n * What is your organization worth?\n * How much debt have you taken?\n * How much profit are you making (and hence paying tax)?\n * How much are you selling?\n * What is your expense break-up?\n", @@ -12,7 +12,7 @@ "is_mandatory": 0, "is_single": 0, "is_skipped": 0, - "modified": "2020-10-15 13:12:04.771355", + "modified": "2020-10-19 14:25:31.427339", "modified_by": "Administrator", "name": "Chart Of Accounts", "owner": "Administrator", diff --git a/erpnext/accounts/onboarding_step/configure_account_settings/configure_account_settings.json b/erpnext/accounts/onboarding_step/configure_account_settings/configure_account_settings.json index 1e8f1034a36..083fbb52bf2 100644 --- a/erpnext/accounts/onboarding_step/configure_account_settings/configure_account_settings.json +++ b/erpnext/accounts/onboarding_step/configure_account_settings/configure_account_settings.json @@ -1,5 +1,5 @@ { - "action": "Create Entry", + "action": "Show Form Tour", "creation": "2020-05-14 17:53:00.876946", "description": "# Account Settings\n\nThis is a crucial piece of configuration. There are various account settings in ERPNext to restrict and configure actions in the Accounting module.\n\nThe following settings are avaialble for you to configure\n\n1. Account Freezing \n2. Credit and Overbilling\n3. Invoicing and Tax Automations\n4. Balance Sheet configurations\n\nThere's much more, you can check it all out in this step", "docstatus": 0, @@ -9,7 +9,7 @@ "is_mandatory": 0, "is_single": 1, "is_skipped": 0, - "modified": "2020-10-15 13:45:14.687458", + "modified": "2020-10-19 14:40:55.584484", "modified_by": "Administrator", "name": "Configure Account Settings", "owner": "Administrator", diff --git a/erpnext/accounts/onboarding_step/create_a_customer/create_a_customer.json b/erpnext/accounts/onboarding_step/create_a_customer/create_a_customer.json index 02434a09bf6..4a967b140b9 100644 --- a/erpnext/accounts/onboarding_step/create_a_customer/create_a_customer.json +++ b/erpnext/accounts/onboarding_step/create_a_customer/create_a_customer.json @@ -10,7 +10,7 @@ "is_mandatory": 0, "is_single": 0, "is_skipped": 0, - "modified": "2020-10-15 13:37:59.699228", + "modified": "2020-10-16 12:59:16.989156", "modified_by": "Administrator", "name": "Create a Customer", "owner": "Administrator", diff --git a/erpnext/accounts/onboarding_step/create_a_product/create_a_product.json b/erpnext/accounts/onboarding_step/create_a_product/create_a_product.json index 3214d8ecf1b..0cbefee8586 100644 --- a/erpnext/accounts/onboarding_step/create_a_product/create_a_product.json +++ b/erpnext/accounts/onboarding_step/create_a_product/create_a_product.json @@ -9,7 +9,7 @@ "is_mandatory": 0, "is_single": 0, "is_skipped": 0, - "modified": "2020-10-15 13:30:46.817174", + "modified": "2020-10-16 12:59:16.983833", "modified_by": "Administrator", "name": "Create a Product", "owner": "Administrator", diff --git a/erpnext/accounts/onboarding_step/create_a_supplier/create_a_supplier.json b/erpnext/accounts/onboarding_step/create_a_supplier/create_a_supplier.json index 62d643aa72e..eede11d9796 100644 --- a/erpnext/accounts/onboarding_step/create_a_supplier/create_a_supplier.json +++ b/erpnext/accounts/onboarding_step/create_a_supplier/create_a_supplier.json @@ -9,7 +9,7 @@ "is_mandatory": 0, "is_single": 0, "is_skipped": 0, - "modified": "2020-10-15 13:32:39.651700", + "modified": "2020-10-16 12:59:16.979176", "modified_by": "Administrator", "name": "Create a Supplier", "owner": "Administrator", diff --git a/erpnext/accounts/onboarding_step/create_your_first_purchase_invoice/create_your_first_purchase_invoice.json b/erpnext/accounts/onboarding_step/create_your_first_purchase_invoice/create_your_first_purchase_invoice.json index 2e753d63b3b..2b53f46fe9c 100644 --- a/erpnext/accounts/onboarding_step/create_your_first_purchase_invoice/create_your_first_purchase_invoice.json +++ b/erpnext/accounts/onboarding_step/create_your_first_purchase_invoice/create_your_first_purchase_invoice.json @@ -9,7 +9,7 @@ "is_mandatory": 0, "is_single": 0, "is_skipped": 0, - "modified": "2020-10-15 13:33:56.079882", + "modified": "2020-10-16 12:59:16.976334", "modified_by": "Administrator", "name": "Create Your First Purchase Invoice", "owner": "Administrator", diff --git a/erpnext/accounts/onboarding_step/create_your_first_sales_invoice/create_your_first_sales_invoice.json b/erpnext/accounts/onboarding_step/create_your_first_sales_invoice/create_your_first_sales_invoice.json index bcf2c56dad7..d56be9220dc 100644 --- a/erpnext/accounts/onboarding_step/create_your_first_sales_invoice/create_your_first_sales_invoice.json +++ b/erpnext/accounts/onboarding_step/create_your_first_sales_invoice/create_your_first_sales_invoice.json @@ -9,7 +9,7 @@ "is_mandatory": 0, "is_single": 0, "is_skipped": 0, - "modified": "2020-10-15 13:39:43.970254", + "modified": "2020-10-16 12:59:16.987507", "modified_by": "Administrator", "name": "Create Your First Sales Invoice", "owner": "Administrator", diff --git a/erpnext/accounts/onboarding_step/setup_taxes/setup_taxes.json b/erpnext/accounts/onboarding_step/setup_taxes/setup_taxes.json index 2eedf56a839..fa3eabd9748 100644 --- a/erpnext/accounts/onboarding_step/setup_taxes/setup_taxes.json +++ b/erpnext/accounts/onboarding_step/setup_taxes/setup_taxes.json @@ -9,7 +9,7 @@ "is_mandatory": 0, "is_single": 0, "is_skipped": 0, - "modified": "2020-10-15 13:21:17.333438", + "modified": "2020-10-16 12:59:16.991287", "modified_by": "Administrator", "name": "Setup Taxes", "owner": "Administrator", From 5e00ed926cc5f74b4d4fa8ada0a83347242106f4 Mon Sep 17 00:00:00 2001 From: Shivam Mishra Date: Wed, 21 Oct 2020 12:30:22 +0530 Subject: [PATCH 033/477] feat: update icons --- erpnext/accounts/desk_page/accounting/accounting.json | 4 ++-- erpnext/buying/desk_page/buying/buying.json | 2 +- erpnext/selling/desk_page/selling/selling.json | 2 +- erpnext/stock/desk_page/stock/stock.json | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/erpnext/accounts/desk_page/accounting/accounting.json b/erpnext/accounts/desk_page/accounting/accounting.json index 45f75b1dcd2..5de091667a4 100644 --- a/erpnext/accounts/desk_page/accounting/accounting.json +++ b/erpnext/accounts/desk_page/accounting/accounting.json @@ -99,7 +99,7 @@ "idx": 0, "is_standard": 1, "label": "Accounting", - "modified": "2020-10-08 20:31:46.022470", + "modified": "2020-10-21 12:27:51.346915", "modified_by": "Administrator", "module": "Accounts", "name": "Accounting", @@ -109,7 +109,7 @@ "pin_to_top": 0, "shortcuts": [ { - "label": "Chart of Accounts", + "label": "Chart Of Accounts", "link_to": "Account", "type": "DocType" }, diff --git a/erpnext/buying/desk_page/buying/buying.json b/erpnext/buying/desk_page/buying/buying.json index 85f9bf62769..16df8dfdd8f 100644 --- a/erpnext/buying/desk_page/buying/buying.json +++ b/erpnext/buying/desk_page/buying/buying.json @@ -61,7 +61,7 @@ "idx": 0, "is_standard": 1, "label": "Buying", - "modified": "2020-09-30 14:40:55.638458", + "modified": "2020-10-21 12:29:02.772723", "modified_by": "Administrator", "module": "Buying", "name": "Buying", diff --git a/erpnext/selling/desk_page/selling/selling.json b/erpnext/selling/desk_page/selling/selling.json index bc813bca23e..82831ab61a9 100644 --- a/erpnext/selling/desk_page/selling/selling.json +++ b/erpnext/selling/desk_page/selling/selling.json @@ -45,7 +45,7 @@ "idx": 0, "is_standard": 1, "label": "Selling", - "modified": "2020-10-08 10:23:09.984377", + "modified": "2020-10-21 12:30:12.164433", "modified_by": "Administrator", "module": "Selling", "name": "Selling", diff --git a/erpnext/stock/desk_page/stock/stock.json b/erpnext/stock/desk_page/stock/stock.json index 3e1618d7fad..9f8f346635f 100644 --- a/erpnext/stock/desk_page/stock/stock.json +++ b/erpnext/stock/desk_page/stock/stock.json @@ -59,7 +59,7 @@ "idx": 0, "is_standard": 1, "label": "Stock", - "modified": "2020-10-07 18:40:17.130207", + "modified": "2020-10-21 12:28:55.503562", "modified_by": "Administrator", "module": "Stock", "name": "Stock", From b57b3c9f6c91ed8053f2464576654a531d0f1caa Mon Sep 17 00:00:00 2001 From: prssanna Date: Thu, 22 Oct 2020 15:37:47 +0530 Subject: [PATCH 034/477] feat: hook to fetch additional print settings in print view --- erpnext/controllers/buying_controller.py | 10 +---- erpnext/controllers/print_settings.py | 50 ++++++++++++++++++++++- erpnext/controllers/selling_controller.py | 11 ++--- erpnext/hooks.py | 1 + erpnext/startup/filters.py | 6 +-- 5 files changed, 57 insertions(+), 21 deletions(-) diff --git a/erpnext/controllers/buying_controller.py b/erpnext/controllers/buying_controller.py index e05c70e41c1..de04abbca40 100644 --- a/erpnext/controllers/buying_controller.py +++ b/erpnext/controllers/buying_controller.py @@ -13,6 +13,7 @@ from erpnext.stock.stock_ledger import get_valuation_rate from erpnext.stock.doctype.stock_entry.stock_entry import get_used_alternative_items from erpnext.stock.doctype.serial_no.serial_no import get_auto_serial_nos, auto_make_serial_nos, get_serial_nos from frappe.contacts.doctype.address.address import get_address_display +from erpnext.controllers.print_settings import print_settings_for_taxes from erpnext.accounts.doctype.budget.budget import validate_expense_against_budget from erpnext.controllers.stock_controller import StockController @@ -20,14 +21,7 @@ from erpnext.controllers.stock_controller import StockController class BuyingController(StockController): def __setup__(self): if hasattr(self, "taxes"): - self.flags.print_taxes_with_zero_amount = cint(frappe.db.get_single_value("Print Settings", - "print_taxes_with_zero_amount")) - self.flags.show_inclusive_tax_in_print = self.is_inclusive_tax() - - self.print_templates = { - "total": "templates/print_formats/includes/total.html", - "taxes": "templates/print_formats/includes/taxes.html" - } + print_settings_for_taxes(self) def get_feed(self): if self.get("supplier_name"): diff --git a/erpnext/controllers/print_settings.py b/erpnext/controllers/print_settings.py index c41db25253f..edd722dbe8c 100644 --- a/erpnext/controllers/print_settings.py +++ b/erpnext/controllers/print_settings.py @@ -5,20 +5,31 @@ from __future__ import unicode_literals import frappe from frappe.utils import cint -def print_settings_for_item_table(doc): +def print_settings_for_item_table(doc, setting_value=None): doc.print_templates = { "qty": "templates/print_formats/includes/item_table_qty.html" } doc.hide_in_print_layout = ["uom", "stock_uom"] - doc.flags.compact_item_print = cint(frappe.db.get_single_value("Print Settings", "compact_item_print")) + doc.flags.compact_item_print = setting_value if setting_value is not None\ + else cint(frappe.db.get_single_value("Print Settings", "compact_item_print")) if doc.flags.compact_item_print: doc.print_templates["description"] = "templates/print_formats/includes/item_table_description.html" doc.flags.compact_item_fields = ["description", "qty", "rate", "amount"] doc.flags.format_columns = format_columns +def print_settings_for_taxes(doc, setting_value=None): + doc.flags.print_taxes_with_zero_amount = setting_value if setting_value is not None\ + else cint(frappe.db.get_single_value("Print Settings", "print_taxes_with_zero_amount")) + doc.flags.show_inclusive_tax_in_print = doc.is_inclusive_tax() + + doc.print_templates = { + "total": "templates/print_formats/includes/total.html", + "taxes": "templates/print_formats/includes/taxes.html" + } + def format_columns(display_columns, compact_fields): compact_fields = compact_fields + ["image", "item_code", "item_name"] final_columns = [] @@ -26,3 +37,38 @@ def format_columns(display_columns, compact_fields): if column not in compact_fields: final_columns.append(column) return final_columns + +@frappe.whitelist() +def show_compact_item_setting(doc): + meta = frappe.get_meta(doc.doctype) + items_field = meta.get_field('items') + if items_field and items_field.fieldtype == 'Table': + return True + return False + +@frappe.whitelist() +def show_taxes_setting(doc): + meta = frappe.get_meta(doc.doctype) + items_field = meta.get_field('taxes') + if items_field and items_field.fieldtype == 'Table': + return True + return False + +def get_print_settings(): + settings = { + 'compact_item_print': { + 'condition': 'erpnext.controllers.print_settings.show_compact_item_setting', + 'fieldtype': 'Check', + 'child_field': 'items', + 'label': 'Compact Item Print', + 'set_template': 'erpnext.controllers.print_settings.print_settings_for_item_table' + }, + 'print_taxes_with_zero_amount': { + 'condition': 'erpnext.controllers.print_settings.show_taxes_setting', + 'fieldtype': 'Check', + 'label': 'Print taxes with zero amount', + 'set_template': 'erpnext.controllers.print_settings.print_settings_for_taxes' + } + } + + return settings diff --git a/erpnext/controllers/selling_controller.py b/erpnext/controllers/selling_controller.py index 58861715c27..ac26d3fea80 100644 --- a/erpnext/controllers/selling_controller.py +++ b/erpnext/controllers/selling_controller.py @@ -11,20 +11,15 @@ from erpnext.stock.get_item_details import get_conversion_factor from erpnext.stock.doctype.item.item import set_item_default from frappe.contacts.doctype.address.address import get_address_display from erpnext.controllers.accounts_controller import get_taxes_and_charges +from erpnext.controllers.print_settings import print_settings_for_taxes from erpnext.controllers.stock_controller import StockController class SellingController(StockController): def __setup__(self): if hasattr(self, "taxes"): - self.flags.print_taxes_with_zero_amount = cint(frappe.db.get_single_value("Print Settings", - "print_taxes_with_zero_amount")) - self.flags.show_inclusive_tax_in_print = self.is_inclusive_tax() + print_settings_for_taxes(self) - self.print_templates = { - "total": "templates/print_formats/includes/total.html", - "taxes": "templates/print_formats/includes/taxes.html" - } def get_feed(self): return _("To {0} | {1} {2}").format(self.customer_name, self.currency, @@ -189,7 +184,7 @@ class SellingController(StockController): for it in self.get("items"): if not it.item_code: continue - + last_purchase_rate, is_stock_item = frappe.get_cached_value("Item", it.item_code, ["last_purchase_rate", "is_stock_item"]) last_purchase_rate_in_sales_uom = last_purchase_rate * (it.conversion_factor or 1) if flt(it.base_net_rate) < flt(last_purchase_rate_in_sales_uom): diff --git a/erpnext/hooks.py b/erpnext/hooks.py index b510208720d..d455972a56a 100644 --- a/erpnext/hooks.py +++ b/erpnext/hooks.py @@ -41,6 +41,7 @@ notification_config = "erpnext.startup.notifications.get_notification_config" get_help_messages = "erpnext.utilities.activation.get_help_messages" leaderboards = "erpnext.startup.leaderboard.get_leaderboards" filters_config = "erpnext.startup.filters.get_filters_config" +additional_print_settings = "erpnext.controllers.print_settings.get_print_settings" on_session_creation = [ "erpnext.portal.utils.create_customer_or_supplier", diff --git a/erpnext/startup/filters.py b/erpnext/startup/filters.py index a99e49b4917..ec07329dedf 100644 --- a/erpnext/startup/filters.py +++ b/erpnext/startup/filters.py @@ -2,13 +2,13 @@ import frappe def get_filters_config(): - filters_config = { + filters_config = { "fiscal year": { "label": "Fiscal Year", "get_field": "erpnext.accounts.utils.get_fiscal_year_filter_field", "valid_for_fieldtypes": ["Date", "Datetime", "DateRange"], "depends_on": "company", } - } + } - return filters_config \ No newline at end of file + return filters_config \ No newline at end of file From 13c6e2f320c100de245a01b18ddf6a134bbed8b5 Mon Sep 17 00:00:00 2001 From: prssanna Date: Thu, 22 Oct 2020 17:19:00 +0530 Subject: [PATCH 035/477] feat: contextual setting for print uom after quantity --- erpnext/controllers/print_settings.py | 46 +++++++++++++------ .../includes/item_table_qty.html | 2 +- 2 files changed, 32 insertions(+), 16 deletions(-) diff --git a/erpnext/controllers/print_settings.py b/erpnext/controllers/print_settings.py index edd722dbe8c..5c295563984 100644 --- a/erpnext/controllers/print_settings.py +++ b/erpnext/controllers/print_settings.py @@ -5,24 +5,24 @@ from __future__ import unicode_literals import frappe from frappe.utils import cint -def print_settings_for_item_table(doc, setting_value=None): - +def print_settings_for_item_table(doc, settings=None): doc.print_templates = { "qty": "templates/print_formats/includes/item_table_qty.html" } doc.hide_in_print_layout = ["uom", "stock_uom"] - doc.flags.compact_item_print = setting_value if setting_value is not None\ - else cint(frappe.db.get_single_value("Print Settings", "compact_item_print")) + setting_fields = ['compact_item_print', 'print_uom_after_quantity'] + set_doc_flags_from_settings(doc, setting_fields, settings) if doc.flags.compact_item_print: doc.print_templates["description"] = "templates/print_formats/includes/item_table_description.html" doc.flags.compact_item_fields = ["description", "qty", "rate", "amount"] doc.flags.format_columns = format_columns -def print_settings_for_taxes(doc, setting_value=None): - doc.flags.print_taxes_with_zero_amount = setting_value if setting_value is not None\ - else cint(frappe.db.get_single_value("Print Settings", "print_taxes_with_zero_amount")) +def print_settings_for_taxes(doc, settings=None): + + set_doc_flags_from_settings(doc, ['print_taxes_with_zero_amount'], settings) + doc.flags.show_inclusive_tax_in_print = doc.is_inclusive_tax() doc.print_templates = { @@ -30,6 +30,17 @@ def print_settings_for_taxes(doc, setting_value=None): "taxes": "templates/print_formats/includes/taxes.html" } +def set_doc_flags_from_settings(doc, fields, settings=None): + if not settings: settings = {} + + print_settings = frappe.get_single('Print Settings') + + for field in fields: + if field in settings: + doc.flags[field] = settings.get(field) + else: + doc.flags[field] = print_settings.get(field) + def format_columns(display_columns, compact_fields): compact_fields = compact_fields + ["image", "item_code", "item_name"] final_columns = [] @@ -38,33 +49,38 @@ def format_columns(display_columns, compact_fields): final_columns.append(column) return final_columns -@frappe.whitelist() -def show_compact_item_setting(doc): +def has_items_field(doc): meta = frappe.get_meta(doc.doctype) items_field = meta.get_field('items') if items_field and items_field.fieldtype == 'Table': return True return False -@frappe.whitelist() -def show_taxes_setting(doc): +def has_taxes_field(doc): meta = frappe.get_meta(doc.doctype) - items_field = meta.get_field('taxes') - if items_field and items_field.fieldtype == 'Table': + taxes_field = meta.get_field('taxes') + if taxes_field and taxes_field.fieldtype == 'Table': return True return False def get_print_settings(): settings = { 'compact_item_print': { - 'condition': 'erpnext.controllers.print_settings.show_compact_item_setting', + 'condition': 'erpnext.controllers.print_settings.has_items_field', 'fieldtype': 'Check', 'child_field': 'items', 'label': 'Compact Item Print', 'set_template': 'erpnext.controllers.print_settings.print_settings_for_item_table' }, + 'print_uom_after_quantity': { + 'condition': 'erpnext.controllers.print_settings.has_taxes_field', + 'fieldtype': 'Check', + 'child_field': 'items', + 'label': 'Print UOM after Quantity', + 'set_template': 'erpnext.controllers.print_settings.print_settings_for_item_table' + }, 'print_taxes_with_zero_amount': { - 'condition': 'erpnext.controllers.print_settings.show_taxes_setting', + 'condition': 'erpnext.controllers.print_settings.has_taxes_field', 'fieldtype': 'Check', 'label': 'Print taxes with zero amount', 'set_template': 'erpnext.controllers.print_settings.print_settings_for_taxes' diff --git a/erpnext/templates/print_formats/includes/item_table_qty.html b/erpnext/templates/print_formats/includes/item_table_qty.html index ecaaef42b55..1d992dc3029 100644 --- a/erpnext/templates/print_formats/includes/item_table_qty.html +++ b/erpnext/templates/print_formats/includes/item_table_qty.html @@ -1,4 +1,4 @@ -{% set qty_first=frappe.db.get_single_value("Print Settings", "print_uom_after_quantity") %} +{% set qty_first=doc.flags.print_uom_after_quantity %} {% if qty_first %} {{ doc.get_formatted("qty", doc) }} {% if (doc.uom and not doc.is_print_hide("uom")) %} {{ _(doc.uom) }} From bc6a2b2f9c260b2073ed2195d3147289664389f1 Mon Sep 17 00:00:00 2001 From: Faris Ansari Date: Tue, 27 Oct 2020 19:42:58 +0530 Subject: [PATCH 036/477] wip --- erpnext/controllers/buying_controller.py | 8 +++++ erpnext/controllers/print_settings.py | 14 +++----- erpnext/controllers/selling_controller.py | 11 +++++++ .../print_formats/includes/items.html | 33 +++++++++++++++++++ 4 files changed, 57 insertions(+), 9 deletions(-) create mode 100644 erpnext/templates/print_formats/includes/items.html diff --git a/erpnext/controllers/buying_controller.py b/erpnext/controllers/buying_controller.py index de04abbca40..596f6f4b57b 100644 --- a/erpnext/controllers/buying_controller.py +++ b/erpnext/controllers/buying_controller.py @@ -23,6 +23,14 @@ class BuyingController(StockController): if hasattr(self, "taxes"): print_settings_for_taxes(self) + def before_print(self): + pass + + def get_print_settings(self): + items_field = self.meta.get_field('items') + if items_field and items_field.fieldtype == 'Table': + return ['compact_item_print', 'print_uom_after_quantity'] + def get_feed(self): if self.get("supplier_name"): return _("From {0} | {1} {2}").format(self.supplier_name, self.currency, diff --git a/erpnext/controllers/print_settings.py b/erpnext/controllers/print_settings.py index 5c295563984..418d8eb3287 100644 --- a/erpnext/controllers/print_settings.py +++ b/erpnext/controllers/print_settings.py @@ -64,26 +64,22 @@ def has_taxes_field(doc): return False def get_print_settings(): + + # return ['comp'] settings = { 'compact_item_print': { 'condition': 'erpnext.controllers.print_settings.has_items_field', - 'fieldtype': 'Check', 'child_field': 'items', - 'label': 'Compact Item Print', - 'set_template': 'erpnext.controllers.print_settings.print_settings_for_item_table' + # 'set_template': 'erpnext.controllers.print_settings.print_settings_for_item_table' }, 'print_uom_after_quantity': { 'condition': 'erpnext.controllers.print_settings.has_taxes_field', - 'fieldtype': 'Check', 'child_field': 'items', - 'label': 'Print UOM after Quantity', - 'set_template': 'erpnext.controllers.print_settings.print_settings_for_item_table' + # 'set_template': 'erpnext.controllers.print_settings.print_settings_for_item_table' }, 'print_taxes_with_zero_amount': { 'condition': 'erpnext.controllers.print_settings.has_taxes_field', - 'fieldtype': 'Check', - 'label': 'Print taxes with zero amount', - 'set_template': 'erpnext.controllers.print_settings.print_settings_for_taxes' + # 'set_template': 'erpnext.controllers.print_settings.print_settings_for_taxes' } } diff --git a/erpnext/controllers/selling_controller.py b/erpnext/controllers/selling_controller.py index ac26d3fea80..4c87e8c2f65 100644 --- a/erpnext/controllers/selling_controller.py +++ b/erpnext/controllers/selling_controller.py @@ -20,6 +20,17 @@ class SellingController(StockController): if hasattr(self, "taxes"): print_settings_for_taxes(self) + def before_print(self): + self.print_templates = { + "items": "templates/print_formats/includes/items.html", + } + self.flags.compact_item_fields = ['description'] + + def get_print_settings(self): + items_field = self.meta.get_field('items') + if items_field and items_field.fieldtype == 'Table': + return ['compact_item_print', 'print_uom_after_quantity'] + def get_feed(self): return _("To {0} | {1} {2}").format(self.customer_name, self.currency, diff --git a/erpnext/templates/print_formats/includes/items.html b/erpnext/templates/print_formats/includes/items.html new file mode 100644 index 00000000000..933ae17c2ad --- /dev/null +++ b/erpnext/templates/print_formats/includes/items.html @@ -0,0 +1,33 @@ +{%- if data -%} + {%- set visible_columns = get_visible_columns(doc.get(df.fieldname), + table_meta, df) -%} + +
+
+ + + + {% for tdf in visible_columns %} + {% if (data and not print_settings.compact_item_print) or tdf.fieldname in doc.get(df.fieldname)[0].flags.compact_item_fields %} + + {% endif %} + {% endfor %} + + + + {% for d in data %} + + + {% for tdf in visible_columns %} + {% if not doc.get(df.fieldname)[0].flags.compact_item_print or tdf.fieldname in doc.get(df.fieldname)[0].flags.compact_item_fields %} + + {% endif %} + {% endfor %} + + {% endfor %} + +
{{ _("Sr") }} + {{ _(tdf.label) }}
{{ d.idx }} +
{{ print_value(tdf, d, doc, visible_columns) }}
+
+{%- endif -%} From 71e5b60df11035b21aba47b08c955bd9f30cf158 Mon Sep 17 00:00:00 2001 From: prssanna Date: Thu, 29 Oct 2020 14:19:34 +0530 Subject: [PATCH 037/477] refactor: refactor contextual print setting implementation --- .../purchase_invoice_item.py | 5 +- .../sales_invoice_item/sales_invoice_item.py | 4 +- .../sales_invoice_return.html | 11 ++- .../purchase_order_item.py | 5 +- .../supplier_quotation_item.py | 5 +- erpnext/controllers/accounts_controller.py | 19 ++++- erpnext/controllers/buying_controller.py | 12 --- erpnext/controllers/print_settings.py | 80 +++++-------------- erpnext/controllers/selling_controller.py | 16 ---- erpnext/projects/doctype/project/project.py | 2 +- .../doctype/quotation_item/quotation_item.py | 4 +- .../sales_order_item/sales_order_item.py | 4 +- .../doctype/delivery_note/delivery_note.py | 2 +- .../delivery_note_item/delivery_note_item.py | 4 +- .../material_request_item.py | 4 +- .../purchase_receipt_item.py | 4 +- .../includes/item_table_description.html | 6 +- .../includes/item_table_qty.html | 2 +- .../print_formats/includes/items.html | 12 ++- .../print_formats/includes/taxes.html | 2 +- 20 files changed, 68 insertions(+), 135 deletions(-) diff --git a/erpnext/accounts/doctype/purchase_invoice_item/purchase_invoice_item.py b/erpnext/accounts/doctype/purchase_invoice_item/purchase_invoice_item.py index 56576df0791..50ec7d8b4d8 100644 --- a/erpnext/accounts/doctype/purchase_invoice_item/purchase_invoice_item.py +++ b/erpnext/accounts/doctype/purchase_invoice_item/purchase_invoice_item.py @@ -6,8 +6,5 @@ import frappe from frappe.model.document import Document -from erpnext.controllers.print_settings import print_settings_for_item_table - class PurchaseInvoiceItem(Document): - def __setup__(self): - print_settings_for_item_table(self) + pass diff --git a/erpnext/accounts/doctype/sales_invoice_item/sales_invoice_item.py b/erpnext/accounts/doctype/sales_invoice_item/sales_invoice_item.py index 7a62f8e2815..a73b03acc84 100644 --- a/erpnext/accounts/doctype/sales_invoice_item/sales_invoice_item.py +++ b/erpnext/accounts/doctype/sales_invoice_item/sales_invoice_item.py @@ -5,8 +5,6 @@ from __future__ import unicode_literals import frappe from frappe.model.document import Document -from erpnext.controllers.print_settings import print_settings_for_item_table class SalesInvoiceItem(Document): - def __setup__(self): - print_settings_for_item_table(self) + pass diff --git a/erpnext/accounts/print_format/sales_invoice_return/sales_invoice_return.html b/erpnext/accounts/print_format/sales_invoice_return/sales_invoice_return.html index 1d758e89355..3d5a9b1da94 100644 --- a/erpnext/accounts/print_format/sales_invoice_return/sales_invoice_return.html +++ b/erpnext/accounts/print_format/sales_invoice_return/sales_invoice_return.html @@ -1,5 +1,5 @@ {%- from "templates/print_formats/standard_macros.html" import add_header, render_field, print_value, fieldmeta, - get_width, get_align_class -%} + get_width, get_align_class with context -%} {%- macro render_currency(df, doc) -%}
@@ -63,14 +63,19 @@ {{ d.idx }} {% for tdf in visible_columns %} - {% if not d.flags.compact_item_print or tdf.fieldname in doc.get(df.fieldname)[0].flags.compact_item_fields %} + {% if not print_settings.compact_item_print or tdf.fieldname in doc.flags.compact_item_fields %} {% if tdf.fieldname == 'qty' %}
{{ (d[tdf.fieldname])|abs }}
{% elif tdf.fieldtype == 'Currency' %}
{{ frappe.utils.fmt_money((d[tdf.fieldname])|abs, currency=doc.currency) }}
{% else %} -
{{ print_value(tdf, d, doc, visible_columns) }}
+ {% if doc.child_print_templates %} + {%- set child_templates = doc.child_print_templates.get(df.fieldname) -%} +
{{ print_value(tdf, d, doc, visible_columns, child_templates) }}
+ {% else %} +
{{ print_value(tdf, d, doc, visible_columns) }}
+ {% endif %} {% endif %} {% endif %} {% endfor %} diff --git a/erpnext/buying/doctype/purchase_order_item/purchase_order_item.py b/erpnext/buying/doctype/purchase_order_item/purchase_order_item.py index b711e36bf99..8bdcd47e028 100644 --- a/erpnext/buying/doctype/purchase_order_item/purchase_order_item.py +++ b/erpnext/buying/doctype/purchase_order_item/purchase_order_item.py @@ -6,11 +6,8 @@ import frappe from frappe.model.document import Document -from erpnext.controllers.print_settings import print_settings_for_item_table - class PurchaseOrderItem(Document): - def __setup__(self): - print_settings_for_item_table(self) + pass def on_doctype_update(): frappe.db.add_index("Purchase Order Item", ["item_code", "warehouse"]) \ No newline at end of file diff --git a/erpnext/buying/doctype/supplier_quotation_item/supplier_quotation_item.py b/erpnext/buying/doctype/supplier_quotation_item/supplier_quotation_item.py index f24e5be0768..64dda879450 100644 --- a/erpnext/buying/doctype/supplier_quotation_item/supplier_quotation_item.py +++ b/erpnext/buying/doctype/supplier_quotation_item/supplier_quotation_item.py @@ -6,8 +6,5 @@ import frappe from frappe.model.document import Document -from erpnext.controllers.print_settings import print_settings_for_item_table - class SupplierQuotationItem(Document): - def __setup__(self): - print_settings_for_item_table(self) + pass diff --git a/erpnext/controllers/accounts_controller.py b/erpnext/controllers/accounts_controller.py index 166564961d1..c016090314e 100644 --- a/erpnext/controllers/accounts_controller.py +++ b/erpnext/controllers/accounts_controller.py @@ -22,6 +22,7 @@ from six import text_type from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import get_accounting_dimensions from erpnext.stock.get_item_details import get_item_warehouse, _get_item_tax_template, get_item_tax_map from erpnext.stock.doctype.packed_item.packed_item import make_packing_list +from erpnext.controllers.print_settings import set_print_templates_for_item_table, set_print_templates_for_taxes force_item_fields = ("item_group", "brand", "stock_uom", "is_fixed_asset", "item_tax_rate", "pricing_rules") @@ -29,6 +30,19 @@ class AccountsController(TransactionBase): def __init__(self, *args, **kwargs): super(AccountsController, self).__init__(*args, **kwargs) + def get_print_settings(self): + print_setting_fields = [] + items_field = self.meta.get_field('items') + + if items_field and items_field.fieldtype == 'Table': + print_setting_fields += ['compact_item_print', 'print_uom_after_quantity'] + + taxes_field = self.meta.get_field('taxes') + if taxes_field and taxes_field.fieldtype == 'Table': + print_setting_fields += ['print_taxes_with_zero_amount'] + + return print_setting_fields + @property def company_currency(self): if not hasattr(self, "__company_currency"): @@ -138,7 +152,7 @@ class AccountsController(TransactionBase): elif self.doctype in ("Quotation", "Purchase Order", "Sales Order"): self.validate_non_invoice_documents_schedule() - def before_print(self): + def before_print(self, settings=None): if self.doctype in ['Purchase Order', 'Sales Order', 'Sales Invoice', 'Purchase Invoice', 'Supplier Quotation', 'Purchase Receipt', 'Delivery Note', 'Quotation']: if self.get("group_same_items"): @@ -151,6 +165,9 @@ class AccountsController(TransactionBase): else: df.set("print_hide", 1) + set_print_templates_for_item_table(self, settings) + set_print_templates_for_taxes(self, settings) + def calculate_paid_amount(self): if hasattr(self, "is_pos") or hasattr(self, "is_paid"): is_paid = self.get("is_pos") or self.get("is_paid") diff --git a/erpnext/controllers/buying_controller.py b/erpnext/controllers/buying_controller.py index 596f6f4b57b..353bc098102 100644 --- a/erpnext/controllers/buying_controller.py +++ b/erpnext/controllers/buying_controller.py @@ -13,23 +13,11 @@ from erpnext.stock.stock_ledger import get_valuation_rate from erpnext.stock.doctype.stock_entry.stock_entry import get_used_alternative_items from erpnext.stock.doctype.serial_no.serial_no import get_auto_serial_nos, auto_make_serial_nos, get_serial_nos from frappe.contacts.doctype.address.address import get_address_display -from erpnext.controllers.print_settings import print_settings_for_taxes from erpnext.accounts.doctype.budget.budget import validate_expense_against_budget from erpnext.controllers.stock_controller import StockController class BuyingController(StockController): - def __setup__(self): - if hasattr(self, "taxes"): - print_settings_for_taxes(self) - - def before_print(self): - pass - - def get_print_settings(self): - items_field = self.meta.get_field('items') - if items_field and items_field.fieldtype == 'Table': - return ['compact_item_print', 'print_uom_after_quantity'] def get_feed(self): if self.get("supplier_name"): diff --git a/erpnext/controllers/print_settings.py b/erpnext/controllers/print_settings.py index 418d8eb3287..e08c400068b 100644 --- a/erpnext/controllers/print_settings.py +++ b/erpnext/controllers/print_settings.py @@ -5,41 +5,33 @@ from __future__ import unicode_literals import frappe from frappe.utils import cint -def print_settings_for_item_table(doc, settings=None): +def set_print_templates_for_item_table(doc, settings): doc.print_templates = { - "qty": "templates/print_formats/includes/item_table_qty.html" + "items": "templates/print_formats/includes/items.html", } - doc.hide_in_print_layout = ["uom", "stock_uom"] - setting_fields = ['compact_item_print', 'print_uom_after_quantity'] - set_doc_flags_from_settings(doc, setting_fields, settings) + doc.child_print_templates = { + "items": { + "qty": "templates/print_formats/includes/item_table_qty.html", + } + } - if doc.flags.compact_item_print: - doc.print_templates["description"] = "templates/print_formats/includes/item_table_description.html" - doc.flags.compact_item_fields = ["description", "qty", "rate", "amount"] + if doc.meta.get_field("items"): + doc.meta.get_field("items").hide_in_print_layout = ["uom", "stock_uom"] + + doc.flags.compact_item_fields = ["description", "qty", "rate", "amount"] + + if settings.compact_item_print: + doc.child_print_templates["items"]["description"] =\ + "templates/print_formats/includes/item_table_description.html" doc.flags.format_columns = format_columns -def print_settings_for_taxes(doc, settings=None): - - set_doc_flags_from_settings(doc, ['print_taxes_with_zero_amount'], settings) - +def set_print_templates_for_taxes(doc, settings): doc.flags.show_inclusive_tax_in_print = doc.is_inclusive_tax() - - doc.print_templates = { + doc.print_templates.update({ "total": "templates/print_formats/includes/total.html", "taxes": "templates/print_formats/includes/taxes.html" - } - -def set_doc_flags_from_settings(doc, fields, settings=None): - if not settings: settings = {} - - print_settings = frappe.get_single('Print Settings') - - for field in fields: - if field in settings: - doc.flags[field] = settings.get(field) - else: - doc.flags[field] = print_settings.get(field) + }) def format_columns(display_columns, compact_fields): compact_fields = compact_fields + ["image", "item_code", "item_name"] @@ -48,39 +40,3 @@ def format_columns(display_columns, compact_fields): if column not in compact_fields: final_columns.append(column) return final_columns - -def has_items_field(doc): - meta = frappe.get_meta(doc.doctype) - items_field = meta.get_field('items') - if items_field and items_field.fieldtype == 'Table': - return True - return False - -def has_taxes_field(doc): - meta = frappe.get_meta(doc.doctype) - taxes_field = meta.get_field('taxes') - if taxes_field and taxes_field.fieldtype == 'Table': - return True - return False - -def get_print_settings(): - - # return ['comp'] - settings = { - 'compact_item_print': { - 'condition': 'erpnext.controllers.print_settings.has_items_field', - 'child_field': 'items', - # 'set_template': 'erpnext.controllers.print_settings.print_settings_for_item_table' - }, - 'print_uom_after_quantity': { - 'condition': 'erpnext.controllers.print_settings.has_taxes_field', - 'child_field': 'items', - # 'set_template': 'erpnext.controllers.print_settings.print_settings_for_item_table' - }, - 'print_taxes_with_zero_amount': { - 'condition': 'erpnext.controllers.print_settings.has_taxes_field', - # 'set_template': 'erpnext.controllers.print_settings.print_settings_for_taxes' - } - } - - return settings diff --git a/erpnext/controllers/selling_controller.py b/erpnext/controllers/selling_controller.py index 4c87e8c2f65..de3cda540aa 100644 --- a/erpnext/controllers/selling_controller.py +++ b/erpnext/controllers/selling_controller.py @@ -11,26 +11,10 @@ from erpnext.stock.get_item_details import get_conversion_factor from erpnext.stock.doctype.item.item import set_item_default from frappe.contacts.doctype.address.address import get_address_display from erpnext.controllers.accounts_controller import get_taxes_and_charges -from erpnext.controllers.print_settings import print_settings_for_taxes from erpnext.controllers.stock_controller import StockController class SellingController(StockController): - def __setup__(self): - if hasattr(self, "taxes"): - print_settings_for_taxes(self) - - def before_print(self): - self.print_templates = { - "items": "templates/print_formats/includes/items.html", - } - self.flags.compact_item_fields = ['description'] - - def get_print_settings(self): - items_field = self.meta.get_field('items') - if items_field and items_field.fieldtype == 'Table': - return ['compact_item_print', 'print_uom_after_quantity'] - def get_feed(self): return _("To {0} | {1} {2}").format(self.customer_name, self.currency, diff --git a/erpnext/projects/doctype/project/project.py b/erpnext/projects/doctype/project/project.py index 5bbd29c4c42..24d0dc16bf9 100644 --- a/erpnext/projects/doctype/project/project.py +++ b/erpnext/projects/doctype/project/project.py @@ -26,7 +26,7 @@ class Project(Document): self.update_costing() - def before_print(self): + def before_print(self, settings=None): self.onload() diff --git a/erpnext/selling/doctype/quotation_item/quotation_item.py b/erpnext/selling/doctype/quotation_item/quotation_item.py index 966b542c41f..7384871ed44 100644 --- a/erpnext/selling/doctype/quotation_item/quotation_item.py +++ b/erpnext/selling/doctype/quotation_item/quotation_item.py @@ -5,8 +5,6 @@ from __future__ import unicode_literals import frappe from frappe.model.document import Document -from erpnext.controllers.print_settings import print_settings_for_item_table class QuotationItem(Document): - def __setup__(self): - print_settings_for_item_table(self) + pass diff --git a/erpnext/selling/doctype/sales_order_item/sales_order_item.py b/erpnext/selling/doctype/sales_order_item/sales_order_item.py index 4a87a0c28af..27f303d43b1 100644 --- a/erpnext/selling/doctype/sales_order_item/sales_order_item.py +++ b/erpnext/selling/doctype/sales_order_item/sales_order_item.py @@ -5,11 +5,9 @@ from __future__ import unicode_literals import frappe from frappe.model.document import Document -from erpnext.controllers.print_settings import print_settings_for_item_table class SalesOrderItem(Document): - def __setup__(self): - print_settings_for_item_table(self) + pass def on_doctype_update(): frappe.db.add_index("Sales Order Item", ["item_code", "warehouse"]) \ No newline at end of file diff --git a/erpnext/stock/doctype/delivery_note/delivery_note.py b/erpnext/stock/doctype/delivery_note/delivery_note.py index d04cf785ab1..1994dfd2043 100644 --- a/erpnext/stock/doctype/delivery_note/delivery_note.py +++ b/erpnext/stock/doctype/delivery_note/delivery_note.py @@ -71,7 +71,7 @@ class DeliveryNote(SellingController): where name=`tabSales Invoice Item`.parent and is_return=1 and update_stock=1)""" }) - def before_print(self): + def before_print(self, settings=None): def toggle_print_hide(meta, fieldname): df = meta.get_field(fieldname) if self.get("print_without_amount"): diff --git a/erpnext/stock/doctype/delivery_note_item/delivery_note_item.py b/erpnext/stock/doctype/delivery_note_item/delivery_note_item.py index aaca802f5c9..50305957892 100644 --- a/erpnext/stock/doctype/delivery_note_item/delivery_note_item.py +++ b/erpnext/stock/doctype/delivery_note_item/delivery_note_item.py @@ -5,8 +5,6 @@ from __future__ import unicode_literals import frappe from frappe.model.document import Document -from erpnext.controllers.print_settings import print_settings_for_item_table class DeliveryNoteItem(Document): - def __setup__(self): - print_settings_for_item_table(self) + pass \ No newline at end of file diff --git a/erpnext/stock/doctype/material_request_item/material_request_item.py b/erpnext/stock/doctype/material_request_item/material_request_item.py index 6c6ecfea831..16f007f6a20 100644 --- a/erpnext/stock/doctype/material_request_item/material_request_item.py +++ b/erpnext/stock/doctype/material_request_item/material_request_item.py @@ -6,12 +6,10 @@ from __future__ import unicode_literals import frappe -from erpnext.controllers.print_settings import print_settings_for_item_table from frappe.model.document import Document class MaterialRequestItem(Document): - def __setup__(self): - print_settings_for_item_table(self) + pass def on_doctype_update(): frappe.db.add_index("Material Request Item", ["item_code", "warehouse"]) \ No newline at end of file diff --git a/erpnext/stock/doctype/purchase_receipt_item/purchase_receipt_item.py b/erpnext/stock/doctype/purchase_receipt_item/purchase_receipt_item.py index 679bd1e2427..b79bb5d0430 100644 --- a/erpnext/stock/doctype/purchase_receipt_item/purchase_receipt_item.py +++ b/erpnext/stock/doctype/purchase_receipt_item/purchase_receipt_item.py @@ -5,8 +5,6 @@ from __future__ import unicode_literals import frappe from frappe.model.document import Document -from erpnext.controllers.print_settings import print_settings_for_item_table class PurchaseReceiptItem(Document): - def __setup__(self): - print_settings_for_item_table(self) + pass diff --git a/erpnext/templates/print_formats/includes/item_table_description.html b/erpnext/templates/print_formats/includes/item_table_description.html index 070cca5eb23..ed46c9e224d 100644 --- a/erpnext/templates/print_formats/includes/item_table_description.html +++ b/erpnext/templates/print_formats/includes/item_table_description.html @@ -1,7 +1,7 @@ -{%- set compact = doc.flags.compact_item_print -%} -{%- set compact_fields = doc.flags.compact_item_fields -%} +{%- set compact = print_settings.compact_item_print -%} +{%- set compact_fields = parent_doc.flags.compact_item_fields -%} {%- set display_columns = visible_columns|map(attribute="fieldname")| list -%} -{%- set columns = doc.flags.format_columns(display_columns, compact_fields) -%} +{%- set columns = parent_doc.flags.format_columns(display_columns, compact_fields) -%} {% if doc.in_format_data("image") and doc.get("image") and "image" in display_columns -%}
diff --git a/erpnext/templates/print_formats/includes/item_table_qty.html b/erpnext/templates/print_formats/includes/item_table_qty.html index 1d992dc3029..8e68f1cc638 100644 --- a/erpnext/templates/print_formats/includes/item_table_qty.html +++ b/erpnext/templates/print_formats/includes/item_table_qty.html @@ -1,4 +1,4 @@ -{% set qty_first=doc.flags.print_uom_after_quantity %} +{% set qty_first=print_settings.print_uom_after_quantity %} {% if qty_first %} {{ doc.get_formatted("qty", doc) }} {% if (doc.uom and not doc.is_print_hide("uom")) %} {{ _(doc.uom) }} diff --git a/erpnext/templates/print_formats/includes/items.html b/erpnext/templates/print_formats/includes/items.html index 933ae17c2ad..55598e7e22d 100644 --- a/erpnext/templates/print_formats/includes/items.html +++ b/erpnext/templates/print_formats/includes/items.html @@ -1,14 +1,13 @@ {%- if data -%} {%- set visible_columns = get_visible_columns(doc.get(df.fieldname), table_meta, df) -%} -
{% for tdf in visible_columns %} - {% if (data and not print_settings.compact_item_print) or tdf.fieldname in doc.get(df.fieldname)[0].flags.compact_item_fields %} + {% if (data and not print_settings.compact_item_print) or tdf.fieldname in doc.flags.compact_item_fields %} {% endif %} @@ -20,9 +19,14 @@ {% for tdf in visible_columns %} - {% if not doc.get(df.fieldname)[0].flags.compact_item_print or tdf.fieldname in doc.get(df.fieldname)[0].flags.compact_item_fields %} + {% if not print_settings.compact_item_print or tdf.fieldname in doc.flags.compact_item_fields %} + {% if doc.child_print_templates %} + {%- set child_templates = doc.child_print_templates.get(df.fieldname) %} +
{{ print_value(tdf, d, doc, visible_columns, child_templates) }}
+ {% else %} +
{{ print_value(tdf, d, doc, visible_columns) }}
+ {% endif %} {% endif %} {% endfor %} diff --git a/erpnext/templates/print_formats/includes/taxes.html b/erpnext/templates/print_formats/includes/taxes.html index 6e984f39016..334ac7834e3 100644 --- a/erpnext/templates/print_formats/includes/taxes.html +++ b/erpnext/templates/print_formats/includes/taxes.html @@ -17,7 +17,7 @@ {{ render_discount_amount(doc) }} {%- endif -%} {%- for charge in data -%} - {%- if (charge.tax_amount or doc.flags.print_taxes_with_zero_amount) and (not charge.included_in_print_rate or doc.flags.show_inclusive_tax_in_print) -%} + {%- if (charge.tax_amount or print_settings.print_taxes_with_zero_amount) and (not charge.included_in_print_rate or doc.flags.show_inclusive_tax_in_print) -%}
From 18ef17f3ba5760569ea650288c45c197abc9f7dd Mon Sep 17 00:00:00 2001 From: Shivam Mishra Date: Fri, 30 Oct 2020 15:41:36 +0530 Subject: [PATCH 038/477] feat: add tour for sales taxes template --- .../sales_taxes_and_charges_template.js | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/erpnext/accounts/doctype/sales_taxes_and_charges_template/sales_taxes_and_charges_template.js b/erpnext/accounts/doctype/sales_taxes_and_charges_template/sales_taxes_and_charges_template.js index 97a6fdd3366..0e011883b15 100644 --- a/erpnext/accounts/doctype/sales_taxes_and_charges_template/sales_taxes_and_charges_template.js +++ b/erpnext/accounts/doctype/sales_taxes_and_charges_template/sales_taxes_and_charges_template.js @@ -5,3 +5,25 @@ cur_frm.cscript.tax_table = "Sales Taxes and Charges"; {% include "erpnext/public/js/controllers/accounts.js" %} +frappe.tour['Sales Taxes and Charges Template'] = [ + { + fieldname: "title", + title: __("Title"), + description: __("A name by which you will identify this template. You can change this later."), + }, + { + fieldname: "company", + title: __("Company"), + description: __("Company for which this tax template will be applicable"), + }, + { + fieldname: "is_default", + title: __("Is this Default?"), + description: __("Set this template as the default for all sales transactions"), + }, + { + fieldname: "taxes", + title: __("Taxes Table"), + description: __("You can add a row for a tax rule here. These rules can be applied on the net total, or can be a flat amount."), + } +]; From 2d1f8341f97fe9cf5849b86b0e187e6b43944870 Mon Sep 17 00:00:00 2001 From: Shivam Mishra Date: Fri, 30 Oct 2020 15:41:58 +0530 Subject: [PATCH 039/477] feat: update onboarding for accounts --- .../accounts/module_onboarding/accounts/accounts.json | 2 +- .../chart_of_accounts/chart_of_accounts.json | 7 ++++--- .../configure_account_settings.json | 2 +- .../create_a_customer/create_a_customer.json | 7 +++---- .../create_a_product/create_a_product.json | 9 +++++---- .../create_a_supplier/create_a_supplier.json | 6 +++--- .../create_your_first_purchase_invoice.json | 6 +++--- .../create_your_first_sales_invoice.json | 2 +- .../onboarding_step/setup_taxes/setup_taxes.json | 7 ++++--- 9 files changed, 25 insertions(+), 23 deletions(-) diff --git a/erpnext/accounts/module_onboarding/accounts/accounts.json b/erpnext/accounts/module_onboarding/accounts/accounts.json index 83748dd9723..6b5c5a1db88 100644 --- a/erpnext/accounts/module_onboarding/accounts/accounts.json +++ b/erpnext/accounts/module_onboarding/accounts/accounts.json @@ -13,7 +13,7 @@ "documentation_url": "https://docs.erpnext.com/docs/user/manual/en/accounts", "idx": 0, "is_complete": 0, - "modified": "2020-10-19 14:43:45.080823", + "modified": "2020-10-30 15:41:15.547225", "modified_by": "Administrator", "module": "Accounts", "name": "Accounts", diff --git a/erpnext/accounts/onboarding_step/chart_of_accounts/chart_of_accounts.json b/erpnext/accounts/onboarding_step/chart_of_accounts/chart_of_accounts.json index ff9dfd2d732..fc49bd652b3 100644 --- a/erpnext/accounts/onboarding_step/chart_of_accounts/chart_of_accounts.json +++ b/erpnext/accounts/onboarding_step/chart_of_accounts/chart_of_accounts.json @@ -1,23 +1,24 @@ { "action": "Go to Page", + "action_label": "View Chart of Accounts", "callback_message": "You can continue with the onboarding after exploring this page", "callback_title": "Awesome Work", "creation": "2020-05-13 19:58:20.928127", - "description": "# Chart Of Accounts\n\n**The Chart of Accounts is the blueprint of the accounts in your organization.**\n\nThe overall structure of your Chart of Accounts is based on a system of double entry\naccounting that has become a standard all over the world to quantify how a\ncompany is doing financially.\n\nChart of Accounts is a tree view of the names of the Accounts (Ledgers and\nGroups) that a Company requires to manage its books of accounts. ERPNext sets\nup a simple chart of accounts for each Company you create, but you can\nmodify it according to your needs and legal requirements.\n\nFor each company, Chart of Accounts signifies the way to classify the accounting entries, mostly\nbased on statutory (tax, compliance to government regulations) requirements.\n\nThe Chart of Accounts helps you to answer questions like:\n\n * What is your organization worth?\n * How much debt have you taken?\n * How much profit are you making (and hence paying tax)?\n * How much are you selling?\n * What is your expense break-up?\n", + "description": "# Chart Of Accounts\n\nThe Chart of Accounts is the blueprint of the accounts in your organization.\nIt is a tree view of the names of the Accounts (Ledgers and Groups) that a Company requires to manage its books of accounts. ERPNext sets up a simple chart of accounts for each Company you create, but you can modify it according to your needs and legal requirements.\n\nFor each company, Chart of Accounts signifies the way to classify the accounting entries, mostly\nbased on statutory (tax, compliance to government regulations) requirements.\n\nThere's a brief video tutorial about chart of accounts in the next step.", "docstatus": 0, "doctype": "Onboarding Step", "idx": 0, "intro_video_url": "https://www.youtube.com/embed/AcfMCT7wLLo", "is_complete": 0, - "is_mandatory": 0, "is_single": 0, "is_skipped": 0, - "modified": "2020-10-19 14:25:31.427339", + "modified": "2020-10-30 14:35:59.474920", "modified_by": "Administrator", "name": "Chart of Accounts", "owner": "Administrator", "path": "Tree/Account", "reference_document": "Account", + "show_form_tour": 0, "show_full_form": 0, "title": "Review Chart of Accounts", "validate_action": 0 diff --git a/erpnext/accounts/onboarding_step/configure_account_settings/configure_account_settings.json b/erpnext/accounts/onboarding_step/configure_account_settings/configure_account_settings.json index 083fbb52bf2..c84430a0c64 100644 --- a/erpnext/accounts/onboarding_step/configure_account_settings/configure_account_settings.json +++ b/erpnext/accounts/onboarding_step/configure_account_settings/configure_account_settings.json @@ -6,7 +6,6 @@ "doctype": "Onboarding Step", "idx": 0, "is_complete": 0, - "is_mandatory": 0, "is_single": 1, "is_skipped": 0, "modified": "2020-10-19 14:40:55.584484", @@ -14,6 +13,7 @@ "name": "Configure Account Settings", "owner": "Administrator", "reference_document": "Accounts Settings", + "show_form_tour": 0, "show_full_form": 1, "title": "Configure Account Settings", "validate_action": 1 diff --git a/erpnext/accounts/onboarding_step/create_a_customer/create_a_customer.json b/erpnext/accounts/onboarding_step/create_a_customer/create_a_customer.json index 4a967b140b9..0b6750c5f8e 100644 --- a/erpnext/accounts/onboarding_step/create_a_customer/create_a_customer.json +++ b/erpnext/accounts/onboarding_step/create_a_customer/create_a_customer.json @@ -1,20 +1,19 @@ { "action": "Create Entry", "creation": "2020-05-14 17:46:41.831517", - "description": "# Customer\n\nA customer, who is sometimes known as a client, buyer, or purchaser is the one who receives goods, services, products, or ideas, from a seller for a monetary consideration.\n\n### Creating a customer is easy and can be done in the following steps\n\n1. Go to the Customer list and click on New.\n2. Enter Full Name of the customer.\n3. Select **Company** if the customer represents a company or **Individual** otherwise in Type field.\n4. Select a Customer Group. A few groups are included by default, you can create additional groups if you need.\n5. Select the Territory.\n6. If the customer is being created against a lead, you can select the same in From Lead field.\n7. Save.\n\nUp next is a video about customers and suppliers that will give you more clarity on these concepts in ERPNext", + "description": "## Who is a Customer?\n\nA customer, who is sometimes known as a client, buyer, or purchaser is the one who receives goods, services, products, or ideas, from a seller for a monetary consideration.\n\nEvery customer needs to be assigned a unique id. Customer name itself can be the id or you can set a naming series for ids to be generated in Selling Settings.\n\nJust like the supplier, let's quickly create a customer.", "docstatus": 0, "doctype": "Onboarding Step", "idx": 0, - "intro_video_url": "https://www.youtube.com/watch?v=zsrrVDk6VBs", "is_complete": 0, - "is_mandatory": 0, "is_single": 0, "is_skipped": 0, - "modified": "2020-10-16 12:59:16.989156", + "modified": "2020-10-30 15:28:46.659660", "modified_by": "Administrator", "name": "Create a Customer", "owner": "Administrator", "reference_document": "Customer", + "show_form_tour": 0, "show_full_form": 0, "title": "Create a Customer", "validate_action": 1 diff --git a/erpnext/accounts/onboarding_step/create_a_product/create_a_product.json b/erpnext/accounts/onboarding_step/create_a_product/create_a_product.json index 0cbefee8586..d76f645d96f 100644 --- a/erpnext/accounts/onboarding_step/create_a_product/create_a_product.json +++ b/erpnext/accounts/onboarding_step/create_a_product/create_a_product.json @@ -1,20 +1,21 @@ { "action": "Create Entry", "creation": "2020-05-12 18:16:06.624554", - "description": "## Creating Products\n\nIn ERPNext, any product or a service offered by your company is called an Item. The term Item is also applicable to raw materials or components of products yet to be produced (before they can be sold to customers). ERPNext allows you to manage all sorts of items like raw-materials, sub-assemblies, finished goods, item variants, and service items.\n\nERPNext is optimized for itemized management of your sales and purchase. If you are in services, you can create an Item for each service that you offer. Completing the Item Master is very essential for the successful implementation of ERPNext.\n\nYou can access the Item section\n\n`Desk > Stock > Item`\n\n\n", + "description": "## Products and Services\n\nDepending on the nature of your business, you might be selling products or services to your clients or even both. \nERPNext is optimized for itemized management of your sales and purchase.\n\nThe **Item Master** is where you can add all your sales items. If you are in services, you can create an Item for each service that you offer. If you run a manufacturing business, the same master is used for keeping a record of raw materials, sub-assemblies etc.\n\nCompleting the Item Master is very essential for the successful implementation of ERPNext. We have a brief video introducing the item master for you, you can watch it in the next step.", "docstatus": 0, "doctype": "Onboarding Step", "idx": 0, + "intro_video_url": "https://www.youtube.com/watch?v=Sl5UFA5H5EQ", "is_complete": 0, - "is_mandatory": 0, "is_single": 0, "is_skipped": 0, - "modified": "2020-10-16 12:59:16.983833", + "modified": "2020-10-30 15:20:30.133495", "modified_by": "Administrator", "name": "Create a Product", "owner": "Administrator", "reference_document": "Item", + "show_form_tour": 0, "show_full_form": 0, - "title": "Create a Product", + "title": "Create a Sales Item", "validate_action": 1 } \ No newline at end of file diff --git a/erpnext/accounts/onboarding_step/create_a_supplier/create_a_supplier.json b/erpnext/accounts/onboarding_step/create_a_supplier/create_a_supplier.json index eede11d9796..64bc7bbfef9 100644 --- a/erpnext/accounts/onboarding_step/create_a_supplier/create_a_supplier.json +++ b/erpnext/accounts/onboarding_step/create_a_supplier/create_a_supplier.json @@ -1,19 +1,19 @@ { "action": "Create Entry", "creation": "2020-05-14 22:09:10.043554", - "description": "## Let's add your Suppliers\n\nSuppliers are companies or individuals who provide you with products or services. A supplier may be distinguished from a contractor or subcontractor, who commonly adds specialized input to deliverables. A supplier is also known as a vendor. There are different types of suppliers based on the goods and products they supply.\n\nERPNext allows you to create your own categories of suppliers. These categories are known as Supplier Groups. For example, if your suppliers are mainly pharmaceutical companies and FMCG distributors, you can create a new Supplier Groups for them and name the groups accordingly.", + "description": "## Who is a Supplier?\n\nSuppliers are companies or individuals who provide you with products or services. ERPNext has comprehensive features for purchase cycles. \n\nLet's quickly create a supplier with the minimal details required. You need the name of the supplier, assign the supplier to a group, and select the type of the supplier, viz. Company or Individual.", "docstatus": 0, "doctype": "Onboarding Step", "idx": 0, "is_complete": 0, - "is_mandatory": 0, "is_single": 0, "is_skipped": 0, - "modified": "2020-10-16 12:59:16.979176", + "modified": "2020-10-30 15:26:48.315772", "modified_by": "Administrator", "name": "Create a Supplier", "owner": "Administrator", "reference_document": "Supplier", + "show_form_tour": 0, "show_full_form": 0, "title": "Create a Supplier", "validate_action": 1 diff --git a/erpnext/accounts/onboarding_step/create_your_first_purchase_invoice/create_your_first_purchase_invoice.json b/erpnext/accounts/onboarding_step/create_your_first_purchase_invoice/create_your_first_purchase_invoice.json index 2b53f46fe9c..ddbc89ec0a7 100644 --- a/erpnext/accounts/onboarding_step/create_your_first_purchase_invoice/create_your_first_purchase_invoice.json +++ b/erpnext/accounts/onboarding_step/create_your_first_purchase_invoice/create_your_first_purchase_invoice.json @@ -1,19 +1,19 @@ { "action": "Create Entry", "creation": "2020-05-14 22:10:07.049704", - "description": "# What's a Purchase Invoice?\n\nA Purchase Invoice is a bill you receive from your Suppliers against which you need to make the payment.\nPurchase Invoice is the exact opposite of your Sales Invoice. Here you accrue expenses to your Supplier. Making a Purchase Invoice is very similar to making a Purchase Order.\n\n![Purchase Flow](https://docs.erpnext.com/docs/assets/img/accounts/pi-flow.png)\n\n", + "description": "# What's a Purchase Invoice?\n\nA Purchase Invoice is a bill you receive from your Suppliers against which you need to make the payment.\nPurchase Invoice is the exact opposite of your Sales Invoice. Here you accrue expenses to your Supplier. \n\nThe following is what a typical purchase cycle looks like, however you can create a purchase invoice directly as well.\n\n![Purchase Flow](https://docs.erpnext.com/docs/assets/img/accounts/pi-flow.png)\n\n", "docstatus": 0, "doctype": "Onboarding Step", "idx": 0, "is_complete": 0, - "is_mandatory": 0, "is_single": 0, "is_skipped": 0, - "modified": "2020-10-16 12:59:16.976334", + "modified": "2020-10-30 15:30:26.337773", "modified_by": "Administrator", "name": "Create Your First Purchase Invoice", "owner": "Administrator", "reference_document": "Purchase Invoice", + "show_form_tour": 0, "show_full_form": 1, "title": "Create Your First Purchase Invoice ", "validate_action": 1 diff --git a/erpnext/accounts/onboarding_step/create_your_first_sales_invoice/create_your_first_sales_invoice.json b/erpnext/accounts/onboarding_step/create_your_first_sales_invoice/create_your_first_sales_invoice.json index d56be9220dc..9e7dd679001 100644 --- a/erpnext/accounts/onboarding_step/create_your_first_sales_invoice/create_your_first_sales_invoice.json +++ b/erpnext/accounts/onboarding_step/create_your_first_sales_invoice/create_your_first_sales_invoice.json @@ -6,7 +6,6 @@ "doctype": "Onboarding Step", "idx": 0, "is_complete": 0, - "is_mandatory": 0, "is_single": 0, "is_skipped": 0, "modified": "2020-10-16 12:59:16.987507", @@ -14,6 +13,7 @@ "name": "Create Your First Sales Invoice", "owner": "Administrator", "reference_document": "Sales Invoice", + "show_form_tour": 0, "show_full_form": 1, "title": "Create Your First Sales Invoice ", "validate_action": 1 diff --git a/erpnext/accounts/onboarding_step/setup_taxes/setup_taxes.json b/erpnext/accounts/onboarding_step/setup_taxes/setup_taxes.json index fa3eabd9748..a4922013dab 100644 --- a/erpnext/accounts/onboarding_step/setup_taxes/setup_taxes.json +++ b/erpnext/accounts/onboarding_step/setup_taxes/setup_taxes.json @@ -1,19 +1,20 @@ { "action": "Create Entry", + "action_label": "Make a Sales Tax Template", "creation": "2020-05-13 19:29:43.844463", - "description": "# Setting up Taxes\n\nOne of the primary motivators for compulsory use of accounting tools is the calculation of taxes. ERPNext allows you to make configurable tax templates that you can apply to your sales or purchase transactions.\n\nThe templates created from this form can be used in Sales Orders and Sales Invoices. The way ERPNext sets up taxes is via templates. Other types of charges that may apply to your invoices (like shipping, insurance etc.) can also be configured as taxes.\n\nFor Tax Accounts that you want to use in the tax templates, go to:\n\n`> Home > Accounting > Chart of Accounts`\n\nSelect an account and click on edit. Select the 'Account Type' as 'Tax' for the account.\nIn this step we will guide you towards making the sales and taxes template.", + "description": "# Setting up Taxes\n\nAny sophisticated accounting system, including ERPNext will have automatic tax calculations for your transactions. These calculations are based on user defined rules in compliance to local rules and regulations.\n\nERPNext allows this via *Tax Templates*. These templates can be used in Sales Orders and Sales Invoices. Other types of charges that may apply to your invoices (like shipping, insurance etc.) can also be configured as taxes.\n\nFor Tax Accounts that you want to use in the tax templates, go to:\n\n`> Accounting > Taxes > Sales Taxes and Charges Template`\n\nYou can read more about these templates in our documentation [here](https://docs.erpnext.com/docs/user/manual/en/selling/sales-taxes-and-charges-template)\n", "docstatus": 0, "doctype": "Onboarding Step", "idx": 0, "is_complete": 0, - "is_mandatory": 0, "is_single": 0, "is_skipped": 0, - "modified": "2020-10-16 12:59:16.991287", + "modified": "2020-10-30 14:54:18.087383", "modified_by": "Administrator", "name": "Setup Taxes", "owner": "Administrator", "reference_document": "Sales Taxes and Charges Template", + "show_form_tour": 1, "show_full_form": 1, "title": "Lets create a Tax Template for Sales ", "validate_action": 0 From e927224fbc45b54929825b015ad7da161bc984d9 Mon Sep 17 00:00:00 2001 From: Shivam Mishra Date: Wed, 4 Nov 2020 19:57:47 +0530 Subject: [PATCH 040/477] feat: update membership setting doctype * rename enable_auto_invoicing to enable_invoicing * add option to make_payment entry --- .../membership_settings.json | 42 +++++++++++++------ .../membership_type/membership_type.js | 4 +- 2 files changed, 32 insertions(+), 14 deletions(-) diff --git a/erpnext/non_profit/doctype/membership_settings/membership_settings.json b/erpnext/non_profit/doctype/membership_settings/membership_settings.json index 5b6bab5b0a0..a70c3c4b8ae 100644 --- a/erpnext/non_profit/doctype/membership_settings/membership_settings.json +++ b/erpnext/non_profit/doctype/membership_settings/membership_settings.json @@ -11,9 +11,11 @@ "billing_frequency", "webhook_secret", "column_break_6", - "enable_auto_invoicing", + "enable_invoicing", + "make_payment_entry", "company", "debit_account", + "payment_account", "column_break_9", "send_email", "send_invoice", @@ -58,14 +60,7 @@ "label": "Invoicing" }, { - "default": "0", - "fieldname": "enable_auto_invoicing", - "fieldtype": "Check", - "label": "Enable Auto Invoicing", - "mandatory_depends_on": "eval:doc.send_invoice" - }, - { - "depends_on": "eval:doc.enable_auto_invoicing", + "depends_on": "eval:doc.enable_invoicing", "fieldname": "debit_account", "fieldtype": "Link", "label": "Debit Account", @@ -77,7 +72,7 @@ "fieldtype": "Column Break" }, { - "depends_on": "eval:doc.enable_auto_invoicing", + "depends_on": "eval:doc.enable_invoicing", "fieldname": "company", "fieldtype": "Link", "label": "Company", @@ -86,7 +81,7 @@ }, { "default": "0", - "depends_on": "eval:doc.enable_auto_invoicing && doc.send_email", + "depends_on": "eval:doc.enable_invoicing && doc.send_email", "fieldname": "send_invoice", "fieldtype": "Check", "label": "Send Invoice with Email" @@ -119,11 +114,34 @@ "label": "Email Template", "mandatory_depends_on": "eval:doc.send_email", "options": "Email Template" + }, + { + "default": "0", + "fieldname": "enable_invoicing", + "fieldtype": "Check", + "label": "Enable Invoicing", + "mandatory_depends_on": "eval:doc.send_invoice || doc.make_payment_entry" + }, + { + "default": "0", + "depends_on": "eval:doc.enable_invoicing", + "fieldname": "make_payment_entry", + "fieldtype": "Check", + "label": "Make Payment Entry" + }, + { + "depends_on": "eval:doc.make_payment_entry", + "fieldname": "payment_account", + "fieldtype": "Link", + "label": "Payment To", + "mandatory_depends_on": "eval:doc.make_payment_entry", + "options": "Account" } ], + "index_web_pages_for_search": 1, "issingle": 1, "links": [], - "modified": "2020-08-05 17:26:37.287395", + "modified": "2020-11-04 19:51:21.990595", "modified_by": "Administrator", "module": "Non Profit", "name": "Membership Settings", diff --git a/erpnext/non_profit/doctype/membership_type/membership_type.js b/erpnext/non_profit/doctype/membership_type/membership_type.js index 43311a2c965..94ccdd83345 100644 --- a/erpnext/non_profit/doctype/membership_type/membership_type.js +++ b/erpnext/non_profit/doctype/membership_type/membership_type.js @@ -2,12 +2,12 @@ // For license information, please see license.txt frappe.ui.form.on('Membership Type', { - refresh: function(frm) { + refresh: function (frm) { frappe.db.get_single_value("Membership Settings", "enable_razorpay").then(val => { if (val) frm.set_df_property('razorpay_plan_id', 'hidden', false); }); - frappe.db.get_single_value("Membership Settings", "enable_auto_invoicing").then(val => { + frappe.db.get_single_value("Membership Settings", "enable_invoicing").then(val => { if (val) frm.set_df_property('linked_item', 'hidden', false); }); } From d75ff1a93e562ac5e22dc5afd2aef20fc8c62ab1 Mon Sep 17 00:00:00 2001 From: Shivam Mishra Date: Wed, 4 Nov 2020 20:17:33 +0530 Subject: [PATCH 041/477] feat: generate invoice on payment authorized --- erpnext/non_profit/doctype/membership/membership.py | 11 ++++++++--- .../membership_settings/membership_settings.json | 10 +++++++++- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/erpnext/non_profit/doctype/membership/membership.py b/erpnext/non_profit/doctype/membership/membership.py index 4c85cb60e8b..97de63b052e 100644 --- a/erpnext/non_profit/doctype/membership/membership.py +++ b/erpnext/non_profit/doctype/membership/membership.py @@ -54,9 +54,14 @@ class Membership(Document): self.to_date = add_months(self.from_date, 1) def on_payment_authorized(self, status_changed_to=None): - if status_changed_to in ("Completed", "Authorized"): - self.load_from_db() - self.db_set('paid', 1) + if status_changed_to not in ("Completed", "Authorized"): + return + self.load_from_db() + self.db_set('paid', 1) + settings = frappe.get_doc("Membership Settings") + if settings.enable_invoicing and settings.create_for_web_forms: + self.generate_invoice(with_payment_entry=settings.make_payment_entry, save=True) + def generate_invoice(self, save=True): if not (self.paid or self.currency or self.amount): diff --git a/erpnext/non_profit/doctype/membership_settings/membership_settings.json b/erpnext/non_profit/doctype/membership_settings/membership_settings.json index a70c3c4b8ae..a25f5ffbc22 100644 --- a/erpnext/non_profit/doctype/membership_settings/membership_settings.json +++ b/erpnext/non_profit/doctype/membership_settings/membership_settings.json @@ -12,6 +12,7 @@ "webhook_secret", "column_break_6", "enable_invoicing", + "create_for_web_forms", "make_payment_entry", "company", "debit_account", @@ -136,12 +137,19 @@ "label": "Payment To", "mandatory_depends_on": "eval:doc.make_payment_entry", "options": "Account" + }, + { + "depends_on": "eval:doc.enable_invoicing", + "description": "Automatically create an invoice when payment is authorized from a web form entry", + "fieldname": "create_for_web_forms", + "fieldtype": "Data", + "label": "Auto Create Invoice for Web Forms" } ], "index_web_pages_for_search": 1, "issingle": 1, "links": [], - "modified": "2020-11-04 19:51:21.990595", + "modified": "2020-11-04 20:19:55.163749", "modified_by": "Administrator", "module": "Non Profit", "name": "Membership Settings", From 9d9fa74e6b8dd5db1f89bc6bf92809c0fba29eda Mon Sep 17 00:00:00 2001 From: Shivam Mishra Date: Mon, 9 Nov 2020 12:29:03 +0530 Subject: [PATCH 042/477] refactor(member): drop email column * remove email column * update controller methods * add patch to add value from email to email_id --- erpnext/non_profit/doctype/member/member.json | 10 +--------- .../doctype/membership/membership.py | 8 ++++++-- erpnext/patches.txt | 3 ++- .../v13_0/update_member_email_address.py | 19 +++++++++++++++++++ 4 files changed, 28 insertions(+), 12 deletions(-) create mode 100644 erpnext/patches/v13_0/update_member_email_address.py diff --git a/erpnext/non_profit/doctype/member/member.json b/erpnext/non_profit/doctype/member/member.json index 992ef16d644..f190cfae755 100644 --- a/erpnext/non_profit/doctype/member/member.json +++ b/erpnext/non_profit/doctype/member/member.json @@ -12,7 +12,6 @@ "membership_expiry_date", "column_break_5", "membership_type", - "email", "email_id", "image", "customer_section", @@ -64,13 +63,6 @@ "options": "Membership Type", "reqd": 1 }, - { - "fieldname": "email", - "fieldtype": "Link", - "in_list_view": 1, - "label": "User", - "options": "User" - }, { "fieldname": "image", "fieldtype": "Attach Image", @@ -178,7 +170,7 @@ ], "image_field": "image", "links": [], - "modified": "2020-09-16 23:44:13.596948", + "modified": "2020-11-09 12:12:10.174647", "modified_by": "Administrator", "module": "Non Profit", "name": "Member", diff --git a/erpnext/non_profit/doctype/membership/membership.py b/erpnext/non_profit/doctype/membership/membership.py index 97de63b052e..36f68bc00c4 100644 --- a/erpnext/non_profit/doctype/membership/membership.py +++ b/erpnext/non_profit/doctype/membership/membership.py @@ -24,7 +24,7 @@ class Membership(Document): user = frappe.get_doc('User', frappe.session.user) member = frappe.get_doc(dict( doctype='Member', - email=frappe.session.user, + email_id=frappe.session.user, membership_type=self.membership_type, member_name=user.get_fullname() )).insert(ignore_permissions=True) @@ -97,8 +97,12 @@ class Membership(Document): frappe.throw(_("You need to enable Send Acknowledge Email in Membership Settings")) member = frappe.get_doc("Member", self.member) + + if not member.email_id: + frappe.throw(_("Email address of member {0} is missing").format(frappe.utils.get_link_to_form("Member", self.member))) + plan = frappe.get_doc("Membership Type", self.membership_type) - email = member.email_id if member.email_id else member.email + email = member.email_id attachments = [frappe.attach_print("Membership", self.name, print_format=settings.membership_print_format)] if self.invoice and settings.send_invoice: diff --git a/erpnext/patches.txt b/erpnext/patches.txt index 34dbdd0bd51..a9cd25fd420 100644 --- a/erpnext/patches.txt +++ b/erpnext/patches.txt @@ -733,4 +733,5 @@ erpnext.patches.v13_0.print_uom_after_quantity_patch erpnext.patches.v13_0.set_payment_channel_in_payment_gateway_account erpnext.patches.v13_0.create_healthcare_custom_fields_in_stock_entry_detail erpnext.patches.v13_0.update_reason_for_resignation_in_employee -execute:frappe.delete_doc("Report", "Quoted Item Comparison") \ No newline at end of file +execute:frappe.delete_doc("Report", "Quoted Item Comparison") +erpnext.patches.v13_0.update_member_email_address \ No newline at end of file diff --git a/erpnext/patches/v13_0/update_member_email_address.py b/erpnext/patches/v13_0/update_member_email_address.py new file mode 100644 index 00000000000..da7828adbcb --- /dev/null +++ b/erpnext/patches/v13_0/update_member_email_address.py @@ -0,0 +1,19 @@ +# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and Contributors +# MIT License. See license.txt + +from __future__ import unicode_literals +import frappe + +def execute(): + """add value to email_id column from email""" + + if frappe.db.has_column("Member", "email"): + # Get all members + for member in frappe.db.get_all("Member", pluck="name"): + # Check if email_id already exists + if not frappe.db.get_value("Member", member, "email_id"): + # fetch email id from the user linked field email + email = frappe.db.get_value("Member", member, "email") + + # Set the value for it + frappe.db.set_value("Member", member, "email_id", email) From e0f4dd0643a9ef59d81d70d35050f7e51cfcdc1d Mon Sep 17 00:00:00 2001 From: Shivam Mishra Date: Mon, 9 Nov 2020 12:29:27 +0530 Subject: [PATCH 043/477] fix: fieldtype for auto_create_for_web_forms --- .../doctype/membership_settings/membership_settings.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/erpnext/non_profit/doctype/membership_settings/membership_settings.json b/erpnext/non_profit/doctype/membership_settings/membership_settings.json index a25f5ffbc22..961a9b9b3b1 100644 --- a/erpnext/non_profit/doctype/membership_settings/membership_settings.json +++ b/erpnext/non_profit/doctype/membership_settings/membership_settings.json @@ -139,17 +139,18 @@ "options": "Account" }, { + "default": "0", "depends_on": "eval:doc.enable_invoicing", "description": "Automatically create an invoice when payment is authorized from a web form entry", "fieldname": "create_for_web_forms", - "fieldtype": "Data", + "fieldtype": "Check", "label": "Auto Create Invoice for Web Forms" } ], "index_web_pages_for_search": 1, "issingle": 1, "links": [], - "modified": "2020-11-04 20:19:55.163749", + "modified": "2020-11-09 12:28:49.972434", "modified_by": "Administrator", "module": "Non Profit", "name": "Membership Settings", From 286ec04197e6cad7aac9a95d9c8996bc44006252 Mon Sep 17 00:00:00 2001 From: Shivam Mishra Date: Mon, 9 Nov 2020 12:53:00 +0530 Subject: [PATCH 044/477] test(membership): setup test defaults --- .../doctype/membership/membership.py | 2 + .../doctype/membership/test_membership.py | 47 ++++++++++++++++++- 2 files changed, 47 insertions(+), 2 deletions(-) diff --git a/erpnext/non_profit/doctype/membership/membership.py b/erpnext/non_profit/doctype/membership/membership.py index 36f68bc00c4..ae4df4a3747 100644 --- a/erpnext/non_profit/doctype/membership/membership.py +++ b/erpnext/non_profit/doctype/membership/membership.py @@ -162,6 +162,8 @@ def get_member_based_on_subscription(subscription_id, email): return None def verify_signature(data): + if frappe.flags.in_test: + return True signature = frappe.request.headers.get('X-Razorpay-Signature') settings = frappe.get_doc("Membership Settings") diff --git a/erpnext/non_profit/doctype/membership/test_membership.py b/erpnext/non_profit/doctype/membership/test_membership.py index b23f4062a97..b62f19bd0de 100644 --- a/erpnext/non_profit/doctype/membership/test_membership.py +++ b/erpnext/non_profit/doctype/membership/test_membership.py @@ -2,8 +2,51 @@ # Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and Contributors # See license.txt from __future__ import unicode_literals - import unittest +from erpnext.non_profit.doctype.member.member import create_member +from erpnext.stock.doctype.item.test_item import create_item class TestMembership(unittest.TestCase): - pass + def setUp(self): + # Get default company + company = frappe.get_doc("Company", erpnext.get_default_company()) + + # update membership settings + settings = frappe.get_doc("Membership Settings") + # Enable razorpay + settings.enable_razorpay = 1 + settings.billing_cycle = "Monthly" + settings.billing_frequency = 24 + # Enable invoicing + settings.enable_invoicing = 1 + settings.make_payment_entry = 1 + settings.company = company.name + settings.payment_to = company.default_cash_account + settings.debit_account = company.default_receivable_account + settings.save() + + # make test plan + plan = frappe.new_doc("Membership Type") + plan.amount = 100 + plan.razorpay_plan_id = "_rzpy_test_milythm" + plan.linked_item = create_item("_Test Item for Non Profit Membership") + plan.insert() + + # make test member + self.member_doc = create_member(frappe._dict({ + 'fullname': "_Test_Member", + 'email': "_test_member_erpnext@example.com", + 'plan_id': plan.name + })) + + def test_auto_generate_invoice_and_payment_entry(self): + pass + + def test_renew within_30_days(self): + pass + + def test_from_to_dates(self): + pass + + def test_razorpay_webook(self): + pass From c04321e64586ec7f466bb848530712320f4bfbe8 Mon Sep 17 00:00:00 2001 From: Shivam Mishra Date: Mon, 9 Nov 2020 13:29:46 +0530 Subject: [PATCH 045/477] test(membership): add test for invoicing and validation --- .../doctype/membership/membership.py | 16 +++- .../doctype/membership/test_membership.py | 78 ++++++++++++++++--- 2 files changed, 84 insertions(+), 10 deletions(-) diff --git a/erpnext/non_profit/doctype/membership/membership.py b/erpnext/non_profit/doctype/membership/membership.py index ae4df4a3747..ac3b89a8d02 100644 --- a/erpnext/non_profit/doctype/membership/membership.py +++ b/erpnext/non_profit/doctype/membership/membership.py @@ -86,6 +86,20 @@ class Membership(Document): invoice = make_invoice(self, member, plan, settings) self.invoice = invoice.name + if with_payment_entry: + if not settings.payment_account: + frappe.throw(_("You need to set Payment Account in Membership Settings")) + + from erpnext.accounts.doctype.payment_entry.payment_entry import get_payment_entry + frappe.flags.ignore_account_permission=True + pe = get_payment_entry(dt='Sales Invoice', dn=invoice.name, bank_amount=invoice.grand_total) + frappe.flags.ignore_account_permission=False + pe.paid_to = settings.payment_account + pe.reference_no = self.name + pe.reference_date = getdate() + pe.save(ignore_permissions=True) + pe.submit() + if save: self.save() @@ -97,7 +111,7 @@ class Membership(Document): frappe.throw(_("You need to enable Send Acknowledge Email in Membership Settings")) member = frappe.get_doc("Member", self.member) - + if not member.email_id: frappe.throw(_("Email address of member {0} is missing").format(frappe.utils.get_link_to_form("Member", self.member))) diff --git a/erpnext/non_profit/doctype/membership/test_membership.py b/erpnext/non_profit/doctype/membership/test_membership.py index b62f19bd0de..6e4885d013c 100644 --- a/erpnext/non_profit/doctype/membership/test_membership.py +++ b/erpnext/non_profit/doctype/membership/test_membership.py @@ -3,7 +3,10 @@ # See license.txt from __future__ import unicode_literals import unittest +import frappe +import erpnext from erpnext.non_profit.doctype.member.member import create_member +from frappe.utils import nowdate, getdate, add_months from erpnext.stock.doctype.item.test_item import create_item class TestMembership(unittest.TestCase): @@ -21,15 +24,16 @@ class TestMembership(unittest.TestCase): settings.enable_invoicing = 1 settings.make_payment_entry = 1 settings.company = company.name - settings.payment_to = company.default_cash_account + settings.payment_account = company.default_cash_account settings.debit_account = company.default_receivable_account settings.save() # make test plan plan = frappe.new_doc("Membership Type") + plan.membership_type = "_rzpy_test_milythm" plan.amount = 100 plan.razorpay_plan_id = "_rzpy_test_milythm" - plan.linked_item = create_item("_Test Item for Non Profit Membership") + plan.linked_item = create_item("_Test Item for Non Profit Membership").name plan.insert() # make test member @@ -38,15 +42,71 @@ class TestMembership(unittest.TestCase): 'email': "_test_member_erpnext@example.com", 'plan_id': plan.name })) + self.member_doc.make_customer_and_link() + self.member = "self.member_doc.name" def test_auto_generate_invoice_and_payment_entry(self): - pass + entry = make_membership(self.member) - def test_renew within_30_days(self): - pass + # Naive test to see if at all invoice was generated and attached to member + # In any case if details were missing, the invoicing would throw an error + invoice = entry.generate_invoice(save=True) + self.assertEqual(invoice.name, entry.invoice) + # entry.delete() - def test_from_to_dates(self): - pass + # # Remove customer + # old_customer = self.member_doc.customer + # self.member_doc.customer = None + # self.member_doc.save() - def test_razorpay_webook(self): - pass + # entry = make_membership(self.member) + # self.assertRaises(frappe.ValidationError, entry.generate_invoice) + + # # Add customer value back + # self.member_doc.customer = old_customer + # self.member_doc.save() + + # # Remove company + # set_config(company, None) + # self.assertRaises(frappe.ValidationError, entry.generate_invoice) + + def test_renew_within_30_days(self): + # create a membership for two months + # Should work fine + make_membership(self.member, { "from_date": nowdate() }) + make_membership(self.member, { "from_date": add_months(nowdate(), 1) }) + + from frappe.utils.user import add_role + add_role("test@example.com", "Non Profit Manager") + frappe.set_user("test@example.com") + + # create next membership with expiry not within 30 days + self.assertRaises(frappe.ValidationError, make_membership, self.member, { + "from_date": add_months(nowdate(), 2), + }) + + frappe.set_user("Administrator") + # create the same membership but as administrator + new_entry = make_membership(self.member, { + "from_date": add_months(nowdate(), 2), + "to_date": add_months(nowdate(), 3), + }) + +def set_config(key, value): + frappe.db.set_value("Membership Settings", None, key, value) + +def make_membership(member, payload={}): + data = { + "doctype": "Membership", + "member": member, + "membership_status": "Current", + "membership_type": "_rzpy_test_milythm", + "currency": "INR", + "paid": 1, + "from_date": nowdate(), + "amount": 100 + } + data.update(payload) + membership = frappe.get_doc(data) + membership.insert(ignore_permissions=True, ignore_if_duplicate=True) + return membership \ No newline at end of file From 7e1cdf9b978ffdb6713a2e2cade4ac7307b73533 Mon Sep 17 00:00:00 2001 From: Shivam Mishra Date: Mon, 9 Nov 2020 14:01:11 +0530 Subject: [PATCH 046/477] feat(breaking): update get_last_membership to fetch correct details --- erpnext/__init__.py | 14 ++++---------- .../non_profit/doctype/membership/membership.py | 2 +- 2 files changed, 5 insertions(+), 11 deletions(-) diff --git a/erpnext/__init__.py b/erpnext/__init__.py index 38d8a62f07f..5a5c448026e 100644 --- a/erpnext/__init__.py +++ b/erpnext/__init__.py @@ -132,16 +132,10 @@ def allow_regional(fn): return caller -def get_last_membership(): +def get_last_membership(member): '''Returns last membership if exists''' last_membership = frappe.get_all('Membership', 'name,to_date,membership_type', - dict(member=frappe.session.user, paid=1), order_by='to_date desc', limit=1) + dict(member=member, paid=1), order_by='to_date desc', limit=1) - return last_membership and last_membership[0] - -def is_member(): - '''Returns true if the user is still a member''' - last_membership = get_last_membership() - if last_membership and getdate(last_membership.to_date) > getdate(): - return True - return False + if last_membership: + return last_membership[0] diff --git a/erpnext/non_profit/doctype/membership/membership.py b/erpnext/non_profit/doctype/membership/membership.py index ac3b89a8d02..7c83a4e0da1 100644 --- a/erpnext/non_profit/doctype/membership/membership.py +++ b/erpnext/non_profit/doctype/membership/membership.py @@ -34,7 +34,7 @@ class Membership(Document): self.member = member_name # get last membership (if active) - last_membership = erpnext.get_last_membership() + last_membership = erpnext.get_last_membership(self.member) # if person applied for offline membership if last_membership and not frappe.session.user == "Administrator": From 12fafa3e7a20bb8a2ad54ea43f8e3d2146bd30b5 Mon Sep 17 00:00:00 2001 From: Shivam Mishra Date: Mon, 9 Nov 2020 14:01:22 +0530 Subject: [PATCH 047/477] chore: remove validation for old member field --- erpnext/non_profit/doctype/member/member.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/erpnext/non_profit/doctype/member/member.py b/erpnext/non_profit/doctype/member/member.py index 44b975e9e9d..7fc4f225aae 100644 --- a/erpnext/non_profit/doctype/member/member.py +++ b/erpnext/non_profit/doctype/member/member.py @@ -18,8 +18,6 @@ class Member(Document): def validate(self): - if self.email: - self.validate_email_type(self.email) if self.email_id: self.validate_email_type(self.email_id) From 723e220a3409150de11c4b74a7bbb5911060382b Mon Sep 17 00:00:00 2001 From: Shivam Mishra Date: Mon, 9 Nov 2020 14:01:52 +0530 Subject: [PATCH 048/477] chore: remove commented code --- .../doctype/membership/test_membership.py | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/erpnext/non_profit/doctype/membership/test_membership.py b/erpnext/non_profit/doctype/membership/test_membership.py index 6e4885d013c..ce31b919562 100644 --- a/erpnext/non_profit/doctype/membership/test_membership.py +++ b/erpnext/non_profit/doctype/membership/test_membership.py @@ -52,23 +52,6 @@ class TestMembership(unittest.TestCase): # In any case if details were missing, the invoicing would throw an error invoice = entry.generate_invoice(save=True) self.assertEqual(invoice.name, entry.invoice) - # entry.delete() - - # # Remove customer - # old_customer = self.member_doc.customer - # self.member_doc.customer = None - # self.member_doc.save() - - # entry = make_membership(self.member) - # self.assertRaises(frappe.ValidationError, entry.generate_invoice) - - # # Add customer value back - # self.member_doc.customer = old_customer - # self.member_doc.save() - - # # Remove company - # set_config(company, None) - # self.assertRaises(frappe.ValidationError, entry.generate_invoice) def test_renew_within_30_days(self): # create a membership for two months From e3b71b9b249946b2e8c8d0d5ebe5096ac7f038bf Mon Sep 17 00:00:00 2001 From: prssanna Date: Tue, 10 Nov 2020 17:23:24 +0530 Subject: [PATCH 049/477] fix: compact item print style --- .../print_formats/includes/item_table_description.html | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/erpnext/templates/print_formats/includes/item_table_description.html b/erpnext/templates/print_formats/includes/item_table_description.html index ed46c9e224d..7569e50b45c 100644 --- a/erpnext/templates/print_formats/includes/item_table_description.html +++ b/erpnext/templates/print_formats/includes/item_table_description.html @@ -11,11 +11,11 @@
{% if doc.in_format_data("item_code") and "item_code" in display_columns -%} -
- {% if compact %}{% endif %} - {{ _(doc.item_code) }} - {% if compact %}{% endif %} + {% if compact %} +
+ {{ _(doc.item_code) }}
+ {% endif %} {%- endif %} {%- if doc.in_format_data("item_name") and "item_name" in display_columns and From c1b0e65f9f9df5fdad4a813a788f4f458b2e8318 Mon Sep 17 00:00:00 2001 From: marination Date: Thu, 12 Nov 2020 09:54:44 +0530 Subject: [PATCH 050/477] feat: Putaway --- .../stock/doctype/putaway_rule/__init__.py | 0 .../doctype/putaway_rule/putaway_rule.js | 18 +++ .../doctype/putaway_rule/putaway_rule.json | 111 ++++++++++++++++++ .../doctype/putaway_rule/putaway_rule.py | 93 +++++++++++++++ .../doctype/putaway_rule/putaway_rule_list.js | 10 ++ .../doctype/putaway_rule/test_putaway_rule.py | 10 ++ 6 files changed, 242 insertions(+) create mode 100644 erpnext/stock/doctype/putaway_rule/__init__.py create mode 100644 erpnext/stock/doctype/putaway_rule/putaway_rule.js create mode 100644 erpnext/stock/doctype/putaway_rule/putaway_rule.json create mode 100644 erpnext/stock/doctype/putaway_rule/putaway_rule.py create mode 100644 erpnext/stock/doctype/putaway_rule/putaway_rule_list.js create mode 100644 erpnext/stock/doctype/putaway_rule/test_putaway_rule.py diff --git a/erpnext/stock/doctype/putaway_rule/__init__.py b/erpnext/stock/doctype/putaway_rule/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/erpnext/stock/doctype/putaway_rule/putaway_rule.js b/erpnext/stock/doctype/putaway_rule/putaway_rule.js new file mode 100644 index 00000000000..ae08e82c28b --- /dev/null +++ b/erpnext/stock/doctype/putaway_rule/putaway_rule.js @@ -0,0 +1,18 @@ +// Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors +// For license information, please see license.txt + +frappe.ui.form.on('Putaway Rule', { + setup: function(frm) { + frm.set_query("warehouse", function() { + return { + "filters": { + "company": frm.doc.company, + "is_group": 0 + } + }; + }); + } + // refresh: function(frm) { + + // } +}); diff --git a/erpnext/stock/doctype/putaway_rule/putaway_rule.json b/erpnext/stock/doctype/putaway_rule/putaway_rule.json new file mode 100644 index 00000000000..6a132c7e256 --- /dev/null +++ b/erpnext/stock/doctype/putaway_rule/putaway_rule.json @@ -0,0 +1,111 @@ +{ + "actions": [], + "autoname": "format:{item_code}-{warehouse}", + "creation": "2020-11-09 11:39:46.489501", + "doctype": "DocType", + "editable_grid": 1, + "engine": "InnoDB", + "field_order": [ + "disable", + "item_code", + "item_name", + "warehouse", + "col_break_capacity", + "company", + "capacity", + "priority", + "stock_uom" + ], + "fields": [ + { + "fieldname": "item_code", + "fieldtype": "Link", + "in_list_view": 1, + "in_standard_filter": 1, + "label": "Item", + "options": "Item", + "reqd": 1 + }, + { + "fetch_from": "item_code.item_name", + "fieldname": "item_name", + "fieldtype": "Data", + "label": "Item Name", + "read_only": 1 + }, + { + "fieldname": "warehouse", + "fieldtype": "Link", + "in_list_view": 1, + "in_standard_filter": 1, + "label": "Warehouse", + "options": "Warehouse", + "reqd": 1 + }, + { + "fieldname": "col_break_capacity", + "fieldtype": "Column Break" + }, + { + "default": "0", + "fieldname": "capacity", + "fieldtype": "Float", + "in_list_view": 1, + "label": "Capacity", + "reqd": 1 + }, + { + "default": "item_code.stock_uom", + "fieldname": "stock_uom", + "fieldtype": "Link", + "label": "Stock UOM", + "options": "UOM", + "read_only": 1 + }, + { + "default": "1", + "fieldname": "priority", + "fieldtype": "Int", + "label": "Priority" + }, + { + "fieldname": "company", + "fieldtype": "Link", + "in_standard_filter": 1, + "label": "Company", + "options": "Company", + "reqd": 1 + }, + { + "default": "0", + "depends_on": "eval:!doc.__islocal", + "fieldname": "disable", + "fieldtype": "Check", + "label": "Disable" + } + ], + "index_web_pages_for_search": 1, + "links": [], + "modified": "2020-11-10 17:06:27.151335", + "modified_by": "Administrator", + "module": "Stock", + "name": "Putaway Rule", + "owner": "Administrator", + "permissions": [ + { + "create": 1, + "delete": 1, + "email": 1, + "export": 1, + "print": 1, + "read": 1, + "report": 1, + "role": "System Manager", + "share": 1, + "write": 1 + } + ], + "sort_field": "modified", + "sort_order": "DESC", + "track_changes": 1 +} \ No newline at end of file diff --git a/erpnext/stock/doctype/putaway_rule/putaway_rule.py b/erpnext/stock/doctype/putaway_rule/putaway_rule.py new file mode 100644 index 00000000000..9f028334311 --- /dev/null +++ b/erpnext/stock/doctype/putaway_rule/putaway_rule.py @@ -0,0 +1,93 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors +# For license information, please see license.txt + +from __future__ import unicode_literals +import frappe +import copy +from frappe import _ +from frappe.utils import flt +from frappe.model.document import Document + +class PutawayRule(Document): + def validate(self): + self.validate_duplicate_rule() + self.validate_warehouse_and_company() + self.validate_capacity() + self.validate_priority() + + def validate_duplicate_rule(self): + existing_rule = frappe.db.exists("Putaway Rule", {"item_code": self.item_code, "warehouse": self.warehouse}) + if existing_rule and existing_rule != self.name: + frappe.throw(_("Putaway Rule already exists for Item {0} in Warehouse {1}.") + .format(frappe.bold(self.item_code), frappe.bold(self.warehouse)), + title=_("Duplicate")) + + def validate_priority(self): + if self.priority < 1: + frappe.throw(_("Priority cannot be lesser than 1."), title=_("Invalid Priority")) + + def validate_warehouse_and_company(self): + company = frappe.db.get_value("Warehouse", self.warehouse, "company") + if company != self.company: + frappe.throw(_("Warehouse {0} does not belong to Company {1}.") + .format(frappe.bold(self.warehouse), frappe.bold(self.company)), + title=_("Invalid Warehouse")) + + def validate_capacity(self): + # check if capacity is lesser than current balance in warehouse + pass + +@frappe.whitelist() +def get_ordered_putaway_rules(item_code, company, qty): + """Returns an ordered list of putaway rules to apply on an item.""" + + # get enabled putaway rules for this item code in this company that have pending capacity + # order the rules by priority first + # if same priority, order by pending capacity (capacity - get how much stock is in the warehouse) + # return this list + # [{'name': "something", "free space": 20}, {'name': "something", "free space": 10}] + +@frappe.whitelist() +def apply_putaway_rule(items, company): + """ Applies Putaway Rule on line items. + + items: List of line items in a Purchase Receipt + company: Company in Purchase Receipt + """ + items_not_accomodated = [] + for item in items: + item_qty = item.qty + at_capacity, rules = get_ordered_putaway_rules(item.item_code, company, item_qty) + + if not rules: + if at_capacity: + items_not_accomodated.append([item.item_code, item_qty]) + continue + + item_row_updated = False + for rule in rules: + while item_qty > 0: + if not item_row_updated: + # update pre-existing row + item.qty = rule.qty + item.warehouse = rule.warehouse + item_row_updated = True + else: + # add rows for split quantity + added_row = copy.deepcopy(item) + added_row.qty = rule.qty + added_row.warehouse = rule.warehouse + items.append(added_row) + + item_qty -= flt(rule.qty) + + # if pending qty after applying rules, add row without warehouse + if item_qty > 0: + added_row = copy.deepcopy(item) + added_row.qty = item_qty + added_row.warehouse = '' + items.append(added_row) + items_not_accomodated.append([item.item_code, item_qty]) + + # need to check pricing rule, item tax impact \ No newline at end of file diff --git a/erpnext/stock/doctype/putaway_rule/putaway_rule_list.js b/erpnext/stock/doctype/putaway_rule/putaway_rule_list.js new file mode 100644 index 00000000000..bb1654cf241 --- /dev/null +++ b/erpnext/stock/doctype/putaway_rule/putaway_rule_list.js @@ -0,0 +1,10 @@ +frappe.listview_settings['Putaway Rule'] = { + add_fields: ["disable"], + get_indicator: (doc) => { + if (doc.disable) { + return [__("Disabled"), "darkgrey", "disable,=,1"]; + } else { + return [__("Active"), "blue", "disable,=,0"]; + }; + } +}; diff --git a/erpnext/stock/doctype/putaway_rule/test_putaway_rule.py b/erpnext/stock/doctype/putaway_rule/test_putaway_rule.py new file mode 100644 index 00000000000..e262217f848 --- /dev/null +++ b/erpnext/stock/doctype/putaway_rule/test_putaway_rule.py @@ -0,0 +1,10 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and Contributors +# See license.txt +from __future__ import unicode_literals + +# import frappe +import unittest + +class TestPutawayRule(unittest.TestCase): + pass From 8b6370bb45232d0e39508a1329258388c4d47439 Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Sun, 15 Nov 2020 22:41:36 +0530 Subject: [PATCH 051/477] feat: Add accounting dimension filter doctype --- .../accounting_dimension_filter/__init__.py | 0 .../accounting_dimension_filter.js | 32 ++++++ .../accounting_dimension_filter.json | 100 ++++++++++++++++++ .../accounting_dimension_filter.py | 63 +++++++++++ .../test_accounting_dimension_filter.py | 10 ++ .../doctype/allowed_dimension/__init__.py | 0 .../allowed_dimension/allowed_dimension.json | 43 ++++++++ .../allowed_dimension/allowed_dimension.py | 10 ++ .../doctype/applicable_on_account/__init__.py | 0 .../applicable_on_account.json | 35 ++++++ .../applicable_on_account.py | 10 ++ 11 files changed, 303 insertions(+) create mode 100644 erpnext/accounts/doctype/accounting_dimension_filter/__init__.py create mode 100644 erpnext/accounts/doctype/accounting_dimension_filter/accounting_dimension_filter.js create mode 100644 erpnext/accounts/doctype/accounting_dimension_filter/accounting_dimension_filter.json create mode 100644 erpnext/accounts/doctype/accounting_dimension_filter/accounting_dimension_filter.py create mode 100644 erpnext/accounts/doctype/accounting_dimension_filter/test_accounting_dimension_filter.py create mode 100644 erpnext/accounts/doctype/allowed_dimension/__init__.py create mode 100644 erpnext/accounts/doctype/allowed_dimension/allowed_dimension.json create mode 100644 erpnext/accounts/doctype/allowed_dimension/allowed_dimension.py create mode 100644 erpnext/accounts/doctype/applicable_on_account/__init__.py create mode 100644 erpnext/accounts/doctype/applicable_on_account/applicable_on_account.json create mode 100644 erpnext/accounts/doctype/applicable_on_account/applicable_on_account.py diff --git a/erpnext/accounts/doctype/accounting_dimension_filter/__init__.py b/erpnext/accounts/doctype/accounting_dimension_filter/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/erpnext/accounts/doctype/accounting_dimension_filter/accounting_dimension_filter.js b/erpnext/accounts/doctype/accounting_dimension_filter/accounting_dimension_filter.js new file mode 100644 index 00000000000..6c254fcfb73 --- /dev/null +++ b/erpnext/accounts/doctype/accounting_dimension_filter/accounting_dimension_filter.js @@ -0,0 +1,32 @@ +// Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors +// For license information, please see license.txt + +frappe.ui.form.on('Accounting Dimension Filter', { + onload: function(frm) { + frappe.db.get_list('Accounting Dimension', + {fields: ['name']}).then((res) => { + let options = ['Cost Center', 'Project']; + + res.forEach((dimension) => { + options.push(dimension.name); + }); + + frm.set_df_property('accounting_dimension', 'options', options); + }); + }, + + accounting_dimension: function(frm) { + frm.clear_table("dimensions"); + let row = frm.add_child("dimensions"); + row.accounting_dimension = frm.doc.accounting_dimension; + frm.refresh_field("dimensions"); + }, +}); + +frappe.ui.form.on('Allowed Dimension', { + dimensions_add: function(frm, cdt, cdn) { + let row = locals[cdt][cdn]; + row.accounting_dimension = frm.doc.accounting_dimension; + frm.refresh_field("dimensions"); + } +}); \ No newline at end of file diff --git a/erpnext/accounts/doctype/accounting_dimension_filter/accounting_dimension_filter.json b/erpnext/accounts/doctype/accounting_dimension_filter/accounting_dimension_filter.json new file mode 100644 index 00000000000..e626a09ce0c --- /dev/null +++ b/erpnext/accounts/doctype/accounting_dimension_filter/accounting_dimension_filter.json @@ -0,0 +1,100 @@ +{ + "actions": [], + "autoname": "format:{accounting_dimension}-{#####}", + "creation": "2020-11-08 18:28:11.906146", + "doctype": "DocType", + "editable_grid": 1, + "engine": "InnoDB", + "field_order": [ + "accounting_dimension", + "column_break_2", + "allow_or_restrict", + "section_break_4", + "accounts", + "column_break_6", + "dimensions" + ], + "fields": [ + { + "fieldname": "accounting_dimension", + "fieldtype": "Select", + "in_list_view": 1, + "label": "Accounting Dimension", + "reqd": 1, + "show_days": 1, + "show_seconds": 1 + }, + { + "fieldname": "column_break_2", + "fieldtype": "Column Break", + "show_days": 1, + "show_seconds": 1 + }, + { + "fieldname": "section_break_4", + "fieldtype": "Section Break", + "hide_border": 1, + "show_days": 1, + "show_seconds": 1 + }, + { + "fieldname": "column_break_6", + "fieldtype": "Column Break", + "show_days": 1, + "show_seconds": 1 + }, + { + "fieldname": "allow_or_restrict", + "fieldtype": "Select", + "label": "Allow Or Restrict Dimension", + "options": "Allow\nRestrict", + "reqd": 1, + "show_days": 1, + "show_seconds": 1 + }, + { + "fieldname": "accounts", + "fieldtype": "Table", + "label": "Accounts", + "options": "Applicable On Account", + "reqd": 1, + "show_days": 1, + "show_seconds": 1 + }, + { + "depends_on": "eval:doc.accounting_dimension", + "fieldname": "dimensions", + "fieldtype": "Table", + "label": "Dimensions", + "options": "Allowed Dimension", + "reqd": 1, + "show_days": 1, + "show_seconds": 1 + } + ], + "index_web_pages_for_search": 1, + "links": [], + "modified": "2020-11-14 18:02:02.616932", + "modified_by": "Administrator", + "module": "Accounts", + "name": "Accounting Dimension Filter", + "owner": "Administrator", + "permissions": [ + { + "create": 1, + "delete": 1, + "email": 1, + "export": 1, + "print": 1, + "read": 1, + "report": 1, + "role": "System Manager", + "share": 1, + "write": 1 + } + ], + "quick_entry": 1, + "sort_field": "modified", + "sort_order": "DESC", + "track_changes": 1 +} \ No newline at end of file diff --git a/erpnext/accounts/doctype/accounting_dimension_filter/accounting_dimension_filter.py b/erpnext/accounts/doctype/accounting_dimension_filter/accounting_dimension_filter.py new file mode 100644 index 00000000000..ccfafd96ed3 --- /dev/null +++ b/erpnext/accounts/doctype/accounting_dimension_filter/accounting_dimension_filter.py @@ -0,0 +1,63 @@ +# -*- coding: utf-8 -*- +# Copyright, (c) 2020, Frappe Technologies Pvt. Ltd. and contributors +# For license information, please see license.txt + +from __future__ import unicode_literals +import frappe +from frappe import _, scrub +from frappe.model.document import Document + +class AccountingDimensionFilter(Document): + def validate(self): + self.validate_applicable_accounts() + + def validate_applicable_accounts(self): + accounts = frappe.db.sql( + """ + SELECT a.applicable_on_account as account + FROM `tabApplicable On Account` a, `tabAccounting Dimension Filter` d + WHERE d.name = a.parent + and d.name != %s + and d.accounting_dimension = %s + """, (self.name, self.accounting_dimension), as_dict=1) + + account_list = [d.account for d in accounts] + + for account in self.get('accounts'): + if account.applicable_on_account in account_list: + frappe.throw(_("Row {0}: {1} account already applied for Accounting Dimension {2}").format( + account.idx, frappe.bold(account.applicable_on_account), frappe.bold(self.accounting_dimension))) + +def get_dimension_filter_map(): + filters = frappe.db.sql( + """ SELECT + a.applicable_on_account, d.dimension_value, p.accounting_dimension, + p.allow_or_restrict, ad.fieldname + FROM + `tabApplicable On Account` a, `tabAllowed Dimension` d, + `tabAccounting Dimension Filter` p, `tabAccounting Dimension` ad + WHERE + p.name = a.parent + AND p.name = d.parent + AND (p.accounting_dimension = ad.name + OR p.accounting_dimension in ('Cost Center', 'Project')) + """, as_dict=1) + + dimension_filter_map = {} + account_filter_map = {} + + for f in filters: + if f.accounting_dimension in ('Cost Center', 'Project'): + f.fieldname = scrub(f.accounting_dimension) + + build_map(dimension_filter_map, f.fieldname, f.applicable_on_account, f.dimension_value, + f.allow_or_restrict) + + return dimension_filter_map + +def build_map(map_object, dimension, account, filter_value, allow_or_restrict): + map_object.setdefault((dimension, account), { + 'allowed_dimensions': [], + 'allow_or_restrict': allow_or_restrict + }) + map_object[(dimension, account)]['allowed_dimensions'].append(filter_value) diff --git a/erpnext/accounts/doctype/accounting_dimension_filter/test_accounting_dimension_filter.py b/erpnext/accounts/doctype/accounting_dimension_filter/test_accounting_dimension_filter.py new file mode 100644 index 00000000000..c271a25fbd8 --- /dev/null +++ b/erpnext/accounts/doctype/accounting_dimension_filter/test_accounting_dimension_filter.py @@ -0,0 +1,10 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and Contributors +# See license.txt +from __future__ import unicode_literals + +# import frappe +import unittest + +class TestAccountingDimensionFilter(unittest.TestCase): + pass diff --git a/erpnext/accounts/doctype/allowed_dimension/__init__.py b/erpnext/accounts/doctype/allowed_dimension/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/erpnext/accounts/doctype/allowed_dimension/allowed_dimension.json b/erpnext/accounts/doctype/allowed_dimension/allowed_dimension.json new file mode 100644 index 00000000000..20024b03226 --- /dev/null +++ b/erpnext/accounts/doctype/allowed_dimension/allowed_dimension.json @@ -0,0 +1,43 @@ +{ + "actions": [], + "creation": "2020-11-08 18:22:36.001131", + "doctype": "DocType", + "editable_grid": 1, + "engine": "InnoDB", + "field_order": [ + "accounting_dimension", + "dimension_value" + ], + "fields": [ + { + "fieldname": "accounting_dimension", + "fieldtype": "Link", + "label": "Accounting Dimension", + "options": "DocType", + "read_only": 1, + "show_days": 1, + "show_seconds": 1 + }, + { + "fieldname": "dimension_value", + "fieldtype": "Dynamic Link", + "in_list_view": 1, + "options": "accounting_dimension", + "show_days": 1, + "show_seconds": 1 + } + ], + "index_web_pages_for_search": 1, + "istable": 1, + "links": [], + "modified": "2020-11-14 19:54:03.269016", + "modified_by": "Administrator", + "module": "Accounts", + "name": "Allowed Dimension", + "owner": "Administrator", + "permissions": [], + "quick_entry": 1, + "sort_field": "modified", + "sort_order": "DESC", + "track_changes": 1 +} \ No newline at end of file diff --git a/erpnext/accounts/doctype/allowed_dimension/allowed_dimension.py b/erpnext/accounts/doctype/allowed_dimension/allowed_dimension.py new file mode 100644 index 00000000000..c2afc1a2621 --- /dev/null +++ b/erpnext/accounts/doctype/allowed_dimension/allowed_dimension.py @@ -0,0 +1,10 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors +# For license information, please see license.txt + +from __future__ import unicode_literals +# import frappe +from frappe.model.document import Document + +class AllowedDimension(Document): + pass diff --git a/erpnext/accounts/doctype/applicable_on_account/__init__.py b/erpnext/accounts/doctype/applicable_on_account/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/erpnext/accounts/doctype/applicable_on_account/applicable_on_account.json b/erpnext/accounts/doctype/applicable_on_account/applicable_on_account.json new file mode 100644 index 00000000000..8305da2ba08 --- /dev/null +++ b/erpnext/accounts/doctype/applicable_on_account/applicable_on_account.json @@ -0,0 +1,35 @@ +{ + "actions": [], + "creation": "2020-11-08 18:20:00.944449", + "doctype": "DocType", + "editable_grid": 1, + "engine": "InnoDB", + "field_order": [ + "applicable_on_account" + ], + "fields": [ + { + "fieldname": "applicable_on_account", + "fieldtype": "Link", + "in_list_view": 1, + "label": "Applicable On Account", + "options": "Account", + "reqd": 1, + "show_days": 1, + "show_seconds": 1 + } + ], + "index_web_pages_for_search": 1, + "istable": 1, + "links": [], + "modified": "2020-11-14 16:54:06.756883", + "modified_by": "Administrator", + "module": "Accounts", + "name": "Applicable On Account", + "owner": "Administrator", + "permissions": [], + "quick_entry": 1, + "sort_field": "modified", + "sort_order": "DESC", + "track_changes": 1 +} \ No newline at end of file diff --git a/erpnext/accounts/doctype/applicable_on_account/applicable_on_account.py b/erpnext/accounts/doctype/applicable_on_account/applicable_on_account.py new file mode 100644 index 00000000000..0fccaf302fb --- /dev/null +++ b/erpnext/accounts/doctype/applicable_on_account/applicable_on_account.py @@ -0,0 +1,10 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors +# For license information, please see license.txt + +from __future__ import unicode_literals +# import frappe +from frappe.model.document import Document + +class ApplicableOnAccount(Document): + pass From 96e874bfda3e93a48613765c7433824587fb0360 Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Sun, 15 Nov 2020 22:43:01 +0530 Subject: [PATCH 052/477] fix: dimension filter query --- .../accounting_dimension.py | 14 +++- erpnext/controllers/queries.py | 47 ++++++++++++++ .../public/js/utils/dimension_tree_filter.js | 65 ++++++++++++++----- 3 files changed, 109 insertions(+), 17 deletions(-) diff --git a/erpnext/accounts/doctype/accounting_dimension/accounting_dimension.py b/erpnext/accounts/doctype/accounting_dimension/accounting_dimension.py index f888d9e038a..b9d4da289ee 100644 --- a/erpnext/accounts/doctype/accounting_dimension/accounting_dimension.py +++ b/erpnext/accounts/doctype/accounting_dimension/accounting_dimension.py @@ -203,7 +203,7 @@ def get_dimension_with_children(doctype, dimension): return all_dimensions @frappe.whitelist() -def get_dimension_filters(): +def get_dimension_filters(with_costcenter_and_project=False): dimension_filters = frappe.db.sql(""" SELECT label, fieldname, document_type FROM `tabAccounting Dimension` @@ -214,6 +214,18 @@ def get_dimension_filters(): FROM `tabAccounting Dimension Detail` c, `tabAccounting Dimension` p WHERE c.parent = p.name""", as_dict=1) + if with_costcenter_and_project: + dimension_filters.extend([ + { + 'fieldname': 'cost_center', + 'document_type': 'Cost Center' + }, + { + 'fieldname': 'project', + 'document_type': 'Project' + } + ]) + default_dimensions_map = {} for dimension in default_dimensions: default_dimensions_map.setdefault(dimension.company, {}) diff --git a/erpnext/controllers/queries.py b/erpnext/controllers/queries.py index 8fe3816c24a..015807d5639 100644 --- a/erpnext/controllers/queries.py +++ b/erpnext/controllers/queries.py @@ -493,6 +493,53 @@ def get_income_account(doctype, txt, searchfield, start, page_len, filters): 'company': filters.get("company", "") }) +@frappe.whitelist() +@frappe.validate_and_sanitize_search_inputs +def get_filtered_dimensions(doctype, txt, searchfield, start, page_len, filters): + from erpnext.accounts.doctype.accounting_dimension_filter.accounting_dimension_filter import get_dimension_filter_map + dimension_filters = get_dimension_filter_map() + dimension_filters = dimension_filters.get((filters.get('dimension'),filters.get('account'))) + group_condition = '' + company_condition = '' + + meta = frappe.get_meta(doctype) + + if meta.is_tree: + group_condition = 'and is_group = 0 ' + + if meta.has_field('company'): + company_condition = 'and company = %s ' % (frappe.db.escape(filters.get('company'))) + + if dimension_filters: + if dimension_filters['allow_or_restrict'] == 'Allow': + query_selector = 'in' + else: + query_selector = 'not in' + + if len(dimension_filters['allowed_dimensions']) == 1: + dimensions = tuple(dimension_filters['allowed_dimensions'] * 2) + else: + dimensions = tuple(dimension_filters['allowed_dimensions']) + + result = frappe.db.sql("""SELECT name from `tab{doctype}` where + name {query_selector} {restricted} + {group_condition} {company_condition} + and {key} LIKE %(txt)s""".format( + doctype=doctype, query_selector=query_selector, restricted=dimensions, + group_condition = group_condition, + company_condition = company_condition, + key=searchfield), { + 'txt': '%' + txt + '%' + }) + + return result + else: + return frappe.db.sql(""" + SELECT name from `tab{doctype}` where + {key} LIKE %(txt)s {group_condition} {company_condition}""" + .format(doctype=doctype, key=searchfield, + group_condition=group_condition, company_condition=company_condition), + { 'txt': '%' + txt + '%'}) @frappe.whitelist() @frappe.validate_and_sanitize_search_inputs diff --git a/erpnext/public/js/utils/dimension_tree_filter.js b/erpnext/public/js/utils/dimension_tree_filter.js index b6720c05cb2..34b563553e1 100644 --- a/erpnext/public/js/utils/dimension_tree_filter.js +++ b/erpnext/public/js/utils/dimension_tree_filter.js @@ -5,14 +5,18 @@ let default_dimensions = {}; let doctypes_with_dimensions = ["GL Entry", "Sales Invoice", "Purchase Invoice", "Payment Entry", "Asset", "Expense Claim", "Stock Entry", "Budget", "Payroll Entry", "Delivery Note", "Shipping Rule", "Loyalty Program", "Fee Schedule", "Fee Structure", "Stock Reconciliation", "Travel Request", "Fees", "POS Profile", "Opening Invoice Creation Tool", - "Subscription", "Purchase Order", "Journal Entry", "Material Request", "Purchase Receipt", "Landed Cost Item", "Asset"]; + "Subscription", "Purchase Order", "Journal Entry", "Material Request", "Purchase Receipt", "Asset", "Asset Value Adjustment"]; let child_docs = ["Sales Invoice Item", "Purchase Invoice Item", "Purchase Order Item", "Journal Entry Account", "Material Request Item", "Delivery Note Item", "Purchase Receipt Item", "Stock Entry Detail", "Payment Entry Deduction", - "Landed Cost Item", "Asset Value Adjustment", "Opening Invoice Creation Tool Item", "Subscription Plan"]; + "Landed Cost Item", "Asset Value Adjustment", "Opening Invoice Creation Tool Item", "Subscription Plan", + "Sales Taxes and Charges", "Purchase Taxes and Charges"]; frappe.call({ method: "erpnext.accounts.doctype.accounting_dimension.accounting_dimension.get_dimension_filters", + args: { + 'with_costcenter_and_project': true + }, callback: function(r) { erpnext.dimension_filters = r.message[0]; default_dimensions = r.message[1]; @@ -24,11 +28,16 @@ doctypes_with_dimensions.forEach((doctype) => { onload: function(frm) { erpnext.dimension_filters.forEach((dimension) => { frappe.model.with_doctype(dimension['document_type'], () => { - if(frappe.meta.has_field(dimension['document_type'], 'is_group')) { - frm.set_query(dimension['fieldname'], { - "is_group": 0 - }); - } + let parent_fields = []; + frappe.meta.get_docfields(doctype).forEach((df) => { + if (df.fieldtype === 'Link' && df.options === 'Account') { + parent_fields.push(df.fieldname); + } else if (df.fieldtype === 'Table') { + setup_child_filters(frm, df.options, df.fieldname, dimension['fieldname']); + }; + + setup_account_filters(frm, dimension['fieldname'], parent_fields); + }); }); }); }, @@ -67,17 +76,41 @@ doctypes_with_dimensions.forEach((doctype) => { child_docs.forEach((doctype) => { frappe.ui.form.on(doctype, { items_add: function(frm, cdt, cdn) { - erpnext.dimension_filters.forEach((dimension) => { - var row = frappe.get_doc(cdt, cdn); - frm.script_manager.copy_from_first_row("items", row, [dimension['fieldname']]); - }); + copy_dimension(frm, cdt, cdn, "items"); }, accounts_add: function(frm, cdt, cdn) { - erpnext.dimension_filters.forEach((dimension) => { - var row = frappe.get_doc(cdt, cdn); - frm.script_manager.copy_from_first_row("accounts", row, [dimension['fieldname']]); - }); + copy_dimension(frm, cdt, cdn, "accounts"); } }); -}); \ No newline at end of file +}); + +let copy_dimension = function(frm, cdt, cdn, fieldname) { + erpnext.dimension_filters.forEach((dimension) => { + let row = frappe.get_doc(cdt, cdn); + frm.script_manager.copy_from_first_row(fieldname, row, [dimension['fieldname']]); + }); +} + +let setup_child_filters = function(frm, doctype, parentfield, dimension) { + let fields = []; + + frappe.model.with_doctype(doctype, () => { + frappe.meta.get_docfields(doctype).forEach((df) => { + if (df.fieldtype === 'Link' && df.options === 'Account') { + fields.push(df.fieldname); + } + }); + + frm.set_query(dimension, parentfield, function(doc, cdt, cdn) { + let row = locals[cdt][cdn]; + return erpnext.queries.get_filtered_dimensions(row, fields, dimension, doc.company); + }); + }); +} + +let setup_account_filters = function(frm, dimension, fields) { + frm.set_query(dimension, function(doc) { + return erpnext.queries.get_filtered_dimensions(doc, fields, dimension, doc.company); + }); +} \ No newline at end of file From 6e5748e2a3344eeead1a7b1f86258de233276d02 Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Sun, 15 Nov 2020 22:43:48 +0530 Subject: [PATCH 053/477] fix: dimension filter query --- erpnext/public/js/queries.js | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/erpnext/public/js/queries.js b/erpnext/public/js/queries.js index 560a5617da5..7b7a9df1ac0 100644 --- a/erpnext/public/js/queries.js +++ b/erpnext/public/js/queries.js @@ -116,6 +116,25 @@ $.extend(erpnext.queries, { ] } + }, + + get_filtered_dimensions: function(doc, child_fields, dimension, company) { + let account = ''; + + child_fields.forEach((field) => { + if (!account) { + account = doc[field]; + } + }); + + return { + query: "erpnext.controllers.queries.get_filtered_dimensions", + filters: { + 'dimension': dimension, + 'account': account, + 'company': company + } + } } }); From f916bc048ff08a4bbae87e37bd8215c35ac32f8a Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Sun, 15 Nov 2020 22:44:39 +0530 Subject: [PATCH 054/477] fix: Remove cost center query from doctypes --- erpnext/accounts/doctype/budget/budget.js | 12 ++---------- .../accounts/doctype/journal_entry/journal_entry.js | 9 --------- .../doctype/loyalty_program/loyalty_program.js | 8 -------- .../accounts/doctype/payment_entry/payment_entry.js | 9 --------- .../doctype/purchase_invoice/purchase_invoice.js | 9 --------- .../accounts/doctype/sales_invoice/sales_invoice.js | 9 --------- .../accounts/doctype/shipping_rule/shipping_rule.js | 8 -------- erpnext/assets/doctype/asset/asset.js | 8 -------- erpnext/hr/doctype/expense_claim/expense_claim.js | 9 --------- .../payroll/doctype/payroll_entry/payroll_entry.js | 9 +-------- erpnext/public/js/controllers/accounts.js | 9 --------- erpnext/public/js/controllers/transaction.js | 10 ---------- 12 files changed, 3 insertions(+), 106 deletions(-) diff --git a/erpnext/accounts/doctype/budget/budget.js b/erpnext/accounts/doctype/budget/budget.js index cadf1e7e0ca..48cc493522a 100644 --- a/erpnext/accounts/doctype/budget/budget.js +++ b/erpnext/accounts/doctype/budget/budget.js @@ -3,14 +3,6 @@ frappe.ui.form.on('Budget', { onload: function(frm) { - frm.set_query("cost_center", function() { - return { - filters: { - company: frm.doc.company - } - } - }) - frm.set_query("project", function() { return { filters: { @@ -18,7 +10,7 @@ frappe.ui.form.on('Budget', { } } }) - + frm.set_query("account", "accounts", function() { return { filters: { @@ -28,7 +20,7 @@ frappe.ui.form.on('Budget', { } } }) - + frm.set_query("monthly_distribution", function() { return { filters: { diff --git a/erpnext/accounts/doctype/journal_entry/journal_entry.js b/erpnext/accounts/doctype/journal_entry/journal_entry.js index ff12967155f..d60a7b76cc4 100644 --- a/erpnext/accounts/doctype/journal_entry/journal_entry.js +++ b/erpnext/accounts/doctype/journal_entry/journal_entry.js @@ -222,15 +222,6 @@ erpnext.accounts.JournalEntry = frappe.ui.form.Controller.extend({ return erpnext.journal_entry.account_query(me.frm); }); - me.frm.set_query("cost_center", "accounts", function(doc, cdt, cdn) { - return { - filters: { - company: me.frm.doc.company, - is_group: 0 - } - }; - }); - me.frm.set_query("party_type", "accounts", function(doc, cdt, cdn) { const row = locals[cdt][cdn]; diff --git a/erpnext/accounts/doctype/loyalty_program/loyalty_program.js b/erpnext/accounts/doctype/loyalty_program/loyalty_program.js index 524a671801b..0d2b8cbf151 100644 --- a/erpnext/accounts/doctype/loyalty_program/loyalty_program.js +++ b/erpnext/accounts/doctype/loyalty_program/loyalty_program.js @@ -46,14 +46,6 @@ frappe.ui.form.on('Loyalty Program', { }; }); - frm.set_query("cost_center", function() { - return { - filters: { - company: frm.doc.company - } - }; - }); - frm.set_value("company", frappe.defaults.get_user_default("Company")); }, diff --git a/erpnext/accounts/doctype/payment_entry/payment_entry.js b/erpnext/accounts/doctype/payment_entry/payment_entry.js index e1174717382..ea5487d5754 100644 --- a/erpnext/accounts/doctype/payment_entry/payment_entry.js +++ b/erpnext/accounts/doctype/payment_entry/payment_entry.js @@ -88,15 +88,6 @@ frappe.ui.form.on('Payment Entry', { } }); - frm.set_query("cost_center", "deductions", function() { - return { - filters: { - "is_group": 0, - "company": frm.doc.company - } - } - }); - frm.set_query("reference_doctype", "references", function() { if (frm.doc.party_type=="Customer") { var doctypes = ["Sales Order", "Sales Invoice", "Journal Entry", "Dunning"]; diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js index 1d41d0fa2a9..3c07ee75cbb 100644 --- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js +++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js @@ -501,15 +501,6 @@ frappe.ui.form.on("Purchase Invoice", { } } } - - frm.set_query("cost_center", function() { - return { - filters: { - company: frm.doc.company, - is_group: 0 - } - }; - }); }, onload: function(frm) { diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.js b/erpnext/accounts/doctype/sales_invoice/sales_invoice.js index 502e65ed8d0..e27bd2fa3ac 100644 --- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.js +++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.js @@ -571,15 +571,6 @@ frappe.ui.form.on('Sales Invoice', { }; }); - frm.set_query("cost_center", function() { - return { - filters: { - company: frm.doc.company, - is_group: 0 - } - }; - }); - frm.custom_make_buttons = { 'Delivery Note': 'Delivery', 'Sales Invoice': 'Sales Return', diff --git a/erpnext/accounts/doctype/shipping_rule/shipping_rule.js b/erpnext/accounts/doctype/shipping_rule/shipping_rule.js index d0904eec3e3..7cfbfed1388 100644 --- a/erpnext/accounts/doctype/shipping_rule/shipping_rule.js +++ b/erpnext/accounts/doctype/shipping_rule/shipping_rule.js @@ -3,14 +3,6 @@ frappe.ui.form.on('Shipping Rule', { refresh: function(frm) { - frm.set_query("cost_center", function() { - return { - filters: { - company: frm.doc.company - } - } - }) - frm.set_query("account", function() { return { filters: { diff --git a/erpnext/assets/doctype/asset/asset.js b/erpnext/assets/doctype/asset/asset.js index 7ad164a8b9b..3af3948fac6 100644 --- a/erpnext/assets/doctype/asset/asset.js +++ b/erpnext/assets/doctype/asset/asset.js @@ -31,14 +31,6 @@ frappe.ui.form.on('Asset', { } }; }); - - frm.set_query("cost_center", function() { - return { - "filters": { - "company": frm.doc.company, - } - }; - }); }, setup: function(frm) { diff --git a/erpnext/hr/doctype/expense_claim/expense_claim.js b/erpnext/hr/doctype/expense_claim/expense_claim.js index 221300b519a..cbafd7d3ac0 100644 --- a/erpnext/hr/doctype/expense_claim/expense_claim.js +++ b/erpnext/hr/doctype/expense_claim/expense_claim.js @@ -167,15 +167,6 @@ frappe.ui.form.on("Expense Claim", { }; }); - frm.set_query("cost_center", "expenses", function() { - return { - filters: { - "company": frm.doc.company, - "is_group": 0 - } - }; - }); - frm.set_query("payable_account", function() { return { filters: { diff --git a/erpnext/payroll/doctype/payroll_entry/payroll_entry.js b/erpnext/payroll/doctype/payroll_entry/payroll_entry.js index 1abc869c539..96006158b68 100644 --- a/erpnext/payroll/doctype/payroll_entry/payroll_entry.js +++ b/erpnext/payroll/doctype/payroll_entry/payroll_entry.js @@ -113,14 +113,7 @@ frappe.ui.form.on('Payroll Entry', { } }; }), - frm.set_query("cost_center", function () { - return { - filters: { - "is_group": 0, - company: frm.doc.company - } - }; - }), + frm.set_query("project", function () { return { filters: { diff --git a/erpnext/public/js/controllers/accounts.js b/erpnext/public/js/controllers/accounts.js index 6e97d811fc1..45c494e3e56 100644 --- a/erpnext/public/js/controllers/accounts.js +++ b/erpnext/public/js/controllers/accounts.js @@ -31,15 +31,6 @@ frappe.ui.form.on(cur_frm.doctype, { } } }); - - frm.set_query("cost_center", "taxes", function(doc) { - return { - filters: { - 'company': doc.company, - "is_group": 0 - } - } - }); } }, validate: function(frm) { diff --git a/erpnext/public/js/controllers/transaction.js b/erpnext/public/js/controllers/transaction.js index 1358a4bd088..ec6b3dc6df1 100644 --- a/erpnext/public/js/controllers/transaction.js +++ b/erpnext/public/js/controllers/transaction.js @@ -159,16 +159,6 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({ }; }); } - if (this.frm.fields_dict["items"].grid.get_field("cost_center")) { - this.frm.set_query("cost_center", "items", function(doc) { - return { - filters: { - "company": doc.company, - "is_group": 0 - } - }; - }); - } if (this.frm.fields_dict["items"].grid.get_field("expense_account")) { this.frm.set_query("expense_account", "items", function(doc) { From 1f9b03345dd6360e5b8fc2df98948cebe1e53a1e Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Mon, 16 Nov 2020 09:55:35 +0530 Subject: [PATCH 055/477] fix: Remove project filter --- erpnext/accounts/doctype/budget/budget.js | 8 -------- erpnext/payroll/doctype/payroll_entry/payroll_entry.js | 10 +--------- 2 files changed, 1 insertion(+), 17 deletions(-) diff --git a/erpnext/accounts/doctype/budget/budget.js b/erpnext/accounts/doctype/budget/budget.js index 48cc493522a..1b793982472 100644 --- a/erpnext/accounts/doctype/budget/budget.js +++ b/erpnext/accounts/doctype/budget/budget.js @@ -3,14 +3,6 @@ frappe.ui.form.on('Budget', { onload: function(frm) { - frm.set_query("project", function() { - return { - filters: { - company: frm.doc.company - } - } - }) - frm.set_query("account", "accounts", function() { return { filters: { diff --git a/erpnext/payroll/doctype/payroll_entry/payroll_entry.js b/erpnext/payroll/doctype/payroll_entry/payroll_entry.js index 96006158b68..bc34d6c3b15 100644 --- a/erpnext/payroll/doctype/payroll_entry/payroll_entry.js +++ b/erpnext/payroll/doctype/payroll_entry/payroll_entry.js @@ -112,15 +112,7 @@ frappe.ui.form.on('Payroll Entry', { "company": frm.doc.company } }; - }), - - frm.set_query("project", function () { - return { - filters: { - company: frm.doc.company - } - }; - }); + }) }, payroll_frequency: function (frm) { From 9e9ea965824c8562d915d3983641b0df1bafec15 Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Mon, 16 Nov 2020 12:03:47 +0530 Subject: [PATCH 056/477] fix: linting --- .../accounting_dimension_filter.js | 10 +++++----- .../accounting_dimension_filter.py | 1 - erpnext/payroll/doctype/payroll_entry/payroll_entry.js | 2 +- erpnext/public/js/queries.js | 2 +- erpnext/public/js/utils/dimension_tree_filter.js | 9 ++++----- 5 files changed, 11 insertions(+), 13 deletions(-) diff --git a/erpnext/accounts/doctype/accounting_dimension_filter/accounting_dimension_filter.js b/erpnext/accounts/doctype/accounting_dimension_filter/accounting_dimension_filter.js index 6c254fcfb73..3e880d3ca68 100644 --- a/erpnext/accounts/doctype/accounting_dimension_filter/accounting_dimension_filter.js +++ b/erpnext/accounts/doctype/accounting_dimension_filter/accounting_dimension_filter.js @@ -5,13 +5,13 @@ frappe.ui.form.on('Accounting Dimension Filter', { onload: function(frm) { frappe.db.get_list('Accounting Dimension', {fields: ['name']}).then((res) => { - let options = ['Cost Center', 'Project']; + let options = ['Cost Center', 'Project']; - res.forEach((dimension) => { - options.push(dimension.name); - }); + res.forEach((dimension) => { + options.push(dimension.name); + }); - frm.set_df_property('accounting_dimension', 'options', options); + frm.set_df_property('accounting_dimension', 'options', options); }); }, diff --git a/erpnext/accounts/doctype/accounting_dimension_filter/accounting_dimension_filter.py b/erpnext/accounts/doctype/accounting_dimension_filter/accounting_dimension_filter.py index ccfafd96ed3..0dcf1164238 100644 --- a/erpnext/accounts/doctype/accounting_dimension_filter/accounting_dimension_filter.py +++ b/erpnext/accounts/doctype/accounting_dimension_filter/accounting_dimension_filter.py @@ -44,7 +44,6 @@ def get_dimension_filter_map(): """, as_dict=1) dimension_filter_map = {} - account_filter_map = {} for f in filters: if f.accounting_dimension in ('Cost Center', 'Project'): diff --git a/erpnext/payroll/doctype/payroll_entry/payroll_entry.js b/erpnext/payroll/doctype/payroll_entry/payroll_entry.js index bc34d6c3b15..d32fdbcaf16 100644 --- a/erpnext/payroll/doctype/payroll_entry/payroll_entry.js +++ b/erpnext/payroll/doctype/payroll_entry/payroll_entry.js @@ -112,7 +112,7 @@ frappe.ui.form.on('Payroll Entry', { "company": frm.doc.company } }; - }) + }); }, payroll_frequency: function (frm) { diff --git a/erpnext/public/js/queries.js b/erpnext/public/js/queries.js index 7b7a9df1ac0..98f1b504ccc 100644 --- a/erpnext/public/js/queries.js +++ b/erpnext/public/js/queries.js @@ -134,7 +134,7 @@ $.extend(erpnext.queries, { 'account': account, 'company': company } - } + }; } }); diff --git a/erpnext/public/js/utils/dimension_tree_filter.js b/erpnext/public/js/utils/dimension_tree_filter.js index 34b563553e1..7a42fb56148 100644 --- a/erpnext/public/js/utils/dimension_tree_filter.js +++ b/erpnext/public/js/utils/dimension_tree_filter.js @@ -1,5 +1,4 @@ frappe.provide('frappe.ui.form'); - let default_dimensions = {}; let doctypes_with_dimensions = ["GL Entry", "Sales Invoice", "Purchase Invoice", "Payment Entry", "Asset", @@ -34,7 +33,7 @@ doctypes_with_dimensions.forEach((doctype) => { parent_fields.push(df.fieldname); } else if (df.fieldtype === 'Table') { setup_child_filters(frm, df.options, df.fieldname, dimension['fieldname']); - }; + } setup_account_filters(frm, dimension['fieldname'], parent_fields); }); @@ -90,7 +89,7 @@ let copy_dimension = function(frm, cdt, cdn, fieldname) { let row = frappe.get_doc(cdt, cdn); frm.script_manager.copy_from_first_row(fieldname, row, [dimension['fieldname']]); }); -} +}; let setup_child_filters = function(frm, doctype, parentfield, dimension) { let fields = []; @@ -107,10 +106,10 @@ let setup_child_filters = function(frm, doctype, parentfield, dimension) { return erpnext.queries.get_filtered_dimensions(row, fields, dimension, doc.company); }); }); -} +}; let setup_account_filters = function(frm, dimension, fields) { frm.set_query(dimension, function(doc) { return erpnext.queries.get_filtered_dimensions(doc, fields, dimension, doc.company); }); -} \ No newline at end of file +}; \ No newline at end of file From d51c953c22a2de6824fbe88e5d9989db19220d1b Mon Sep 17 00:00:00 2001 From: marination Date: Mon, 16 Nov 2020 12:48:40 +0530 Subject: [PATCH 057/477] chore: Fix Tests, use project name instead of project_name field --- .../accounts/doctype/budget/test_budget.py | 15 +++++++--- .../journal_entry/test_journal_entry.py | 23 +++++++++------ .../purchase_invoice/test_purchase_invoice.py | 29 +++++++++++-------- .../sales_invoice/test_sales_invoice.py | 14 ++++----- .../doctype/crop_cycle/test_crop_cycle.py | 2 +- .../test_employee_onboarding.py | 3 +- .../expense_claim/test_expense_claim.py | 17 ++++++----- .../projects/doctype/project/test_project.py | 4 +++ erpnext/projects/doctype/task/test_task.py | 8 +++-- .../doctype/timesheet/test_timesheet.py | 5 ++-- 10 files changed, 73 insertions(+), 47 deletions(-) diff --git a/erpnext/accounts/doctype/budget/test_budget.py b/erpnext/accounts/doctype/budget/test_budget.py index 0f115f9cc20..62d17c4e697 100644 --- a/erpnext/accounts/doctype/budget/test_budget.py +++ b/erpnext/accounts/doctype/budget/test_budget.py @@ -122,8 +122,10 @@ class TestBudget(unittest.TestCase): frappe.db.set_value("Budget", budget.name, "action_if_accumulated_monthly_budget_exceeded", "Stop") + project = frappe.get_value("Project", {"project_name": "_Test Project"}) + jv = make_journal_entry("_Test Account Cost for Goods Sold - _TC", - "_Test Bank - _TC", 40000, "_Test Cost Center - _TC", project="_Test Project", posting_date=nowdate()) + "_Test Bank - _TC", 40000, "_Test Cost Center - _TC", project=project, posting_date=nowdate()) self.assertRaises(BudgetError, jv.submit) @@ -147,8 +149,11 @@ class TestBudget(unittest.TestCase): budget = make_budget(budget_against="Project") + project = frappe.get_value("Project", {"project_name": "_Test Project"}) + jv = make_journal_entry("_Test Account Cost for Goods Sold - _TC", - "_Test Bank - _TC", 250000, "_Test Cost Center - _TC", project="_Test Project", posting_date=nowdate()) + "_Test Bank - _TC", 250000, "_Test Cost Center - _TC", + project=project, posting_date=nowdate()) self.assertRaises(BudgetError, jv.submit) @@ -184,9 +189,11 @@ class TestBudget(unittest.TestCase): if month > 10: month = 10 + project = frappe.get_value("Project", {"project_name": "_Test Project"}) for i in range(month): jv = make_journal_entry("_Test Account Cost for Goods Sold - _TC", - "_Test Bank - _TC", 20000, "_Test Cost Center - _TC", posting_date=nowdate(), submit=True, project="_Test Project") + "_Test Bank - _TC", 20000, "_Test Cost Center - _TC", posting_date=nowdate(), submit=True, + project=project) self.assertTrue(frappe.db.get_value("GL Entry", {"voucher_type": "Journal Entry", "voucher_no": jv.name})) @@ -289,7 +296,7 @@ def make_budget(**args): budget = frappe.new_doc("Budget") if budget_against == "Project": - budget.project = "_Test Project" + budget.project = frappe.get_value("Project", {"project_name": "_Test Project"}) else: budget.cost_center =cost_center or "_Test Cost Center - _TC" diff --git a/erpnext/accounts/doctype/journal_entry/test_journal_entry.py b/erpnext/accounts/doctype/journal_entry/test_journal_entry.py index 53c07583d8e..402ea5085e5 100644 --- a/erpnext/accounts/doctype/journal_entry/test_journal_entry.py +++ b/erpnext/accounts/doctype/journal_entry/test_journal_entry.py @@ -168,7 +168,7 @@ class TestJournalEntry(unittest.TestCase): self.assertFalse(gle) def test_reverse_journal_entry(self): - from erpnext.accounts.doctype.journal_entry.journal_entry import make_reverse_journal_entry + from erpnext.accounts.doctype.journal_entry.journal_entry import make_reverse_journal_entry jv = make_journal_entry("_Test Bank USD - _TC", "Sales - _TC", 100, exchange_rate=50, save=False) @@ -307,15 +307,20 @@ class TestJournalEntry(unittest.TestCase): def test_jv_with_project(self): from erpnext.projects.doctype.project.test_project import make_project - project = make_project({ - 'project_name': 'Journal Entry Project', - 'project_template_name': 'Test Project Template', - 'start_date': '2020-01-01' - }) + + if not frappe.db.exists("Project", {"project_name": "Journal Entry Project"}): + project = make_project({ + 'project_name': 'Journal Entry Project', + 'project_template_name': 'Test Project Template', + 'start_date': '2020-01-01' + }) + project_name = project.name + else: + project_name = frappe.get_value("Project", {"project_name": "_Test Project"}) jv = make_journal_entry("_Test Cash - _TC", "_Test Bank - _TC", 100, save=False) for d in jv.accounts: - d.project = project.project_name + d.project = project_name jv.voucher_type = "Bank Entry" jv.multi_currency = 0 jv.cheque_no = "112233" @@ -325,10 +330,10 @@ class TestJournalEntry(unittest.TestCase): expected_values = { "_Test Cash - _TC": { - "project": project.project_name + "project": project_name }, "_Test Bank - _TC": { - "project": project.project_name + "project": project_name } } diff --git a/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py b/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py index 2e5a7142a33..26acad3a4fb 100644 --- a/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py +++ b/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py @@ -436,26 +436,31 @@ class TestPurchaseInvoice(unittest.TestCase): ) def test_total_purchase_cost_for_project(self): - make_project({'project_name':'_Test Project'}) + if not frappe.db.exists("Project", {"project_name": "_Test Project for Purchase"}): + project = make_project({'project_name':'_Test Project for Purchase'}) + else: + project = frappe.get_doc("Project", {"project_name": "_Test Project for Purchase"}) existing_purchase_cost = frappe.db.sql("""select sum(base_net_amount) - from `tabPurchase Invoice Item` where project = '_Test Project' and docstatus=1""") + from `tabPurchase Invoice Item` + where project = '{0}' + and docstatus=1""".format(project.name)) existing_purchase_cost = existing_purchase_cost and existing_purchase_cost[0][0] or 0 - pi = make_purchase_invoice(currency="USD", conversion_rate=60, project="_Test Project") - self.assertEqual(frappe.db.get_value("Project", "_Test Project", "total_purchase_cost"), + pi = make_purchase_invoice(currency="USD", conversion_rate=60, project=project.name) + self.assertEqual(frappe.db.get_value("Project", project.name, "total_purchase_cost"), existing_purchase_cost + 15000) - pi1 = make_purchase_invoice(qty=10, project="_Test Project") - self.assertEqual(frappe.db.get_value("Project", "_Test Project", "total_purchase_cost"), + pi1 = make_purchase_invoice(qty=10, project=project.name) + self.assertEqual(frappe.db.get_value("Project", project.name, "total_purchase_cost"), existing_purchase_cost + 15500) pi1.cancel() - self.assertEqual(frappe.db.get_value("Project", "_Test Project", "total_purchase_cost"), + self.assertEqual(frappe.db.get_value("Project", project.name, "total_purchase_cost"), existing_purchase_cost + 15000) pi.cancel() - self.assertEqual(frappe.db.get_value("Project", "_Test Project", "total_purchase_cost"), existing_purchase_cost) + self.assertEqual(frappe.db.get_value("Project", project.name, "total_purchase_cost"), existing_purchase_cost) def test_return_purchase_invoice(self): set_perpetual_inventory() @@ -874,17 +879,17 @@ class TestPurchaseInvoice(unittest.TestCase): }) pi = make_purchase_invoice(credit_to="Creditors - _TC" ,do_not_save=1) - pi.items[0].project = item_project.project_name - pi.project = project.project_name + pi.items[0].project = item_project.name + pi.project = project.name pi.submit() expected_values = { "Creditors - _TC": { - "project": project.project_name + "project": project.name }, "_Test Account Cost for Goods Sold - _TC": { - "project": item_project.project_name + "project": item_project.name } } diff --git a/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py index 9660c9570e2..29b1ea2f9f0 100644 --- a/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py +++ b/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py @@ -1571,7 +1571,7 @@ class TestSalesInvoice(unittest.TestCase): for gle in gl_entries: self.assertEqual(expected_values[gle.account]["cost_center"], gle.cost_center) - + def test_sales_invoice_with_project_link(self): from erpnext.projects.doctype.project.test_project import make_project @@ -1587,17 +1587,17 @@ class TestSalesInvoice(unittest.TestCase): }) sales_invoice = create_sales_invoice(do_not_save=1) - sales_invoice.items[0].project = item_project.project_name - sales_invoice.project = project.project_name + sales_invoice.items[0].project = item_project.name + sales_invoice.project = project.name sales_invoice.submit() expected_values = { "Debtors - _TC": { - "project": project.project_name + "project": project.name }, "Sales - _TC": { - "project": item_project.project_name + "project": item_project.name } } @@ -1605,9 +1605,9 @@ class TestSalesInvoice(unittest.TestCase): debit_in_account_currency, credit_in_account_currency from `tabGL Entry` where voucher_type='Sales Invoice' and voucher_no=%s order by account asc""", sales_invoice.name, as_dict=1) - + self.assertTrue(gl_entries) - + for gle in gl_entries: self.assertEqual(expected_values[gle.account]["project"], gle.project) diff --git a/erpnext/agriculture/doctype/crop_cycle/test_crop_cycle.py b/erpnext/agriculture/doctype/crop_cycle/test_crop_cycle.py index 5510d5ac020..763b4036c3a 100644 --- a/erpnext/agriculture/doctype/crop_cycle/test_crop_cycle.py +++ b/erpnext/agriculture/doctype/crop_cycle/test_crop_cycle.py @@ -71,4 +71,4 @@ def check_task_creation(): def check_project_creation(): - return True if frappe.db.exists('Project', 'Basil from seed 2017') else False + return True if frappe.db.exists('Project', {'project_name': 'Basil from seed 2017'}) else False diff --git a/erpnext/hr/doctype/employee_onboarding/test_employee_onboarding.py b/erpnext/hr/doctype/employee_onboarding/test_employee_onboarding.py index 4e9ee3b143a..336e13c9b77 100644 --- a/erpnext/hr/doctype/employee_onboarding/test_employee_onboarding.py +++ b/erpnext/hr/doctype/employee_onboarding/test_employee_onboarding.py @@ -38,7 +38,8 @@ class TestEmployeeOnboarding(unittest.TestCase): onboarding.insert() onboarding.submit() - self.assertEqual(onboarding.project, 'Employee Onboarding : Test Researcher - test@researcher.com') + project_name = frappe.db.get_value("Project", onboarding.project, "project_name") + self.assertEqual(project_name, 'Employee Onboarding : Test Researcher - test@researcher.com') # don't allow making employee if onboarding is not complete self.assertRaises(IncompleteTaskError, make_employee, onboarding.name) diff --git a/erpnext/hr/doctype/expense_claim/test_expense_claim.py b/erpnext/hr/doctype/expense_claim/test_expense_claim.py index 6e97f0513d6..d9b472cce7f 100644 --- a/erpnext/hr/doctype/expense_claim/test_expense_claim.py +++ b/erpnext/hr/doctype/expense_claim/test_expense_claim.py @@ -19,35 +19,36 @@ class TestExpenseClaim(unittest.TestCase): frappe.db.sql("""delete from `tabProject` where name = "_Test Project 1" """) frappe.db.sql("update `tabExpense Claim` set project = '', task = ''") - frappe.get_doc({ + project = frappe.get_doc({ "project_name": "_Test Project 1", "doctype": "Project" - }).save() + }) + project.save() task = frappe.get_doc(dict( doctype = 'Task', subject = '_Test Project Task 1', status = 'Open', - project = '_Test Project 1' + project = project.name )).insert() task_name = task.name payable_account = get_payable_account(company_name) - make_expense_claim(payable_account, 300, 200, company_name, "Travel Expenses - _TC4", "_Test Project 1", task_name) + make_expense_claim(payable_account, 300, 200, company_name, "Travel Expenses - _TC4", project.name, task_name) self.assertEqual(frappe.db.get_value("Task", task_name, "total_expense_claim"), 200) - self.assertEqual(frappe.db.get_value("Project", "_Test Project 1", "total_expense_claim"), 200) + self.assertEqual(frappe.db.get_value("Project", project.name, "total_expense_claim"), 200) - expense_claim2 = make_expense_claim(payable_account, 600, 500, company_name, "Travel Expenses - _TC4","_Test Project 1", task_name) + expense_claim2 = make_expense_claim(payable_account, 600, 500, company_name, "Travel Expenses - _TC4", project.name, task_name) self.assertEqual(frappe.db.get_value("Task", task_name, "total_expense_claim"), 700) - self.assertEqual(frappe.db.get_value("Project", "_Test Project 1", "total_expense_claim"), 700) + self.assertEqual(frappe.db.get_value("Project", project.name, "total_expense_claim"), 700) expense_claim2.cancel() self.assertEqual(frappe.db.get_value("Task", task_name, "total_expense_claim"), 200) - self.assertEqual(frappe.db.get_value("Project", "_Test Project 1", "total_expense_claim"), 200) + self.assertEqual(frappe.db.get_value("Project", project.name, "total_expense_claim"), 200) def test_expense_claim_status(self): payable_account = get_payable_account(company_name) diff --git a/erpnext/projects/doctype/project/test_project.py b/erpnext/projects/doctype/project/test_project.py index 0c4f6f1bdfe..f31225e36b6 100644 --- a/erpnext/projects/doctype/project/test_project.py +++ b/erpnext/projects/doctype/project/test_project.py @@ -47,6 +47,10 @@ def get_project(name): def make_project(args): args = frappe._dict(args) + + if args.project_name and frappe.db.exists("Project", {"project_name": args.project_name}): + return frappe.get_doc("Project", {"project_name": args.project_name}) + if args.project_template_name: template = make_project_template(args.project_template_name) else: diff --git a/erpnext/projects/doctype/task/test_task.py b/erpnext/projects/doctype/task/test_task.py index 47a28fd1114..6ad8a19532b 100644 --- a/erpnext/projects/doctype/task/test_task.py +++ b/erpnext/projects/doctype/task/test_task.py @@ -30,14 +30,16 @@ class TestTask(unittest.TestCase): }) def test_reschedule_dependent_task(self): + project = frappe.get_value("Project", {"project_name": "_Test Project"}) + task1 = create_task("_Test Task 1", nowdate(), add_days(nowdate(), 10)) task2 = create_task("_Test Task 2", add_days(nowdate(), 11), add_days(nowdate(), 15), task1.name) - task2.get("depends_on")[0].project = "_Test Project" + task2.get("depends_on")[0].project = project task2.save() task3 = create_task("_Test Task 3", add_days(nowdate(), 11), add_days(nowdate(), 15), task2.name) - task3.get("depends_on")[0].project = "_Test Project" + task3.get("depends_on")[0].project = project task3.save() task1.update({ @@ -104,7 +106,7 @@ def create_task(subject, start=None, end=None, depends_on=None, project=None, sa task.subject = subject task.exp_start_date = start or nowdate() task.exp_end_date = end or nowdate() - task.project = project or "_Test Project" + task.project = project or frappe.get_value("Project", {"project_name": "_Test Project"}) if save: task.save() else: diff --git a/erpnext/projects/doctype/timesheet/test_timesheet.py b/erpnext/projects/doctype/timesheet/test_timesheet.py index a5ce44dcf24..4cb38049ff4 100644 --- a/erpnext/projects/doctype/timesheet/test_timesheet.py +++ b/erpnext/projects/doctype/timesheet/test_timesheet.py @@ -89,10 +89,11 @@ class TestTimesheet(unittest.TestCase): def test_timesheet_billing_based_on_project(self): emp = make_employee("test_employee_6@salary.com") + project = frappe.get_value("Project", {"project_name": "_Test Project"}) - timesheet = make_timesheet(emp, simulate=True, billable=1, project = '_Test Project', company='_Test Company') + timesheet = make_timesheet(emp, simulate=True, billable=1, project=project, company='_Test Company') sales_invoice = create_sales_invoice(do_not_save=True) - sales_invoice.project = '_Test Project' + sales_invoice.project = project sales_invoice.submit() ts = frappe.get_doc('Timesheet', timesheet.name) From 0c6319194e7fb498e9639d6efb66cbf1a629df89 Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Mon, 16 Nov 2020 13:20:19 +0530 Subject: [PATCH 058/477] fix: GL Entry validation for dimensions --- erpnext/accounts/doctype/gl_entry/gl_entry.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/erpnext/accounts/doctype/gl_entry/gl_entry.py b/erpnext/accounts/doctype/gl_entry/gl_entry.py index def9ed6803e..1ac607940fc 100644 --- a/erpnext/accounts/doctype/gl_entry/gl_entry.py +++ b/erpnext/accounts/doctype/gl_entry/gl_entry.py @@ -13,6 +13,8 @@ from erpnext.accounts.utils import get_account_currency from erpnext.accounts.utils import get_fiscal_year from erpnext.exceptions import InvalidAccountCurrency from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import get_checks_for_pl_and_bs_accounts +from erpnext.accounts.doctype.accounting_dimension_filter.accounting_dimension_filter import get_dimension_filter_map +from six import iteritems exclude_from_linked_with = True class GLEntry(Document): @@ -37,6 +39,7 @@ class GLEntry(Document): def on_update_with_args(self, adv_adj, update_outstanding = 'Yes'): self.validate_account_details(adv_adj) self.validate_dimensions_for_pl_and_bs() + self.validate_allowed_dimensions() validate_frozen_account(self.account, adv_adj) validate_balance_type(self.account, adv_adj) @@ -91,6 +94,21 @@ class GLEntry(Document): frappe.throw(_("Accounting Dimension {0} is required for 'Balance Sheet' account {1}.") .format(dimension.label, self.account)) + def validate_allowed_dimensions(self): + dimension_filter_map = get_dimension_filter_map() + for key, value in iteritems(dimension_filter_map): + dimension = key[0] + account = key[1] + + if self.account == account: + if value['allow_or_restrict'] == 'Allow': + if self.get(dimension) and self.get(dimension) not in value['allowed_dimensions']: + frappe.throw(_("Invalid value {0} for account {1}").format( + frappe.bold(self.get(dimension)), frappe.bold(self.account))) + else: + if self.get(dimension) and self.get(dimension) in value['allowed_dimensions']: + frappe.throw(_("Invalid value {0} for account {1}").format( + frappe.bold(self.get(dimension)), frappe.bold(self.account))) def check_pl_account(self): if self.is_opening=='Yes' and \ From d82c0f3beafe43146f396dce9593edd4a9d69557 Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Mon, 16 Nov 2020 20:32:16 +0530 Subject: [PATCH 059/477] fix: Add disable and mandatory check for accounting dimension filters --- .../accounting_dimension_filter.js | 37 ++++++++++++++++++- .../accounting_dimension_filter.json | 23 +++++++++++- .../accounting_dimension_filter.py | 8 ++-- .../allowed_dimension/allowed_dimension.json | 3 +- .../applicable_on_account.json | 15 +++++++- erpnext/accounts/doctype/gl_entry/gl_entry.py | 6 ++- 6 files changed, 80 insertions(+), 12 deletions(-) diff --git a/erpnext/accounts/doctype/accounting_dimension_filter/accounting_dimension_filter.js b/erpnext/accounts/doctype/accounting_dimension_filter/accounting_dimension_filter.js index 3e880d3ca68..c8c32d58bd3 100644 --- a/erpnext/accounts/doctype/accounting_dimension_filter/accounting_dimension_filter.js +++ b/erpnext/accounts/doctype/accounting_dimension_filter/accounting_dimension_filter.js @@ -3,16 +3,48 @@ frappe.ui.form.on('Accounting Dimension Filter', { onload: function(frm) { + frm.set_query('applicable_on_account', 'accounts', function() { + return { + filters : { + 'company': frm.doc.company + } + } + }); + frappe.db.get_list('Accounting Dimension', - {fields: ['name']}).then((res) => { + {fields: ['document_type']}).then((res) => { let options = ['Cost Center', 'Project']; res.forEach((dimension) => { - options.push(dimension.name); + options.push(dimension.document_type); }); frm.set_df_property('accounting_dimension', 'options', options); }); + + frm.trigger('setup_filters'); + }, + + setup_filters: function(frm) { + let filters = {}; + + frappe.model.with_doctype(frm.doc.accounting_dimension, function() { + if (frm.doc.accounting_dimension) { + if (frappe.model.is_tree(frm.doc.accounting_dimension)) { + filters['is_group'] = 0; + } + + if (frappe.meta.has_field(frm.doc.accounting_dimension, 'company')) { + filters['company'] = frm.doc.company; + } + + frm.set_query('dimension_value', 'dimensions', function() { + return { + filters: filters + } + }); + } + }); }, accounting_dimension: function(frm) { @@ -20,6 +52,7 @@ frappe.ui.form.on('Accounting Dimension Filter', { let row = frm.add_child("dimensions"); row.accounting_dimension = frm.doc.accounting_dimension; frm.refresh_field("dimensions"); + frm.trigger('setup_filters'); }, }); diff --git a/erpnext/accounts/doctype/accounting_dimension_filter/accounting_dimension_filter.json b/erpnext/accounts/doctype/accounting_dimension_filter/accounting_dimension_filter.json index e626a09ce0c..c1190a395fe 100644 --- a/erpnext/accounts/doctype/accounting_dimension_filter/accounting_dimension_filter.json +++ b/erpnext/accounts/doctype/accounting_dimension_filter/accounting_dimension_filter.json @@ -7,8 +7,10 @@ "engine": "InnoDB", "field_order": [ "accounting_dimension", - "column_break_2", "allow_or_restrict", + "column_break_2", + "company", + "disabled", "section_break_4", "accounts", "column_break_6", @@ -70,11 +72,28 @@ "reqd": 1, "show_days": 1, "show_seconds": 1 + }, + { + "default": "0", + "fieldname": "disabled", + "fieldtype": "Check", + "label": "Disabled", + "show_days": 1, + "show_seconds": 1 + }, + { + "fieldname": "company", + "fieldtype": "Link", + "label": "Company", + "options": "Company", + "reqd": 1, + "show_days": 1, + "show_seconds": 1 } ], "index_web_pages_for_search": 1, "links": [], - "modified": "2020-11-14 18:02:02.616932", + "modified": "2020-11-16 17:27:40.292860", "modified_by": "Administrator", "module": "Accounts", "name": "Accounting Dimension Filter", diff --git a/erpnext/accounts/doctype/accounting_dimension_filter/accounting_dimension_filter.py b/erpnext/accounts/doctype/accounting_dimension_filter/accounting_dimension_filter.py index 0dcf1164238..210b2c8ea89 100644 --- a/erpnext/accounts/doctype/accounting_dimension_filter/accounting_dimension_filter.py +++ b/erpnext/accounts/doctype/accounting_dimension_filter/accounting_dimension_filter.py @@ -32,12 +32,13 @@ def get_dimension_filter_map(): filters = frappe.db.sql( """ SELECT a.applicable_on_account, d.dimension_value, p.accounting_dimension, - p.allow_or_restrict, ad.fieldname + p.allow_or_restrict, ad.fieldname, a.is_mandatory FROM `tabApplicable On Account` a, `tabAllowed Dimension` d, `tabAccounting Dimension Filter` p, `tabAccounting Dimension` ad WHERE p.name = a.parent + AND p.disabled = 0 AND p.name = d.parent AND (p.accounting_dimension = ad.name OR p.accounting_dimension in ('Cost Center', 'Project')) @@ -50,13 +51,14 @@ def get_dimension_filter_map(): f.fieldname = scrub(f.accounting_dimension) build_map(dimension_filter_map, f.fieldname, f.applicable_on_account, f.dimension_value, - f.allow_or_restrict) + f.allow_or_restrict, f.is_mandatory) return dimension_filter_map -def build_map(map_object, dimension, account, filter_value, allow_or_restrict): +def build_map(map_object, dimension, account, filter_value, allow_or_restrict, is_mandatory): map_object.setdefault((dimension, account), { 'allowed_dimensions': [], + 'is_mandatory': is_mandatory, 'allow_or_restrict': allow_or_restrict }) map_object[(dimension, account)]['allowed_dimensions'].append(filter_value) diff --git a/erpnext/accounts/doctype/allowed_dimension/allowed_dimension.json b/erpnext/accounts/doctype/allowed_dimension/allowed_dimension.json index 20024b03226..c2d34b3b7e6 100644 --- a/erpnext/accounts/doctype/allowed_dimension/allowed_dimension.json +++ b/erpnext/accounts/doctype/allowed_dimension/allowed_dimension.json @@ -22,6 +22,7 @@ "fieldname": "dimension_value", "fieldtype": "Dynamic Link", "in_list_view": 1, + "label": "Applicable Dimension", "options": "accounting_dimension", "show_days": 1, "show_seconds": 1 @@ -30,7 +31,7 @@ "index_web_pages_for_search": 1, "istable": 1, "links": [], - "modified": "2020-11-14 19:54:03.269016", + "modified": "2020-11-16 17:41:50.422843", "modified_by": "Administrator", "module": "Accounts", "name": "Allowed Dimension", diff --git a/erpnext/accounts/doctype/applicable_on_account/applicable_on_account.json b/erpnext/accounts/doctype/applicable_on_account/applicable_on_account.json index 8305da2ba08..5c809515c29 100644 --- a/erpnext/accounts/doctype/applicable_on_account/applicable_on_account.json +++ b/erpnext/accounts/doctype/applicable_on_account/applicable_on_account.json @@ -5,7 +5,8 @@ "editable_grid": 1, "engine": "InnoDB", "field_order": [ - "applicable_on_account" + "applicable_on_account", + "is_mandatory" ], "fields": [ { @@ -17,12 +18,22 @@ "reqd": 1, "show_days": 1, "show_seconds": 1 + }, + { + "columns": 2, + "default": "0", + "fieldname": "is_mandatory", + "fieldtype": "Check", + "in_list_view": 1, + "label": "Is Mandatory", + "show_days": 1, + "show_seconds": 1 } ], "index_web_pages_for_search": 1, "istable": 1, "links": [], - "modified": "2020-11-14 16:54:06.756883", + "modified": "2020-11-16 13:36:59.129672", "modified_by": "Administrator", "module": "Accounts", "name": "Applicable On Account", diff --git a/erpnext/accounts/doctype/gl_entry/gl_entry.py b/erpnext/accounts/doctype/gl_entry/gl_entry.py index 1ac607940fc..b3caf6a82e8 100644 --- a/erpnext/accounts/doctype/gl_entry/gl_entry.py +++ b/erpnext/accounts/doctype/gl_entry/gl_entry.py @@ -77,11 +77,9 @@ class GLEntry(Document): .format(self.voucher_type, self.voucher_no, self.account)) def validate_dimensions_for_pl_and_bs(self): - account_type = frappe.db.get_value("Account", self.account, "report_type") for dimension in get_checks_for_pl_and_bs_accounts(): - if account_type == "Profit and Loss" \ and self.company == dimension.company and dimension.mandatory_for_pl and not dimension.disabled: if not self.get(dimension.fieldname): @@ -101,6 +99,10 @@ class GLEntry(Document): account = key[1] if self.account == account: + if value['is_mandatory'] and not self.get(dimension): + frappe.throw(_("{0} is mandatory for account {1}").format( + frappe.bold(frappe.unscrub(dimension)), frappe.bold(self.account))) + if value['allow_or_restrict'] == 'Allow': if self.get(dimension) and self.get(dimension) not in value['allowed_dimensions']: frappe.throw(_("Invalid value {0} for account {1}").format( From 4bd52b48424c2fbe02d5e00ca5ddd3ce4665eb44 Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Mon, 16 Nov 2020 23:01:36 +0530 Subject: [PATCH 060/477] fix: Add test case --- .../test_accounting_dimension.py | 64 ++++++++-------- .../accounting_dimension_filter.py | 10 +-- .../test_accounting_dimension_filter.py | 75 ++++++++++++++++++- 3 files changed, 110 insertions(+), 39 deletions(-) diff --git a/erpnext/accounts/doctype/accounting_dimension/test_accounting_dimension.py b/erpnext/accounts/doctype/accounting_dimension/test_accounting_dimension.py index 104880f6f34..b5375e106fe 100644 --- a/erpnext/accounts/doctype/accounting_dimension/test_accounting_dimension.py +++ b/erpnext/accounts/doctype/accounting_dimension/test_accounting_dimension.py @@ -11,37 +11,7 @@ from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import d class TestAccountingDimension(unittest.TestCase): def setUp(self): - frappe.set_user("Administrator") - - if not frappe.db.exists("Accounting Dimension", {"document_type": "Department"}): - dimension = frappe.get_doc({ - "doctype": "Accounting Dimension", - "document_type": "Department", - }).insert() - else: - dimension1 = frappe.get_doc("Accounting Dimension", "Department") - dimension1.disabled = 0 - dimension1.save() - - if not frappe.db.exists("Accounting Dimension", {"document_type": "Location"}): - dimension1 = frappe.get_doc({ - "doctype": "Accounting Dimension", - "document_type": "Location", - }) - - dimension1.append("dimension_defaults", { - "company": "_Test Company", - "reference_document": "Location", - "default_dimension": "Block 1", - "mandatory_for_bs": 1 - }) - - dimension1.insert() - dimension1.save() - else: - dimension1 = frappe.get_doc("Accounting Dimension", "Location") - dimension1.disabled = 0 - dimension1.save() + create_dimension() def test_dimension_against_sales_invoice(self): si = create_sales_invoice(do_not_save=1) @@ -101,6 +71,38 @@ class TestAccountingDimension(unittest.TestCase): def tearDown(self): disable_dimension() +def create_dimension(): + frappe.set_user("Administrator") + + if not frappe.db.exists("Accounting Dimension", {"document_type": "Department"}): + dimension = frappe.get_doc({ + "doctype": "Accounting Dimension", + "document_type": "Department", + }).insert() + else: + dimension1 = frappe.get_doc("Accounting Dimension", "Department") + dimension1.disabled = 0 + dimension1.save() + + if not frappe.db.exists("Accounting Dimension", {"document_type": "Location"}): + dimension1 = frappe.get_doc({ + "doctype": "Accounting Dimension", + "document_type": "Location", + }) + + dimension1.append("dimension_defaults", { + "company": "_Test Company", + "reference_document": "Location", + "default_dimension": "Block 1", + "mandatory_for_bs": 1 + }) + + dimension1.insert() + dimension1.save() + else: + dimension1 = frappe.get_doc("Accounting Dimension", "Location") + dimension1.disabled = 0 + dimension1.save() def disable_dimension(): dimension1 = frappe.get_doc("Accounting Dimension", "Department") diff --git a/erpnext/accounts/doctype/accounting_dimension_filter/accounting_dimension_filter.py b/erpnext/accounts/doctype/accounting_dimension_filter/accounting_dimension_filter.py index 210b2c8ea89..440073b7230 100644 --- a/erpnext/accounts/doctype/accounting_dimension_filter/accounting_dimension_filter.py +++ b/erpnext/accounts/doctype/accounting_dimension_filter/accounting_dimension_filter.py @@ -32,23 +32,21 @@ def get_dimension_filter_map(): filters = frappe.db.sql( """ SELECT a.applicable_on_account, d.dimension_value, p.accounting_dimension, - p.allow_or_restrict, ad.fieldname, a.is_mandatory + p.allow_or_restrict, a.is_mandatory FROM `tabApplicable On Account` a, `tabAllowed Dimension` d, - `tabAccounting Dimension Filter` p, `tabAccounting Dimension` ad + `tabAccounting Dimension Filter` p WHERE p.name = a.parent AND p.disabled = 0 AND p.name = d.parent - AND (p.accounting_dimension = ad.name - OR p.accounting_dimension in ('Cost Center', 'Project')) + """, as_dict=1) dimension_filter_map = {} for f in filters: - if f.accounting_dimension in ('Cost Center', 'Project'): - f.fieldname = scrub(f.accounting_dimension) + f.fieldname = scrub(f.accounting_dimension) build_map(dimension_filter_map, f.fieldname, f.applicable_on_account, f.dimension_value, f.allow_or_restrict, f.is_mandatory) diff --git a/erpnext/accounts/doctype/accounting_dimension_filter/test_accounting_dimension_filter.py b/erpnext/accounts/doctype/accounting_dimension_filter/test_accounting_dimension_filter.py index c271a25fbd8..feb0af1bd59 100644 --- a/erpnext/accounts/doctype/accounting_dimension_filter/test_accounting_dimension_filter.py +++ b/erpnext/accounts/doctype/accounting_dimension_filter/test_accounting_dimension_filter.py @@ -3,8 +3,79 @@ # See license.txt from __future__ import unicode_literals -# import frappe +import frappe import unittest +from erpnext.accounts.doctype.sales_invoice.test_sales_invoice import create_sales_invoice +from erpnext.accounts.doctype.accounting_dimension.test_accounting_dimension import create_dimension class TestAccountingDimensionFilter(unittest.TestCase): - pass + def setUp(self): + create_accounting_dimension_filter() + + def test_allowed_dimension_validation(self): + si = create_sales_invoice(do_not_save=1) + si.items[0].cost_center = 'Main - _TC' + si.save() + + self.assertRaises(frappe.ValidationError, si.submit) + + def test_mandatory_dimension_validation(self): + si = create_sales_invoice(do_not_save=1) + si.items[0].location = '' + si.save() + + self.assertRaises(frappe.ValidationError, si.submit) + + def tearDown(self): + disable_dimension_filter() + +def create_accounting_dimension_filter(): + if not frappe.db.get_value('Accounting Dimension Filter', + {'accounting_dimension': 'Cost Center'}): + frappe.get_doc({ + 'doctype': 'Accounting Dimension Filter', + 'accounting_dimension': 'Cost Center', + 'allow_or_restrict': 'Allow', + 'company': '_Test Company', + 'accounts': [{ + 'applicable_on_account': 'Sales - _TC', + }], + 'dimensions': [{ + 'accounting_dimension': 'Cost Center', + 'dimension_value': '_Test Cost Center 3 - _TC' + }] + }).insert() + else: + doc = frappe.get_doc('Accounting Dimension Filter', {'accounting_dimension': 'Cost Center'}) + doc.disabled = 0 + doc.save() + + if not frappe.db.get_value('Accounting Dimension Filter', + {'accounting_dimension': 'Location'}): + frappe.get_doc({ + 'doctype': 'Accounting Dimension Filter', + 'accounting_dimension': 'Location', + 'allow_or_restrict': 'Allow', + 'company': '_Test Company', + 'accounts': [{ + 'applicable_on_account': 'Sales - _TC', + 'is_mandatory': 1 + }], + 'dimensions': [{ + 'accounting_dimension': 'Location', + 'dimension_value': 'Block 1' + }] + }).insert() + else: + doc = frappe.get_doc('Accounting Dimension Filter', {'accounting_dimension': 'Location'}) + doc.disabled = 0 + doc.save() + +def disable_dimension_filter(): + doc = frappe.get_doc('Accounting Dimension Filter', {'accounting_dimension': 'Cost Center'}) + doc.disabled = 0 + doc.save() + + doc = frappe.get_doc('Accounting Dimension Filter', {'accounting_dimension': 'Location'}) + doc.disabled = 0 + doc.save() From 6456c3dc244c0b294748707ed08e558826f3ab65 Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Tue, 17 Nov 2020 11:10:00 +0530 Subject: [PATCH 061/477] fix: Linting and test cases --- .../accounting_dimension/test_accounting_dimension.py | 8 ++++---- .../accounting_dimension_filter.js | 4 ++-- .../test_accounting_dimension_filter.py | 3 ++- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/erpnext/accounts/doctype/accounting_dimension/test_accounting_dimension.py b/erpnext/accounts/doctype/accounting_dimension/test_accounting_dimension.py index b5375e106fe..fc1d7e344af 100644 --- a/erpnext/accounts/doctype/accounting_dimension/test_accounting_dimension.py +++ b/erpnext/accounts/doctype/accounting_dimension/test_accounting_dimension.py @@ -75,14 +75,14 @@ def create_dimension(): frappe.set_user("Administrator") if not frappe.db.exists("Accounting Dimension", {"document_type": "Department"}): - dimension = frappe.get_doc({ + frappe.get_doc({ "doctype": "Accounting Dimension", "document_type": "Department", }).insert() else: - dimension1 = frappe.get_doc("Accounting Dimension", "Department") - dimension1.disabled = 0 - dimension1.save() + dimension = frappe.get_doc("Accounting Dimension", "Department") + dimension.disabled = 0 + dimension.save() if not frappe.db.exists("Accounting Dimension", {"document_type": "Location"}): dimension1 = frappe.get_doc({ diff --git a/erpnext/accounts/doctype/accounting_dimension_filter/accounting_dimension_filter.js b/erpnext/accounts/doctype/accounting_dimension_filter/accounting_dimension_filter.js index c8c32d58bd3..994ee44354d 100644 --- a/erpnext/accounts/doctype/accounting_dimension_filter/accounting_dimension_filter.js +++ b/erpnext/accounts/doctype/accounting_dimension_filter/accounting_dimension_filter.js @@ -8,7 +8,7 @@ frappe.ui.form.on('Accounting Dimension Filter', { filters : { 'company': frm.doc.company } - } + }; }); frappe.db.get_list('Accounting Dimension', @@ -41,7 +41,7 @@ frappe.ui.form.on('Accounting Dimension Filter', { frm.set_query('dimension_value', 'dimensions', function() { return { filters: filters - } + }; }); } }); diff --git a/erpnext/accounts/doctype/accounting_dimension_filter/test_accounting_dimension_filter.py b/erpnext/accounts/doctype/accounting_dimension_filter/test_accounting_dimension_filter.py index feb0af1bd59..02fd75e7595 100644 --- a/erpnext/accounts/doctype/accounting_dimension_filter/test_accounting_dimension_filter.py +++ b/erpnext/accounts/doctype/accounting_dimension_filter/test_accounting_dimension_filter.py @@ -10,6 +10,7 @@ from erpnext.accounts.doctype.accounting_dimension.test_accounting_dimension imp class TestAccountingDimensionFilter(unittest.TestCase): def setUp(self): + create_dimension() create_accounting_dimension_filter() def test_allowed_dimension_validation(self): @@ -42,7 +43,7 @@ def create_accounting_dimension_filter(): }], 'dimensions': [{ 'accounting_dimension': 'Cost Center', - 'dimension_value': '_Test Cost Center 3 - _TC' + 'dimension_value': '_Test Cost Center 2 - _TC' }] }).insert() else: From 8b4d92d4fcc8ffbd92366dd63bd66122719156d2 Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Tue, 17 Nov 2020 13:19:29 +0530 Subject: [PATCH 062/477] fix: Disable filters after test --- .../test_accounting_dimension_filter.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/erpnext/accounts/doctype/accounting_dimension_filter/test_accounting_dimension_filter.py b/erpnext/accounts/doctype/accounting_dimension_filter/test_accounting_dimension_filter.py index 02fd75e7595..801786b6e96 100644 --- a/erpnext/accounts/doctype/accounting_dimension_filter/test_accounting_dimension_filter.py +++ b/erpnext/accounts/doctype/accounting_dimension_filter/test_accounting_dimension_filter.py @@ -74,9 +74,9 @@ def create_accounting_dimension_filter(): def disable_dimension_filter(): doc = frappe.get_doc('Accounting Dimension Filter', {'accounting_dimension': 'Cost Center'}) - doc.disabled = 0 + doc.disabled = 1 doc.save() doc = frappe.get_doc('Accounting Dimension Filter', {'accounting_dimension': 'Location'}) - doc.disabled = 0 + doc.disabled = 1 doc.save() From 350972ece4e80b66d02f7943acdc2cb13f277f6f Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Tue, 17 Nov 2020 13:51:58 +0530 Subject: [PATCH 063/477] fix: Account filters --- .../accounting_dimension_filter.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/erpnext/accounts/doctype/accounting_dimension_filter/accounting_dimension_filter.js b/erpnext/accounts/doctype/accounting_dimension_filter/accounting_dimension_filter.js index 994ee44354d..f0362d31403 100644 --- a/erpnext/accounts/doctype/accounting_dimension_filter/accounting_dimension_filter.js +++ b/erpnext/accounts/doctype/accounting_dimension_filter/accounting_dimension_filter.js @@ -28,8 +28,8 @@ frappe.ui.form.on('Accounting Dimension Filter', { setup_filters: function(frm) { let filters = {}; - frappe.model.with_doctype(frm.doc.accounting_dimension, function() { - if (frm.doc.accounting_dimension) { + if (frm.doc.accounting_dimension) { + frappe.model.with_doctype(frm.doc.accounting_dimension, function() { if (frappe.model.is_tree(frm.doc.accounting_dimension)) { filters['is_group'] = 0; } @@ -43,8 +43,8 @@ frappe.ui.form.on('Accounting Dimension Filter', { filters: filters }; }); - } - }); + }); + } }, accounting_dimension: function(frm) { From f9e4f6b57a238f6f391754a7a7392928d6061294 Mon Sep 17 00:00:00 2001 From: Shivam Mishra Date: Tue, 17 Nov 2020 16:34:05 +0530 Subject: [PATCH 064/477] feat: add templates for online store --- .../shopping_cart/web_template/__init__.py | 0 .../web_template/hero_slider/__init__.py | 0 .../web_template/hero_slider/hero_slider.html | 0 .../web_template/hero_slider/hero_slider.json | 142 ++++++++ .../web_template/item_card_group/__init__.py | 0 .../item_card_group/item_card_group.html | 0 .../item_card_group/item_card_group.json | 312 ++++++++++++++++++ .../web_template/product_card/__init__.py | 0 .../product_card/product_card.html | 0 .../product_card/product_card.json | 33 ++ .../product_category_cards/__init__.py | 0 .../product_category_cards.html | 0 .../product_category_cards.json | 95 ++++++ 13 files changed, 582 insertions(+) create mode 100644 erpnext/shopping_cart/web_template/__init__.py create mode 100644 erpnext/shopping_cart/web_template/hero_slider/__init__.py create mode 100644 erpnext/shopping_cart/web_template/hero_slider/hero_slider.html create mode 100644 erpnext/shopping_cart/web_template/hero_slider/hero_slider.json create mode 100644 erpnext/shopping_cart/web_template/item_card_group/__init__.py create mode 100644 erpnext/shopping_cart/web_template/item_card_group/item_card_group.html create mode 100644 erpnext/shopping_cart/web_template/item_card_group/item_card_group.json create mode 100644 erpnext/shopping_cart/web_template/product_card/__init__.py create mode 100644 erpnext/shopping_cart/web_template/product_card/product_card.html create mode 100644 erpnext/shopping_cart/web_template/product_card/product_card.json create mode 100644 erpnext/shopping_cart/web_template/product_category_cards/__init__.py create mode 100644 erpnext/shopping_cart/web_template/product_category_cards/product_category_cards.html create mode 100644 erpnext/shopping_cart/web_template/product_category_cards/product_category_cards.json diff --git a/erpnext/shopping_cart/web_template/__init__.py b/erpnext/shopping_cart/web_template/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/erpnext/shopping_cart/web_template/hero_slider/__init__.py b/erpnext/shopping_cart/web_template/hero_slider/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/erpnext/shopping_cart/web_template/hero_slider/hero_slider.html b/erpnext/shopping_cart/web_template/hero_slider/hero_slider.html new file mode 100644 index 00000000000..e69de29bb2d diff --git a/erpnext/shopping_cart/web_template/hero_slider/hero_slider.json b/erpnext/shopping_cart/web_template/hero_slider/hero_slider.json new file mode 100644 index 00000000000..a8ce2cd3cbb --- /dev/null +++ b/erpnext/shopping_cart/web_template/hero_slider/hero_slider.json @@ -0,0 +1,142 @@ +{ + "__unsaved": 1, + "creation": "2020-11-17 15:21:51.207221", + "docstatus": 0, + "doctype": "Web Template", + "fields": [ + { + "__unsaved": 1, + "fieldname": "slide_1_image", + "fieldtype": "Attach Image", + "label": "Image", + "reqd": 0 + }, + { + "__unsaved": 1, + "fieldname": "slide_1_title", + "fieldtype": "Data", + "label": "Title", + "reqd": 0 + }, + { + "__unsaved": 1, + "fieldname": "slide_1_subtitle", + "fieldtype": "Data", + "label": "Subtitle", + "reqd": 0 + }, + { + "__unsaved": 1, + "fieldname": "slide_1_primary_action_label", + "fieldtype": "Data", + "label": "Primary Action Label", + "reqd": 0 + }, + { + "__unsaved": 1, + "fieldname": "slide_1_primary_action", + "fieldtype": "Data", + "label": "Primary Action", + "reqd": 0 + }, + { + "__unsaved": 1, + "fieldname": "slide_2", + "fieldtype": "Section Break", + "label": "Slide 2", + "reqd": 0 + }, + { + "__unsaved": 1, + "fieldname": "slide_2_image", + "fieldtype": "Attach Image", + "label": "Image ", + "reqd": 0 + }, + { + "__unsaved": 1, + "fieldname": "slide_2_title", + "fieldtype": "Data", + "label": "Title ", + "reqd": 0 + }, + { + "__unsaved": 1, + "fieldname": "slide_2_subtitle", + "fieldtype": "Data", + "label": "Subtitle ", + "reqd": 0 + }, + { + "__unsaved": 1, + "fieldname": "slide_2_primary_action_label", + "fieldtype": "Data", + "label": "Primary Action Label ", + "reqd": 0 + }, + { + "__unsaved": 1, + "fieldname": "slide_2_primary_action", + "fieldtype": "Data", + "label": "Primary Action ", + "reqd": 0 + }, + { + "__islocal": 1, + "__unsaved": 1, + "fieldname": "slide_3", + "fieldtype": "Section Break", + "label": "Slide 3", + "reqd": 0 + }, + { + "__islocal": 1, + "__unsaved": 1, + "fieldname": "slide_3_image", + "fieldtype": "Attach Image", + "label": "Image ", + "reqd": 0 + }, + { + "__islocal": 1, + "__unsaved": 1, + "fieldname": "slide_3_title", + "fieldtype": "Data", + "label": "Title ", + "reqd": 0 + }, + { + "__islocal": 1, + "__unsaved": 1, + "fieldname": "slide_3_subtitle", + "fieldtype": "Data", + "label": "Subtitle ", + "reqd": 0 + }, + { + "__islocal": 1, + "__unsaved": 1, + "fieldname": "slide_3_primary_action_label", + "fieldtype": "Data", + "label": "Primary Action Label ", + "reqd": 0 + }, + { + "__islocal": 1, + "__unsaved": 1, + "fieldname": "slide_3_primary_action", + "fieldtype": "Data", + "label": "Primary Action ", + "reqd": 0 + } + ], + "idx": 0, + "modified": "2020-11-17 15:23:48.584868", + "modified_by": "Administrator", + "module": "Shopping Cart", + "name": "Hero Slider", + "owner": "Administrator", + "standard": 1, + "template": "", + "type": "Section" +} \ No newline at end of file diff --git a/erpnext/shopping_cart/web_template/item_card_group/__init__.py b/erpnext/shopping_cart/web_template/item_card_group/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/erpnext/shopping_cart/web_template/item_card_group/item_card_group.html b/erpnext/shopping_cart/web_template/item_card_group/item_card_group.html new file mode 100644 index 00000000000..e69de29bb2d diff --git a/erpnext/shopping_cart/web_template/item_card_group/item_card_group.json b/erpnext/shopping_cart/web_template/item_card_group/item_card_group.json new file mode 100644 index 00000000000..f1a70a99adb --- /dev/null +++ b/erpnext/shopping_cart/web_template/item_card_group/item_card_group.json @@ -0,0 +1,312 @@ +{ + "__unsaved": 1, + "creation": "2020-11-17 15:35:05.285322", + "docstatus": 0, + "doctype": "Web Template", + "fields": [ + { + "fieldname": "title", + "fieldtype": "Data", + "label": "Title", + "reqd": 1 + }, + { + "fieldname": "subtitle", + "fieldtype": "Data", + "label": "Subtitle", + "reqd": 0 + }, + { + "fieldname": "card_1", + "fieldtype": "Section Break", + "label": "Card 1", + "reqd": 0 + }, + { + "fieldname": "card_1_item", + "fieldtype": "Link", + "label": "Item", + "options": "Item", + "reqd": 0 + }, + { + "fieldname": "card_1_featured", + "fieldtype": "Check", + "label": "Featured", + "reqd": 0 + }, + { + "__islocal": 1, + "__unsaved": 1, + "fieldname": "card_2", + "fieldtype": "Section Break", + "label": "Card 2", + "reqd": 0 + }, + { + "__islocal": 1, + "__unsaved": 1, + "fieldname": "card_2_item", + "fieldtype": "Link", + "label": "Item", + "reqd": 0 + }, + { + "__islocal": 1, + "__unsaved": 1, + "fieldname": "card_2_featured", + "fieldtype": "Check", + "label": "Featured", + "reqd": 0 + }, + { + "__islocal": 1, + "__unsaved": 1, + "fieldname": "card_3", + "fieldtype": "Section Break", + "label": "Card 3", + "reqd": 0 + }, + { + "__islocal": 1, + "__unsaved": 1, + "fieldname": "card_3_item", + "fieldtype": "Link", + "label": "Item", + "reqd": 0 + }, + { + "__islocal": 1, + "__unsaved": 1, + "fieldname": "card_3_featured", + "fieldtype": "Check", + "label": "Featured", + "reqd": 0 + }, + { + "__islocal": 1, + "__unsaved": 1, + "fieldname": "card_4", + "fieldtype": "Section Break", + "label": "Card 4", + "reqd": 0 + }, + { + "__islocal": 1, + "__unsaved": 1, + "fieldname": "card_4_item", + "fieldtype": "Link", + "label": "Item", + "reqd": 0 + }, + { + "__islocal": 1, + "__unsaved": 1, + "fieldname": "card_4_featured", + "fieldtype": "Check", + "label": "Featured", + "reqd": 0 + }, + { + "__islocal": 1, + "__unsaved": 1, + "fieldname": "card_5", + "fieldtype": "Section Break", + "label": "Card 5", + "reqd": 0 + }, + { + "__islocal": 1, + "__unsaved": 1, + "fieldname": "card_5_item", + "fieldtype": "Link", + "label": "Item", + "reqd": 0 + }, + { + "__islocal": 1, + "__unsaved": 1, + "fieldname": "card_5_featured", + "fieldtype": "Check", + "label": "Featured", + "reqd": 0 + }, + { + "__islocal": 1, + "__unsaved": 1, + "fieldname": "card_6", + "fieldtype": "Section Break", + "label": "Card 6", + "reqd": 0 + }, + { + "__islocal": 1, + "__unsaved": 1, + "fieldname": "card_6_item", + "fieldtype": "Link", + "label": "Item", + "reqd": 0 + }, + { + "__islocal": 1, + "__unsaved": 1, + "fieldname": "card_6_featured", + "fieldtype": "Check", + "label": "Featured", + "reqd": 0 + }, + { + "__islocal": 1, + "__unsaved": 1, + "fieldname": "card_7", + "fieldtype": "Section Break", + "label": "Card 7", + "reqd": 0 + }, + { + "__islocal": 1, + "__unsaved": 1, + "fieldname": "card_7_item", + "fieldtype": "Link", + "label": "Item", + "reqd": 0 + }, + { + "__islocal": 1, + "__unsaved": 1, + "fieldname": "card_7_featured", + "fieldtype": "Check", + "label": "Featured", + "reqd": 0 + }, + { + "__islocal": 1, + "__unsaved": 1, + "fieldname": "card_8", + "fieldtype": "Section Break", + "label": "Card 8", + "reqd": 0 + }, + { + "__islocal": 1, + "__unsaved": 1, + "fieldname": "card_8_item", + "fieldtype": "Link", + "label": "Item", + "reqd": 0 + }, + { + "__islocal": 1, + "__unsaved": 1, + "fieldname": "card_8_featured", + "fieldtype": "Check", + "label": "Featured", + "reqd": 0 + }, + { + "__islocal": 1, + "__unsaved": 1, + "fieldname": "card_9", + "fieldtype": "Section Break", + "label": "Card 9", + "reqd": 0 + }, + { + "__islocal": 1, + "__unsaved": 1, + "fieldname": "card_9_item", + "fieldtype": "Link", + "label": "Item", + "reqd": 0 + }, + { + "__islocal": 1, + "__unsaved": 1, + "fieldname": "card_9_featured", + "fieldtype": "Check", + "label": "Featured", + "reqd": 0 + }, + { + "__islocal": 1, + "__unsaved": 1, + "fieldname": "card_10", + "fieldtype": "Section Break", + "label": "Card 10", + "reqd": 0 + }, + { + "__islocal": 1, + "__unsaved": 1, + "fieldname": "card_10_item", + "fieldtype": "Link", + "label": "Item", + "reqd": 0 + }, + { + "__islocal": 1, + "__unsaved": 1, + "fieldname": "card_10_featured", + "fieldtype": "Check", + "label": "Featured", + "reqd": 0 + }, + { + "__islocal": 1, + "__unsaved": 1, + "fieldname": "card_11", + "fieldtype": "Section Break", + "label": "Card 11", + "reqd": 0 + }, + { + "__islocal": 1, + "__unsaved": 1, + "fieldname": "card_11_item", + "fieldtype": "Link", + "label": "Item", + "reqd": 0 + }, + { + "__islocal": 1, + "__unsaved": 1, + "fieldname": "card_11_featured", + "fieldtype": "Check", + "label": "Featured", + "reqd": 0 + }, + { + "__islocal": 1, + "__unsaved": 1, + "fieldname": "card_12", + "fieldtype": "Section Break", + "label": "Card 12", + "reqd": 0 + }, + { + "__islocal": 1, + "__unsaved": 1, + "fieldname": "card_12_item", + "fieldtype": "Link", + "label": "Item", + "reqd": 0 + }, + { + "__islocal": 1, + "__unsaved": 1, + "fieldname": "card_12_featured", + "fieldtype": "Check", + "label": "Featured", + "reqd": 0 + } + ], + "idx": 0, + "modified": "2020-11-17 16:37:46.325181", + "modified_by": "Administrator", + "module": "Shopping Cart", + "name": "Item Card Group", + "owner": "Administrator", + "standard": 1, + "template": "", + "type": "Section" +} \ No newline at end of file diff --git a/erpnext/shopping_cart/web_template/product_card/__init__.py b/erpnext/shopping_cart/web_template/product_card/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/erpnext/shopping_cart/web_template/product_card/product_card.html b/erpnext/shopping_cart/web_template/product_card/product_card.html new file mode 100644 index 00000000000..e69de29bb2d diff --git a/erpnext/shopping_cart/web_template/product_card/product_card.json b/erpnext/shopping_cart/web_template/product_card/product_card.json new file mode 100644 index 00000000000..1059c1b2519 --- /dev/null +++ b/erpnext/shopping_cart/web_template/product_card/product_card.json @@ -0,0 +1,33 @@ +{ + "__unsaved": 1, + "creation": "2020-11-17 15:28:47.809342", + "docstatus": 0, + "doctype": "Web Template", + "fields": [ + { + "__unsaved": 1, + "fieldname": "item", + "fieldtype": "Link", + "label": "Item", + "options": "Item", + "reqd": 0 + }, + { + "__unsaved": 1, + "fieldname": "featured", + "fieldtype": "Check", + "label": "Featured", + "options": "", + "reqd": 0 + } + ], + "idx": 0, + "modified": "2020-11-17 15:33:34.982515", + "modified_by": "Administrator", + "module": "Shopping Cart", + "name": "Product Card", + "owner": "Administrator", + "standard": 1, + "template": "", + "type": "Component" +} \ No newline at end of file diff --git a/erpnext/shopping_cart/web_template/product_category_cards/__init__.py b/erpnext/shopping_cart/web_template/product_category_cards/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/erpnext/shopping_cart/web_template/product_category_cards/product_category_cards.html b/erpnext/shopping_cart/web_template/product_category_cards/product_category_cards.html new file mode 100644 index 00000000000..e69de29bb2d diff --git a/erpnext/shopping_cart/web_template/product_category_cards/product_category_cards.json b/erpnext/shopping_cart/web_template/product_category_cards/product_category_cards.json new file mode 100644 index 00000000000..1a3143c2098 --- /dev/null +++ b/erpnext/shopping_cart/web_template/product_category_cards/product_category_cards.json @@ -0,0 +1,95 @@ +{ + "__unsaved": 1, + "creation": "2020-11-17 15:25:50.855934", + "docstatus": 0, + "doctype": "Web Template", + "fields": [ + { + "__unsaved": 1, + "fieldname": "title", + "fieldtype": "Data", + "label": "Title", + "reqd": 1 + }, + { + "__unsaved": 1, + "fieldname": "subtitle", + "fieldtype": "Data", + "label": "Subtitle", + "reqd": 0 + }, + { + "__unsaved": 1, + "fieldname": "category_1_group", + "fieldtype": "Link", + "label": "Item Group", + "options": "Item Group", + "reqd": 0 + }, + { + "__unsaved": 1, + "fieldname": "category_2_group", + "fieldtype": "Link", + "label": "Item Group", + "options": "Item Group", + "reqd": 0 + }, + { + "__unsaved": 1, + "fieldname": "category_3_group", + "fieldtype": "Link", + "label": "Item Group", + "options": "Item Group", + "reqd": 0 + }, + { + "__unsaved": 1, + "fieldname": "category_4_group", + "fieldtype": "Link", + "label": "Item Group", + "options": "Item Group", + "reqd": 0 + }, + { + "__unsaved": 1, + "fieldname": "category_5_group", + "fieldtype": "Link", + "label": "Item Group", + "options": "Item Group", + "reqd": 0 + }, + { + "__unsaved": 1, + "fieldname": "category_6_group", + "fieldtype": "Link", + "label": "Item Group", + "options": "Item Group", + "reqd": 0 + }, + { + "__unsaved": 1, + "fieldname": "category_7_group", + "fieldtype": "Link", + "label": "Item Group", + "options": "Item Group", + "reqd": 0 + }, + { + "__unsaved": 1, + "fieldname": "category_8_group", + "fieldtype": "Link", + "label": "Item Group", + "options": "Item Group", + "reqd": 0 + } + ], + "idx": 0, + "modified": "2020-11-17 15:27:36.250460", + "modified_by": "Administrator", + "module": "Shopping Cart", + "name": "Product Category Cards", + "owner": "Administrator", + "standard": 1, + "template": "", + "type": "Section" +} \ No newline at end of file From 542bc017184db1187be0dcab948dbee0ba753a91 Mon Sep 17 00:00:00 2001 From: Rushabh Mehta Date: Wed, 18 Nov 2020 15:00:34 +0530 Subject: [PATCH 065/477] fix(minor): update routes --- .../opening_invoice_creation_tool.py | 6 +++--- erpnext/assets/doctype/asset/asset.py | 8 ++++---- .../supplier_quotation/supplier_quotation.py | 2 +- erpnext/config/education.py | 2 +- erpnext/config/projects.py | 6 +++--- .../assessment_result_tool.js | 2 +- .../course_scheduling_tool.js | 2 +- .../program_enrollment/program_enrollment.py | 2 +- .../tally_migration/tally_migration.js | 4 ++-- .../clinical_procedure/clinical_procedure.js | 2 +- .../inpatient_record/inpatient_record.py | 2 +- .../patient_appointment.py | 4 ++-- erpnext/healthcare/utils.py | 10 +++++----- .../employee_transfer/employee_transfer.py | 2 +- .../leave_allocation/leave_allocation.py | 2 +- .../leave_application/leave_application.py | 2 +- .../hr/doctype/shift_request/shift_request.py | 2 +- erpnext/hr/utils.py | 2 +- erpnext/manufacturing/doctype/bom/bom.js | 2 +- .../doctype/bom/bom_item_preview.html | 4 ++-- .../production_plan/production_plan.py | 4 ++-- .../bom_stock_report/bom_stock_report.js | 4 ++-- .../doctype/payroll_period/payroll_period.py | 2 +- erpnext/projects/doctype/task/task_list.js | 2 +- erpnext/public/js/call_popup/call_popup.js | 4 ++-- erpnext/public/js/communication.js | 2 +- .../js/education/assessment_result_tool.html | 6 +++--- .../doctype/sales_order/sales_order.js | 4 ++-- .../page/point_of_sale/pos_controller.js | 20 +++++++++---------- .../welcome_to_erpnext.html | 1 - erpnext/stock/dashboard/item_dashboard.js | 2 +- erpnext/stock/doctype/batch/batch.js | 2 +- erpnext/stock/doctype/item/item.js | 4 ++-- erpnext/stock/doctype/item/item.py | 2 +- .../stock/doctype/item_price/item_price.js | 2 +- erpnext/support/doctype/issue/issue.js | 2 +- erpnext/support/doctype/issue/issue.py | 2 +- erpnext/utilities/bot.py | 4 ++-- 38 files changed, 68 insertions(+), 69 deletions(-) diff --git a/erpnext/accounts/doctype/opening_invoice_creation_tool/opening_invoice_creation_tool.py b/erpnext/accounts/doctype/opening_invoice_creation_tool/opening_invoice_creation_tool.py index d51856a8a4b..0e1d140b2ec 100644 --- a/erpnext/accounts/doctype/opening_invoice_creation_tool/opening_invoice_creation_tool.py +++ b/erpnext/accounts/doctype/opening_invoice_creation_tool/opening_invoice_creation_tool.py @@ -64,11 +64,11 @@ class OpeningInvoiceCreationTool(Document): prepare_invoice_summary(doctype, invoices) return invoices_summary, max_count - + def validate_company(self): if not self.company: frappe.throw(_("Please select the Company")) - + def set_missing_values(self, row): row.qty = row.qty or 1.0 row.temporary_opening_account = row.temporary_opening_account or get_temporary_opening_account(self.company) @@ -209,7 +209,7 @@ def start_import(invoices): frappe.db.commit() if errors: frappe.msgprint(_("You had {} errors while creating opening invoices. Check {} for more details") - .format(errors, "Error Log"), indicator="red", title=_("Error Occured")) + .format(errors, "Error Log"), indicator="red", title=_("Error Occured")) return names def publish(index, total, doctype): diff --git a/erpnext/assets/doctype/asset/asset.py b/erpnext/assets/doctype/asset/asset.py index 30abc66a024..1793dad4940 100644 --- a/erpnext/assets/doctype/asset/asset.py +++ b/erpnext/assets/doctype/asset/asset.py @@ -471,7 +471,7 @@ class Asset(AccountsController): asset_bought_with_invoice = (purchase_document == self.purchase_invoice) fixed_asset_account = self.get_fixed_asset_account() - + cwip_enabled = is_cwip_accounting_enabled(self.asset_category) cwip_account = self.get_cwip_account(cwip_enabled=cwip_enabled) @@ -503,10 +503,10 @@ class Asset(AccountsController): purchase_document = self.purchase_invoice if asset_bought_with_invoice else self.purchase_receipt return purchase_document - + def get_fixed_asset_account(self): return get_asset_category_account('fixed_asset_account', None, self.name, None, self.asset_category, self.company) - + def get_cwip_account(self, cwip_enabled=False): cwip_account = None try: @@ -659,7 +659,7 @@ def transfer_asset(args): frappe.db.commit() - frappe.msgprint(_("Asset Movement record {0} created").format("{0}").format(movement_entry.name)) + frappe.msgprint(_("Asset Movement record {0} created").format("{0}").format(movement_entry.name)) @frappe.whitelist() def get_item_details(item_code, asset_category): diff --git a/erpnext/buying/doctype/supplier_quotation/supplier_quotation.py b/erpnext/buying/doctype/supplier_quotation/supplier_quotation.py index ae5611f3c41..6a4c02c075c 100644 --- a/erpnext/buying/doctype/supplier_quotation/supplier_quotation.py +++ b/erpnext/buying/doctype/supplier_quotation/supplier_quotation.py @@ -71,7 +71,7 @@ class SupplierQuotation(BuyingController): doc_sup = doc_sup[0] if doc_sup else None if not doc_sup: frappe.throw(_("Supplier {0} not found in {1}").format(self.supplier, - " Request for Quotation {0} ".format(doc.name))) + " Request for Quotation {0} ".format(doc.name))) quote_status = _('Received') for item in doc.items: diff --git a/erpnext/config/education.py b/erpnext/config/education.py index 4efaaa65cdc..1c8ab10f537 100644 --- a/erpnext/config/education.py +++ b/erpnext/config/education.py @@ -173,7 +173,7 @@ def get_data(): { "type": "doctype", "name": "Course Schedule", - "route": "#List/Course Schedule/Calendar" + "route": "/app/List/Course Schedule/Calendar" }, { "type": "doctype", diff --git a/erpnext/config/projects.py b/erpnext/config/projects.py index 47700d10b2a..ab4db964772 100644 --- a/erpnext/config/projects.py +++ b/erpnext/config/projects.py @@ -16,13 +16,13 @@ def get_data(): { "type": "doctype", "name": "Task", - "route": "#List/Task", + "route": "/app/List/Task", "description": _("Project activity / task."), "onboard": 1, }, { "type": "report", - "route": "#List/Task/Gantt", + "route": "/app/List/Task/Gantt", "doctype": "Task", "name": "Gantt Chart", "description": _("Gantt chart of all tasks."), @@ -97,5 +97,5 @@ def get_data(): }, ] }, - + ] diff --git a/erpnext/education/doctype/assessment_result_tool/assessment_result_tool.js b/erpnext/education/doctype/assessment_result_tool/assessment_result_tool.js index 3cd451209f1..e213309c5e9 100644 --- a/erpnext/education/doctype/assessment_result_tool/assessment_result_tool.js +++ b/erpnext/education/doctype/assessment_result_tool/assessment_result_tool.js @@ -128,7 +128,7 @@ frappe.ui.form.on('Assessment Result Tool', { result_table.find(`span[data-student=${assessment_result.student}].total-score-grade`).html(assessment_result.grade); let link_span = result_table.find(`span[data-student=${assessment_result.student}].total-result-link`); $(link_span).css("display", "block"); - $(link_span).find("a").attr("href", "#Form/Assessment Result/"+assessment_result.name); + $(link_span).find("a").attr("href", "/desk/Form/Assessment Result/"+assessment_result.name); } }); } diff --git a/erpnext/education/doctype/course_scheduling_tool/course_scheduling_tool.js b/erpnext/education/doctype/course_scheduling_tool/course_scheduling_tool.js index 20503f919cc..f408dae7bda 100644 --- a/erpnext/education/doctype/course_scheduling_tool/course_scheduling_tool.js +++ b/erpnext/education/doctype/course_scheduling_tool/course_scheduling_tool.js @@ -25,7 +25,7 @@ frappe.ui.form.on('Course Scheduling Tool', {
${course_schedules.map( - c => ` + c => `` ).join('')} diff --git a/erpnext/education/doctype/program_enrollment/program_enrollment.py b/erpnext/education/doctype/program_enrollment/program_enrollment.py index 6fbcd8aa97f..3045db7f32b 100644 --- a/erpnext/education/doctype/program_enrollment/program_enrollment.py +++ b/erpnext/education/doctype/program_enrollment/program_enrollment.py @@ -87,7 +87,7 @@ class ProgramEnrollment(Document): fees.submit() fee_list.append(fees.name) if fee_list: - fee_list = ["""%s""" % \ + fee_list = ["""%s""" % \ (fee, fee) for fee in fee_list] msgprint(_("Fee Records Created - {0}").format(comma_and(fee_list))) diff --git a/erpnext/erpnext_integrations/doctype/tally_migration/tally_migration.js b/erpnext/erpnext_integrations/doctype/tally_migration/tally_migration.js index fd16d1e84aa..e8641114beb 100644 --- a/erpnext/erpnext_integrations/doctype/tally_migration/tally_migration.js +++ b/erpnext/erpnext_integrations/doctype/tally_migration/tally_migration.js @@ -23,10 +23,10 @@ frappe.ui.form.on("Tally Migration", { frappe.msgprint({ message: __("An error has occurred during {0}. Check {1} for more details", [ - repl("%(tally_document)s", { + repl("%(tally_document)s", { tally_document: frm.docname }), - "Error Log" + "Error Log" ] ), title: __("Tally Migration Error"), diff --git a/erpnext/healthcare/doctype/clinical_procedure/clinical_procedure.js b/erpnext/healthcare/doctype/clinical_procedure/clinical_procedure.js index eb7d4bdebad..19bddbb1911 100644 --- a/erpnext/healthcare/doctype/clinical_procedure/clinical_procedure.js +++ b/erpnext/healthcare/doctype/clinical_procedure/clinical_procedure.js @@ -86,7 +86,7 @@ frappe.ui.form.on('Clinical Procedure', { if (r.message) { frappe.show_alert({ message: __('Stock Entry {0} created', - ['' + r.message + '']), + ['' + r.message + '']), indicator: 'green' }); } diff --git a/erpnext/healthcare/doctype/inpatient_record/inpatient_record.py b/erpnext/healthcare/doctype/inpatient_record/inpatient_record.py index bc769706018..c7ab4478600 100644 --- a/erpnext/healthcare/doctype/inpatient_record/inpatient_record.py +++ b/erpnext/healthcare/doctype/inpatient_record/inpatient_record.py @@ -50,7 +50,7 @@ class InpatientRecord(Document): if ip_record: msg = _(("Already {0} Patient {1} with Inpatient Record ").format(ip_record[0].status, self.patient) \ - + """ {0}""".format(ip_record[0].name)) + + """ {0}""".format(ip_record[0].name)) frappe.throw(msg) def admit(self, service_unit, check_in, expected_discharge=None): diff --git a/erpnext/healthcare/doctype/patient_appointment/patient_appointment.py b/erpnext/healthcare/doctype/patient_appointment/patient_appointment.py index e685b20a8c8..90d9023278a 100755 --- a/erpnext/healthcare/doctype/patient_appointment/patient_appointment.py +++ b/erpnext/healthcare/doctype/patient_appointment/patient_appointment.py @@ -63,7 +63,7 @@ class PatientAppointment(Document): if overlaps: overlapping_details = _('Appointment overlaps with ') - overlapping_details += "{0}
".format(overlaps[0][0]) + overlapping_details += "{0}
".format(overlaps[0][0]) overlapping_details += _('{0} has appointment scheduled with {1} at {2} having {3} minute(s) duration.').format( overlaps[0][1], overlaps[0][2], overlaps[0][3], overlaps[0][4]) frappe.throw(overlapping_details, title=_('Appointments Overlapping')) @@ -75,7 +75,7 @@ class PatientAppointment(Document): if frappe.db.get_single_value('Healthcare Settings', 'automate_appointment_invoicing'): if not frappe.db.get_value('Patient', self.patient, 'customer'): msg = _("Please set a Customer linked to the Patient") - msg += " {0}".format(self.patient) + msg += " {0}".format(self.patient) frappe.throw(msg, title=_('Customer Not Found')) def update_prescription_details(self): diff --git a/erpnext/healthcare/utils.py b/erpnext/healthcare/utils.py index 96282f50a92..248692332c8 100644 --- a/erpnext/healthcare/utils.py +++ b/erpnext/healthcare/utils.py @@ -32,7 +32,7 @@ def get_healthcare_services_to_invoice(patient, company): def validate_customer_created(patient): if not frappe.db.get_value('Patient', patient.name, 'customer'): msg = _("Please set a Customer linked to the Patient") - msg += " {0}".format(patient.name) + msg += " {0}".format(patient.name) frappe.throw(msg, title=_('Customer Not Found')) @@ -169,7 +169,7 @@ def get_clinical_procedures_to_invoice(patient, company): service_item = get_healthcare_service_item('clinical_procedure_consumable_item') if not service_item: msg = _('Please Configure Clinical Procedure Consumable Item in ') - msg += '''Healthcare Settings''' + msg += '''Healthcare Settings''' frappe.throw(msg, title=_('Missing Configuration')) clinical_procedures_to_invoice.append({ @@ -324,7 +324,7 @@ def throw_config_service_item(is_inpatient): service_item_label = _('Inpatient Visit Charge Item') msg = _(('Please Configure {0} in ').format(service_item_label) \ - + '''Healthcare Settings''') + + '''Healthcare Settings''') frappe.throw(msg, title=_('Missing Configuration')) @@ -334,7 +334,7 @@ def throw_config_practitioner_charge(is_inpatient, practitioner): charge_name = _('Inpatient Visit Charge') msg = _(('Please Configure {0} for Healthcare Practitioner').format(charge_name) \ - + ''' {0}'''.format(practitioner)) + + ''' {0}'''.format(practitioner)) frappe.throw(msg, title=_('Missing Configuration')) @@ -654,6 +654,6 @@ def render_doc_as_html(doctype, docname, exclude_fields = []): >
" \ + section_html + html +'
' if doc_html: - doc_html = "
" %(doctype, docname) + doc_html + '
' + doc_html = "
" %(doctype, docname) + doc_html + '
' return {'html': doc_html} diff --git a/erpnext/hr/doctype/employee_transfer/employee_transfer.py b/erpnext/hr/doctype/employee_transfer/employee_transfer.py index c730e022a50..37d616f14d4 100644 --- a/erpnext/hr/doctype/employee_transfer/employee_transfer.py +++ b/erpnext/hr/doctype/employee_transfer/employee_transfer.py @@ -50,7 +50,7 @@ class EmployeeTransfer(Document): employee = frappe.get_doc("Employee", self.employee) if self.create_new_employee_id: if self.new_employee_id: - frappe.throw(_("Please delete the Employee {0}\ + frappe.throw(_("Please delete the Employee {0}\ to cancel this document").format(self.new_employee_id)) #mark the employee as active employee.status = "Active" diff --git a/erpnext/hr/doctype/leave_allocation/leave_allocation.py b/erpnext/hr/doctype/leave_allocation/leave_allocation.py index 03fe3fa035c..32c54562395 100755 --- a/erpnext/hr/doctype/leave_allocation/leave_allocation.py +++ b/erpnext/hr/doctype/leave_allocation/leave_allocation.py @@ -82,7 +82,7 @@ class LeaveAllocation(Document): frappe.msgprint(_("{0} already allocated for Employee {1} for period {2} to {3}") .format(self.leave_type, self.employee, formatdate(self.from_date), formatdate(self.to_date))) - frappe.throw(_('Reference') + ': {0}' + frappe.throw(_('Reference') + ': {0}' .format(leave_allocation[0][0]), OverlapError) def validate_back_dated_allocation(self): diff --git a/erpnext/hr/doctype/leave_application/leave_application.py b/erpnext/hr/doctype/leave_application/leave_application.py index 3f25f583833..35c3ea77ea2 100755 --- a/erpnext/hr/doctype/leave_application/leave_application.py +++ b/erpnext/hr/doctype/leave_application/leave_application.py @@ -246,7 +246,7 @@ class LeaveApplication(Document): def throw_overlap_error(self, d): msg = _("Employee {0} has already applied for {1} between {2} and {3} : ").format(self.employee, d['leave_type'], formatdate(d['from_date']), formatdate(d['to_date'])) \ - + """ {0}""".format(d["name"]) + + """ {0}""".format(d["name"]) frappe.throw(msg, OverlapError) def get_total_leaves_on_half_day(self): diff --git a/erpnext/hr/doctype/shift_request/shift_request.py b/erpnext/hr/doctype/shift_request/shift_request.py index 1c2801bf08f..473193d5ac4 100644 --- a/erpnext/hr/doctype/shift_request/shift_request.py +++ b/erpnext/hr/doctype/shift_request/shift_request.py @@ -87,5 +87,5 @@ class ShiftRequest(Document): def throw_overlap_error(self, d): msg = _("Employee {0} has already applied for {1} between {2} and {3} : ").format(self.employee, d['shift_type'], formatdate(d['from_date']), formatdate(d['to_date'])) \ - + """ {0}""".format(d["name"]) + + """ {0}""".format(d["name"]) frappe.throw(msg, OverlapError) \ No newline at end of file diff --git a/erpnext/hr/utils.py b/erpnext/hr/utils.py index 8d95924681a..3b8d73b0f00 100644 --- a/erpnext/hr/utils.py +++ b/erpnext/hr/utils.py @@ -211,7 +211,7 @@ def get_doc_condition(doctype): def throw_overlap_error(doc, exists_for, overlap_doc, from_date, to_date): msg = _("A {0} exists between {1} and {2} (").format(doc.doctype, formatdate(from_date), formatdate(to_date)) \ - + """ {1}""".format(doc.doctype, overlap_doc) \ + + """ {1}""".format(doc.doctype, overlap_doc) \ + _(") for {0}").format(exists_for) frappe.throw(msg) diff --git a/erpnext/manufacturing/doctype/bom/bom.js b/erpnext/manufacturing/doctype/bom/bom.js index 1c4b7a1e1ce..55f7a1b8a90 100644 --- a/erpnext/manufacturing/doctype/bom/bom.js +++ b/erpnext/manufacturing/doctype/bom/bom.js @@ -134,7 +134,7 @@ frappe.ui.form.on("BOM", { frm.set_intro(__('This is a Template BOM and will be used to make the work order for {0} of the item {1}', [ `variants`, - `${frm.doc.item}`, + `${frm.doc.item}`, ]), true); frm.$wrapper.find(".variants-intro").on("click", () => { diff --git a/erpnext/manufacturing/doctype/bom/bom_item_preview.html b/erpnext/manufacturing/doctype/bom/bom_item_preview.html index c782f7bf0ee..6cd5f8cb3cf 100644 --- a/erpnext/manufacturing/doctype/bom/bom_item_preview.html +++ b/erpnext/manufacturing/doctype/bom/bom_item_preview.html @@ -12,11 +12,11 @@

{% if data.value %} - + {{ __("Open BOM {0}", [data.value.bold()]) }} {% endif %} {% if data.item_code %} - + {{ __("Open Item {0}", [data.item_code.bold()]) }} {% endif %}

diff --git a/erpnext/manufacturing/doctype/production_plan/production_plan.py b/erpnext/manufacturing/doctype/production_plan/production_plan.py index 3833e86d276..8f9dd052175 100644 --- a/erpnext/manufacturing/doctype/production_plan/production_plan.py +++ b/erpnext/manufacturing/doctype/production_plan/production_plan.py @@ -319,7 +319,7 @@ class ProductionPlan(Document): frappe.flags.mute_messages = False if wo_list: - wo_list = ["""%s""" % \ + wo_list = ["""%s""" % \ (p, p) for p in wo_list] msgprint(_("{0} created").format(comma_and(wo_list))) else : @@ -423,7 +423,7 @@ class ProductionPlan(Document): frappe.flags.mute_messages = False if material_request_list: - material_request_list = ["""{1}""".format(m.name, m.name) \ + material_request_list = ["""{1}""".format(m.name, m.name) \ for m in material_request_list] msgprint(_("{0} created").format(comma_and(material_request_list))) else : diff --git a/erpnext/manufacturing/report/bom_stock_report/bom_stock_report.js b/erpnext/manufacturing/report/bom_stock_report/bom_stock_report.js index 2ac6fa073bf..2f18d1704b4 100644 --- a/erpnext/manufacturing/report/bom_stock_report/bom_stock_report.js +++ b/erpnext/manufacturing/report/bom_stock_report/bom_stock_report.js @@ -27,9 +27,9 @@ frappe.query_reports["BOM Stock Report"] = { value = default_formatter(value, row, column, data); if (column.id == "Item"){ if (data["Enough Parts to Build"] > 0){ - value = `${data['Item']}` + value = `${data['Item']}` } else { - value = `${data['Item']}` + value = `${data['Item']}` } } return value diff --git a/erpnext/payroll/doctype/payroll_period/payroll_period.py b/erpnext/payroll/doctype/payroll_period/payroll_period.py index d7893d06572..1c8cc53debf 100644 --- a/erpnext/payroll/doctype/payroll_period/payroll_period.py +++ b/erpnext/payroll/doctype/payroll_period/payroll_period.py @@ -41,7 +41,7 @@ class PayrollPeriod(Document): if overlap_doc: msg = _("A {0} exists between {1} and {2} (").format(self.doctype, formatdate(self.start_date), formatdate(self.end_date)) \ - + """ {1}""".format(self.doctype, overlap_doc[0].name) \ + + """ {1}""".format(self.doctype, overlap_doc[0].name) \ + _(") for {0}").format(self.company) frappe.throw(msg) diff --git a/erpnext/projects/doctype/task/task_list.js b/erpnext/projects/doctype/task/task_list.js index 941fe975468..7c620317dee 100644 --- a/erpnext/projects/doctype/task/task_list.js +++ b/erpnext/projects/doctype/task/task_list.js @@ -26,7 +26,7 @@ frappe.listview_settings['Task'] = { }, gantt_custom_popup_html: function(ganttobj, task) { var html = `
${ganttobj.name}
`; + href="/desk/Form/Task/${ganttobj.id}""> ${ganttobj.name} `; if(task.project) html += `

Project: ${task.project}

`; html += `

Progress: ${ganttobj.progress}

`; diff --git a/erpnext/public/js/call_popup/call_popup.js b/erpnext/public/js/call_popup/call_popup.js index 5e4d4a585fa..378d6d131d3 100644 --- a/erpnext/public/js/call_popup/call_popup.js +++ b/erpnext/public/js/call_popup/call_popup.js @@ -85,7 +85,7 @@ class CallPopup {
+ href="/desk/Form/Call Log/${this.call_log.name}"> ${__('View call log')} `, @@ -167,7 +167,7 @@ class CallPopup { const issue_field = this.dialog.get_field("last_issue"); issue_field.set_value(issue.subject); issue_field.$wrapper.append(` - + ${__('View all issues from {0}', [issue.customer])} `); diff --git a/erpnext/public/js/communication.js b/erpnext/public/js/communication.js index 26e5ab8b322..38778e2ab0a 100644 --- a/erpnext/public/js/communication.js +++ b/erpnext/public/js/communication.js @@ -84,7 +84,7 @@ frappe.ui.form.on("Communication", { frm.reload_doc(); frappe.show_alert({ message: __("Opportunity {0} created", - ['' + r.message + '']), + ['' + r.message + '']), indicator: 'green' }); } diff --git a/erpnext/public/js/education/assessment_result_tool.html b/erpnext/public/js/education/assessment_result_tool.html index 9fc17f7be1d..b591010ec86 100644 --- a/erpnext/public/js/education/assessment_result_tool.html +++ b/erpnext/public/js/education/assessment_result_tool.html @@ -19,7 +19,7 @@ {% for s in students %} - @@ -29,7 +29,7 @@ + + """.format(item_link, frappe.bold(entry[1])) + + msg += """ +
{{ _("Sr") }} {{ _(tdf.label) }}
{{ d.idx }} -
{{ print_value(tdf, d, doc, visible_columns) }}
${__("Course")}${__("Date")}
${c.name}
${c.name} ${c.schedule_date}
{% if(s.assessment_details) { %} - {{s.assessment_details[c.assessment_criteria][1]}} + {{s.assessment_details[c.assessment_criteria][1]}} {% } %} - + diff --git a/erpnext/selling/doctype/sales_order/sales_order.js b/erpnext/selling/doctype/sales_order/sales_order.js index 73cc0b836e4..96d265c9899 100644 --- a/erpnext/selling/doctype/sales_order/sales_order.js +++ b/erpnext/selling/doctype/sales_order/sales_order.js @@ -328,7 +328,7 @@ erpnext.selling.SalesOrderController = erpnext.selling.SellingController.extend( frappe.msgprint({ message: __('Work Orders Created: {0}', [r.message.map(function(d) { - return repl('%(name)s', {name:d}) + return repl('%(name)s', {name:d}) }).join(', ')]), indicator: 'green' }) @@ -437,7 +437,7 @@ erpnext.selling.SalesOrderController = erpnext.selling.SellingController.extend( callback: function(r) { if(r.message) { frappe.msgprint(__('Material Request {0} submitted.', - ['' + r.message.name+ ''])); + ['' + r.message.name+ ''])); } d.hide(); me.frm.reload_doc(); diff --git a/erpnext/selling/page/point_of_sale/pos_controller.js b/erpnext/selling/page/point_of_sale/pos_controller.js index 970d8406654..288084d2454 100644 --- a/erpnext/selling/page/point_of_sale/pos_controller.js +++ b/erpnext/selling/page/point_of_sale/pos_controller.js @@ -45,7 +45,7 @@ erpnext.PointOfSale.Controller = class { { fieldname: "opening_amount", fieldtype: "Currency", in_list_view: 1, label: "Opening Amount", - options: "company:company_currency", + options: "company:company_currency", change: function () { dialog.fields_dict.balance_details.df.data.some(d => { if (d.idx == this.doc.idx) { @@ -134,7 +134,7 @@ erpnext.PointOfSale.Controller = class { set_opening_entry_status() { this.page.set_title_sub( ` - + Opened at ${moment(this.pos_opening_time).format("Do MMMM, h:mma")} `); @@ -199,7 +199,7 @@ erpnext.PointOfSale.Controller = class { if (this.frm.doc.items.length == 0) { frappe.show_alert({ - message:__("You must add atleast one item to save it as draft."), + message:__("You must add atleast one item to save it as draft."), indicator:'red' }); frappe.utils.play_sound("error"); @@ -208,7 +208,7 @@ erpnext.PointOfSale.Controller = class { this.frm.save(undefined, undefined, undefined, () => { frappe.show_alert({ - message:__("There was an error saving the document."), + message:__("There was an error saving the document."), indicator:'red' }); frappe.utils.play_sound("error"); @@ -256,7 +256,7 @@ erpnext.PointOfSale.Controller = class { cart_item_clicked: (item_code, batch_no, uom) => { const item_row = this.frm.doc.items.find( - i => i.item_code === item_code + i => i.item_code === item_code && i.uom === uom && (!batch_no || (batch_no && i.batch_no === batch_no)) ); @@ -429,7 +429,7 @@ erpnext.PointOfSale.Controller = class { }) } - + toggle_recent_order_list(show) { this.toggle_components(!show); @@ -539,7 +539,7 @@ erpnext.PointOfSale.Controller = class { const qty_needed = field === 'qty' ? value * item_row.conversion_factor : item_row.qty * value; await this.check_stock_availability(item_row, qty_needed, this.frm.doc.set_warehouse); } - + if (this.is_current_item_being_edited(item_row) || item_selected_from_selector) { await frappe.model.set_value(item_row.doctype, item_row.name, field, value); this.update_cart_html(item_row); @@ -577,7 +577,7 @@ erpnext.PointOfSale.Controller = class { this.check_serial_batch_selection_needed(item_row) && this.edit_item_details_of(item_row); this.update_cart_html(item_row); - } + } } catch (error) { console.log(error); } finally { @@ -588,7 +588,7 @@ erpnext.PointOfSale.Controller = class { get_item_from_frm(item_code, batch_no, uom) { const has_batch_no = batch_no; return this.frm.doc.items.find( - i => i.item_code === item_code + i => i.item_code === item_code && (!has_batch_no || (has_batch_no && i.batch_no === batch_no)) && (i.uom === uom) ); @@ -617,7 +617,7 @@ erpnext.PointOfSale.Controller = class { const no_serial_selected = !item_row.serial_no; const no_batch_selected = !item_row.batch_no; - if ((serialized && no_serial_selected) || (batched && no_batch_selected) || + if ((serialized && no_serial_selected) || (batched && no_batch_selected) || (serialized && batched && (no_batch_selected || no_serial_selected))) { return true; } diff --git a/erpnext/setup/page/welcome_to_erpnext/welcome_to_erpnext.html b/erpnext/setup/page/welcome_to_erpnext/welcome_to_erpnext.html index 5808ce73ee9..7166ba37867 100644 --- a/erpnext/setup/page/welcome_to_erpnext/welcome_to_erpnext.html +++ b/erpnext/setup/page/welcome_to_erpnext/welcome_to_erpnext.html @@ -21,7 +21,6 @@

{%= __("Next Steps") %}

diff --git a/erpnext/stock/dashboard/item_dashboard.js b/erpnext/stock/dashboard/item_dashboard.js index 9bd03d45cbb..faa9b5df2fa 100644 --- a/erpnext/stock/dashboard/item_dashboard.js +++ b/erpnext/stock/dashboard/item_dashboard.js @@ -198,7 +198,7 @@ erpnext.stock.move_item = function(item, source, target, actual_qty, rate, callb freeze: true, callback: function(r) { frappe.show_alert(__('Stock Entry {0} created', - ['' + r.message.name+ ''])); + ['' + r.message.name+ ''])); dialog.hide(); callback(r); }, diff --git a/erpnext/stock/doctype/batch/batch.js b/erpnext/stock/doctype/batch/batch.js index 71a3e7abcab..7b2edff7e0e 100644 --- a/erpnext/stock/doctype/batch/batch.js +++ b/erpnext/stock/doctype/batch/batch.js @@ -102,7 +102,7 @@ frappe.ui.form.on('Batch', { }, callback: (r) => { frappe.show_alert(__('Stock Entry {0} created', - ['' + r.message.name+ ''])); + ['' + r.message.name+ ''])); frm.refresh(); }, }); diff --git a/erpnext/stock/doctype/item/item.js b/erpnext/stock/doctype/item/item.js index faf4accc738..43e18d16fc4 100644 --- a/erpnext/stock/doctype/item/item.js +++ b/erpnext/stock/doctype/item/item.js @@ -85,7 +85,7 @@ frappe.ui.form.on("Item", { } if (frm.doc.variant_of) { frm.set_intro(__('This Item is a Variant of {0} (Template).', - [`${frm.doc.variant_of}`]), true); + [`${frm.doc.variant_of}`]), true); } if (frappe.defaults.get_default("item_naming_by")!="Naming Series" || frm.doc.variant_of) { @@ -649,7 +649,7 @@ $.extend(erpnext.item, { if (r.message) { var variant = r.message; frappe.msgprint_dialog = frappe.msgprint(__("Item Variant {0} already exists with same attributes", - [repl('%(item)s', { + [repl('%(item)s', { item_encoded: encodeURIComponent(variant), item: variant })] diff --git a/erpnext/stock/doctype/item/item.py b/erpnext/stock/doctype/item/item.py index 3b62c38b866..1993d56a6cd 100644 --- a/erpnext/stock/doctype/item/item.py +++ b/erpnext/stock/doctype/item/item.py @@ -860,7 +860,7 @@ class Item(WebsiteGenerator): rows = '' for docname, attr_list in not_included.items(): - link = "{0}".format(frappe.bold(_(docname))) + link = "{0}".format(frappe.bold(_(docname))) rows += table_row(link, body(attr_list)) error_description = _('The following deleted attributes exist in Variants but not in the Template. You can either delete the Variants or keep the attribute(s) in template.') diff --git a/erpnext/stock/doctype/item_price/item_price.js b/erpnext/stock/doctype/item_price/item_price.js index 2729f4b15e2..773fddcf96b 100644 --- a/erpnext/stock/doctype/item_price/item_price.js +++ b/erpnext/stock/doctype/item_price/item_price.js @@ -14,6 +14,6 @@ frappe.ui.form.on("Item Price", { frm.add_fetch("item_code", "stock_uom", "uom"); frm.set_df_property("bulk_import_help", "options", - '' + __("Import in Bulk") + ''); + '' + __("Import in Bulk") + ''); } }); diff --git a/erpnext/support/doctype/issue/issue.js b/erpnext/support/doctype/issue/issue.js index 940b940aba5..e58ac22d0b3 100644 --- a/erpnext/support/doctype/issue/issue.js +++ b/erpnext/support/doctype/issue/issue.js @@ -184,7 +184,7 @@ frappe.ui.form.on("Issue", { let url = window.location.href let arr = url.split("/"); let result = arr[0] + "//" + arr[2] - frappe.msgprint(`New issue created: ${r.message}`) + frappe.msgprint(`New issue created: ${r.message}`) frm.reload_doc(); dialog.hide(); }); diff --git a/erpnext/support/doctype/issue/issue.py b/erpnext/support/doctype/issue/issue.py index 62b39cced53..e4e7b2543b6 100644 --- a/erpnext/support/doctype/issue/issue.py +++ b/erpnext/support/doctype/issue/issue.py @@ -207,7 +207,7 @@ class Issue(Document): "comment_type": "Info", "reference_doctype": "Issue", "reference_name": replicated_issue.name, - "content": " - Split the Issue from {1}".format(self.name, frappe.bold(self.name)), + "content": " - Split the Issue from {1}".format(self.name, frappe.bold(self.name)), }).insert(ignore_permissions=True) return replicated_issue.name diff --git a/erpnext/utilities/bot.py b/erpnext/utilities/bot.py index 0e5e95d1a82..b2e74da9215 100644 --- a/erpnext/utilities/bot.py +++ b/erpnext/utilities/bot.py @@ -26,12 +26,12 @@ class FindItemBot(BotParser): for warehouse in warehouses: qty = frappe.db.get_value("Bin", {'item_code': item[0], 'warehouse': warehouse.name}, 'actual_qty') if qty: - out.append(_('{0} units of [{1}](#Form/Item/{1}) found in [{2}](#Form/Warehouse/{2})').format(qty, + out.append(_('{0} units of [{1}](/app/Form/Item/{1}) found in [{2}](/app/Form/Warehouse/{2})').format(qty, item[0], warehouse.name)) found = True if not found: - out.append(_('[{0}](#Form/Item/{0}) is out of stock').format(item[0])) + out.append(_('[{0}](/app/Form/Item/{0}) is out of stock').format(item[0])) return "\n\n".join(out) From 8cf3bdd044aa26559ee6e7c4c9a10a5ac86a258f Mon Sep 17 00:00:00 2001 From: Shivam Mishra Date: Wed, 18 Nov 2020 17:09:45 +0530 Subject: [PATCH 066/477] feat: add slider template --- .../web_template/hero_slider/hero_slider.html | 112 +++++++++ .../web_template/hero_slider/hero_slider.json | 230 ++++++++++++++++-- 2 files changed, 323 insertions(+), 19 deletions(-) diff --git a/erpnext/shopping_cart/web_template/hero_slider/hero_slider.html b/erpnext/shopping_cart/web_template/hero_slider/hero_slider.html index e69de29bb2d..e8b79743ab3 100644 --- a/erpnext/shopping_cart/web_template/hero_slider/hero_slider.html +++ b/erpnext/shopping_cart/web_template/hero_slider/hero_slider.html @@ -0,0 +1,112 @@ +{%- macro slide(image, title, subtitle, action, label, index, align="Left", theme="Dark") -%} +{%- set align_class = resolve_class({ + 'text-right': align == 'Right', + 'text-centre': align == 'Center', + 'text-left': align == 'Left', +}) -%} + +{%- set heading_class = resolve_class({ + 'text-white': theme == 'Dark', + '': theme == 'Light', +}) -%} + +{%- endmacro -%} + + + + + + \ No newline at end of file diff --git a/erpnext/shopping_cart/web_template/hero_slider/hero_slider.json b/erpnext/shopping_cart/web_template/hero_slider/hero_slider.json index a8ce2cd3cbb..496fc7995e2 100644 --- a/erpnext/shopping_cart/web_template/hero_slider/hero_slider.json +++ b/erpnext/shopping_cart/web_template/hero_slider/hero_slider.json @@ -5,35 +5,56 @@ "doctype": "Web Template", "fields": [ { - "__unsaved": 1, + "fieldname": "slider_name", + "fieldtype": "Data", + "label": "Slider Name", + "reqd": 1 + }, + { + "default": "1", + "fieldname": "show_indicators", + "fieldtype": "Check", + "label": "Show Indicators", + "reqd": 0 + }, + { + "default": "1", + "fieldname": "show_controls", + "fieldtype": "Check", + "label": "Show Controls", + "reqd": 0 + }, + { + "fieldname": "slide_1", + "fieldtype": "Section Break", + "label": "Slide 1", + "reqd": 0 + }, + { "fieldname": "slide_1_image", "fieldtype": "Attach Image", "label": "Image", "reqd": 0 }, { - "__unsaved": 1, "fieldname": "slide_1_title", "fieldtype": "Data", "label": "Title", "reqd": 0 }, { - "__unsaved": 1, "fieldname": "slide_1_subtitle", - "fieldtype": "Data", + "fieldtype": "Small Text", "label": "Subtitle", "reqd": 0 }, { - "__unsaved": 1, "fieldname": "slide_1_primary_action_label", "fieldtype": "Data", "label": "Primary Action Label", "reqd": 0 }, { - "__unsaved": 1, "fieldname": "slide_1_primary_action", "fieldtype": "Data", "label": "Primary Action", @@ -41,46 +62,73 @@ }, { "__unsaved": 1, + "fieldname": "slide_1_content_align", + "fieldtype": "Select", + "label": "Content Align", + "options": "Left\nCentre\nRight", + "reqd": 0 + }, + { + "__unsaved": 1, + "fieldname": "slide_1_theme", + "fieldtype": "Select", + "label": "Slide Theme", + "options": "Dark\nLight", + "reqd": 0 + }, + { "fieldname": "slide_2", "fieldtype": "Section Break", "label": "Slide 2", "reqd": 0 }, { - "__unsaved": 1, "fieldname": "slide_2_image", "fieldtype": "Attach Image", "label": "Image ", "reqd": 0 }, { - "__unsaved": 1, "fieldname": "slide_2_title", "fieldtype": "Data", "label": "Title ", "reqd": 0 }, { - "__unsaved": 1, "fieldname": "slide_2_subtitle", - "fieldtype": "Data", + "fieldtype": "Small Text", "label": "Subtitle ", "reqd": 0 }, { - "__unsaved": 1, "fieldname": "slide_2_primary_action_label", "fieldtype": "Data", "label": "Primary Action Label ", "reqd": 0 }, { - "__unsaved": 1, "fieldname": "slide_2_primary_action", "fieldtype": "Data", "label": "Primary Action ", "reqd": 0 }, + { + "__unsaved": 1, + "default": "Left", + "fieldname": "slide_2_content_align", + "fieldtype": "Select", + "label": "Content Align", + "options": "Left\nCentre\nRight", + "reqd": 0 + }, + { + "__unsaved": 1, + "fieldname": "slide_2_theme", + "fieldtype": "Select", + "label": "Slide Theme", + "options": "Dark\nLight", + "reqd": 0 + }, { "__islocal": 1, "__unsaved": 1, @@ -94,7 +142,7 @@ "__unsaved": 1, "fieldname": "slide_3_image", "fieldtype": "Attach Image", - "label": "Image ", + "label": "Image", "reqd": 0 }, { @@ -102,15 +150,15 @@ "__unsaved": 1, "fieldname": "slide_3_title", "fieldtype": "Data", - "label": "Title ", + "label": "Title", "reqd": 0 }, { "__islocal": 1, "__unsaved": 1, "fieldname": "slide_3_subtitle", - "fieldtype": "Data", - "label": "Subtitle ", + "fieldtype": "Small Text", + "label": "Subtitle", "reqd": 0 }, { @@ -118,7 +166,7 @@ "__unsaved": 1, "fieldname": "slide_3_primary_action_label", "fieldtype": "Data", - "label": "Primary Action Label ", + "label": "Primary Action Label", "reqd": 0 }, { @@ -126,12 +174,156 @@ "__unsaved": 1, "fieldname": "slide_3_primary_action", "fieldtype": "Data", - "label": "Primary Action ", + "label": "Primary Action", + "reqd": 0 + }, + { + "__islocal": 1, + "__unsaved": 1, + "fieldname": "slide_3_content_align", + "fieldtype": "Select", + "label": "Content Align", + "reqd": 0 + }, + { + "__islocal": 1, + "__unsaved": 1, + "fieldname": "slide_3_theme", + "fieldtype": "Select", + "label": "Slide Theme", + "reqd": 0 + }, + { + "__islocal": 1, + "__unsaved": 1, + "fieldname": "slide_4", + "fieldtype": "Section Break", + "label": "Slide 4", + "reqd": 0 + }, + { + "__islocal": 1, + "__unsaved": 1, + "fieldname": "slide_4_image", + "fieldtype": "Attach Image", + "label": "Image", + "reqd": 0 + }, + { + "__islocal": 1, + "__unsaved": 1, + "fieldname": "slide_4_title", + "fieldtype": "Data", + "label": "Title", + "reqd": 0 + }, + { + "__islocal": 1, + "__unsaved": 1, + "fieldname": "slide_4_subtitle", + "fieldtype": "Small Text", + "label": "Subtitle", + "reqd": 0 + }, + { + "__islocal": 1, + "__unsaved": 1, + "fieldname": "slide_4_primary_action_label", + "fieldtype": "Data", + "label": "Primary Action Label", + "reqd": 0 + }, + { + "__islocal": 1, + "__unsaved": 1, + "fieldname": "slide_4_primary_action", + "fieldtype": "Data", + "label": "Primary Action", + "reqd": 0 + }, + { + "__islocal": 1, + "__unsaved": 1, + "fieldname": "slide_4_content_align", + "fieldtype": "Select", + "label": "Content Align", + "reqd": 0 + }, + { + "__islocal": 1, + "__unsaved": 1, + "fieldname": "slide_4_theme", + "fieldtype": "Select", + "label": "Slide Theme", + "reqd": 0 + }, + { + "__islocal": 1, + "__unsaved": 1, + "fieldname": "slide_5", + "fieldtype": "Section Break", + "label": "Slide 5", + "reqd": 0 + }, + { + "__islocal": 1, + "__unsaved": 1, + "fieldname": "slide_5_image", + "fieldtype": "Attach Image", + "label": "Image", + "reqd": 0 + }, + { + "__islocal": 1, + "__unsaved": 1, + "fieldname": "slide_5_title", + "fieldtype": "Data", + "label": "Title", + "reqd": 0 + }, + { + "__islocal": 1, + "__unsaved": 1, + "fieldname": "slide_5_subtitle", + "fieldtype": "Small Text", + "label": "Subtitle", + "reqd": 0 + }, + { + "__islocal": 1, + "__unsaved": 1, + "fieldname": "slide_5_primary_action_label", + "fieldtype": "Data", + "label": "Primary Action Label", + "reqd": 0 + }, + { + "__islocal": 1, + "__unsaved": 1, + "fieldname": "slide_5_primary_action", + "fieldtype": "Data", + "label": "Primary Action", + "reqd": 0 + }, + { + "__islocal": 1, + "__unsaved": 1, + "fieldname": "slide_5_content_align", + "fieldtype": "Select", + "label": "Content Align", + "reqd": 0 + }, + { + "__islocal": 1, + "__unsaved": 1, + "fieldname": "slide_5_theme", + "fieldtype": "Select", + "label": "Slide Theme", "reqd": 0 } ], "idx": 0, - "modified": "2020-11-17 15:23:48.584868", + "modified": "2020-11-18 17:09:31.323198", "modified_by": "Administrator", "module": "Shopping Cart", "name": "Hero Slider", From 3bec3cfef16f33945440b334a3fa98d851b73ed2 Mon Sep 17 00:00:00 2001 From: Shivam Mishra Date: Wed, 18 Nov 2020 17:10:02 +0530 Subject: [PATCH 067/477] fix: don't use primary action for create --- erpnext/stock/doctype/item/item.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/stock/doctype/item/item.js b/erpnext/stock/doctype/item/item.js index faf4accc738..8b8b70031c5 100644 --- a/erpnext/stock/doctype/item/item.js +++ b/erpnext/stock/doctype/item/item.js @@ -81,7 +81,7 @@ frappe.ui.form.on("Item", { }, __('Create')); } - frm.page.set_inner_btn_group_as_primary(__('Create')); + // frm.page.set_inner_btn_group_as_primary(__('Create')); } if (frm.doc.variant_of) { frm.set_intro(__('This Item is a Variant of {0} (Template).', From ca3809831cb7f2d423f7289ed2df1f39bd24b03a Mon Sep 17 00:00:00 2001 From: Shivam Mishra Date: Wed, 18 Nov 2020 17:39:17 +0530 Subject: [PATCH 068/477] refactor: use h1 for slidetitle --- erpnext/shopping_cart/web_template/hero_slider/hero_slider.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/shopping_cart/web_template/hero_slider/hero_slider.html b/erpnext/shopping_cart/web_template/hero_slider/hero_slider.html index e8b79743ab3..3f0419e5642 100644 --- a/erpnext/shopping_cart/web_template/hero_slider/hero_slider.html +++ b/erpnext/shopping_cart/web_template/hero_slider/hero_slider.html @@ -14,7 +14,7 @@ {%- if title or subtitle -%}
{0}{1}
+ + + + + {2} +
{0}{1}
+ """.format(_("Item"), _("Unassigned Qty"), formatted_item_rows) + frappe.msgprint(msg, title=_("Insufficient Capacity"), is_minimizable=True, wide=True) return updated_table if updated_table else items From ccbd432b56b952e7d40003c15202279379338336 Mon Sep 17 00:00:00 2001 From: marination Date: Tue, 24 Nov 2020 12:47:13 +0530 Subject: [PATCH 090/477] chore: Added Tests - Fixed Sider Issues - Added perms to Putaway Rule - Added Unit Tests to check warehouse assignment --- .../doctype/putaway_rule/putaway_rule.js | 4 +- .../doctype/putaway_rule/putaway_rule.json | 27 +- .../doctype/putaway_rule/putaway_rule.py | 7 +- .../doctype/putaway_rule/test_putaway_rule.py | 257 +++++++++++++++++- 4 files changed, 287 insertions(+), 8 deletions(-) diff --git a/erpnext/stock/doctype/putaway_rule/putaway_rule.js b/erpnext/stock/doctype/putaway_rule/putaway_rule.js index 00a84b0e8d7..e0569206ef9 100644 --- a/erpnext/stock/doctype/putaway_rule/putaway_rule.js +++ b/erpnext/stock/doctype/putaway_rule/putaway_rule.js @@ -14,7 +14,7 @@ frappe.ui.form.on('Putaway Rule', { }, uom: function(frm) { - if(frm.doc.item_code && frm.doc.uom) { + if (frm.doc.item_code && frm.doc.uom) { return frm.call({ method: "erpnext.stock.get_item_details.get_conversion_factor", args: { @@ -22,7 +22,7 @@ frappe.ui.form.on('Putaway Rule', { uom: frm.doc.uom }, callback: function(r) { - if(!r.exc) { + if (!r.exc) { let stock_capacity = flt(frm.doc.capacity) * flt(r.message.conversion_factor); frm.set_value('conversion_factor', r.message.conversion_factor); frm.set_value('stock_capacity', stock_capacity); diff --git a/erpnext/stock/doctype/putaway_rule/putaway_rule.json b/erpnext/stock/doctype/putaway_rule/putaway_rule.json index d5ae68faf3e..e5b6b2b98fc 100644 --- a/erpnext/stock/doctype/putaway_rule/putaway_rule.json +++ b/erpnext/stock/doctype/putaway_rule/putaway_rule.json @@ -107,7 +107,7 @@ ], "index_web_pages_for_search": 1, "links": [], - "modified": "2020-11-23 16:53:48.387054", + "modified": "2020-11-23 19:25:50.948068", "modified_by": "Administrator", "module": "Stock", "name": "Putaway Rule", @@ -121,7 +121,30 @@ "print": 1, "read": 1, "report": 1, - "role": "System Manager", + "role": "Stock Manager", + "share": 1, + "write": 1 + }, + { + "create": 1, + "delete": 1, + "email": 1, + "export": 1, + "print": 1, + "read": 1, + "report": 1, + "role": "Stock User", + "share": 1, + "write": 1 + }, + { + "email": 1, + "export": 1, + "permlevel": 1, + "print": 1, + "read": 1, + "report": 1, + "role": "Stock Manager", "share": 1, "write": 1 } diff --git a/erpnext/stock/doctype/putaway_rule/putaway_rule.py b/erpnext/stock/doctype/putaway_rule/putaway_rule.py index cc58def33a3..73534aa14f1 100644 --- a/erpnext/stock/doctype/putaway_rule/putaway_rule.py +++ b/erpnext/stock/doctype/putaway_rule/putaway_rule.py @@ -17,6 +17,7 @@ class PutawayRule(Document): self.validate_warehouse_and_company() self.validate_capacity() self.validate_priority() + self.set_stock_capacity() def validate_duplicate_rule(self): existing_rule = frappe.db.exists("Putaway Rule", {"item_code": self.item_code, "warehouse": self.warehouse}) @@ -45,10 +46,13 @@ class PutawayRule(Document): if not self.capacity: frappe.throw(_("Capacity must be greater than 0"), title=_("Invalid")) + def set_stock_capacity(self): + self.stock_capacity = (flt(self.conversion_factor) or 1) * flt(self.capacity) + @frappe.whitelist() def get_ordered_putaway_rules(item_code, company): """Returns an ordered list of putaway rules to apply on an item.""" - rules = frappe.get_all("Putaway Rule", fields=["name", "stock_capacity", "priority", "warehouse"], + rules = frappe.get_all("Putaway Rule", fields=["name", "item_code", "stock_capacity", "priority", "warehouse"], filters={"item_code": item_code, "company": company, "disable": 0}, order_by="priority asc, capacity desc") @@ -86,6 +90,7 @@ def apply_putaway_rule(items, company): new_updated_table_row.name = '' new_updated_table_row.idx = 1 if not updated_table else flt(updated_table[-1].idx) + 1 new_updated_table_row.qty = to_allocate + new_updated_table_row.stock_qty = flt(to_allocate) * flt(new_updated_table_row.conversion_factor) new_updated_table_row.warehouse = warehouse updated_table.append(new_updated_table_row) diff --git a/erpnext/stock/doctype/putaway_rule/test_putaway_rule.py b/erpnext/stock/doctype/putaway_rule/test_putaway_rule.py index e262217f848..7b81784d5fa 100644 --- a/erpnext/stock/doctype/putaway_rule/test_putaway_rule.py +++ b/erpnext/stock/doctype/putaway_rule/test_putaway_rule.py @@ -2,9 +2,260 @@ # Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and Contributors # See license.txt from __future__ import unicode_literals - -# import frappe +import frappe import unittest +from frappe.utils import add_days, nowdate +from erpnext.stock.doctype.item.test_item import make_item +from erpnext.stock.get_item_details import get_conversion_factor +from erpnext.stock.doctype.warehouse.test_warehouse import create_warehouse +from erpnext.stock.doctype.stock_entry.test_stock_entry import make_stock_entry +from erpnext.buying.doctype.purchase_order.purchase_order import make_purchase_receipt +from erpnext.buying.doctype.purchase_order.test_purchase_order import create_purchase_order class TestPutawayRule(unittest.TestCase): - pass + def setUp(self): + if not frappe.db.exists("Item", "_Rice"): + make_item("_Rice", { + 'is_stock_item': 1, + 'has_batch_no' : 1, + 'create_new_batch': 1, + 'stock_uom': 'Kg' + }) + + if not frappe.db.exists("Warehouse", {"warehouse_name": "Rack 1"}): + create_warehouse("Rack 1") + if not frappe.db.exists("Warehouse", {"warehouse_name": "Rack 2"}): + create_warehouse("Rack 2") + + if not frappe.db.exists("UOM", "Bag"): + new_uom = frappe.new_doc("UOM") + new_uom.uom_name = "Bag" + new_uom.save() + + def test_putaway_rules_priority(self): + """Test if rule is applied by priority, irrespective of free space.""" + warehouse_1 = frappe.db.get_value("Warehouse", {"warehouse_name": "Rack 1"}) + warehouse_2 = frappe.db.get_value("Warehouse", {"warehouse_name": "Rack 2"}) + + rule_1 = create_putaway_rule(item_code="_Rice", warehouse=warehouse_1, capacity=200, + uom="Kg") + rule_2 = create_putaway_rule(item_code="_Rice", warehouse=warehouse_2, capacity=300, + uom="Kg", priority=2) + + po = create_purchase_order(item_code="_Rice", qty=300) + self.assertEqual(len(po.items), 1) + + pr = make_purchase_receipt(po.name) + self.assertEqual(len(pr.items), 2) + self.assertEqual(pr.items[0].qty, 200) + self.assertEqual(pr.items[0].warehouse, warehouse_1) + self.assertEqual(pr.items[1].qty, 100) + self.assertEqual(pr.items[1].warehouse, warehouse_2) + + po.cancel() + rule_1.delete() + rule_2.delete() + + def test_putaway_rules_with_same_priority(self): + """Test if rule with more free space is applied, + among two rules with same priority and capacity.""" + warehouse_1 = frappe.db.get_value("Warehouse", {"warehouse_name": "Rack 1"}) + warehouse_2 = frappe.db.get_value("Warehouse", {"warehouse_name": "Rack 2"}) + + rule_1 = create_putaway_rule(item_code="_Rice", warehouse=warehouse_1, capacity=500, + uom="Kg") + rule_2 = create_putaway_rule(item_code="_Rice", warehouse=warehouse_2, capacity=500, + uom="Kg") + + # out of 500 kg capacity, occupy 100 kg in warehouse_1 + stock_receipt = make_stock_entry(item_code="_Rice", target=warehouse_1, qty=100, basic_rate=50) + + po = create_purchase_order(item_code="_Rice", qty=700) + self.assertEqual(len(po.items), 1) + + pr = make_purchase_receipt(po.name) + self.assertEqual(len(pr.items), 2) + self.assertEqual(pr.items[0].qty, 500) + # warehouse_2 has 500 kg free space, it is given priority + self.assertEqual(pr.items[0].warehouse, warehouse_2) + self.assertEqual(pr.items[1].qty, 200) + # warehouse_1 has 400 kg free space, it is given less priority + self.assertEqual(pr.items[1].warehouse, warehouse_1) + + po.cancel() + stock_receipt.cancel() + rule_1.delete() + rule_2.delete() + + def test_putaway_rules_with_insufficient_capacity(self): + """Test if qty exceeding capacity, is handled.""" + warehouse_1 = frappe.db.get_value("Warehouse", {"warehouse_name": "Rack 1"}) + warehouse_2 = frappe.db.get_value("Warehouse", {"warehouse_name": "Rack 2"}) + + rule_1 = create_putaway_rule(item_code="_Rice", warehouse=warehouse_1, capacity=100, + uom="Kg") + rule_2 = create_putaway_rule(item_code="_Rice", warehouse=warehouse_2, capacity=200, + uom="Kg") + + po = create_purchase_order(item_code="_Rice", qty=350) + self.assertEqual(len(po.items), 1) + + pr = make_purchase_receipt(po.name) + + self.assertEqual(len(pr.items), 3) + self.assertEqual(pr.items[0].qty, 200) + self.assertEqual(pr.items[0].warehouse, warehouse_2) + self.assertEqual(pr.items[1].qty, 100) + self.assertEqual(pr.items[1].warehouse, warehouse_1) + # extra qty has no warehouse assigned + self.assertEqual(pr.items[2].qty, 50) + self.assertEqual(pr.items[2].warehouse, '') + + po.cancel() + rule_1.delete() + rule_2.delete() + + def test_putaway_rules_multi_uom(self): + """Test rules applied on uom other than stock uom.""" + item = frappe.get_doc("Item", "_Rice") + if not frappe.db.get_value("UOM Conversion Detail", {"parent": "_Rice", "uom": "Bag"}): + item.append("uoms", { + "uom": "Bag", + "conversion_factor": 1000 + }) + item.save() + + warehouse_1 = frappe.db.get_value("Warehouse", {"warehouse_name": "Rack 1"}) + warehouse_2 = frappe.db.get_value("Warehouse", {"warehouse_name": "Rack 2"}) + + rule_1 = create_putaway_rule(item_code="_Rice", warehouse=warehouse_1, capacity=3, + uom="Bag") + self.assertEqual(rule_1.stock_capacity, 3000) + rule_2 = create_putaway_rule(item_code="_Rice", warehouse=warehouse_2, capacity=4, + uom="Bag") + self.assertEqual(rule_2.stock_capacity, 4000) + + stock_receipt = make_stock_entry(item_code="_Rice", target=warehouse_1, qty=1000, basic_rate=50) + + po = create_purchase_order(item_code="_Rice", qty=6, do_not_save=True) + po.items[0].uom = "Bag" + po.save() + po.submit() + + self.assertEqual(po.items[0].stock_qty, 6000) + + pr = make_purchase_receipt(po.name) + self.assertEqual(len(pr.items), 2) + self.assertEqual(pr.items[0].qty, 4) + self.assertEqual(pr.items[0].warehouse, warehouse_2) + self.assertEqual(pr.items[1].qty, 2) + self.assertEqual(pr.items[1].warehouse, warehouse_1) + + po.cancel() + stock_receipt.cancel() + rule_1.delete() + rule_2.delete() + + def test_putaway_rules_multi_uom_whole_uom(self): + """Test if whole UOMs are handled.""" + item = frappe.get_doc("Item", "_Rice") + if not frappe.db.get_value("UOM Conversion Detail", {"parent": "_Rice", "uom": "Bag"}): + item.append("uoms", { + "uom": "Bag", + "conversion_factor": 1000 + }) + item.save() + + frappe.db.set_value("UOM", "Bag", "must_be_whole_number", 1) + + warehouse_1 = frappe.db.get_value("Warehouse", {"warehouse_name": "Rack 1"}) + warehouse_2 = frappe.db.get_value("Warehouse", {"warehouse_name": "Rack 2"}) + + # Putaway Rule in different UOM + rule_1 = create_putaway_rule(item_code="_Rice", warehouse=warehouse_1, capacity=1, + uom="Bag") + self.assertEqual(rule_1.stock_capacity, 1000) + # Putaway Rule in Stock UOM + rule_2 = create_putaway_rule(item_code="_Rice", warehouse=warehouse_2, capacity=500) + self.assertEqual(rule_2.stock_capacity, 500) + # total capacity is 1500 Kg + + po = create_purchase_order(item_code="_Rice", qty=2, do_not_save=True) + # PO for 2 Bags (2000 Kg) + po.items[0].uom = "Bag" + po.save() + po.submit() + + self.assertEqual(po.items[0].stock_qty, 2000) + + pr = make_purchase_receipt(po.name) + self.assertEqual(len(pr.items), 2) + self.assertEqual(pr.items[0].qty, 1) + self.assertEqual(pr.items[0].warehouse, warehouse_1) + # leftover space was for 500 kg (0.5 Bag) + # Since Bag is a whole UOM, 1(out of 2) Bag will be unassigned + self.assertEqual(pr.items[1].qty, 1) + self.assertEqual(pr.items[1].warehouse, '') + + po.cancel() + rule_1.delete() + rule_2.delete() + + def test_putaway_rules_with_reoccurring_item(self): + """Test rules on same item entered multiple times.""" + warehouse_1 = frappe.db.get_value("Warehouse", {"warehouse_name": "Rack 1"}) + warehouse_2 = frappe.db.get_value("Warehouse", {"warehouse_name": "Rack 2"}) + + rule_1 = create_putaway_rule(item_code="_Rice", warehouse=warehouse_1, capacity=200, + uom="Kg") + rule_2 = create_putaway_rule(item_code="_Rice", warehouse=warehouse_2, capacity=100, + uom="Kg", priority=2) + # total capacity is 300 Kg + + po = create_purchase_order(item_code="_Rice", qty=200, rate=100, do_not_save=True) + po.append("items", { + "item_code":"_Rice", + "warehouse": "_Test Warehouse - _TC", + "qty": 300, + "rate": 120, + "schedule_date": add_days(nowdate(), 1), + }) + po.save() + po.submit() + # PO for 500 Kg (two rows of same item, different rates) + self.assertEqual(len(po.items), 2) + + pr = make_purchase_receipt(po.name) + self.assertEqual(len(pr.items), 3) + self.assertEqual(pr.items[0].qty, 200) + self.assertEqual(pr.items[0].warehouse, warehouse_1) + # same rules applied to second item row + # with previous assignment considered + self.assertEqual(pr.items[1].qty, 100) + self.assertEqual(pr.items[1].warehouse, warehouse_2) + # unassigned 200 Kg + self.assertEqual(pr.items[2].qty, 200) + self.assertEqual(pr.items[2].warehouse, '') + + po.cancel() + rule_1.delete() + rule_2.delete() + +def create_putaway_rule(**args): + args = frappe._dict(args) + putaway = frappe.new_doc("Putaway Rule") + + putaway.disable = args.disable or 0 + putaway.company = args.company or "_Test Company" + putaway.item_code = args.item or args.item_code or "_Test Item" + putaway.warehouse = args.warehouse + putaway.priority = args.priority or 1 + putaway.capacity = args.capacity or 1 + putaway.stock_uom = frappe.db.get_value("Item", putaway.item_code, "stock_uom") + putaway.uom = args.uom or putaway.stock_uom + putaway.conversion_factor = get_conversion_factor(putaway.item_code, putaway.uom)['conversion_factor'] + + if not args.do_not_save: + putaway.save() + + return putaway \ No newline at end of file From 7f1d7894c204b3dcadca47453c4556af2a72b86f Mon Sep 17 00:00:00 2001 From: Saqib Ansari Date: Tue, 24 Nov 2020 14:04:49 +0530 Subject: [PATCH 091/477] fix: cannot find erpnext.payments --- erpnext/public/js/payment/payments.js | 239 ++++++++++++++++++++++++++ 1 file changed, 239 insertions(+) create mode 100644 erpnext/public/js/payment/payments.js diff --git a/erpnext/public/js/payment/payments.js b/erpnext/public/js/payment/payments.js new file mode 100644 index 00000000000..0d656bc1fb6 --- /dev/null +++ b/erpnext/public/js/payment/payments.js @@ -0,0 +1,239 @@ +// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors +// License: GNU General Public License v3. See license.txt + +erpnext.payments = erpnext.stock.StockController.extend({ + make_payment: function() { + var me = this; + + this.dialog = new frappe.ui.Dialog({ + title: 'Payment' + }); + + this.dialog.show(); + this.$body = this.dialog.body; + this.set_payment_primary_action(); + this.make_keyboard(); + this.select_text() + }, + + select_text: function(){ + var me = this; + $(this.$body).find('.form-control').click(function(){ + $(this).select(); + }) + }, + + set_payment_primary_action: function(){ + var me = this; + + this.dialog.set_primary_action(__("Submit"), function() { + // Allow no ZERO payment + $.each(me.frm.doc.payments, function (index, data) { + if (data.amount != 0) { + me.dialog.hide(); + me.submit_invoice(); + return; + } + }); + }) + }, + + make_keyboard: function(){ + var me = this; + $(this.$body).empty(); + $(this.$body).html(frappe.render_template('pos_payment', this.frm.doc)) + this.show_payment_details(); + this.bind_keyboard_event() + this.clear_amount() + }, + + make_multimode_payment: function(){ + var me = this; + + if(this.frm.doc.change_amount > 0){ + me.payment_val = me.doc.outstanding_amount + } + + this.payments = frappe.model.add_child(this.frm.doc, 'Multi Mode Payment', "payments"); + this.payments.mode_of_payment = this.dialog.fields_dict.mode_of_payment.get_value(); + this.payments.amount = flt(this.payment_val); + }, + + show_payment_details: function(){ + var me = this; + var multimode_payments = $(this.$body).find('.multimode-payments').empty(); + if(this.frm.doc.payments.length){ + $.each(this.frm.doc.payments, function(index, data){ + $(frappe.render_template('payment_details', { + mode_of_payment: data.mode_of_payment, + amount: data.amount, + idx: data.idx, + currency: me.frm.doc.currency, + type: data.type + })).appendTo(multimode_payments) + + if (data.type == 'Cash' && data.amount == me.frm.doc.paid_amount) { + me.idx = data.idx; + me.selected_mode = $(me.$body).find(repl("input[idx='%(idx)s']",{'idx': me.idx})); + me.highlight_selected_row(); + me.bind_amount_change_event(); + } + }) + }else{ + $("

No payment mode selected in pos profile

").appendTo(multimode_payments) + } + }, + + set_outstanding_amount: function(){ + this.selected_mode = $(this.$body).find(repl("input[idx='%(idx)s']",{'idx': this.idx})); + this.highlight_selected_row() + this.payment_val = 0.0 + if(this.frm.doc.outstanding_amount > 0 && flt(this.selected_mode.val()) == 0.0){ + //When user first time click on row + this.payment_val = flt(this.frm.doc.outstanding_amount / this.frm.doc.conversion_rate, precision("outstanding_amount")) + this.selected_mode.val(format_currency(this.payment_val, this.frm.doc.currency)); + this.update_payment_amount() + }else if(flt(this.selected_mode.val()) > 0){ + //If user click on existing row which has value + this.payment_val = flt(this.selected_mode.val()); + } + this.selected_mode.select() + this.bind_amount_change_event(); + }, + + bind_keyboard_event: function(){ + var me = this; + this.payment_val = ''; + this.bind_form_control_event(); + this.bind_numeric_keys_event(); + }, + + bind_form_control_event: function(){ + var me = this; + $(this.$body).find('.pos-payment-row').click(function(){ + me.idx = $(this).attr("idx"); + me.set_outstanding_amount() + }) + + $(this.$body).find('.form-control').click(function(){ + me.idx = $(this).attr("idx"); + me.set_outstanding_amount(); + me.update_paid_amount(true); + }) + + $(this.$body).find('.write_off_amount').change(function(){ + me.write_off_amount(flt($(this).val()), precision("write_off_amount")); + }) + + $(this.$body).find('.change_amount').change(function(){ + me.change_amount(flt($(this).val()), precision("change_amount")); + }) + }, + + highlight_selected_row: function(){ + var me = this; + var selected_row = $(this.$body).find(repl(".pos-payment-row[idx='%(idx)s']",{'idx': this.idx})); + $(this.$body).find('.pos-payment-row').removeClass('selected-payment-mode') + selected_row.addClass('selected-payment-mode') + $(this.$body).find('.amount').attr('disabled', true); + this.selected_mode.attr('disabled', false); + }, + + bind_numeric_keys_event: function(){ + var me = this; + $(this.$body).find('.pos-keyboard-key').click(function(){ + me.payment_val += $(this).text(); + me.selected_mode.val(format_currency(me.payment_val, me.frm.doc.currency)) + me.idx = me.selected_mode.attr("idx") + me.update_paid_amount() + }) + + $(this.$body).find('.delete-btn').click(function(){ + me.payment_val = cstr(flt(me.selected_mode.val())).slice(0, -1); + me.selected_mode.val(format_currency(me.payment_val, me.frm.doc.currency)); + me.idx = me.selected_mode.attr("idx") + me.update_paid_amount(); + }) + + }, + + bind_amount_change_event: function(){ + var me = this; + this.selected_mode.change(function(){ + me.payment_val = flt($(this).val()) || 0.0; + me.selected_mode.val(format_currency(me.payment_val, me.frm.doc.currency)) + me.idx = me.selected_mode.attr("idx") + me.update_payment_amount() + }) + }, + + clear_amount: function() { + var me = this; + $(this.$body).find('.clr').click(function(e){ + e.stopPropagation(); + me.idx = $(this).attr("idx"); + me.selected_mode = $(me.$body).find(repl("input[idx='%(idx)s']",{'idx': me.idx})); + me.payment_val = 0.0; + me.selected_mode.val(0.0); + me.highlight_selected_row(); + me.update_payment_amount(); + }) + }, + + write_off_amount: function(write_off_amount) { + var me = this; + + this.frm.doc.write_off_amount = flt(write_off_amount, precision("write_off_amount")); + this.frm.doc.base_write_off_amount = flt(this.frm.doc.write_off_amount * this.frm.doc.conversion_rate, + precision("base_write_off_amount")); + this.calculate_outstanding_amount(false) + this.show_amounts() + }, + + change_amount: function(change_amount) { + var me = this; + + this.frm.doc.change_amount = flt(change_amount, precision("change_amount")); + this.calculate_write_off_amount() + this.show_amounts() + }, + + update_paid_amount: function(update_write_off) { + var me = this; + if(in_list(['change_amount', 'write_off_amount'], this.idx)){ + var value = me.selected_mode.val(); + if(me.idx == 'change_amount'){ + me.change_amount(value) + } else{ + if(flt(value) == 0 && update_write_off && me.frm.doc.outstanding_amount > 0) { + value = flt(me.frm.doc.outstanding_amount / me.frm.doc.conversion_rate, precision(me.idx)); + } + me.write_off_amount(value) + } + }else{ + this.update_payment_amount() + } + }, + + update_payment_amount: function(){ + var me = this; + + $.each(this.frm.doc.payments, function(index, data){ + if(cint(me.idx) == cint(data.idx)){ + data.amount = flt(me.selected_mode.val(), 2) + } + }) + + this.calculate_outstanding_amount(false); + this.show_amounts(); + }, + + show_amounts: function(){ + var me = this; + $(this.$body).find(".write_off_amount").val(format_currency(this.frm.doc.write_off_amount, this.frm.doc.currency)); + $(this.$body).find('.paid_amount').text(format_currency(this.frm.doc.paid_amount, this.frm.doc.currency)); + $(this.$body).find('.change_amount').val(format_currency(this.frm.doc.change_amount, this.frm.doc.currency)) + $(this.$body).find('.outstanding_amount').text(format_currency(this.frm.doc.outstanding_amount, frappe.get_doc(":Company", this.frm.doc.company).default_currency)) + this.update_invoice(); + } +}) \ No newline at end of file From ac164c66ed3494368fcb074a5ec472b661914065 Mon Sep 17 00:00:00 2001 From: Saqib Ansari Date: Tue, 24 Nov 2020 16:09:11 +0530 Subject: [PATCH 092/477] perf: get recent transaction only when component is visible --- erpnext/selling/page/point_of_sale/pos_past_order_list.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/selling/page/point_of_sale/pos_past_order_list.js b/erpnext/selling/page/point_of_sale/pos_past_order_list.js index 166d9cf0cef..ec392313f5e 100644 --- a/erpnext/selling/page/point_of_sale/pos_past_order_list.js +++ b/erpnext/selling/page/point_of_sale/pos_past_order_list.js @@ -62,7 +62,7 @@ erpnext.PointOfSale.PastOrderList = class { options: `Draft\nPaid\nConsolidated\nReturn`, placeholder: __('Filter by invoice status'), onchange: function() { - me.refresh_list(me.search_field.get_value(), this.value); + if (me.$component.is(':visible')) me.refresh_list(); } }, parent: this.$component.find('.status-field'), From 68a49efc8098808386e234c380692791e926b2aa Mon Sep 17 00:00:00 2001 From: marination Date: Tue, 24 Nov 2020 17:38:34 +0530 Subject: [PATCH 093/477] chore: Added Putaway Rule to Desk Page and added Priority to List View --- erpnext/stock/desk_page/stock/stock.json | 4 ++-- erpnext/stock/doctype/putaway_rule/putaway_rule.json | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/erpnext/stock/desk_page/stock/stock.json b/erpnext/stock/desk_page/stock/stock.json index 390fcd91e3b..aa4fc28ec94 100644 --- a/erpnext/stock/desk_page/stock/stock.json +++ b/erpnext/stock/desk_page/stock/stock.json @@ -8,7 +8,7 @@ { "hidden": 0, "label": "Stock Transactions", - "links": "[\n {\n \"dependencies\": [\n \"Item\"\n ],\n \"label\": \"Material Request\",\n \"name\": \"Material Request\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Item\"\n ],\n \"label\": \"Stock Entry\",\n \"name\": \"Stock Entry\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Item\",\n \"Customer\"\n ],\n \"label\": \"Delivery Note\",\n \"name\": \"Delivery Note\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Item\",\n \"Supplier\"\n ],\n \"label\": \"Purchase Receipt\",\n \"name\": \"Purchase Receipt\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Item\"\n ],\n \"label\": \"Pick List\",\n \"name\": \"Pick List\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Delivery Trip\",\n \"name\": \"Delivery Trip\",\n \"type\": \"doctype\"\n }\n]" + "links": "[\n {\n \"dependencies\": [\n \"Item\"\n ],\n \"label\": \"Material Request\",\n \"name\": \"Material Request\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Item\"\n ],\n \"label\": \"Stock Entry\",\n \"name\": \"Stock Entry\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Item\",\n \"Customer\"\n ],\n \"label\": \"Delivery Note\",\n \"name\": \"Delivery Note\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Item\",\n \"Supplier\"\n ],\n \"label\": \"Purchase Receipt\",\n \"name\": \"Purchase Receipt\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Item\"\n ],\n \"label\": \"Pick List\",\n \"name\": \"Pick List\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Item\"\n ],\n \"label\": \"Putaway Rule\",\n \"name\": \"Putaway Rule\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Delivery Trip\",\n \"name\": \"Delivery Trip\",\n \"type\": \"doctype\"\n }\n]" }, { "hidden": 0, @@ -58,7 +58,7 @@ "idx": 0, "is_standard": 1, "label": "Stock", - "modified": "2020-10-07 18:40:17.130207", + "modified": "2020-11-24 15:43:20.496057", "modified_by": "Administrator", "module": "Stock", "name": "Stock", diff --git a/erpnext/stock/doctype/putaway_rule/putaway_rule.json b/erpnext/stock/doctype/putaway_rule/putaway_rule.json index e5b6b2b98fc..325e6f1355d 100644 --- a/erpnext/stock/doctype/putaway_rule/putaway_rule.json +++ b/erpnext/stock/doctype/putaway_rule/putaway_rule.json @@ -68,6 +68,7 @@ "default": "1", "fieldname": "priority", "fieldtype": "Int", + "in_list_view": 1, "label": "Priority" }, { @@ -107,7 +108,7 @@ ], "index_web_pages_for_search": 1, "links": [], - "modified": "2020-11-23 19:25:50.948068", + "modified": "2020-11-24 16:20:18.306671", "modified_by": "Administrator", "module": "Stock", "name": "Putaway Rule", From 2ed80656aa1be30fb735a85202ce71d62eba6763 Mon Sep 17 00:00:00 2001 From: marination Date: Tue, 24 Nov 2020 21:06:43 +0530 Subject: [PATCH 094/477] chore: Code Cleanup - Validate capacity < stock level only on new rule - Mention stock uom while validating capacity in new rule - Separate function to format and display unassigned items - Format ORM args --- .../doctype/putaway_rule/putaway_rule.py | 59 ++++++++++--------- 1 file changed, 32 insertions(+), 27 deletions(-) diff --git a/erpnext/stock/doctype/putaway_rule/putaway_rule.py b/erpnext/stock/doctype/putaway_rule/putaway_rule.py index 73534aa14f1..606e190458c 100644 --- a/erpnext/stock/doctype/putaway_rule/putaway_rule.py +++ b/erpnext/stock/doctype/putaway_rule/putaway_rule.py @@ -38,10 +38,13 @@ class PutawayRule(Document): title=_("Invalid Warehouse")) def validate_capacity(self): + stock_uom = frappe.db.get_value("Item", self.item_code, "stock_uom") balance_qty = get_stock_balance(self.item_code, self.warehouse, nowdate()) - if flt(self.stock_capacity) < flt(balance_qty): - frappe.throw(_("Warehouse Capacity for Item '{0}' must be greater than the existing stock level of {1} qty.") - .format(self.item_code, frappe.bold(balance_qty)), title=_("Insufficient Capacity")) + + if flt(self.stock_capacity) < flt(balance_qty) and self.get('__islocal'): + frappe.throw(_("Warehouse Capacity for Item '{0}' must be greater than the existing stock level of {1} {2}.") + .format(self.item_code, frappe.bold(balance_qty), stock_uom), + title=_("Insufficient Capacity")) if not self.capacity: frappe.throw(_("Capacity must be greater than 0"), title=_("Invalid")) @@ -49,10 +52,10 @@ class PutawayRule(Document): def set_stock_capacity(self): self.stock_capacity = (flt(self.conversion_factor) or 1) * flt(self.capacity) -@frappe.whitelist() def get_ordered_putaway_rules(item_code, company): """Returns an ordered list of putaway rules to apply on an item.""" - rules = frappe.get_all("Putaway Rule", fields=["name", "item_code", "stock_capacity", "priority", "warehouse"], + rules = frappe.get_all("Putaway Rule", + fields=["name", "item_code", "stock_capacity", "priority", "warehouse"], filters={"item_code": item_code, "company": company, "disable": 0}, order_by="priority asc, capacity desc") @@ -145,27 +148,29 @@ def apply_putaway_rule(items, company): items_not_accomodated.append([item.item_code, pending_qty]) if items_not_accomodated: - msg = _("The following Items, having Putaway Rules, could not be accomodated:") + "

" - formatted_item_rows = "" - - for entry in items_not_accomodated: - item_link = frappe.utils.get_link_to_form("Item", entry[0]) - formatted_item_rows += """ - {0} - {1} - """.format(item_link, frappe.bold(entry[1])) - - msg += """ - - - - - - {2} -
{0}{1}
- """.format(_("Item"), _("Unassigned Qty"), formatted_item_rows) - - frappe.msgprint(msg, title=_("Insufficient Capacity"), is_minimizable=True, wide=True) + format_unassigned_items_error(items_not_accomodated) return updated_table if updated_table else items - # TODO: check pricing rule, item tax impact \ No newline at end of file + +def format_unassigned_items_error(items_not_accomodated): + msg = _("The following Items, having Putaway Rules, could not be accomodated:") + "

" + formatted_item_rows = "" + + for entry in items_not_accomodated: + item_link = frappe.utils.get_link_to_form("Item", entry[0]) + formatted_item_rows += """ + {0} + {1} + """.format(item_link, frappe.bold(entry[1])) + + msg += """ + + + + + + {2} +
{0}{1}
+ """.format(_("Item"), _("Unassigned Qty"), formatted_item_rows) + + frappe.msgprint(msg, title=_("Insufficient Capacity"), is_minimizable=True, wide=True) \ No newline at end of file From 6c17b84caef6300f3872ce5b5db031e0ec7501fd Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Wed, 25 Nov 2020 13:42:16 +0530 Subject: [PATCH 095/477] fix: Replace raw query with ORM --- erpnext/controllers/queries.py | 34 +++++++++++----------------------- 1 file changed, 11 insertions(+), 23 deletions(-) diff --git a/erpnext/controllers/queries.py b/erpnext/controllers/queries.py index 015807d5639..e3aac9aba85 100644 --- a/erpnext/controllers/queries.py +++ b/erpnext/controllers/queries.py @@ -499,16 +499,17 @@ def get_filtered_dimensions(doctype, txt, searchfield, start, page_len, filters) from erpnext.accounts.doctype.accounting_dimension_filter.accounting_dimension_filter import get_dimension_filter_map dimension_filters = get_dimension_filter_map() dimension_filters = dimension_filters.get((filters.get('dimension'),filters.get('account'))) - group_condition = '' - company_condition = '' + query_filters = [] meta = frappe.get_meta(doctype) - if meta.is_tree: - group_condition = 'and is_group = 0 ' + query_filters.append(['is_group', '=', 0]) if meta.has_field('company'): - company_condition = 'and company = %s ' % (frappe.db.escape(filters.get('company'))) + query_filters.append(['company', '=', filters.get('company')]) + + if txt: + query_filters.append([searchfield, 'LIKE', "%%%s%%" % txt]) if dimension_filters: if dimension_filters['allow_or_restrict'] == 'Allow': @@ -521,25 +522,12 @@ def get_filtered_dimensions(doctype, txt, searchfield, start, page_len, filters) else: dimensions = tuple(dimension_filters['allowed_dimensions']) - result = frappe.db.sql("""SELECT name from `tab{doctype}` where - name {query_selector} {restricted} - {group_condition} {company_condition} - and {key} LIKE %(txt)s""".format( - doctype=doctype, query_selector=query_selector, restricted=dimensions, - group_condition = group_condition, - company_condition = company_condition, - key=searchfield), { - 'txt': '%' + txt + '%' - }) + query_filters.append(['name', query_selector, dimensions]) - return result - else: - return frappe.db.sql(""" - SELECT name from `tab{doctype}` where - {key} LIKE %(txt)s {group_condition} {company_condition}""" - .format(doctype=doctype, key=searchfield, - group_condition=group_condition, company_condition=company_condition), - { 'txt': '%' + txt + '%'}) + output = frappe.get_all(doctype, filters=query_filters) + result = [d.name for d in output] + + return [(d,) for d in set(result)] @frappe.whitelist() @frappe.validate_and_sanitize_search_inputs From df065f7044df675d161314992a2eaeec83971839 Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Wed, 25 Nov 2020 13:44:52 +0530 Subject: [PATCH 096/477] fix: form layout and naming fixes --- .../accounting_dimension.js | 1 - .../accounting_dimension.py | 4 +-- .../accounting_dimension_filter.js | 7 +++++- .../accounting_dimension_filter.json | 10 ++++---- .../accounting_dimension_filter.py | 25 +++++++++---------- 5 files changed, 25 insertions(+), 22 deletions(-) diff --git a/erpnext/accounts/doctype/accounting_dimension/accounting_dimension.js b/erpnext/accounts/doctype/accounting_dimension/accounting_dimension.js index 9a6c3893393..65c5ff1ceaf 100644 --- a/erpnext/accounts/doctype/accounting_dimension/accounting_dimension.js +++ b/erpnext/accounts/doctype/accounting_dimension/accounting_dimension.js @@ -2,7 +2,6 @@ // For license information, please see license.txt frappe.ui.form.on('Accounting Dimension', { - refresh: function(frm) { frm.set_query('document_type', () => { let invalid_doctypes = frappe.model.core_doctypes_list; diff --git a/erpnext/accounts/doctype/accounting_dimension/accounting_dimension.py b/erpnext/accounts/doctype/accounting_dimension/accounting_dimension.py index b9d4da289ee..52e9ff8b764 100644 --- a/erpnext/accounts/doctype/accounting_dimension/accounting_dimension.py +++ b/erpnext/accounts/doctype/accounting_dimension/accounting_dimension.py @@ -203,7 +203,7 @@ def get_dimension_with_children(doctype, dimension): return all_dimensions @frappe.whitelist() -def get_dimension_filters(with_costcenter_and_project=False): +def get_dimensions(with_cost_center_and_project=False): dimension_filters = frappe.db.sql(""" SELECT label, fieldname, document_type FROM `tabAccounting Dimension` @@ -214,7 +214,7 @@ def get_dimension_filters(with_costcenter_and_project=False): FROM `tabAccounting Dimension Detail` c, `tabAccounting Dimension` p WHERE c.parent = p.name""", as_dict=1) - if with_costcenter_and_project: + if with_cost_center_and_project: dimension_filters.extend([ { 'fieldname': 'cost_center', diff --git a/erpnext/accounts/doctype/accounting_dimension_filter/accounting_dimension_filter.js b/erpnext/accounts/doctype/accounting_dimension_filter/accounting_dimension_filter.js index f0362d31403..a2526e92c36 100644 --- a/erpnext/accounts/doctype/accounting_dimension_filter/accounting_dimension_filter.js +++ b/erpnext/accounts/doctype/accounting_dimension_filter/accounting_dimension_filter.js @@ -2,10 +2,15 @@ // For license information, please see license.txt frappe.ui.form.on('Accounting Dimension Filter', { + refresh: function(frm, cdt, cdn) { + if (frm.doc.accounting_dimension) { + frm.set_df_property('dimensions', 'label', frm.doc.accounting_dimension, cdn, 'dimension_value'); + } + }, onload: function(frm) { frm.set_query('applicable_on_account', 'accounts', function() { return { - filters : { + filters: { 'company': frm.doc.company } }; diff --git a/erpnext/accounts/doctype/accounting_dimension_filter/accounting_dimension_filter.json b/erpnext/accounts/doctype/accounting_dimension_filter/accounting_dimension_filter.json index c1190a395fe..7736b2dffb2 100644 --- a/erpnext/accounts/doctype/accounting_dimension_filter/accounting_dimension_filter.json +++ b/erpnext/accounts/doctype/accounting_dimension_filter/accounting_dimension_filter.json @@ -7,10 +7,10 @@ "engine": "InnoDB", "field_order": [ "accounting_dimension", - "allow_or_restrict", + "disabled", "column_break_2", "company", - "disabled", + "allow_or_restrict", "section_break_4", "accounts", "column_break_6", @@ -57,7 +57,7 @@ { "fieldname": "accounts", "fieldtype": "Table", - "label": "Accounts", + "label": "Applicable On Account", "options": "Applicable On Account", "reqd": 1, "show_days": 1, @@ -67,7 +67,7 @@ "depends_on": "eval:doc.accounting_dimension", "fieldname": "dimensions", "fieldtype": "Table", - "label": "Dimensions", + "label": "Applicable Dimension", "options": "Allowed Dimension", "reqd": 1, "show_days": 1, @@ -93,7 +93,7 @@ ], "index_web_pages_for_search": 1, "links": [], - "modified": "2020-11-16 17:27:40.292860", + "modified": "2020-11-24 12:34:42.458713", "modified_by": "Administrator", "module": "Accounts", "name": "Accounting Dimension Filter", diff --git a/erpnext/accounts/doctype/accounting_dimension_filter/accounting_dimension_filter.py b/erpnext/accounts/doctype/accounting_dimension_filter/accounting_dimension_filter.py index 440073b7230..6aef9caa747 100644 --- a/erpnext/accounts/doctype/accounting_dimension_filter/accounting_dimension_filter.py +++ b/erpnext/accounts/doctype/accounting_dimension_filter/accounting_dimension_filter.py @@ -29,19 +29,18 @@ class AccountingDimensionFilter(Document): account.idx, frappe.bold(account.applicable_on_account), frappe.bold(self.accounting_dimension))) def get_dimension_filter_map(): - filters = frappe.db.sql( - """ SELECT - a.applicable_on_account, d.dimension_value, p.accounting_dimension, - p.allow_or_restrict, a.is_mandatory - FROM - `tabApplicable On Account` a, `tabAllowed Dimension` d, - `tabAccounting Dimension Filter` p - WHERE - p.name = a.parent - AND p.disabled = 0 - AND p.name = d.parent - - """, as_dict=1) + filters = frappe.db.sql(""" + SELECT + a.applicable_on_account, d.dimension_value, p.accounting_dimension, + p.allow_or_restrict, a.is_mandatory + FROM + `tabApplicable On Account` a, `tabAllowed Dimension` d, + `tabAccounting Dimension Filter` p + WHERE + p.name = a.parent + AND p.disabled = 0 + AND p.name = d.parent + """, as_dict=1) dimension_filter_map = {} From 4e991fe668daafe8488560fddef806cbc540373d Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Wed, 25 Nov 2020 13:46:07 +0530 Subject: [PATCH 097/477] fix: Define specific exceptions and fix tests --- .../test_accounting_dimension_filter.py | 27 ++++++++++++------- erpnext/accounts/doctype/gl_entry/gl_entry.py | 8 +++--- erpnext/exceptions.py | 2 ++ 3 files changed, 23 insertions(+), 14 deletions(-) diff --git a/erpnext/accounts/doctype/accounting_dimension_filter/test_accounting_dimension_filter.py b/erpnext/accounts/doctype/accounting_dimension_filter/test_accounting_dimension_filter.py index 801786b6e96..f67e1de4044 100644 --- a/erpnext/accounts/doctype/accounting_dimension_filter/test_accounting_dimension_filter.py +++ b/erpnext/accounts/doctype/accounting_dimension_filter/test_accounting_dimension_filter.py @@ -6,7 +6,8 @@ from __future__ import unicode_literals import frappe import unittest from erpnext.accounts.doctype.sales_invoice.test_sales_invoice import create_sales_invoice -from erpnext.accounts.doctype.accounting_dimension.test_accounting_dimension import create_dimension +from erpnext.accounts.doctype.accounting_dimension.test_accounting_dimension import create_dimension, disable_dimension +from erpnext.exceptions import InvalidAccountDimension, MandatoryDimension class TestAccountingDimensionFilter(unittest.TestCase): def setUp(self): @@ -16,19 +17,25 @@ class TestAccountingDimensionFilter(unittest.TestCase): def test_allowed_dimension_validation(self): si = create_sales_invoice(do_not_save=1) si.items[0].cost_center = 'Main - _TC' + si.location = 'Block 1' si.save() - self.assertRaises(frappe.ValidationError, si.submit) + self.assertRaises(InvalidAccountDimension, si.submit) def test_mandatory_dimension_validation(self): si = create_sales_invoice(do_not_save=1) - si.items[0].location = '' + si.location = 'Block 1' + + # Test with no department for Sales Account + si.items[0].department = '' + si.items[0].cost_center = '_Test Cost Center 2 - _TC' si.save() - self.assertRaises(frappe.ValidationError, si.submit) + self.assertRaises(MandatoryDimension, si.submit) def tearDown(self): disable_dimension_filter() + disable_dimension() def create_accounting_dimension_filter(): if not frappe.db.get_value('Accounting Dimension Filter', @@ -52,10 +59,10 @@ def create_accounting_dimension_filter(): doc.save() if not frappe.db.get_value('Accounting Dimension Filter', - {'accounting_dimension': 'Location'}): + {'accounting_dimension': 'Department'}): frappe.get_doc({ 'doctype': 'Accounting Dimension Filter', - 'accounting_dimension': 'Location', + 'accounting_dimension': 'Department', 'allow_or_restrict': 'Allow', 'company': '_Test Company', 'accounts': [{ @@ -63,12 +70,12 @@ def create_accounting_dimension_filter(): 'is_mandatory': 1 }], 'dimensions': [{ - 'accounting_dimension': 'Location', - 'dimension_value': 'Block 1' + 'accounting_dimension': 'Department', + 'dimension_value': '_Test Department - _TC' }] }).insert() else: - doc = frappe.get_doc('Accounting Dimension Filter', {'accounting_dimension': 'Location'}) + doc = frappe.get_doc('Accounting Dimension Filter', {'accounting_dimension': 'Department'}) doc.disabled = 0 doc.save() @@ -77,6 +84,6 @@ def disable_dimension_filter(): doc.disabled = 1 doc.save() - doc = frappe.get_doc('Accounting Dimension Filter', {'accounting_dimension': 'Location'}) + doc = frappe.get_doc('Accounting Dimension Filter', {'accounting_dimension': 'Department'}) doc.disabled = 1 doc.save() diff --git a/erpnext/accounts/doctype/gl_entry/gl_entry.py b/erpnext/accounts/doctype/gl_entry/gl_entry.py index b3caf6a82e8..f586de82e35 100644 --- a/erpnext/accounts/doctype/gl_entry/gl_entry.py +++ b/erpnext/accounts/doctype/gl_entry/gl_entry.py @@ -11,7 +11,7 @@ from frappe.model.meta import get_field_precision from erpnext.accounts.party import validate_party_gle_currency, validate_party_frozen_disabled from erpnext.accounts.utils import get_account_currency from erpnext.accounts.utils import get_fiscal_year -from erpnext.exceptions import InvalidAccountCurrency +from erpnext.exceptions import InvalidAccountCurrency, InvalidAccountDimension, MandatoryDimension from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import get_checks_for_pl_and_bs_accounts from erpnext.accounts.doctype.accounting_dimension_filter.accounting_dimension_filter import get_dimension_filter_map from six import iteritems @@ -101,16 +101,16 @@ class GLEntry(Document): if self.account == account: if value['is_mandatory'] and not self.get(dimension): frappe.throw(_("{0} is mandatory for account {1}").format( - frappe.bold(frappe.unscrub(dimension)), frappe.bold(self.account))) + frappe.bold(frappe.unscrub(dimension)), frappe.bold(self.account)), MandatoryDimension) if value['allow_or_restrict'] == 'Allow': if self.get(dimension) and self.get(dimension) not in value['allowed_dimensions']: frappe.throw(_("Invalid value {0} for account {1}").format( - frappe.bold(self.get(dimension)), frappe.bold(self.account))) + frappe.bold(self.get(dimension)), frappe.bold(self.account)), InvalidAccountDimension) else: if self.get(dimension) and self.get(dimension) in value['allowed_dimensions']: frappe.throw(_("Invalid value {0} for account {1}").format( - frappe.bold(self.get(dimension)), frappe.bold(self.account))) + frappe.bold(self.get(dimension)), frappe.bold(self.account)), InvalidAccountDimension) def check_pl_account(self): if self.is_opening=='Yes' and \ diff --git a/erpnext/exceptions.py b/erpnext/exceptions.py index d92af5d7227..dcf3d6bad1a 100644 --- a/erpnext/exceptions.py +++ b/erpnext/exceptions.py @@ -6,3 +6,5 @@ class PartyFrozen(frappe.ValidationError): pass class InvalidAccountCurrency(frappe.ValidationError): pass class InvalidCurrency(frappe.ValidationError): pass class PartyDisabled(frappe.ValidationError):pass +class InvalidAccountDimension(frappe.ValidationError): pass +class MandatoryDimension(frappe.ValidationError): pass From 92b3449789689fc71dbd2ea3df7a2f7553cb0dec Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Wed, 25 Nov 2020 14:01:57 +0530 Subject: [PATCH 098/477] fix: Label changes --- .../accounts/doctype/allowed_dimension/allowed_dimension.json | 3 +-- .../doctype/applicable_on_account/applicable_on_account.json | 4 ++-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/erpnext/accounts/doctype/allowed_dimension/allowed_dimension.json b/erpnext/accounts/doctype/allowed_dimension/allowed_dimension.json index c2d34b3b7e6..7fe2a3c647e 100644 --- a/erpnext/accounts/doctype/allowed_dimension/allowed_dimension.json +++ b/erpnext/accounts/doctype/allowed_dimension/allowed_dimension.json @@ -22,7 +22,6 @@ "fieldname": "dimension_value", "fieldtype": "Dynamic Link", "in_list_view": 1, - "label": "Applicable Dimension", "options": "accounting_dimension", "show_days": 1, "show_seconds": 1 @@ -31,7 +30,7 @@ "index_web_pages_for_search": 1, "istable": 1, "links": [], - "modified": "2020-11-16 17:41:50.422843", + "modified": "2020-11-23 09:56:19.744200", "modified_by": "Administrator", "module": "Accounts", "name": "Allowed Dimension", diff --git a/erpnext/accounts/doctype/applicable_on_account/applicable_on_account.json b/erpnext/accounts/doctype/applicable_on_account/applicable_on_account.json index 5c809515c29..95e98d0b673 100644 --- a/erpnext/accounts/doctype/applicable_on_account/applicable_on_account.json +++ b/erpnext/accounts/doctype/applicable_on_account/applicable_on_account.json @@ -13,7 +13,7 @@ "fieldname": "applicable_on_account", "fieldtype": "Link", "in_list_view": 1, - "label": "Applicable On Account", + "label": "Accounts", "options": "Account", "reqd": 1, "show_days": 1, @@ -33,7 +33,7 @@ "index_web_pages_for_search": 1, "istable": 1, "links": [], - "modified": "2020-11-16 13:36:59.129672", + "modified": "2020-11-22 19:55:13.324136", "modified_by": "Administrator", "module": "Accounts", "name": "Applicable On Account", From 6b9dda5f3eb7af999456ffbf4cc69c255c2f09b2 Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Wed, 25 Nov 2020 14:49:10 +0530 Subject: [PATCH 099/477] fix: Move filter setup to doctype controllers --- erpnext/accounts/doctype/budget/budget.js | 7 +- .../doctype/journal_entry/journal_entry.js | 5 + .../loyalty_program/loyalty_program.js | 7 + .../opening_invoice_creation_tool.js | 3 + .../doctype/payment_entry/payment_entry.js | 4 + .../doctype/pos_profile/pos_profile.js | 3 + .../purchase_invoice/purchase_invoice.js | 7 + .../doctype/sales_invoice/sales_invoice.js | 8 +- .../doctype/shipping_rule/shipping_rule.js | 10 ++ erpnext/assets/doctype/asset/asset.js | 7 + .../asset_value_adjustment.js | 10 ++ .../doctype/purchase_order/purchase_order.js | 8 +- .../doctype/fee_schedule/fee_schedule.js | 7 + .../doctype/fee_structure/fee_structure.js | 8 + erpnext/education/doctype/fees/fees.js | 7 + .../hr/doctype/expense_claim/expense_claim.js | 20 ++- .../doctype/payroll_entry/payroll_entry.js | 5 + erpnext/public/js/controllers/transaction.js | 4 + .../public/js/utils/dimension_tree_filter.js | 164 ++++++++---------- .../doctype/delivery_note/delivery_note.js | 4 +- .../material_request/material_request.js | 7 + .../purchase_receipt/purchase_receipt.js | 3 + .../stock/doctype/stock_entry/stock_entry.js | 4 + .../stock_reconciliation.js | 7 + 24 files changed, 218 insertions(+), 101 deletions(-) diff --git a/erpnext/accounts/doctype/budget/budget.js b/erpnext/accounts/doctype/budget/budget.js index 1b793982472..e60bc60475e 100644 --- a/erpnext/accounts/doctype/budget/budget.js +++ b/erpnext/accounts/doctype/budget/budget.js @@ -1,5 +1,6 @@ // Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors // For license information, please see license.txt +frappe.provide("erpnext.accounts.dimensions"); frappe.ui.form.on('Budget', { onload: function(frm) { @@ -11,7 +12,7 @@ frappe.ui.form.on('Budget', { is_group: 0 } } - }) + }); frm.set_query("monthly_distribution", function() { return { @@ -19,7 +20,9 @@ frappe.ui.form.on('Budget', { fiscal_year: frm.doc.fiscal_year } } - }) + }); + + erpnext.accounts.dimensions.setup_dimension_filters(frm, frm.doctype); }, refresh: function(frm) { diff --git a/erpnext/accounts/doctype/journal_entry/journal_entry.js b/erpnext/accounts/doctype/journal_entry/journal_entry.js index d60a7b76cc4..37b03f3f0e0 100644 --- a/erpnext/accounts/doctype/journal_entry/journal_entry.js +++ b/erpnext/accounts/doctype/journal_entry/journal_entry.js @@ -120,6 +120,8 @@ frappe.ui.form.on("Journal Entry", { } } }); + + erpnext.accounts.dimensions.update_dimension(frm, frm.doctype); }, voucher_type: function(frm){ @@ -197,6 +199,7 @@ erpnext.accounts.JournalEntry = frappe.ui.form.Controller.extend({ this.load_defaults(); this.setup_queries(); this.setup_balance_formatter(); + erpnext.accounts.dimensions.setup_dimension_filters(this.frm, this.frm.doctype); }, onload_post_render: function() { @@ -397,6 +400,8 @@ erpnext.accounts.JournalEntry = frappe.ui.form.Controller.extend({ } } cur_frm.cscript.update_totals(doc); + + erpnext.accounts.dimensions.copy_dimension_from_first_row(this.frm, cdt, cdn, 'accounts'); }, }); diff --git a/erpnext/accounts/doctype/loyalty_program/loyalty_program.js b/erpnext/accounts/doctype/loyalty_program/loyalty_program.js index 0d2b8cbf151..f90f86728de 100644 --- a/erpnext/accounts/doctype/loyalty_program/loyalty_program.js +++ b/erpnext/accounts/doctype/loyalty_program/loyalty_program.js @@ -1,6 +1,8 @@ // Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors // For license information, please see license.txt +frappe.provide("erpnext.accounts.dimensions"); + frappe.ui.form.on('Loyalty Program', { setup: function(frm) { var help_content = @@ -47,11 +49,16 @@ frappe.ui.form.on('Loyalty Program', { }); frm.set_value("company", frappe.defaults.get_user_default("Company")); + erpnext.accounts.dimensions.setup_dimension_filters(frm, frm.doctype); }, refresh: function(frm) { if (frm.doc.loyalty_program_type === "Single Tier Program" && frm.doc.collection_rules.length > 1) { frappe.throw(__("Please select the Multiple Tier Program type for more than one collection rules.")); } + }, + + company: function(frm) { + erpnext.accounts.dimensions.update_dimension(frm, frm.doctype); } }); diff --git a/erpnext/accounts/doctype/opening_invoice_creation_tool/opening_invoice_creation_tool.js b/erpnext/accounts/doctype/opening_invoice_creation_tool/opening_invoice_creation_tool.js index 3ce5701823e..c087980798c 100644 --- a/erpnext/accounts/doctype/opening_invoice_creation_tool/opening_invoice_creation_tool.js +++ b/erpnext/accounts/doctype/opening_invoice_creation_tool/opening_invoice_creation_tool.js @@ -36,6 +36,8 @@ frappe.ui.form.on('Opening Invoice Creation Tool', { frm.dashboard.show_progress(data.title, (data.count / data.total) * 100, data.message); frm.page.set_indicator(__('In Progress'), 'orange'); }); + + erpnext.accounts.dimensions.setup_dimension_filters(frm, frm.doctype); }, refresh: function(frm) { @@ -100,6 +102,7 @@ frappe.ui.form.on('Opening Invoice Creation Tool', { } }) } + erpnext.accounts.dimensions.update_dimension(frm, frm.doctype); }, invoice_type: function(frm) { diff --git a/erpnext/accounts/doctype/payment_entry/payment_entry.js b/erpnext/accounts/doctype/payment_entry/payment_entry.js index ea5487d5754..4318aea2bda 100644 --- a/erpnext/accounts/doctype/payment_entry/payment_entry.js +++ b/erpnext/accounts/doctype/payment_entry/payment_entry.js @@ -1,6 +1,7 @@ // Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors // For license information, please see license.txt {% include "erpnext/public/js/controllers/accounts.js" %} +frappe.provide("erpnext.accounts.dimensions"); frappe.ui.form.on('Payment Entry', { onload: function(frm) { @@ -8,6 +9,8 @@ frappe.ui.form.on('Payment Entry', { if (!frm.doc.paid_from) frm.set_value("paid_from_account_currency", null); if (!frm.doc.paid_to) frm.set_value("paid_to_account_currency", null); } + + erpnext.accounts.dimensions.setup_dimension_filters(frm, frm.doctype); }, setup: function(frm) { @@ -158,6 +161,7 @@ frappe.ui.form.on('Payment Entry', { company: function(frm) { frm.events.hide_unhide_fields(frm); frm.events.set_dynamic_labels(frm); + erpnext.accounts.dimensions.update_dimension(frm, frm.doctype); }, contact_person: function(frm) { diff --git a/erpnext/accounts/doctype/pos_profile/pos_profile.js b/erpnext/accounts/doctype/pos_profile/pos_profile.js index 558e21c13aa..668cf016d35 100755 --- a/erpnext/accounts/doctype/pos_profile/pos_profile.js +++ b/erpnext/accounts/doctype/pos_profile/pos_profile.js @@ -48,6 +48,8 @@ frappe.ui.form.on('POS Profile', { } }; }); + + erpnext.accounts.dimensions.setup_dimension_filters(frm, frm.doctype); }, refresh: function(frm) { @@ -58,6 +60,7 @@ frappe.ui.form.on('POS Profile', { company: function(frm) { frm.trigger("toggle_display_account_head"); + erpnext.accounts.dimensions.update_dimension(frm, frm.doctype); }, toggle_display_account_head: function(frm) { diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js index 3c07ee75cbb..3fa6ee76e61 100644 --- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js +++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js @@ -16,6 +16,11 @@ erpnext.accounts.PurchaseInvoice = erpnext.buying.BuyingController.extend({ }); } }, + + company: function() { + erpnext.accounts.dimensions.update_dimension(this.frm, this.frm.doctype); + }, + onload: function() { this._super(); @@ -31,6 +36,8 @@ erpnext.accounts.PurchaseInvoice = erpnext.buying.BuyingController.extend({ if (this.frm.doc.supplier && this.frm.doc.__islocal) { this.frm.trigger('supplier'); } + + erpnext.accounts.dimensions.setup_dimension_filters(this.frm, this.frm.doctype); }, refresh: function(doc) { diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.js b/erpnext/accounts/doctype/sales_invoice/sales_invoice.js index e27bd2fa3ac..b89cecfab5e 100644 --- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.js +++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.js @@ -5,14 +5,17 @@ cur_frm.pformat.print_heading = 'Invoice'; {% include 'erpnext/selling/sales_common.js' %}; - - frappe.provide("erpnext.accounts"); + + erpnext.accounts.SalesInvoiceController = erpnext.selling.SellingController.extend({ setup: function(doc) { this.setup_posting_date_time_check(); this._super(doc); }, + company: function() { + erpnext.accounts.dimensions.update_dimension(this.frm, this.frm.doctype); + }, onload: function() { var me = this; this._super(); @@ -33,6 +36,7 @@ erpnext.accounts.SalesInvoiceController = erpnext.selling.SellingController.exte me.frm.refresh_fields(); } erpnext.queries.setup_warehouse_query(this.frm); + erpnext.accounts.dimensions.setup_dimension_filters(this.frm, this.frm.doctype); }, refresh: function(doc, dt, dn) { diff --git a/erpnext/accounts/doctype/shipping_rule/shipping_rule.js b/erpnext/accounts/doctype/shipping_rule/shipping_rule.js index 7cfbfed1388..8e4b806f02d 100644 --- a/erpnext/accounts/doctype/shipping_rule/shipping_rule.js +++ b/erpnext/accounts/doctype/shipping_rule/shipping_rule.js @@ -1,7 +1,17 @@ // Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors // License: GNU General Public License v3. See license.txt +frappe.provide('erpnext.accounts.dimensions'); + frappe.ui.form.on('Shipping Rule', { + onload: function(frm) { + erpnext.accounts.dimensions.setup_dimension_filters(frm, frm.doctype); + }, + + company: function(frm) { + erpnext.accounts.dimensions.update_dimension(frm, frm.doctype); + }, + refresh: function(frm) { frm.set_query("account", function() { return { diff --git a/erpnext/assets/doctype/asset/asset.js b/erpnext/assets/doctype/asset/asset.js index 3af3948fac6..e9c8aff678d 100644 --- a/erpnext/assets/doctype/asset/asset.js +++ b/erpnext/assets/doctype/asset/asset.js @@ -2,6 +2,7 @@ // For license information, please see license.txt frappe.provide("erpnext.asset"); +frappe.provide("erpnext.accounts.dimensions"); frappe.ui.form.on('Asset', { onload: function(frm) { @@ -31,6 +32,12 @@ frappe.ui.form.on('Asset', { } }; }); + + erpnext.accounts.dimensions.setup_dimension_filters(frm, frm.doctype); + }, + + company: function(frm) { + erpnext.accounts.dimensions.update_dimension(frm, frm.doctype); }, setup: function(frm) { diff --git a/erpnext/assets/doctype/asset_value_adjustment/asset_value_adjustment.js b/erpnext/assets/doctype/asset_value_adjustment/asset_value_adjustment.js index a6e6974c48d..79c8861bcdc 100644 --- a/erpnext/assets/doctype/asset_value_adjustment/asset_value_adjustment.js +++ b/erpnext/assets/doctype/asset_value_adjustment/asset_value_adjustment.js @@ -1,6 +1,8 @@ // Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors // For license information, please see license.txt +frappe.provide("erpnext.accounts.dimensions"); + frappe.ui.form.on('Asset Value Adjustment', { setup: function(frm) { frm.add_fetch('company', 'cost_center', 'cost_center'); @@ -13,11 +15,19 @@ frappe.ui.form.on('Asset Value Adjustment', { } }); }, + onload: function(frm) { if(frm.is_new() && frm.doc.asset) { frm.trigger("set_current_asset_value"); } + + erpnext.accounts.dimensions.setup_dimension_filters(frm, frm.doctype); }, + + company: function(frm) { + erpnext.accounts.dimensions.update_dimension(frm, frm.doctype); + }, + asset: function(frm) { frm.trigger("set_current_asset_value"); }, diff --git a/erpnext/buying/doctype/purchase_order/purchase_order.js b/erpnext/buying/doctype/purchase_order/purchase_order.js index 2f52a9e0355..92e2708eab6 100644 --- a/erpnext/buying/doctype/purchase_order/purchase_order.js +++ b/erpnext/buying/doctype/purchase_order/purchase_order.js @@ -2,7 +2,7 @@ // License: GNU General Public License v3. See license.txt frappe.provide("erpnext.buying"); - +frappe.provide("erpnext.accounts.dimensions"); {% include 'erpnext/public/js/controllers/buying.js' %}; frappe.ui.form.on("Purchase Order", { @@ -30,6 +30,10 @@ frappe.ui.form.on("Purchase Order", { }, + company: function(frm) { + erpnext.accounts.dimensions.update_dimension(frm, frm.doctype); + }, + onload: function(frm) { set_schedule_date(frm); if (!frm.doc.transaction_date){ @@ -39,6 +43,8 @@ frappe.ui.form.on("Purchase Order", { erpnext.queries.setup_queries(frm, "Warehouse", function() { return erpnext.queries.warehouse(frm.doc); }); + + erpnext.accounts.dimensions.setup_dimension_filters(frm, frm.doctype); } }); diff --git a/erpnext/education/doctype/fee_schedule/fee_schedule.js b/erpnext/education/doctype/fee_schedule/fee_schedule.js index 75dd4469e84..65b5fa6cf23 100644 --- a/erpnext/education/doctype/fee_schedule/fee_schedule.js +++ b/erpnext/education/doctype/fee_schedule/fee_schedule.js @@ -1,6 +1,7 @@ // Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors // For license information, please see license.txt +frappe.provide("erpnext.accounts.dimensions"); frappe.ui.form.on('Fee Schedule', { setup: function(frm) { frm.add_fetch('fee_structure', 'receivable_account', 'receivable_account'); @@ -8,6 +9,10 @@ frappe.ui.form.on('Fee Schedule', { frm.add_fetch('fee_structure', 'cost_center', 'cost_center'); }, + company: function(frm) { + erpnext.accounts.dimensions.update_dimension(frm, frm.doctype); + }, + onload: function(frm) { frm.set_query('receivable_account', function(doc) { return { @@ -50,6 +55,8 @@ frappe.ui.form.on('Fee Schedule', { } } }); + + erpnext.accounts.dimensions.setup_dimension_filters(frm, frm.doctype); }, refresh: function(frm) { diff --git a/erpnext/education/doctype/fee_structure/fee_structure.js b/erpnext/education/doctype/fee_structure/fee_structure.js index b331c6d3c0e..310c4105f47 100644 --- a/erpnext/education/doctype/fee_structure/fee_structure.js +++ b/erpnext/education/doctype/fee_structure/fee_structure.js @@ -1,6 +1,8 @@ // Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors // For license information, please see license.txt +frappe.provide("erpnext.accounts.dimensions"); + frappe.ui.form.on('Fee Structure', { setup: function(frm) { frm.add_fetch('company', 'default_receivable_account', 'receivable_account'); @@ -8,6 +10,10 @@ frappe.ui.form.on('Fee Structure', { frm.add_fetch('company', 'cost_center', 'cost_center'); }, + company: function(frm) { + erpnext.accounts.dimensions.update_dimension(frm, frm.doctype); + }, + onload: function(frm) { frm.set_query('academic_term', function() { return { @@ -35,6 +41,8 @@ frappe.ui.form.on('Fee Structure', { } }; }); + + erpnext.accounts.dimensions.setup_dimension_filters(frm, frm.doctype); }, refresh: function(frm) { diff --git a/erpnext/education/doctype/fees/fees.js b/erpnext/education/doctype/fees/fees.js index aaf42b47517..433bd64d2fb 100644 --- a/erpnext/education/doctype/fees/fees.js +++ b/erpnext/education/doctype/fees/fees.js @@ -1,6 +1,7 @@ // Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors // For license information, please see license.txt +frappe.provide("erpnext.accounts.dimensions"); frappe.ui.form.on("Fees", { setup: function(frm) { @@ -9,6 +10,10 @@ frappe.ui.form.on("Fees", { frm.add_fetch("fee_structure", "cost_center", "cost_center"); }, + company: function(frm) { + erpnext.accounts.dimensions.update_dimension(frm, frm.doctype); + }, + onload: function(frm){ frm.set_query("academic_term",function(){ return{ @@ -45,6 +50,8 @@ frappe.ui.form.on("Fees", { if (!frm.doc.posting_date) { frm.doc.posting_date = frappe.datetime.get_today(); } + + erpnext.accounts.dimensions.setup_dimension_filters(frm, frm.doctype); }, refresh: function(frm) { diff --git a/erpnext/hr/doctype/expense_claim/expense_claim.js b/erpnext/hr/doctype/expense_claim/expense_claim.js index cbafd7d3ac0..e399b22f90f 100644 --- a/erpnext/hr/doctype/expense_claim/expense_claim.js +++ b/erpnext/hr/doctype/expense_claim/expense_claim.js @@ -2,11 +2,21 @@ // License: GNU General Public License v3. See license.txt frappe.provide("erpnext.hr"); +frappe.provide("erpnext.accounts.dimensions"); -erpnext.hr.ExpenseClaimController = frappe.ui.form.Controller.extend({ - expense_type: function(doc, cdt, cdn) { +frappe.ui.form.on('Expense Claim', { + onload: function(frm) { + erpnext.accounts.dimensions.setup_dimension_filters(frm, frm.doctype); + }, + company: function(frm) { + erpnext.accounts.dimensions.update_dimension(frm, frm.doctype); + }, +}); + +frappe.ui.form.on('Expense Claim Detail', { + expense_type: function(frm, cdt, cdn) { var d = locals[cdt][cdn]; - if(!doc.company) { + if(!frm.doc.company) { d.expense_type = ""; frappe.msgprint(__("Please set the Company")); this.frm.refresh_fields(); @@ -20,7 +30,7 @@ erpnext.hr.ExpenseClaimController = frappe.ui.form.Controller.extend({ method: "erpnext.hr.doctype.expense_claim.expense_claim.get_expense_claim_account_and_cost_center", args: { "expense_claim_type": d.expense_type, - "company": doc.company + "company": frm.doc.company }, callback: function(r) { if (r.message) { @@ -32,8 +42,6 @@ erpnext.hr.ExpenseClaimController = frappe.ui.form.Controller.extend({ } }); -$.extend(cur_frm.cscript, new erpnext.hr.ExpenseClaimController({frm: cur_frm})); - cur_frm.add_fetch('employee', 'company', 'company'); cur_frm.add_fetch('employee','employee_name','employee_name'); cur_frm.add_fetch('expense_type','description','description'); diff --git a/erpnext/payroll/doctype/payroll_entry/payroll_entry.js b/erpnext/payroll/doctype/payroll_entry/payroll_entry.js index d32fdbcaf16..410840771cf 100644 --- a/erpnext/payroll/doctype/payroll_entry/payroll_entry.js +++ b/erpnext/payroll/doctype/payroll_entry/payroll_entry.js @@ -3,6 +3,8 @@ var in_progress = false; +frappe.provide("erpnext.accounts.dimensions"); + frappe.ui.form.on('Payroll Entry', { onload: function (frm) { if (!frm.doc.posting_date) { @@ -17,6 +19,8 @@ frappe.ui.form.on('Payroll Entry', { } }; }); + + erpnext.accounts.dimensions.setup_dimension_filters(frm, frm.doctype); }, refresh: function(frm) { @@ -122,6 +126,7 @@ frappe.ui.form.on('Payroll Entry', { company: function (frm) { frm.events.clear_employee_table(frm); + erpnext.accounts.dimensions.update_dimension(frm, frm.doctype); }, department: function (frm) { diff --git a/erpnext/public/js/controllers/transaction.js b/erpnext/public/js/controllers/transaction.js index ec6b3dc6df1..3f293782b41 100644 --- a/erpnext/public/js/controllers/transaction.js +++ b/erpnext/public/js/controllers/transaction.js @@ -1,6 +1,8 @@ // Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors // License: GNU General Public License v3. See license.txt +frappe.provide('erpnext.accounts.dimensions'); + erpnext.TransactionController = erpnext.taxes_and_totals.extend({ setup: function() { this._super(); @@ -106,6 +108,8 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({ if(!item.warehouse && frm.doc.set_warehouse) { item.warehouse = frm.doc.set_warehouse; } + + erpnext.accounts.dimensions.copy_dimension_from_first_row(frm, cdt, cdn, 'items'); } }); diff --git a/erpnext/public/js/utils/dimension_tree_filter.js b/erpnext/public/js/utils/dimension_tree_filter.js index 7a42fb56148..c79736d0e19 100644 --- a/erpnext/public/js/utils/dimension_tree_filter.js +++ b/erpnext/public/js/utils/dimension_tree_filter.js @@ -1,60 +1,79 @@ -frappe.provide('frappe.ui.form'); -let default_dimensions = {}; +frappe.provide('erpnext.accounts'); -let doctypes_with_dimensions = ["GL Entry", "Sales Invoice", "Purchase Invoice", "Payment Entry", "Asset", - "Expense Claim", "Stock Entry", "Budget", "Payroll Entry", "Delivery Note", "Shipping Rule", "Loyalty Program", - "Fee Schedule", "Fee Structure", "Stock Reconciliation", "Travel Request", "Fees", "POS Profile", "Opening Invoice Creation Tool", - "Subscription", "Purchase Order", "Journal Entry", "Material Request", "Purchase Receipt", "Asset", "Asset Value Adjustment"]; - -let child_docs = ["Sales Invoice Item", "Purchase Invoice Item", "Purchase Order Item", "Journal Entry Account", - "Material Request Item", "Delivery Note Item", "Purchase Receipt Item", "Stock Entry Detail", "Payment Entry Deduction", - "Landed Cost Item", "Asset Value Adjustment", "Opening Invoice Creation Tool Item", "Subscription Plan", - "Sales Taxes and Charges", "Purchase Taxes and Charges"]; - -frappe.call({ - method: "erpnext.accounts.doctype.accounting_dimension.accounting_dimension.get_dimension_filters", - args: { - 'with_costcenter_and_project': true +erpnext.accounts.dimensions = { + setup_dimension_filters(frm, doctype) { + this.accounting_dimensions = []; + this.default_dimensions = {}; + this.fetch_custom_dimensions(frm, doctype); }, - callback: function(r) { - erpnext.dimension_filters = r.message[0]; - default_dimensions = r.message[1]; - } -}); -doctypes_with_dimensions.forEach((doctype) => { - frappe.ui.form.on(doctype, { - onload: function(frm) { - erpnext.dimension_filters.forEach((dimension) => { - frappe.model.with_doctype(dimension['document_type'], () => { - let parent_fields = []; - frappe.meta.get_docfields(doctype).forEach((df) => { - if (df.fieldtype === 'Link' && df.options === 'Account') { - parent_fields.push(df.fieldname); - } else if (df.fieldtype === 'Table') { - setup_child_filters(frm, df.options, df.fieldname, dimension['fieldname']); - } + fetch_custom_dimensions(frm, doctype) { + let me = this; + frappe.call({ + method: "erpnext.accounts.doctype.accounting_dimension.accounting_dimension.get_dimensions", + args: { + 'with_cost_center_and_project': true + }, + callback: function(r) { + me.accounting_dimensions = r.message[0]; + me.default_dimensions = r.message[1]; + me.setup_filters(frm, doctype); + } + }); + }, - setup_account_filters(frm, dimension['fieldname'], parent_fields); - }); + setup_filters(frm, doctype) { + this.accounting_dimensions.forEach((dimension) => { + frappe.model.with_doctype(dimension['document_type'], () => { + let parent_fields = []; + frappe.meta.get_docfields(doctype).forEach((df) => { + if (df.fieldtype === 'Link' && df.options === 'Account') { + parent_fields.push(df.fieldname); + } else if (df.fieldtype === 'Table') { + this.setup_child_filters(frm, df.options, df.fieldname, dimension['fieldname']); + } + + if (frappe.meta.has_field(doctype, dimension['fieldname'])) { + this.setup_account_filters(frm, dimension['fieldname'], parent_fields); + } }); }); - }, + }); + }, - company: function(frm) { - if(frm.doc.company && (Object.keys(default_dimensions || {}).length > 0) - && default_dimensions[frm.doc.company]) { - frm.trigger('update_dimension'); - } - }, + setup_child_filters(frm, doctype, parentfield, dimension) { + let fields = []; - update_dimension: function(frm) { - erpnext.dimension_filters.forEach((dimension) => { + if (frappe.meta.has_field(doctype, dimension)) { + frappe.model.with_doctype(doctype, () => { + frappe.meta.get_docfields(doctype).forEach((df) => { + if (df.fieldtype === 'Link' && df.options === 'Account') { + fields.push(df.fieldname); + } + }); + + frm.set_query(dimension, parentfield, function(doc, cdt, cdn) { + let row = locals[cdt][cdn]; + return erpnext.queries.get_filtered_dimensions(row, fields, dimension, doc.company); + }); + }); + } + }, + + setup_account_filters(frm, dimension, fields) { + frm.set_query(dimension, function(doc) { + return erpnext.queries.get_filtered_dimensions(doc, fields, dimension, doc.company); + }); + }, + + update_dimension(frm, doctype) { + if (this.accounting_dimensions) { + this.accounting_dimensions.forEach((dimension) => { if(frm.is_new()) { - if(frm.doc.company && Object.keys(default_dimensions || {}).length > 0 - && default_dimensions[frm.doc.company]) { + if(frm.doc.company && Object.keys(this.default_dimensions || {}).length > 0 + && this.default_dimensions[frm.doc.company]) { - let default_dimension = default_dimensions[frm.doc.company][dimension['fieldname']]; + let default_dimension = this.default_dimensions[frm.doc.company][dimension['fieldname']]; if(default_dimension) { if (frappe.meta.has_field(doctype, dimension['fieldname'])) { @@ -69,47 +88,14 @@ doctypes_with_dimensions.forEach((doctype) => { } }); } - }); -}); + }, -child_docs.forEach((doctype) => { - frappe.ui.form.on(doctype, { - items_add: function(frm, cdt, cdn) { - copy_dimension(frm, cdt, cdn, "items"); - }, - - accounts_add: function(frm, cdt, cdn) { - copy_dimension(frm, cdt, cdn, "accounts"); + copy_dimension_from_first_row(frm, cdt, cdn, fieldname) { + if (frappe.meta.has_field(frm.doctype, fieldname)) { + this.accounting_dimensions.forEach((dimension) => { + let row = frappe.get_doc(cdt, cdn); + frm.script_manager.copy_from_first_row(fieldname, row, [dimension['fieldname']]); + }); } - }); -}); - -let copy_dimension = function(frm, cdt, cdn, fieldname) { - erpnext.dimension_filters.forEach((dimension) => { - let row = frappe.get_doc(cdt, cdn); - frm.script_manager.copy_from_first_row(fieldname, row, [dimension['fieldname']]); - }); -}; - -let setup_child_filters = function(frm, doctype, parentfield, dimension) { - let fields = []; - - frappe.model.with_doctype(doctype, () => { - frappe.meta.get_docfields(doctype).forEach((df) => { - if (df.fieldtype === 'Link' && df.options === 'Account') { - fields.push(df.fieldname); - } - }); - - frm.set_query(dimension, parentfield, function(doc, cdt, cdn) { - let row = locals[cdt][cdn]; - return erpnext.queries.get_filtered_dimensions(row, fields, dimension, doc.company); - }); - }); -}; - -let setup_account_filters = function(frm, dimension, fields) { - frm.set_query(dimension, function(doc) { - return erpnext.queries.get_filtered_dimensions(doc, fields, dimension, doc.company); - }); -}; \ No newline at end of file + } +} \ No newline at end of file diff --git a/erpnext/stock/doctype/delivery_note/delivery_note.js b/erpnext/stock/doctype/delivery_note/delivery_note.js index 251a26a592e..ccc719c26d0 100644 --- a/erpnext/stock/doctype/delivery_note/delivery_note.js +++ b/erpnext/stock/doctype/delivery_note/delivery_note.js @@ -7,6 +7,7 @@ cur_frm.add_fetch('customer', 'tax_id', 'tax_id'); frappe.provide("erpnext.stock"); frappe.provide("erpnext.stock.delivery_note"); +frappe.provide("erpnext.accounts.dimensions"); frappe.ui.form.on("Delivery Note", { setup: function(frm) { @@ -75,7 +76,7 @@ frappe.ui.form.on("Delivery Note", { } }); - + erpnext.accounts.dimensions.setup_dimension_filters(frm, frm.doctype); }, print_without_amount: function(frm) { @@ -305,6 +306,7 @@ frappe.ui.form.on('Delivery Note', { company: function(frm) { frm.trigger("unhide_account_head"); + erpnext.accounts.dimensions.update_dimension(frm, frm.doctype); }, unhide_account_head: function(frm) { diff --git a/erpnext/stock/doctype/material_request/material_request.js b/erpnext/stock/doctype/material_request/material_request.js index 01edd99e9d2..527b0d3ea93 100644 --- a/erpnext/stock/doctype/material_request/material_request.js +++ b/erpnext/stock/doctype/material_request/material_request.js @@ -2,6 +2,7 @@ // License: GNU General Public License v3. See license.txt // eslint-disable-next-line +frappe.provide("erpnext.accounts.dimensions"); {% include 'erpnext/public/js/controllers/buying.js' %}; frappe.ui.form.on('Material Request', { @@ -66,6 +67,12 @@ frappe.ui.form.on('Material Request', { filters: {'company': doc.company} }; }); + + erpnext.accounts.dimensions.setup_dimension_filters(frm, frm.doctype); + }, + + company: function(frm) { + erpnext.accounts.dimensions.update_dimension(frm, frm.doctype); }, onload_post_render: function(frm) { diff --git a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.js b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.js index bc1d81d3565..d998729c479 100644 --- a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.js +++ b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.js @@ -46,6 +46,8 @@ frappe.ui.form.on("Purchase Receipt", { erpnext.queries.setup_queries(frm, "Warehouse", function() { return erpnext.queries.warehouse(frm.doc); }); + + erpnext.accounts.dimensions.setup_dimension_filters(frm, frm.doctype); }, refresh: function(frm) { @@ -75,6 +77,7 @@ frappe.ui.form.on("Purchase Receipt", { company: function(frm) { frm.trigger("toggle_display_account_head"); + erpnext.accounts.dimensions.update_dimension(frm, frm.doctype); }, toggle_display_account_head: function(frm) { diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.js b/erpnext/stock/doctype/stock_entry/stock_entry.js index 91217582ca4..80f18a63f56 100644 --- a/erpnext/stock/doctype/stock_entry/stock_entry.js +++ b/erpnext/stock/doctype/stock_entry/stock_entry.js @@ -1,6 +1,7 @@ // Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors // License: GNU General Public License v3. See license.txt frappe.provide("erpnext.stock"); +frappe.provide("erpnext.accounts.dimensions"); frappe.ui.form.on('Stock Entry', { setup: function(frm) { @@ -97,6 +98,7 @@ frappe.ui.form.on('Stock Entry', { }); frm.add_fetch("bom_no", "inspection_required", "inspection_required"); + erpnext.accounts.dimensions.setup_dimension_filters(frm, frm.doctype); }, setup_quality_inspection: function(frm) { @@ -312,6 +314,8 @@ frappe.ui.form.on('Stock Entry', { frm.set_value("letter_head", company_doc.default_letter_head); } frm.trigger("toggle_display_account_head"); + + erpnext.accounts.dimensions.update_dimension(frm, frm.doctype); } }, diff --git a/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.js b/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.js index e2121fce3f2..be9404d9c8c 100644 --- a/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.js +++ b/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.js @@ -2,6 +2,7 @@ // License: GNU General Public License v3. See license.txt frappe.provide("erpnext.stock"); +frappe.provide("erpnext.accounts.dimensions") frappe.ui.form.on("Stock Reconciliation", { onload: function(frm) { @@ -26,6 +27,12 @@ frappe.ui.form.on("Stock Reconciliation", { if (!frm.doc.expense_account) { frm.trigger("set_expense_account"); } + + erpnext.accounts.dimensions.setup_dimension_filters(frm, frm.doctype); + }, + + company: function(frm) { + erpnext.accounts.dimensions.update_dimension(frm, frm.doctype); }, refresh: function(frm) { From 1087d97c03a0ea9973ffc0d70472c4a3fcac8654 Mon Sep 17 00:00:00 2001 From: marination Date: Thu, 26 Nov 2020 10:45:44 +0530 Subject: [PATCH 100/477] feat: Warehouse Capacity Summary - Added Page Warehouse Capacity Summary - Added Page to Desk and Putaway List View - Reused Item Dashboard/Stock Balance page render code - Added naming series to Putaway Rule --- erpnext/public/build.json | 4 +- erpnext/stock/dashboard/item_dashboard.js | 75 ++++++++--- .../dashboard/warehouse_capacity_dashboard.py | 69 ++++++++++ erpnext/stock/desk_page/stock/stock.json | 4 +- erpnext/stock/doctype/item/item.js | 5 +- .../purchase_receipt/purchase_receipt.json | 9 +- .../doctype/putaway_rule/putaway_rule.json | 8 +- .../doctype/putaway_rule/putaway_rule_list.js | 10 +- .../stock/page/stock_balance/stock_balance.js | 3 + .../warehouse_capacity_summary/__init__.py | 0 .../warehouse_capacity_summary.html | 40 ++++++ .../warehouse_capacity_summary.js | 120 ++++++++++++++++++ .../warehouse_capacity_summary.json | 26 ++++ .../warehouse_capacity_summary_header.html | 19 +++ 14 files changed, 367 insertions(+), 25 deletions(-) create mode 100644 erpnext/stock/dashboard/warehouse_capacity_dashboard.py create mode 100644 erpnext/stock/page/warehouse_capacity_summary/__init__.py create mode 100644 erpnext/stock/page/warehouse_capacity_summary/warehouse_capacity_summary.html create mode 100644 erpnext/stock/page/warehouse_capacity_summary/warehouse_capacity_summary.js create mode 100644 erpnext/stock/page/warehouse_capacity_summary/warehouse_capacity_summary.json create mode 100644 erpnext/stock/page/warehouse_capacity_summary/warehouse_capacity_summary_header.html diff --git a/erpnext/public/build.json b/erpnext/public/build.json index 2695502269a..8b18a1fcfb5 100644 --- a/erpnext/public/build.json +++ b/erpnext/public/build.json @@ -54,6 +54,8 @@ "js/item-dashboard.min.js": [ "stock/dashboard/item_dashboard.html", "stock/dashboard/item_dashboard_list.html", - "stock/dashboard/item_dashboard.js" + "stock/dashboard/item_dashboard.js", + "stock/page/warehouse_capacity_summary/warehouse_capacity_summary.html", + "stock/page/warehouse_capacity_summary/warehouse_capacity_summary_header.html" ] } diff --git a/erpnext/stock/dashboard/item_dashboard.js b/erpnext/stock/dashboard/item_dashboard.js index 9bd03d45cbb..abc286fcc6e 100644 --- a/erpnext/stock/dashboard/item_dashboard.js +++ b/erpnext/stock/dashboard/item_dashboard.js @@ -24,6 +24,16 @@ erpnext.stock.ItemDashboard = Class.extend({ handle_move_add($(this), "Add") }); + this.content.on('click', '.btn-edit', function() { + let item = unescape($(this).attr('data-item')); + let warehouse = unescape($(this).attr('data-warehouse')); + let company = unescape($(this).attr('data-company')); + frappe.db.get_value('Putaway Rule', + {'item_code': item, 'warehouse': warehouse, 'company': company}, 'name', (r) => { + frappe.set_route("Form", "Putaway Rule", r.name); + }); + }); + function handle_move_add(element, action) { let item = unescape(element.attr('data-item')); let warehouse = unescape(element.attr('data-warehouse')); @@ -59,7 +69,7 @@ erpnext.stock.ItemDashboard = Class.extend({ // more this.content.find('.btn-more').on('click', function() { - me.start += 20; + me.start += this.page_length; me.refresh(); }); @@ -69,33 +79,41 @@ erpnext.stock.ItemDashboard = Class.extend({ this.before_refresh(); } + let args = { + item_code: this.item_code, + warehouse: this.warehouse, + parent_warehouse: this.parent_warehouse, + item_group: this.item_group, + company: this.company, + start: this.start, + sort_by: this.sort_by, + sort_order: this.sort_order + } + var me = this; frappe.call({ - method: 'erpnext.stock.dashboard.item_dashboard.get_data', - args: { - item_code: this.item_code, - warehouse: this.warehouse, - item_group: this.item_group, - start: this.start, - sort_by: this.sort_by, - sort_order: this.sort_order, - }, + method: this.method, + args: args, callback: function(r) { me.render(r.message); } }); }, render: function(data) { - if(this.start===0) { + if (this.start===0) { this.max_count = 0; this.result.empty(); } + if (this.page_name === "warehouse-capacity-summary") { + var context = this.get_capacity_dashboard_data(data); + } else { + var context = this.get_item_dashboard_data(data, this.max_count, true); + } - var context = this.get_item_dashboard_data(data, this.max_count, true); this.max_count = this.max_count; // show more button - if(data && data.length===21) { + if (data && data.length===(this.page_length + 1)) { this.content.find('.more').removeClass('hidden'); // remove the last element @@ -106,12 +124,17 @@ erpnext.stock.ItemDashboard = Class.extend({ // If not any stock in any warehouses provide a message to end user if (context.data.length > 0) { - $(frappe.render_template('item_dashboard_list', context)).appendTo(this.result); + this.content.find('.result').css('text-align', 'unset'); + $(frappe.render_template(this.template, context)).appendTo(this.result); } else { - var message = __("Currently no stock available in any warehouse"); - $(` ${message} `).appendTo(this.result); + var message = __("No Stock Available Currently"); + this.content.find('.result').css('text-align', 'center'); + + $(`
+ ${message}
`).appendTo(this.result); } }, + get_item_dashboard_data: function(data, max_count, show_item) { if(!max_count) max_count = 0; if(!data) data = []; @@ -128,7 +151,7 @@ erpnext.stock.ItemDashboard = Class.extend({ d.total_reserved, max_count); }); - var can_write = 0; + let can_write = 0; if(frappe.boot.user.can_write.indexOf("Stock Entry")>=0){ can_write = 1; } @@ -139,6 +162,24 @@ erpnext.stock.ItemDashboard = Class.extend({ can_write:can_write, show_item: show_item || false } + }, + + get_capacity_dashboard_data: function(data) { + if(!data) data = []; + + data.forEach(function(d) { + d.color = d.percent_occupied >=80 ? "#f8814f" : "#2490ef"; + }); + + let can_write = 0; + if(frappe.boot.user.can_write.indexOf("Putaway Rule")>=0){ + can_write = 1; + } + + return { + data: data, + can_write: can_write, + } } }) diff --git a/erpnext/stock/dashboard/warehouse_capacity_dashboard.py b/erpnext/stock/dashboard/warehouse_capacity_dashboard.py new file mode 100644 index 00000000000..ab573e566ac --- /dev/null +++ b/erpnext/stock/dashboard/warehouse_capacity_dashboard.py @@ -0,0 +1,69 @@ +from __future__ import unicode_literals + +import frappe +from frappe.model.db_query import DatabaseQuery +from frappe.utils import nowdate +from frappe.utils import flt +from erpnext.stock.utils import get_stock_balance + +@frappe.whitelist() +def get_data(item_code=None, warehouse=None, parent_warehouse=None, + company=None, start=0, sort_by="stock_capacity", sort_order="desc"): + """Return data to render the warehouse capacity dashboard.""" + filters = get_filters(item_code, warehouse, parent_warehouse, company) + + no_permission, filters = get_warehouse_filter_based_on_permissions(filters) + if no_permission: + return [] + + capacity_data = get_warehouse_capacity_data(filters, start) + + asc_desc = -1 if sort_order == "desc" else 1 + capacity_data = sorted(capacity_data, key = lambda i: (i[sort_by] * asc_desc)) + + return capacity_data + +def get_filters(item_code=None, warehouse=None, parent_warehouse=None, + company=None): + filters = [['disable', '=', 0]] + if item_code: + filters.append(['item_code', '=', item_code]) + if warehouse: + filters.append(['warehouse', '=', warehouse]) + if company: + filters.append(['company', '=', company]) + if parent_warehouse: + lft, rgt = frappe.db.get_value("Warehouse", parent_warehouse, ["lft", "rgt"]) + warehouses = frappe.db.sql_list(""" + select name from `tabWarehouse` + where lft >=%s and rgt<=%s + """, (lft, rgt)) + filters.append(['warehouse', 'in', warehouses]) + return filters + +def get_warehouse_filter_based_on_permissions(filters): + try: + # check if user has any restrictions based on user permissions on warehouse + if DatabaseQuery('Warehouse', user=frappe.session.user).build_match_conditions(): + filters.append(['warehouse', 'in', [w.name for w in frappe.get_list('Warehouse')]]) + return False, filters + except frappe.PermissionError: + # user does not have access on warehouse + return True, [] + +def get_warehouse_capacity_data(filters, start): + capacity_data = frappe.db.get_all('Putaway Rule', + fields=['item_code', 'warehouse','stock_capacity', 'company'], + filters=filters, + limit_start=start, + limit_page_length='11' + ) + + for entry in capacity_data: + balance_qty = get_stock_balance(entry.item_code, entry.warehouse, nowdate()) or 0 + entry.update({ + 'actual_qty': balance_qty, + 'percent_occupied': flt((flt(balance_qty) / flt(entry.stock_capacity)) * 100, 0) + }) + + return capacity_data \ No newline at end of file diff --git a/erpnext/stock/desk_page/stock/stock.json b/erpnext/stock/desk_page/stock/stock.json index aa4fc28ec94..0038c0a9710 100644 --- a/erpnext/stock/desk_page/stock/stock.json +++ b/erpnext/stock/desk_page/stock/stock.json @@ -13,7 +13,7 @@ { "hidden": 0, "label": "Stock Reports", - "links": "[\n {\n \"dependencies\": [\n \"Item\"\n ],\n \"doctype\": \"Stock Ledger Entry\",\n \"is_query_report\": true,\n \"label\": \"Stock Ledger\",\n \"name\": \"Stock Ledger\",\n \"onboard\": 1,\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Item\"\n ],\n \"doctype\": \"Stock Ledger Entry\",\n \"is_query_report\": true,\n \"label\": \"Stock Balance\",\n \"name\": \"Stock Balance\",\n \"onboard\": 1,\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Item\"\n ],\n \"doctype\": \"Item\",\n \"is_query_report\": true,\n \"label\": \"Stock Projected Qty\",\n \"name\": \"Stock Projected Qty\",\n \"onboard\": 1,\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Item\"\n ],\n \"label\": \"Stock Summary\",\n \"name\": \"stock-balance\",\n \"type\": \"page\"\n },\n {\n \"dependencies\": [\n \"Item\"\n ],\n \"doctype\": \"Item\",\n \"is_query_report\": true,\n \"label\": \"Stock Ageing\",\n \"name\": \"Stock Ageing\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Item\"\n ],\n \"doctype\": \"Item\",\n \"is_query_report\": true,\n \"label\": \"Item Price Stock\",\n \"name\": \"Item Price Stock\",\n \"type\": \"report\"\n }\n]" + "links": "[\n {\n \"dependencies\": [\n \"Item\"\n ],\n \"doctype\": \"Stock Ledger Entry\",\n \"is_query_report\": true,\n \"label\": \"Stock Ledger\",\n \"name\": \"Stock Ledger\",\n \"onboard\": 1,\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Item\"\n ],\n \"doctype\": \"Stock Ledger Entry\",\n \"is_query_report\": true,\n \"label\": \"Stock Balance\",\n \"name\": \"Stock Balance\",\n \"onboard\": 1,\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Item\"\n ],\n \"doctype\": \"Item\",\n \"is_query_report\": true,\n \"label\": \"Stock Projected Qty\",\n \"name\": \"Stock Projected Qty\",\n \"onboard\": 1,\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Item\"\n ],\n \"label\": \"Stock Summary\",\n \"name\": \"stock-balance\",\n \"type\": \"page\"\n },\n {\n \"dependencies\": [\n \"Item\"\n ],\n \"doctype\": \"Item\",\n \"is_query_report\": true,\n \"label\": \"Stock Ageing\",\n \"name\": \"Stock Ageing\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Item\"\n ],\n \"doctype\": \"Item\",\n \"is_query_report\": true,\n \"label\": \"Item Price Stock\",\n \"name\": \"Item Price Stock\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Item\",\n \"Putaway Rule\"\n ],\n \"label\": \"Warehouse Capacity Summary\",\n \"name\": \"warehouse-capacity-summary\",\n \"type\": \"page\"\n }\n]" }, { "hidden": 0, @@ -58,7 +58,7 @@ "idx": 0, "is_standard": 1, "label": "Stock", - "modified": "2020-11-24 15:43:20.496057", + "modified": "2020-11-26 10:43:48.286663", "modified_by": "Administrator", "module": "Stock", "name": "Stock", diff --git a/erpnext/stock/doctype/item/item.js b/erpnext/stock/doctype/item/item.js index faeeb578fe3..ec32b0f0440 100644 --- a/erpnext/stock/doctype/item/item.js +++ b/erpnext/stock/doctype/item/item.js @@ -384,7 +384,10 @@ $.extend(erpnext.item, { ' + __("Stock Levels") + ''); erpnext.item.item_dashboard = new erpnext.stock.ItemDashboard({ parent: section, - item_code: frm.doc.name + item_code: frm.doc.name, + page_length: 20, + method: 'erpnext.stock.dashboard.item_dashboard.get_data', + template: 'item_dashboard_list' }); erpnext.item.item_dashboard.refresh(); }); diff --git a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.json b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.json index 13c8ceb7596..7213eb86169 100755 --- a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.json +++ b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.json @@ -21,6 +21,7 @@ "posting_date", "posting_time", "set_posting_time", + "apply_putaway_rule", "is_return", "return_against", "section_addresses", @@ -1104,13 +1105,19 @@ "fieldtype": "Small Text", "label": "Billing Address", "read_only": 1 + }, + { + "default": "0", + "fieldname": "apply_putaway_rule", + "fieldtype": "Check", + "label": "Apply Putaway Rule" } ], "icon": "fa fa-truck", "idx": 261, "is_submittable": 1, "links": [], - "modified": "2020-10-30 14:00:08.347534", + "modified": "2020-11-25 18:31:32.234503", "modified_by": "Administrator", "module": "Stock", "name": "Purchase Receipt", diff --git a/erpnext/stock/doctype/putaway_rule/putaway_rule.json b/erpnext/stock/doctype/putaway_rule/putaway_rule.json index 325e6f1355d..a003f4986f9 100644 --- a/erpnext/stock/doctype/putaway_rule/putaway_rule.json +++ b/erpnext/stock/doctype/putaway_rule/putaway_rule.json @@ -1,6 +1,6 @@ { "actions": [], - "autoname": "format:{item_code}-{warehouse}", + "autoname": "PUT-.####", "creation": "2020-11-09 11:39:46.489501", "doctype": "DocType", "editable_grid": 1, @@ -90,12 +90,14 @@ "fieldname": "uom", "fieldtype": "Link", "label": "UOM", + "no_copy": 1, "options": "UOM" }, { "fieldname": "stock_capacity", "fieldtype": "Float", "label": "Capacity in Stock UOM", + "no_copy": 1, "read_only": 1 }, { @@ -103,12 +105,13 @@ "fieldname": "conversion_factor", "fieldtype": "Float", "label": "Conversion Factor", + "no_copy": 1, "read_only": 1 } ], "index_web_pages_for_search": 1, "links": [], - "modified": "2020-11-24 16:20:18.306671", + "modified": "2020-11-25 20:39:19.973437", "modified_by": "Administrator", "module": "Stock", "name": "Putaway Rule", @@ -152,5 +155,6 @@ ], "sort_field": "modified", "sort_order": "DESC", + "title_field": "item_code", "track_changes": 1 } \ No newline at end of file diff --git a/erpnext/stock/doctype/putaway_rule/putaway_rule_list.js b/erpnext/stock/doctype/putaway_rule/putaway_rule_list.js index e48c415f14c..725e91ee8d9 100644 --- a/erpnext/stock/doctype/putaway_rule/putaway_rule_list.js +++ b/erpnext/stock/doctype/putaway_rule/putaway_rule_list.js @@ -6,5 +6,13 @@ frappe.listview_settings['Putaway Rule'] = { } else { return [__("Active"), "blue", "disable,=,0"]; } - } + }, + + reports: [ + { + name: 'Warehouse Capacity Summary', + report_type: 'Page', + route: 'warehouse-capacity-summary' + } + ] }; diff --git a/erpnext/stock/page/stock_balance/stock_balance.js b/erpnext/stock/page/stock_balance/stock_balance.js index da21c6bc64f..bddffd465e6 100644 --- a/erpnext/stock/page/stock_balance/stock_balance.js +++ b/erpnext/stock/page/stock_balance/stock_balance.js @@ -65,6 +65,9 @@ frappe.pages['stock-balance'].on_page_load = function(wrapper) { frappe.require('assets/js/item-dashboard.min.js', function() { page.item_dashboard = new erpnext.stock.ItemDashboard({ parent: page.main, + page_length: 20, + method: 'erpnext.stock.dashboard.item_dashboard.get_data', + template: 'item_dashboard_list' }) page.item_dashboard.before_refresh = function() { diff --git a/erpnext/stock/page/warehouse_capacity_summary/__init__.py b/erpnext/stock/page/warehouse_capacity_summary/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/erpnext/stock/page/warehouse_capacity_summary/warehouse_capacity_summary.html b/erpnext/stock/page/warehouse_capacity_summary/warehouse_capacity_summary.html new file mode 100644 index 00000000000..90112c78a83 --- /dev/null +++ b/erpnext/stock/page/warehouse_capacity_summary/warehouse_capacity_summary.html @@ -0,0 +1,40 @@ +{% for d in data %} +
+
+ + +
+ {{ d.stock_capacity }} +
+
+ {{ d.actual_qty }} +
+
+
+
+
+
+
+
+ {{ d.percent_occupied }}% +
+ {% if can_write %} +
+
+ {% endif %} +
+
+{% endfor %} \ No newline at end of file diff --git a/erpnext/stock/page/warehouse_capacity_summary/warehouse_capacity_summary.js b/erpnext/stock/page/warehouse_capacity_summary/warehouse_capacity_summary.js new file mode 100644 index 00000000000..c3b3b5d8ec4 --- /dev/null +++ b/erpnext/stock/page/warehouse_capacity_summary/warehouse_capacity_summary.js @@ -0,0 +1,120 @@ +frappe.pages['warehouse-capacity-summary'].on_page_load = function(wrapper) { + var page = frappe.ui.make_app_page({ + parent: wrapper, + title: 'Warehouse Capacity Summary', + single_column: true + }); + page.set_secondary_action('Refresh', () => page.capacity_dashboard.refresh(), 'octicon octicon-sync'); + page.start = 0; + + page.company_field = page.add_field({ + fieldname: 'company', + label: __('Company'), + fieldtype:'Link', + options:'Company', + reqd: 1, + default: frappe.defaults.get_default("company"), + change: function() { + page.capacity_dashboard.start = 0; + page.capacity_dashboard.refresh(); + } + }); + + page.warehouse_field = page.add_field({ + fieldname: 'warehouse', + label: __('Warehouse'), + fieldtype:'Link', + options:'Warehouse', + change: function() { + page.capacity_dashboard.start = 0; + page.capacity_dashboard.refresh(); + } + }); + + page.item_field = page.add_field({ + fieldname: 'item_code', + label: __('Item'), + fieldtype:'Link', + options:'Item', + change: function() { + page.capacity_dashboard.start = 0; + page.capacity_dashboard.refresh(); + } + }); + + page.parent_warehouse_field = page.add_field({ + fieldname: 'parent_warehouse', + label: __('Parent Warehouse'), + fieldtype:'Link', + options:'Warehouse', + get_query: function() { + return { + filters: { + "is_group": 1 + } + }; + }, + change: function() { + page.capacity_dashboard.start = 0; + page.capacity_dashboard.refresh(); + } + }); + + page.sort_selector = new frappe.ui.SortSelector({ + parent: page.wrapper.find('.page-form'), + args: { + sort_by: 'stock_capacity', + sort_order: 'desc', + options: [ + {fieldname: 'stock_capacity', label: __('Capacity (Stock UOM)')}, + {fieldname: 'percent_occupied', label:__('% Occupied')}, + {fieldname: 'actual_qty', label:__('Balance Qty (Stock ')} + ] + }, + change: function(sort_by, sort_order) { + page.capacity_dashboard.sort_by = sort_by; + page.capacity_dashboard.sort_order = sort_order; + page.capacity_dashboard.start = 0; + page.capacity_dashboard.refresh(); + } + }); + + frappe.require('assets/js/item-dashboard.min.js', function() { + $(frappe.render_template('warehouse_capacity_summary_header')).appendTo(page.main); + + page.capacity_dashboard = new erpnext.stock.ItemDashboard({ + page_name: "warehouse-capacity-summary", + page_length: 10, + parent: page.main, + sort_by: 'stock_capacity', + sort_order: 'desc', + method: 'erpnext.stock.dashboard.warehouse_capacity_dashboard.get_data', + template: 'warehouse_capacity_summary' + }) + + page.capacity_dashboard.before_refresh = function() { + this.item_code = page.item_field.get_value(); + this.warehouse = page.warehouse_field.get_value(); + this.parent_warehouse = page.parent_warehouse_field.get_value(); + this.company = page.company_field.get_value(); + } + + page.capacity_dashboard.refresh(); + + let setup_click = function(doctype) { + page.main.on('click', 'a[data-type="'+ doctype.toLowerCase() +'"]', function() { + var name = $(this).attr('data-name'); + var field = page[doctype.toLowerCase() + '_field']; + if(field.get_value()===name) { + frappe.set_route('Form', doctype, name) + } else { + field.set_input(name); + page.capacity_dashboard.refresh(); + } + }); + } + + setup_click('Item'); + setup_click('Warehouse'); + }); +} \ No newline at end of file diff --git a/erpnext/stock/page/warehouse_capacity_summary/warehouse_capacity_summary.json b/erpnext/stock/page/warehouse_capacity_summary/warehouse_capacity_summary.json new file mode 100644 index 00000000000..a6e5b45332b --- /dev/null +++ b/erpnext/stock/page/warehouse_capacity_summary/warehouse_capacity_summary.json @@ -0,0 +1,26 @@ +{ + "content": null, + "creation": "2020-11-25 12:07:54.056208", + "docstatus": 0, + "doctype": "Page", + "idx": 0, + "modified": "2020-11-25 11:07:54.056208", + "modified_by": "Administrator", + "module": "Stock", + "name": "warehouse-capacity-summary", + "owner": "Administrator", + "page_name": "Warehouse Capacity Summary", + "roles": [ + { + "role": "Stock User" + }, + { + "role": "Stock Manager" + } + ], + "script": null, + "standard": "Yes", + "style": null, + "system_page": 0, + "title": "Warehouse Capacity Summary" +} \ No newline at end of file diff --git a/erpnext/stock/page/warehouse_capacity_summary/warehouse_capacity_summary_header.html b/erpnext/stock/page/warehouse_capacity_summary/warehouse_capacity_summary_header.html new file mode 100644 index 00000000000..acaf180a903 --- /dev/null +++ b/erpnext/stock/page/warehouse_capacity_summary/warehouse_capacity_summary_header.html @@ -0,0 +1,19 @@ +
+
+
+ Warehouse +
+
+ Item +
+
+ Stock Capacity +
+
+ Balance Stock Qty +
+
+ % Occupied +
+
+
\ No newline at end of file From 2c114053ad3087ad12a8d8a084cabb817b126066 Mon Sep 17 00:00:00 2001 From: Rucha Mahabal Date: Fri, 27 Nov 2020 15:05:28 +0530 Subject: [PATCH 101/477] feat: Patient History Settings --- .../__init__.py | 0 .../patient_history_custom_document_type.json | 46 ++++++++++ .../patient_history_custom_document_type.py | 10 +++ .../patient_history_settings/__init__.py | 0 .../patient_history_settings.js | 85 +++++++++++++++++++ .../patient_history_settings.json | 55 ++++++++++++ .../patient_history_settings.py | 10 +++ .../test_patient_history_settings.py | 10 +++ .../__init__.py | 0 ...atient_history_standard_document_type.json | 47 ++++++++++ .../patient_history_standard_document_type.py | 10 +++ 11 files changed, 273 insertions(+) create mode 100644 erpnext/healthcare/doctype/patient_history_custom_document_type/__init__.py create mode 100644 erpnext/healthcare/doctype/patient_history_custom_document_type/patient_history_custom_document_type.json create mode 100644 erpnext/healthcare/doctype/patient_history_custom_document_type/patient_history_custom_document_type.py create mode 100644 erpnext/healthcare/doctype/patient_history_settings/__init__.py create mode 100644 erpnext/healthcare/doctype/patient_history_settings/patient_history_settings.js create mode 100644 erpnext/healthcare/doctype/patient_history_settings/patient_history_settings.json create mode 100644 erpnext/healthcare/doctype/patient_history_settings/patient_history_settings.py create mode 100644 erpnext/healthcare/doctype/patient_history_settings/test_patient_history_settings.py create mode 100644 erpnext/healthcare/doctype/patient_history_standard_document_type/__init__.py create mode 100644 erpnext/healthcare/doctype/patient_history_standard_document_type/patient_history_standard_document_type.json create mode 100644 erpnext/healthcare/doctype/patient_history_standard_document_type/patient_history_standard_document_type.py diff --git a/erpnext/healthcare/doctype/patient_history_custom_document_type/__init__.py b/erpnext/healthcare/doctype/patient_history_custom_document_type/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/erpnext/healthcare/doctype/patient_history_custom_document_type/patient_history_custom_document_type.json b/erpnext/healthcare/doctype/patient_history_custom_document_type/patient_history_custom_document_type.json new file mode 100644 index 00000000000..a158075e7b9 --- /dev/null +++ b/erpnext/healthcare/doctype/patient_history_custom_document_type/patient_history_custom_document_type.json @@ -0,0 +1,46 @@ +{ + "actions": [], + "creation": "2020-11-25 13:40:23.054469", + "doctype": "DocType", + "editable_grid": 1, + "engine": "InnoDB", + "field_order": [ + "document_type", + "select_fields", + "selected_fields" + ], + "fields": [ + { + "fieldname": "document_type", + "fieldtype": "Link", + "in_list_view": 1, + "label": "Document Type", + "options": "DocType", + "reqd": 1 + }, + { + "fieldname": "select_fields", + "fieldtype": "Button", + "in_list_view": 1, + "label": "Select Fields" + }, + { + "fieldname": "selected_fields", + "fieldtype": "Code", + "label": "selected_fields" + } + ], + "index_web_pages_for_search": 1, + "istable": 1, + "links": [], + "modified": "2020-11-25 14:19:33.637543", + "modified_by": "Administrator", + "module": "Healthcare", + "name": "Patient History Custom Document Type", + "owner": "Administrator", + "permissions": [], + "quick_entry": 1, + "sort_field": "modified", + "sort_order": "DESC", + "track_changes": 1 +} \ No newline at end of file diff --git a/erpnext/healthcare/doctype/patient_history_custom_document_type/patient_history_custom_document_type.py b/erpnext/healthcare/doctype/patient_history_custom_document_type/patient_history_custom_document_type.py new file mode 100644 index 00000000000..f0a1f929f45 --- /dev/null +++ b/erpnext/healthcare/doctype/patient_history_custom_document_type/patient_history_custom_document_type.py @@ -0,0 +1,10 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors +# For license information, please see license.txt + +from __future__ import unicode_literals +# import frappe +from frappe.model.document import Document + +class PatientHistoryCustomDocumentType(Document): + pass diff --git a/erpnext/healthcare/doctype/patient_history_settings/__init__.py b/erpnext/healthcare/doctype/patient_history_settings/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/erpnext/healthcare/doctype/patient_history_settings/patient_history_settings.js b/erpnext/healthcare/doctype/patient_history_settings/patient_history_settings.js new file mode 100644 index 00000000000..155476e2b10 --- /dev/null +++ b/erpnext/healthcare/doctype/patient_history_settings/patient_history_settings.js @@ -0,0 +1,85 @@ +// Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors +// For license information, please see license.txt + +frappe.ui.form.on('Patient History Settings', { + refresh: function(frm) { + frm.set_query('document_type', 'custom_doctypes', () => { + return { + filters: { + custom: 1, + module: 'Healthcare' + } + }; + }); + }, + + field_selector: function(frm, doc) { + let document_fields = (JSON.parse(doc.selected_fields)).map(f => f.fieldname); + let d = new frappe.ui.Dialog({ + title: __('{0} Fields', [__(doc.document_type)]), + fields: [ + { + label: __('Select Fields'), + fieldtype: 'MultiCheck', + fieldname: 'fields', + options: frm.events.get_doctype_fields(frm, doc.document_type, document_fields), + columns: 2 + } + ] + }); + + d.set_primary_action(__('Save'), () => { + let values = d.get_values().fields; + + let selected_fields = []; + + for (let idx in values) { + let value = values[idx]; + + let field = frappe.meta.get_docfield(doc.document_type, value); + if (field) { + selected_fields.push({ + label: field.label, + fieldname: field.fieldname + }); + } + } + + frappe.model.set_value('Patient History Custom Document Type', doc.name, 'selected_fields', JSON.stringify(selected_fields)); + d.hide(); + }); + + d.show(); + }, + + get_doctype_fields(frm, document_type, fields) { + let multiselect_fields = []; + + frappe.model.with_doctype(document_type, () => { + // get doctype fields + frappe.get_doc('DocType', document_type).fields.forEach(field => { + if (!in_list(frappe.model.no_value_type, field.fieldtype) && !field.hidden) { + multiselect_fields.push({ + label: field.label, + value: field.fieldname, + checked: in_list(fields, field.fieldname) + }); + } + }); + }); + + return multiselect_fields; + } +}); + +frappe.ui.form.on('Patient History Custom Document Type', { + select_fields: function(frm) { + let doc = frm.selected_doc; + + if (!doc.document_type) + frappe.throw(__('Select the Document Type first.')) + + frm.events.field_selector(frm, doc); + } + +}); diff --git a/erpnext/healthcare/doctype/patient_history_settings/patient_history_settings.json b/erpnext/healthcare/doctype/patient_history_settings/patient_history_settings.json new file mode 100644 index 00000000000..143e2c91eb5 --- /dev/null +++ b/erpnext/healthcare/doctype/patient_history_settings/patient_history_settings.json @@ -0,0 +1,55 @@ +{ + "actions": [], + "creation": "2020-11-25 13:41:37.675518", + "doctype": "DocType", + "editable_grid": 1, + "engine": "InnoDB", + "field_order": [ + "standard_doctypes", + "section_break_2", + "custom_doctypes" + ], + "fields": [ + { + "fieldname": "section_break_2", + "fieldtype": "Section Break" + }, + { + "fieldname": "custom_doctypes", + "fieldtype": "Table", + "label": "Custom Document Types", + "options": "Patient History Custom Document Type" + }, + { + "fieldname": "standard_doctypes", + "fieldtype": "Table", + "label": "Standard Document Types", + "options": "Patient History Standard Document Type", + "read_only": 1 + } + ], + "index_web_pages_for_search": 1, + "issingle": 1, + "links": [], + "modified": "2020-11-25 13:43:38.511771", + "modified_by": "Administrator", + "module": "Healthcare", + "name": "Patient History Settings", + "owner": "Administrator", + "permissions": [ + { + "create": 1, + "delete": 1, + "email": 1, + "print": 1, + "read": 1, + "role": "System Manager", + "share": 1, + "write": 1 + } + ], + "quick_entry": 1, + "sort_field": "modified", + "sort_order": "DESC", + "track_changes": 1 +} \ No newline at end of file diff --git a/erpnext/healthcare/doctype/patient_history_settings/patient_history_settings.py b/erpnext/healthcare/doctype/patient_history_settings/patient_history_settings.py new file mode 100644 index 00000000000..27cbf2fc60d --- /dev/null +++ b/erpnext/healthcare/doctype/patient_history_settings/patient_history_settings.py @@ -0,0 +1,10 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors +# For license information, please see license.txt + +from __future__ import unicode_literals +# import frappe +from frappe.model.document import Document + +class PatientHistorySettings(Document): + pass diff --git a/erpnext/healthcare/doctype/patient_history_settings/test_patient_history_settings.py b/erpnext/healthcare/doctype/patient_history_settings/test_patient_history_settings.py new file mode 100644 index 00000000000..548c423670f --- /dev/null +++ b/erpnext/healthcare/doctype/patient_history_settings/test_patient_history_settings.py @@ -0,0 +1,10 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and Contributors +# See license.txt +from __future__ import unicode_literals + +# import frappe +import unittest + +class TestPatientHistorySettings(unittest.TestCase): + pass diff --git a/erpnext/healthcare/doctype/patient_history_standard_document_type/__init__.py b/erpnext/healthcare/doctype/patient_history_standard_document_type/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/erpnext/healthcare/doctype/patient_history_standard_document_type/patient_history_standard_document_type.json b/erpnext/healthcare/doctype/patient_history_standard_document_type/patient_history_standard_document_type.json new file mode 100644 index 00000000000..ec40d893eba --- /dev/null +++ b/erpnext/healthcare/doctype/patient_history_standard_document_type/patient_history_standard_document_type.json @@ -0,0 +1,47 @@ +{ + "actions": [], + "creation": "2020-11-25 13:39:36.014814", + "doctype": "DocType", + "editable_grid": 1, + "engine": "InnoDB", + "field_order": [ + "document_type", + "select_fields", + "selected_fields" + ], + "fields": [ + { + "fieldname": "document_type", + "fieldtype": "Link", + "in_list_view": 1, + "label": "Document Type", + "options": "DocType", + "read_only": 1, + "reqd": 1 + }, + { + "fieldname": "select_fields", + "fieldtype": "Button", + "in_list_view": 1, + "label": "Select Fields" + }, + { + "fieldname": "selected_fields", + "fieldtype": "Code", + "label": "Selected Fields" + } + ], + "index_web_pages_for_search": 1, + "istable": 1, + "links": [], + "modified": "2020-11-25 14:19:53.708991", + "modified_by": "Administrator", + "module": "Healthcare", + "name": "Patient History Standard Document Type", + "owner": "Administrator", + "permissions": [], + "quick_entry": 1, + "sort_field": "modified", + "sort_order": "DESC", + "track_changes": 1 +} \ No newline at end of file diff --git a/erpnext/healthcare/doctype/patient_history_standard_document_type/patient_history_standard_document_type.py b/erpnext/healthcare/doctype/patient_history_standard_document_type/patient_history_standard_document_type.py new file mode 100644 index 00000000000..2d94911855a --- /dev/null +++ b/erpnext/healthcare/doctype/patient_history_standard_document_type/patient_history_standard_document_type.py @@ -0,0 +1,10 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors +# For license information, please see license.txt + +from __future__ import unicode_literals +# import frappe +from frappe.model.document import Document + +class PatientHistoryStandardDocumentType(Document): + pass From f2932d720882433e18c690be130a7d919a0570d6 Mon Sep 17 00:00:00 2001 From: Rucha Mahabal Date: Sat, 28 Nov 2020 19:19:58 +0530 Subject: [PATCH 102/477] feat: set date field in Settings for Patient Medical Record --- .../patient_history_custom_document_type.json | 24 ++++++++++++------- .../patient_history_settings.js | 13 ++++------ .../patient_history_settings.py | 17 +++++++++++-- ...atient_history_standard_document_type.json | 16 ++++++------- 4 files changed, 44 insertions(+), 26 deletions(-) diff --git a/erpnext/healthcare/doctype/patient_history_custom_document_type/patient_history_custom_document_type.json b/erpnext/healthcare/doctype/patient_history_custom_document_type/patient_history_custom_document_type.json index a158075e7b9..7986e48ced7 100644 --- a/erpnext/healthcare/doctype/patient_history_custom_document_type/patient_history_custom_document_type.json +++ b/erpnext/healthcare/doctype/patient_history_custom_document_type/patient_history_custom_document_type.json @@ -6,7 +6,8 @@ "engine": "InnoDB", "field_order": [ "document_type", - "select_fields", + "date_fieldname", + "add_edit_fields", "selected_fields" ], "fields": [ @@ -18,22 +19,29 @@ "options": "DocType", "reqd": 1 }, - { - "fieldname": "select_fields", - "fieldtype": "Button", - "in_list_view": 1, - "label": "Select Fields" - }, { "fieldname": "selected_fields", "fieldtype": "Code", "label": "selected_fields" + }, + { + "fieldname": "add_edit_fields", + "fieldtype": "Button", + "in_list_view": 1, + "label": "Add / Edit Fields" + }, + { + "fieldname": "date_fieldname", + "fieldtype": "Data", + "in_list_view": 1, + "label": "Date Fieldname", + "reqd": 1 } ], "index_web_pages_for_search": 1, "istable": 1, "links": [], - "modified": "2020-11-25 14:19:33.637543", + "modified": "2020-11-28 19:04:48.323164", "modified_by": "Administrator", "module": "Healthcare", "name": "Patient History Custom Document Type", diff --git a/erpnext/healthcare/doctype/patient_history_settings/patient_history_settings.js b/erpnext/healthcare/doctype/patient_history_settings/patient_history_settings.js index 155476e2b10..ca2707f6a60 100644 --- a/erpnext/healthcare/doctype/patient_history_settings/patient_history_settings.js +++ b/erpnext/healthcare/doctype/patient_history_settings/patient_history_settings.js @@ -73,13 +73,10 @@ frappe.ui.form.on('Patient History Settings', { }); frappe.ui.form.on('Patient History Custom Document Type', { - select_fields: function(frm) { - let doc = frm.selected_doc; - - if (!doc.document_type) - frappe.throw(__('Select the Document Type first.')) - - frm.events.field_selector(frm, doc); + add_edit_fields: function(frm, cdt, cdn) { + let row = locals[cdt][cdn]; + if (row.document_type) { + frm.events.field_selector(frm, row); + } } - }); diff --git a/erpnext/healthcare/doctype/patient_history_settings/patient_history_settings.py b/erpnext/healthcare/doctype/patient_history_settings/patient_history_settings.py index 27cbf2fc60d..9e876e8c959 100644 --- a/erpnext/healthcare/doctype/patient_history_settings/patient_history_settings.py +++ b/erpnext/healthcare/doctype/patient_history_settings/patient_history_settings.py @@ -3,8 +3,21 @@ # For license information, please see license.txt from __future__ import unicode_literals -# import frappe +import frappe +from frappe import _ from frappe.model.document import Document class PatientHistorySettings(Document): - pass + def validate(self): + self.validate_date_fieldnames() + + def validate_date_fieldnames(self): + for entry in self.custom_doctypes: + field = frappe.get_meta(entry.document_type).get_field(entry.date_fieldname) + if not field: + frappe.throw(_('Row #{0}: No such Field named {1} found in the Document Type {2}.').format( + entry.idx, frappe.bold(entry.date_fieldname), frappe.bold(entry.document_type))) + + if field.fieldtype not in ['Date', 'Datetime']: + frappe.throw(_('Row #{0}: Field {1} in Document Type {2} is not a Date / Datetime field.').format( + entry.idx, frappe.bold(entry.date_fieldname), frappe.bold(entry.document_type))) \ No newline at end of file diff --git a/erpnext/healthcare/doctype/patient_history_standard_document_type/patient_history_standard_document_type.json b/erpnext/healthcare/doctype/patient_history_standard_document_type/patient_history_standard_document_type.json index ec40d893eba..ef4fc2bfe1e 100644 --- a/erpnext/healthcare/doctype/patient_history_standard_document_type/patient_history_standard_document_type.json +++ b/erpnext/healthcare/doctype/patient_history_standard_document_type/patient_history_standard_document_type.json @@ -6,7 +6,7 @@ "engine": "InnoDB", "field_order": [ "document_type", - "select_fields", + "add_edit_fields", "selected_fields" ], "fields": [ @@ -19,22 +19,22 @@ "read_only": 1, "reqd": 1 }, - { - "fieldname": "select_fields", - "fieldtype": "Button", - "in_list_view": 1, - "label": "Select Fields" - }, { "fieldname": "selected_fields", "fieldtype": "Code", "label": "Selected Fields" + }, + { + "fieldname": "add_edit_fields", + "fieldtype": "Button", + "in_list_view": 1, + "label": "Add / Edit Fields" } ], "index_web_pages_for_search": 1, "istable": 1, "links": [], - "modified": "2020-11-25 14:19:53.708991", + "modified": "2020-11-28 18:57:30.446348", "modified_by": "Administrator", "module": "Healthcare", "name": "Patient History Standard Document Type", From c91e03c8911286cb50731dd7064501b9c80474a9 Mon Sep 17 00:00:00 2001 From: Rucha Mahabal Date: Sat, 28 Nov 2020 20:24:06 +0530 Subject: [PATCH 103/477] feat: Create Patient Medical Record on configured doctype submission --- .../patient_history_settings.js | 6 ++- .../patient_history_settings.py | 53 ++++++++++++++++++- erpnext/hooks.py | 4 ++ 3 files changed, 60 insertions(+), 3 deletions(-) diff --git a/erpnext/healthcare/doctype/patient_history_settings/patient_history_settings.js b/erpnext/healthcare/doctype/patient_history_settings/patient_history_settings.js index ca2707f6a60..60926eeb119 100644 --- a/erpnext/healthcare/doctype/patient_history_settings/patient_history_settings.js +++ b/erpnext/healthcare/doctype/patient_history_settings/patient_history_settings.js @@ -40,7 +40,8 @@ frappe.ui.form.on('Patient History Settings', { if (field) { selected_fields.push({ label: field.label, - fieldname: field.fieldname + fieldname: field.fieldname, + fieldtype: field.fieldtype }); } } @@ -58,7 +59,8 @@ frappe.ui.form.on('Patient History Settings', { frappe.model.with_doctype(document_type, () => { // get doctype fields frappe.get_doc('DocType', document_type).fields.forEach(field => { - if (!in_list(frappe.model.no_value_type, field.fieldtype) && !field.hidden) { + if (!in_list(frappe.model.no_value_type, field.fieldtype) || + in_list(frappe.model.table_fields, field.fieldtype) && !field.hidden) { multiselect_fields.push({ label: field.label, value: field.fieldname, diff --git a/erpnext/healthcare/doctype/patient_history_settings/patient_history_settings.py b/erpnext/healthcare/doctype/patient_history_settings/patient_history_settings.py index 9e876e8c959..af8c6f45574 100644 --- a/erpnext/healthcare/doctype/patient_history_settings/patient_history_settings.py +++ b/erpnext/healthcare/doctype/patient_history_settings/patient_history_settings.py @@ -5,6 +5,7 @@ from __future__ import unicode_literals import frappe from frappe import _ +from frappe.utils import cstr from frappe.model.document import Document class PatientHistorySettings(Document): @@ -20,4 +21,54 @@ class PatientHistorySettings(Document): if field.fieldtype not in ['Date', 'Datetime']: frappe.throw(_('Row #{0}: Field {1} in Document Type {2} is not a Date / Datetime field.').format( - entry.idx, frappe.bold(entry.date_fieldname), frappe.bold(entry.document_type))) \ No newline at end of file + entry.idx, frappe.bold(entry.date_fieldname), frappe.bold(entry.document_type))) + + +def create_medical_record(doc, method=None): + if frappe.flags.in_patch or frappe.flags.in_install or frappe.flags.in_setup_wizard or \ + frappe.db.get_value('Doctype', doc.doctype, 'module') != 'Healthcare': + return + + subject = set_subject_field(doc) + date_field = get_date_field(doc.doctype) + medical_record = frappe.new_doc('Patient Medical Record') + medical_record.patient = doc.patient + medical_record.subject = subject + medical_record.status = 'Open' + medical_record.communication_date = doc.get(date_field) + medical_record.reference_doctype = doc.doctype + medical_record.reference_name = doc.name + medical_record.reference_owner = doc.owner + medical_record.save(ignore_permissions=True) + + +def set_subject_field(doc): + from frappe.utils.formatters import format_value + + meta = frappe.get_meta(doc.doctype) + subject = '' + patient_history_fields = get_patient_history_fields(doc) + + for entry in patient_history_fields: + fieldname = entry.get('fieldname') + if doc.get(fieldname): + formated_value = format_value(doc.get(fieldname), meta.get_field(fieldname), doc) + subject += frappe.bold(_(entry.get('label')) + ': ') + cstr(formated_value) + subject += '
' + + return subject + + +def get_date_field(doctype): + return frappe.db.get_value('Patient History Custom Document Type', + { 'document_type': doctype }, 'date_fieldname') + + +def get_patient_history_fields(doc): + import json + patient_history_fields = frappe.db.get_value('Patient History Custom Document Type', + { 'document_type': doc.doctype }, 'selected_fields') + + if patient_history_fields: + return json.loads(patient_history_fields) + diff --git a/erpnext/hooks.py b/erpnext/hooks.py index 741176f33f4..4ee42c7559d 100644 --- a/erpnext/hooks.py +++ b/erpnext/hooks.py @@ -221,6 +221,10 @@ standard_queries = { } doc_events = { + "*": { + "on_submit": "erpnext.healthcare.doctype.patient_history_settings.patient_history_settings.create_medical_record", + "on_cancel": "erpnext.healthcare.doctype.patient_history_settings.patient_history_settings.delete_medical_record" + }, "Stock Entry": { "on_submit": "erpnext.stock.doctype.material_request.material_request.update_completed_and_requested_qty", "on_cancel": "erpnext.stock.doctype.material_request.material_request.update_completed_and_requested_qty" From a75f79762f224f8b38d2877b7a596cc93d9647fd Mon Sep 17 00:00:00 2001 From: Rucha Mahabal Date: Sat, 28 Nov 2020 23:09:07 +0530 Subject: [PATCH 104/477] feat: Link for individual documents in Patient History --- .../page/patient_history/patient_history.html | 1 - .../page/patient_history/patient_history.js | 19 ++++++++++++------- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/erpnext/healthcare/page/patient_history/patient_history.html b/erpnext/healthcare/page/patient_history/patient_history.html index 7a9446dffd7..60f4501fed1 100644 --- a/erpnext/healthcare/page/patient_history/patient_history.html +++ b/erpnext/healthcare/page/patient_history/patient_history.html @@ -1,6 +1,5 @@
-

{%= __("Select Patient") %}

diff --git a/erpnext/healthcare/page/patient_history/patient_history.js b/erpnext/healthcare/page/patient_history/patient_history.js index fe5b7bc4883..3e6d790ca73 100644 --- a/erpnext/healthcare/page/patient_history/patient_history.js +++ b/erpnext/healthcare/page/patient_history/patient_history.js @@ -16,6 +16,8 @@ frappe.pages['patient_history'].on_page_load = function(wrapper) { fieldtype: "Link", options: "Patient", fieldname: "patient", + placeholder: __('Select Patient'), + only_select: true, change: function(){ if(pid != patient.get_value() && patient.get_value()){ me.start = 0; @@ -27,7 +29,6 @@ frappe.pages['patient_history'].on_page_load = function(wrapper) { pid = patient.get_value(); } }, - only_input: true, }); patient.refresh(); @@ -120,7 +121,11 @@ var add_to_records = function(me, data){ data[i].imgsrc = false; } var time_line_heading = data[i].practitioner ? `${data[i].practitioner} ` : ``; - time_line_heading += data[i].reference_doctype + " - "+ data[i].reference_name; + time_line_heading += data[i].reference_doctype + " - " + + ` + ${data[i].reference_name} + ` + details += `
  • `; @@ -135,7 +140,7 @@ var add_to_records = function(me, data){ } details += `
    - `+time_line_heading+` on + `+time_line_heading+` ${data[i].date_sep} @@ -172,11 +177,11 @@ var add_date_separator = function(data) { var diff = frappe.datetime.get_day_diff(frappe.datetime.get_today(), frappe.datetime.obj_to_str(date)); if(diff < 1) { - var pdate = 'Today'; + var pdate = __('Today'); } else if(diff < 2) { - pdate = 'Yesterday'; + pdate = __('Yesterday'); } else { - pdate = frappe.datetime.global_date_format(date); + pdate = __('on ') + frappe.datetime.global_date_format(date); } data.date_sep = pdate; return data; @@ -227,7 +232,7 @@ var show_patient_vital_charts = function(patient, me, btn_show_id, pts, title) { }, callback: function(r) { if (r.message){ - var show_chart_btns_html = "
    "); - me.page.main.find("."+docname).parent().find('.document-html').show(); - me.page.main.find("."+docname).parent().find('.document-html').attr('data-fetched', "1"); + if (r.message) { + me.page.main.find('.' + docname).hide(); + + me.page.main.find('.' + docname).parent().find('.document-html').html( + `${r.message.html} +
    + + +
    + `); + + me.page.main.find('.' + docname).parent().find('.document-html').show(); + me.page.main.find('.' + docname).parent().find('.document-html').attr('data-fetched', '1'); } - }, - freeze: true + } }); } } }); - this.page.main.on("click", ".btn-less", function() { - var docname = $(this).attr("data-docname"); - me.page.main.find("."+docname).parent().find('.document-id').show(); - me.page.main.find("."+docname).parent().find('.document-html').hide(); + this.page.main.on('click', '.btn-less', function() { + let docname = $(this).attr('data-docname'); + me.page.main.find('.' + docname).parent().find('.document-id').show(); + me.page.main.find('.' + docname).parent().find('.document-html').hide(); }); me.start = 0; - me.page.main.on("click", ".btn-get-records", function(){ + me.page.main.on('click', '.btn-get-records', function(){ get_documents(patient.get_value(), me); }); }; -var get_documents = function(patient, me){ +let get_documents = function(patient, me) { frappe.call({ - "method": "erpnext.healthcare.page.patient_history.patient_history.get_feed", + 'method': 'erpnext.healthcare.page.patient_history.patient_history.get_feed', args: { name: patient, start: me.start, page_length: 20 }, - callback: function (r) { - var data = r.message; - if(data.length){ + callback: function(r) { + let data = r.message; + if (data.length) { add_to_records(me, data); - }else{ - me.page.main.find(".patient_documents_list").append("


    No more records..

    "); - me.page.main.find(".btn-get-records").hide(); + } else { + me.page.main.find('.patient_documents_list').append(` +
    +

    ${__('No more records..')}

    +
    `); + me.page.main.find('.btn-get-records').hide(); } } }); }; -var add_to_records = function(me, data){ - var details = ""; - me.page.main.find(".patient_documents_list").append(details); + + details += ''; + me.page.main.find('.patient_documents_list').append(details); me.start += data.length; - if(data.length===20){ + + if (data.length === 20) { me.page.main.find(".btn-get-records").show(); - }else{ + } else { me.page.main.find(".btn-get-records").hide(); - me.page.main.find(".patient_documents_list").append("


    No more records..

    "); + me.page.main.find(".patient_documents_list").append(` +
    +

    ${__('No more records..')}

    +
    `); } }; -var add_date_separator = function(data) { - var date = frappe.datetime.str_to_obj(data.creation); +let add_date_separator = function(data) { + let date = frappe.datetime.str_to_obj(data.creation); + let pdate = ''; + let diff = frappe.datetime.get_day_diff(frappe.datetime.get_today(), frappe.datetime.obj_to_str(date)); - var diff = frappe.datetime.get_day_diff(frappe.datetime.get_today(), frappe.datetime.obj_to_str(date)); - if(diff < 1) { - var pdate = __('Today'); - } else if(diff < 2) { + if (diff < 1) { + pdate = __('Today'); + } else if (diff < 2) { pdate = __('Yesterday'); } else { pdate = __('on ') + frappe.datetime.global_date_format(date); @@ -187,107 +212,118 @@ var add_date_separator = function(data) { return data; }; -var show_patient_info = function(patient, me){ +let show_patient_info = function(patient, me) { frappe.call({ - "method": "erpnext.healthcare.doctype.patient.patient.get_patient_detail", + 'method': 'erpnext.healthcare.doctype.patient.patient.get_patient_detail', args: { patient: patient }, - callback: function (r) { - var data = r.message; - var details = ""; - if(data.image){ - details += "
    "; + callback: function(r) { + let data = r.message; + let details = ''; + if (data.image){ + details += `
    `; } - details += "" + data.patient_name +"
    " + data.sex; - if(data.email) details += "
    " + data.email; - if(data.mobile) details += "
    " + data.mobile; - if(data.occupation) details += "

    Occupation : " + data.occupation; - if(data.blood_group) details += "
    Blood group : " + data.blood_group; - if(data.allergies) details += "

    Allergies : "+ data.allergies.replace("\n", "
    "); - if(data.medication) details += "
    Medication : "+ data.medication.replace("\n", "
    "); - if(data.alcohol_current_use) details += "

    Alcohol use : "+ data.alcohol_current_use; - if(data.alcohol_past_use) details += "
    Alcohol past use : "+ data.alcohol_past_use; - if(data.tobacco_current_use) details += "
    Tobacco use : "+ data.tobacco_current_use; - if(data.tobacco_past_use) details += "
    Tobacco past use : "+ data.tobacco_past_use; - if(data.medical_history) details += "

    Medical history : "+ data.medical_history.replace("\n", "
    "); - if(data.surgical_history) details += "
    Surgical history : "+ data.surgical_history.replace("\n", "
    "); - if(data.surrounding_factors) details += "

    Occupational hazards : "+ data.surrounding_factors.replace("\n", "
    "); - if(data.other_risk_factors) details += "
    Other risk factors : " + data.other_risk_factors.replace("\n", "
    "); - if(data.patient_details) details += "

    More info : " + data.patient_details.replace("\n", "
    "); - if(details){ - details = "
    " + details + "
    "; + details += ` ${data.patient_name}
    ${data.sex}`; + if (data.email) details += `
    ${data.email}` + if (data.mobile) details += `
    ${data.mobile}`; + if (data.occupation) details += `

    ${__('Occupation')} : ${data.occupation}`; + if (data.blood_group) details += `
    ${__('Blood Group')} : ${data.blood_group}`; + if (data.allergies) details += `

    ${__('Allerigies')} : ${data.allergies.replace("\n", ", ")}`; + if (data.medication) details += `
    ${__('Medication')} : ${data.medication.replace("\n", ", ")}`; + if (data.alcohol_current_use) details += `

    ${__('Alcohol use')} : ${data.alcohol_current_use}`; + if (data.alcohol_past_use) details += `
    ${__('Alcohol past use')} : ${data.alcohol_past_use}`; + if (data.tobacco_current_use) details += `
    ${__('Tobacco use')} : ${data.tobacco_current_use}`; + if (data.tobacco_past_use) details += `
    ${__('Tobacco past use')} : ${data.tobacco_past_use}`; + if (data.medical_history) details += `

    ${__('Medical history')} : ${data.medical_history.replace("\n", ", ")}`; + if (data.surgical_history) details += `
    ${__('Surgical history')} : ${data.surgical_history.replace("\n", ", ")}`; + if (data.surrounding_factors) details += `

    ${__('Occupational hazards')} : ${data.surrounding_factors.replace("\n", ", ")}`; + if (data.other_risk_factors) details += `
    ${__('Other risk factors')} : ${data.other_risk_factors.replace("\n", ", ")}`; + if (data.patient_details) details += `

    ${__('More info')} : ${data.patient_details.replace("\n", ", ")}`; + + if (details){ + details = `
    ` + details + `
    `; } - me.page.main.find(".patient_details").html(details); + me.page.main.find('.patient_details').html(details); } }); }; -var show_patient_vital_charts = function(patient, me, btn_show_id, pts, title) { +let show_patient_vital_charts = function(patient, me, btn_show_id, pts, title) { frappe.call({ - method: "erpnext.healthcare.utils.get_patient_vitals", + method: 'erpnext.healthcare.utils.get_patient_vitals', args:{ patient: patient }, callback: function(r) { - if (r.message){ - var show_chart_btns_html = ""; - me.page.main.find(".show_chart_btns").html(show_chart_btns_html); - var data = r.message; + if (r.message) { + let show_chart_btns_html = ` + `; + + me.page.main.find('.show_chart_btns').html(show_chart_btns_html); + let data = r.message; let labels = [], datasets = []; let bp_systolic = [], bp_diastolic = [], temperature = []; let pulse = [], respiratory_rate = [], bmi = [], height = [], weight = []; - for(var i=0; i d + ' ' + pts, } }); - }else{ - me.page.main.find(".patient_vital_charts").html(""); - me.page.main.find(".show_chart_btns").html(""); + } else { + me.page.main.find('.patient_vital_charts').html(''); + me.page.main.find('.show_chart_btns').html(''); } } }); From fc1e352adf3f7efbbf243a029714d3c8eef0720f Mon Sep 17 00:00:00 2001 From: Rucha Mahabal Date: Sun, 29 Nov 2020 22:38:14 +0530 Subject: [PATCH 106/477] feat: Doctype filter for Patient History --- .../page/patient_history/patient_history.css | 5 ++ .../page/patient_history/patient_history.html | 8 +++ .../page/patient_history/patient_history.js | 58 ++++++++++++++---- .../page/patient_history/patient_history.py | 59 ++++++++++++------- 4 files changed, 98 insertions(+), 32 deletions(-) diff --git a/erpnext/healthcare/page/patient_history/patient_history.css b/erpnext/healthcare/page/patient_history/patient_history.css index 865d6abee00..1bb589164e6 100644 --- a/erpnext/healthcare/page/patient_history/patient_history.css +++ b/erpnext/healthcare/page/patient_history/patient_history.css @@ -109,6 +109,11 @@ padding-right: 0px; } +.patient-history-filter { + margin-left: 35px; + width: 25%; +} + #page-medical_record .plot-wrapper { padding: 20px 15px; border-bottom: 1px solid #d1d8dd; diff --git a/erpnext/healthcare/page/patient_history/patient_history.html b/erpnext/healthcare/page/patient_history/patient_history.html index 60f4501fed1..00b38e7258d 100644 --- a/erpnext/healthcare/page/patient_history/patient_history.html +++ b/erpnext/healthcare/page/patient_history/patient_history.html @@ -10,6 +10,14 @@
    +
    +
    +
    +
    +
    +
    +
    +
    diff --git a/erpnext/healthcare/page/patient_history/patient_history.js b/erpnext/healthcare/page/patient_history/patient_history.js index 5f1851fb0f3..40b86fdff4d 100644 --- a/erpnext/healthcare/page/patient_history/patient_history.js +++ b/erpnext/healthcare/page/patient_history/patient_history.js @@ -20,14 +20,16 @@ frappe.pages['patient_history'].on_page_load = function(wrapper) { placeholder: __('Select Patient'), only_select: true, change: function(){ - if (pid != patient.get_value() && patient.get_value()) { + let patient_id = patient.get_value(); + if (pid != patient_id && patient_id) { me.start = 0; me.page.main.find('.patient_documents_list').html(''); - get_documents(patient.get_value(), me); - show_patient_info(patient.get_value(), me); - show_patient_vital_charts(patient.get_value(), me, 'bp', 'mmHg', 'Blood Pressure'); + setup_filters(patient_id, me) + get_documents(patient_id, me); + show_patient_info(patient_id, me); + show_patient_vital_charts(patient_id, me, 'bp', 'mmHg', 'Blood Pressure'); } - pid = patient.get_value(); + pid = patient_id; } }, }); @@ -93,14 +95,48 @@ frappe.pages['patient_history'].on_page_load = function(wrapper) { }); }; -let get_documents = function(patient, me) { +let setup_filters = function(patient, me) { + frappe.xcall( + 'erpnext.healthcare.page.patient_history.patient_history.get_patient_history_doctypes' + ).then(document_types => { + let doctype_filter = frappe.ui.form.make_control({ + parent: $('.doctype-filter'), + df: { + fieldtype: 'MultiSelectList', + fieldname: 'document_type', + placeholder: __('Select Document Type'), + input_class: 'input-xs', + change: () => { + me.start = 0; + me.page.main.find('.patient_documents_list').html(''); + get_documents(patient, me, doctype_filter.get_value()); + }, + get_data: () => { + return document_types.map(document_type => { + return { + description: document_type, + value: document_type + }; + }); + }, + } + }); + doctype_filter.refresh(); + }) +} + +let get_documents = function(patient, me, document_types="") { + let filters = { + name: patient, + start: me.start, + page_length: 20 + }; + if (document_types) + filters['document_types'] = document_types; + frappe.call({ 'method': 'erpnext.healthcare.page.patient_history.patient_history.get_feed', - args: { - name: patient, - start: me.start, - page_length: 20 - }, + args: filters, callback: function(r) { let data = r.message; if (data.length) { diff --git a/erpnext/healthcare/page/patient_history/patient_history.py b/erpnext/healthcare/page/patient_history/patient_history.py index 772aa4ef5eb..c04b3761970 100644 --- a/erpnext/healthcare/page/patient_history/patient_history.py +++ b/erpnext/healthcare/page/patient_history/patient_history.py @@ -4,36 +4,53 @@ from __future__ import unicode_literals import frappe +import json from frappe.utils import cint from erpnext.healthcare.utils import render_docs_as_html @frappe.whitelist() -def get_feed(name, start=0, page_length=20): +def get_feed(name, document_types=None, start=0, page_length=20): """get feed""" - result = frappe.db.sql("""select name, owner, creation, - reference_doctype, reference_name, subject - from `tabPatient Medical Record` - where patient=%(patient)s - order by creation desc - limit %(start)s, %(page_length)s""", - { - "patient": name, - "start": cint(start), - "page_length": cint(page_length) - }, as_dict=True) + filters = {'patient': name} + if document_types: + document_types = json.loads(document_types) + filters['reference_doctype'] = ['IN', document_types] + + result = frappe.db.get_all('Patient Medical Record', + fields=['name', 'owner', 'creation', + 'reference_doctype', 'reference_name', 'subject'], + filters=filters, + order_by='creation DESC', + limit=cint(page_length), + start=cint(start) + ) + return result @frappe.whitelist() def get_feed_for_dt(doctype, docname): """get feed""" - result = frappe.db.sql("""select name, owner, modified, creation, - reference_doctype, reference_name, subject - from `tabPatient Medical Record` - where reference_name=%(docname)s and reference_doctype=%(doctype)s - order by creation desc""", - { - "docname": docname, - "doctype": doctype - }, as_dict=True) + result = frappe.db.get_all('Patient Medical Record', + fields=['name', 'owner', 'creation', + 'reference_doctype', 'reference_name', 'subject'], + filters={ + 'reference_doctype': doctype, + 'reference_name': docname + }, + order_by='creation DESC' + ) return result + +@frappe.whitelist() +def get_patient_history_doctypes(): + document_types = [] + settings = frappe.get_single("Patient History Settings") + + for entry in settings.standard_doctypes: + document_types.append(entry.document_type) + + for entry in settings.custom_doctypes: + document_types.append(entry.document_type) + + return document_types \ No newline at end of file From 4af3d4e4bb745f35549ce3b638981206c1f84a3e Mon Sep 17 00:00:00 2001 From: Rucha Mahabal Date: Sun, 29 Nov 2020 22:43:56 +0530 Subject: [PATCH 107/477] fix: feed not visible when filter is reset --- erpnext/healthcare/page/patient_history/patient_history.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/erpnext/healthcare/page/patient_history/patient_history.py b/erpnext/healthcare/page/patient_history/patient_history.py index c04b3761970..b8494c9e587 100644 --- a/erpnext/healthcare/page/patient_history/patient_history.py +++ b/erpnext/healthcare/page/patient_history/patient_history.py @@ -14,7 +14,8 @@ def get_feed(name, document_types=None, start=0, page_length=20): filters = {'patient': name} if document_types: document_types = json.loads(document_types) - filters['reference_doctype'] = ['IN', document_types] + if len(document_types): + filters['reference_doctype'] = ['IN', document_types] result = frappe.db.get_all('Patient Medical Record', fields=['name', 'owner', 'creation', From 4d6d115a4d43aa3b7c6ebf2604998a2a4728050c Mon Sep 17 00:00:00 2001 From: Rucha Mahabal Date: Sun, 29 Nov 2020 23:16:12 +0530 Subject: [PATCH 108/477] feat: date range filter for Patient History --- .../page/patient_history/patient_history.html | 3 +- .../page/patient_history/patient_history.js | 27 +++++++++++++++-- .../page/patient_history/patient_history.py | 30 ++++++++++++++----- 3 files changed, 48 insertions(+), 12 deletions(-) diff --git a/erpnext/healthcare/page/patient_history/patient_history.html b/erpnext/healthcare/page/patient_history/patient_history.html index 00b38e7258d..deaaa97868c 100644 --- a/erpnext/healthcare/page/patient_history/patient_history.html +++ b/erpnext/healthcare/page/patient_history/patient_history.html @@ -14,8 +14,7 @@
    -
    -
    +
    diff --git a/erpnext/healthcare/page/patient_history/patient_history.js b/erpnext/healthcare/page/patient_history/patient_history.js index 40b86fdff4d..5a6295b7079 100644 --- a/erpnext/healthcare/page/patient_history/patient_history.js +++ b/erpnext/healthcare/page/patient_history/patient_history.js @@ -109,7 +109,7 @@ let setup_filters = function(patient, me) { change: () => { me.start = 0; me.page.main.find('.patient_documents_list').html(''); - get_documents(patient, me, doctype_filter.get_value()); + get_documents(patient, me, doctype_filter.get_value(), date_range_field.get_value()); }, get_data: () => { return document_types.map(document_type => { @@ -122,10 +122,29 @@ let setup_filters = function(patient, me) { } }); doctype_filter.refresh(); - }) + + let date_range_field = frappe.ui.form.make_control({ + df: { + fieldtype: 'DateRange', + fieldname: 'date_range', + placeholder: __('Date Range'), + input_class: 'input-xs', + change: () => { + let selected_date_range = date_range_field.get_value(); + if (selected_date_range && selected_date_range.length === 2) { + me.start = 0; + me.page.main.find('.patient_documents_list').html(''); + get_documents(patient, me, doctype_filter.get_value(), selected_date_range); + } + } + }, + parent: $('.date-filter') + }); + date_range_field.refresh(); + }); } -let get_documents = function(patient, me, document_types="") { +let get_documents = function(patient, me, document_types="", selected_date_range="") { let filters = { name: patient, start: me.start, @@ -133,6 +152,8 @@ let get_documents = function(patient, me, document_types="") { }; if (document_types) filters['document_types'] = document_types; + if (selected_date_range) + filters['date_range'] = selected_date_range; frappe.call({ 'method': 'erpnext.healthcare.page.patient_history.patient_history.get_feed', diff --git a/erpnext/healthcare/page/patient_history/patient_history.py b/erpnext/healthcare/page/patient_history/patient_history.py index b8494c9e587..de8a5771d2f 100644 --- a/erpnext/healthcare/page/patient_history/patient_history.py +++ b/erpnext/healthcare/page/patient_history/patient_history.py @@ -9,13 +9,9 @@ from frappe.utils import cint from erpnext.healthcare.utils import render_docs_as_html @frappe.whitelist() -def get_feed(name, document_types=None, start=0, page_length=20): +def get_feed(name, document_types=None, date_range=None, start=0, page_length=20): """get feed""" - filters = {'patient': name} - if document_types: - document_types = json.loads(document_types) - if len(document_types): - filters['reference_doctype'] = ['IN', document_types] + filters = get_filters(name, document_types, date_range) result = frappe.db.get_all('Patient Medical Record', fields=['name', 'owner', 'creation', @@ -28,6 +24,25 @@ def get_feed(name, document_types=None, start=0, page_length=20): return result + +def get_filters(name, document_types=None, date_range=None): + filters = {'patient': name} + if document_types: + document_types = json.loads(document_types) + if len(document_types): + filters['reference_doctype'] = ['IN', document_types] + + if date_range: + try: + date_range = json.loads(date_range) + if date_range: + filters['creation'] = ['between', [date_range[0], date_range[1]]] + except json.decoder.JSONDecodeError: + pass + + return filters + + @frappe.whitelist() def get_feed_for_dt(doctype, docname): """get feed""" @@ -43,6 +58,7 @@ def get_feed_for_dt(doctype, docname): return result + @frappe.whitelist() def get_patient_history_doctypes(): document_types = [] @@ -54,4 +70,4 @@ def get_patient_history_doctypes(): for entry in settings.custom_doctypes: document_types.append(entry.document_type) - return document_types \ No newline at end of file + return document_types From 06e7cc2c35bf526f5a7bfba81d645ed4028a276b Mon Sep 17 00:00:00 2001 From: Rucha Mahabal Date: Mon, 30 Nov 2020 12:01:48 +0530 Subject: [PATCH 109/477] fix: Handle table field rendering in Patient Medical record --- .../patient_history_settings.py | 38 +++++++++++++++++-- 1 file changed, 34 insertions(+), 4 deletions(-) diff --git a/erpnext/healthcare/doctype/patient_history_settings/patient_history_settings.py b/erpnext/healthcare/doctype/patient_history_settings/patient_history_settings.py index af8c6f45574..759fcadef26 100644 --- a/erpnext/healthcare/doctype/patient_history_settings/patient_history_settings.py +++ b/erpnext/healthcare/doctype/patient_history_settings/patient_history_settings.py @@ -51,10 +51,16 @@ def set_subject_field(doc): for entry in patient_history_fields: fieldname = entry.get('fieldname') - if doc.get(fieldname): - formated_value = format_value(doc.get(fieldname), meta.get_field(fieldname), doc) - subject += frappe.bold(_(entry.get('label')) + ': ') + cstr(formated_value) - subject += '
    ' + if entry.get('fieldtype') == 'Table' and doc.get(fieldname): + formatted_value = get_formatted_value_for_table_field(doc.get(fieldname), meta.get_field(fieldname)) + subject += frappe.bold(_(entry.get('label')) + ': ') + '
    ' + cstr(formatted_value) + + else: + if doc.get(fieldname): + formatted_value = format_value(doc.get(fieldname), meta.get_field(fieldname), doc) + subject += frappe.bold(_(entry.get('label')) + ': ') + cstr(formatted_value) + + subject += '
    ' return subject @@ -72,3 +78,27 @@ def get_patient_history_fields(doc): if patient_history_fields: return json.loads(patient_history_fields) + +def get_formatted_value_for_table_field(items, df): + child_meta = frappe.get_meta(df.options) + + table_head = '' + table_row = '' + html = '' + create_head = True + for item in items: + table_row += '' + for cdf in child_meta.fields: + if cdf.in_list_view: + if create_head: + table_head += '' + cdf.label + '' + if item.get(cdf.fieldname): + table_row += '' + str(item.get(cdf.fieldname)) + '' + else: + table_row += '' + create_head = False + table_row += '' + + html += "" + table_head + table_row + '
    ' + + return html From f3df5c9f3cec4db7092c301d03897eca3acc67e0 Mon Sep 17 00:00:00 2001 From: Rucha Mahabal Date: Mon, 30 Nov 2020 12:16:28 +0530 Subject: [PATCH 110/477] feat: patch to setup standard doctype config in Patient History Settings --- .../healthcare/doctype/lab_test/lab_test.json | 6 +- .../patient_encounter/patient_encounter.json | 4 +- ...atient_history_standard_document_type.json | 11 ++- erpnext/healthcare/setup.py | 80 +++++++++++++++++++ erpnext/patches.txt | 1 + ..._history_settings_for_standard_doctypes.py | 9 +++ 6 files changed, 107 insertions(+), 4 deletions(-) create mode 100644 erpnext/patches/v13_0/setup_patient_history_settings_for_standard_doctypes.py diff --git a/erpnext/healthcare/doctype/lab_test/lab_test.json b/erpnext/healthcare/doctype/lab_test/lab_test.json index edf1d911aac..ac61fea3ad7 100644 --- a/erpnext/healthcare/doctype/lab_test/lab_test.json +++ b/erpnext/healthcare/doctype/lab_test/lab_test.json @@ -359,6 +359,7 @@ { "fieldname": "normal_test_items", "fieldtype": "Table", + "label": "Normal Test Result", "options": "Normal Test Result", "print_hide": 1 }, @@ -380,6 +381,7 @@ { "fieldname": "sensitivity_test_items", "fieldtype": "Table", + "label": "Sensitivity Test Result", "options": "Sensitivity Test Result", "print_hide": 1, "report_hide": 1 @@ -529,6 +531,7 @@ { "fieldname": "descriptive_test_items", "fieldtype": "Table", + "label": "Descriptive Test Result", "options": "Descriptive Test Result", "print_hide": 1, "report_hide": 1 @@ -549,13 +552,14 @@ { "fieldname": "organism_test_items", "fieldtype": "Table", + "label": "Organism Test Result", "options": "Organism Test Result", "print_hide": 1 } ], "is_submittable": 1, "links": [], - "modified": "2020-07-30 18:18:38.516215", + "modified": "2020-11-30 11:04:17.195848", "modified_by": "Administrator", "module": "Healthcare", "name": "Lab Test", diff --git a/erpnext/healthcare/doctype/patient_encounter/patient_encounter.json b/erpnext/healthcare/doctype/patient_encounter/patient_encounter.json index 15675f4673f..b646ff9ebe6 100644 --- a/erpnext/healthcare/doctype/patient_encounter/patient_encounter.json +++ b/erpnext/healthcare/doctype/patient_encounter/patient_encounter.json @@ -210,7 +210,7 @@ { "fieldname": "drug_prescription", "fieldtype": "Table", - "label": "Items", + "label": "Drug Prescription", "options": "Drug Prescription" }, { @@ -328,7 +328,7 @@ ], "is_submittable": 1, "links": [], - "modified": "2020-05-16 21:00:08.644531", + "modified": "2020-11-30 10:39:00.783119", "modified_by": "Administrator", "module": "Healthcare", "name": "Patient Encounter", diff --git a/erpnext/healthcare/doctype/patient_history_standard_document_type/patient_history_standard_document_type.json b/erpnext/healthcare/doctype/patient_history_standard_document_type/patient_history_standard_document_type.json index ef4fc2bfe1e..9c9d0cb4cd8 100644 --- a/erpnext/healthcare/doctype/patient_history_standard_document_type/patient_history_standard_document_type.json +++ b/erpnext/healthcare/doctype/patient_history_standard_document_type/patient_history_standard_document_type.json @@ -6,6 +6,7 @@ "engine": "InnoDB", "field_order": [ "document_type", + "date_fieldname", "add_edit_fields", "selected_fields" ], @@ -29,12 +30,20 @@ "fieldtype": "Button", "in_list_view": 1, "label": "Add / Edit Fields" + }, + { + "fieldname": "date_fieldname", + "fieldtype": "Data", + "in_list_view": 1, + "label": "Date Fieldname", + "read_only": 1, + "reqd": 1 } ], "index_web_pages_for_search": 1, "istable": 1, "links": [], - "modified": "2020-11-28 18:57:30.446348", + "modified": "2020-11-30 12:15:14.940935", "modified_by": "Administrator", "module": "Healthcare", "name": "Patient History Standard Document Type", diff --git a/erpnext/healthcare/setup.py b/erpnext/healthcare/setup.py index 06840801d37..bf4df7e4c88 100644 --- a/erpnext/healthcare/setup.py +++ b/erpnext/healthcare/setup.py @@ -16,6 +16,7 @@ def setup_healthcare(): create_healthcare_item_groups() create_sensitivity() add_healthcare_service_unit_tree_root() + setup_patient_history_settings() def create_medical_departments(): departments = [ @@ -213,3 +214,82 @@ def get_company(): if company: return company[0].name return None + +def setup_patient_history_settings(): + import json + + settings = frappe.get_single('Patient History Settings') + configuration = get_patient_history_config() + for dt, config in configuration.items(): + settings.append("standard_doctypes", { + "document_type": dt, + "date_fieldname": config[0], + "selected_fields": json.dumps(config[1]) + }) + settings.save() + +def get_patient_history_config(): + return { + "Patient Encounter": ("encounter_date", [ + {"label": "Healthcare Practitioner", "fieldname": "practitioner", "fieldtype": "Link"}, + {"label": "Symptoms", "fieldname": "symptoms", "fieldtype": "Table Multiselect"}, + {"label": "Diagnosis", "fieldname": "diagnosis", "fieldtype": "Table Multiselect"}, + {"label": "Drug Prescription", "fieldname": "drug_prescription", "fieldtype": "Table"}, + {"label": "Lab Tests", "fieldname": "lab_test_prescription", "fieldtype": "Table"}, + {"label": "Clinical Procedures", "fieldname": "procedure_prescription", "fieldtype": "Table"}, + {"label": "Therapies", "fieldname": "therapies", "fieldtype": "Table"}, + {"label": "Review Details", "fieldname": "encounter_comment", "fieldtype": "Small Text"} + ]), + "Clinical Procedure": ("start_date", [ + {"label": "Procedure Template", "fieldname": "procedure_template", "fieldtype": "Link"}, + {"label": "Healthcare Practitioner", "fieldname": "practitioner", "fieldtype": "Link"}, + {"label": "Notes", "fieldname": "notes", "fieldtype": "Small Text"}, + {"label": "Service Unit", "fieldname": "service_unit", "fieldtype": "Healthcare Service Unit"}, + {"label": "Start Time", "fieldname": "start_time", "fieldtype": "Time"}, + {"label": "Sample", "fieldname": "sample", "fieldtype": "Link"} + ]), + "Lab Test": ("result_date", [ + {"label": "Test Template", "fieldname": "template", "fieldtype": "Link"}, + {"label": "Healthcare Practitioner", "fieldname": "practitioner", "fieldtype": "Link"}, + {"label": "Test Name", "fieldname": "lab_test_name", "fieldtype": "Data"}, + {"label": "Lab Technician Name", "fieldname": "employee_name", "fieldtype": "Data"}, + {"label": "Sample ID", "fieldname": "sample", "fieldtype": "Link"}, + {"label": "Normal Test Result", "fieldname": "normal_test_items", "fieldtype": "Table"}, + {"label": "Descriptive Test Result", "fieldname": "descriptive_test_items", "fieldtype": "Table"}, + {"label": "Organism Test Result", "fieldname": "organism_test_items", "fieldtype": "Table"}, + {"label": "Sensitivity Test Result", "fieldname": "sensitivity_test_items", "fieldtype": "Table"}, + {"label": "Comments", "fieldname": "lab_test_comment", "fieldtype": "Table"} + ]), + "Therapy Session": ("start_date", [ + {"label": "Therapy Type", "fieldname": "therapy_type", "fieldtype": "Link"}, + {"label": "Healthcare Practitioner", "fieldname": "practitioner", "fieldtype": "Link"}, + {"label": "Therapy Plan", "fieldname": "therapy_plan", "fieldtype": "Link"}, + {"label": "Duration", "fieldname": "duration", "fieldtype": "Int"}, + {"label": "Location", "fieldname": "location", "fieldtype": "Link"}, + {"label": "Healthcare Service Unit", "fieldname": "service_unit", "fieldtype": "Link"}, + {"label": "Start Time", "fieldname": "start_time", "fieldtype": "Time"}, + {"label": "Exercises", "fieldname": "exercises", "fieldtype": "Table"}, + {"label": "Total Counts Targeted", "fieldname": "total_counts_targeted", "fieldtype": "Int"}, + {"label": "Total Counts Completed", "fieldname": "total_counts_completed", "fieldtype": "Int"} + ]), + "Vital Signs": ("signs_date", [ + {"label": "Body Temperature", "fieldname": "temperature", "fieldtype": "Data"}, + {"label": "Heart Rate / Pulse", "fieldname": "pulse", "fieldtype": "Data"}, + {"label": "Respiratory rate", "fieldname": "respiratory_rate", "fieldtype": "Data"}, + {"label": "Tongue", "fieldname": "tongue", "fieldtype": "Select"}, + {"label": "Abdomen", "fieldname": "abdomen", "fieldtype": "Select"}, + {"label": "Reflexes", "fieldname": "reflexes", "fieldtype": "Select"}, + {"label": "Blood Pressure", "fieldname": "bp", "fieldtype": "Data"}, + {"label": "Notes", "fieldname": "vital_signs_note", "fieldtype": "Small Text"}, + {"label": "Height (In Meter)", "fieldname": "height", "fieldtype": "Float"}, + {"label": "Weight (In Kilogram)", "fieldname": "weight", "fieldtype": "Float"}, + {"label": "BMI", "fieldname": "bmi", "fieldtype": "Float"} + ]), + "Inpatient Medication Order": ("start_date", [ + {"label": "Healthcare Practitioner", "fieldname": "practitioner", "fieldtype": "Link"}, + {"label": "Start Date", "fieldname": "start_date", "fieldtype": "Date"}, + {"label": "End Date", "fieldname": "end_date", "fieldtype": "Date"}, + {"label": "Medication Orders", "fieldname": "medication_orders", "fieldtype": "Table"}, + {"label": "Total Orders", "fieldname": "total_orders", "fieldtype": "Float"} + ]) + } \ No newline at end of file diff --git a/erpnext/patches.txt b/erpnext/patches.txt index 25be8841174..fcb63ed6e4d 100644 --- a/erpnext/patches.txt +++ b/erpnext/patches.txt @@ -735,3 +735,4 @@ erpnext.patches.v13_0.create_healthcare_custom_fields_in_stock_entry_detail erpnext.patches.v13_0.update_reason_for_resignation_in_employee erpnext.patches.v13_0.update_custom_fields_for_shopify execute:frappe.delete_doc("Report", "Quoted Item Comparison") +erpnext.patches.v13_0.setup_patient_history_settings_for_standard_doctypes diff --git a/erpnext/patches/v13_0/setup_patient_history_settings_for_standard_doctypes.py b/erpnext/patches/v13_0/setup_patient_history_settings_for_standard_doctypes.py new file mode 100644 index 00000000000..3332be05613 --- /dev/null +++ b/erpnext/patches/v13_0/setup_patient_history_settings_for_standard_doctypes.py @@ -0,0 +1,9 @@ +from __future__ import unicode_literals +import frappe +from erpnext.healthcare.setup import setup_patient_history_settings + +def execute(): + if 'Healthcare' not in frappe.get_active_domains(): + return + + setup_patient_history_settings() \ No newline at end of file From 4097e89f8b80140389eec6b29aea337d3a7835f0 Mon Sep 17 00:00:00 2001 From: Rucha Mahabal Date: Mon, 30 Nov 2020 12:48:39 +0530 Subject: [PATCH 111/477] feat: Standard doctype config for Patient History --- .../patient_history_settings.js | 17 ++++++++++++-- .../patient_history_settings.py | 22 ++++++++++++++----- erpnext/hooks.py | 1 + 3 files changed, 33 insertions(+), 7 deletions(-) diff --git a/erpnext/healthcare/doctype/patient_history_settings/patient_history_settings.js b/erpnext/healthcare/doctype/patient_history_settings/patient_history_settings.js index 60926eeb119..c3d0dce6756 100644 --- a/erpnext/healthcare/doctype/patient_history_settings/patient_history_settings.js +++ b/erpnext/healthcare/doctype/patient_history_settings/patient_history_settings.js @@ -13,7 +13,7 @@ frappe.ui.form.on('Patient History Settings', { }); }, - field_selector: function(frm, doc) { + field_selector: function(frm, doc, standard=1) { let document_fields = (JSON.parse(doc.selected_fields)).map(f => f.fieldname); let d = new frappe.ui.Dialog({ title: __('{0} Fields', [__(doc.document_type)]), @@ -45,8 +45,12 @@ frappe.ui.form.on('Patient History Settings', { }); } } + let doctype = 'Patient History Custom Document Type'; + if (standard) + doctype = 'Patient History Standard Document Type'; - frappe.model.set_value('Patient History Custom Document Type', doc.name, 'selected_fields', JSON.stringify(selected_fields)); + + frappe.model.set_value(doctype, doc.name, 'selected_fields', JSON.stringify(selected_fields)); d.hide(); }); @@ -75,6 +79,15 @@ frappe.ui.form.on('Patient History Settings', { }); frappe.ui.form.on('Patient History Custom Document Type', { + add_edit_fields: function(frm, cdt, cdn) { + let row = locals[cdt][cdn]; + if (row.document_type) { + frm.events.field_selector(frm, row, standard=0); + } + } +}); + +frappe.ui.form.on('Patient History Standard Document Type', { add_edit_fields: function(frm, cdt, cdn) { let row = locals[cdt][cdn]; if (row.document_type) { diff --git a/erpnext/healthcare/doctype/patient_history_settings/patient_history_settings.py b/erpnext/healthcare/doctype/patient_history_settings/patient_history_settings.py index 759fcadef26..20b062e909e 100644 --- a/erpnext/healthcare/doctype/patient_history_settings/patient_history_settings.py +++ b/erpnext/healthcare/doctype/patient_history_settings/patient_history_settings.py @@ -7,6 +7,7 @@ import frappe from frappe import _ from frappe.utils import cstr from frappe.model.document import Document +from erpnext.healthcare.page.patient_history.patient_history import get_patient_history_doctypes class PatientHistorySettings(Document): def validate(self): @@ -29,6 +30,9 @@ def create_medical_record(doc, method=None): frappe.db.get_value('Doctype', doc.doctype, 'module') != 'Healthcare': return + if doc.doctype not in get_patient_history_doctypes(): + return + subject = set_subject_field(doc) date_field = get_date_field(doc.doctype) medical_record = frappe.new_doc('Patient Medical Record') @@ -66,14 +70,15 @@ def set_subject_field(doc): def get_date_field(doctype): - return frappe.db.get_value('Patient History Custom Document Type', - { 'document_type': doctype }, 'date_fieldname') + dt = get_patient_history_config_dt(doctype) + + return frappe.db.get_value(dt, { 'document_type': doctype }, 'date_fieldname') def get_patient_history_fields(doc): import json - patient_history_fields = frappe.db.get_value('Patient History Custom Document Type', - { 'document_type': doc.doctype }, 'selected_fields') + dt = get_patient_history_config_dt(doc.doctype) + patient_history_fields = frappe.db.get_value(dt, { 'document_type': doc.doctype }, 'selected_fields') if patient_history_fields: return json.loads(patient_history_fields) @@ -99,6 +104,13 @@ def get_formatted_value_for_table_field(items, df): create_head = False table_row += '' - html += "" + table_head + table_row + '
    ' + html += "" + table_head + table_row + "
    " return html + + +def get_patient_history_config_dt(doctype): + if frappe.db.get_value('DocType', doctype, 'custom'): + return 'Patient History Custom Document Type' + else: + return 'Patient History Standard Document Type' diff --git a/erpnext/hooks.py b/erpnext/hooks.py index 4ee42c7559d..aa5291aa0e7 100644 --- a/erpnext/hooks.py +++ b/erpnext/hooks.py @@ -223,6 +223,7 @@ standard_queries = { doc_events = { "*": { "on_submit": "erpnext.healthcare.doctype.patient_history_settings.patient_history_settings.create_medical_record", + "on_cancel": "erpnext.healthcare.doctype.patient_history_settings.patient_history_settings.update_medical_record", "on_cancel": "erpnext.healthcare.doctype.patient_history_settings.patient_history_settings.delete_medical_record" }, "Stock Entry": { From c0fcc807d338ad614aa76f7ea03d2b804760da77 Mon Sep 17 00:00:00 2001 From: Rucha Mahabal Date: Mon, 30 Nov 2020 13:22:01 +0530 Subject: [PATCH 112/477] feat: hooks for updating and deleting medical records --- .../patient_history_settings.py | 41 +++++++++++++++++-- erpnext/hooks.py | 2 +- 2 files changed, 39 insertions(+), 4 deletions(-) diff --git a/erpnext/healthcare/doctype/patient_history_settings/patient_history_settings.py b/erpnext/healthcare/doctype/patient_history_settings/patient_history_settings.py index 20b062e909e..367c34f1e86 100644 --- a/erpnext/healthcare/doctype/patient_history_settings/patient_history_settings.py +++ b/erpnext/healthcare/doctype/patient_history_settings/patient_history_settings.py @@ -26,11 +26,11 @@ class PatientHistorySettings(Document): def create_medical_record(doc, method=None): - if frappe.flags.in_patch or frappe.flags.in_install or frappe.flags.in_setup_wizard or \ - frappe.db.get_value('Doctype', doc.doctype, 'module') != 'Healthcare': + medical_record_required = validate_medical_record_required(doc) + if not medical_record_required: return - if doc.doctype not in get_patient_history_doctypes(): + if frappe.db.exists('Patient Medical Record', { 'reference_name': doc.name }): return subject = set_subject_field(doc) @@ -46,6 +46,30 @@ def create_medical_record(doc, method=None): medical_record.save(ignore_permissions=True) +def update_medical_record(doc, method=None): + medical_record_required = validate_medical_record_required(doc) + if not medical_record_required: + return + + medical_record_id = frappe.db.exists('Patient Medical Record', { 'reference_name': doc.name }) + + if medical_record_id: + subject = set_subject_field(doc) + frappe.db.set_value('Patient Medical Record', medical_record_id[0][0], 'subject', subject) + else: + create_medical_record(doc) + + +def delete_medical_record(doc, method=None): + medical_record_required = validate_medical_record_required(doc) + if not medical_record_required: + return + + record = frappe.db.exists('Patient Medical Record', { 'reference_name': doc.name }) + if record: + frappe.delete_doc('Patient Medical Record', record, force=1) + + def set_subject_field(doc): from frappe.utils.formatters import format_value @@ -114,3 +138,14 @@ def get_patient_history_config_dt(doctype): return 'Patient History Custom Document Type' else: return 'Patient History Standard Document Type' + + +def validate_medical_record_required(doc): + if frappe.flags.in_patch or frappe.flags.in_install or frappe.flags.in_setup_wizard or \ + frappe.db.get_value('Doctype', doc.doctype, 'module') != 'Healthcare': + return False + + if doc.doctype not in get_patient_history_doctypes(): + return False + + return True \ No newline at end of file diff --git a/erpnext/hooks.py b/erpnext/hooks.py index aa5291aa0e7..51c169f4003 100644 --- a/erpnext/hooks.py +++ b/erpnext/hooks.py @@ -223,7 +223,7 @@ standard_queries = { doc_events = { "*": { "on_submit": "erpnext.healthcare.doctype.patient_history_settings.patient_history_settings.create_medical_record", - "on_cancel": "erpnext.healthcare.doctype.patient_history_settings.patient_history_settings.update_medical_record", + "on_update": "erpnext.healthcare.doctype.patient_history_settings.patient_history_settings.update_medical_record", "on_cancel": "erpnext.healthcare.doctype.patient_history_settings.patient_history_settings.delete_medical_record" }, "Stock Entry": { From c538a4a31d2c9f829a308e03a01d9eac5d537d0e Mon Sep 17 00:00:00 2001 From: Rucha Mahabal Date: Mon, 30 Nov 2020 13:22:34 +0530 Subject: [PATCH 113/477] refactor: remove medical record creation methods from individual doctypes --- .../clinical_procedure/clinical_procedure.py | 19 ------ .../healthcare/doctype/lab_test/lab_test.py | 56 ----------------- .../patient_encounter/patient_encounter.py | 62 +------------------ .../therapy_session/therapy_session.py | 21 ------- .../doctype/vital_signs/vital_signs.py | 40 ------------ 5 files changed, 1 insertion(+), 197 deletions(-) diff --git a/erpnext/healthcare/doctype/clinical_procedure/clinical_procedure.py b/erpnext/healthcare/doctype/clinical_procedure/clinical_procedure.py index e55a1433a51..c3242284674 100644 --- a/erpnext/healthcare/doctype/clinical_procedure/clinical_procedure.py +++ b/erpnext/healthcare/doctype/clinical_procedure/clinical_procedure.py @@ -100,7 +100,6 @@ class ClinicalProcedure(Document): allow_start = self.set_actual_qty() if allow_start: self.db_set('status', 'In Progress') - insert_clinical_procedure_to_medical_record(self) return 'success' return 'insufficient stock' @@ -247,21 +246,3 @@ def make_procedure(source_name, target_doc=None): }, target_doc, set_missing_values) return doc - - -def insert_clinical_procedure_to_medical_record(doc): - subject = frappe.bold(_("Clinical Procedure conducted: ")) + cstr(doc.procedure_template) + "
    " - if doc.practitioner: - subject += frappe.bold(_('Healthcare Practitioner: ')) + doc.practitioner - if subject and doc.notes: - subject += '
    ' + doc.notes - - medical_record = frappe.new_doc('Patient Medical Record') - medical_record.patient = doc.patient - medical_record.subject = subject - medical_record.status = 'Open' - medical_record.communication_date = doc.start_date - medical_record.reference_doctype = 'Clinical Procedure' - medical_record.reference_name = doc.name - medical_record.reference_owner = doc.owner - medical_record.save(ignore_permissions=True) diff --git a/erpnext/healthcare/doctype/lab_test/lab_test.py b/erpnext/healthcare/doctype/lab_test/lab_test.py index 2db77438653..4b57cd073d0 100644 --- a/erpnext/healthcare/doctype/lab_test/lab_test.py +++ b/erpnext/healthcare/doctype/lab_test/lab_test.py @@ -17,11 +17,9 @@ class LabTest(Document): self.validate_result_values() self.db_set('submitted_date', getdate()) self.db_set('status', 'Completed') - insert_lab_test_to_medical_record(self) def on_cancel(self): self.db_set('status', 'Cancelled') - delete_lab_test_from_medical_record(self) self.reload() def on_update(self): @@ -330,60 +328,6 @@ def get_employee_by_user_id(user_id): return frappe.get_doc('Employee', emp_id) return None -def insert_lab_test_to_medical_record(doc): - table_row = False - subject = cstr(doc.lab_test_name) - if doc.practitioner: - subject += frappe.bold(_('Healthcare Practitioner: '))+ doc.practitioner + '
    ' - if doc.normal_test_items: - item = doc.normal_test_items[0] - comment = '' - if item.lab_test_comment: - comment = str(item.lab_test_comment) - table_row = frappe.bold(_('Lab Test Conducted: ')) + item.lab_test_name - - if item.lab_test_event: - table_row += frappe.bold(_('Lab Test Event: ')) + item.lab_test_event - - if item.result_value: - table_row += ' ' + frappe.bold(_('Lab Test Result: ')) + item.result_value - - if item.normal_range: - table_row += ' ' + _('Normal Range: ') + item.normal_range - table_row += ' ' + comment - - elif doc.descriptive_test_items: - item = doc.descriptive_test_items[0] - - if item.lab_test_particulars and item.result_value: - table_row = item.lab_test_particulars + ' ' + item.result_value - - elif doc.sensitivity_test_items: - item = doc.sensitivity_test_items[0] - - if item.antibiotic and item.antibiotic_sensitivity: - table_row = item.antibiotic + ' ' + item.antibiotic_sensitivity - - if table_row: - subject += '
    ' + table_row - if doc.lab_test_comment: - subject += '
    ' + cstr(doc.lab_test_comment) - - medical_record = frappe.new_doc('Patient Medical Record') - medical_record.patient = doc.patient - medical_record.subject = subject - medical_record.status = 'Open' - medical_record.communication_date = doc.result_date - medical_record.reference_doctype = 'Lab Test' - medical_record.reference_name = doc.name - medical_record.reference_owner = doc.owner - medical_record.save(ignore_permissions = True) - -def delete_lab_test_from_medical_record(self): - medical_record_id = frappe.db.sql('select name from `tabPatient Medical Record` where reference_name=%s', (self.name)) - - if medical_record_id and medical_record_id[0][0]: - frappe.delete_doc('Patient Medical Record', medical_record_id[0][0]) @frappe.whitelist() def get_lab_test_prescribed(patient): diff --git a/erpnext/healthcare/doctype/patient_encounter/patient_encounter.py b/erpnext/healthcare/doctype/patient_encounter/patient_encounter.py index 87f42491fce..cc2141790f7 100644 --- a/erpnext/healthcare/doctype/patient_encounter/patient_encounter.py +++ b/erpnext/healthcare/doctype/patient_encounter/patient_encounter.py @@ -17,10 +17,6 @@ class PatientEncounter(Document): def on_update(self): if self.appointment: frappe.db.set_value('Patient Appointment', self.appointment, 'status', 'Closed') - update_encounter_medical_record(self) - - def after_insert(self): - insert_encounter_to_medical_record(self) def on_submit(self): if self.therapies: @@ -33,8 +29,6 @@ class PatientEncounter(Document): if self.inpatient_record and self.drug_prescription: delete_ip_medication_order(self) - delete_medical_record(self) - def set_title(self): self.title = _('{0} with {1}').format(self.patient_name or self.patient, self.practitioner_name or self.practitioner)[:100] @@ -102,61 +96,7 @@ def create_therapy_plan(encounter): frappe.msgprint(_('Therapy Plan {0} created successfully.').format(frappe.bold(doc.name)), alert=True) -def insert_encounter_to_medical_record(doc): - subject = set_subject_field(doc) - medical_record = frappe.new_doc('Patient Medical Record') - medical_record.patient = doc.patient - medical_record.subject = subject - medical_record.status = 'Open' - medical_record.communication_date = doc.encounter_date - medical_record.reference_doctype = 'Patient Encounter' - medical_record.reference_name = doc.name - medical_record.reference_owner = doc.owner - medical_record.save(ignore_permissions=True) - - -def update_encounter_medical_record(encounter): - medical_record_id = frappe.db.exists('Patient Medical Record', {'reference_name': encounter.name}) - - if medical_record_id and medical_record_id[0][0]: - subject = set_subject_field(encounter) - frappe.db.set_value('Patient Medical Record', medical_record_id[0][0], 'subject', subject) - else: - insert_encounter_to_medical_record(encounter) - - -def delete_medical_record(encounter): - record = frappe.db.exists('Patient Medical Record', {'reference_name', encounter.name}) - if record: - frappe.delete_doc('Patient Medical Record', record, force=1) - def delete_ip_medication_order(encounter): record = frappe.db.exists('Inpatient Medication Order', {'patient_encounter': encounter.name}) if record: - frappe.delete_doc('Inpatient Medication Order', record, force=1) - - -def set_subject_field(encounter): - subject = frappe.bold(_('Healthcare Practitioner: ')) + encounter.practitioner + '
    ' - if encounter.symptoms: - subject += frappe.bold(_('Symptoms: ')) + '
    ' - for entry in encounter.symptoms: - subject += cstr(entry.complaint) + '
    ' - else: - subject += frappe.bold(_('No Symptoms')) + '
    ' - - if encounter.diagnosis: - subject += frappe.bold(_('Diagnosis: ')) + '
    ' - for entry in encounter.diagnosis: - subject += cstr(entry.diagnosis) + '
    ' - else: - subject += frappe.bold(_('No Diagnosis')) + '
    ' - - if encounter.drug_prescription: - subject += '
    ' + _('Drug(s) Prescribed.') - if encounter.lab_test_prescription: - subject += '
    ' + _('Test(s) Prescribed.') - if encounter.procedure_prescription: - subject += '
    ' + _('Procedure(s) Prescribed.') - - return subject + frappe.delete_doc('Inpatient Medication Order', record, force=1) \ No newline at end of file diff --git a/erpnext/healthcare/doctype/therapy_session/therapy_session.py b/erpnext/healthcare/doctype/therapy_session/therapy_session.py index 85d09701774..f8a8e0c8a19 100644 --- a/erpnext/healthcare/doctype/therapy_session/therapy_session.py +++ b/erpnext/healthcare/doctype/therapy_session/therapy_session.py @@ -41,7 +41,6 @@ class TherapySession(Document): def on_submit(self): self.update_sessions_count_in_therapy_plan() - insert_session_medical_record(self) def on_cancel(self): self.update_sessions_count_in_therapy_plan(on_cancel=True) @@ -135,23 +134,3 @@ def get_therapy_item(therapy, item): item.reference_dt = 'Therapy Session' item.reference_dn = therapy.name return item - - -def insert_session_medical_record(doc): - subject = frappe.bold(_('Therapy: ')) + cstr(doc.therapy_type) + '
    ' - if doc.therapy_plan: - subject += frappe.bold(_('Therapy Plan: ')) + cstr(doc.therapy_plan) + '
    ' - if doc.practitioner: - subject += frappe.bold(_('Healthcare Practitioner: ')) + doc.practitioner - subject += frappe.bold(_('Total Counts Targeted: ')) + cstr(doc.total_counts_targeted) + '
    ' - subject += frappe.bold(_('Total Counts Completed: ')) + cstr(doc.total_counts_completed) + '
    ' - - medical_record = frappe.new_doc('Patient Medical Record') - medical_record.patient = doc.patient - medical_record.subject = subject - medical_record.status = 'Open' - medical_record.communication_date = doc.start_date - medical_record.reference_doctype = 'Therapy Session' - medical_record.reference_name = doc.name - medical_record.reference_owner = doc.owner - medical_record.save(ignore_permissions=True) \ No newline at end of file diff --git a/erpnext/healthcare/doctype/vital_signs/vital_signs.py b/erpnext/healthcare/doctype/vital_signs/vital_signs.py index 69d81ff4b08..35c823d739c 100644 --- a/erpnext/healthcare/doctype/vital_signs/vital_signs.py +++ b/erpnext/healthcare/doctype/vital_signs/vital_signs.py @@ -12,47 +12,7 @@ class VitalSigns(Document): def validate(self): self.set_title() - def on_submit(self): - insert_vital_signs_to_medical_record(self) - - def on_cancel(self): - delete_vital_signs_from_medical_record(self) - def set_title(self): self.title = _('{0} on {1}').format(self.patient_name or self.patient, frappe.utils.format_date(self.signs_date))[:100] -def insert_vital_signs_to_medical_record(doc): - subject = set_subject_field(doc) - medical_record = frappe.new_doc('Patient Medical Record') - medical_record.patient = doc.patient - medical_record.subject = subject - medical_record.status = 'Open' - medical_record.communication_date = doc.signs_date - medical_record.reference_doctype = 'Vital Signs' - medical_record.reference_name = doc.name - medical_record.reference_owner = doc.owner - medical_record.flags.ignore_mandatory = True - medical_record.save(ignore_permissions=True) - -def delete_vital_signs_from_medical_record(doc): - medical_record = frappe.db.get_value('Patient Medical Record', {'reference_name': doc.name}) - if medical_record: - frappe.delete_doc('Patient Medical Record', medical_record) - -def set_subject_field(doc): - subject = '' - if doc.temperature: - subject += frappe.bold(_('Temperature: ')) + cstr(doc.temperature) + '
    ' - if doc.pulse: - subject += frappe.bold(_('Pulse: ')) + cstr(doc.pulse) + '
    ' - if doc.respiratory_rate: - subject += frappe.bold(_('Respiratory Rate: ')) + cstr(doc.respiratory_rate) + '
    ' - if doc.bp: - subject += frappe.bold(_('BP: ')) + cstr(doc.bp) + '
    ' - if doc.bmi: - subject += frappe.bold(_('BMI: ')) + cstr(doc.bmi) + '
    ' - if doc.nutrition_note: - subject += frappe.bold(_('Note: ')) + cstr(doc.nutrition_note) + '
    ' - - return subject From 5e3c51bf7d157a34baed3e791f8bb40052587654 Mon Sep 17 00:00:00 2001 From: Rucha Mahabal Date: Mon, 30 Nov 2020 13:35:00 +0530 Subject: [PATCH 114/477] refactor: format value using standard formatters --- erpnext/healthcare/utils.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/erpnext/healthcare/utils.py b/erpnext/healthcare/utils.py index 96282f50a92..6b495a4eac9 100644 --- a/erpnext/healthcare/utils.py +++ b/erpnext/healthcare/utils.py @@ -6,6 +6,7 @@ from __future__ import unicode_literals import math import frappe from frappe import _ +from frappe.utils.formatters import format_value from frappe.utils import time_diff_in_hours, rounded from erpnext.healthcare.doctype.healthcare_settings.healthcare_settings import get_income_account from erpnext.healthcare.doctype.fee_validity.fee_validity import create_fee_validity @@ -642,11 +643,15 @@ def render_doc_as_html(doctype, docname, exclude_fields = []): html += "" \ + table_head + table_row + "
    " continue + #on other field types add label and value to html if not df.hidden and not df.print_hide and doc.get(df.fieldname) and df.fieldname not in exclude_fields: - html += '
    {0} : {1}'.format(df.label or df.fieldname, \ - doc.get(df.fieldname)) + if doc.get(df.fieldname): + formatted_value = format_value(doc.get(df.fieldname), meta.get_field(df.fieldname), doc) + html += '
    {0} : {1}'.format(df.label or df.fieldname, formatted_value) + if not has_data : has_data = True + if sec_on and col_on and has_data: doc_html += section_html + html + '
    ' elif sec_on and not col_on and has_data: From 4ee293d2f45c257fa4b103adc1af088e68d4dd5f Mon Sep 17 00:00:00 2001 From: Rucha Mahabal Date: Mon, 30 Nov 2020 14:12:48 +0530 Subject: [PATCH 115/477] fix: handle non-configured fields --- .../patient_history_custom_document_type.json | 5 +++-- .../patient_history_settings.js | 12 ++++++++---- .../patient_history_standard_document_type.json | 5 +++-- 3 files changed, 14 insertions(+), 8 deletions(-) diff --git a/erpnext/healthcare/doctype/patient_history_custom_document_type/patient_history_custom_document_type.json b/erpnext/healthcare/doctype/patient_history_custom_document_type/patient_history_custom_document_type.json index 7986e48ced7..3025c7b06d7 100644 --- a/erpnext/healthcare/doctype/patient_history_custom_document_type/patient_history_custom_document_type.json +++ b/erpnext/healthcare/doctype/patient_history_custom_document_type/patient_history_custom_document_type.json @@ -22,7 +22,8 @@ { "fieldname": "selected_fields", "fieldtype": "Code", - "label": "selected_fields" + "label": "Selected Fields", + "read_only": 1 }, { "fieldname": "add_edit_fields", @@ -41,7 +42,7 @@ "index_web_pages_for_search": 1, "istable": 1, "links": [], - "modified": "2020-11-28 19:04:48.323164", + "modified": "2020-11-30 13:54:37.474671", "modified_by": "Administrator", "module": "Healthcare", "name": "Patient History Custom Document Type", diff --git a/erpnext/healthcare/doctype/patient_history_settings/patient_history_settings.js b/erpnext/healthcare/doctype/patient_history_settings/patient_history_settings.js index c3d0dce6756..ee363462ef8 100644 --- a/erpnext/healthcare/doctype/patient_history_settings/patient_history_settings.js +++ b/erpnext/healthcare/doctype/patient_history_settings/patient_history_settings.js @@ -14,7 +14,11 @@ frappe.ui.form.on('Patient History Settings', { }, field_selector: function(frm, doc, standard=1) { - let document_fields = (JSON.parse(doc.selected_fields)).map(f => f.fieldname); + let document_fields = []; + if (doc.selected_fields) + document_fields = (JSON.parse(doc.selected_fields)).map(f => f.fieldname); + + let doctype_fields = frm.events.get_doctype_fields(frm, doc.document_type, document_fields); let d = new frappe.ui.Dialog({ title: __('{0} Fields', [__(doc.document_type)]), fields: [ @@ -22,7 +26,7 @@ frappe.ui.form.on('Patient History Settings', { label: __('Select Fields'), fieldtype: 'MultiCheck', fieldname: 'fields', - options: frm.events.get_doctype_fields(frm, doc.document_type, document_fields), + options: doctype_fields, columns: 2 } ] @@ -49,7 +53,7 @@ frappe.ui.form.on('Patient History Settings', { if (standard) doctype = 'Patient History Standard Document Type'; - + d.refresh(); frappe.model.set_value(doctype, doc.name, 'selected_fields', JSON.stringify(selected_fields)); d.hide(); }); @@ -82,7 +86,7 @@ frappe.ui.form.on('Patient History Custom Document Type', { add_edit_fields: function(frm, cdt, cdn) { let row = locals[cdt][cdn]; if (row.document_type) { - frm.events.field_selector(frm, row, standard=0); + frm.events.field_selector(frm, row, 0); } } }); diff --git a/erpnext/healthcare/doctype/patient_history_standard_document_type/patient_history_standard_document_type.json b/erpnext/healthcare/doctype/patient_history_standard_document_type/patient_history_standard_document_type.json index 9c9d0cb4cd8..b43099c4ea9 100644 --- a/erpnext/healthcare/doctype/patient_history_standard_document_type/patient_history_standard_document_type.json +++ b/erpnext/healthcare/doctype/patient_history_standard_document_type/patient_history_standard_document_type.json @@ -23,7 +23,8 @@ { "fieldname": "selected_fields", "fieldtype": "Code", - "label": "Selected Fields" + "label": "Selected Fields", + "read_only": 1 }, { "fieldname": "add_edit_fields", @@ -43,7 +44,7 @@ "index_web_pages_for_search": 1, "istable": 1, "links": [], - "modified": "2020-11-30 12:15:14.940935", + "modified": "2020-11-30 13:54:56.773325", "modified_by": "Administrator", "module": "Healthcare", "name": "Patient History Standard Document Type", From ed3fc20731ae7e2279fabf6274a7660ca520a2e7 Mon Sep 17 00:00:00 2001 From: Rucha Mahabal Date: Mon, 30 Nov 2020 14:56:24 +0530 Subject: [PATCH 116/477] fix: sider issues --- .../page/patient_history/patient_history.js | 34 +++++++++---------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/erpnext/healthcare/page/patient_history/patient_history.js b/erpnext/healthcare/page/patient_history/patient_history.js index 5a6295b7079..d509ea22a2d 100644 --- a/erpnext/healthcare/page/patient_history/patient_history.js +++ b/erpnext/healthcare/page/patient_history/patient_history.js @@ -24,7 +24,7 @@ frappe.pages['patient_history'].on_page_load = function(wrapper) { if (pid != patient_id && patient_id) { me.start = 0; me.page.main.find('.patient_documents_list').html(''); - setup_filters(patient_id, me) + setup_filters(patient_id, me); get_documents(patient_id, me); show_patient_info(patient_id, me); show_patient_vital_charts(patient_id, me, 'bp', 'mmHg', 'Blood Pressure'); @@ -90,7 +90,7 @@ frappe.pages['patient_history'].on_page_load = function(wrapper) { me.page.main.find('.' + docname).parent().find('.document-html').hide(); }); me.start = 0; - me.page.main.on('click', '.btn-get-records', function(){ + me.page.main.on('click', '.btn-get-records', function() { get_documents(patient.get_value(), me); }); }; @@ -142,7 +142,7 @@ let setup_filters = function(patient, me) { }); date_range_field.refresh(); }); -} +}; let get_documents = function(patient, me, document_types="", selected_date_range="") { let filters = { @@ -176,7 +176,7 @@ let get_documents = function(patient, me, document_types="", selected_date_range let add_to_records = function(me, data) { let details = "
    `; } details += ` ${data.patient_name}
    ${data.sex}`; - if (data.email) details += `
    ${data.email}` + if (data.email) details += `
    ${data.email}`; if (data.mobile) details += `
    ${data.mobile}`; if (data.occupation) details += `

    ${__('Occupation')} : ${data.occupation}`; if (data.blood_group) details += `
    ${__('Blood Group')} : ${data.blood_group}`; @@ -299,7 +299,7 @@ let show_patient_info = function(patient, me) { if (data.other_risk_factors) details += `
    ${__('Other risk factors')} : ${data.other_risk_factors.replace("\n", ", ")}`; if (data.patient_details) details += `

    ${__('More info')} : ${data.patient_details.replace("\n", ", ")}`; - if (details){ + if (details) { details = `
    ` + details + `
    `; } me.page.main.find('.patient_details').html(details); @@ -337,7 +337,7 @@ let show_patient_vital_charts = function(patient, me, btn_show_id, pts, title) { let bp_systolic = [], bp_diastolic = [], temperature = []; let pulse = [], respiratory_rate = [], bmi = [], height = [], weight = []; - for(let i=0; i Date: Thu, 12 Nov 2020 16:57:42 +0530 Subject: [PATCH 117/477] fix: added wrong absent days calculation in salary slip --- erpnext/payroll/doctype/salary_slip/salary_slip.py | 1 - 1 file changed, 1 deletion(-) diff --git a/erpnext/payroll/doctype/salary_slip/salary_slip.py b/erpnext/payroll/doctype/salary_slip/salary_slip.py index 4ccf56435dd..cecb8cde7c2 100644 --- a/erpnext/payroll/doctype/salary_slip/salary_slip.py +++ b/erpnext/payroll/doctype/salary_slip/salary_slip.py @@ -240,7 +240,6 @@ class SalarySlip(TransactionBase): self.absent_days += unmarked_days #will be treated as absent self.payment_days -= unmarked_days if include_holidays_in_total_working_days: - self.absent_days -= len(holidays) for holiday in holidays: if not frappe.db.exists("Attendance", {"employee": self.employee, "attendance_date": holiday, "docstatus": 1 }): self.payment_days += 1 From 7b16c55c9a387ac5d688a0ee98efd7e93cf12c66 Mon Sep 17 00:00:00 2001 From: Deepesh Garg <42651287+deepeshgarg007@users.noreply.github.com> Date: Fri, 13 Nov 2020 16:53:35 +0530 Subject: [PATCH 118/477] feat: Sync old shopify orders (#23841) * feat: Sync old shopify orders * fix: Old orders syncing by date * fix: Remove unnecessary code * fix: Remove unintentional changes Co-authored-by: Saurabh --- .../connectors/shopify_connection.py | 97 ++++++++++++++++--- .../shopify_settings/shopify_settings.json | 78 ++++++++++++++- .../shopify_settings/shopify_settings.py | 12 ++- .../shopify_settings/test_shopify_settings.py | 4 +- erpnext/hooks.py | 1 + erpnext/patches.txt | 1 + .../v13_0/update_custom_fields_for_shopify.py | 10 ++ 7 files changed, 184 insertions(+), 19 deletions(-) create mode 100644 erpnext/patches/v13_0/update_custom_fields_for_shopify.py diff --git a/erpnext/erpnext_integrations/connectors/shopify_connection.py b/erpnext/erpnext_integrations/connectors/shopify_connection.py index d59f9092983..8aa7453bd6b 100644 --- a/erpnext/erpnext_integrations/connectors/shopify_connection.py +++ b/erpnext/erpnext_integrations/connectors/shopify_connection.py @@ -2,12 +2,13 @@ from __future__ import unicode_literals import frappe from frappe import _ import json -from frappe.utils import cstr, cint, nowdate, flt +from frappe.utils import cstr, cint, nowdate, getdate, flt, get_request_session, get_datetime from erpnext.erpnext_integrations.utils import validate_webhooks_request from erpnext.selling.doctype.sales_order.sales_order import make_delivery_note, make_sales_invoice from erpnext.erpnext_integrations.doctype.shopify_settings.sync_product import sync_item_from_shopify from erpnext.erpnext_integrations.doctype.shopify_settings.sync_customer import create_customer from erpnext.erpnext_integrations.doctype.shopify_log.shopify_log import make_shopify_log, dump_request_data +from erpnext.erpnext_integrations.doctype.shopify_settings.shopify_settings import get_shopify_url, get_header @frappe.whitelist(allow_guest=True) @validate_webhooks_request("Shopify Settings", 'X-Shopify-Hmac-Sha256', secret_key='shared_secret') @@ -18,7 +19,7 @@ def store_request_data(order=None, event=None): dump_request_data(order, event) -def sync_sales_order(order, request_id=None): +def sync_sales_order(order, request_id=None, old_order_sync=False): frappe.set_user('Administrator') shopify_settings = frappe.get_doc("Shopify Settings") frappe.flags.request_id = request_id @@ -27,7 +28,7 @@ def sync_sales_order(order, request_id=None): try: validate_customer(order, shopify_settings) validate_item(order, shopify_settings) - create_order(order, shopify_settings) + create_order(order, shopify_settings, old_order_sync=old_order_sync) except Exception as e: make_shopify_log(status="Error", exception=e) @@ -77,13 +78,13 @@ def validate_item(order, shopify_settings): if item.get("product_id") and not frappe.db.get_value("Item", {"shopify_product_id": item.get("product_id")}, "name"): sync_item_from_shopify(shopify_settings, item) -def create_order(order, shopify_settings, company=None): +def create_order(order, shopify_settings, old_order_sync=False, company=None): so = create_sales_order(order, shopify_settings, company) if so: if order.get("financial_status") == "paid": - create_sales_invoice(order, shopify_settings, so) + create_sales_invoice(order, shopify_settings, so, old_order_sync=old_order_sync) - if order.get("fulfillments"): + if order.get("fulfillments") and not old_order_sync: create_delivery_note(order, shopify_settings, so) def create_sales_order(shopify_order, shopify_settings, company=None): @@ -92,7 +93,7 @@ def create_sales_order(shopify_order, shopify_settings, company=None): so = frappe.db.get_value("Sales Order", {"shopify_order_id": shopify_order.get("id")}, "name") if not so: - items = get_order_items(shopify_order.get("line_items"), shopify_settings) + items = get_order_items(shopify_order.get("line_items"), shopify_settings, getdate(shopify_order.get('created_at'))) if not items: message = 'Following items exists in the shopify order but relevant records were not found in the shopify Product master' @@ -106,8 +107,10 @@ def create_sales_order(shopify_order, shopify_settings, company=None): "doctype": "Sales Order", "naming_series": shopify_settings.sales_order_series or "SO-Shopify-", "shopify_order_id": shopify_order.get("id"), + "shopify_order_number": shopify_order.get("name"), "customer": customer or shopify_settings.default_customer, - "delivery_date": nowdate(), + "transaction_date": getdate(shopify_order.get("created_at")) or nowdate(), + "delivery_date": getdate(shopify_order.get("created_at")) or nowdate(), "company": shopify_settings.company, "selling_price_list": shopify_settings.price_list, "ignore_pricing_rule": 1, @@ -132,12 +135,20 @@ def create_sales_order(shopify_order, shopify_settings, company=None): frappe.db.commit() return so -def create_sales_invoice(shopify_order, shopify_settings, so): +def create_sales_invoice(shopify_order, shopify_settings, so, old_order_sync=False): if not frappe.db.get_value("Sales Invoice", {"shopify_order_id": shopify_order.get("id")}, "name")\ and so.docstatus==1 and not so.per_billed and cint(shopify_settings.sync_sales_invoice): + if old_order_sync: + posting_date = getdate(shopify_order.get('created_at')) + else: + posting_date = nowdate() + si = make_sales_invoice(so.name, ignore_permissions=True) si.shopify_order_id = shopify_order.get("id") + si.shopify_order_number = shopify_order.get("name") + si.set_posting_time = 1 + si.posting_date = posting_date si.naming_series = shopify_settings.sales_invoice_series or "SI-Shopify-" si.flags.ignore_mandatory = True set_cost_center(si.items, shopify_settings.cost_center) @@ -169,6 +180,9 @@ def create_delivery_note(shopify_order, shopify_settings, so): dn = make_delivery_note(so.name) dn.shopify_order_id = fulfillment.get("order_id") + dn.shopify_order_number = shopify_order.get("name") + dn.set_posting_time = 1 + dn.posting_date = getdate(fulfillment.get("created_at")) dn.shopify_fulfillment_id = fulfillment.get("id") dn.naming_series = shopify_settings.delivery_note_series or "DN-Shopify-" dn.items = get_fulfillment_items(dn.items, fulfillment.get("line_items"), shopify_settings) @@ -187,7 +201,7 @@ def get_discounted_amount(order): discounted_amount += flt(discount.get("amount")) return discounted_amount -def get_order_items(order_items, shopify_settings): +def get_order_items(order_items, shopify_settings, delivery_date): items = [] all_product_exists = True product_not_exists = [] @@ -205,7 +219,7 @@ def get_order_items(order_items, shopify_settings): "item_code": item_code, "item_name": shopify_item.get("name"), "rate": shopify_item.get("price"), - "delivery_date": nowdate(), + "delivery_date": delivery_date, "qty": shopify_item.get("quantity"), "stock_uom": shopify_item.get("uom") or _("Nos"), "warehouse": shopify_settings.warehouse @@ -265,3 +279,64 @@ def get_tax_account_head(tax): frappe.throw(_("Tax Account not specified for Shopify Tax {0}").format(tax.get("title"))) return tax_account + +@frappe.whitelist(allow_guest=True) +def sync_old_orders(): + frappe.set_user('Administrator') + shopify_settings = frappe.get_doc('Shopify Settings') + + if not shopify_settings.sync_missing_orders: + return + + url = get_url(shopify_settings) + session = get_request_session() + + try: + res = session.get(url, headers=get_header(shopify_settings)) + res.raise_for_status() + orders = res.json()["orders"] + + for order in orders: + if is_sync_complete(shopify_settings, order): + stop_sync(shopify_settings) + return + + sync_sales_order(order=order, old_order_sync=True) + last_order_id = order.get('id') + + if last_order_id: + shopify_settings.load_from_db() + shopify_settings.last_order_id = last_order_id + shopify_settings.save() + frappe.db.commit() + + except Exception as e: + raise e + +def stop_sync(shopify_settings): + shopify_settings.sync_missing_orders = 0 + shopify_settings.last_order_id = '' + shopify_settings.save() + frappe.db.commit() + +def get_url(shopify_settings): + last_order_id = shopify_settings.last_order_id + + if not last_order_id: + if shopify_settings.sync_based_on == 'Date': + url = get_shopify_url("admin/api/2020-10/orders.json?limit=250&created_at_min={0}&since_id=0".format( + get_datetime(shopify_settings.from_date)), shopify_settings) + else: + url = get_shopify_url("admin/api/2020-10/orders.json?limit=250&since_id={0}".format( + shopify_settings.from_order_id), shopify_settings) + else: + url = get_shopify_url("admin/api/2020-10/orders.json?limit=250&since_id={0}".format(last_order_id), shopify_settings) + + return url + +def is_sync_complete(shopify_settings, order): + if shopify_settings.sync_based_on == 'Date': + return getdate(shopify_settings.to_date) < getdate(order.get('created_at')) + else: + return cstr(order.get('id')) == cstr(shopify_settings.to_order_id) + diff --git a/erpnext/erpnext_integrations/doctype/shopify_settings/shopify_settings.json b/erpnext/erpnext_integrations/doctype/shopify_settings/shopify_settings.json index 2e10751f967..20ec06373e7 100644 --- a/erpnext/erpnext_integrations/doctype/shopify_settings/shopify_settings.json +++ b/erpnext/erpnext_integrations/doctype/shopify_settings/shopify_settings.json @@ -1,7 +1,9 @@ { + "actions": [], "creation": "2015-05-18 05:21:07.270859", "doctype": "DocType", "document_type": "System", + "engine": "InnoDB", "field_order": [ "status_html", "enable_shopify", @@ -40,7 +42,16 @@ "sales_invoice_series", "section_break_22", "html_16", - "taxes" + "taxes", + "syncing_details_section", + "sync_missing_orders", + "sync_based_on", + "column_break_41", + "from_date", + "to_date", + "from_order_id", + "to_order_id", + "last_order_id" ], "fields": [ { @@ -255,10 +266,71 @@ "fieldtype": "Table", "label": "Shopify Tax Account", "options": "Shopify Tax Account" + }, + { + "collapsible": 1, + "fieldname": "syncing_details_section", + "fieldtype": "Section Break", + "label": "Syncing Missing Orders" + }, + { + "depends_on": "eval:doc.sync_missing_orders", + "fieldname": "last_order_id", + "fieldtype": "Data", + "label": "Last Order Id", + "read_only": 1 + }, + { + "fieldname": "column_break_41", + "fieldtype": "Column Break" + }, + { + "default": "0", + "description": "On checking this Order from the ", + "fieldname": "sync_missing_orders", + "fieldtype": "Check", + "label": "Sync Missing Old Shopify Orders" + }, + { + "depends_on": "eval:doc.sync_missing_orders", + "fieldname": "sync_based_on", + "fieldtype": "Select", + "label": "Sync Based On", + "mandatory_depends_on": "eval:doc.sync_missing_orders", + "options": "\nDate\nShopify Order Id" + }, + { + "depends_on": "eval:doc.sync_based_on == 'Date' && doc.sync_missing_orders", + "fieldname": "from_date", + "fieldtype": "Date", + "label": "From Date", + "mandatory_depends_on": "eval:doc.sync_based_on == 'Date' && doc.sync_missing_orders" + }, + { + "depends_on": "eval:doc.sync_based_on == 'Date' && doc.sync_missing_orders", + "fieldname": "to_date", + "fieldtype": "Date", + "label": "To Date", + "mandatory_depends_on": "eval:doc.sync_based_on == 'Date' && doc.sync_missing_orders" + }, + { + "depends_on": "eval:doc.sync_based_on == 'Shopify Order Id' && doc.sync_missing_orders", + "fieldname": "from_order_id", + "fieldtype": "Data", + "label": "From Order Id", + "mandatory_depends_on": "eval:doc.sync_based_on == 'Shopify Order Id' && doc.sync_missing_orders" + }, + { + "depends_on": "eval:doc.sync_based_on == 'Shopify Order Id' && doc.sync_missing_orders", + "fieldname": "to_order_id", + "fieldtype": "Data", + "label": "To Order Id", + "mandatory_depends_on": "eval:doc.sync_based_on == 'Shopify Order Id' && doc.sync_missing_orders" } ], "issingle": 1, - "modified": "2020-09-18 17:26:09.703215", + "links": [], + "modified": "2020-11-05 20:44:03.664891", "modified_by": "Administrator", "module": "ERPNext Integrations", "name": "Shopify Settings", @@ -277,4 +349,4 @@ ], "sort_field": "modified", "sort_order": "DESC" -} +} \ No newline at end of file diff --git a/erpnext/erpnext_integrations/doctype/shopify_settings/shopify_settings.py b/erpnext/erpnext_integrations/doctype/shopify_settings/shopify_settings.py index 25ffd281099..cbdf90681d3 100644 --- a/erpnext/erpnext_integrations/doctype/shopify_settings/shopify_settings.py +++ b/erpnext/erpnext_integrations/doctype/shopify_settings/shopify_settings.py @@ -87,7 +87,7 @@ def get_shopify_url(path, settings): def get_header(settings): header = {'Content-Type': 'application/json'} - return header; + return header @frappe.whitelist() def get_series(): @@ -121,17 +121,23 @@ def setup_custom_fields(): ], "Sales Order": [ dict(fieldname='shopify_order_id', label='Shopify Order Id', - fieldtype='Data', insert_after='title', read_only=1, print_hide=1) + fieldtype='Data', insert_after='title', read_only=1, print_hide=1), + dict(fieldname='shopify_order_number', label='Shopify Order Number', + fieldtype='Data', insert_after='shopify_order_id', read_only=1, print_hide=1) ], "Delivery Note":[ dict(fieldname='shopify_order_id', label='Shopify Order Id', fieldtype='Data', insert_after='title', read_only=1, print_hide=1), + dict(fieldname='shopify_order_number', label='Shopify Order Number', + fieldtype='Data', insert_after='shopify_order_id', read_only=1, print_hide=1), dict(fieldname='shopify_fulfillment_id', label='Shopify Fulfillment Id', fieldtype='Data', insert_after='title', read_only=1, print_hide=1) ], "Sales Invoice": [ dict(fieldname='shopify_order_id', label='Shopify Order Id', - fieldtype='Data', insert_after='title', read_only=1, print_hide=1) + fieldtype='Data', insert_after='title', read_only=1, print_hide=1), + dict(fieldname='shopify_order_number', label='Shopify Order Number', + fieldtype='Data', insert_after='shopify_order_id', read_only=1, print_hide=1) ] } diff --git a/erpnext/erpnext_integrations/doctype/shopify_settings/test_shopify_settings.py b/erpnext/erpnext_integrations/doctype/shopify_settings/test_shopify_settings.py index 64ef3dc0859..30fa23cfb4a 100644 --- a/erpnext/erpnext_integrations/doctype/shopify_settings/test_shopify_settings.py +++ b/erpnext/erpnext_integrations/doctype/shopify_settings/test_shopify_settings.py @@ -58,7 +58,7 @@ class ShopifySettings(unittest.TestCase): }).save(ignore_permissions=True) self.shopify_settings = shopify_settings - + def test_order(self): ### Create Customer ### with open (os.path.join(os.path.dirname(__file__), "test_data", "shopify_customer.json")) as shopify_customer: @@ -75,7 +75,7 @@ class ShopifySettings(unittest.TestCase): with open (os.path.join(os.path.dirname(__file__), "test_data", "shopify_order.json")) as shopify_order: shopify_order = json.load(shopify_order) - create_order(shopify_order.get("order"), self.shopify_settings, "_Test Company") + create_order(shopify_order.get("order"), self.shopify_settings, False, company="_Test Company") sales_order = frappe.get_doc("Sales Order", {"shopify_order_id": cstr(shopify_order.get("order").get("id"))}) diff --git a/erpnext/hooks.py b/erpnext/hooks.py index 21dd582593f..aadead21ecd 100644 --- a/erpnext/hooks.py +++ b/erpnext/hooks.py @@ -308,6 +308,7 @@ scheduler_events = { "erpnext.projects.doctype.project.project.collect_project_status", "erpnext.hr.doctype.shift_type.shift_type.process_auto_attendance_for_all_shifts", "erpnext.support.doctype.issue.issue.set_service_level_agreement_variance", + "erpnext.erpnext_integrations.connectors.shopify_connection.sync_old_orders", ], "daily": [ "erpnext.stock.reorder_item.reorder_item", diff --git a/erpnext/patches.txt b/erpnext/patches.txt index 0d8d1b427a4..97177de0013 100644 --- a/erpnext/patches.txt +++ b/erpnext/patches.txt @@ -734,4 +734,5 @@ erpnext.patches.v13_0.print_uom_after_quantity_patch erpnext.patches.v13_0.set_payment_channel_in_payment_gateway_account erpnext.patches.v13_0.create_healthcare_custom_fields_in_stock_entry_detail erpnext.patches.v13_0.update_reason_for_resignation_in_employee +erpnext.patches.v13_0.update_custom_fields_for_shopify execute:frappe.delete_doc("Report", "Quoted Item Comparison") diff --git a/erpnext/patches/v13_0/update_custom_fields_for_shopify.py b/erpnext/patches/v13_0/update_custom_fields_for_shopify.py new file mode 100644 index 00000000000..f1d2ea2d747 --- /dev/null +++ b/erpnext/patches/v13_0/update_custom_fields_for_shopify.py @@ -0,0 +1,10 @@ +# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and Contributors +# MIT License. See license.txt + +from __future__ import unicode_literals +import frappe +from erpnext.erpnext_integrations.doctype.shopify_settings.shopify_settings import setup_custom_fields + +def execute(): + if frappe.db.get_single_value('Shopify Settings', 'enable_shopify'): + setup_custom_fields() From d6a2b390dc56ff4e3301e7cc0ca9b300d92084d6 Mon Sep 17 00:00:00 2001 From: Rohit Waghchaure Date: Fri, 13 Nov 2020 22:17:07 +0530 Subject: [PATCH 119/477] fix: not able to save bom --- erpnext/manufacturing/doctype/bom/bom.py | 31 +++++++++--------------- 1 file changed, 12 insertions(+), 19 deletions(-) diff --git a/erpnext/manufacturing/doctype/bom/bom.py b/erpnext/manufacturing/doctype/bom/bom.py index 2ab1b987077..8888a967683 100644 --- a/erpnext/manufacturing/doctype/bom/bom.py +++ b/erpnext/manufacturing/doctype/bom/bom.py @@ -76,6 +76,7 @@ class BOM(WebsiteGenerator): self.set_routing_operations() self.validate_operations() self.calculate_cost() + self.update_stock_qty() self.update_cost(update_parent=False, from_child_bom=True, save=False) def get_context(self, context): @@ -84,8 +85,6 @@ class BOM(WebsiteGenerator): def on_update(self): frappe.cache().hdel('bom_children', self.name) self.check_recursion() - self.update_stock_qty() - self.update_exploded_items() def on_submit(self): self.manage_default_bom() @@ -237,7 +236,8 @@ class BOM(WebsiteGenerator): self.calculate_cost() if save: self.db_update() - self.update_exploded_items() + + self.update_exploded_items(save=save) # update parent BOMs if self.total_cost != existing_bom_cost and update_parent: @@ -318,8 +318,6 @@ class BOM(WebsiteGenerator): m.uom = m.stock_uom m.qty = m.stock_qty - m.db_update() - def validate_uom_is_interger(self): from erpnext.utilities.transaction_base import validate_uom_is_integer validate_uom_is_integer(self, "uom", "qty", "BOM Item") @@ -372,15 +370,6 @@ class BOM(WebsiteGenerator): if raise_exception: frappe.throw(_("BOM recursion: {0} cannot be parent or child of {1}").format(self.name, self.name)) - def update_cost_and_exploded_items(self, bom_list=[]): - bom_list = self.traverse_tree(bom_list) - for bom in bom_list: - bom_obj = frappe.get_doc("BOM", bom) - bom_obj.check_recursion(bom_list=bom_list) - bom_obj.update_exploded_items() - - return bom_list - def traverse_tree(self, bom_list=None): def _get_children(bom_no): children = frappe.cache().hget('bom_children', bom_no) @@ -472,10 +461,10 @@ class BOM(WebsiteGenerator): d.rate = rate d.amount = (d.stock_qty or d.qty) * rate - def update_exploded_items(self): + def update_exploded_items(self, save=True): """ Update Flat BOM, following will be correct data""" self.get_exploded_items() - self.add_exploded_items() + self.add_exploded_items(save=save) def get_exploded_items(self): """ Get all raw materials including items from child bom""" @@ -544,11 +533,13 @@ class BOM(WebsiteGenerator): 'sourced_by_supplier': d.get('sourced_by_supplier', 0) })) - def add_exploded_items(self): + def add_exploded_items(self, save=True): "Add items to Flat BOM table" - frappe.db.sql("""delete from `tabBOM Explosion Item` where parent=%s""", self.name) self.set('exploded_items', []) + if save: + frappe.db.sql("""delete from `tabBOM Explosion Item` where parent=%s""", self.name) + for d in sorted(self.cur_exploded_items, key=itemgetter(0)): ch = self.append('exploded_items', {}) for i in self.cur_exploded_items[d].keys(): @@ -556,7 +547,9 @@ class BOM(WebsiteGenerator): ch.amount = flt(ch.stock_qty) * flt(ch.rate) ch.qty_consumed_per_unit = flt(ch.stock_qty) / flt(self.quantity) ch.docstatus = self.docstatus - ch.db_insert() + + if save: + ch.db_insert() def validate_bom_links(self): if not self.is_active: From ecce3bca2f8237fc3f1a681071dea16b864232b3 Mon Sep 17 00:00:00 2001 From: Marica Date: Sun, 15 Nov 2020 09:17:42 +0530 Subject: [PATCH 120/477] chore: PO cleanup (#23774) * chore: Subcontracting section and items section enhancement - Set target warehouse moved to Items section - Added subcontraction label to supply RM section * chore: PO & PO Item Form Cleanup * chore: PO Get Items from cleanup * fix: Taxes and Charges field visibility * chore: Cleanup * fix: Translation styling --- .../doctype/purchase_order/purchase_order.js | 39 ++++++--- .../purchase_order/purchase_order.json | 81 ++++++++++++------- .../purchase_order_item.json | 56 ++++++------- 3 files changed, 106 insertions(+), 70 deletions(-) diff --git a/erpnext/buying/doctype/purchase_order/purchase_order.js b/erpnext/buying/doctype/purchase_order/purchase_order.js index 2f52a9e0355..47483c9d1c3 100644 --- a/erpnext/buying/doctype/purchase_order/purchase_order.js +++ b/erpnext/buying/doctype/purchase_order/purchase_order.js @@ -90,6 +90,11 @@ erpnext.buying.PurchaseOrderController = erpnext.buying.BuyingController.extend( this.frm.set_df_property("drop_ship", "hidden", !is_drop_ship); if(doc.docstatus == 1) { + this.frm.fields_dict.items_section.wrapper.addClass("hide-border"); + if(!this.frm.doc.set_warehouse) { + this.frm.fields_dict.items_section.wrapper.removeClass("hide-border"); + } + if(!in_list(["Closed", "Delivered"], doc.status)) { if(this.frm.doc.status !== 'Closed' && flt(this.frm.doc.per_received) < 100 && flt(this.frm.doc.per_billed) < 100) { this.frm.add_custom_button(__('Update Items'), () => { @@ -126,16 +131,25 @@ erpnext.buying.PurchaseOrderController = erpnext.buying.BuyingController.extend( if(doc.status != "Closed") { if (doc.status != "On Hold") { if(flt(doc.per_received) < 100 && allow_receipt) { - cur_frm.add_custom_button(__('Receipt'), this.make_purchase_receipt, __('Create')); + cur_frm.add_custom_button(__('Purchase Receipt'), this.make_purchase_receipt, __('Create')); if(doc.is_subcontracted==="Yes" && me.has_unsupplied_items()) { cur_frm.add_custom_button(__('Material to Supplier'), function() { me.make_stock_entry(); }, __("Transfer")); } } if(flt(doc.per_billed) < 100) - cur_frm.add_custom_button(__('Invoice'), + cur_frm.add_custom_button(__('Purchase Invoice'), this.make_purchase_invoice, __('Create')); + if(flt(doc.per_billed)==0 && doc.status != "Delivered") { + cur_frm.add_custom_button(__('Payment'), cur_frm.cscript.make_payment_entry, __('Create')); + } + + if(flt(doc.per_billed)==0) { + this.frm.add_custom_button(__('Payment Request'), + function() { me.make_payment_request() }, __('Create')); + } + if(!doc.auto_repeat) { cur_frm.add_custom_button(__('Subscription'), function() { erpnext.utils.make_subscription(doc.doctype, doc.name) @@ -156,13 +170,7 @@ erpnext.buying.PurchaseOrderController = erpnext.buying.BuyingController.extend( }); } } - if(flt(doc.per_billed)==0) { - this.frm.add_custom_button(__('Payment Request'), - function() { me.make_payment_request() }, __('Create')); - } - if(flt(doc.per_billed)==0 && doc.status != "Delivered") { - cur_frm.add_custom_button(__('Payment'), cur_frm.cscript.make_payment_entry, __('Create')); - } + cur_frm.page.set_inner_btn_group_as_primary(__('Create')); } } else if(doc.docstatus===0) { @@ -358,12 +366,16 @@ erpnext.buying.PurchaseOrderController = erpnext.buying.BuyingController.extend( method: "erpnext.stock.doctype.material_request.material_request.make_purchase_order", source_doctype: "Material Request", target: me.frm, - setters: {}, + setters: { + schedule_date: undefined, + status: undefined + }, get_query_filters: { material_request_type: "Purchase", docstatus: 1, status: ["!=", "Stopped"], per_ordered: ["<", 99.99], + company: me.frm.doc.company } }) }, __("Get Items From")); @@ -375,16 +387,17 @@ erpnext.buying.PurchaseOrderController = erpnext.buying.BuyingController.extend( source_doctype: "Supplier Quotation", target: me.frm, setters: { - supplier: me.frm.doc.supplier + supplier: me.frm.doc.supplier, + valid_till: undefined }, get_query_filters: { docstatus: 1, - status: ["!=", "Stopped"], + status: ["not in", ["Stopped", "Expired"]], } }) }, __("Get Items From")); - this.frm.add_custom_button(__('Update rate as per last purchase'), + this.frm.add_custom_button(__('Update Rate as per Last Purchase'), function() { frappe.call({ "method": "get_last_purchase_rate", diff --git a/erpnext/buying/doctype/purchase_order/purchase_order.json b/erpnext/buying/doctype/purchase_order/purchase_order.json index 2747c7c54d7..4b865a98e9e 100644 --- a/erpnext/buying/doctype/purchase_order/purchase_order.json +++ b/erpnext/buying/doctype/purchase_order/purchase_order.json @@ -30,8 +30,8 @@ "customer_contact_email", "section_addresses", "supplier_address", - "contact_person", "address_display", + "contact_person", "contact_display", "contact_mobile", "contact_email", @@ -49,12 +49,14 @@ "plc_conversion_rate", "ignore_pricing_rule", "sec_warehouse", - "set_warehouse", - "col_break_warehouse", "is_subcontracted", + "col_break_warehouse", "supplier_warehouse", - "items_section", + "before_items_section", "scan_barcode", + "items_col_break", + "set_warehouse", + "items_section", "items", "sb_last_purchase", "total_qty", @@ -108,18 +110,13 @@ "payment_terms_template", "payment_schedule", "tracking_section", - "per_billed", + "status", "column_break_75", + "per_billed", "per_received", "terms_section_break", "tc_name", "terms", - "more_info", - "status", - "ref_sq", - "column_break_74", - "party_account_currency", - "inter_company_order_reference", "column_break5", "letter_head", "select_print_heading", @@ -131,7 +128,12 @@ "to_date", "column_break_97", "auto_repeat", - "update_auto_repeat_reference" + "update_auto_repeat_reference", + "more_info", + "ref_sq", + "column_break_74", + "party_account_currency", + "inter_company_order_reference" ], "fields": [ { @@ -313,34 +315,34 @@ { "fieldname": "supplier_address", "fieldtype": "Link", - "label": "Select Supplier Address", + "label": "Supplier Address", "options": "Address", "print_hide": 1 }, { "fieldname": "contact_person", "fieldtype": "Link", - "label": "Contact Person", + "label": "Supplier Contact", "options": "Contact", "print_hide": 1 }, { "fieldname": "address_display", "fieldtype": "Small Text", - "label": "Address", + "label": "Supplier Address Details", "read_only": 1 }, { "fieldname": "contact_display", "fieldtype": "Small Text", "in_global_search": 1, - "label": "Contact", + "label": "Contact Name", "read_only": 1 }, { "fieldname": "contact_mobile", "fieldtype": "Small Text", - "label": "Mobile No", + "label": "Contact Mobile No", "read_only": 1 }, { @@ -358,14 +360,14 @@ { "fieldname": "shipping_address", "fieldtype": "Link", - "label": "Select Shipping Address", + "label": "Company Shipping Address", "options": "Address", "print_hide": 1 }, { "fieldname": "shipping_address_display", "fieldtype": "Small Text", - "label": "Shipping Address", + "label": "Shipping Address Details", "print_hide": 1, "read_only": 1 }, @@ -433,7 +435,8 @@ }, { "fieldname": "sec_warehouse", - "fieldtype": "Section Break" + "fieldtype": "Section Break", + "label": "Subcontracting" }, { "description": "Sets 'Warehouse' in each row of the Items table.", @@ -466,6 +469,7 @@ { "fieldname": "items_section", "fieldtype": "Section Break", + "hide_border": 1, "oldfieldtype": "Section Break", "options": "fa fa-shopping-cart" }, @@ -598,7 +602,8 @@ }, { "fieldname": "section_break_52", - "fieldtype": "Section Break" + "fieldtype": "Section Break", + "hide_border": 1 }, { "fieldname": "taxes", @@ -626,10 +631,12 @@ { "fieldname": "totals", "fieldtype": "Section Break", + "label": "Taxes and Charges", "oldfieldtype": "Section Break", "options": "fa fa-money" }, { + "depends_on": "base_taxes_and_charges_added", "fieldname": "base_taxes_and_charges_added", "fieldtype": "Currency", "label": "Taxes and Charges Added (Company Currency)", @@ -640,6 +647,7 @@ "read_only": 1 }, { + "depends_on": "base_taxes_and_charges_deducted", "fieldname": "base_taxes_and_charges_deducted", "fieldtype": "Currency", "label": "Taxes and Charges Deducted (Company Currency)", @@ -650,6 +658,7 @@ "read_only": 1 }, { + "depends_on": "base_total_taxes_and_charges", "fieldname": "base_total_taxes_and_charges", "fieldtype": "Currency", "label": "Total Taxes and Charges (Company Currency)", @@ -665,6 +674,7 @@ "fieldtype": "Column Break" }, { + "depends_on": "taxes_and_charges_added", "fieldname": "taxes_and_charges_added", "fieldtype": "Currency", "label": "Taxes and Charges Added", @@ -675,6 +685,7 @@ "read_only": 1 }, { + "depends_on": "taxes_and_charges_deducted", "fieldname": "taxes_and_charges_deducted", "fieldtype": "Currency", "label": "Taxes and Charges Deducted", @@ -685,6 +696,7 @@ "read_only": 1 }, { + "depends_on": "total_taxes_and_charges", "fieldname": "total_taxes_and_charges", "fieldtype": "Currency", "label": "Total Taxes and Charges", @@ -694,7 +706,7 @@ }, { "collapsible": 1, - "collapsible_depends_on": "discount_amount", + "collapsible_depends_on": "apply_discount_on", "fieldname": "discount_section", "fieldtype": "Section Break", "label": "Additional Discount" @@ -734,7 +746,8 @@ }, { "fieldname": "totals_section", - "fieldtype": "Section Break" + "fieldtype": "Section Break", + "label": "Totals" }, { "fieldname": "base_grand_total", @@ -902,12 +915,12 @@ }, { "fieldname": "ref_sq", - "fieldtype": "Data", - "hidden": 1, - "label": "Ref SQ", + "fieldtype": "Link", + "label": "Supplier Quotation", "no_copy": 1, "oldfieldname": "ref_sq", "oldfieldtype": "Data", + "options": "Supplier Quotation", "print_hide": 1, "read_only": 1 }, @@ -1061,7 +1074,7 @@ "collapsible": 1, "fieldname": "tracking_section", "fieldtype": "Section Break", - "label": "Tracking" + "label": "Order Status" }, { "fieldname": "column_break_75", @@ -1070,21 +1083,29 @@ { "fieldname": "billing_address", "fieldtype": "Link", - "label": "Select Billing Address", + "label": "Company Billing Address", "options": "Address" }, { "fieldname": "billing_address_display", "fieldtype": "Small Text", - "label": "Billing Address", + "label": "Billing Address Details", "read_only": 1 + }, + { + "fieldname": "before_items_section", + "fieldtype": "Section Break" + }, + { + "fieldname": "items_col_break", + "fieldtype": "Column Break" } ], "icon": "fa fa-file-text", "idx": 105, "is_submittable": 1, "links": [], - "modified": "2020-10-07 14:31:57.661221", + "modified": "2020-10-30 11:39:37.388249", "modified_by": "Administrator", "module": "Buying", "name": "Purchase Order", diff --git a/erpnext/buying/doctype/purchase_order_item/purchase_order_item.json b/erpnext/buying/doctype/purchase_order_item/purchase_order_item.json index 7a52c28a0ee..10db240a446 100644 --- a/erpnext/buying/doctype/purchase_order_item/purchase_order_item.json +++ b/erpnext/buying/doctype/purchase_order_item/purchase_order_item.json @@ -24,6 +24,7 @@ "col_break2", "uom", "conversion_factor", + "stock_qty", "sec_break1", "price_list_rate", "discount_percentage", @@ -46,11 +47,8 @@ "column_break_32", "base_net_rate", "base_net_amount", - "billed_amt", "warehouse_and_reference", "warehouse", - "delivered_by_supplier", - "project", "material_request", "material_request_item", "sales_order", @@ -58,36 +56,37 @@ "supplier_quotation", "supplier_quotation_item", "col_break5", + "delivered_by_supplier", "against_blanket_order", "blanket_order", "blanket_order_rate", "item_group", "brand", - "bom", - "include_exploded_items", "section_break_56", - "stock_qty", - "column_break_60", "received_qty", "returned_qty", - "manufacture_details", - "manufacturer", - "column_break_14", - "manufacturer_part_no", - "more_info_section_break", - "is_fixed_asset", - "item_tax_rate", + "column_break_60", + "billed_amt", "accounting_details", "expense_account", - "column_break_68", + "manufacture_details", + "manufacturer", + "manufacturer_part_no", + "column_break_14", + "bom", + "include_exploded_items", "item_weight_details", "weight_per_unit", "total_weight", "column_break_40", "weight_uom", "accounting_dimensions_section", - "cost_center", + "project", "dimension_col_break", + "cost_center", + "more_info_section_break", + "is_fixed_asset", + "item_tax_rate", "section_break_72", "page_break" ], @@ -346,6 +345,7 @@ }, { "default": "0", + "depends_on": "is_free_item", "fieldname": "is_free_item", "fieldtype": "Check", "label": "Is Free Item", @@ -508,9 +508,10 @@ }, { "default": "0", + "depends_on": "delivered_by_supplier", "fieldname": "delivered_by_supplier", "fieldtype": "Check", - "label": "To be delivered to customer", + "label": "To be Delivered to Customer", "print_hide": 1, "read_only": 1 }, @@ -558,6 +559,7 @@ "read_only": 1 }, { + "depends_on": "eval:parent.is_subcontracted == 'Yes'", "fieldname": "bom", "fieldtype": "Link", "label": "BOM", @@ -574,21 +576,21 @@ }, { "fieldname": "section_break_56", - "fieldtype": "Section Break" + "fieldtype": "Section Break", + "label": "Billed, Received & Returned" }, { "fieldname": "stock_qty", "fieldtype": "Float", - "label": "Qty as per Stock UOM", + "label": "Qty in Stock UOM", "no_copy": 1, - "oldfieldname": "stock_qty", - "oldfieldtype": "Currency", "print_hide": 1, "print_width": "100px", "read_only": 1, "width": "100px" }, { + "depends_on": "received_qty", "fieldname": "received_qty", "fieldtype": "Float", "label": "Received Qty", @@ -612,9 +614,10 @@ "fieldtype": "Column Break" }, { + "depends_on": "billed_amt", "fieldname": "billed_amt", "fieldtype": "Currency", - "label": "Billed Amt", + "label": "Billed Amount", "no_copy": 1, "options": "currency", "print_hide": 1, @@ -633,6 +636,7 @@ "report_hide": 1 }, { + "collapsible": 1, "fieldname": "accounting_details", "fieldtype": "Section Break", "label": "Accounting Details" @@ -644,10 +648,6 @@ "options": "Account", "print_hide": 1 }, - { - "fieldname": "column_break_68", - "fieldtype": "Column Break" - }, { "fieldname": "cost_center", "fieldtype": "Link", @@ -715,6 +715,7 @@ }, { "default": "0", + "depends_on": "is_fixed_asset", "fetch_from": "item_code.is_fixed_asset", "fieldname": "is_fixed_asset", "fieldtype": "Check", @@ -728,9 +729,10 @@ } ], "idx": 1, + "index_web_pages_for_search": 1, "istable": 1, "links": [], - "modified": "2020-04-21 11:55:58.643393", + "modified": "2020-10-30 11:59:47.670951", "modified_by": "Administrator", "module": "Buying", "name": "Purchase Order Item", From 1ea12079da89921470ec5f8e423630dd3dded71a Mon Sep 17 00:00:00 2001 From: Raffael Meyer <14891507+barredterra@users.noreply.github.com> Date: Sun, 15 Nov 2020 05:02:24 +0100 Subject: [PATCH 121/477] fix: fiscal year can be shorter than 12 months (#23838) * fix: replace unnecessary SQL query * feat: checkbox "Is Short Year" Also, set checkbox and dates only once. * fix: toggle no longer necessary Date fields use set_only_once. * feat: short years can be less than 12 months * fix: if short year, don't add 12 months to start date * test: short year * fix: move short fiscal year to test records --- .../doctype/fiscal_year/fiscal_year.js | 14 +- .../doctype/fiscal_year/fiscal_year.json | 435 +++++------------- .../doctype/fiscal_year/fiscal_year.py | 19 +- .../doctype/fiscal_year/test_fiscal_year.py | 1 + .../doctype/fiscal_year/test_records.json | 7 + 5 files changed, 131 insertions(+), 345 deletions(-) diff --git a/erpnext/accounts/doctype/fiscal_year/fiscal_year.js b/erpnext/accounts/doctype/fiscal_year/fiscal_year.js index 152e17dbc88..bc77dac1cdd 100644 --- a/erpnext/accounts/doctype/fiscal_year/fiscal_year.js +++ b/erpnext/accounts/doctype/fiscal_year/fiscal_year.js @@ -9,11 +9,7 @@ frappe.ui.form.on('Fiscal Year', { } }, refresh: function (frm) { - let doc = frm.doc; - frm.toggle_enable('year_start_date', doc.__islocal); - frm.toggle_enable('year_end_date', doc.__islocal); - - if (!doc.__islocal && (doc.name != frappe.sys_defaults.fiscal_year)) { + if (!frm.doc.__islocal && (frm.doc.name != frappe.sys_defaults.fiscal_year)) { frm.add_custom_button(__("Set as Default"), () => frm.events.set_as_default(frm)); frm.set_intro(__("To set this Fiscal Year as Default, click on 'Set as Default'")); } else { @@ -24,8 +20,10 @@ frappe.ui.form.on('Fiscal Year', { return frm.call('set_as_default'); }, year_start_date: function(frm) { - let year_end_date = - frappe.datetime.add_days(frappe.datetime.add_months(frm.doc.year_start_date, 12), -1); - frm.set_value("year_end_date", year_end_date); + if (!frm.doc.is_short_year) { + let year_end_date = + frappe.datetime.add_days(frappe.datetime.add_months(frm.doc.year_start_date, 12), -1); + frm.set_value("year_end_date", year_end_date); + } }, }); diff --git a/erpnext/accounts/doctype/fiscal_year/fiscal_year.json b/erpnext/accounts/doctype/fiscal_year/fiscal_year.json index 4ca9f6b96fb..5ab91f2506c 100644 --- a/erpnext/accounts/doctype/fiscal_year/fiscal_year.json +++ b/erpnext/accounts/doctype/fiscal_year/fiscal_year.json @@ -1,347 +1,126 @@ { - "allow_copy": 0, - "allow_guest_to_view": 0, - "allow_import": 1, - "allow_rename": 0, - "autoname": "field:year", - "beta": 0, - "creation": "2013-01-22 16:50:25", - "custom": 0, - "description": "**Fiscal Year** represents a Financial Year. All accounting entries and other major transactions are tracked against **Fiscal Year**.", - "docstatus": 0, - "doctype": "DocType", - "document_type": "Setup", - "editable_grid": 0, + "actions": [], + "allow_import": 1, + "autoname": "field:year", + "creation": "2013-01-22 16:50:25", + "description": "**Fiscal Year** represents a Financial Year. All accounting entries and other major transactions are tracked against **Fiscal Year**.", + "doctype": "DocType", + "document_type": "Setup", + "engine": "InnoDB", + "field_order": [ + "year", + "disabled", + "is_short_year", + "year_start_date", + "year_end_date", + "companies", + "auto_created" + ], "fields": [ { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "description": "For e.g. 2012, 2012-13", - "fieldname": "year", - "fieldtype": "Data", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Year Name", - "length": 0, - "no_copy": 0, - "oldfieldname": "year", - "oldfieldtype": "Data", - "permlevel": 0, - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 1, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, + "description": "For e.g. 2012, 2012-13", + "fieldname": "year", + "fieldtype": "Data", + "in_list_view": 1, + "label": "Year Name", + "oldfieldname": "year", + "oldfieldtype": "Data", + "reqd": 1, + "unique": 1 + }, { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "disabled", - "fieldtype": "Check", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Disabled", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, + "default": "0", + "fieldname": "disabled", + "fieldtype": "Check", + "label": "Disabled" + }, { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "year_start_date", - "fieldtype": "Date", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Year Start Date", - "length": 0, - "no_copy": 1, - "oldfieldname": "year_start_date", - "oldfieldtype": "Date", - "permlevel": 0, - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 1, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, + "fieldname": "year_start_date", + "fieldtype": "Date", + "in_list_view": 1, + "label": "Year Start Date", + "no_copy": 1, + "oldfieldname": "year_start_date", + "oldfieldtype": "Date", + "reqd": 1, + "set_only_once": 1 + }, { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "year_end_date", - "fieldtype": "Date", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Year End Date", - "length": 0, - "no_copy": 1, - "permlevel": 0, - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 1, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, + "fieldname": "year_end_date", + "fieldtype": "Date", + "in_list_view": 1, + "label": "Year End Date", + "no_copy": 1, + "reqd": 1, + "set_only_once": 1 + }, { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "companies", - "fieldtype": "Table", - "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": "Companies", - "length": 0, - "no_copy": 0, - "options": "Fiscal Year Company", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, + "fieldname": "companies", + "fieldtype": "Table", + "label": "Companies", + "options": "Fiscal Year Company" + }, { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "default": "0", - "fieldname": "auto_created", - "fieldtype": "Check", - "hidden": 1, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Auto Created", - "length": 0, - "no_copy": 1, - "permlevel": 0, - "precision": "", - "print_hide": 1, - "print_hide_if_no_value": 0, - "read_only": 1, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 + "default": "0", + "fieldname": "auto_created", + "fieldtype": "Check", + "hidden": 1, + "label": "Auto Created", + "no_copy": 1, + "print_hide": 1, + "read_only": 1 + }, + { + "default": "0", + "description": "Less than 12 months.", + "fieldname": "is_short_year", + "fieldtype": "Check", + "label": "Is Short Year", + "set_only_once": 1 } - ], - "has_web_view": 0, - "hide_heading": 0, - "hide_toolbar": 0, - "icon": "fa fa-calendar", - "idx": 1, - "image_view": 0, - "in_create": 0, - "is_submittable": 0, - "issingle": 0, - "istable": 0, - "max_attachments": 0, - "modified": "2018-04-25 14:21:41.273354", - "modified_by": "Administrator", - "module": "Accounts", - "name": "Fiscal Year", - "owner": "Administrator", + ], + "icon": "fa fa-calendar", + "idx": 1, + "links": [], + "modified": "2020-11-05 12:16:53.081573", + "modified_by": "Administrator", + "module": "Accounts", + "name": "Fiscal Year", + "owner": "Administrator", "permissions": [ { - "amend": 0, - "cancel": 0, - "create": 1, - "delete": 1, - "email": 1, - "export": 0, - "if_owner": 0, - "import": 0, - "permlevel": 0, - "print": 1, - "read": 1, - "report": 1, - "role": "System Manager", - "set_user_permissions": 0, - "share": 1, - "submit": 0, + "create": 1, + "delete": 1, + "email": 1, + "print": 1, + "read": 1, + "report": 1, + "role": "System Manager", + "share": 1, "write": 1 - }, + }, { - "amend": 0, - "cancel": 0, - "create": 0, - "delete": 0, - "email": 0, - "export": 0, - "if_owner": 0, - "import": 0, - "permlevel": 0, - "print": 0, - "read": 1, - "report": 0, - "role": "Sales User", - "set_user_permissions": 0, - "share": 0, - "submit": 0, - "write": 0 - }, + "read": 1, + "role": "Sales User" + }, { - "amend": 0, - "cancel": 0, - "create": 0, - "delete": 0, - "email": 0, - "export": 0, - "if_owner": 0, - "import": 0, - "permlevel": 0, - "print": 0, - "read": 1, - "report": 0, - "role": "Purchase User", - "set_user_permissions": 0, - "share": 0, - "submit": 0, - "write": 0 - }, + "read": 1, + "role": "Purchase User" + }, { - "amend": 0, - "cancel": 0, - "create": 0, - "delete": 0, - "email": 0, - "export": 0, - "if_owner": 0, - "import": 0, - "permlevel": 0, - "print": 0, - "read": 1, - "report": 0, - "role": "Accounts User", - "set_user_permissions": 0, - "share": 0, - "submit": 0, - "write": 0 - }, + "read": 1, + "role": "Accounts User" + }, { - "amend": 0, - "cancel": 0, - "create": 0, - "delete": 0, - "email": 0, - "export": 0, - "if_owner": 0, - "import": 0, - "permlevel": 0, - "print": 0, - "read": 1, - "report": 0, - "role": "Stock User", - "set_user_permissions": 0, - "share": 0, - "submit": 0, - "write": 0 - }, + "read": 1, + "role": "Stock User" + }, { - "amend": 0, - "cancel": 0, - "create": 0, - "delete": 0, - "email": 0, - "export": 0, - "if_owner": 0, - "import": 0, - "permlevel": 0, - "print": 0, - "read": 1, - "report": 0, - "role": "Employee", - "set_user_permissions": 0, - "share": 0, - "submit": 0, - "write": 0 + "read": 1, + "role": "Employee" } - ], - "quick_entry": 0, - "read_only": 0, - "read_only_onload": 0, - "show_name_in_global_search": 1, - "sort_field": "name", - "sort_order": "DESC", - "track_changes": 0, - "track_seen": 0 + ], + "show_name_in_global_search": 1, + "sort_field": "name", + "sort_order": "DESC" } \ No newline at end of file diff --git a/erpnext/accounts/doctype/fiscal_year/fiscal_year.py b/erpnext/accounts/doctype/fiscal_year/fiscal_year.py index d80bc7fad10..da6a3fd2ef9 100644 --- a/erpnext/accounts/doctype/fiscal_year/fiscal_year.py +++ b/erpnext/accounts/doctype/fiscal_year/fiscal_year.py @@ -36,6 +36,11 @@ class FiscalYear(Document): frappe.throw(_("Cannot change Fiscal Year Start Date and Fiscal Year End Date once the Fiscal Year is saved.")) def validate_dates(self): + if self.is_short_year: + # Fiscal Year can be shorter than one year, in some jurisdictions + # under certain circumstances. For example, in the USA and Germany. + return + if getdate(self.year_start_date) > getdate(self.year_end_date): frappe.throw(_("Fiscal Year Start Date should be one year earlier than Fiscal Year End Date"), FiscalYearIncorrectDate) @@ -116,12 +121,8 @@ def auto_create_fiscal_year(): pass def get_from_and_to_date(fiscal_year): - from_and_to_date_tuple = frappe.db.sql("""select year_start_date, year_end_date - from `tabFiscal Year` where name=%s""", (fiscal_year))[0] - - from_and_to_date = { - "from_date": from_and_to_date_tuple[0], - "to_date": from_and_to_date_tuple[1] - } - - return from_and_to_date + fields = [ + "year_start_date as from_date", + "year_end_date as to_date" + ] + return frappe.db.get_value("Fiscal Year", fiscal_year, fields, as_dict=1) diff --git a/erpnext/accounts/doctype/fiscal_year/test_fiscal_year.py b/erpnext/accounts/doctype/fiscal_year/test_fiscal_year.py index f7b77827668..cec4f4492d6 100644 --- a/erpnext/accounts/doctype/fiscal_year/test_fiscal_year.py +++ b/erpnext/accounts/doctype/fiscal_year/test_fiscal_year.py @@ -11,6 +11,7 @@ test_records = frappe.get_test_records('Fiscal Year') test_ignore = ["Company"] class TestFiscalYear(unittest.TestCase): + def test_extra_year(self): if frappe.db.exists("Fiscal Year", "_Test Fiscal Year 2000"): frappe.delete_doc("Fiscal Year", "_Test Fiscal Year 2000") diff --git a/erpnext/accounts/doctype/fiscal_year/test_records.json b/erpnext/accounts/doctype/fiscal_year/test_records.json index d5723ca62ba..44052535cbd 100644 --- a/erpnext/accounts/doctype/fiscal_year/test_records.json +++ b/erpnext/accounts/doctype/fiscal_year/test_records.json @@ -1,4 +1,11 @@ [ + { + "doctype": "Fiscal Year", + "year": "_Test Short Fiscal Year 2011", + "is_short_year": 1, + "year_end_date": "2011-04-01", + "year_start_date": "2011-12-31" + }, { "doctype": "Fiscal Year", "year": "_Test Fiscal Year 2012", From 59be7ff144bd4e17111732fe526d719140653d4c Mon Sep 17 00:00:00 2001 From: Raffael Meyer <14891507+barredterra@users.noreply.github.com> Date: Sun, 15 Nov 2020 05:04:05 +0100 Subject: [PATCH 122/477] feat: make account number length configurable (#23845) --- .../datev_settings/datev_settings.json | 22 ++++++++++++++----- .../regional/germany/utils/datev/datev_csv.py | 2 +- erpnext/regional/report/datev/datev.py | 2 ++ 3 files changed, 19 insertions(+), 7 deletions(-) diff --git a/erpnext/regional/doctype/datev_settings/datev_settings.json b/erpnext/regional/doctype/datev_settings/datev_settings.json index 39486dfc123..713e8e34ef6 100644 --- a/erpnext/regional/doctype/datev_settings/datev_settings.json +++ b/erpnext/regional/doctype/datev_settings/datev_settings.json @@ -1,4 +1,5 @@ { + "actions": [], "autoname": "field:client", "creation": "2019-08-13 23:56:34.259906", "doctype": "DocType", @@ -6,6 +7,7 @@ "engine": "InnoDB", "field_order": [ "client", + "account_number_length", "column_break_2", "client_number", "section_break_4", @@ -28,8 +30,8 @@ "fieldtype": "Data", "in_list_view": 1, "label": "Client ID", - "reqd": 1, - "length": 5 + "length": 5, + "reqd": 1 }, { "fieldname": "consultant", @@ -43,8 +45,8 @@ "fieldtype": "Data", "in_list_view": 1, "label": "Consultant ID", - "reqd": 1, - "length": 7 + "length": 7, + "reqd": 1 }, { "fieldname": "column_break_2", @@ -57,9 +59,17 @@ { "fieldname": "column_break_6", "fieldtype": "Column Break" + }, + { + "default": "4", + "fieldname": "account_number_length", + "fieldtype": "Int", + "label": "Account Number Length", + "reqd": 1 } ], - "modified": "2019-08-14 00:03:26.616460", + "links": [], + "modified": "2020-11-05 17:52:11.674329", "modified_by": "Administrator", "module": "Regional", "name": "DATEV Settings", @@ -104,4 +114,4 @@ "sort_field": "modified", "sort_order": "DESC", "track_changes": 1 -} +} \ No newline at end of file diff --git a/erpnext/regional/germany/utils/datev/datev_csv.py b/erpnext/regional/germany/utils/datev/datev_csv.py index cf07a1c824f..f138a807bca 100644 --- a/erpnext/regional/germany/utils/datev/datev_csv.py +++ b/erpnext/regional/germany/utils/datev/datev_csv.py @@ -106,7 +106,7 @@ def get_header(filters, csv_class): # M = Start of the fiscal year (Wirtschaftsjahresbeginn) frappe.utils.formatdate(filters.get('fiscal_year_start'), 'yyyyMMdd'), # N = Length of account numbers (Sachkontenlänge) - datev_settings.get('account_number_length', '4'), + str(filters.get('account_number_length', 4)), # O = Transaction batch start date (YYYYMMDD) frappe.utils.formatdate(filters.get('from_date'), 'yyyyMMdd') if csv_class.DATA_CATEGORY == DataCategory.TRANSACTIONS else '', # P = Transaction batch end date (YYYYMMDD) diff --git a/erpnext/regional/report/datev/datev.py b/erpnext/regional/report/datev/datev.py index dbae230f1ef..3f4cb981ccb 100644 --- a/erpnext/regional/report/datev/datev.py +++ b/erpnext/regional/report/datev/datev.py @@ -340,6 +340,8 @@ def download_datev_csv(filters): coa = frappe.get_value('Company', company, 'chart_of_accounts') filters['skr'] = '04' if 'SKR04' in coa else ('03' if 'SKR03' in coa else '') + filters['account_number_length'] = frappe.get_value('DATEV Settings', company, 'account_number_length') + transactions = get_transactions(filters) account_names = get_account_names(filters) customers = get_customers(filters) From 10c168e2578ad96afdd2b6d4fecd492fe1e0ee46 Mon Sep 17 00:00:00 2001 From: rohitwaghchaure Date: Sun, 15 Nov 2020 09:40:44 +0530 Subject: [PATCH 123/477] fix: default cost center in item master not set in stock entry (#23877) Co-authored-by: Marica --- .../doctype/work_order/test_work_order.py | 5 ++++ .../stock/doctype/stock_entry/stock_entry.py | 5 ++-- erpnext/stock/get_item_details.py | 23 ++++++++++++++++--- 3 files changed, 27 insertions(+), 6 deletions(-) diff --git a/erpnext/manufacturing/doctype/work_order/test_work_order.py b/erpnext/manufacturing/doctype/work_order/test_work_order.py index 5f8a13428c1..e53927918eb 100644 --- a/erpnext/manufacturing/doctype/work_order/test_work_order.py +++ b/erpnext/manufacturing/doctype/work_order/test_work_order.py @@ -443,6 +443,11 @@ class TestWorkOrder(unittest.TestCase): ste1 = frappe.get_doc(make_stock_entry(wo.name, "Manufacture", 1)) self.assertEqual(len(ste1.items), 3) + def test_cost_center_for_manufacture(self): + wo_order = make_wo_order_test_record() + ste = make_stock_entry(wo_order.name, "Material Transfer for Manufacture", wo_order.qty) + self.assertEquals(ste.get("items")[0].get("cost_center"), "_Test Cost Center - _TC") + def test_operation_time_with_batch_size(self): fg_item = "Test Batch Size Item For BOM" rm1 = "Test Batch Size Item RM 1 For BOM" diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.py b/erpnext/stock/doctype/stock_entry/stock_entry.py index 768526705c9..e3159b95c30 100644 --- a/erpnext/stock/doctype/stock_entry/stock_entry.py +++ b/erpnext/stock/doctype/stock_entry/stock_entry.py @@ -1227,8 +1227,6 @@ class StockEntry(StockController): return item_dict def add_to_stock_entry_detail(self, item_dict, bom_no=None): - cost_center = frappe.db.get_value("Company", self.company, 'cost_center') - for d in item_dict: stock_uom = item_dict[d].get("stock_uom") or frappe.db.get_value("Item", d, "stock_uom") @@ -1239,9 +1237,10 @@ class StockEntry(StockController): se_child.uom = item_dict[d]["uom"] if item_dict[d].get("uom") else stock_uom se_child.stock_uom = stock_uom se_child.qty = flt(item_dict[d]["qty"], se_child.precision("qty")) - se_child.cost_center = item_dict[d].get("cost_center") or cost_center se_child.allow_alternative_item = item_dict[d].get("allow_alternative_item", 0) se_child.subcontracted_item = item_dict[d].get("main_item_code") + se_child.cost_center = (item_dict[d].get("cost_center") or + get_default_cost_center(item_dict[d], company = self.company)) for field in ["idx", "po_detail", "original_item", "expense_account", "description", "item_name"]: diff --git a/erpnext/stock/get_item_details.py b/erpnext/stock/get_item_details.py index 8d8dcb74c31..08f7a83b893 100644 --- a/erpnext/stock/get_item_details.py +++ b/erpnext/stock/get_item_details.py @@ -559,23 +559,40 @@ def get_default_deferred_account(args, item, fieldname=None): else: return None -def get_default_cost_center(args, item, item_group, brand, company=None): +def get_default_cost_center(args, item=None, item_group=None, brand=None, company=None): cost_center = None + + if not company and args.get("company"): + company = args.get("company") + if args.get('project'): cost_center = frappe.db.get_value("Project", args.get("project"), "cost_center", cache=True) - if not cost_center: + if not cost_center and (item and item_group and brand): if args.get('customer'): cost_center = item.get('selling_cost_center') or item_group.get('selling_cost_center') or brand.get('selling_cost_center') else: cost_center = item.get('buying_cost_center') or item_group.get('buying_cost_center') or brand.get('buying_cost_center') - cost_center = cost_center or args.get("cost_center") + elif not cost_center and args.get("item_code") and company: + for method in ["get_item_defaults", "get_item_group_defaults", "get_brand_defaults"]: + path = "erpnext.stock.get_item_details.{0}".format(method) + data = frappe.get_attr(path)(args.get("item_code"), company) + + if data and (data.selling_cost_center or data.buying_cost_center): + return data.selling_cost_center or data.buying_cost_center + + if not cost_center and args.get("cost_center"): + cost_center = args.get("cost_center") if (company and cost_center and frappe.get_cached_value("Cost Center", cost_center, "company") != company): return None + if not cost_center and company: + cost_center = frappe.get_cached_value("Company", + company, "cost_center") + return cost_center def get_default_supplier(args, item, item_group, brand): From 39102e68dfa76050ea33a5b4cda3f7cb4aac615c Mon Sep 17 00:00:00 2001 From: Kenneth Sequeira <33246109+kennethsequeira@users.noreply.github.com> Date: Sun, 15 Nov 2020 09:44:36 +0530 Subject: [PATCH 124/477] fix: make contract template editable (#23891) --- erpnext/crm/doctype/contract_template/contract_template.json | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/erpnext/crm/doctype/contract_template/contract_template.json b/erpnext/crm/doctype/contract_template/contract_template.json index ef9974f8636..5e4582f8d3d 100644 --- a/erpnext/crm/doctype/contract_template/contract_template.json +++ b/erpnext/crm/doctype/contract_template/contract_template.json @@ -23,8 +23,7 @@ { "fieldname": "contract_terms", "fieldtype": "Text Editor", - "label": "Contract Terms and Conditions", - "read_only": 1 + "label": "Contract Terms and Conditions" }, { "fieldname": "sb_fulfilment", @@ -45,7 +44,7 @@ } ], "links": [], - "modified": "2020-06-03 00:24:58.179816", + "modified": "2020-11-11 17:49:44.879363", "modified_by": "Administrator", "module": "CRM", "name": "Contract Template", From 896e4b1722dcf3e1bcab13d1421b53efec44e92e Mon Sep 17 00:00:00 2001 From: Raffael Meyer <14891507+barredterra@users.noreply.github.com> Date: Sun, 15 Nov 2020 05:15:10 +0100 Subject: [PATCH 125/477] fix: improve UX of DATEV report (#23892) * feat(DATEV Settings): button to show report * feat(desk): add DATEV to Reports under Accounting * fix(report DATEV): last calendar month as default * fix: let user create DATEV Settings (Instead of showing an error message.) --- .../desk_page/accounting/accounting.json | 4 ++-- .../doctype/datev_settings/datev_settings.js | 6 +++--- erpnext/regional/report/datev/datev.js | 18 ++++++++++++++++-- erpnext/regional/report/datev/datev.py | 19 +++++++++++++------ 4 files changed, 34 insertions(+), 13 deletions(-) diff --git a/erpnext/accounts/desk_page/accounting/accounting.json b/erpnext/accounts/desk_page/accounting/accounting.json index 45e3dcf5e73..2917a364639 100644 --- a/erpnext/accounts/desk_page/accounting/accounting.json +++ b/erpnext/accounts/desk_page/accounting/accounting.json @@ -23,7 +23,7 @@ { "hidden": 0, "label": "Reports", - "links": "[\n {\n \"dependencies\": [\n \"GL Entry\"\n ],\n \"doctype\": \"GL Entry\",\n \"is_query_report\": true,\n \"label\": \"Trial Balance for Party\",\n \"name\": \"Trial Balance for Party\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Journal Entry\"\n ],\n \"doctype\": \"Journal Entry\",\n \"is_query_report\": true,\n \"label\": \"Payment Period Based On Invoice Date\",\n \"name\": \"Payment Period Based On Invoice Date\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Sales Invoice\"\n ],\n \"doctype\": \"Sales Invoice\",\n \"is_query_report\": true,\n \"label\": \"Sales Partners Commission\",\n \"name\": \"Sales Partners Commission\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Customer\"\n ],\n \"doctype\": \"Customer\",\n \"is_query_report\": true,\n \"label\": \"Customer Credit Balance\",\n \"name\": \"Customer Credit Balance\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Sales Invoice\"\n ],\n \"doctype\": \"Sales Invoice\",\n \"is_query_report\": true,\n \"label\": \"Sales Payment Summary\",\n \"name\": \"Sales Payment Summary\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Address\"\n ],\n \"doctype\": \"Address\",\n \"is_query_report\": true,\n \"label\": \"Address And Contacts\",\n \"name\": \"Address And Contacts\",\n \"type\": \"report\"\n }\n]" + "links": "[\n {\n \"dependencies\": [\n \"GL Entry\"\n ],\n \"doctype\": \"GL Entry\",\n \"is_query_report\": true,\n \"label\": \"Trial Balance for Party\",\n \"name\": \"Trial Balance for Party\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Journal Entry\"\n ],\n \"doctype\": \"Journal Entry\",\n \"is_query_report\": true,\n \"label\": \"Payment Period Based On Invoice Date\",\n \"name\": \"Payment Period Based On Invoice Date\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Sales Invoice\"\n ],\n \"doctype\": \"Sales Invoice\",\n \"is_query_report\": true,\n \"label\": \"Sales Partners Commission\",\n \"name\": \"Sales Partners Commission\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Customer\"\n ],\n \"doctype\": \"Customer\",\n \"is_query_report\": true,\n \"label\": \"Customer Credit Balance\",\n \"name\": \"Customer Credit Balance\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Sales Invoice\"\n ],\n \"doctype\": \"Sales Invoice\",\n \"is_query_report\": true,\n \"label\": \"Sales Payment Summary\",\n \"name\": \"Sales Payment Summary\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Address\"\n ],\n \"doctype\": \"Address\",\n \"is_query_report\": true,\n \"label\": \"Address And Contacts\",\n \"name\": \"Address And Contacts\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"GL Entry\"\n ],\n \"doctype\": \"GL Entry\",\n \"is_query_report\": true,\n \"label\": \"DATEV Export\",\n \"name\": \"DATEV\",\n \"type\": \"report\"\n }\n]" }, { "hidden": 0, @@ -99,7 +99,7 @@ "idx": 0, "is_standard": 1, "label": "Accounting", - "modified": "2020-11-06 13:05:58.650150", + "modified": "2020-11-11 18:35:11.542909", "modified_by": "Administrator", "module": "Accounts", "name": "Accounting", diff --git a/erpnext/regional/doctype/datev_settings/datev_settings.js b/erpnext/regional/doctype/datev_settings/datev_settings.js index 69747b0b89e..f04705929fc 100644 --- a/erpnext/regional/doctype/datev_settings/datev_settings.js +++ b/erpnext/regional/doctype/datev_settings/datev_settings.js @@ -2,7 +2,7 @@ // For license information, please see license.txt frappe.ui.form.on('DATEV Settings', { - // refresh: function(frm) { - - // } + refresh: function(frm) { + frm.add_custom_button('Show Report', () => frappe.set_route('query-report', 'DATEV'), "fa fa-table"); + } }); diff --git a/erpnext/regional/report/datev/datev.js b/erpnext/regional/report/datev/datev.js index 55f12cf3738..4124e3df190 100644 --- a/erpnext/regional/report/datev/datev.js +++ b/erpnext/regional/report/datev/datev.js @@ -11,14 +11,14 @@ frappe.query_reports["DATEV"] = { { "fieldname": "from_date", "label": __("From Date"), - "default": frappe.datetime.month_start(), + "default": moment().subtract(1, 'month').startOf('month').format(), "fieldtype": "Date", "reqd": 1 }, { "fieldname": "to_date", "label": __("To Date"), - "default": frappe.datetime.now_date(), + "default": moment().subtract(1, 'month').endOf('month').format(), "fieldtype": "Date", "reqd": 1 }, @@ -30,9 +30,23 @@ frappe.query_reports["DATEV"] = { } ], onload: function(query_report) { + let company = frappe.query_report.get_filter_value('company'); + frappe.db.exists('DATEV Settings', company).then((settings_exist) => { + if (!settings_exist) { + frappe.confirm(__('DATEV Settings for your Company are missing. Would you like to create them now?'), + () => frappe.new_doc('DATEV Settings', {'company': company}) + ); + } + }); + query_report.page.add_menu_item(__("Download DATEV File"), () => { const filters = JSON.stringify(query_report.get_values()); window.open(`/api/method/erpnext.regional.report.datev.datev.download_datev_csv?filters=${filters}`); }); + + query_report.page.add_menu_item(__("Change DATEV Settings"), () => { + let company = frappe.query_report.get_filter_value('company'); // read company from filters again – it might have changed by now. + frappe.set_route('Form', 'DATEV Settings', company); + }); } }; diff --git a/erpnext/regional/report/datev/datev.py b/erpnext/regional/report/datev/datev.py index 3f4cb981ccb..1e39c57786c 100644 --- a/erpnext/regional/report/datev/datev.py +++ b/erpnext/regional/report/datev/datev.py @@ -94,8 +94,11 @@ COLUMNS = [ def execute(filters=None): """Entry point for frappe.""" - validate(filters) - return COLUMNS, get_transactions(filters, as_dict=0) + data = [] + if filters and validate(filters): + data = get_transactions(filters, as_dict=0) + + return COLUMNS, data def validate(filters): @@ -114,10 +117,14 @@ def validate(filters): validate_fiscal_year(from_date, to_date, company) - try: - frappe.get_doc('DATEV Settings', filters.get('company')) - except frappe.DoesNotExistError: - frappe.throw(_('Please create DATEV Settings for Company {}.').format(filters.get('company'))) + if not frappe.db.exists('DATEV Settings', filters.get('company')): + frappe.log_error(_('Please create {} for Company {}.').format( + '{}'.format(_('DATEV Settings')), + frappe.bold(filters.get('company')) + )) + return False + + return True def validate_fiscal_year(from_date, to_date, company): From 58a3fea1b7229378713a1b1f95a9d84d71a9aeeb Mon Sep 17 00:00:00 2001 From: Anurag Mishra <32095923+Anurag810@users.noreply.github.com> Date: Sun, 15 Nov 2020 11:14:35 +0530 Subject: [PATCH 126/477] fix: Error handling in Upload Attendance (#23907) --- erpnext/hr/doctype/upload_attendance/upload_attendance.js | 8 ++++---- erpnext/hr/doctype/upload_attendance/upload_attendance.py | 7 ++++++- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/erpnext/hr/doctype/upload_attendance/upload_attendance.js b/erpnext/hr/doctype/upload_attendance/upload_attendance.js index 9df2948a157..29aa85484a8 100644 --- a/erpnext/hr/doctype/upload_attendance/upload_attendance.js +++ b/erpnext/hr/doctype/upload_attendance/upload_attendance.js @@ -24,10 +24,10 @@ erpnext.hr.AttendanceControlPanel = frappe.ui.form.Controller.extend({ } window.location.href = repl(frappe.request.url + '?cmd=%(cmd)s&from_date=%(from_date)s&to_date=%(to_date)s', { - cmd: "erpnext.hr.doctype.upload_attendance.upload_attendance.get_template", - from_date: this.frm.doc.att_fr_date, - to_date: this.frm.doc.att_to_date, - }); + cmd: "erpnext.hr.doctype.upload_attendance.upload_attendance.get_template", + from_date: this.frm.doc.att_fr_date, + to_date: this.frm.doc.att_to_date, + }); }, show_upload() { diff --git a/erpnext/hr/doctype/upload_attendance/upload_attendance.py b/erpnext/hr/doctype/upload_attendance/upload_attendance.py index edf05e827b9..674c8e3eb45 100644 --- a/erpnext/hr/doctype/upload_attendance/upload_attendance.py +++ b/erpnext/hr/doctype/upload_attendance/upload_attendance.py @@ -28,7 +28,12 @@ def get_template(): w = UnicodeWriter() w = add_header(w) - w = add_data(w, args) + try: + w = add_data(w, args) + except Exception as e: + frappe.clear_messages() + frappe.respond_as_web_page("Holiday List Missing", html=e) + return # write out response as a type csv frappe.response['result'] = cstr(w.getvalue()) From 8e2ce641c3d96d6c126e47bc9c691d8ff4671024 Mon Sep 17 00:00:00 2001 From: marination Date: Wed, 14 Oct 2020 14:05:54 +0530 Subject: [PATCH 127/477] fix: Dont overrule Item Price via Pricing Rule Rate if 0 --- erpnext/accounts/doctype/pricing_rule/pricing_rule.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/erpnext/accounts/doctype/pricing_rule/pricing_rule.py b/erpnext/accounts/doctype/pricing_rule/pricing_rule.py index 149c47673c6..55a5b0e5139 100644 --- a/erpnext/accounts/doctype/pricing_rule/pricing_rule.py +++ b/erpnext/accounts/doctype/pricing_rule/pricing_rule.py @@ -352,8 +352,14 @@ def apply_price_discount_rule(pricing_rule, item_details, args): pricing_rule_rate = 0.0 if pricing_rule.currency == args.currency: pricing_rule_rate = pricing_rule.rate + + if pricing_rule_rate: + # Override already set price list rate (from item price) + # if pricing_rule_rate > 0 + item_details.update({ + "price_list_rate": pricing_rule_rate * args.get("conversion_factor", 1), + }) item_details.update({ - "price_list_rate": pricing_rule_rate * args.get("conversion_factor", 1), "discount_percentage": 0.0 }) From d0ee615c2ce33c9cc0693877974f8b80e0b51ad3 Mon Sep 17 00:00:00 2001 From: marination Date: Tue, 3 Nov 2020 20:22:48 +0530 Subject: [PATCH 128/477] chore: Pricing Rule with Item Price Test --- .../doctype/pricing_rule/test_pricing_rule.py | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/erpnext/accounts/doctype/pricing_rule/test_pricing_rule.py b/erpnext/accounts/doctype/pricing_rule/test_pricing_rule.py index 22a031c162f..ec0a485bfc1 100644 --- a/erpnext/accounts/doctype/pricing_rule/test_pricing_rule.py +++ b/erpnext/accounts/doctype/pricing_rule/test_pricing_rule.py @@ -484,6 +484,43 @@ class TestPricingRule(unittest.TestCase): frappe.delete_doc_if_exists("Pricing Rule", "_Test Pricing Rule 1") frappe.delete_doc_if_exists("Pricing Rule", "_Test Pricing Rule 2") + def test_item_price_with_pricing_rule(self): + item = make_item("Water Flask") + make_item_price("Water Flask", "_Test Price List", 100) + + pricing_rule_record = { + "doctype": "Pricing Rule", + "title": "_Test Water Flask Rule", + "apply_on": "Item Code", + "items": [{ + "item_code": "Water Flask", + }], + "selling": 1, + "currency": "INR", + "rate_or_discount": "Rate", + "rate": 0, + "margin_type": "Percentage", + "margin_rate_or_amount": 2, + "company": "_Test Company" + } + rule = frappe.get_doc(pricing_rule_record) + rule.insert() + + si = create_sales_invoice(do_not_save=True, item_code="Water Flask") + si.selling_price_list = "_Test Price List" + si.save() + + # If rate in Rule is 0, give preference to Item Price if it exists + self.assertEqual(si.items[0].price_list_rate, 100) + self.assertEqual(si.items[0].margin_rate_or_amount, 2) + self.assertEqual(si.items[0].rate_with_margin, 102) + self.assertEqual(si.items[0].rate, 102) + + si.delete() + rule.delete() + frappe.get_doc("Item Price", {"item_code": "Water Flask"}).delete() + item.delete() + def make_pricing_rule(**args): args = frappe._dict(args) From beb1811523b4ed57a2978a8632507ec96eff4947 Mon Sep 17 00:00:00 2001 From: Afshan Date: Wed, 11 Nov 2020 15:13:38 +0530 Subject: [PATCH 129/477] fix: payroll attendance error --- .../doctype/payroll_entry/payroll_entry.py | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/erpnext/payroll/doctype/payroll_entry/payroll_entry.py b/erpnext/payroll/doctype/payroll_entry/payroll_entry.py index 30ea432678c..49c204ab443 100644 --- a/erpnext/payroll/doctype/payroll_entry/payroll_entry.py +++ b/erpnext/payroll/doctype/payroll_entry/payroll_entry.py @@ -344,9 +344,13 @@ class PayrollEntry(Document): employees_to_mark_attendance = [] days_in_payroll, days_holiday, days_attendance_marked = 0, 0, 0 for employee_detail in self.employees: - days_holiday = self.get_count_holidays_of_employee(employee_detail.employee) - days_attendance_marked = self.get_count_employee_attendance(employee_detail.employee) - days_in_payroll = date_diff(self.end_date, self.start_date) + 1 + employee_joining_date = frappe.db.get_value("Employee", employee_detail.employee, 'date_of_joining') + start_date = self.start_date + if employee_joining_date > getdate(self.start_date): + start_date = employee_joining_date + days_holiday = self.get_count_holidays_of_employee(employee_detail.employee, start_date) + days_attendance_marked = self.get_count_employee_attendance(employee_detail.employee, start_date) + days_in_payroll = date_diff(self.end_date, start_date) + 1 if days_in_payroll > days_holiday + days_attendance_marked: employees_to_mark_attendance.append({ "employee": employee_detail.employee, @@ -354,22 +358,22 @@ class PayrollEntry(Document): }) return employees_to_mark_attendance - def get_count_holidays_of_employee(self, employee): + def get_count_holidays_of_employee(self, employee, start_date): holiday_list = get_holiday_list_for_employee(employee) holidays = 0 if holiday_list: days = frappe.db.sql("""select count(*) from tabHoliday where parent=%s and holiday_date between %s and %s""", (holiday_list, - self.start_date, self.end_date)) + start_date, self.end_date)) if days and days[0][0]: holidays = days[0][0] return holidays - def get_count_employee_attendance(self, employee): + def get_count_employee_attendance(self, employee, start_date): marked_days = 0 attendances = frappe.db.sql("""select count(*) from tabAttendance where employee=%s and docstatus=1 and attendance_date between %s and %s""", - (employee, self.start_date, self.end_date)) + (employee, start_date, self.end_date)) if attendances and attendances[0][0]: marked_days = attendances[0][0] return marked_days From 8c3b2d0a0d04c1d7e021b4462986e5645534e01c Mon Sep 17 00:00:00 2001 From: Afshan Date: Fri, 13 Nov 2020 17:04:05 +0530 Subject: [PATCH 130/477] fix: change query to frappe.get_all --- erpnext/payroll/doctype/payroll_entry/payroll_entry.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/erpnext/payroll/doctype/payroll_entry/payroll_entry.py b/erpnext/payroll/doctype/payroll_entry/payroll_entry.py index 49c204ab443..a3d12c35c09 100644 --- a/erpnext/payroll/doctype/payroll_entry/payroll_entry.py +++ b/erpnext/payroll/doctype/payroll_entry/payroll_entry.py @@ -371,9 +371,12 @@ class PayrollEntry(Document): def get_count_employee_attendance(self, employee, start_date): marked_days = 0 - attendances = frappe.db.sql("""select count(*) from tabAttendance where - employee=%s and docstatus=1 and attendance_date between %s and %s""", - (employee, start_date, self.end_date)) + attendances = frappe.get_all("Attendance", + fields = ["count(*)"], + filters = { + "employee": employee, + "attendance_date": ('between', [start_date, self.end_date]) + }, as_list=1) if attendances and attendances[0][0]: marked_days = attendances[0][0] return marked_days From c8b5f982ac0f97f88b41e1c2f22d99a2d21f3f37 Mon Sep 17 00:00:00 2001 From: Suraj Shetty <13928957+surajshetty3416@users.noreply.github.com> Date: Tue, 17 Nov 2020 10:58:09 +0530 Subject: [PATCH 131/477] fix: Typo (Enchashment > Encashment) (#23919) --- erpnext/patches/v12_0/generate_leave_ledger_entries.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/patches/v12_0/generate_leave_ledger_entries.py b/erpnext/patches/v12_0/generate_leave_ledger_entries.py index 7afde373c30..fe072d7eb96 100644 --- a/erpnext/patches/v12_0/generate_leave_ledger_entries.py +++ b/erpnext/patches/v12_0/generate_leave_ledger_entries.py @@ -51,7 +51,7 @@ def generate_encashment_leave_ledger_entries(): for encashment in leave_encashments: if not frappe.db.exists("Leave Ledger Entry", {'transaction_type': 'Leave Encashment', 'transaction_name': encashment.name}): - frappe.get_doc("Leave Enchashment", encashment).create_leave_ledger_entry() + frappe.get_doc("Leave Encashment", encashment).create_leave_ledger_entry() def generate_expiry_allocation_ledger_entries(): ''' fix ledger entries for missing leave allocation transaction ''' From 1466ed4579736422e0ded807a044c05384a1d460 Mon Sep 17 00:00:00 2001 From: Marica Date: Tue, 17 Nov 2020 11:12:31 +0530 Subject: [PATCH 132/477] fix: Don't copy terms and discount from SO to PO (#23903) * fix: Dont copy terms, discount and required by from SO to PO * fix: Let delivery date and required by date get mapped --- .../selling/doctype/sales_order/sales_order.py | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/erpnext/selling/doctype/sales_order/sales_order.py b/erpnext/selling/doctype/sales_order/sales_order.py index ec1c82339be..04d85e575cc 100755 --- a/erpnext/selling/doctype/sales_order/sales_order.py +++ b/erpnext/selling/doctype/sales_order/sales_order.py @@ -844,7 +844,8 @@ def make_purchase_order_for_default_supplier(source_name, selected_items=None, t "contact_email", "contact_person", "taxes_and_charges", - "shipping_address" + "shipping_address", + "terms" ], "validation": { "docstatus": ["=", 1] @@ -863,7 +864,10 @@ def make_purchase_order_for_default_supplier(source_name, selected_items=None, t "field_no_map": [ "rate", "price_list_rate", - "item_tax_template" + "item_tax_template", + "discount_percentage", + "discount_amount", + "pricing_rules" ], "postprocess": update_item, "condition": lambda doc: doc.ordered_qty < doc.stock_qty and doc.supplier == supplier and doc.item_code in items_to_map @@ -917,7 +921,8 @@ def make_purchase_order(source_name, selected_items=None, target_doc=None): "contact_email", "contact_person", "taxes_and_charges", - "shipping_address" + "shipping_address", + "terms" ], "validation": { "docstatus": ["=", 1] @@ -937,7 +942,10 @@ def make_purchase_order(source_name, selected_items=None, target_doc=None): "rate", "price_list_rate", "item_tax_template", - "supplier" + "discount_percentage", + "discount_amount", + "supplier", + "pricing_rules" ], "postprocess": update_item, "condition": lambda doc: doc.ordered_qty < doc.stock_qty and doc.item_code in items_to_map From 7e2d8ca91676c9edafcfa7e8378ae0a2ac109052 Mon Sep 17 00:00:00 2001 From: Afshan <33727827+AfshanKhan@users.noreply.github.com> Date: Tue, 17 Nov 2020 12:08:31 +0530 Subject: [PATCH 133/477] fix: Handle the "no leave_allocation found" case (#23922) * fix: Handle the "no leave_allocation found" case * fix: format of error msg --- erpnext/hr/doctype/leave_encashment/leave_encashment.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/erpnext/hr/doctype/leave_encashment/leave_encashment.py b/erpnext/hr/doctype/leave_encashment/leave_encashment.py index 8913c648c52..c1dcc97b1a9 100644 --- a/erpnext/hr/doctype/leave_encashment/leave_encashment.py +++ b/erpnext/hr/doctype/leave_encashment/leave_encashment.py @@ -32,7 +32,7 @@ class LeaveEncashment(Document): additional_salary.employee = self.employee earning_component = frappe.get_value("Leave Type", self.leave_type, "earning_component") if not earning_component: - frappe.throw(_("Please set Earning Component for Leave type: {0}.".format(self.leave_type))) + frappe.throw(_("Please set Earning Component for Leave type: {0}.").format(self.leave_type)) additional_salary.salary_component = earning_component additional_salary.payroll_date = self.encashment_date additional_salary.amount = self.encashment_amount @@ -98,7 +98,11 @@ class LeaveEncashment(Document): create_leave_ledger_entry(self, args, submit) # create reverse entry for expired leaves - to_date = self.get_leave_allocation().get('to_date') + leave_allocation = self.get_leave_allocation() + if not leave_allocation: + return + + to_date = leave_allocation.get('to_date') if to_date < getdate(nowdate()): args = frappe._dict( leaves=self.encashable_days, From 9707b4789e24071752660d3f55b22d118fd3f143 Mon Sep 17 00:00:00 2001 From: rohitwaghchaure Date: Tue, 17 Nov 2020 12:10:27 +0530 Subject: [PATCH 134/477] fix: stock ageing report not working (#23923) --- erpnext/stock/report/stock_ageing/stock_ageing.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/erpnext/stock/report/stock_ageing/stock_ageing.py b/erpnext/stock/report/stock_ageing/stock_ageing.py index 3dc806fb430..8aaf7abcbe4 100644 --- a/erpnext/stock/report/stock_ageing/stock_ageing.py +++ b/erpnext/stock/report/stock_ageing/stock_ageing.py @@ -20,7 +20,8 @@ def execute(filters=None): fifo_queue = sorted(filter(_func, item_dict["fifo_queue"]), key=_func) details = item_dict["details"] - if not fifo_queue and (not item_dict.get("total_qty")): continue + + if not fifo_queue: continue average_age = get_average_age(fifo_queue, to_date) earliest_age = date_diff(to_date, fifo_queue[0][1]) From 61388d412b11f7fbcab52871c147695f0e01ef35 Mon Sep 17 00:00:00 2001 From: Shivam Mishra Date: Tue, 17 Nov 2020 13:02:15 +0530 Subject: [PATCH 135/477] feat: update desk pages --- .../desk_page/accounting/accounting.json | 953 +++++++++++++++++- .../desk_page/agriculture/agriculture.json | 124 ++- erpnext/assets/desk_page/assets/assets.json | 133 ++- erpnext/buying/desk_page/buying/buying.json | 413 +++++++- erpnext/crm/desk_page/crm/crm.json | 318 +++++- .../desk_page/education/education.json | 569 ++++++++++- .../erpnext_integrations.json | 88 +- .../erpnext_integrations_settings.json | 56 +- .../desk_page/healthcare/healthcare.json | 427 +++++++- erpnext/hr/desk_page/hr/hr.json | 804 ++++++++++++++- .../loan_management/desk_page/loan/loan.json | 192 +++- .../manufacturing/manufacturing.json | 252 ++++- .../desk_page/non_profit/non_profit.json | 163 ++- .../payroll/desk_page/payroll/payroll.json | 248 ++++- .../projects/desk_page/projects/projects.json | 124 ++- .../desk_page/quality/quality.json | 122 ++- erpnext/selling/desk_page/retail/retail.json | 79 +- .../selling/desk_page/selling/selling.json | 453 ++++++++- .../erpnext_settings/erpnext_settings.json | 3 +- erpnext/setup/desk_page/home/home.json | 373 ++++++- erpnext/stock/desk_page/stock/stock.json | 582 ++++++++++- .../support/desk_page/support/support.json | 136 ++- .../desk_page/utilities/utilities.json | 31 +- 23 files changed, 6601 insertions(+), 42 deletions(-) diff --git a/erpnext/accounts/desk_page/accounting/accounting.json b/erpnext/accounts/desk_page/accounting/accounting.json index 2917a364639..dfc2243b38a 100644 --- a/erpnext/accounts/desk_page/accounting/accounting.json +++ b/erpnext/accounts/desk_page/accounting/accounting.json @@ -99,7 +99,958 @@ "idx": 0, "is_standard": 1, "label": "Accounting", - "modified": "2020-11-11 18:35:11.542909", + "links": [ + { + "hidden": 0, + "is_query_report": 0, + "label": "Accounting Masters", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Company", + "link_to": "Company", + "link_type": "DocType", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Chart of Accounts", + "link_to": "Account", + "link_type": "DocType", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Accounts Settings", + "link_to": "Accounts Settings", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Fiscal Year", + "link_to": "Fiscal Year", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Accounting Dimension", + "link_to": "Accounting Dimension", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Finance Book", + "link_to": "Finance Book", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Accounting Period", + "link_to": "Accounting Period", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Payment Term", + "link_to": "Payment Term", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "General Ledger", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Journal Entry", + "link_to": "Journal Entry", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Journal Entry Template", + "link_to": "Journal Entry Template", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 1, + "label": "General Ledger", + "link_to": "General Ledger", + "link_type": "Report", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 1, + "label": "Customer Ledger Summary", + "link_to": "Customer Ledger Summary", + "link_type": "Report", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 1, + "label": "Supplier Ledger Summary", + "link_to": "Supplier Ledger Summary", + "link_type": "Report", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Accounts Receivable", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Sales Invoice", + "link_to": "Sales Invoice", + "link_type": "DocType", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Customer", + "link_to": "Customer", + "link_type": "DocType", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Payment Entry", + "link_to": "Payment Entry", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Payment Request", + "link_to": "Payment Request", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 1, + "label": "Accounts Receivable", + "link_to": "Accounts Receivable", + "link_type": "Report", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 1, + "label": "Accounts Receivable Summary", + "link_to": "Accounts Receivable Summary", + "link_type": "Report", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 1, + "label": "Sales Register", + "link_to": "Sales Register", + "link_type": "Report", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 1, + "label": "Item-wise Sales Register", + "link_to": "Item-wise Sales Register", + "link_type": "Report", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 1, + "label": "Sales Order Analysis", + "link_to": "Sales Order Analysis", + "link_type": "Report", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 1, + "label": "Delivered Items To Be Billed", + "link_to": "Delivered Items To Be Billed", + "link_type": "Report", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Accounts Payable", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Purchase Invoice", + "link_to": "Purchase Invoice", + "link_type": "DocType", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Supplier", + "link_to": "Supplier", + "link_type": "DocType", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Payment Entry", + "link_to": "Payment Entry", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 1, + "label": "Accounts Payable", + "link_to": "Accounts Payable", + "link_type": "Report", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 1, + "label": "Accounts Payable Summary", + "link_to": "Accounts Payable Summary", + "link_type": "Report", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 1, + "label": "Purchase Register", + "link_to": "Purchase Register", + "link_type": "Report", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 1, + "label": "Item-wise Purchase Register", + "link_to": "Item-wise Purchase Register", + "link_type": "Report", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 1, + "label": "Purchase Order Analysis", + "link_to": "Purchase Order Analysis", + "link_type": "Report", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 1, + "label": "Received Items To Be Billed", + "link_to": "Received Items To Be Billed", + "link_type": "Report", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Reports", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 1, + "label": "Trial Balance for Party", + "link_to": "Trial Balance for Party", + "link_type": "Report", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 1, + "label": "Payment Period Based On Invoice Date", + "link_to": "Payment Period Based On Invoice Date", + "link_type": "Report", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 1, + "label": "Sales Partners Commission", + "link_to": "Sales Partners Commission", + "link_type": "Report", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 1, + "label": "Customer Credit Balance", + "link_to": "Customer Credit Balance", + "link_type": "Report", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 1, + "label": "Sales Payment Summary", + "link_to": "Sales Payment Summary", + "link_type": "Report", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 1, + "label": "Address And Contacts", + "link_to": "Address And Contacts", + "link_type": "Report", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 1, + "label": "DATEV Export", + "link_to": "DATEV", + "link_type": "Report", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Financial Statements", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 1, + "label": "Trial Balance", + "link_to": "Trial Balance", + "link_type": "Report", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 1, + "label": "Profit and Loss Statement", + "link_to": "Profit and Loss Statement", + "link_type": "Report", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 1, + "label": "Balance Sheet", + "link_to": "Balance Sheet", + "link_type": "Report", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 1, + "label": "Cash Flow", + "link_to": "Cash Flow", + "link_type": "Report", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 1, + "label": "Consolidated Financial Statement", + "link_to": "Consolidated Financial Statement", + "link_type": "Report", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Multi Currency", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Currency", + "link_to": "Currency", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Currency Exchange", + "link_to": "Currency Exchange", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Exchange Rate Revaluation", + "link_to": "Exchange Rate Revaluation", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Settings", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Payment Gateway Account", + "link_to": "Payment Gateway Account", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Terms and Conditions Template", + "link_to": "Terms and Conditions", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Mode of Payment", + "link_to": "Mode of Payment", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Bank Statement", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Bank", + "link_to": "Bank", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Bank Account", + "link_to": "Bank Account", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Bank Clearance", + "link_to": "Bank Clearance", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Bank Reconciliation", + "link_to": "bank-reconciliation", + "link_type": "Page", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 1, + "label": "Bank Reconciliation Statement", + "link_to": "Bank Reconciliation Statement", + "link_type": "Report", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Bank Statement Transaction Entry", + "link_to": "Bank Statement Transaction Entry", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Bank Statement Settings", + "link_to": "Bank Statement Settings", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Subscription Management", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Subscription Plan", + "link_to": "Subscription Plan", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Subscription", + "link_to": "Subscription", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Subscription Settings", + "link_to": "Subscription Settings", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Goods and Services Tax (GST India)", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "GST Settings", + "link_to": "GST Settings", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "GST HSN Code", + "link_to": "GST HSN Code", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 1, + "label": "GSTR-1", + "link_to": "GSTR-1", + "link_type": "Report", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 1, + "label": "GSTR-2", + "link_to": "GSTR-2", + "link_type": "Report", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "GSTR 3B Report", + "link_to": "GSTR 3B Report", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 1, + "label": "GST Sales Register", + "link_to": "GST Sales Register", + "link_type": "Report", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 1, + "label": "GST Purchase Register", + "link_to": "GST Purchase Register", + "link_type": "Report", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 1, + "label": "GST Itemised Sales Register", + "link_to": "GST Itemised Sales Register", + "link_type": "Report", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 1, + "label": "GST Itemised Purchase Register", + "link_to": "GST Itemised Purchase Register", + "link_type": "Report", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "C-Form", + "link_to": "C-Form", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Lower Deduction Certificate", + "link_to": "Lower Deduction Certificate", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Share Management", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Shareholder", + "link_to": "Shareholder", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Share Transfer", + "link_to": "Share Transfer", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 1, + "label": "Share Ledger", + "link_to": "Share Ledger", + "link_type": "Report", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 1, + "label": "Share Balance", + "link_to": "Share Balance", + "link_type": "Report", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Cost Center and Budgeting", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Chart of Cost Centers", + "link_to": "Cost Center", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Budget", + "link_to": "Budget", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Accounting Dimension", + "link_to": "Accounting Dimension", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 1, + "label": "Budget Variance Report", + "link_to": "Budget Variance Report", + "link_type": "Report", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Monthly Distribution", + "link_to": "Monthly Distribution", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Opening and Closing", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Opening Invoice Creation Tool", + "link_to": "Opening Invoice Creation Tool", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Chart of Accounts Importer", + "link_to": "Chart of Accounts Importer", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Period Closing Voucher", + "link_to": "Period Closing Voucher", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Taxes", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Sales Taxes and Charges Template", + "link_to": "Sales Taxes and Charges Template", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Purchase Taxes and Charges Template", + "link_to": "Purchase Taxes and Charges Template", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Item Tax Template", + "link_to": "Item Tax Template", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Tax Category", + "link_to": "Tax Category", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Tax Rule", + "link_to": "Tax Rule", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Tax Withholding Category", + "link_to": "Tax Withholding Category", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Profitability", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 1, + "label": "Gross Profit", + "link_to": "Gross Profit", + "link_type": "Report", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 1, + "label": "Profitability Analysis", + "link_to": "Profitability Analysis", + "link_type": "Report", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 1, + "label": "Sales Invoice Trends", + "link_to": "Sales Invoice Trends", + "link_type": "Report", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 1, + "label": "Purchase Invoice Trends", + "link_to": "Purchase Invoice Trends", + "link_type": "Report", + "onboard": 0, + "type": "Card Break" + } + ], + "modified": "2020-11-17 13:00:30.922133", "modified_by": "Administrator", "module": "Accounts", "name": "Accounting", diff --git a/erpnext/agriculture/desk_page/agriculture/agriculture.json b/erpnext/agriculture/desk_page/agriculture/agriculture.json index 094e1652b33..30ac23d60f3 100644 --- a/erpnext/agriculture/desk_page/agriculture/agriculture.json +++ b/erpnext/agriculture/desk_page/agriculture/agriculture.json @@ -29,7 +29,129 @@ "idx": 0, "is_standard": 1, "label": "Agriculture", - "modified": "2020-06-30 18:35:25.350213", + "links": [ + { + "hidden": 0, + "is_query_report": 0, + "label": "Crops & Lands", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Crop", + "link_to": "Crop", + "link_type": "DocType", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Crop Cycle", + "link_to": "Crop Cycle", + "link_type": "DocType", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Location", + "link_to": "Location", + "link_type": "DocType", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Analytics", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Plant Analysis", + "link_to": "Plant Analysis", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Soil Analysis", + "link_to": "Soil Analysis", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Water Analysis", + "link_to": "Water Analysis", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Soil Texture", + "link_to": "Soil Texture", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Weather", + "link_to": "Weather", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Agriculture Analysis Criteria", + "link_to": "Agriculture Analysis Criteria", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Diseases & Fertilizers", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Disease", + "link_to": "Disease", + "link_type": "DocType", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Fertilizer", + "link_to": "Fertilizer", + "link_type": "DocType", + "onboard": 1, + "type": "Card Break" + } + ], + "modified": "2020-11-17 13:00:25.889184", "modified_by": "Administrator", "module": "Agriculture", "name": "Agriculture", diff --git a/erpnext/assets/desk_page/assets/assets.json b/erpnext/assets/desk_page/assets/assets.json index 515fc22f052..f5330c083fe 100644 --- a/erpnext/assets/desk_page/assets/assets.json +++ b/erpnext/assets/desk_page/assets/assets.json @@ -34,7 +34,138 @@ "idx": 0, "is_standard": 1, "label": "Assets", - "modified": "2020-06-30 18:36:11.169586", + "links": [ + { + "hidden": 0, + "is_query_report": 0, + "label": "Assets", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Asset", + "link_to": "Asset", + "link_type": "DocType", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Location", + "link_to": "Location", + "link_type": "DocType", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Asset Category", + "link_to": "Asset Category", + "link_type": "DocType", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Asset Movement", + "link_to": "Asset Movement", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Maintenance", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Asset Maintenance Team", + "link_to": "Asset Maintenance Team", + "link_type": "DocType", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Asset Maintenance", + "link_to": "Asset Maintenance", + "link_type": "DocType", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Asset Maintenance Log", + "link_to": "Asset Maintenance Log", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Asset Value Adjustment", + "link_to": "Asset Value Adjustment", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Asset Repair", + "link_to": "Asset Repair", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Reports", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 1, + "label": "Asset Depreciation Ledger", + "link_to": "Asset Depreciation Ledger", + "link_type": "Report", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 1, + "label": "Asset Depreciations and Balances", + "link_to": "Asset Depreciations and Balances", + "link_type": "Report", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Asset Maintenance", + "link_to": "Asset Maintenance", + "link_type": "Report", + "onboard": 0, + "type": "Card Break" + } + ], + "modified": "2020-11-17 13:00:26.576154", "modified_by": "Administrator", "module": "Assets", "name": "Assets", diff --git a/erpnext/buying/desk_page/buying/buying.json b/erpnext/buying/desk_page/buying/buying.json index 16df8dfdd8f..1c1d8f38d89 100644 --- a/erpnext/buying/desk_page/buying/buying.json +++ b/erpnext/buying/desk_page/buying/buying.json @@ -28,7 +28,7 @@ { "hidden": 0, "label": "Key Reports", - "links": "[\n {\n \"is_query_report\": true,\n \"label\": \"Purchase Analytics\",\n \"name\": \"Purchase Analytics\",\n \"onboard\": 1,\n \"reference_doctype\": \"Purchase Order\",\n \"type\": \"report\"\n },\n {\n \"is_query_report\": true,\n \"label\": \"Purchase Order Analysis\",\n \"name\": \"Purchase Order Analysis\",\n \"onboard\": 1,\n \"reference_doctype\": \"Purchase Order\",\n \"type\": \"report\"\n },\n {\n \"is_query_report\": true,\n \"label\": \"Supplier-Wise Sales Analytics\",\n \"name\": \"Supplier-Wise Sales Analytics\",\n \"onboard\": 1,\n \"reference_doctype\": \"Stock Ledger Entry\",\n \"type\": \"report\"\n },\n {\n \"is_query_report\": true,\n \"label\": \"Requested Items to Order\",\n \"name\": \"Requested Items to Order\",\n \"onboard\": 1,\n \"reference_doctype\": \"Material Request\",\n \"type\": \"report\"\n },\n {\n \"is_query_report\": true,\n \"label\": \"Purchase Order Trends\",\n \"name\": \"Purchase Order Trends\",\n \"onboard\": 1,\n \"reference_doctype\": \"Purchase Order\",\n \"type\": \"report\"\n },\n {\n \"is_query_report\": true,\n \"label\": \"Procurement Tracker\",\n \"name\": \"Procurement Tracker\",\n \"onboard\": 1,\n \"reference_doctype\": \"Purchase Order\",\n \"type\": \"report\"\n }\n]" + "links": "[\n {\n \"is_query_report\": true,\n \"label\": \"Purchase Analytics\",\n \"name\": \"Purchase Analytics\",\n \"onboard\": 1,\n \"reference_doctype\": \"Purchase Order\",\n \"type\": \"report\"\n },\n {\n \"is_query_report\": true,\n \"label\": \"Purchase Order Analysis\",\n \"name\": \"Purchase Order Analysis\",\n \"onboard\": 1,\n \"reference_doctype\": \"Purchase Order\",\n \"type\": \"report\"\n },\n {\n \"is_query_report\": true,\n \"label\": \"Supplier-Wise Sales Analytics\",\n \"name\": \"Supplier-Wise Sales Analytics\",\n \"onboard\": 1,\n \"reference_doctype\": \"Stock Ledger Entry\",\n \"type\": \"report\"\n },\n {\n \"is_query_report\": true,\n \"label\": \"Items to Order and Receive\",\n \"name\": \"Requested Items to Order and Receive\",\n \"onboard\": 1,\n \"reference_doctype\": \"Material Request\",\n \"type\": \"report\"\n },\n {\n \"is_query_report\": true,\n \"label\": \"Purchase Order Trends\",\n \"name\": \"Purchase Order Trends\",\n \"onboard\": 1,\n \"reference_doctype\": \"Purchase Order\",\n \"type\": \"report\"\n },\n {\n \"is_query_report\": true,\n \"label\": \"Procurement Tracker\",\n \"name\": \"Procurement Tracker\",\n \"onboard\": 1,\n \"reference_doctype\": \"Purchase Order\",\n \"type\": \"report\"\n }\n]" }, { "hidden": 0, @@ -61,7 +61,416 @@ "idx": 0, "is_standard": 1, "label": "Buying", - "modified": "2020-10-21 12:29:02.772723", + "links": [ + { + "hidden": 0, + "is_query_report": 0, + "label": "Buying", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Material Request", + "link_to": "Material Request", + "link_type": "DocType", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Purchase Order", + "link_to": "Purchase Order", + "link_type": "DocType", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Purchase Invoice", + "link_to": "Purchase Invoice", + "link_type": "DocType", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Request for Quotation", + "link_to": "Request for Quotation", + "link_type": "DocType", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Supplier Quotation", + "link_to": "Supplier Quotation", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Items & Pricing", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Item", + "link_to": "Item", + "link_type": "DocType", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Item Price", + "link_to": "Item Price", + "link_type": "DocType", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Price List", + "link_to": "Price List", + "link_type": "DocType", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Product Bundle", + "link_to": "Product Bundle", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Item Group", + "link_to": "Item Group", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Promotional Scheme", + "link_to": "Promotional Scheme", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Pricing Rule", + "link_to": "Pricing Rule", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Settings", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Buying Settings", + "link_to": "Buying Settings", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Purchase Taxes and Charges Template", + "link_to": "Purchase Taxes and Charges Template", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Terms and Conditions Template", + "link_to": "Terms and Conditions", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Supplier", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Supplier", + "link_to": "Supplier", + "link_type": "DocType", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Supplier Group", + "link_to": "Supplier Group", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Contact", + "link_to": "Contact", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Address", + "link_to": "Address", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Supplier Scorecard", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Supplier Scorecard", + "link_to": "Supplier Scorecard", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Supplier Scorecard Variable", + "link_to": "Supplier Scorecard Variable", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Supplier Scorecard Criteria", + "link_to": "Supplier Scorecard Criteria", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Supplier Scorecard Standing", + "link_to": "Supplier Scorecard Standing", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Key Reports", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 1, + "label": "Purchase Analytics", + "link_to": "Purchase Analytics", + "link_type": "Report", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 1, + "label": "Purchase Order Analysis", + "link_to": "Purchase Order Analysis", + "link_type": "Report", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 1, + "label": "Supplier-Wise Sales Analytics", + "link_to": "Supplier-Wise Sales Analytics", + "link_type": "Report", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 1, + "label": "Items to Order and Receive", + "link_to": "Requested Items to Order and Receive", + "link_type": "Report", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 1, + "label": "Purchase Order Trends", + "link_to": "Purchase Order Trends", + "link_type": "Report", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 1, + "label": "Procurement Tracker", + "link_to": "Procurement Tracker", + "link_type": "Report", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Other Reports", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 1, + "label": "Items To Be Requested", + "link_to": "Items To Be Requested", + "link_type": "Report", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 1, + "label": "Item-wise Purchase History", + "link_to": "Item-wise Purchase History", + "link_type": "Report", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 1, + "label": "Purchase Receipt Trends", + "link_to": "Purchase Receipt Trends", + "link_type": "Report", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 1, + "label": "Purchase Invoice Trends", + "link_to": "Purchase Invoice Trends", + "link_type": "Report", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 1, + "label": "Subcontracted Raw Materials To Be Transferred", + "link_to": "Subcontracted Raw Materials To Be Transferred", + "link_type": "Report", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 1, + "label": "Subcontracted Item To Be Received", + "link_to": "Subcontracted Item To Be Received", + "link_type": "Report", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 1, + "label": "Supplier Quotation Comparison", + "link_to": "Supplier Quotation Comparison", + "link_type": "Report", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 1, + "label": "Material Requests for which Supplier Quotations are not created", + "link_to": "Material Requests for which Supplier Quotations are not created", + "link_type": "Report", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 1, + "label": "Supplier Addresses And Contacts", + "link_to": "Address And Contacts", + "link_type": "Report", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Regional", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Import Supplier Invoice", + "link_to": "Import Supplier Invoice", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + } + ], + "modified": "2020-11-17 13:00:25.184766", "modified_by": "Administrator", "module": "Buying", "name": "Buying", diff --git a/erpnext/crm/desk_page/crm/crm.json b/erpnext/crm/desk_page/crm/crm.json index 5497f3e511b..3238962a281 100644 --- a/erpnext/crm/desk_page/crm/crm.json +++ b/erpnext/crm/desk_page/crm/crm.json @@ -43,7 +43,323 @@ "idx": 0, "is_standard": 1, "label": "CRM", - "modified": "2020-08-11 18:55:18.238900", + "links": [ + { + "hidden": 0, + "is_query_report": 0, + "label": "Sales Pipeline", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Lead", + "link_to": "Lead", + "link_type": "DocType", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Opportunity", + "link_to": "Opportunity", + "link_type": "DocType", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Customer", + "link_to": "Customer", + "link_type": "DocType", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Contact", + "link_to": "Contact", + "link_type": "DocType", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Communication", + "link_to": "Communication", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Lead Source", + "link_to": "Lead Source", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Contract", + "link_to": "Contract", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Appointment", + "link_to": "Appointment", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Newsletter", + "link_to": "Newsletter", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Reports", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 1, + "label": "Lead Details", + "link_to": "Lead Details", + "link_type": "Report", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Sales Funnel", + "link_to": "sales-funnel", + "link_type": "Page", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 1, + "label": "Prospects Engaged But Not Converted", + "link_to": "Prospects Engaged But Not Converted", + "link_type": "Report", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 1, + "label": "First Response Time for Opportunity", + "link_to": "First Response Time for Opportunity", + "link_type": "Report", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 1, + "label": "Inactive Customers", + "link_to": "Inactive Customers", + "link_type": "Report", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 1, + "label": "Campaign Efficiency", + "link_to": "Campaign Efficiency", + "link_type": "Report", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 1, + "label": "Lead Owner Efficiency", + "link_to": "Lead Owner Efficiency", + "link_type": "Report", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Maintenance", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Maintenance Schedule", + "link_to": "Maintenance Schedule", + "link_type": "DocType", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Maintenance Visit", + "link_to": "Maintenance Visit", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Warranty Claim", + "link_to": "Warranty Claim", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Campaign", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Campaign", + "link_to": "Campaign", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Email Campaign", + "link_to": "Email Campaign", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Social Media Post", + "link_to": "Social Media Post", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Settings", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Customer Group", + "link_to": "Customer Group", + "link_type": "DocType", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Territory", + "link_to": "Territory", + "link_type": "DocType", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Sales Person", + "link_to": "Sales Person", + "link_type": "DocType", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "SMS Center", + "link_to": "SMS Center", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "SMS Log", + "link_to": "SMS Log", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "SMS Settings", + "link_to": "SMS Settings", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Email Group", + "link_to": "Email Group", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Twitter Settings", + "link_to": "Twitter Settings", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "LinkedIn Settings", + "link_to": "LinkedIn Settings", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + } + ], + "modified": "2020-11-17 13:00:28.196723", "modified_by": "Administrator", "module": "CRM", "name": "CRM", diff --git a/erpnext/education/desk_page/education/education.json b/erpnext/education/desk_page/education/education.json index 0d51048ab37..dd5338926df 100644 --- a/erpnext/education/desk_page/education/education.json +++ b/erpnext/education/desk_page/education/education.json @@ -84,7 +84,568 @@ "idx": 0, "is_standard": 1, "label": "Education", - "modified": "2020-07-27 19:35:18.832694", + "links": [ + { + "hidden": 0, + "is_query_report": 0, + "label": "Student and Instructor", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Student", + "link_to": "Student", + "link_type": "DocType", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Instructor", + "link_to": "Instructor", + "link_type": "DocType", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Guardian", + "link_to": "Guardian", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Student Group", + "link_to": "Student Group", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Student Log", + "link_to": "Student Log", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Masters", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Program", + "link_to": "Program", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Course", + "link_to": "Course", + "link_type": "DocType", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Topic", + "link_to": "Topic", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Room", + "link_to": "Room", + "link_type": "DocType", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Content Masters", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Article", + "link_to": "Article", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Video", + "link_to": "Video", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Quiz", + "link_to": "Quiz", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Settings", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Education Settings", + "link_to": "Education Settings", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Student Category", + "link_to": "Student Category", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Student Batch Name", + "link_to": "Student Batch Name", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Grading Scale", + "link_to": "Grading Scale", + "link_type": "DocType", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Academic Term", + "link_to": "Academic Term", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Academic Year", + "link_to": "Academic Year", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Admission", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Student Applicant", + "link_to": "Student Applicant", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Student Admission", + "link_to": "Student Admission", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Program Enrollment", + "link_to": "Program Enrollment", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Course Enrollment", + "link_to": "Course Enrollment", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Fees", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Fee Structure", + "link_to": "Fee Structure", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Fee Category", + "link_to": "Fee Category", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Fee Schedule", + "link_to": "Fee Schedule", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Fees", + "link_to": "Fees", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 1, + "label": "Student Fee Collection Report", + "link_to": "Student Fee Collection", + "link_type": "Report", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 1, + "label": "Program wise Fee Collection Report", + "link_to": "Program wise Fee Collection", + "link_type": "Report", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Schedule", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Course Schedule", + "link_to": "Course Schedule", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Course Scheduling Tool", + "link_to": "Course Scheduling Tool", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Attendance", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Student Attendance", + "link_to": "Student Attendance", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Student Leave Application", + "link_to": "Student Leave Application", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 1, + "label": "Student Monthly Attendance Sheet", + "link_to": "Student Monthly Attendance Sheet", + "link_type": "Report", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 1, + "label": "Absent Student Report", + "link_to": "Absent Student Report", + "link_type": "Report", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 1, + "label": "Student Batch-Wise Attendance", + "link_to": "Student Batch-Wise Attendance", + "link_type": "Report", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "LMS Activity", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Course Enrollment", + "link_to": "Course Enrollment", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Course Activity", + "link_to": "Course Activity", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Quiz Activity", + "link_to": "Quiz Activity", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Assessment", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Assessment Plan", + "link_to": "Assessment Plan", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Assessment Group", + "link_to": "Assessment Group", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Assessment Result", + "link_to": "Assessment Result", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Assessment Criteria", + "link_to": "Assessment Criteria", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Assessment Reports", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 1, + "label": "Course wise Assessment Report", + "link_to": "Course wise Assessment Report", + "link_type": "Report", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 1, + "label": "Final Assessment Grades", + "link_to": "Final Assessment Grades", + "link_type": "Report", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 1, + "label": "Assessment Plan Status", + "link_to": "Assessment Plan Status", + "link_type": "Report", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Student Report Generation Tool", + "link_to": "Student Report Generation Tool", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Tools", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Student Attendance Tool", + "link_to": "Student Attendance Tool", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Assessment Result Tool", + "link_to": "Assessment Result Tool", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Student Group Creation Tool", + "link_to": "Student Group Creation Tool", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Program Enrollment Tool", + "link_to": "Program Enrollment Tool", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Course Scheduling Tool", + "link_to": "Course Scheduling Tool", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Other Reports", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 1, + "label": "Student and Guardian Contact Details", + "link_to": "Student and Guardian Contact Details", + "link_type": "Report", + "onboard": 0, + "type": "Card Break" + } + ], + "modified": "2020-11-17 13:00:27.243450", "modified_by": "Administrator", "module": "Education", "name": "Education", @@ -95,7 +656,7 @@ "restrict_to_domain": "Education", "shortcuts": [ { - "color": "#cef6d1", + "color": "Grey", "format": "{} Active", "label": "Student", "link_to": "Student", @@ -103,7 +664,7 @@ "type": "DocType" }, { - "color": "#cef6d1", + "color": "Grey", "format": "{} Active", "label": "Instructor", "link_to": "Instructor", @@ -124,7 +685,7 @@ "type": "DocType" }, { - "color": "#ffe8cd", + "color": "Grey", "format": "{} Unpaid", "label": "Fees", "link_to": "Fees", diff --git a/erpnext/erpnext_integrations/desk_page/erpnext_integrations/erpnext_integrations.json b/erpnext/erpnext_integrations/desk_page/erpnext_integrations/erpnext_integrations.json index ea3b1291b72..cffa5a2e2cf 100644 --- a/erpnext/erpnext_integrations/desk_page/erpnext_integrations/erpnext_integrations.json +++ b/erpnext/erpnext_integrations/desk_page/erpnext_integrations/erpnext_integrations.json @@ -29,7 +29,93 @@ "idx": 0, "is_standard": 1, "label": "ERPNext Integrations", - "modified": "2020-10-29 19:54:46.228222", + "links": [ + { + "hidden": 0, + "is_query_report": 0, + "label": "Marketplace", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Woocommerce Settings", + "link_to": "Woocommerce Settings", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Amazon MWS Settings", + "link_to": "Amazon MWS Settings", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Shopify Settings", + "link_to": "Shopify Settings", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Payments", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "GoCardless Settings", + "link_to": "GoCardless Settings", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "M-Pesa Settings", + "link_to": "Mpesa Settings", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Settings", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Plaid Settings", + "link_to": "Plaid Settings", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Exotel Settings", + "link_to": "Exotel Settings", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + } + ], + "modified": "2020-11-17 13:00:30.437617", "modified_by": "Administrator", "module": "ERPNext Integrations", "name": "ERPNext Integrations", diff --git a/erpnext/erpnext_integrations/desk_page/erpnext_integrations_settings/erpnext_integrations_settings.json b/erpnext/erpnext_integrations/desk_page/erpnext_integrations_settings/erpnext_integrations_settings.json index 3bbc36ad940..fd5d4dc1c3d 100644 --- a/erpnext/erpnext_integrations/desk_page/erpnext_integrations_settings/erpnext_integrations_settings.json +++ b/erpnext/erpnext_integrations/desk_page/erpnext_integrations_settings/erpnext_integrations_settings.json @@ -19,7 +19,61 @@ "idx": 0, "is_standard": 1, "label": "ERPNext Integrations Settings", - "modified": "2020-07-31 10:44:39.374297", + "links": [ + { + "hidden": 0, + "is_query_report": 0, + "label": "Integrations Settings", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Woocommerce Settings", + "link_to": "Woocommerce Settings", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Shopify Settings", + "link_to": "Shopify Settings", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Amazon MWS Settings", + "link_to": "Amazon MWS Settings", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Plaid Settings", + "link_to": "Plaid Settings", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Exotel Settings", + "link_to": "Exotel Settings", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + } + ], + "modified": "2020-11-17 13:00:31.919189", "modified_by": "Administrator", "module": "ERPNext Integrations", "name": "ERPNext Integrations Settings", diff --git a/erpnext/healthcare/desk_page/healthcare/healthcare.json b/erpnext/healthcare/desk_page/healthcare/healthcare.json index 353d86f4d7f..63751e32345 100644 --- a/erpnext/healthcare/desk_page/healthcare/healthcare.json +++ b/erpnext/healthcare/desk_page/healthcare/healthcare.json @@ -65,7 +65,432 @@ "idx": 0, "is_standard": 1, "label": "Healthcare", - "modified": "2020-09-10 15:37:23.666787", + "links": [ + { + "hidden": 0, + "is_query_report": 0, + "label": "Masters", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Patient", + "link_to": "Patient", + "link_type": "DocType", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Healthcare Practitioner", + "link_to": "Healthcare Practitioner", + "link_type": "DocType", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Practitioner Schedule", + "link_to": "Practitioner Schedule", + "link_type": "DocType", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Medical Department", + "link_to": "Medical Department", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Healthcare Service Unit Type", + "link_to": "Healthcare Service Unit Type", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Healthcare Service Unit", + "link_to": "Healthcare Service Unit", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Medical Code Standard", + "link_to": "Medical Code Standard", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Medical Code", + "link_to": "Medical Code", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Consultation Setup", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Appointment Type", + "link_to": "Appointment Type", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Clinical Procedure Template", + "link_to": "Clinical Procedure Template", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Prescription Dosage", + "link_to": "Prescription Dosage", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Prescription Duration", + "link_to": "Prescription Duration", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Antibiotic", + "link_to": "Antibiotic", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Consultation", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Patient Appointment", + "link_to": "Patient Appointment", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Clinical Procedure", + "link_to": "Clinical Procedure", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Patient Encounter", + "link_to": "Patient Encounter", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Vital Signs", + "link_to": "Vital Signs", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Complaint", + "link_to": "Complaint", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Diagnosis", + "link_to": "Diagnosis", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Fee Validity", + "link_to": "Fee Validity", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Settings", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Healthcare Settings", + "link_to": "Healthcare Settings", + "link_type": "DocType", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Laboratory Setup", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Lab Test Template", + "link_to": "Lab Test Template", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Lab Test Sample", + "link_to": "Lab Test Sample", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Lab Test UOM", + "link_to": "Lab Test UOM", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Sensitivity", + "link_to": "Sensitivity", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Laboratory", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Lab Test", + "link_to": "Lab Test", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Sample Collection", + "link_to": "Sample Collection", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Dosage Form", + "link_to": "Dosage Form", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Rehabilitation and Physiotherapy", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Exercise Type", + "link_to": "Exercise Type", + "link_type": "DocType", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Therapy Type", + "link_to": "Therapy Type", + "link_type": "DocType", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Therapy Plan", + "link_to": "Therapy Plan", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Therapy Session", + "link_to": "Therapy Session", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Patient Assessment Template", + "link_to": "Patient Assessment Template", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Patient Assessment", + "link_to": "Patient Assessment", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Records and History", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Patient History", + "link_to": "patient_history", + "link_type": "Page", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Patient Progress", + "link_to": "patient-progress", + "link_type": "Page", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Patient Medical Record", + "link_to": "Patient Medical Record", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Inpatient Record", + "link_to": "Inpatient Record", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Reports", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 1, + "label": "Patient Appointment Analytics", + "link_to": "Patient Appointment Analytics", + "link_type": "Report", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 1, + "label": "Lab Test Report", + "link_to": "Lab Test Report", + "link_type": "Report", + "onboard": 0, + "type": "Card Break" + } + ], + "modified": "2020-11-17 13:00:31.675127", "modified_by": "Administrator", "module": "Healthcare", "name": "Healthcare", diff --git a/erpnext/hr/desk_page/hr/hr.json b/erpnext/hr/desk_page/hr/hr.json index 217b94a4141..4a2ff10a2ab 100644 --- a/erpnext/hr/desk_page/hr/hr.json +++ b/erpnext/hr/desk_page/hr/hr.json @@ -63,7 +63,7 @@ { "hidden": 0, "label": "Reports", - "links": "[\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"doctype\": \"Employee\",\n \"is_query_report\": true,\n \"label\": \"Employee Birthday\",\n \"name\": \"Employee Birthday\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"doctype\": \"Employee\",\n \"is_query_report\": true,\n \"label\": \"Employees working on a holiday\",\n \"name\": \"Employees working on a holiday\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"doctype\": \"Employee\",\n \"is_query_report\": true,\n \"label\": \"Department Analytics\",\n \"name\": \"Department Analytics\",\n \"type\": \"report\"\n }\n]" + "links": "[\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"doctype\": \"Employee\",\n \"is_query_report\": true,\n \"label\": \"Employee Birthday\",\n \"name\": \"Employee Birthday\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"doctype\": \"Employee\",\n \"is_query_report\": true,\n \"label\": \"Employees working on a holiday\",\n \"name\": \"Employees working on a holiday\",\n \"type\": \"report\"\n }\n]" }, { "hidden": 0, @@ -94,7 +94,807 @@ "idx": 0, "is_standard": 1, "label": "HR", - "modified": "2020-08-11 17:04:38.655417", + "links": [ + { + "hidden": 0, + "is_query_report": 0, + "label": "Employee", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Employee", + "link_to": "Employee", + "link_type": "DocType", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Employment Type", + "link_to": "Employment Type", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Branch", + "link_to": "Branch", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Department", + "link_to": "Department", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Designation", + "link_to": "Designation", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Employee Grade", + "link_to": "Employee Grade", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Employee Group", + "link_to": "Employee Group", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Employee Health Insurance", + "link_to": "Employee Health Insurance", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Employee Lifecycle", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Employee Onboarding", + "link_to": "Employee Onboarding", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Employee Skill Map", + "link_to": "Employee Skill Map", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Employee Promotion", + "link_to": "Employee Promotion", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Employee Transfer", + "link_to": "Employee Transfer", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Employee Separation", + "link_to": "Employee Separation", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Employee Onboarding Template", + "link_to": "Employee Onboarding Template", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Employee Separation Template", + "link_to": "Employee Separation Template", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Shift Management", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Shift Type", + "link_to": "Shift Type", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Shift Request", + "link_to": "Shift Request", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Shift Assignment", + "link_to": "Shift Assignment", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Leaves", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Leave Application", + "link_to": "Leave Application", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Leave Allocation", + "link_to": "Leave Allocation", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Leave Policy", + "link_to": "Leave Policy", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Leave Period", + "link_to": "Leave Period", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Leave Type", + "link_to": "Leave Type", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Holiday List", + "link_to": "Holiday List", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Compensatory Leave Request", + "link_to": "Compensatory Leave Request", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Leave Encashment", + "link_to": "Leave Encashment", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Leave Block List", + "link_to": "Leave Block List", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 1, + "label": "Employee Leave Balance", + "link_to": "Employee Leave Balance", + "link_type": "Report", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Payroll", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Salary Structure", + "link_to": "Salary Structure", + "link_type": "DocType", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Salary Structure Assignment", + "link_to": "Salary Structure Assignment", + "link_type": "DocType", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Payroll Entry", + "link_to": "Payroll Entry", + "link_type": "DocType", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Salary Slip", + "link_to": "Salary Slip", + "link_type": "DocType", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Payroll Period", + "link_to": "Payroll Period", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Income Tax Slab", + "link_to": "Income Tax Slab", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Salary Component", + "link_to": "Salary Component", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Additional Salary", + "link_to": "Additional Salary", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Retention Bonus", + "link_to": "Retention Bonus", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Employee Incentive", + "link_to": "Employee Incentive", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 1, + "label": "Salary Register", + "link_to": "Salary Register", + "link_type": "Report", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Attendance", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Employee Attendance Tool", + "link_to": "Employee Attendance Tool", + "link_type": "DocType", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Attendance", + "link_to": "Attendance", + "link_type": "DocType", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Attendance Request", + "link_to": "Attendance Request", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Upload Attendance", + "link_to": "Upload Attendance", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Employee Checkin", + "link_to": "Employee Checkin", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 1, + "label": "Monthly Attendance Sheet", + "link_to": "Monthly Attendance Sheet", + "link_type": "Report", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Expense Claims", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Expense Claim", + "link_to": "Expense Claim", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Employee Advance", + "link_to": "Employee Advance", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Settings", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "HR Settings", + "link_to": "HR Settings", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Daily Work Summary Group", + "link_to": "Daily Work Summary Group", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Team Updates", + "link_to": "team-updates", + "link_type": "Page", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Fleet Management", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Vehicle", + "link_to": "Vehicle", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Vehicle Log", + "link_to": "Vehicle Log", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 1, + "label": "Vehicle Expenses", + "link_to": "Vehicle Expenses", + "link_type": "Report", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Recruitment", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Job Opening", + "link_to": "Job Opening", + "link_type": "DocType", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Job Applicant", + "link_to": "Job Applicant", + "link_type": "DocType", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Job Offer", + "link_to": "Job Offer", + "link_type": "DocType", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Staffing Plan", + "link_to": "Staffing Plan", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Loans", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Loan Application", + "link_to": "Loan Application", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Loan", + "link_to": "Loan", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Loan Type", + "link_to": "Loan Type", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Training", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Training Program", + "link_to": "Training Program", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Training Event", + "link_to": "Training Event", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Training Result", + "link_to": "Training Result", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Training Feedback", + "link_to": "Training Feedback", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Reports", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 1, + "label": "Employee Birthday", + "link_to": "Employee Birthday", + "link_type": "Report", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 1, + "label": "Employees working on a holiday", + "link_to": "Employees working on a holiday", + "link_type": "Report", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Performance", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Appraisal", + "link_to": "Appraisal", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Appraisal Template", + "link_to": "Appraisal Template", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Energy Point Rule", + "link_to": "Energy Point Rule", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Energy Point Log", + "link_to": "Energy Point Log", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Employee Tax and Benefits", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Employee Tax Exemption Declaration", + "link_to": "Employee Tax Exemption Declaration", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Employee Tax Exemption Proof Submission", + "link_to": "Employee Tax Exemption Proof Submission", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Employee Other Income", + "link_to": "Employee Other Income", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Employee Benefit Application", + "link_to": "Employee Benefit Application", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Employee Benefit Claim", + "link_to": "Employee Benefit Claim", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Employee Tax Exemption Category", + "link_to": "Employee Tax Exemption Category", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Employee Tax Exemption Sub Category", + "link_to": "Employee Tax Exemption Sub Category", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + } + ], + "modified": "2020-11-17 13:00:24.707870", "modified_by": "Administrator", "module": "HR", "name": "HR", diff --git a/erpnext/loan_management/desk_page/loan/loan.json b/erpnext/loan_management/desk_page/loan/loan.json index 7f59348ef9f..0156809619e 100644 --- a/erpnext/loan_management/desk_page/loan/loan.json +++ b/erpnext/loan_management/desk_page/loan/loan.json @@ -39,7 +39,197 @@ "idx": 0, "is_standard": 1, "label": "Loan", - "modified": "2020-10-17 12:59:50.336085", + "links": [ + { + "hidden": 0, + "is_query_report": 0, + "label": "Loan", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Loan Type", + "link_to": "Loan Type", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Loan Application", + "link_to": "Loan Application", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Loan", + "link_to": "Loan", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Loan Processes", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Process Loan Security Shortfall", + "link_to": "Process Loan Security Shortfall", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Process Loan Interest Accrual", + "link_to": "Process Loan Interest Accrual", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Disbursement and Repayment", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Loan Disbursement", + "link_to": "Loan Disbursement", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Loan Repayment", + "link_to": "Loan Repayment", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Loan Write Off", + "link_to": "Loan Write Off", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Loan Interest Accrual", + "link_to": "Loan Interest Accrual", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Loan Security", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Loan Security Type", + "link_to": "Loan Security Type", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Loan Security Price", + "link_to": "Loan Security Price", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Loan Security", + "link_to": "Loan Security", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Loan Security Pledge", + "link_to": "Loan Security Pledge", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Loan Security Unpledge", + "link_to": "Loan Security Unpledge", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Loan Security Shortfall", + "link_to": "Loan Security Shortfall", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Reports", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 1, + "label": "Loan Repayment and Closure", + "link_to": "Loan Repayment and Closure", + "link_type": "Report", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 1, + "label": "Loan Security Status", + "link_to": "Loan Security Status", + "link_type": "Report", + "onboard": 0, + "type": "Card Break" + } + ], + "modified": "2020-11-17 13:00:29.299238", "modified_by": "Administrator", "module": "Loan Management", "name": "Loan", diff --git a/erpnext/manufacturing/desk_page/manufacturing/manufacturing.json b/erpnext/manufacturing/desk_page/manufacturing/manufacturing.json index 3dd86a38bf7..020b147916e 100644 --- a/erpnext/manufacturing/desk_page/manufacturing/manufacturing.json +++ b/erpnext/manufacturing/desk_page/manufacturing/manufacturing.json @@ -24,11 +24,6 @@ "hidden": 0, "label": "Settings", "links": "[\n {\n \"description\": \"Global settings for all manufacturing processes.\",\n \"label\": \"Manufacturing Settings\",\n \"name\": \"Manufacturing Settings\",\n \"type\": \"doctype\"\n }\n]" - }, - { - "hidden": 0, - "label": "Help", - "links": "[\n {\n \"label\": \"Work Order\",\n \"name\": \"Work Order\",\n \"type\": \"help\",\n \"youtube_id\": \"ZotgLyp2YFY\"\n }\n]" } ], "category": "Domains", @@ -48,7 +43,242 @@ "idx": 0, "is_standard": 1, "label": "Manufacturing", - "modified": "2020-06-30 18:40:04.454826", + "links": [ + { + "hidden": 0, + "is_query_report": 0, + "label": "Production", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Work Order", + "link_to": "Work Order", + "link_type": "DocType", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Production Plan", + "link_to": "Production Plan", + "link_type": "DocType", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Stock Entry", + "link_to": "Stock Entry", + "link_type": "DocType", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Job Card", + "link_to": "Job Card", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Downtime Entry", + "link_to": "Downtime Entry", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Bill of Materials", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Item", + "link_to": "Item", + "link_type": "DocType", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Bill of Materials", + "link_to": "BOM", + "link_type": "DocType", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Workstation", + "link_to": "Workstation", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Operation", + "link_to": "Operation", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Routing", + "link_to": "Routing", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Reports", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 1, + "label": "Production Planning Report", + "link_to": "Production Planning Report", + "link_type": "Report", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 1, + "label": "Work Order Summary", + "link_to": "Work Order Summary", + "link_type": "Report", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 1, + "label": "Quality Inspection Summary", + "link_to": "Quality Inspection Summary", + "link_type": "Report", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 1, + "label": "Downtime Analysis", + "link_to": "Downtime Analysis", + "link_type": "Report", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 1, + "label": "Job Card Summary", + "link_to": "Job Card Summary", + "link_type": "Report", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 1, + "label": "BOM Search", + "link_to": "BOM Search", + "link_type": "Report", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 1, + "label": "BOM Stock Report", + "link_to": "BOM Stock Report", + "link_type": "Report", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 1, + "label": "Production Analytics", + "link_to": "Production Analytics", + "link_type": "Report", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 1, + "label": "BOM Operations Time", + "link_to": "BOM Operations Time", + "link_type": "Report", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Tools", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "BOM Update Tool", + "link_to": "BOM Update Tool", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "BOM Comparison Tool", + "link_to": "bom-comparison-tool", + "link_type": "Page", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Settings", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Manufacturing Settings", + "link_to": "Manufacturing Settings", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + } + ], + "modified": "2020-11-17 13:00:24.140642", "modified_by": "Administrator", "module": "Manufacturing", "name": "Manufacturing", @@ -116,10 +346,10 @@ "type": "Report" }, { - "label": "Dashboard", - "link_to": "Manufacturing", - "restrict_to_domain": "Manufacturing", - "type": "Dashboard" - } + "label": "Dashboard", + "link_to": "Manufacturing", + "restrict_to_domain": "Manufacturing", + "type": "Dashboard" + } ] } \ No newline at end of file diff --git a/erpnext/non_profit/desk_page/non_profit/non_profit.json b/erpnext/non_profit/desk_page/non_profit/non_profit.json index 24d655ad6f6..078e324454c 100644 --- a/erpnext/non_profit/desk_page/non_profit/non_profit.json +++ b/erpnext/non_profit/desk_page/non_profit/non_profit.json @@ -44,7 +44,168 @@ "idx": 0, "is_standard": 1, "label": "Non Profit", - "modified": "2020-06-30 18:35:52.770917", + "links": [ + { + "hidden": 0, + "is_query_report": 0, + "label": "Loan Management", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Loan Type", + "link_to": "Loan Type", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Loan Application", + "link_to": "Loan Application", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Loan", + "link_to": "Loan", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Grant Application", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Grant Application", + "link_to": "Grant Application", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Membership", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Member", + "link_to": "Member", + "link_type": "DocType", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Membership", + "link_to": "Membership", + "link_type": "DocType", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Membership Type", + "link_to": "Membership Type", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Membership Settings", + "link_to": "Membership Settings", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Volunteer", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Volunteer", + "link_to": "Volunteer", + "link_type": "DocType", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Volunteer Type", + "link_to": "Volunteer Type", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Chapter", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Chapter", + "link_to": "Chapter", + "link_type": "DocType", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Donor", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Donor", + "link_to": "Donor", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Donor Type", + "link_to": "Donor Type", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + } + ], + "modified": "2020-11-17 13:00:26.036726", "modified_by": "Administrator", "module": "Non Profit", "name": "Non Profit", diff --git a/erpnext/payroll/desk_page/payroll/payroll.json b/erpnext/payroll/desk_page/payroll/payroll.json index 8fe8c448b37..9247213c345 100644 --- a/erpnext/payroll/desk_page/payroll/payroll.json +++ b/erpnext/payroll/desk_page/payroll/payroll.json @@ -39,7 +39,253 @@ "idx": 0, "is_standard": 1, "label": "Payroll", - "modified": "2020-08-10 19:38:45.976209", + "links": [ + { + "hidden": 0, + "is_query_report": 0, + "label": "Payroll", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Salary Component", + "link_to": "Salary Component", + "link_type": "DocType", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Salary Structure", + "link_to": "Salary Structure", + "link_type": "DocType", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Salary Structure Assignment", + "link_to": "Salary Structure Assignment", + "link_type": "DocType", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Payroll Entry", + "link_to": "Payroll Entry", + "link_type": "DocType", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Salary Slip", + "link_to": "Salary Slip", + "link_type": "DocType", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Taxation", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Payroll Period", + "link_to": "Payroll Period", + "link_type": "DocType", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Income Tax Slab", + "link_to": "Income Tax Slab", + "link_type": "DocType", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Employee Other Income", + "link_to": "Employee Other Income", + "link_type": "DocType", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Employee Tax Exemption Declaration", + "link_to": "Employee Tax Exemption Declaration", + "link_type": "DocType", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Employee Tax Exemption Proof Submission", + "link_to": "Employee Tax Exemption Proof Submission", + "link_type": "DocType", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Employee Tax Exemption Category", + "link_to": "Employee Tax Exemption Category", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Employee Tax Exemption Sub Category", + "link_to": "Employee Tax Exemption Sub Category", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Compensations", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Additional Salary", + "link_to": "Additional Salary", + "link_type": "DocType", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Retention Bonus", + "link_to": "Retention Bonus", + "link_type": "DocType", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Employee Incentive", + "link_to": "Employee Incentive", + "link_type": "DocType", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Employee Benefit Application", + "link_to": "Employee Benefit Application", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Employee Benefit Claim", + "link_to": "Employee Benefit Claim", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Reports", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 1, + "label": "Salary Register", + "link_to": "Salary Register", + "link_type": "Report", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 1, + "label": "Salary Payments Based On Payment Mode", + "link_to": "Salary Payments Based On Payment Mode", + "link_type": "Report", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 1, + "label": "Salary Payments via ECS", + "link_to": "Salary Payments via ECS", + "link_type": "Report", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 1, + "label": "Income Tax Deductions", + "link_to": "Income Tax Deductions", + "link_type": "Report", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 1, + "label": "Professional Tax Deductions", + "link_to": "Professional Tax Deductions", + "link_type": "Report", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 1, + "label": "Provident Fund Deductions", + "link_to": "Provident Fund Deductions", + "link_type": "Report", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 1, + "label": "Bank Remittance", + "link_to": "Bank Remittance", + "link_type": "Report", + "onboard": 0, + "type": "Card Break" + } + ], + "modified": "2020-11-17 13:00:27.751514", "modified_by": "Administrator", "module": "Payroll", "name": "Payroll", diff --git a/erpnext/projects/desk_page/projects/projects.json b/erpnext/projects/desk_page/projects/projects.json index 3756c5bb507..4ea2963f50c 100644 --- a/erpnext/projects/desk_page/projects/projects.json +++ b/erpnext/projects/desk_page/projects/projects.json @@ -34,7 +34,129 @@ "idx": 0, "is_standard": 1, "label": "Projects", - "modified": "2020-06-30 18:38:40.130763", + "links": [ + { + "hidden": 0, + "is_query_report": 0, + "label": "Projects", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Project", + "link_to": "Project", + "link_type": "DocType", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Task", + "link_to": "Task", + "link_type": "DocType", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Project Template", + "link_to": "Project Template", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Project Type", + "link_to": "Project Type", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Project Update", + "link_to": "Project Update", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Time Tracking", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Timesheet", + "link_to": "Timesheet", + "link_type": "DocType", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Activity Type", + "link_to": "Activity Type", + "link_type": "DocType", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Activity Cost", + "link_to": "Activity Cost", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Reports", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 1, + "label": "Daily Timesheet Summary", + "link_to": "Daily Timesheet Summary", + "link_type": "Report", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 1, + "label": "Project wise Stock Tracking", + "link_to": "Project wise Stock Tracking", + "link_type": "Report", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 1, + "label": "Project Billing Summary", + "link_to": "Project Billing Summary", + "link_type": "Report", + "onboard": 0, + "type": "Card Break" + } + ], + "modified": "2020-11-17 13:00:26.739225", "modified_by": "Administrator", "module": "Projects", "name": "Projects", diff --git a/erpnext/quality_management/desk_page/quality/quality.json b/erpnext/quality_management/desk_page/quality/quality.json index 474f0525689..499182e082a 100644 --- a/erpnext/quality_management/desk_page/quality/quality.json +++ b/erpnext/quality_management/desk_page/quality/quality.json @@ -34,7 +34,118 @@ "idx": 0, "is_standard": 1, "label": "Quality", - "modified": "2020-10-27 16:28:54.138055", + "links": [ + { + "hidden": 0, + "is_query_report": 0, + "label": "Goal and Procedure", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Quality Goal", + "link_to": "Quality Goal", + "link_type": "DocType", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Quality Procedure", + "link_to": "Quality Procedure", + "link_type": "DocType", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Tree of Procedures", + "link_to": "Quality Procedure", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Feedback", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Quality Feedback", + "link_to": "Quality Feedback", + "link_type": "DocType", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Quality Feedback Template", + "link_to": "Quality Feedback Template", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Meeting", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Quality Meeting", + "link_to": "Quality Meeting", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Review and Action", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Non Conformance", + "link_to": "Non Conformance", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Quality Review", + "link_to": "Quality Review", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Quality Action", + "link_to": "Quality Action", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + } + ], + "modified": "2020-11-17 13:00:31.488858", "modified_by": "Administrator", "module": "Quality Management", "name": "Quality", @@ -43,23 +154,26 @@ "pin_to_top": 0, "shortcuts": [ { + "color": "Grey", "label": "Quality Goal", "link_to": "Quality Goal", "type": "DocType" }, { + "color": "Grey", "doc_view": "Tree", "label": "Quality Procedure", "link_to": "Quality Procedure", "type": "DocType" }, { + "color": "Grey", "label": "Quality Inspection", "link_to": "Quality Inspection", "type": "DocType" }, { - "color": "#ff8989", + "color": "Grey", "doc_view": "", "format": "{} Open", "label": "Quality Review", @@ -68,7 +182,7 @@ "type": "DocType" }, { - "color": "#ff8989", + "color": "Grey", "doc_view": "", "format": "{} Open", "label": "Quality Action", @@ -77,7 +191,7 @@ "type": "DocType" }, { - "color": "#ff8989", + "color": "Grey", "doc_view": "", "format": "{} Open", "label": "Non Conformance", diff --git a/erpnext/selling/desk_page/retail/retail.json b/erpnext/selling/desk_page/retail/retail.json index cdafaeaa9b4..c5f461abb6b 100644 --- a/erpnext/selling/desk_page/retail/retail.json +++ b/erpnext/selling/desk_page/retail/retail.json @@ -29,7 +29,84 @@ "idx": 0, "is_standard": 1, "label": "Retail", - "modified": "2020-09-09 11:46:28.297435", + "links": [ + { + "hidden": 0, + "is_query_report": 0, + "label": "Settings & Configurations", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Point-of-Sale Profile", + "link_to": "POS Profile", + "link_type": "DocType", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "POS Settings", + "link_to": "POS Settings", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Loyalty Program", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Loyalty Program", + "link_to": "Loyalty Program", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Loyalty Point Entry", + "link_to": "Loyalty Point Entry", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Opening & Closing", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "POS Opening Entry", + "link_to": "POS Opening Entry", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "POS Closing Entry", + "link_to": "POS Closing Entry", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + } + ], + "modified": "2020-11-17 13:00:29.114099", "modified_by": "Administrator", "module": "Selling", "name": "Retail", diff --git a/erpnext/selling/desk_page/selling/selling.json b/erpnext/selling/desk_page/selling/selling.json index 82831ab61a9..23edc259da3 100644 --- a/erpnext/selling/desk_page/selling/selling.json +++ b/erpnext/selling/desk_page/selling/selling.json @@ -45,7 +45,458 @@ "idx": 0, "is_standard": 1, "label": "Selling", - "modified": "2020-10-21 12:30:12.164433", + "links": [ + { + "hidden": 0, + "is_query_report": 0, + "label": "Selling", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Customer", + "link_to": "Customer", + "link_type": "DocType", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Quotation", + "link_to": "Quotation", + "link_type": "DocType", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Sales Order", + "link_to": "Sales Order", + "link_type": "DocType", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Sales Invoice", + "link_to": "Sales Invoice", + "link_type": "DocType", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Blanket Order", + "link_to": "Blanket Order", + "link_type": "DocType", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Sales Partner", + "link_to": "Sales Partner", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Sales Person", + "link_to": "Sales Person", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Items and Pricing", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Item", + "link_to": "Item", + "link_type": "DocType", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Item Price", + "link_to": "Item Price", + "link_type": "DocType", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Price List", + "link_to": "Price List", + "link_type": "DocType", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Item Group", + "link_to": "Item Group", + "link_type": "DocType", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Product Bundle", + "link_to": "Product Bundle", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Promotional Scheme", + "link_to": "Promotional Scheme", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Pricing Rule", + "link_to": "Pricing Rule", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Shipping Rule", + "link_to": "Shipping Rule", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Coupon Code", + "link_to": "Coupon Code", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Settings", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Selling Settings", + "link_to": "Selling Settings", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Terms and Conditions Template", + "link_to": "Terms and Conditions", + "link_type": "DocType", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Sales Taxes and Charges Template", + "link_to": "Sales Taxes and Charges Template", + "link_type": "DocType", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Lead Source", + "link_to": "Lead Source", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Customer Group", + "link_to": "Customer Group", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Contact", + "link_to": "Contact", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Address", + "link_to": "Address", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Territory", + "link_to": "Territory", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Campaign", + "link_to": "Campaign", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Key Reports", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 1, + "label": "Sales Analytics", + "link_to": "Sales Analytics", + "link_type": "Report", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 1, + "label": "Sales Order Analysis", + "link_to": "Sales Order Analysis", + "link_type": "Report", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Sales Funnel", + "link_to": "sales-funnel", + "link_type": "Page", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 1, + "label": "Sales Order Trends", + "link_to": "Sales Order Trends", + "link_type": "Report", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 1, + "label": "Quotation Trends", + "link_to": "Quotation Trends", + "link_type": "Report", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 1, + "label": "Customer Acquisition and Loyalty", + "link_to": "Customer Acquisition and Loyalty", + "link_type": "Report", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 1, + "label": "Inactive Customers", + "link_to": "Inactive Customers", + "link_type": "Report", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 1, + "label": "Sales Person-wise Transaction Summary", + "link_to": "Sales Person-wise Transaction Summary", + "link_type": "Report", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 1, + "label": "Item-wise Sales History", + "link_to": "Item-wise Sales History", + "link_type": "Report", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Other Reports", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 1, + "label": "Lead Details", + "link_to": "Lead Details", + "link_type": "Report", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 1, + "label": "Customer Addresses And Contacts", + "link_to": "Address And Contacts", + "link_type": "Report", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 1, + "label": "Available Stock for Packing Items", + "link_to": "Available Stock for Packing Items", + "link_type": "Report", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 1, + "label": "Pending SO Items For Purchase Request", + "link_to": "Pending SO Items For Purchase Request", + "link_type": "Report", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 1, + "label": "Delivery Note Trends", + "link_to": "Delivery Note Trends", + "link_type": "Report", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 1, + "label": "Sales Invoice Trends", + "link_to": "Sales Invoice Trends", + "link_type": "Report", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 1, + "label": "Customer Credit Balance", + "link_to": "Customer Credit Balance", + "link_type": "Report", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 1, + "label": "Customers Without Any Sales Transactions", + "link_to": "Customers Without Any Sales Transactions", + "link_type": "Report", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 1, + "label": "Sales Partners Commission", + "link_to": "Sales Partners Commission", + "link_type": "Report", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 1, + "label": "Territory Target Variance Based On Item Group", + "link_to": "Territory Target Variance Based On Item Group", + "link_type": "Report", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 1, + "label": "Sales Person Target Variance Based On Item Group", + "link_to": "Sales Person Target Variance Based On Item Group", + "link_type": "Report", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 1, + "label": "Sales Partner Target Variance Based On Item Group", + "link_to": "Sales Partner Target Variance based on Item Group", + "link_type": "Report", + "onboard": 0, + "type": "Card Break" + } + ], + "modified": "2020-11-17 13:00:30.100950", "modified_by": "Administrator", "module": "Selling", "name": "Selling", diff --git a/erpnext/setup/desk_page/erpnext_settings/erpnext_settings.json b/erpnext/setup/desk_page/erpnext_settings/erpnext_settings.json index 5c8cd6977b8..efa27e9a55d 100644 --- a/erpnext/setup/desk_page/erpnext_settings/erpnext_settings.json +++ b/erpnext/setup/desk_page/erpnext_settings/erpnext_settings.json @@ -14,7 +14,8 @@ "idx": 0, "is_standard": 1, "label": "ERPNext Settings", - "modified": "2020-07-08 12:53:44.904241", + "links": [], + "modified": "2020-11-17 13:00:26.889826", "modified_by": "Administrator", "module": "Setup", "name": "ERPNext Settings", diff --git a/erpnext/setup/desk_page/home/home.json b/erpnext/setup/desk_page/home/home.json index 23dec32d729..5f7ab0161ea 100644 --- a/erpnext/setup/desk_page/home/home.json +++ b/erpnext/setup/desk_page/home/home.json @@ -59,7 +59,378 @@ "idx": 0, "is_standard": 1, "label": "Home", - "modified": "2020-06-30 18:36:05.637904", + "links": [ + { + "hidden": 0, + "is_query_report": 0, + "label": "Healthcare", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Patient", + "link_to": "Patient", + "link_type": "DocType", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Diagnosis", + "link_to": "Diagnosis", + "link_type": "DocType", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Agriculture", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Crop", + "link_to": "Crop", + "link_type": "DocType", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Crop Cycle", + "link_to": "Crop Cycle", + "link_type": "DocType", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Location", + "link_to": "Location", + "link_type": "DocType", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Fertilizer", + "link_to": "Fertilizer", + "link_type": "DocType", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Education", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Student", + "link_to": "Student", + "link_type": "DocType", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Course", + "link_to": "Course", + "link_type": "DocType", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Instructor", + "link_to": "Instructor", + "link_type": "DocType", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Room", + "link_to": "Room", + "link_type": "DocType", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Non Profit", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Member", + "link_to": "Member", + "link_type": "DocType", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Volunteer", + "link_to": "Volunteer", + "link_type": "DocType", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Chapter", + "link_to": "Chapter", + "link_type": "DocType", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Donor", + "link_to": "Donor", + "link_type": "DocType", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Stock", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Warehouse", + "link_to": "Warehouse", + "link_type": "DocType", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Brand", + "link_to": "Brand", + "link_type": "DocType", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Unit of Measure (UOM)", + "link_to": "UOM", + "link_type": "DocType", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Stock Reconciliation", + "link_to": "Stock Reconciliation", + "link_type": "DocType", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Human Resources", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Employee", + "link_to": "Employee", + "link_type": "DocType", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Employee Attendance Tool", + "link_to": "Employee Attendance Tool", + "link_type": "DocType", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Salary Structure", + "link_to": "Salary Structure", + "link_type": "DocType", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "CRM", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Lead", + "link_to": "Lead", + "link_type": "DocType", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Customer Group", + "link_to": "Customer Group", + "link_type": "DocType", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Territory", + "link_to": "Territory", + "link_type": "DocType", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Accounting", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Item", + "link_to": "Item", + "link_type": "DocType", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Customer", + "link_to": "Customer", + "link_type": "DocType", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Supplier", + "link_to": "Supplier", + "link_type": "DocType", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Company", + "link_to": "Company", + "link_type": "DocType", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Chart of Accounts", + "link_to": "Account", + "link_type": "DocType", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Opening Invoice Creation Tool", + "link_to": "Opening Invoice Creation Tool", + "link_type": "DocType", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Data Import and Settings", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Import Data", + "link_to": "Data Import", + "link_type": "DocType", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Chart of Accounts Importer", + "link_to": "Chart of Accounts Importer", + "link_type": "DocType", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Letter Head", + "link_to": "Letter Head", + "link_type": "DocType", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Email Account", + "link_to": "Email Account", + "link_type": "DocType", + "onboard": 1, + "type": "Card Break" + } + ], + "modified": "2020-11-17 13:00:26.284801", "modified_by": "Administrator", "module": "Setup", "name": "Home", diff --git a/erpnext/stock/desk_page/stock/stock.json b/erpnext/stock/desk_page/stock/stock.json index 9f8f346635f..86b3767f476 100644 --- a/erpnext/stock/desk_page/stock/stock.json +++ b/erpnext/stock/desk_page/stock/stock.json @@ -59,7 +59,587 @@ "idx": 0, "is_standard": 1, "label": "Stock", - "modified": "2020-10-21 12:28:55.503562", + "links": [ + { + "hidden": 0, + "is_query_report": 0, + "label": "Items and Pricing", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Item", + "link_to": "Item", + "link_type": "DocType", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Item Group", + "link_to": "Item Group", + "link_type": "DocType", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Product Bundle", + "link_to": "Product Bundle", + "link_type": "DocType", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Price List", + "link_to": "Price List", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Item Price", + "link_to": "Item Price", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Shipping Rule", + "link_to": "Shipping Rule", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Pricing Rule", + "link_to": "Pricing Rule", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Item Alternative", + "link_to": "Item Alternative", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Item Manufacturer", + "link_to": "Item Manufacturer", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Customs Tariff Number", + "link_to": "Customs Tariff Number", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Stock Transactions", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Material Request", + "link_to": "Material Request", + "link_type": "DocType", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Stock Entry", + "link_to": "Stock Entry", + "link_type": "DocType", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Delivery Note", + "link_to": "Delivery Note", + "link_type": "DocType", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Purchase Receipt", + "link_to": "Purchase Receipt", + "link_type": "DocType", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Pick List", + "link_to": "Pick List", + "link_type": "DocType", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Delivery Trip", + "link_to": "Delivery Trip", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Stock Reports", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 1, + "label": "Stock Ledger", + "link_to": "Stock Ledger", + "link_type": "Report", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 1, + "label": "Stock Balance", + "link_to": "Stock Balance", + "link_type": "Report", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 1, + "label": "Stock Projected Qty", + "link_to": "Stock Projected Qty", + "link_type": "Report", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Stock Summary", + "link_to": "stock-balance", + "link_type": "Page", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 1, + "label": "Stock Ageing", + "link_to": "Stock Ageing", + "link_type": "Report", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 1, + "label": "Item Price Stock", + "link_to": "Item Price Stock", + "link_type": "Report", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Settings", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Stock Settings", + "link_to": "Stock Settings", + "link_type": "DocType", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Warehouse", + "link_to": "Warehouse", + "link_type": "DocType", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Unit of Measure (UOM)", + "link_to": "UOM", + "link_type": "DocType", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Item Variant Settings", + "link_to": "Item Variant Settings", + "link_type": "DocType", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Brand", + "link_to": "Brand", + "link_type": "DocType", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Item Attribute", + "link_to": "Item Attribute", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "UOM Conversion Factor", + "link_to": "UOM Conversion Factor", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Serial No and Batch", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Serial No", + "link_to": "Serial No", + "link_type": "DocType", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Batch", + "link_to": "Batch", + "link_type": "DocType", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Installation Note", + "link_to": "Installation Note", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Serial No Service Contract Expiry", + "link_to": "Serial No Service Contract Expiry", + "link_type": "Report", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Serial No Status", + "link_to": "Serial No Status", + "link_type": "Report", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Serial No Warranty Expiry", + "link_to": "Serial No Warranty Expiry", + "link_type": "Report", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Tools", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Stock Reconciliation", + "link_to": "Stock Reconciliation", + "link_type": "DocType", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Landed Cost Voucher", + "link_to": "Landed Cost Voucher", + "link_type": "DocType", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Packing Slip", + "link_to": "Packing Slip", + "link_type": "DocType", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Quality Inspection", + "link_to": "Quality Inspection", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Quality Inspection Template", + "link_to": "Quality Inspection Template", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Quick Stock Balance", + "link_to": "Quick Stock Balance", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Key Reports", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Item-wise Price List Rate", + "link_to": "Item-wise Price List Rate", + "link_type": "Report", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 1, + "label": "Stock Analytics", + "link_to": "Stock Analytics", + "link_type": "Report", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 1, + "label": "Stock Qty vs Serial No Count", + "link_to": "Stock Qty vs Serial No Count", + "link_type": "Report", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 1, + "label": "Delivery Note Trends", + "link_to": "Delivery Note Trends", + "link_type": "Report", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 1, + "label": "Purchase Receipt Trends", + "link_to": "Purchase Receipt Trends", + "link_type": "Report", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 1, + "label": "Sales Order Analysis", + "link_to": "Sales Order Analysis", + "link_type": "Report", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 1, + "label": "Purchase Order Analysis", + "link_to": "Purchase Order Analysis", + "link_type": "Report", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 1, + "label": "Item Shortage Report", + "link_to": "Item Shortage Report", + "link_type": "Report", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 1, + "label": "Batch-Wise Balance History", + "link_to": "Batch-Wise Balance History", + "link_type": "Report", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Other Reports", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 1, + "label": "Requested Items To Be Transferred", + "link_to": "Requested Items To Be Transferred", + "link_type": "Report", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 1, + "label": "Batch Item Expiry Status", + "link_to": "Batch Item Expiry Status", + "link_type": "Report", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 1, + "label": "Item Prices", + "link_to": "Item Prices", + "link_type": "Report", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 1, + "label": "Itemwise Recommended Reorder Level", + "link_to": "Itemwise Recommended Reorder Level", + "link_type": "Report", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 1, + "label": "Item Variant Details", + "link_to": "Item Variant Details", + "link_type": "Report", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 1, + "label": "Subcontracted Raw Materials To Be Transferred", + "link_to": "Subcontracted Raw Materials To Be Transferred", + "link_type": "Report", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 1, + "label": "Subcontracted Item To Be Received", + "link_to": "Subcontracted Item To Be Received", + "link_type": "Report", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 1, + "label": "Stock and Account Value Comparison", + "link_to": "Stock and Account Value Comparison", + "link_type": "Report", + "onboard": 0, + "type": "Card Break" + } + ], + "modified": "2020-11-17 13:00:29.632812", "modified_by": "Administrator", "module": "Stock", "name": "Stock", diff --git a/erpnext/support/desk_page/support/support.json b/erpnext/support/desk_page/support/support.json index f676ce5ecbc..4dd322a9ca1 100644 --- a/erpnext/support/desk_page/support/support.json +++ b/erpnext/support/desk_page/support/support.json @@ -44,7 +44,141 @@ "idx": 0, "is_standard": 1, "label": "Support", - "modified": "2020-08-11 15:49:34.307341", + "links": [ + { + "hidden": 0, + "is_query_report": 0, + "label": "Issues", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Issue", + "link_to": "Issue", + "link_type": "DocType", + "onboard": 1, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Issue Type", + "link_to": "Issue Type", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Issue Priority", + "link_to": "Issue Priority", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Maintenance", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Maintenance Schedule", + "link_to": "Maintenance Schedule", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Maintenance Visit", + "link_to": "Maintenance Visit", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Service Level Agreement", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Service Level Agreement", + "link_to": "Service Level Agreement", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Warranty", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Warranty Claim", + "link_to": "Warranty Claim", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Serial No", + "link_to": "Serial No", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Settings", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Support Settings", + "link_to": "Support Settings", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Reports", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 1, + "label": "First Response Time for Issues", + "link_to": "First Response Time for Issues", + "link_type": "Report", + "onboard": 0, + "type": "Card Break" + } + ], + "modified": "2020-11-17 13:00:27.977688", "modified_by": "Administrator", "module": "Support", "name": "Support", diff --git a/erpnext/utilities/desk_page/utilities/utilities.json b/erpnext/utilities/desk_page/utilities/utilities.json index 591eab5ed40..987b6515068 100644 --- a/erpnext/utilities/desk_page/utilities/utilities.json +++ b/erpnext/utilities/desk_page/utilities/utilities.json @@ -18,8 +18,35 @@ "idx": 0, "is_standard": 1, "label": "Utilities", - "modified": "2020-09-10 12:33:30.089853", - "modified_by": "user@erpnext.com", + "links": [ + { + "hidden": 0, + "is_query_report": 0, + "label": "Video", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Video", + "link_to": "Video", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Video Settings", + "link_to": "Video Settings", + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + } + ], + "modified": "2020-11-17 13:00:29.198857", + "modified_by": "Administrator", "module": "Utilities", "name": "Utilities", "owner": "user@erpnext.com", From 3e6cdea51f15f095314de67f12b34aea907cdf75 Mon Sep 17 00:00:00 2001 From: Shivam Mishra Date: Tue, 17 Nov 2020 13:03:47 +0530 Subject: [PATCH 136/477] feat: delete config python files --- erpnext/config/__init__.py | 0 erpnext/config/accounts.py | 626 --------------------------- erpnext/config/agriculture.py | 70 --- erpnext/config/assets.py | 94 ---- erpnext/config/buying.py | 264 ----------- erpnext/config/crm.py | 236 ---------- erpnext/config/desktop.py | 220 ---------- erpnext/config/docs.py | 3 - erpnext/config/getting_started.py | 268 ------------ erpnext/config/healthcare.py | 254 ----------- erpnext/config/help.py | 273 ------------ erpnext/config/hr.py | 470 -------------------- erpnext/config/hub_node.py | 24 - erpnext/config/integrations.py | 51 --- erpnext/config/loan_management.py | 107 ----- erpnext/config/manufacturing.py | 168 ------- erpnext/config/non_profit.py | 101 ----- erpnext/config/quality_management.py | 73 ---- erpnext/config/retail.py | 48 -- erpnext/config/selling.py | 320 -------------- erpnext/config/settings.py | 117 ----- erpnext/config/stock.py | 361 --------------- erpnext/config/support.py | 105 ----- erpnext/config/website.py | 33 -- 24 files changed, 4286 deletions(-) delete mode 100644 erpnext/config/__init__.py delete mode 100644 erpnext/config/accounts.py delete mode 100644 erpnext/config/agriculture.py delete mode 100644 erpnext/config/assets.py delete mode 100644 erpnext/config/buying.py delete mode 100644 erpnext/config/crm.py delete mode 100644 erpnext/config/desktop.py delete mode 100644 erpnext/config/docs.py delete mode 100644 erpnext/config/getting_started.py delete mode 100644 erpnext/config/healthcare.py delete mode 100644 erpnext/config/help.py delete mode 100644 erpnext/config/hr.py delete mode 100644 erpnext/config/hub_node.py delete mode 100644 erpnext/config/integrations.py delete mode 100644 erpnext/config/loan_management.py delete mode 100644 erpnext/config/manufacturing.py delete mode 100644 erpnext/config/non_profit.py delete mode 100644 erpnext/config/quality_management.py delete mode 100644 erpnext/config/retail.py delete mode 100644 erpnext/config/selling.py delete mode 100644 erpnext/config/settings.py delete mode 100644 erpnext/config/stock.py delete mode 100644 erpnext/config/support.py delete mode 100644 erpnext/config/website.py diff --git a/erpnext/config/__init__.py b/erpnext/config/__init__.py deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/erpnext/config/accounts.py b/erpnext/config/accounts.py deleted file mode 100644 index 839c4ad84a1..00000000000 --- a/erpnext/config/accounts.py +++ /dev/null @@ -1,626 +0,0 @@ -from __future__ import unicode_literals -from frappe import _ -import frappe - - -def get_data(): - config = [ - { - "label": _("Accounts Receivable"), - "items": [ - { - "type": "doctype", - "name": "Sales Invoice", - "description": _("Bills raised to Customers."), - "onboard": 1, - }, - { - "type": "doctype", - "name": "Customer", - "description": _("Customer database."), - "onboard": 1, - }, - { - "type": "doctype", - "name": "Payment Entry", - "description": _("Bank/Cash transactions against party or for internal transfer") - }, - { - "type": "doctype", - "name": "Payment Request", - "description": _("Payment Request"), - }, - { - "type": "report", - "name": "Accounts Receivable", - "doctype": "Sales Invoice", - "is_query_report": True - }, - { - "type": "report", - "name": "Accounts Receivable Summary", - "doctype": "Sales Invoice", - "is_query_report": True - }, - { - "type": "report", - "name": "Sales Register", - "doctype": "Sales Invoice", - "is_query_report": True - }, - { - "type": "report", - "name": "Item-wise Sales Register", - "is_query_report": True, - "doctype": "Sales Invoice" - }, - { - "type": "report", - "name": "Ordered Items To Be Billed", - "is_query_report": True, - "doctype": "Sales Invoice" - }, - { - "type": "report", - "name": "Delivered Items To Be Billed", - "is_query_report": True, - "doctype": "Sales Invoice" - }, - ] - }, - { - "label": _("Accounts Payable"), - "items": [ - { - "type": "doctype", - "name": "Purchase Invoice", - "description": _("Bills raised by Suppliers."), - "onboard": 1 - }, - { - "type": "doctype", - "name": "Supplier", - "description": _("Supplier database."), - "onboard": 1, - }, - { - "type": "doctype", - "name": "Payment Entry", - "description": _("Bank/Cash transactions against party or for internal transfer") - }, - { - "type": "report", - "name": "Accounts Payable", - "doctype": "Purchase Invoice", - "is_query_report": True - }, - { - "type": "report", - "name": "Accounts Payable Summary", - "doctype": "Purchase Invoice", - "is_query_report": True - }, - { - "type": "report", - "name": "Purchase Register", - "doctype": "Purchase Invoice", - "is_query_report": True - }, - { - "type": "report", - "name": "Item-wise Purchase Register", - "is_query_report": True, - "doctype": "Purchase Invoice" - }, - { - "type": "report", - "name": "Purchase Order Items To Be Billed", - "is_query_report": True, - "doctype": "Purchase Invoice" - }, - { - "type": "report", - "name": "Received Items To Be Billed", - "is_query_report": True, - "doctype": "Purchase Invoice" - }, - ] - }, - { - "label": _("Accounting Masters"), - "items": [ - { - "type": "doctype", - "name": "Company", - "description": _("Company (not Customer or Supplier) master."), - "onboard": 1, - }, - { - "type": "doctype", - "name": "Account", - "icon": "fa fa-sitemap", - "label": _("Chart of Accounts"), - "route": "#Tree/Account", - "description": _("Tree of financial accounts."), - "onboard": 1, - }, - { - "type": "doctype", - "name": "Accounts Settings", - }, - { - "type": "doctype", - "name": "Fiscal Year", - "description": _("Financial / accounting year.") - }, - { - "type": "doctype", - "name": "Accounting Dimension", - }, - { - "type": "doctype", - "name": "Finance Book", - }, - { - "type": "doctype", - "name": "Accounting Period", - }, - { - "type": "doctype", - "name": "Payment Term", - "description": _("Payment Terms based on conditions") - }, - ] - }, - { - "label": _("Banking and Payments"), - "items": [ - { - "type": "doctype", - "label": _("Match Payments with Invoices"), - "name": "Payment Reconciliation", - "description": _("Match non-linked Invoices and Payments.") - }, - { - "type": "doctype", - "label": _("Update Bank Clearance Dates"), - "name": "Bank Clearance", - "description": _("Update bank payment dates with journals.") - }, - { - "type": "doctype", - "label": _("Invoice Discounting"), - "name": "Invoice Discounting", - }, - { - "type": "report", - "name": "Bank Reconciliation Statement", - "is_query_report": True, - "doctype": "Journal Entry" - },{ - "type": "page", - "name": "bank-reconciliation", - "label": _("Bank Reconciliation"), - "icon": "fa fa-bar-chart" - }, - { - "type": "report", - "name": "Bank Clearance Summary", - "is_query_report": True, - "doctype": "Journal Entry" - }, - { - "type": "doctype", - "name": "Bank Guarantee" - }, - { - "type": "doctype", - "name": "Cheque Print Template", - "description": _("Setup cheque dimensions for printing") - }, - ] - }, - { - "label": _("General Ledger"), - "items": [ - { - "type": "doctype", - "name": "Journal Entry", - "description": _("Accounting journal entries.") - }, - { - "type": "report", - "name": "General Ledger", - "doctype": "GL Entry", - "is_query_report": True, - }, - { - "type": "report", - "name": "Customer Ledger Summary", - "doctype": "Sales Invoice", - "is_query_report": True, - }, - { - "type": "report", - "name": "Supplier Ledger Summary", - "doctype": "Sales Invoice", - "is_query_report": True, - }, - { - "type": "doctype", - "name": "Process Deferred Accounting" - } - ] - }, - { - "label": _("Taxes"), - "items": [ - { - "type": "doctype", - "name": "Sales Taxes and Charges Template", - "description": _("Tax template for selling transactions.") - }, - { - "type": "doctype", - "name": "Purchase Taxes and Charges Template", - "description": _("Tax template for buying transactions.") - }, - { - "type": "doctype", - "name": "Item Tax Template", - "description": _("Tax template for item tax rates.") - }, - { - "type": "doctype", - "name": "Tax Category", - "description": _("Tax Category for overriding tax rates.") - }, - { - "type": "doctype", - "name": "Tax Rule", - "description": _("Tax Rule for transactions.") - }, - { - "type": "doctype", - "name": "Tax Withholding Category", - "description": _("Tax Withholding rates to be applied on transactions.") - }, - ] - }, - { - "label": _("Cost Center and Budgeting"), - "items": [ - { - "type": "doctype", - "name": "Cost Center", - "icon": "fa fa-sitemap", - "label": _("Chart of Cost Centers"), - "route": "#Tree/Cost Center", - "description": _("Tree of financial Cost Centers."), - }, - { - "type": "doctype", - "name": "Budget", - "description": _("Define budget for a financial year.") - }, - { - "type": "doctype", - "name": "Accounting Dimension", - }, - { - "type": "report", - "name": "Budget Variance Report", - "is_query_report": True, - "doctype": "Cost Center" - }, - { - "type": "doctype", - "name": "Monthly Distribution", - "description": _("Seasonality for setting budgets, targets etc.") - }, - ] - }, - { - "label": _("Financial Statements"), - "items": [ - { - "type": "report", - "name": "Trial Balance", - "doctype": "GL Entry", - "is_query_report": True, - }, - { - "type": "report", - "name": "Profit and Loss Statement", - "doctype": "GL Entry", - "is_query_report": True - }, - { - "type": "report", - "name": "Balance Sheet", - "doctype": "GL Entry", - "is_query_report": True - }, - { - "type": "report", - "name": "Cash Flow", - "doctype": "GL Entry", - "is_query_report": True - }, - { - "type": "report", - "name": "Consolidated Financial Statement", - "doctype": "GL Entry", - "is_query_report": True - }, - ] - }, - { - "label": _("Opening and Closing"), - "items": [ - { - "type": "doctype", - "name": "Opening Invoice Creation Tool", - }, - { - "type": "doctype", - "name": "Chart of Accounts Importer", - }, - { - "type": "doctype", - "name": "Period Closing Voucher", - "description": _("Close Balance Sheet and book Profit or Loss.") - }, - ] - - }, - { - "label": _("Multi Currency"), - "items": [ - { - "type": "doctype", - "name": "Currency", - "description": _("Enable / disable currencies.") - }, - { - "type": "doctype", - "name": "Currency Exchange", - "description": _("Currency exchange rate master.") - }, - { - "type": "doctype", - "name": "Exchange Rate Revaluation", - "description": _("Exchange Rate Revaluation master.") - }, - ] - }, - { - "label": _("Settings"), - "icon": "fa fa-cog", - "items": [ - { - "type": "doctype", - "name": "Payment Gateway Account", - "description": _("Setup Gateway accounts.") - }, - { - "type": "doctype", - "name": "Terms and Conditions", - "label": _("Terms and Conditions Template"), - "description": _("Template of terms or contract.") - }, - { - "type": "doctype", - "name": "Mode of Payment", - "description": _("e.g. Bank, Cash, Credit Card") - }, - ] - }, - { - "label": _("Subscription Management"), - "items": [ - { - "type": "doctype", - "name": "Subscriber", - }, - { - "type": "doctype", - "name": "Subscription Plan", - }, - { - "type": "doctype", - "name": "Subscription" - }, - { - "type": "doctype", - "name": "Subscription Settings" - } - ] - }, - { - "label": _("Bank Statement"), - "items": [ - { - "type": "doctype", - "label": _("Bank"), - "name": "Bank", - }, - { - "type": "doctype", - "label": _("Bank Account"), - "name": "Bank Account", - }, - { - "type": "doctype", - "name": "Bank Statement Transaction Entry", - }, - { - "type": "doctype", - "label": _("Bank Statement Settings"), - "name": "Bank Statement Settings", - }, - ] - }, - { - "label": _("Profitability"), - "items": [ - { - "type": "report", - "name": "Gross Profit", - "doctype": "Sales Invoice", - "is_query_report": True - }, - { - "type": "report", - "name": "Profitability Analysis", - "doctype": "GL Entry", - "is_query_report": True, - }, - { - "type": "report", - "name": "Sales Invoice Trends", - "is_query_report": True, - "doctype": "Sales Invoice" - }, - { - "type": "report", - "name": "Purchase Invoice Trends", - "is_query_report": True, - "doctype": "Purchase Invoice" - }, - ] - }, - { - "label": _("Reports"), - "icon": "fa fa-table", - "items": [ - { - "type": "report", - "name": "Trial Balance for Party", - "doctype": "GL Entry", - "is_query_report": True, - }, - { - "type": "report", - "name": "Payment Period Based On Invoice Date", - "is_query_report": True, - "doctype": "Journal Entry" - }, - { - "type": "report", - "name": "Sales Partners Commission", - "is_query_report": True, - "doctype": "Sales Invoice" - }, - { - "type": "report", - "is_query_report": True, - "name": "Customer Credit Balance", - "doctype": "Customer" - }, - { - "type": "report", - "is_query_report": True, - "name": "Sales Payment Summary", - "doctype": "Sales Invoice" - }, - { - "type": "report", - "is_query_report": True, - "name": "Address And Contacts", - "doctype": "Address" - } - ] - }, - { - "label": _("Share Management"), - "icon": "fa fa-microchip ", - "items": [ - { - "type": "doctype", - "name": "Shareholder", - "description": _("List of available Shareholders with folio numbers") - }, - { - "type": "doctype", - "name": "Share Transfer", - "description": _("List of all share transactions"), - }, - { - "type": "report", - "name": "Share Ledger", - "doctype": "Share Transfer", - "is_query_report": True - }, - { - "type": "report", - "name": "Share Balance", - "doctype": "Share Transfer", - "is_query_report": True - } - ] - }, - - ] - - gst = { - "label": _("Goods and Services Tax (GST India)"), - "items": [ - { - "type": "doctype", - "name": "GST Settings", - }, - { - "type": "doctype", - "name": "GST HSN Code", - }, - { - "type": "report", - "name": "GSTR-1", - "is_query_report": True - }, - { - "type": "report", - "name": "GSTR-2", - "is_query_report": True - }, - { - "type": "doctype", - "name": "GSTR 3B Report", - }, - { - "type": "report", - "name": "GST Sales Register", - "is_query_report": True - }, - { - "type": "report", - "name": "GST Purchase Register", - "is_query_report": True - }, - { - "type": "report", - "name": "GST Itemised Sales Register", - "is_query_report": True - }, - { - "type": "report", - "name": "GST Itemised Purchase Register", - "is_query_report": True - }, - { - "type": "doctype", - "name": "C-Form", - "description": _("C-Form records"), - "country": "India" - }, - ] - } - - - countries = frappe.get_all("Company", fields="country") - countries = [country["country"] for country in countries] - if "India" in countries: - config.insert(9, gst) - domains = frappe.get_active_domains() - return config diff --git a/erpnext/config/agriculture.py b/erpnext/config/agriculture.py deleted file mode 100644 index 937d76ef7b3..00000000000 --- a/erpnext/config/agriculture.py +++ /dev/null @@ -1,70 +0,0 @@ -from __future__ import unicode_literals -from frappe import _ - -def get_data(): - return [ - { - "label": _("Crops & Lands"), - "items": [ - { - "type": "doctype", - "name": "Crop", - "onboard": 1, - }, - { - "type": "doctype", - "name": "Crop Cycle", - "onboard": 1, - }, - { - "type": "doctype", - "name": "Location", - "onboard": 1, - } - ] - }, - { - "label": _("Diseases & Fertilizers"), - "items": [ - { - "type": "doctype", - "name": "Disease", - "onboard": 1, - }, - { - "type": "doctype", - "name": "Fertilizer", - "onboard": 1, - } - ] - }, - { - "label": _("Analytics"), - "items": [ - { - "type": "doctype", - "name": "Plant Analysis", - }, - { - "type": "doctype", - "name": "Soil Analysis", - }, - { - "type": "doctype", - "name": "Water Analysis", - }, - { - "type": "doctype", - "name": "Soil Texture", - }, - { - "type": "doctype", - "name": "Weather", - }, - { - "type": "doctype", - "name": "Agriculture Analysis Criteria", - } - ] - }, - ] \ No newline at end of file diff --git a/erpnext/config/assets.py b/erpnext/config/assets.py deleted file mode 100644 index 4cf7cf08067..00000000000 --- a/erpnext/config/assets.py +++ /dev/null @@ -1,94 +0,0 @@ -from __future__ import unicode_literals -from frappe import _ - -def get_data(): - return [ - { - "label": _("Assets"), - "items": [ - { - "type": "doctype", - "name": "Asset", - "onboard": 1, - }, - { - "type": "doctype", - "name": "Location", - "onboard": 1, - }, - { - "type": "doctype", - "name": "Asset Category", - "onboard": 1, - }, - { - "type": "doctype", - "name": "Asset Movement", - "description": _("Transfer an asset from one warehouse to another") - }, - ] - }, - { - "label": _("Maintenance"), - "items": [ - { - "type": "doctype", - "name": "Asset Maintenance Team", - "onboard": 1, - }, - { - "type": "doctype", - "name": "Asset Maintenance", - "onboard": 1, - "dependencies": ["Asset Maintenance Team"], - }, - { - "type": "doctype", - "name": "Asset Maintenance Tasks", - "onboard": 1, - "dependencies": ["Asset Maintenance"], - }, - { - "type": "doctype", - "name": "Asset Maintenance Log", - "dependencies": ["Asset Maintenance"], - }, - { - "type": "doctype", - "name": "Asset Value Adjustment", - "dependencies": ["Asset"], - }, - { - "type": "doctype", - "name": "Asset Repair", - "dependencies": ["Asset"], - }, - ] - }, - { - "label": _("Reports"), - "icon": "fa fa-table", - "items": [ - { - "type": "report", - "name": "Asset Depreciation Ledger", - "doctype": "Asset", - "is_query_report": True, - "dependencies": ["Asset"], - }, - { - "type": "report", - "name": "Asset Depreciations and Balances", - "doctype": "Asset", - "is_query_report": True, - "dependencies": ["Asset"], - }, - { - "type": "report", - "name": "Asset Maintenance", - "doctype": "Asset Maintenance", - "dependencies": ["Asset Maintenance"] - }, - ] - } - ] diff --git a/erpnext/config/buying.py b/erpnext/config/buying.py deleted file mode 100644 index b06bb76ca82..00000000000 --- a/erpnext/config/buying.py +++ /dev/null @@ -1,264 +0,0 @@ -from __future__ import unicode_literals -import frappe -from frappe import _ - -def get_data(): - config = [ - { - "label": _("Purchasing"), - "icon": "fa fa-star", - "items": [ - { - "type": "doctype", - "name": "Material Request", - "onboard": 1, - "dependencies": ["Item"], - "description": _("Request for purchase."), - }, - { - "type": "doctype", - "name": "Purchase Order", - "onboard": 1, - "dependencies": ["Item", "Supplier"], - "description": _("Purchase Orders given to Suppliers."), - }, - { - "type": "doctype", - "name": "Purchase Invoice", - "onboard": 1, - "dependencies": ["Item", "Supplier"] - }, - { - "type": "doctype", - "name": "Request for Quotation", - "onboard": 1, - "dependencies": ["Item", "Supplier"], - "description": _("Request for quotation."), - }, - { - "type": "doctype", - "name": "Supplier Quotation", - "dependencies": ["Item", "Supplier"], - "description": _("Quotations received from Suppliers."), - }, - ] - }, - { - "label": _("Items and Pricing"), - "items": [ - { - "type": "doctype", - "name": "Item", - "onboard": 1, - "description": _("All Products or Services."), - }, - { - "type": "doctype", - "name": "Item Price", - "description": _("Multiple Item prices."), - "onboard": 1, - "route": "#Report/Item Price" - }, - { - "type": "doctype", - "name": "Price List", - "description": _("Price List master.") - }, - { - "type": "doctype", - "name": "Pricing Rule", - "description": _("Rules for applying pricing and discount.") - }, - { - "type": "doctype", - "name": "Product Bundle", - "description": _("Bundle items at time of sale."), - }, - { - "type": "doctype", - "name": "Item Group", - "icon": "fa fa-sitemap", - "label": _("Item Group"), - "link": "Tree/Item Group", - "description": _("Tree of Item Groups."), - }, - { - "type": "doctype", - "name": "Promotional Scheme", - "description": _("Rules for applying different promotional schemes.") - } - ] - }, - { - "label": _("Settings"), - "icon": "fa fa-cog", - "items": [ - { - "type": "doctype", - "name": "Buying Settings", - "settings": 1, - "description": _("Default settings for buying transactions.") - }, - { - "type": "doctype", - "name": "Purchase Taxes and Charges Template", - "description": _("Tax template for buying transactions.") - }, - { - "type": "doctype", - "name":"Terms and Conditions", - "label": _("Terms and Conditions Template"), - "description": _("Template of terms or contract.") - }, - ] - }, - { - "label": _("Supplier"), - "items": [ - { - "type": "doctype", - "name": "Supplier", - "onboard": 1, - "description": _("Supplier database."), - }, - { - "type": "doctype", - "name": "Supplier Group", - "description": _("Supplier Group master.") - }, - { - "type": "doctype", - "name": "Contact", - "description": _("All Contacts."), - }, - { - "type": "doctype", - "name": "Address", - "description": _("All Addresses."), - }, - - ] - }, - { - "label": _("Key Reports"), - "icon": "fa fa-table", - "items": [ - { - "type": "report", - "is_query_report": True, - "name": "Purchase Analytics", - "reference_doctype": "Purchase Order", - "onboard": 1 - }, - { - "type": "report", - "is_query_report": True, - "name": "Purchase Order Trends", - "reference_doctype": "Purchase Order", - "onboard": 1, - }, - { - "type": "report", - "is_query_report": True, - "name": "Procurement Tracker", - "reference_doctype": "Purchase Order", - "onboard": 1, - }, - { - "type": "report", - "is_query_report": True, - "name": "Requested Items To Order", - "reference_doctype": "Material Request", - "onboard": 1, - }, - { - "type": "report", - "is_query_report": True, - "name": "Address And Contacts", - "label": _("Supplier Addresses And Contacts"), - "reference_doctype": "Address", - "route_options": { - "party_type": "Supplier" - } - } - ] - }, - { - "label": _("Supplier Scorecard"), - "items": [ - { - "type": "doctype", - "name": "Supplier Scorecard", - "description": _("All Supplier scorecards."), - }, - { - "type": "doctype", - "name": "Supplier Scorecard Variable", - "description": _("Templates of supplier scorecard variables.") - }, - { - "type": "doctype", - "name": "Supplier Scorecard Criteria", - "description": _("Templates of supplier scorecard criteria."), - }, - { - "type": "doctype", - "name": "Supplier Scorecard Standing", - "description": _("Templates of supplier standings."), - }, - - ] - }, - { - "label": _("Other Reports"), - "icon": "fa fa-list", - "items": [ - { - "type": "report", - "is_query_report": True, - "name": "Items To Be Requested", - "reference_doctype": "Item", - "onboard": 1, - }, - { - "type": "report", - "is_query_report": True, - "name": "Item-wise Purchase History", - "reference_doctype": "Item", - "onboard": 1, - }, - { - "type": "report", - "is_query_report": True, - "name": "Supplier-Wise Sales Analytics", - "reference_doctype": "Stock Ledger Entry", - "onboard": 1 - }, - { - "type": "report", - "is_query_report": True, - "name": "Material Requests for which Supplier Quotations are not created", - "reference_doctype": "Material Request" - } - ] - }, - - ] - - regional = { - "label": _("Regional"), - "items": [ - { - "type": "doctype", - "name": "Import Supplier Invoice", - "description": _("Import Italian Supplier Invoice."), - "onboard": 1, - } - ] - } - - countries = frappe.get_all("Company", fields="country") - countries = [country["country"] for country in countries] - if "Italy" in countries: - config.append(regional) - return config \ No newline at end of file diff --git a/erpnext/config/crm.py b/erpnext/config/crm.py deleted file mode 100644 index 09c2a65633b..00000000000 --- a/erpnext/config/crm.py +++ /dev/null @@ -1,236 +0,0 @@ -from __future__ import unicode_literals -from frappe import _ - -def get_data(): - return [ - { - "label": _("Sales Pipeline"), - "icon": "fa fa-star", - "items": [ - { - "type": "doctype", - "name": "Lead", - "description": _("Database of potential customers."), - "onboard": 1, - }, - { - "type": "doctype", - "name": "Opportunity", - "description": _("Potential opportunities for selling."), - "onboard": 1, - }, - { - "type": "doctype", - "name": "Customer", - "description": _("Customer database."), - "onboard": 1, - }, - { - "type": "doctype", - "name": "Contact", - "description": _("All Contacts."), - "onboard": 1, - }, - { - "type": "doctype", - "name": "Communication", - "description": _("Record of all communications of type email, phone, chat, visit, etc."), - }, - { - "type": "doctype", - "name": "Lead Source", - "description": _("Track Leads by Lead Source.") - }, - { - "type": "doctype", - "name": "Contract", - "description": _("Helps you keep tracks of Contracts based on Supplier, Customer and Employee"), - }, - { - "type": "doctype", - "name": "Appointment", - "description" : _("Helps you manage appointments with your leads"), - }, - { - "type": "doctype", - "name": "Newsletter", - "label": _("Newsletter"), - } - ] - }, - { - "label": _("Reports"), - "icon": "fa fa-list", - "items": [ - { - "type": "report", - "is_query_report": True, - "name": "Lead Details", - "doctype": "Lead", - "onboard": 1, - }, - { - "type": "page", - "name": "sales-funnel", - "label": _("Sales Funnel"), - "icon": "fa fa-bar-chart", - "onboard": 1, - }, - { - "type": "report", - "name": "Prospects Engaged But Not Converted", - "doctype": "Lead", - "is_query_report": True, - "onboard": 1, - }, - { - "type": "report", - "name": "Minutes to First Response for Opportunity", - "doctype": "Opportunity", - "is_query_report": True, - "dependencies": ["Opportunity"] - }, - { - "type": "report", - "is_query_report": True, - "name": "Customer Addresses And Contacts", - "doctype": "Contact", - "dependencies": ["Customer"] - }, - { - "type": "report", - "is_query_report": True, - "name": "Inactive Customers", - "doctype": "Sales Order", - "dependencies": ["Sales Order"] - }, - { - "type": "report", - "is_query_report": True, - "name": "Campaign Efficiency", - "doctype": "Lead", - "dependencies": ["Lead"] - }, - { - "type": "report", - "is_query_report": True, - "name": "Lead Owner Efficiency", - "doctype": "Lead", - "dependencies": ["Lead"] - }, - { - "type": "report", - "is_query_report": True, - "name": "Territory-wise Sales", - "doctype": "Opportunity", - "dependencies": ["Opportunity"] - } - ] - }, - { - "label": _("Settings"), - "icon": "fa fa-cog", - "items": [ - { - "type": "doctype", - "label": _("Customer Group"), - "name": "Customer Group", - "icon": "fa fa-sitemap", - "link": "Tree/Customer Group", - "description": _("Manage Customer Group Tree."), - "onboard": 1, - }, - { - "type": "doctype", - "label": _("Territory"), - "name": "Territory", - "icon": "fa fa-sitemap", - "link": "Tree/Territory", - "description": _("Manage Territory Tree."), - "onboard": 1, - }, - { - "type": "doctype", - "label": _("Sales Person"), - "name": "Sales Person", - "icon": "fa fa-sitemap", - "link": "Tree/Sales Person", - "description": _("Manage Sales Person Tree."), - "onboard": 1, - }, - { - "type": "doctype", - "name": "Campaign", - "description": _("Sales campaigns."), - }, - { - "type": "doctype", - "name": "Email Campaign", - "description": _("Sends Mails to lead or contact based on a Campaign schedule"), - }, - { - "type": "doctype", - "name": "SMS Center", - "description":_("Send mass SMS to your contacts"), - }, - { - "type": "doctype", - "name": "SMS Log", - "description":_("Logs for maintaining sms delivery status"), - }, - { - "type": "doctype", - "name": "SMS Settings", - "description": _("Setup SMS gateway settings") - }, - { - "type": "doctype", - "label": _("Email Group"), - "name": "Email Group", - } - ] - }, - { - "label": _("Maintenance"), - "icon": "fa fa-star", - "items": [ - { - "type": "doctype", - "name": "Maintenance Schedule", - "description": _("Plan for maintenance visits."), - "onboard": 1, - }, - { - "type": "doctype", - "name": "Maintenance Visit", - "description": _("Visit report for maintenance call."), - }, - { - "type": "report", - "name": "Maintenance Schedules", - "is_query_report": True, - "doctype": "Maintenance Schedule" - }, - { - "type": "doctype", - "name": "Warranty Claim", - "description": _("Warranty Claim against Serial No."), - }, - ] - }, - # { - # "label": _("Help"), - # "items": [ - # { - # "type": "help", - # "label": _("Lead to Quotation"), - # "youtube_id": "TxYX4r4JAKA" - # }, - # { - # "type": "help", - # "label": _("Newsletters"), - # "youtube_id": "muLKsCrrDRo" - # }, - # ] - # }, - ] diff --git a/erpnext/config/desktop.py b/erpnext/config/desktop.py deleted file mode 100644 index ce7c245a631..00000000000 --- a/erpnext/config/desktop.py +++ /dev/null @@ -1,220 +0,0 @@ -# coding=utf-8 - -from __future__ import unicode_literals -from frappe import _ - -def get_data(): - return [ - # Modules - { - "module_name": "Getting Started", - "category": "Modules", - "label": _("Getting Started"), - "color": "#1abc9c", - "icon": "fa fa-check-square-o", - "type": "module", - "disable_after_onboard": 1, - "description": "Dive into the basics for your organisation's needs.", - "onboard_present": 1 - }, - { - "module_name": "Accounts", - "category": "Modules", - "label": _("Accounting"), - "color": "#3498db", - "icon": "octicon octicon-repo", - "type": "module", - "description": "Accounts, billing, payments, cost center and budgeting." - }, - { - "module_name": "Selling", - "category": "Modules", - "label": _("Selling"), - "color": "#1abc9c", - "icon": "octicon octicon-tag", - "type": "module", - "description": "Sales orders, quotations, customers and items." - }, - { - "module_name": "Buying", - "category": "Modules", - "label": _("Buying"), - "color": "#c0392b", - "icon": "octicon octicon-briefcase", - "type": "module", - "description": "Purchasing, suppliers, material requests, and items." - }, - { - "module_name": "Stock", - "category": "Modules", - "label": _("Stock"), - "color": "#f39c12", - "icon": "octicon octicon-package", - "type": "module", - "description": "Stock transactions, reports, serial numbers and batches." - }, - { - "module_name": "Assets", - "category": "Modules", - "label": _("Assets"), - "color": "#4286f4", - "icon": "octicon octicon-database", - "type": "module", - "description": "Asset movement, maintainance and tools." - }, - { - "module_name": "Projects", - "category": "Modules", - "label": _("Projects"), - "color": "#8e44ad", - "icon": "octicon octicon-rocket", - "type": "module", - "description": "Updates, Timesheets and Activities." - }, - { - "module_name": "CRM", - "category": "Modules", - "label": _("CRM"), - "color": "#EF4DB6", - "icon": "octicon octicon-broadcast", - "type": "module", - "description": "Sales pipeline, leads, opportunities and customers." - }, - { - "module_name": "Loan Management", - "category": "Modules", - "label": _("Loan Management"), - "color": "#EF4DB6", - "icon": "octicon octicon-repo", - "type": "module", - "description": "Loan Management for Customer and Employees" - }, - { - "module_name": "Support", - "category": "Modules", - "label": _("Support"), - "color": "#1abc9c", - "icon": "fa fa-check-square-o", - "type": "module", - "description": "User interactions, support issues and knowledge base." - }, - { - "module_name": "HR", - "category": "Modules", - "label": _("Human Resources"), - "color": "#2ecc71", - "icon": "octicon octicon-organization", - "type": "module", - "description": "Employees, attendance, payroll, leaves and shifts." - }, - { - "module_name": "Quality Management", - "category": "Modules", - "label": _("Quality"), - "color": "#1abc9c", - "icon": "fa fa-check-square-o", - "type": "module", - "description": "Quality goals, procedures, reviews and action." - }, - - - # Category: "Domains" - { - "module_name": "Manufacturing", - "category": "Domains", - "label": _("Manufacturing"), - "color": "#7f8c8d", - "icon": "octicon octicon-tools", - "type": "module", - "description": "BOMS, work orders, operations, and timesheets." - }, - { - "module_name": "Retail", - "category": "Domains", - "label": _("Retail"), - "color": "#7f8c8d", - "icon": "octicon octicon-credit-card", - "type": "module", - "description": "Point of Sale and cashier closing." - }, - { - "module_name": "Education", - "category": "Domains", - "label": _("Education"), - "color": "#428B46", - "icon": "octicon octicon-mortar-board", - "type": "module", - "description": "Student admissions, fees, courses and scores." - }, - - { - "module_name": "Healthcare", - "category": "Domains", - "label": _("Healthcare"), - "color": "#FF888B", - "icon": "fa fa-heartbeat", - "type": "module", - "description": "Patient appointments, procedures and tests." - }, - { - "module_name": "Agriculture", - "category": "Domains", - "label": _("Agriculture"), - "color": "#8BC34A", - "icon": "octicon octicon-globe", - "type": "module", - "description": "Crop cycles, land areas, soil and plant analysis." - }, - { - "module_name": "Hotels", - "category": "Domains", - "label": _("Hotels"), - "color": "#EA81E8", - "icon": "fa fa-bed", - "type": "module", - "description": "Hotel rooms, pricing, reservation and amenities." - }, - - { - "module_name": "Non Profit", - "category": "Domains", - "label": _("Non Profit"), - "color": "#DE2B37", - "icon": "octicon octicon-heart", - "type": "module", - "description": "Volunteers, memberships, grants and chapters." - }, - { - "module_name": "Restaurant", - "category": "Domains", - "label": _("Restaurant"), - "color": "#EA81E8", - "icon": "fa fa-cutlery", - "_doctype": "Restaurant", - "type": "module", - "link": "List/Restaurant", - "description": "Menu, Orders and Table Reservations." - }, - - { - "module_name": "Help", - "category": "Administration", - "label": _("Learn"), - "color": "#FF888B", - "icon": "octicon octicon-device-camera-video", - "type": "module", - "is_help": True, - "description": "Explore Help Articles and Videos." - }, - { - "module_name": 'Marketplace', - "category": "Places", - "label": _('Marketplace'), - "icon": "octicon octicon-star", - "type": 'link', - "link": '#marketplace/home', - "color": '#FF4136', - 'standard': 1, - "description": "Publish items to other ERPNext users." - }, - ] diff --git a/erpnext/config/docs.py b/erpnext/config/docs.py deleted file mode 100644 index 85e600687f2..00000000000 --- a/erpnext/config/docs.py +++ /dev/null @@ -1,3 +0,0 @@ -from __future__ import unicode_literals - -source_link = "https://github.com/erpnext/foundation" diff --git a/erpnext/config/getting_started.py b/erpnext/config/getting_started.py deleted file mode 100644 index dc72316d08b..00000000000 --- a/erpnext/config/getting_started.py +++ /dev/null @@ -1,268 +0,0 @@ -from __future__ import unicode_literals -import frappe -from frappe import _ - -active_domains = frappe.get_active_domains() - -def get_data(): - return [ - { - "label": _("Accounting"), - "items": [ - { - "type": "doctype", - "name": "Item", - "onboard": 1, - }, - { - "type": "doctype", - "name": "Customer", - "description": _("Customer database."), - "onboard": 1, - }, - { - "type": "doctype", - "name": "Supplier", - "description": _("Supplier database."), - "onboard": 1, - }, - { - "type": "doctype", - "name": "Company", - "description": _("Company (not Customer or Supplier) master."), - "onboard": 1, - }, - { - "type": "doctype", - "name": "Account", - "icon": "fa fa-sitemap", - "label": _("Chart of Accounts"), - "route": "#Tree/Account", - "description": _("Tree of financial accounts."), - "onboard": 1, - }, - { - "type": "doctype", - "name": "Opening Invoice Creation Tool", - "description": _("Create Opening Sales and Purchase Invoices"), - "onboard": 1, - }, - ] - }, - { - "label": _("Data Import and Settings"), - "items": [ - { - "type": "doctype", - "name": "Data Import", - "label": _("Import Data"), - "icon": "octicon octicon-cloud-upload", - "description": _("Import Data from CSV / Excel files."), - "onboard": 1, - }, - { - "type": "doctype", - "name": "Chart of Accounts Importer", - "label": _("Chart of Accounts Importer"), - "description": _("Import Chart of Accounts from CSV / Excel files"), - "onboard": 1 - }, - { - "type": "doctype", - "name": "Letter Head", - "description": _("Letter Heads for print templates."), - "onboard": 1, - }, - { - "type": "doctype", - "name": "Email Account", - "description": _("Add / Manage Email Accounts."), - "onboard": 1, - }, - - ] - }, - { - "label": _("Stock"), - "items": [ - { - "type": "doctype", - "name": "Warehouse", - "onboard": 1, - }, - { - "type": "doctype", - "name": "Brand", - "onboard": 1, - }, - { - "type": "doctype", - "name": "UOM", - "label": _("Unit of Measure") + " (UOM)", - "onboard": 1, - }, - { - "type": "doctype", - "name": "Stock Reconciliation", - "onboard": 1, - }, - ] - }, - { - "label": _("CRM"), - "items": [ - { - "type": "doctype", - "name": "Lead", - "description": _("Database of potential customers."), - "onboard": 1, - }, - { - "type": "doctype", - "label": _("Customer Group"), - "name": "Customer Group", - "icon": "fa fa-sitemap", - "link": "Tree/Customer Group", - "description": _("Manage Customer Group Tree."), - "onboard": 1, - }, - { - "type": "doctype", - "label": _("Territory"), - "name": "Territory", - "icon": "fa fa-sitemap", - "link": "Tree/Territory", - "description": _("Manage Territory Tree."), - "onboard": 1, - }, - ] - }, - { - "label": _("Human Resources"), - "items": [ - { - "type": "doctype", - "name": "Employee", - "onboard": 1, - }, - { - "type": "doctype", - "name": "Employee Attendance Tool", - "hide_count": True, - "onboard": 1, - "dependencies": ["Employee"] - }, - { - "type": "doctype", - "name": "Salary Structure", - "onboard": 1, - }, - ] - }, - { - "label": _("Education"), - "condition": "Education" in active_domains, - "items": [ - { - "type": "doctype", - "name": "Student", - "onboard": 1, - }, - { - "type": "doctype", - "name": "Course", - "onboard": 1, - }, - { - "type": "doctype", - "name": "Instructor", - "onboard": 1, - }, - { - "type": "doctype", - "name": "Room", - "onboard": 1, - }, - ] - }, - { - "label": _("Healthcare"), - "condition": "Healthcare" in active_domains, - "items": [ - { - "type": "doctype", - "name": "Patient", - "label": _("Patient"), - "onboard": 1, - }, - { - "type": "doctype", - "name": "Physician", - "label": _("Physician"), - "onboard": 1, - }, - { - "type": "doctype", - "name": "Diagnosis", - "label": _("Diagnosis"), - "onboard": 1, - } - ] - }, - { - "label": _("Agriculture"), - "condition": "Agriculture" in active_domains, - "items": [ - { - "type": "doctype", - "name": "Crop", - "onboard": 1, - }, - { - "type": "doctype", - "name": "Crop Cycle", - "onboard": 1, - }, - { - "type": "doctype", - "name": "Location", - "onboard": 1, - }, - { - "type": "doctype", - "name": "Fertilizer", - "onboard": 1, - } - ] - }, - { - "label": _("Non Profit"), - "condition": "Non Profit" in active_domains, - "items": [ - { - "type": "doctype", - "name": "Member", - "description": _("Member information."), - "onboard": 1, - }, - { - "type": "doctype", - "name": "Volunteer", - "description": _("Volunteer information."), - "onboard": 1, - }, - { - "type": "doctype", - "name": "Chapter", - "description": _("Chapter information."), - "onboard": 1, - }, - { - "type": "doctype", - "name": "Donor", - "description": _("Donor information."), - "onboard": 1, - }, - ] - } - ] \ No newline at end of file diff --git a/erpnext/config/healthcare.py b/erpnext/config/healthcare.py deleted file mode 100644 index da24d11538d..00000000000 --- a/erpnext/config/healthcare.py +++ /dev/null @@ -1,254 +0,0 @@ -from __future__ import unicode_literals -from frappe import _ - -def get_data(): - return [ - { - "label": _("Masters"), - "items": [ - { - "type": "doctype", - "name": "Patient", - "label": _("Patient"), - "onboard": 1 - }, - { - "type": "doctype", - "name": "Healthcare Practitioner", - "label": _("Healthcare Practitioner"), - "onboard": 1 - }, - { - "type": "doctype", - "name": "Practitioner Schedule", - "label": _("Practitioner Schedule"), - "onboard": 1 - }, - { - "type": "doctype", - "name": "Medical Department", - "label": _("Medical Department"), - }, - { - "type": "doctype", - "name": "Healthcare Service Unit Type", - "label": _("Healthcare Service Unit Type") - }, - { - "type": "doctype", - "name": "Healthcare Service Unit", - "label": _("Healthcare Service Unit") - }, - { - "type": "doctype", - "name": "Medical Code Standard", - "label": _("Medical Code Standard") - }, - { - "type": "doctype", - "name": "Medical Code", - "label": _("Medical Code") - } - ] - }, - { - "label": _("Consultation Setup"), - "items": [ - { - "type": "doctype", - "name": "Appointment Type", - "label": _("Appointment Type"), - }, - { - "type": "doctype", - "name": "Clinical Procedure Template", - "label": _("Clinical Procedure Template") - }, - { - "type": "doctype", - "name": "Prescription Dosage", - "label": _("Prescription Dosage") - }, - { - "type": "doctype", - "name": "Prescription Duration", - "label": _("Prescription Duration") - }, - { - "type": "doctype", - "name": "Antibiotic", - "label": _("Antibiotic") - } - ] - }, - { - "label": _("Consultation"), - "items": [ - { - "type": "doctype", - "name": "Patient Appointment", - "label": _("Patient Appointment") - }, - { - "type": "doctype", - "name": "Clinical Procedure", - "label": _("Clinical Procedure") - }, - { - "type": "doctype", - "name": "Patient Encounter", - "label": _("Patient Encounter") - }, - { - "type": "doctype", - "name": "Vital Signs", - "label": _("Vital Signs") - }, - { - "type": "doctype", - "name": "Complaint", - "label": _("Complaint") - }, - { - "type": "doctype", - "name": "Diagnosis", - "label": _("Diagnosis") - }, - { - "type": "doctype", - "name": "Fee Validity", - "label": _("Fee Validity") - } - ] - }, - { - "label": _("Settings"), - "items": [ - { - "type": "doctype", - "name": "Healthcare Settings", - "label": _("Healthcare Settings"), - "onboard": 1 - } - ] - }, - { - "label": _("Laboratory Setup"), - "items": [ - { - "type": "doctype", - "name": "Lab Test Template", - "label": _("Lab Test Template") - }, - { - "type": "doctype", - "name": "Lab Test Sample", - "label": _("Lab Test Sample") - }, - { - "type": "doctype", - "name": "Lab Test UOM", - "label": _("Lab Test UOM") - }, - { - "type": "doctype", - "name": "Sensitivity", - "label": _("Sensitivity") - } - ] - }, - { - "label": _("Laboratory"), - "items": [ - { - "type": "doctype", - "name": "Lab Test", - "label": _("Lab Test") - }, - { - "type": "doctype", - "name": "Sample Collection", - "label": _("Sample Collection") - }, - { - "type": "doctype", - "name": "Dosage Form", - "label": _("Dosage Form") - } - ] - }, - { - "label": _("Records and History"), - "items": [ - { - "type": "page", - "name": "patient_history", - "label": _("Patient History"), - }, - { - "type": "doctype", - "name": "Patient Medical Record", - "label": _("Patient Medical Record") - }, - { - "type": "doctype", - "name": "Inpatient Record", - "label": _("Inpatient Record") - } - ] - }, - { - "label": _("Reports"), - "items": [ - { - "type": "report", - "is_query_report": True, - "name": "Patient Appointment Analytics", - "doctype": "Patient Appointment" - }, - { - "type": "report", - "is_query_report": True, - "name": "Lab Test Report", - "doctype": "Lab Test", - "label": _("Lab Test Report") - } - ] - }, - { - "label": _("Rehabilitation"), - "icon": "icon-cog", - "items": [ - { - "type": "doctype", - "name": "Exercise Type", - "label": _("Exercise Type") - }, - { - "type": "doctype", - "name": "Exercise Difficulty Level", - "label": _("Exercise Difficulty Level") - }, - { - "type": "doctype", - "name": "Therapy Type", - "label": _("Therapy Type") - }, - { - "type": "doctype", - "name": "Therapy Plan", - "label": _("Therapy Plan") - }, - { - "type": "doctype", - "name": "Therapy Session", - "label": _("Therapy Session") - }, - { - "type": "doctype", - "name": "Motor Assessment Scale", - "label": _("Motor Assessment Scale") - } - ] - } - ] diff --git a/erpnext/config/help.py b/erpnext/config/help.py deleted file mode 100644 index 922afb4c495..00000000000 --- a/erpnext/config/help.py +++ /dev/null @@ -1,273 +0,0 @@ -from __future__ import unicode_literals -from frappe import _ - -def get_data(): - return [ - { - "label": _("General"), - "items": [ - { - "type": "help", - "label": _("Navigating"), - "youtube_id": "YDoI2DF4Lmc" - }, - { - "type": "help", - "label": _("Setup Wizard"), - "youtube_id": "oIOf_zCFWKQ" - }, - { - "type": "help", - "label": _("Customizing Forms"), - "youtube_id": "pJhL9mmxV_U" - }, - { - "type": "help", - "label": _("Report Builder"), - "youtube_id": "TxJGUNarcQs" - }, - ] - - }, - { - "label": _("Settings"), - "items": [ - { - "type": "help", - "label": _("Data Import and Export"), - "youtube_id": "6wiriRKPhmg" - }, - { - "type": "help", - "label": _("Opening Stock Balance"), - "youtube_id": "nlHX0ZZ84Lw" - }, - { - "type": "help", - "label": _("Setting up Email Account"), - "youtube_id": "YFYe0DrB95o" - }, - { - "type": "help", - "label": _("Printing and Branding"), - "youtube_id": "cKZHcx1znMc" - }, - { - "type": "help", - "label": _("Users and Permissions"), - "youtube_id": "8Slw1hsTmUI" - }, - { - "type": "help", - "label": _("Workflow"), - "youtube_id": "yObJUg9FxFs" - }, - { - "type": "help", - "label": _("File Manager"), - "youtube_id": "4-osLW3E_Rk" - }, - ] - }, - { - "label": _("Accounting"), - "items": [ - { - "type": "help", - "label": _("Chart of Accounts"), - "youtube_id": "DyR-DST-PyA" - }, - { - "type": "help", - "label": _("Setting up Taxes"), - "youtube_id": "nQ1zZdPgdaQ" - }, - { - "type": "help", - "label": _("Opening Accounting Balance"), - "youtube_id": "kdgM20Q-q68" - }, - { - "type": "help", - "label": _("Advance Payments"), - "youtube_id": "J46-6qtyZ9U" - }, - ] - }, - { - "label": _("CRM"), - "items": [ - { - "type": "help", - "label": _("Lead to Quotation"), - "youtube_id": "TxYX4r4JAKA" - }, - { - "type": "help", - "label": _("Newsletters"), - "youtube_id": "muLKsCrrDRo" - }, - ] - }, - { - "label": _("Selling"), - "items": [ - { - "type": "help", - "label": _("Customer and Supplier"), - "youtube_id": "anoGi_RpQ20" - }, - { - "type": "help", - "label": _("Sales Order to Payment"), - "youtube_id": "1eP90MWoDQM" - }, - { - "type": "help", - "label": _("Point-of-Sale"), - "youtube_id": "4WkelWkbP_c" - }, - { - "type": "help", - "label": _("Product Bundle"), - "youtube_id": "yk3kPrRyRRc" - }, - { - "type": "help", - "label": _("Drop Ship"), - "youtube_id": "hUc0hu_XLdo" - }, - ] - }, - { - "label": _("Stock"), - "items": [ - { - "type": "help", - "label": _("Items and Pricing"), - "youtube_id": "qXaEwld4_Ps" - }, - { - "type": "help", - "label": _("Item Variants"), - "youtube_id": "OGBETlCzU5o" - }, - { - "type": "help", - "label": _("Opening Stock Balance"), - "youtube_id": "0yPgrtfeCTs" - }, - { - "type": "help", - "label": _("Making Stock Entries"), - "youtube_id": "Njt107hlY3I" - }, - { - "type": "help", - "label": _("Serialized Inventory"), - "youtube_id": "gvOVlEwFDAk" - }, - { - "type": "help", - "label": _("Batch Inventory"), - "youtube_id": "J0QKl7ABPKM" - }, - { - "type": "help", - "label": _("Managing Subcontracting"), - "youtube_id": "ThiMCC2DtKo" - }, - { - "type": "help", - "label": _("Quality Inspection"), - "youtube_id": "WmtcF3Y40Fs" - }, - ] - }, - { - "label": _("Buying"), - "items": [ - { - "type": "help", - "label": _("Customer and Supplier"), - "youtube_id": "anoGi_RpQ20" - }, - { - "type": "help", - "label": _("Material Request to Purchase Order"), - "youtube_id": "55Gk2j7Q8Zw" - }, - { - "type": "help", - "label": _("Purchase Order to Payment"), - "youtube_id": "efFajTTQBa8" - }, - { - "type": "help", - "label": _("Managing Subcontracting"), - "youtube_id": "ThiMCC2DtKo" - }, - ] - }, - { - "label": _("Manufacturing"), - "items": [ - { - "type": "help", - "label": _("Bill of Materials"), - "youtube_id": "hDV0c1OeWLo" - }, - { - "type": "help", - "label": _("Work Order"), - "youtube_id": "ZotgLyp2YFY" - }, - - ] - }, - { - "label": _("Human Resource"), - "items": [ - { - "type": "help", - "label": _("Setting up Employees"), - "youtube_id": "USfIUdZlUhw" - }, - { - "type": "help", - "label": _("Leave Management"), - "youtube_id": "fc0p_AXebc8" - }, - { - "type": "help", - "label": _("Expense Claims"), - "youtube_id": "5SZHJF--ZFY" - } - ] - }, - { - "label": _("Projects"), - "items": [ - { - "type": "help", - "label": _("Managing Projects"), - "youtube_id": "gCzShu9Niu4" - }, - ] - }, - { - "label": _("Website"), - "items": [ - { - "type": "help", - "label": _("Publish Items on Website"), - "youtube_id": "W31LBBNzbgc" - }, - { - "type": "help", - "label": _("Shopping Cart"), - "youtube_id": "xkrYO-KFukM" - }, - ] - }, - ] diff --git a/erpnext/config/hr.py b/erpnext/config/hr.py deleted file mode 100644 index 9855a115a60..00000000000 --- a/erpnext/config/hr.py +++ /dev/null @@ -1,470 +0,0 @@ -from __future__ import unicode_literals -from frappe import _ - -def get_data(): - return [ - { - "label": _("Employee"), - "items": [ - { - "type": "doctype", - "name": "Employee", - "onboard": 1, - }, - { - "type": "doctype", - "name": "Employment Type", - }, - { - "type": "doctype", - "name": "Branch", - }, - { - "type": "doctype", - "name": "Department", - }, - { - "type": "doctype", - "name": "Designation", - }, - { - "type": "doctype", - "name": "Employee Grade", - }, - { - "type": "doctype", - "name": "Employee Group", - "dependencies": ["Employee"] - }, - { - "type": "doctype", - "name": "Employee Health Insurance" - }, - ] - }, - { - "label": _("Attendance"), - "items": [ - { - "type": "doctype", - "name": "Employee Attendance Tool", - "hide_count": True, - "onboard": 1, - "dependencies": ["Employee"] - }, - { - "type": "doctype", - "name": "Attendance", - "onboard": 1, - "dependencies": ["Employee"] - }, - { - "type": "doctype", - "name": "Attendance Request", - "dependencies": ["Employee"] - }, - { - "type": "doctype", - "name": "Upload Attendance", - "hide_count": True, - "dependencies": ["Employee"] - }, - { - "type": "doctype", - "name": "Employee Checkin", - "hide_count": True, - "dependencies": ["Employee"] - }, - { - "type": "report", - "is_query_report": True, - "name": "Monthly Attendance Sheet", - "doctype": "Attendance" - }, - ] - }, - { - "label": _("Leaves"), - "items": [ - { - "type": "doctype", - "name": "Leave Application", - "dependencies": ["Employee"] - }, - { - "type": "doctype", - "name": "Leave Allocation", - "dependencies": ["Employee"] - }, - { - "type": "doctype", - "name": "Leave Policy", - "dependencies": ["Leave Type"] - }, - { - "type": "doctype", - "name": "Leave Period", - "dependencies": ["Employee"] - }, - { - "type": "doctype", - "name":"Leave Type", - }, - { - "type": "doctype", - "name": "Holiday List", - }, - { - "type": "doctype", - "name": "Compensatory Leave Request", - "dependencies": ["Employee"] - }, - { - "type": "doctype", - "name": "Leave Encashment", - "dependencies": ["Employee"] - }, - { - "type": "doctype", - "name": "Leave Block List", - }, - { - "type": "report", - "is_query_report": True, - "name": "Employee Leave Balance", - "doctype": "Leave Application" - }, - { - "type": "report", - "is_query_report": True, - "name": "Leave Ledger Entry", - "doctype": "Leave Ledger Entry" - }, - ] - }, - { - "label": _("Payroll"), - "items": [ - { - "type": "doctype", - "name": "Salary Structure", - "onboard": 1, - }, - { - "type": "doctype", - "name": "Salary Structure Assignment", - "onboard": 1, - "dependencies": ["Salary Structure", "Employee"], - }, - { - "type": "doctype", - "name": "Payroll Entry", - "onboard": 1, - }, - { - "type": "doctype", - "name": "Salary Slip", - "onboard": 1, - }, - { - "type": "doctype", - "name": "Payroll Period", - }, - { - "type": "doctype", - "name": "Income Tax Slab", - }, - { - "type": "doctype", - "name": "Salary Component", - }, - { - "type": "doctype", - "name": "Additional Salary", - }, - { - "type": "doctype", - "name": "Retention Bonus", - "dependencies": ["Employee"] - }, - { - "type": "doctype", - "name": "Employee Incentive", - "dependencies": ["Employee"] - }, - { - "type": "report", - "is_query_report": True, - "name": "Salary Register", - "doctype": "Salary Slip" - }, - ] - }, - { - "label": _("Employee Tax and Benefits"), - "items": [ - { - "type": "doctype", - "name": "Employee Tax Exemption Declaration", - "dependencies": ["Employee"] - }, - { - "type": "doctype", - "name": "Employee Tax Exemption Proof Submission", - "dependencies": ["Employee"] - }, - { - "type": "doctype", - "name": "Employee Other Income", - }, - { - "type": "doctype", - "name": "Employee Benefit Application", - "dependencies": ["Employee"] - }, - { - "type": "doctype", - "name": "Employee Benefit Claim", - "dependencies": ["Employee"] - }, - { - "type": "doctype", - "name": "Employee Tax Exemption Category", - "dependencies": ["Employee"] - }, - { - "type": "doctype", - "name": "Employee Tax Exemption Sub Category", - "dependencies": ["Employee"] - }, - ] - }, - { - "label": _("Employee Lifecycle"), - "items": [ - { - "type": "doctype", - "name": "Employee Onboarding", - "dependencies": ["Job Applicant"], - }, - { - "type": "doctype", - "name": "Employee Skill Map", - "dependencies": ["Employee"], - }, - { - "type": "doctype", - "name": "Employee Promotion", - "dependencies": ["Employee"], - }, - { - "type": "doctype", - "name": "Employee Transfer", - "dependencies": ["Employee"], - }, - { - "type": "doctype", - "name": "Employee Separation", - "dependencies": ["Employee"], - }, - { - "type": "doctype", - "name": "Employee Onboarding Template", - "dependencies": ["Employee"] - }, - { - "type": "doctype", - "name": "Employee Separation Template", - "dependencies": ["Employee"] - }, - ] - }, - { - "label": _("Recruitment"), - "items": [ - { - "type": "doctype", - "name": "Job Opening", - "onboard": 1, - }, - { - "type": "doctype", - "name": "Job Applicant", - "onboard": 1, - }, - { - "type": "doctype", - "name": "Job Offer", - "onboard": 1, - }, - { - "type": "doctype", - "name": "Appointment Letter", - }, - { - "type": "doctype", - "name": "Staffing Plan", - }, - ] - }, - { - "label": _("Training"), - "items": [ - { - "type": "doctype", - "name": "Training Program" - }, - { - "type": "doctype", - "name": "Training Event" - }, - { - "type": "doctype", - "name": "Training Result" - }, - { - "type": "doctype", - "name": "Training Feedback" - }, - ] - }, - { - "label": _("Performance"), - "items": [ - { - "type": "doctype", - "name": "Appraisal", - }, - { - "type": "doctype", - "name": "Appraisal Template", - }, - { - "type": "doctype", - "name": "Energy Point Rule", - }, - { - "type": "doctype", - "name": "Energy Point Log", - }, - { - "type": "link", - "doctype": "Energy Point Log", - "label": _("Energy Point Leaderboard"), - "route": "#social/users" - }, - ] - }, - { - "label": _("Expense Claims"), - "items": [ - { - "type": "doctype", - "name": "Expense Claim", - "dependencies": ["Employee"] - }, - { - "type": "doctype", - "name": "Employee Advance", - "dependencies": ["Employee"] - }, - ] - }, - { - "label": _("Loans"), - "items": [ - { - "type": "doctype", - "name": "Loan Application", - "dependencies": ["Employee"] - }, - { - "type": "doctype", - "name": "Loan" - }, - { - "type": "doctype", - "name": "Loan Type", - }, - ] - }, - { - "label": _("Shift Management"), - "items": [ - { - "type": "doctype", - "name": "Shift Type", - }, - { - "type": "doctype", - "name": "Shift Request", - }, - { - "type": "doctype", - "name": "Shift Assignment", - }, - ] - }, - { - "label": _("Fleet Management"), - "items": [ - { - "type": "doctype", - "name": "Vehicle" - }, - { - "type": "doctype", - "name": "Vehicle Log" - }, - { - "type": "report", - "is_query_report": True, - "name": "Vehicle Expenses", - "doctype": "Vehicle" - }, - ] - }, - { - "label": _("Settings"), - "icon": "fa fa-cog", - "items": [ - { - "type": "doctype", - "name": "HR Settings", - }, - { - "type": "doctype", - "name": "Daily Work Summary Group" - }, - { - "type": "page", - "name": "team-updates", - "label": _("Team Updates") - }, - ] - }, - { - "label": _("Reports"), - "icon": "fa fa-list", - "items": [ - { - "type": "report", - "is_query_report": True, - "name": "Employee Birthday", - "doctype": "Employee" - }, - { - "type": "report", - "is_query_report": True, - "name": "Employees working on a holiday", - "doctype": "Employee" - }, - { - "type": "report", - "is_query_report": True, - "name": "Department Analytics", - "doctype": "Employee" - }, - ] - }, - ] diff --git a/erpnext/config/hub_node.py b/erpnext/config/hub_node.py deleted file mode 100644 index 0afdeb52b16..00000000000 --- a/erpnext/config/hub_node.py +++ /dev/null @@ -1,24 +0,0 @@ -from __future__ import unicode_literals -from frappe import _ - -def get_data(): - return [ - { - "label": _("Settings"), - "items": [ - { - "type": "doctype", - "name": "Marketplace Settings" - }, - ] - }, - { - "label": _("Marketplace"), - "items": [ - { - "type": "page", - "name": "marketplace/home" - }, - ] - }, - ] \ No newline at end of file diff --git a/erpnext/config/integrations.py b/erpnext/config/integrations.py deleted file mode 100644 index f8b3257b5c2..00000000000 --- a/erpnext/config/integrations.py +++ /dev/null @@ -1,51 +0,0 @@ -from __future__ import unicode_literals -from frappe import _ - -def get_data(): - return [ - { - "label": _("Payments"), - "icon": "fa fa-star", - "items": [ - { - "type": "doctype", - "name": "GoCardless Settings", - "description": _("GoCardless payment gateway settings"), - }, - { - "type": "doctype", - "name": "GoCardless Mandate", - "description": _("GoCardless SEPA Mandate"), - } - ] - }, - { - "label": _("Settings"), - "items": [ - { - "type": "doctype", - "name": "Woocommerce Settings" - }, - { - "type": "doctype", - "name": "Shopify Settings", - "description": _("Connect Shopify with ERPNext"), - }, - { - "type": "doctype", - "name": "Amazon MWS Settings", - "description": _("Connect Amazon with ERPNext"), - }, - { - "type": "doctype", - "name": "Plaid Settings", - "description": _("Connect your bank accounts to ERPNext"), - }, - { - "type": "doctype", - "name": "Exotel Settings", - "description": _("Connect your Exotel Account to ERPNext and track call logs"), - } - ] - } - ] diff --git a/erpnext/config/loan_management.py b/erpnext/config/loan_management.py deleted file mode 100644 index a84f13ababc..00000000000 --- a/erpnext/config/loan_management.py +++ /dev/null @@ -1,107 +0,0 @@ -from __future__ import unicode_literals -from frappe import _ -import frappe - - -def get_data(): - return [ - { - "label": _("Loan"), - "items": [ - { - "type": "doctype", - "name": "Loan Type", - "description": _("Loan Type for interest and penalty rates"), - }, - { - "type": "doctype", - "name": "Loan Application", - "description": _("Loan Applications from customers and employees."), - }, - { - "type": "doctype", - "name": "Loan", - "description": _("Loans provided to customers and employees."), - }, - - ] - }, - { - "label": _("Loan Security"), - "items": [ - { - "type": "doctype", - "name": "Loan Security Type", - }, - { - "type": "doctype", - "name": "Loan Security Price", - }, - { - "type": "doctype", - "name": "Loan Security", - }, - { - "type": "doctype", - "name": "Loan Security Pledge", - }, - { - "type": "doctype", - "name": "Loan Security Unpledge", - }, - { - "type": "doctype", - "name": "Loan Security Shortfall", - }, - ] - }, - { - "label": _("Disbursement and Repayment"), - "items": [ - { - "type": "doctype", - "name": "Loan Disbursement", - }, - { - "type": "doctype", - "name": "Loan Repayment", - }, - { - "type": "doctype", - "name": "Loan Interest Accrual" - } - ] - }, - { - "label": _("Loan Processes"), - "items": [ - { - "type": "doctype", - "name": "Process Loan Security Shortfall", - }, - { - "type": "doctype", - "name": "Process Loan Interest Accrual", - } - ] - }, - { - "label": _("Reports"), - "items": [ - { - "type": "report", - "is_query_report": True, - "name": "Loan Repayment and Closure", - "route": "#query-report/Loan Repayment and Closure", - "doctype": "Loan Repayment", - }, - { - "type": "report", - "is_query_report": True, - "name": "Loan Security Status", - "route": "#query-report/Loan Security Status", - "doctype": "Loan Security Pledge", - } - ] - } - ] \ No newline at end of file diff --git a/erpnext/config/manufacturing.py b/erpnext/config/manufacturing.py deleted file mode 100644 index 012f1cad0ad..00000000000 --- a/erpnext/config/manufacturing.py +++ /dev/null @@ -1,168 +0,0 @@ -from __future__ import unicode_literals -from frappe import _ - -def get_data(): - return [ - { - "label": _("Bill of Materials"), - "items": [ - { - "type": "doctype", - "name": "Item", - "description": _("All Products or Services."), - "onboard": 1, - }, - { - "type": "doctype", - "name": "BOM", - "description": _("Bill of Materials (BOM)"), - "label": _("Bill of Materials"), - "onboard": 1, - "dependencies": ["Item"] - }, - { - "type": "doctype", - "name": "BOM Browser", - "icon": "fa fa-sitemap", - "label": _("BOM Browser"), - "description": _("Tree of Bill of Materials"), - "link": "Tree/BOM", - "onboard": 1, - "dependencies": ["Item"] - }, - - { - "type": "doctype", - "name": "Workstation", - "description": _("Where manufacturing operations are carried."), - }, - { - "type": "doctype", - "name": "Operation", - "description": _("Details of the operations carried out."), - }, - { - "type": "doctype", - "name": "Routing" - } - - ] - }, - { - "label": _("Production"), - "icon": "fa fa-star", - "items": [ - { - "type": "doctype", - "name": "Work Order", - "description": _("Orders released for production."), - "onboard": 1, - "dependencies": ["Item", "BOM"] - }, - { - "type": "doctype", - "name": "Production Plan", - "description": _("Generate Material Requests (MRP) and Work Orders."), - "onboard": 1, - "dependencies": ["Item", "BOM"] - }, - { - "type": "doctype", - "name": "Stock Entry", - "onboard": 1, - "dependencies": ["Item"] - }, - { - "type": "doctype", - "name": "Timesheet", - "description": _("Time Sheet for manufacturing."), - "onboard": 1, - "dependencies": ["Activity Type"] - }, - { - "type": "doctype", - "name": "Job Card" - } - ] - }, - { - "label": _("Tools"), - "icon": "fa fa-wrench", - "items": [ - { - "type": "doctype", - "name": "BOM Update Tool", - "description": _("Replace BOM and update latest price in all BOMs"), - }, - { - "type": "page", - "label": _("BOM Comparison Tool"), - "name": "bom-comparison-tool", - "description": _("Compare BOMs for changes in Raw Materials and Operations"), - "data_doctype": "BOM" - }, - ] - }, - { - "label": _("Settings"), - "items": [ - { - "type": "doctype", - "name": "Manufacturing Settings", - "description": _("Global settings for all manufacturing processes."), - } - ] - }, - { - "label": _("Reports"), - "icon": "fa fa-list", - "items": [ - { - "type": "report", - "is_query_report": True, - "name": "Work Order Summary", - "doctype": "Work Order" - }, - { - "type": "report", - "is_query_report": True, - "name": "Issued Items Against Work Order", - "doctype": "Work Order" - }, - { - "type": "report", - "is_query_report": True, - "name": "Production Analytics", - "doctype": "Work Order" - }, - { - "type": "report", - "is_query_report": True, - "name": "BOM Search", - "doctype": "BOM" - }, - { - "type": "report", - "is_query_report": True, - "name": "BOM Stock Report", - "doctype": "BOM" - } - ] - }, - { - "label": _("Help"), - "icon": "fa fa-facetime-video", - "items": [ - { - "type": "help", - "label": _("Bill of Materials"), - "youtube_id": "hDV0c1OeWLo" - }, - { - "type": "help", - "label": _("Work Order"), - "youtube_id": "ZotgLyp2YFY" - }, - ] - } - ] diff --git a/erpnext/config/non_profit.py b/erpnext/config/non_profit.py deleted file mode 100644 index 42ec9d3db35..00000000000 --- a/erpnext/config/non_profit.py +++ /dev/null @@ -1,101 +0,0 @@ -from __future__ import unicode_literals -from frappe import _ - -def get_data(): - return [ - { - "label": _("Chapter"), - "icon": "fa fa-star", - "items": [ - { - "type": "doctype", - "name": "Chapter", - "description": _("Chapter information."), - "onboard": 1, - } - ] - }, - { - "label": _("Membership"), - "items": [ - { - "type": "doctype", - "name": "Member", - "description": _("Member information."), - "onboard": 1, - }, - { - "type": "doctype", - "name": "Membership", - "description": _("Memebership Details"), - "onboard": 1, - }, - { - "type": "doctype", - "name": "Membership Type", - "description": _("Memebership Type Details"), - }, - ] - }, - { - "label": _("Volunteer"), - "items": [ - { - "type": "doctype", - "name": "Volunteer", - "description": _("Volunteer information."), - "onboard": 1, - }, - { - "type": "doctype", - "name": "Volunteer Type", - "description": _("Volunteer Type information."), - } - ] - }, - { - "label": _("Donor"), - "items": [ - { - "type": "doctype", - "name": "Donor", - "description": _("Donor information."), - }, - { - "type": "doctype", - "name": "Donor Type", - "description": _("Donor Type information."), - } - ] - }, - { - "label": _("Loan Management"), - "icon": "icon-list", - "items": [ - { - "type": "doctype", - "name": "Loan Type", - "description": _("Define various loan types") - }, - { - "type": "doctype", - "name": "Loan Application", - "description": _("Loan Application") - }, - { - "type": "doctype", - "name": "Loan" - }, - ] - }, - { - "label": _("Grant Application"), - "items": [ - { - "type": "doctype", - "name": "Grant Application", - "description": _("Grant information."), - } - ] - } - ] diff --git a/erpnext/config/quality_management.py b/erpnext/config/quality_management.py deleted file mode 100644 index 35acdfab24f..00000000000 --- a/erpnext/config/quality_management.py +++ /dev/null @@ -1,73 +0,0 @@ -from __future__ import unicode_literals -from frappe import _ - -def get_data(): - return [ - { - "label": _("Goal and Procedure"), - "items": [ - { - "type": "doctype", - "name": "Quality Goal", - "description":_("Quality Goal."), - "onboard": 1, - }, - { - "type": "doctype", - "name": "Quality Procedure", - "description":_("Quality Procedure."), - "onboard": 1, - }, - { - "type": "doctype", - "name": "Quality Procedure", - "icon": "fa fa-sitemap", - "label": _("Tree of Procedures"), - "route": "#Tree/Quality Procedure", - "description": _("Tree of Quality Procedures."), - }, - ] - }, - { - "label": _("Review and Action"), - "items": [ - { - "type": "doctype", - "name": "Quality Review", - "description":_("Quality Review"), - "onboard": 1, - }, - { - "type": "doctype", - "name": "Quality Action", - "description":_("Quality Action"), - } - ] - }, - { - "label": _("Meeting"), - "items": [ - { - "type": "doctype", - "name": "Quality Meeting", - "description":_("Quality Meeting"), - } - ] - }, - { - "label": _("Feedback"), - "items": [ - { - "type": "doctype", - "name": "Quality Feedback", - "description":_("Quality Feedback"), - "onboard": 1, - }, - { - "type": "doctype", - "name": "Quality Feedback Template", - "description":_("Quality Feedback Template"), - } - ] - }, - ] \ No newline at end of file diff --git a/erpnext/config/retail.py b/erpnext/config/retail.py deleted file mode 100644 index 738be7eb173..00000000000 --- a/erpnext/config/retail.py +++ /dev/null @@ -1,48 +0,0 @@ -from __future__ import unicode_literals -from frappe import _ - -def get_data(): - return [ - { - "label": _("Retail Operations"), - "items": [ - { - "type": "doctype", - "name": "POS Profile", - "label": _("Point-of-Sale Profile"), - "description": _("Setup default values for POS Invoices"), - "onboard": 1, - }, - { - "type": "page", - "name": "pos", - "label": _("POS"), - "description": _("Point of Sale"), - "onboard": 1, - "dependencies": ["POS Profile"] - }, - { - "type": "doctype", - "name": "Cashier Closing", - "description": _("Cashier Closing"), - }, - { - "type": "doctype", - "name": "POS Settings", - "description": _("Setup mode of POS (Online / Offline)") - }, - { - "type": "doctype", - "name": "Loyalty Program", - "label": _("Loyalty Program"), - "description": _("To make Customer based incentive schemes.") - }, - { - "type": "doctype", - "name": "Loyalty Point Entry", - "label": _("Loyalty Point Entry"), - "description": _("To view logs of Loyalty Points assigned to a Customer.") - } - ] - } - ] \ No newline at end of file diff --git a/erpnext/config/selling.py b/erpnext/config/selling.py deleted file mode 100644 index 5db4cc27021..00000000000 --- a/erpnext/config/selling.py +++ /dev/null @@ -1,320 +0,0 @@ -from __future__ import unicode_literals -from frappe import _ - -def get_data(): - return [ - { - "label": _("Sales"), - "icon": "fa fa-star", - "items": [ - { - "type": "doctype", - "name": "Customer", - "description": _("Customer Database."), - "onboard": 1, - }, - { - "type": "doctype", - "name": "Quotation", - "description": _("Quotes to Leads or Customers."), - "onboard": 1, - "dependencies": ["Item", "Customer"], - }, - { - "type": "doctype", - "name": "Sales Order", - "description": _("Confirmed orders from Customers."), - "onboard": 1, - "dependencies": ["Item", "Customer"], - }, - { - "type": "doctype", - "name": "Sales Invoice", - "description": _("Invoices for Costumers."), - "onboard": 1, - "dependencies": ["Item", "Customer"], - }, - { - "type": "doctype", - "name": "Blanket Order", - "description": _("Blanket Orders from Costumers."), - "onboard": 1, - "dependencies": ["Item", "Customer"], - }, - { - "type": "doctype", - "name": "Sales Partner", - "description": _("Manage Sales Partners."), - "dependencies": ["Item"], - }, - { - "type": "doctype", - "label": _("Sales Person"), - "name": "Sales Person", - "icon": "fa fa-sitemap", - "link": "Tree/Sales Person", - "description": _("Manage Sales Person Tree."), - "dependencies": ["Item", "Customer"], - }, - { - "type": "report", - "is_query_report": True, - "name": "Territory Target Variance (Item Group-Wise)", - "route": "#query-report/Territory Target Variance Item Group-Wise", - "doctype": "Territory", - }, - { - "type": "report", - "is_query_report": True, - "name": "Sales Person Target Variance (Item Group-Wise)", - "route": "#query-report/Sales Person Target Variance Item Group-Wise", - "doctype": "Sales Person", - "dependencies": ["Sales Person"], - }, - ] - }, - { - "label": _("Items and Pricing"), - "items": [ - { - "type": "doctype", - "name": "Item", - "description": _("All Products or Services."), - "onboard": 1, - }, - { - "type": "doctype", - "name": "Item Price", - "description": _("Multiple Item prices."), - "route": "#Report/Item Price", - "dependencies": ["Item", "Price List"], - "onboard": 1, - }, - { - "type": "doctype", - "name": "Price List", - "description": _("Price List master."), - "onboard": 1, - }, - { - "type": "doctype", - "name": "Item Group", - "icon": "fa fa-sitemap", - "label": _("Item Group"), - "link": "Tree/Item Group", - "description": _("Tree of Item Groups."), - "onboard": 1, - }, - { - "type": "doctype", - "name": "Product Bundle", - "description": _("Bundle items at time of sale."), - "dependencies": ["Item"], - }, - { - "type": "doctype", - "name": "Promotional Scheme", - "description": _("Rules for applying different promotional schemes.") - }, - { - "type": "doctype", - "name": "Pricing Rule", - "description": _("Rules for applying pricing and discount."), - "dependencies": ["Item"], - }, - { - "type": "doctype", - "name": "Shipping Rule", - "description": _("Rules for adding shipping costs."), - }, - { - "type": "doctype", - "name": "Coupon Code", - "description": _("Define coupon codes."), - } - ] - }, - { - "label": _("Settings"), - "icon": "fa fa-cog", - "items": [ - { - "type": "doctype", - "name": "Selling Settings", - "description": _("Default settings for selling transactions."), - "settings": 1, - }, - { - "type": "doctype", - "name":"Terms and Conditions", - "label": _("Terms and Conditions Template"), - "description": _("Template of terms or contract."), - "onboard": 1, - }, - { - "type": "doctype", - "name": "Sales Taxes and Charges Template", - "description": _("Tax template for selling transactions."), - "onboard": 1, - }, - { - "type": "doctype", - "name": "Lead Source", - "description": _("Track Leads by Lead Source.") - }, - { - "type": "doctype", - "label": _("Customer Group"), - "name": "Customer Group", - "icon": "fa fa-sitemap", - "link": "Tree/Customer Group", - "description": _("Manage Customer Group Tree."), - }, - { - "type": "doctype", - "name": "Contact", - "description": _("All Contacts."), - }, - { - "type": "doctype", - "name": "Address", - "description": _("All Addresses."), - }, - { - "type": "doctype", - "label": _("Territory"), - "name": "Territory", - "icon": "fa fa-sitemap", - "link": "Tree/Territory", - "description": _("Manage Territory Tree."), - }, - { - "type": "doctype", - "name": "Campaign", - "description": _("Sales campaigns."), - }, - ] - }, - { - "label": _("Key Reports"), - "icon": "fa fa-table", - "items": [ - { - "type": "report", - "is_query_report": True, - "name": "Sales Analytics", - "doctype": "Sales Order", - "onboard": 1, - }, - { - "type": "page", - "name": "sales-funnel", - "label": _("Sales Funnel"), - "icon": "fa fa-bar-chart", - "onboard": 1, - }, - { - "type": "report", - "is_query_report": True, - "name": "Customer Acquisition and Loyalty", - "doctype": "Customer", - "icon": "fa fa-bar-chart", - }, - { - "type": "report", - "is_query_report": True, - "name": "Inactive Customers", - "doctype": "Sales Order" - }, - { - "type": "report", - "is_query_report": True, - "name": "Ordered Items To Be Delivered", - "doctype": "Sales Order" - }, - { - "type": "report", - "is_query_report": True, - "name": "Sales Person-wise Transaction Summary", - "doctype": "Sales Order" - }, - { - "type": "report", - "is_query_report": True, - "name": "Item-wise Sales History", - "doctype": "Item" - }, - { - "type": "report", - "is_query_report": True, - "name": "Quotation Trends", - "doctype": "Quotation" - }, - { - "type": "report", - "is_query_report": True, - "name": "Sales Order Trends", - "doctype": "Sales Order" - }, - ] - }, - { - "label": _("Other Reports"), - "icon": "fa fa-list", - "items": [ - { - "type": "report", - "is_query_report": True, - "name": "Lead Details", - "doctype": "Lead" - }, - { - "type": "report", - "is_query_report": True, - "name": "Address And Contacts", - "label": _("Customer Addresses And Contacts"), - "doctype": "Address", - "route_options": { - "party_type": "Customer" - } - }, - { - "type": "report", - "is_query_report": True, - "name": "BOM Search", - "doctype": "BOM" - }, - { - "type": "report", - "is_query_report": True, - "name": "Available Stock for Packing Items", - "doctype": "Item", - }, - { - "type": "report", - "is_query_report": True, - "name": "Pending SO Items For Purchase Request", - "doctype": "Sales Order" - }, - { - "type": "report", - "is_query_report": True, - "name": "Customer Credit Balance", - "doctype": "Customer" - }, - { - "type": "report", - "is_query_report": True, - "name": "Customers Without Any Sales Transactions", - "doctype": "Customer" - }, - { - "type": "report", - "is_query_report": True, - "name": "Sales Partners Commission", - "doctype": "Customer" - } - ] - }, - - ] diff --git a/erpnext/config/settings.py b/erpnext/config/settings.py deleted file mode 100644 index 323683a3e6d..00000000000 --- a/erpnext/config/settings.py +++ /dev/null @@ -1,117 +0,0 @@ -from __future__ import unicode_literals -from frappe import _ -from frappe.desk.moduleview import add_setup_section - -def get_data(): - data = [ - { - "label": _("Settings"), - "icon": "fa fa-wrench", - "items": [ - { - "type": "doctype", - "name": "Global Defaults", - "label": _("ERPNext Settings"), - "description": _("Set Default Values like Company, Currency, Current Fiscal Year, etc."), - "hide_count": True, - "settings": 1, - } - ] - }, - { - "label": _("Printing"), - "icon": "fa fa-print", - "items": [ - { - "type": "doctype", - "name": "Letter Head", - "description": _("Letter Heads for print templates."), - "onboard": 1, - }, - { - "type": "doctype", - "name": "Print Heading", - "description": _("Titles for print templates e.g. Proforma Invoice.") - }, - { - "type": "doctype", - "name": "Address Template", - "description": _("Country wise default Address Templates") - }, - { - "type": "doctype", - "name": "Terms and Conditions", - "description": _("Standard contract terms for Sales or Purchase.") - }, - ] - }, - { - "label": _("Help"), - "items": [ - { - "type": "help", - "name": _("Data Import and Export"), - "youtube_id": "6wiriRKPhmg" - }, - { - "type": "help", - "label": _("Setting up Email"), - "youtube_id": "YFYe0DrB95o" - }, - { - "type": "help", - "label": _("Printing and Branding"), - "youtube_id": "cKZHcx1znMc" - }, - { - "type": "help", - "label": _("Users and Permissions"), - "youtube_id": "8Slw1hsTmUI" - }, - { - "type": "help", - "label": _("Workflow"), - "youtube_id": "yObJUg9FxFs" - }, - ] - }, - { - "label": _("Customize"), - "icon": "fa fa-glass", - "items": [ - { - "type": "doctype", - "name": "Authorization Rule", - "description": _("Create rules to restrict transactions based on values.") - } - ] - }, - { - "label": _("Email"), - "icon": "fa fa-envelope", - "items": [ - { - "type": "doctype", - "name": "Email Digest", - "description": _("Create and manage daily, weekly and monthly email digests.") - }, - { - "type": "doctype", - "name": "SMS Settings", - "description": _("Setup SMS gateway settings") - }, - ] - } - ] - - for module, label, icon in ( - ("accounts", _("Accounting"), "fa fa-money"), - ("stock", _("Stock"), "fa fa-truck"), - ("selling", _("Selling"), "fa fa-tag"), - ("buying", _("Buying"), "fa fa-shopping-cart"), - ("hr", _("Human Resources"), "fa fa-group"), - ("support", _("Support"), "fa fa-phone")): - - add_setup_section(data, "erpnext", module, label, icon) - - return data diff --git a/erpnext/config/stock.py b/erpnext/config/stock.py deleted file mode 100644 index dd35f5ab368..00000000000 --- a/erpnext/config/stock.py +++ /dev/null @@ -1,361 +0,0 @@ -from __future__ import unicode_literals -from frappe import _ - -def get_data(): - return [ - { - "label": _("Stock Transactions"), - "items": [ - { - "type": "doctype", - "name": "Stock Entry", - "onboard": 1, - "dependencies": ["Item"], - }, - { - "type": "doctype", - "name": "Delivery Note", - "onboard": 1, - "dependencies": ["Item", "Customer"], - }, - { - "type": "doctype", - "name": "Purchase Receipt", - "onboard": 1, - "dependencies": ["Item", "Supplier"], - }, - { - "type": "doctype", - "name": "Material Request", - "onboard": 1, - "dependencies": ["Item"], - }, - { - "type": "doctype", - "name": "Pick List", - "onboard": 1, - "dependencies": ["Item"], - }, - { - "type": "doctype", - "name": "Delivery Trip" - }, - ] - }, - { - "label": _("Stock Reports"), - "items": [ - { - "type": "report", - "is_query_report": True, - "name": "Stock Ledger", - "doctype": "Stock Ledger Entry", - "onboard": 1, - "dependencies": ["Item"], - }, - { - "type": "report", - "is_query_report": True, - "name": "Stock Balance", - "doctype": "Stock Ledger Entry", - "onboard": 1, - "dependencies": ["Item"], - }, - { - "type": "report", - "is_query_report": True, - "name": "Stock Projected Qty", - "doctype": "Item", - "onboard": 1, - "dependencies": ["Item"], - }, - { - "type": "page", - "name": "stock-balance", - "label": _("Stock Summary"), - "dependencies": ["Item"], - }, - { - "type": "report", - "is_query_report": True, - "name": "Stock Ageing", - "doctype": "Item", - "dependencies": ["Item"], - }, - { - "type": "report", - "is_query_report": True, - "name": "Item Price Stock", - "doctype": "Item", - "dependencies": ["Item"], - } - ] - }, - { - "label": _("Settings"), - "icon": "fa fa-cog", - "items": [ - { - "type": "doctype", - "name": "Stock Settings", - "onboard": 1, - }, - { - "type": "doctype", - "name": "Warehouse", - "onboard": 1, - }, - { - "type": "doctype", - "name": "UOM", - "label": _("Unit of Measure") + " (UOM)", - "onboard": 1, - }, - { - "type": "doctype", - "name": "Brand", - "onboard": 1, - }, - { - "type": "doctype", - "name": "Item Attribute", - }, - { - "type": "doctype", - "name": "Item Variant Settings", - }, - ] - }, - { - "label": _("Items and Pricing"), - "items": [ - { - "type": "doctype", - "name": "Item", - "onboard": 1, - }, - { - "type": "doctype", - "name": "Product Bundle", - "onboard": 1, - }, - { - "type": "doctype", - "name": "Item Group", - "icon": "fa fa-sitemap", - "label": _("Item Group"), - "link": "Tree/Item Group", - "onboard": 1, - }, - { - "type": "doctype", - "name": "Price List", - }, - { - "type": "doctype", - "name": "Item Price", - }, - { - "type": "doctype", - "name": "Shipping Rule", - }, - { - "type": "doctype", - "name": "Pricing Rule", - }, - { - "type": "doctype", - "name": "Item Alternative", - }, - { - "type": "doctype", - "name": "Item Manufacturer", - }, - { - "type": "doctype", - "name": "Item Variant Settings", - }, - ] - }, - { - "label": _("Serial No and Batch"), - "items": [ - { - "type": "doctype", - "name": "Serial No", - "onboard": 1, - "dependencies": ["Item"], - }, - { - "type": "doctype", - "name": "Batch", - "onboard": 1, - "dependencies": ["Item"], - }, - { - "type": "doctype", - "name": "Installation Note", - "dependencies": ["Item"], - }, - { - "type": "report", - "name": "Serial No Service Contract Expiry", - "doctype": "Serial No" - }, - { - "type": "report", - "name": "Serial No Status", - "doctype": "Serial No" - }, - { - "type": "report", - "name": "Serial No Warranty Expiry", - "doctype": "Serial No" - }, - ] - }, - { - "label": _("Tools"), - "icon": "fa fa-wrench", - "items": [ - { - "type": "doctype", - "name": "Stock Reconciliation", - "onboard": 1, - }, - { - "type": "doctype", - "name": "Landed Cost Voucher", - "onboard": 1, - }, - { - "type": "doctype", - "name": "Packing Slip", - "onboard": 1, - }, - { - "type": "doctype", - "name": "Quality Inspection", - }, - { - "type": "doctype", - "name": "Quality Inspection Template", - }, - { - "type": "doctype", - "name": "Quick Stock Balance", - }, - ] - }, - { - "label": _("Key Reports"), - "icon": "fa fa-table", - "items": [ - { - "type": "report", - "is_query_report": False, - "name": "Item-wise Price List Rate", - "doctype": "Item Price", - "onboard": 1, - }, - { - "type": "report", - "is_query_report": True, - "name": "Stock Analytics", - "doctype": "Stock Entry", - "onboard": 1, - }, - { - "type": "report", - "is_query_report": True, - "name": "Delivery Note Trends", - "doctype": "Delivery Note" - }, - { - "type": "report", - "is_query_report": True, - "name": "Purchase Receipt Trends", - "doctype": "Purchase Receipt" - }, - { - "type": "report", - "is_query_report": True, - "name": "Ordered Items To Be Delivered", - "doctype": "Delivery Note" - }, - { - "type": "report", - "is_query_report": True, - "name": "Purchase Order Items To Be Received", - "doctype": "Purchase Receipt" - }, - { - "type": "report", - "is_query_report": True, - "name": "Item Shortage Report", - "doctype": "Bin" - }, - { - "type": "report", - "is_query_report": True, - "name": "Batch-Wise Balance History", - "doctype": "Batch" - }, - ] - }, - { - "label": _("Other Reports"), - "icon": "fa fa-list", - "items": [ - { - "type": "report", - "is_query_report": True, - "name": "Requested Items To Be Transferred", - "doctype": "Material Request" - }, - { - "type": "report", - "is_query_report": True, - "name": "Batch Item Expiry Status", - "doctype": "Stock Ledger Entry" - }, - { - "type": "report", - "is_query_report": True, - "name": "Item Prices", - "doctype": "Price List" - }, - { - "type": "report", - "is_query_report": True, - "name": "Itemwise Recommended Reorder Level", - "doctype": "Item" - }, - { - "type": "report", - "is_query_report": True, - "name": "Item Variant Details", - "doctype": "Item" - }, - { - "type": "report", - "is_query_report": True, - "name": "Subcontracted Raw Materials To Be Transferred", - "doctype": "Purchase Order" - }, - { - "type": "report", - "is_query_report": True, - "name": "Subcontracted Item To Be Received", - "doctype": "Purchase Order" - }, - { - "type": "report", - "is_query_report": True, - "name": "Stock and Account Value Comparison", - "doctype": "Stock Ledger Entry" - } - ] - }, - - ] diff --git a/erpnext/config/support.py b/erpnext/config/support.py deleted file mode 100644 index 151c4f743e1..00000000000 --- a/erpnext/config/support.py +++ /dev/null @@ -1,105 +0,0 @@ -from __future__ import unicode_literals -from frappe import _ - -def get_data(): - return [ - { - "label": _("Issues"), - "items": [ - { - "type": "doctype", - "name": "Issue", - "description": _("Support queries from customers."), - "onboard": 1, - }, - { - "type": "doctype", - "name": "Issue Type", - "description": _("Issue Type."), - }, - { - "type": "doctype", - "name": "Issue Priority", - "description": _("Issue Priority."), - } - ] - }, - { - "label": _("Warranty"), - "items": [ - { - "type": "doctype", - "name": "Warranty Claim", - "description": _("Warranty Claim against Serial No."), - }, - { - "type": "doctype", - "name": "Serial No", - "description": _("Single unit of an Item."), - }, - ] - }, - { - "label": _("Service Level Agreement"), - "items": [ - { - "type": "doctype", - "name": "Service Level", - "description": _("Service Level."), - }, - { - "type": "doctype", - "name": "Service Level Agreement", - "description": _("Service Level Agreement."), - } - ] - }, - { - "label": _("Maintenance"), - "items": [ - { - "type": "doctype", - "name": "Maintenance Schedule", - }, - { - "type": "doctype", - "name": "Maintenance Visit", - }, - ] - }, - { - "label": _("Reports"), - "icon": "fa fa-list", - "items": [ - { - "type": "page", - "name": "support-analytics", - "label": _("Support Analytics"), - "icon": "fa fa-bar-chart" - }, - { - "type": "report", - "name": "Minutes to First Response for Issues", - "doctype": "Issue", - "is_query_report": True - }, - { - "type": "report", - "name": "Support Hours", - "doctype": "Issue", - "is_query_report": True - }, - ] - }, - { - "label": _("Settings"), - "icon": "fa fa-list", - "items": [ - { - "type": "doctype", - "name": "Support Settings", - "label": _("Support Settings"), - }, - ] - }, - ] \ No newline at end of file diff --git a/erpnext/config/website.py b/erpnext/config/website.py deleted file mode 100644 index d31b0578812..00000000000 --- a/erpnext/config/website.py +++ /dev/null @@ -1,33 +0,0 @@ -from __future__ import unicode_literals -from frappe import _ - -def get_data(): - return [ - { - "label": _("Portal"), - "items": [ - { - "type": "doctype", - "name": "Homepage", - "description": _("Settings for website homepage"), - }, - { - "type": "doctype", - "name": "Homepage Section", - "description": _("Add cards or custom sections on homepage"), - }, - { - "type": "doctype", - "name": "Products Settings", - "description": _("Settings for website product listing"), - }, - { - "type": "doctype", - "name": "Shopping Cart Settings", - "label": _("Shopping Cart Settings"), - "description": _("Settings for online shopping cart such as shipping rules, price list etc."), - "hide_count": True - } - ] - } - ] From 27e7c264f2d10e8851312742bf72b5beebb8b79c Mon Sep 17 00:00:00 2001 From: Shivam Mishra Date: Tue, 17 Nov 2020 13:19:21 +0530 Subject: [PATCH 137/477] fix: link type --- .../desk_page/accounting/accounting.json | 188 +++++++++--------- .../desk_page/agriculture/agriculture.json | 24 +-- erpnext/assets/desk_page/assets/assets.json | 26 +-- erpnext/buying/desk_page/buying/buying.json | 80 ++++---- erpnext/crm/desk_page/crm/crm.json | 64 +++--- .../desk_page/education/education.json | 106 +++++----- .../erpnext_integrations.json | 16 +- .../erpnext_integrations_settings.json | 12 +- .../desk_page/healthcare/healthcare.json | 82 ++++---- erpnext/hr/desk_page/hr/hr.json | 156 +++++++-------- .../loan_management/desk_page/loan/loan.json | 36 ++-- .../manufacturing/manufacturing.json | 46 ++--- .../desk_page/non_profit/non_profit.json | 28 +-- .../payroll/desk_page/payroll/payroll.json | 50 ++--- .../projects/desk_page/projects/projects.json | 24 +-- .../desk_page/quality/quality.json | 20 +- erpnext/selling/desk_page/retail/retail.json | 14 +- .../selling/desk_page/selling/selling.json | 94 ++++----- .../erpnext_settings/erpnext_settings.json | 2 +- erpnext/setup/desk_page/home/home.json | 70 +++---- erpnext/stock/desk_page/stock/stock.json | 118 +++++------ .../support/desk_page/support/support.json | 22 +- .../desk_page/utilities/utilities.json | 6 +- 23 files changed, 642 insertions(+), 642 deletions(-) diff --git a/erpnext/accounts/desk_page/accounting/accounting.json b/erpnext/accounts/desk_page/accounting/accounting.json index dfc2243b38a..2de2492d2a1 100644 --- a/erpnext/accounts/desk_page/accounting/accounting.json +++ b/erpnext/accounts/desk_page/accounting/accounting.json @@ -114,7 +114,7 @@ "link_to": "Company", "link_type": "DocType", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -123,7 +123,7 @@ "link_to": "Account", "link_type": "DocType", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -132,7 +132,7 @@ "link_to": "Accounts Settings", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -141,7 +141,7 @@ "link_to": "Fiscal Year", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -150,7 +150,7 @@ "link_to": "Accounting Dimension", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -159,7 +159,7 @@ "link_to": "Finance Book", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -168,7 +168,7 @@ "link_to": "Accounting Period", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -177,7 +177,7 @@ "link_to": "Payment Term", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -193,7 +193,7 @@ "link_to": "Journal Entry", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -202,7 +202,7 @@ "link_to": "Journal Entry Template", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -211,7 +211,7 @@ "link_to": "General Ledger", "link_type": "Report", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -220,7 +220,7 @@ "link_to": "Customer Ledger Summary", "link_type": "Report", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -229,7 +229,7 @@ "link_to": "Supplier Ledger Summary", "link_type": "Report", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -245,7 +245,7 @@ "link_to": "Sales Invoice", "link_type": "DocType", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -254,7 +254,7 @@ "link_to": "Customer", "link_type": "DocType", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -263,7 +263,7 @@ "link_to": "Payment Entry", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -272,7 +272,7 @@ "link_to": "Payment Request", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -281,7 +281,7 @@ "link_to": "Accounts Receivable", "link_type": "Report", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -290,7 +290,7 @@ "link_to": "Accounts Receivable Summary", "link_type": "Report", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -299,7 +299,7 @@ "link_to": "Sales Register", "link_type": "Report", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -308,7 +308,7 @@ "link_to": "Item-wise Sales Register", "link_type": "Report", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -317,7 +317,7 @@ "link_to": "Sales Order Analysis", "link_type": "Report", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -326,7 +326,7 @@ "link_to": "Delivered Items To Be Billed", "link_type": "Report", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -342,7 +342,7 @@ "link_to": "Purchase Invoice", "link_type": "DocType", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -351,7 +351,7 @@ "link_to": "Supplier", "link_type": "DocType", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -360,7 +360,7 @@ "link_to": "Payment Entry", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -369,7 +369,7 @@ "link_to": "Accounts Payable", "link_type": "Report", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -378,7 +378,7 @@ "link_to": "Accounts Payable Summary", "link_type": "Report", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -387,7 +387,7 @@ "link_to": "Purchase Register", "link_type": "Report", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -396,7 +396,7 @@ "link_to": "Item-wise Purchase Register", "link_type": "Report", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -405,7 +405,7 @@ "link_to": "Purchase Order Analysis", "link_type": "Report", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -414,7 +414,7 @@ "link_to": "Received Items To Be Billed", "link_type": "Report", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -430,7 +430,7 @@ "link_to": "Trial Balance for Party", "link_type": "Report", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -439,7 +439,7 @@ "link_to": "Payment Period Based On Invoice Date", "link_type": "Report", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -448,7 +448,7 @@ "link_to": "Sales Partners Commission", "link_type": "Report", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -457,7 +457,7 @@ "link_to": "Customer Credit Balance", "link_type": "Report", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -466,7 +466,7 @@ "link_to": "Sales Payment Summary", "link_type": "Report", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -475,7 +475,7 @@ "link_to": "Address And Contacts", "link_type": "Report", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -484,7 +484,7 @@ "link_to": "DATEV", "link_type": "Report", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -500,7 +500,7 @@ "link_to": "Trial Balance", "link_type": "Report", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -509,7 +509,7 @@ "link_to": "Profit and Loss Statement", "link_type": "Report", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -518,7 +518,7 @@ "link_to": "Balance Sheet", "link_type": "Report", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -527,7 +527,7 @@ "link_to": "Cash Flow", "link_type": "Report", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -536,7 +536,7 @@ "link_to": "Consolidated Financial Statement", "link_type": "Report", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -552,7 +552,7 @@ "link_to": "Currency", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -561,7 +561,7 @@ "link_to": "Currency Exchange", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -570,7 +570,7 @@ "link_to": "Exchange Rate Revaluation", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -586,7 +586,7 @@ "link_to": "Payment Gateway Account", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -595,7 +595,7 @@ "link_to": "Terms and Conditions", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -604,7 +604,7 @@ "link_to": "Mode of Payment", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -620,7 +620,7 @@ "link_to": "Bank", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -629,7 +629,7 @@ "link_to": "Bank Account", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -638,7 +638,7 @@ "link_to": "Bank Clearance", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -647,7 +647,7 @@ "link_to": "bank-reconciliation", "link_type": "Page", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -656,7 +656,7 @@ "link_to": "Bank Reconciliation Statement", "link_type": "Report", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -665,7 +665,7 @@ "link_to": "Bank Statement Transaction Entry", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -674,7 +674,7 @@ "link_to": "Bank Statement Settings", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -690,7 +690,7 @@ "link_to": "Subscription Plan", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -699,7 +699,7 @@ "link_to": "Subscription", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -708,7 +708,7 @@ "link_to": "Subscription Settings", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -724,7 +724,7 @@ "link_to": "GST Settings", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -733,7 +733,7 @@ "link_to": "GST HSN Code", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -742,7 +742,7 @@ "link_to": "GSTR-1", "link_type": "Report", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -751,7 +751,7 @@ "link_to": "GSTR-2", "link_type": "Report", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -760,7 +760,7 @@ "link_to": "GSTR 3B Report", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -769,7 +769,7 @@ "link_to": "GST Sales Register", "link_type": "Report", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -778,7 +778,7 @@ "link_to": "GST Purchase Register", "link_type": "Report", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -787,7 +787,7 @@ "link_to": "GST Itemised Sales Register", "link_type": "Report", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -796,7 +796,7 @@ "link_to": "GST Itemised Purchase Register", "link_type": "Report", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -805,7 +805,7 @@ "link_to": "C-Form", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -814,7 +814,7 @@ "link_to": "Lower Deduction Certificate", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -830,7 +830,7 @@ "link_to": "Shareholder", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -839,7 +839,7 @@ "link_to": "Share Transfer", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -848,7 +848,7 @@ "link_to": "Share Ledger", "link_type": "Report", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -857,7 +857,7 @@ "link_to": "Share Balance", "link_type": "Report", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -873,7 +873,7 @@ "link_to": "Cost Center", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -882,7 +882,7 @@ "link_to": "Budget", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -891,7 +891,7 @@ "link_to": "Accounting Dimension", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -900,7 +900,7 @@ "link_to": "Budget Variance Report", "link_type": "Report", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -909,7 +909,7 @@ "link_to": "Monthly Distribution", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -925,7 +925,7 @@ "link_to": "Opening Invoice Creation Tool", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -934,7 +934,7 @@ "link_to": "Chart of Accounts Importer", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -943,7 +943,7 @@ "link_to": "Period Closing Voucher", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -959,7 +959,7 @@ "link_to": "Sales Taxes and Charges Template", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -968,7 +968,7 @@ "link_to": "Purchase Taxes and Charges Template", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -977,7 +977,7 @@ "link_to": "Item Tax Template", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -986,7 +986,7 @@ "link_to": "Tax Category", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -995,7 +995,7 @@ "link_to": "Tax Rule", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -1004,7 +1004,7 @@ "link_to": "Tax Withholding Category", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -1020,7 +1020,7 @@ "link_to": "Gross Profit", "link_type": "Report", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -1029,7 +1029,7 @@ "link_to": "Profitability Analysis", "link_type": "Report", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -1038,7 +1038,7 @@ "link_to": "Sales Invoice Trends", "link_type": "Report", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -1047,10 +1047,10 @@ "link_to": "Purchase Invoice Trends", "link_type": "Report", "onboard": 0, - "type": "Card Break" + "type": "Link" } ], - "modified": "2020-11-17 13:00:30.922133", + "modified": "2020-11-17 13:18:37.583879", "modified_by": "Administrator", "module": "Accounts", "name": "Accounting", diff --git a/erpnext/agriculture/desk_page/agriculture/agriculture.json b/erpnext/agriculture/desk_page/agriculture/agriculture.json index 30ac23d60f3..145ef07c105 100644 --- a/erpnext/agriculture/desk_page/agriculture/agriculture.json +++ b/erpnext/agriculture/desk_page/agriculture/agriculture.json @@ -44,7 +44,7 @@ "link_to": "Crop", "link_type": "DocType", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -53,7 +53,7 @@ "link_to": "Crop Cycle", "link_type": "DocType", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -62,7 +62,7 @@ "link_to": "Location", "link_type": "DocType", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -78,7 +78,7 @@ "link_to": "Plant Analysis", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -87,7 +87,7 @@ "link_to": "Soil Analysis", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -96,7 +96,7 @@ "link_to": "Water Analysis", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -105,7 +105,7 @@ "link_to": "Soil Texture", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -114,7 +114,7 @@ "link_to": "Weather", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -123,7 +123,7 @@ "link_to": "Agriculture Analysis Criteria", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -139,7 +139,7 @@ "link_to": "Disease", "link_type": "DocType", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -148,10 +148,10 @@ "link_to": "Fertilizer", "link_type": "DocType", "onboard": 1, - "type": "Card Break" + "type": "Link" } ], - "modified": "2020-11-17 13:00:25.889184", + "modified": "2020-11-17 13:18:42.501139", "modified_by": "Administrator", "module": "Agriculture", "name": "Agriculture", diff --git a/erpnext/assets/desk_page/assets/assets.json b/erpnext/assets/desk_page/assets/assets.json index f5330c083fe..66f448fc9c2 100644 --- a/erpnext/assets/desk_page/assets/assets.json +++ b/erpnext/assets/desk_page/assets/assets.json @@ -49,7 +49,7 @@ "link_to": "Asset", "link_type": "DocType", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -58,7 +58,7 @@ "link_to": "Location", "link_type": "DocType", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -67,7 +67,7 @@ "link_to": "Asset Category", "link_type": "DocType", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -76,7 +76,7 @@ "link_to": "Asset Movement", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -92,7 +92,7 @@ "link_to": "Asset Maintenance Team", "link_type": "DocType", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -101,7 +101,7 @@ "link_to": "Asset Maintenance", "link_type": "DocType", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -110,7 +110,7 @@ "link_to": "Asset Maintenance Log", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -119,7 +119,7 @@ "link_to": "Asset Value Adjustment", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -128,7 +128,7 @@ "link_to": "Asset Repair", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -144,7 +144,7 @@ "link_to": "Asset Depreciation Ledger", "link_type": "Report", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -153,7 +153,7 @@ "link_to": "Asset Depreciations and Balances", "link_type": "Report", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -162,10 +162,10 @@ "link_to": "Asset Maintenance", "link_type": "Report", "onboard": 0, - "type": "Card Break" + "type": "Link" } ], - "modified": "2020-11-17 13:00:26.576154", + "modified": "2020-11-17 13:18:41.714472", "modified_by": "Administrator", "module": "Assets", "name": "Assets", diff --git a/erpnext/buying/desk_page/buying/buying.json b/erpnext/buying/desk_page/buying/buying.json index 1c1d8f38d89..5b85e6ab101 100644 --- a/erpnext/buying/desk_page/buying/buying.json +++ b/erpnext/buying/desk_page/buying/buying.json @@ -76,7 +76,7 @@ "link_to": "Material Request", "link_type": "DocType", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -85,7 +85,7 @@ "link_to": "Purchase Order", "link_type": "DocType", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -94,7 +94,7 @@ "link_to": "Purchase Invoice", "link_type": "DocType", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -103,7 +103,7 @@ "link_to": "Request for Quotation", "link_type": "DocType", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -112,7 +112,7 @@ "link_to": "Supplier Quotation", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -128,7 +128,7 @@ "link_to": "Item", "link_type": "DocType", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -137,7 +137,7 @@ "link_to": "Item Price", "link_type": "DocType", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -146,7 +146,7 @@ "link_to": "Price List", "link_type": "DocType", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -155,7 +155,7 @@ "link_to": "Product Bundle", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -164,7 +164,7 @@ "link_to": "Item Group", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -173,7 +173,7 @@ "link_to": "Promotional Scheme", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -182,7 +182,7 @@ "link_to": "Pricing Rule", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -198,7 +198,7 @@ "link_to": "Buying Settings", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -207,7 +207,7 @@ "link_to": "Purchase Taxes and Charges Template", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -216,7 +216,7 @@ "link_to": "Terms and Conditions", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -232,7 +232,7 @@ "link_to": "Supplier", "link_type": "DocType", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -241,7 +241,7 @@ "link_to": "Supplier Group", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -250,7 +250,7 @@ "link_to": "Contact", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -259,7 +259,7 @@ "link_to": "Address", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -275,7 +275,7 @@ "link_to": "Supplier Scorecard", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -284,7 +284,7 @@ "link_to": "Supplier Scorecard Variable", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -293,7 +293,7 @@ "link_to": "Supplier Scorecard Criteria", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -302,7 +302,7 @@ "link_to": "Supplier Scorecard Standing", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -318,7 +318,7 @@ "link_to": "Purchase Analytics", "link_type": "Report", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -327,7 +327,7 @@ "link_to": "Purchase Order Analysis", "link_type": "Report", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -336,7 +336,7 @@ "link_to": "Supplier-Wise Sales Analytics", "link_type": "Report", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -345,7 +345,7 @@ "link_to": "Requested Items to Order and Receive", "link_type": "Report", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -354,7 +354,7 @@ "link_to": "Purchase Order Trends", "link_type": "Report", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -363,7 +363,7 @@ "link_to": "Procurement Tracker", "link_type": "Report", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -379,7 +379,7 @@ "link_to": "Items To Be Requested", "link_type": "Report", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -388,7 +388,7 @@ "link_to": "Item-wise Purchase History", "link_type": "Report", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -397,7 +397,7 @@ "link_to": "Purchase Receipt Trends", "link_type": "Report", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -406,7 +406,7 @@ "link_to": "Purchase Invoice Trends", "link_type": "Report", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -415,7 +415,7 @@ "link_to": "Subcontracted Raw Materials To Be Transferred", "link_type": "Report", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -424,7 +424,7 @@ "link_to": "Subcontracted Item To Be Received", "link_type": "Report", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -433,7 +433,7 @@ "link_to": "Supplier Quotation Comparison", "link_type": "Report", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -442,7 +442,7 @@ "link_to": "Material Requests for which Supplier Quotations are not created", "link_type": "Report", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -451,7 +451,7 @@ "link_to": "Address And Contacts", "link_type": "Report", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -467,10 +467,10 @@ "link_to": "Import Supplier Invoice", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" } ], - "modified": "2020-11-17 13:00:25.184766", + "modified": "2020-11-17 13:18:43.304970", "modified_by": "Administrator", "module": "Buying", "name": "Buying", diff --git a/erpnext/crm/desk_page/crm/crm.json b/erpnext/crm/desk_page/crm/crm.json index 3238962a281..fd97ba6c0cc 100644 --- a/erpnext/crm/desk_page/crm/crm.json +++ b/erpnext/crm/desk_page/crm/crm.json @@ -58,7 +58,7 @@ "link_to": "Lead", "link_type": "DocType", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -67,7 +67,7 @@ "link_to": "Opportunity", "link_type": "DocType", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -76,7 +76,7 @@ "link_to": "Customer", "link_type": "DocType", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -85,7 +85,7 @@ "link_to": "Contact", "link_type": "DocType", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -94,7 +94,7 @@ "link_to": "Communication", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -103,7 +103,7 @@ "link_to": "Lead Source", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -112,7 +112,7 @@ "link_to": "Contract", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -121,7 +121,7 @@ "link_to": "Appointment", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -130,7 +130,7 @@ "link_to": "Newsletter", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -146,7 +146,7 @@ "link_to": "Lead Details", "link_type": "Report", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -155,7 +155,7 @@ "link_to": "sales-funnel", "link_type": "Page", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -164,7 +164,7 @@ "link_to": "Prospects Engaged But Not Converted", "link_type": "Report", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -173,7 +173,7 @@ "link_to": "First Response Time for Opportunity", "link_type": "Report", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -182,7 +182,7 @@ "link_to": "Inactive Customers", "link_type": "Report", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -191,7 +191,7 @@ "link_to": "Campaign Efficiency", "link_type": "Report", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -200,7 +200,7 @@ "link_to": "Lead Owner Efficiency", "link_type": "Report", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -216,7 +216,7 @@ "link_to": "Maintenance Schedule", "link_type": "DocType", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -225,7 +225,7 @@ "link_to": "Maintenance Visit", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -234,7 +234,7 @@ "link_to": "Warranty Claim", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -250,7 +250,7 @@ "link_to": "Campaign", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -259,7 +259,7 @@ "link_to": "Email Campaign", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -268,7 +268,7 @@ "link_to": "Social Media Post", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -284,7 +284,7 @@ "link_to": "Customer Group", "link_type": "DocType", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -293,7 +293,7 @@ "link_to": "Territory", "link_type": "DocType", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -302,7 +302,7 @@ "link_to": "Sales Person", "link_type": "DocType", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -311,7 +311,7 @@ "link_to": "SMS Center", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -320,7 +320,7 @@ "link_to": "SMS Log", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -329,7 +329,7 @@ "link_to": "SMS Settings", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -338,7 +338,7 @@ "link_to": "Email Group", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -347,7 +347,7 @@ "link_to": "Twitter Settings", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -356,10 +356,10 @@ "link_to": "LinkedIn Settings", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" } ], - "modified": "2020-11-17 13:00:28.196723", + "modified": "2020-11-17 13:18:40.216301", "modified_by": "Administrator", "module": "CRM", "name": "CRM", diff --git a/erpnext/education/desk_page/education/education.json b/erpnext/education/desk_page/education/education.json index dd5338926df..06d7797933a 100644 --- a/erpnext/education/desk_page/education/education.json +++ b/erpnext/education/desk_page/education/education.json @@ -99,7 +99,7 @@ "link_to": "Student", "link_type": "DocType", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -108,7 +108,7 @@ "link_to": "Instructor", "link_type": "DocType", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -117,7 +117,7 @@ "link_to": "Guardian", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -126,7 +126,7 @@ "link_to": "Student Group", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -135,7 +135,7 @@ "link_to": "Student Log", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -151,7 +151,7 @@ "link_to": "Program", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -160,7 +160,7 @@ "link_to": "Course", "link_type": "DocType", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -169,7 +169,7 @@ "link_to": "Topic", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -178,7 +178,7 @@ "link_to": "Room", "link_type": "DocType", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -194,7 +194,7 @@ "link_to": "Article", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -203,7 +203,7 @@ "link_to": "Video", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -212,7 +212,7 @@ "link_to": "Quiz", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -228,7 +228,7 @@ "link_to": "Education Settings", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -237,7 +237,7 @@ "link_to": "Student Category", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -246,7 +246,7 @@ "link_to": "Student Batch Name", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -255,7 +255,7 @@ "link_to": "Grading Scale", "link_type": "DocType", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -264,7 +264,7 @@ "link_to": "Academic Term", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -273,7 +273,7 @@ "link_to": "Academic Year", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -289,7 +289,7 @@ "link_to": "Student Applicant", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -298,7 +298,7 @@ "link_to": "Student Admission", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -307,7 +307,7 @@ "link_to": "Program Enrollment", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -316,7 +316,7 @@ "link_to": "Course Enrollment", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -332,7 +332,7 @@ "link_to": "Fee Structure", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -341,7 +341,7 @@ "link_to": "Fee Category", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -350,7 +350,7 @@ "link_to": "Fee Schedule", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -359,7 +359,7 @@ "link_to": "Fees", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -368,7 +368,7 @@ "link_to": "Student Fee Collection", "link_type": "Report", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -377,7 +377,7 @@ "link_to": "Program wise Fee Collection", "link_type": "Report", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -393,7 +393,7 @@ "link_to": "Course Schedule", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -402,7 +402,7 @@ "link_to": "Course Scheduling Tool", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -418,7 +418,7 @@ "link_to": "Student Attendance", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -427,7 +427,7 @@ "link_to": "Student Leave Application", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -436,7 +436,7 @@ "link_to": "Student Monthly Attendance Sheet", "link_type": "Report", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -445,7 +445,7 @@ "link_to": "Absent Student Report", "link_type": "Report", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -454,7 +454,7 @@ "link_to": "Student Batch-Wise Attendance", "link_type": "Report", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -470,7 +470,7 @@ "link_to": "Course Enrollment", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -479,7 +479,7 @@ "link_to": "Course Activity", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -488,7 +488,7 @@ "link_to": "Quiz Activity", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -504,7 +504,7 @@ "link_to": "Assessment Plan", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -513,7 +513,7 @@ "link_to": "Assessment Group", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -522,7 +522,7 @@ "link_to": "Assessment Result", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -531,7 +531,7 @@ "link_to": "Assessment Criteria", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -547,7 +547,7 @@ "link_to": "Course wise Assessment Report", "link_type": "Report", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -556,7 +556,7 @@ "link_to": "Final Assessment Grades", "link_type": "Report", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -565,7 +565,7 @@ "link_to": "Assessment Plan Status", "link_type": "Report", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -574,7 +574,7 @@ "link_to": "Student Report Generation Tool", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -590,7 +590,7 @@ "link_to": "Student Attendance Tool", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -599,7 +599,7 @@ "link_to": "Assessment Result Tool", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -608,7 +608,7 @@ "link_to": "Student Group Creation Tool", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -617,7 +617,7 @@ "link_to": "Program Enrollment Tool", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -626,7 +626,7 @@ "link_to": "Course Scheduling Tool", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -642,10 +642,10 @@ "link_to": "Student and Guardian Contact Details", "link_type": "Report", "onboard": 0, - "type": "Card Break" + "type": "Link" } ], - "modified": "2020-11-17 13:00:27.243450", + "modified": "2020-11-17 13:18:40.981880", "modified_by": "Administrator", "module": "Education", "name": "Education", diff --git a/erpnext/erpnext_integrations/desk_page/erpnext_integrations/erpnext_integrations.json b/erpnext/erpnext_integrations/desk_page/erpnext_integrations/erpnext_integrations.json index cffa5a2e2cf..df4ed76d473 100644 --- a/erpnext/erpnext_integrations/desk_page/erpnext_integrations/erpnext_integrations.json +++ b/erpnext/erpnext_integrations/desk_page/erpnext_integrations/erpnext_integrations.json @@ -44,7 +44,7 @@ "link_to": "Woocommerce Settings", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -53,7 +53,7 @@ "link_to": "Amazon MWS Settings", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -62,7 +62,7 @@ "link_to": "Shopify Settings", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -78,7 +78,7 @@ "link_to": "GoCardless Settings", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -87,7 +87,7 @@ "link_to": "Mpesa Settings", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -103,7 +103,7 @@ "link_to": "Plaid Settings", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -112,10 +112,10 @@ "link_to": "Exotel Settings", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" } ], - "modified": "2020-11-17 13:00:30.437617", + "modified": "2020-11-17 13:18:38.150378", "modified_by": "Administrator", "module": "ERPNext Integrations", "name": "ERPNext Integrations", diff --git a/erpnext/erpnext_integrations/desk_page/erpnext_integrations_settings/erpnext_integrations_settings.json b/erpnext/erpnext_integrations/desk_page/erpnext_integrations_settings/erpnext_integrations_settings.json index fd5d4dc1c3d..0150a0d5305 100644 --- a/erpnext/erpnext_integrations/desk_page/erpnext_integrations_settings/erpnext_integrations_settings.json +++ b/erpnext/erpnext_integrations/desk_page/erpnext_integrations_settings/erpnext_integrations_settings.json @@ -34,7 +34,7 @@ "link_to": "Woocommerce Settings", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -43,7 +43,7 @@ "link_to": "Shopify Settings", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -52,7 +52,7 @@ "link_to": "Amazon MWS Settings", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -61,7 +61,7 @@ "link_to": "Plaid Settings", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -70,10 +70,10 @@ "link_to": "Exotel Settings", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" } ], - "modified": "2020-11-17 13:00:31.919189", + "modified": "2020-11-17 13:18:36.389137", "modified_by": "Administrator", "module": "ERPNext Integrations", "name": "ERPNext Integrations Settings", diff --git a/erpnext/healthcare/desk_page/healthcare/healthcare.json b/erpnext/healthcare/desk_page/healthcare/healthcare.json index 63751e32345..baf7ad86e62 100644 --- a/erpnext/healthcare/desk_page/healthcare/healthcare.json +++ b/erpnext/healthcare/desk_page/healthcare/healthcare.json @@ -80,7 +80,7 @@ "link_to": "Patient", "link_type": "DocType", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -89,7 +89,7 @@ "link_to": "Healthcare Practitioner", "link_type": "DocType", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -98,7 +98,7 @@ "link_to": "Practitioner Schedule", "link_type": "DocType", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -107,7 +107,7 @@ "link_to": "Medical Department", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -116,7 +116,7 @@ "link_to": "Healthcare Service Unit Type", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -125,7 +125,7 @@ "link_to": "Healthcare Service Unit", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -134,7 +134,7 @@ "link_to": "Medical Code Standard", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -143,7 +143,7 @@ "link_to": "Medical Code", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -159,7 +159,7 @@ "link_to": "Appointment Type", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -168,7 +168,7 @@ "link_to": "Clinical Procedure Template", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -177,7 +177,7 @@ "link_to": "Prescription Dosage", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -186,7 +186,7 @@ "link_to": "Prescription Duration", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -195,7 +195,7 @@ "link_to": "Antibiotic", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -211,7 +211,7 @@ "link_to": "Patient Appointment", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -220,7 +220,7 @@ "link_to": "Clinical Procedure", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -229,7 +229,7 @@ "link_to": "Patient Encounter", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -238,7 +238,7 @@ "link_to": "Vital Signs", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -247,7 +247,7 @@ "link_to": "Complaint", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -256,7 +256,7 @@ "link_to": "Diagnosis", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -265,7 +265,7 @@ "link_to": "Fee Validity", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -281,7 +281,7 @@ "link_to": "Healthcare Settings", "link_type": "DocType", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -297,7 +297,7 @@ "link_to": "Lab Test Template", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -306,7 +306,7 @@ "link_to": "Lab Test Sample", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -315,7 +315,7 @@ "link_to": "Lab Test UOM", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -324,7 +324,7 @@ "link_to": "Sensitivity", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -340,7 +340,7 @@ "link_to": "Lab Test", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -349,7 +349,7 @@ "link_to": "Sample Collection", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -358,7 +358,7 @@ "link_to": "Dosage Form", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -374,7 +374,7 @@ "link_to": "Exercise Type", "link_type": "DocType", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -383,7 +383,7 @@ "link_to": "Therapy Type", "link_type": "DocType", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -392,7 +392,7 @@ "link_to": "Therapy Plan", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -401,7 +401,7 @@ "link_to": "Therapy Session", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -410,7 +410,7 @@ "link_to": "Patient Assessment Template", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -419,7 +419,7 @@ "link_to": "Patient Assessment", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -435,7 +435,7 @@ "link_to": "patient_history", "link_type": "Page", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -444,7 +444,7 @@ "link_to": "patient-progress", "link_type": "Page", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -453,7 +453,7 @@ "link_to": "Patient Medical Record", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -462,7 +462,7 @@ "link_to": "Inpatient Record", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -478,7 +478,7 @@ "link_to": "Patient Appointment Analytics", "link_type": "Report", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -487,10 +487,10 @@ "link_to": "Lab Test Report", "link_type": "Report", "onboard": 0, - "type": "Card Break" + "type": "Link" } ], - "modified": "2020-11-17 13:00:31.675127", + "modified": "2020-11-17 13:18:36.771243", "modified_by": "Administrator", "module": "Healthcare", "name": "Healthcare", diff --git a/erpnext/hr/desk_page/hr/hr.json b/erpnext/hr/desk_page/hr/hr.json index 4a2ff10a2ab..787dbd35dd6 100644 --- a/erpnext/hr/desk_page/hr/hr.json +++ b/erpnext/hr/desk_page/hr/hr.json @@ -109,7 +109,7 @@ "link_to": "Employee", "link_type": "DocType", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -118,7 +118,7 @@ "link_to": "Employment Type", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -127,7 +127,7 @@ "link_to": "Branch", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -136,7 +136,7 @@ "link_to": "Department", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -145,7 +145,7 @@ "link_to": "Designation", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -154,7 +154,7 @@ "link_to": "Employee Grade", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -163,7 +163,7 @@ "link_to": "Employee Group", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -172,7 +172,7 @@ "link_to": "Employee Health Insurance", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -188,7 +188,7 @@ "link_to": "Employee Onboarding", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -197,7 +197,7 @@ "link_to": "Employee Skill Map", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -206,7 +206,7 @@ "link_to": "Employee Promotion", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -215,7 +215,7 @@ "link_to": "Employee Transfer", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -224,7 +224,7 @@ "link_to": "Employee Separation", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -233,7 +233,7 @@ "link_to": "Employee Onboarding Template", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -242,7 +242,7 @@ "link_to": "Employee Separation Template", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -258,7 +258,7 @@ "link_to": "Shift Type", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -267,7 +267,7 @@ "link_to": "Shift Request", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -276,7 +276,7 @@ "link_to": "Shift Assignment", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -292,7 +292,7 @@ "link_to": "Leave Application", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -301,7 +301,7 @@ "link_to": "Leave Allocation", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -310,7 +310,7 @@ "link_to": "Leave Policy", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -319,7 +319,7 @@ "link_to": "Leave Period", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -328,7 +328,7 @@ "link_to": "Leave Type", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -337,7 +337,7 @@ "link_to": "Holiday List", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -346,7 +346,7 @@ "link_to": "Compensatory Leave Request", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -355,7 +355,7 @@ "link_to": "Leave Encashment", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -364,7 +364,7 @@ "link_to": "Leave Block List", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -373,7 +373,7 @@ "link_to": "Employee Leave Balance", "link_type": "Report", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -389,7 +389,7 @@ "link_to": "Salary Structure", "link_type": "DocType", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -398,7 +398,7 @@ "link_to": "Salary Structure Assignment", "link_type": "DocType", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -407,7 +407,7 @@ "link_to": "Payroll Entry", "link_type": "DocType", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -416,7 +416,7 @@ "link_to": "Salary Slip", "link_type": "DocType", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -425,7 +425,7 @@ "link_to": "Payroll Period", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -434,7 +434,7 @@ "link_to": "Income Tax Slab", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -443,7 +443,7 @@ "link_to": "Salary Component", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -452,7 +452,7 @@ "link_to": "Additional Salary", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -461,7 +461,7 @@ "link_to": "Retention Bonus", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -470,7 +470,7 @@ "link_to": "Employee Incentive", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -479,7 +479,7 @@ "link_to": "Salary Register", "link_type": "Report", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -495,7 +495,7 @@ "link_to": "Employee Attendance Tool", "link_type": "DocType", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -504,7 +504,7 @@ "link_to": "Attendance", "link_type": "DocType", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -513,7 +513,7 @@ "link_to": "Attendance Request", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -522,7 +522,7 @@ "link_to": "Upload Attendance", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -531,7 +531,7 @@ "link_to": "Employee Checkin", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -540,7 +540,7 @@ "link_to": "Monthly Attendance Sheet", "link_type": "Report", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -556,7 +556,7 @@ "link_to": "Expense Claim", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -565,7 +565,7 @@ "link_to": "Employee Advance", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -581,7 +581,7 @@ "link_to": "HR Settings", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -590,7 +590,7 @@ "link_to": "Daily Work Summary Group", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -599,7 +599,7 @@ "link_to": "team-updates", "link_type": "Page", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -615,7 +615,7 @@ "link_to": "Vehicle", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -624,7 +624,7 @@ "link_to": "Vehicle Log", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -633,7 +633,7 @@ "link_to": "Vehicle Expenses", "link_type": "Report", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -649,7 +649,7 @@ "link_to": "Job Opening", "link_type": "DocType", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -658,7 +658,7 @@ "link_to": "Job Applicant", "link_type": "DocType", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -667,7 +667,7 @@ "link_to": "Job Offer", "link_type": "DocType", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -676,7 +676,7 @@ "link_to": "Staffing Plan", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -692,7 +692,7 @@ "link_to": "Loan Application", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -701,7 +701,7 @@ "link_to": "Loan", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -710,7 +710,7 @@ "link_to": "Loan Type", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -726,7 +726,7 @@ "link_to": "Training Program", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -735,7 +735,7 @@ "link_to": "Training Event", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -744,7 +744,7 @@ "link_to": "Training Result", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -753,7 +753,7 @@ "link_to": "Training Feedback", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -769,7 +769,7 @@ "link_to": "Employee Birthday", "link_type": "Report", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -778,7 +778,7 @@ "link_to": "Employees working on a holiday", "link_type": "Report", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -794,7 +794,7 @@ "link_to": "Appraisal", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -803,7 +803,7 @@ "link_to": "Appraisal Template", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -812,7 +812,7 @@ "link_to": "Energy Point Rule", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -821,7 +821,7 @@ "link_to": "Energy Point Log", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -837,7 +837,7 @@ "link_to": "Employee Tax Exemption Declaration", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -846,7 +846,7 @@ "link_to": "Employee Tax Exemption Proof Submission", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -855,7 +855,7 @@ "link_to": "Employee Other Income", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -864,7 +864,7 @@ "link_to": "Employee Benefit Application", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -873,7 +873,7 @@ "link_to": "Employee Benefit Claim", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -882,7 +882,7 @@ "link_to": "Employee Tax Exemption Category", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -891,10 +891,10 @@ "link_to": "Employee Tax Exemption Sub Category", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" } ], - "modified": "2020-11-17 13:00:24.707870", + "modified": "2020-11-17 13:18:43.807222", "modified_by": "Administrator", "module": "HR", "name": "HR", diff --git a/erpnext/loan_management/desk_page/loan/loan.json b/erpnext/loan_management/desk_page/loan/loan.json index 0156809619e..0c9bd358e9f 100644 --- a/erpnext/loan_management/desk_page/loan/loan.json +++ b/erpnext/loan_management/desk_page/loan/loan.json @@ -54,7 +54,7 @@ "link_to": "Loan Type", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -63,7 +63,7 @@ "link_to": "Loan Application", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -72,7 +72,7 @@ "link_to": "Loan", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -88,7 +88,7 @@ "link_to": "Process Loan Security Shortfall", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -97,7 +97,7 @@ "link_to": "Process Loan Interest Accrual", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -113,7 +113,7 @@ "link_to": "Loan Disbursement", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -122,7 +122,7 @@ "link_to": "Loan Repayment", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -131,7 +131,7 @@ "link_to": "Loan Write Off", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -140,7 +140,7 @@ "link_to": "Loan Interest Accrual", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -156,7 +156,7 @@ "link_to": "Loan Security Type", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -165,7 +165,7 @@ "link_to": "Loan Security Price", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -174,7 +174,7 @@ "link_to": "Loan Security", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -183,7 +183,7 @@ "link_to": "Loan Security Pledge", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -192,7 +192,7 @@ "link_to": "Loan Security Unpledge", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -201,7 +201,7 @@ "link_to": "Loan Security Shortfall", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -217,7 +217,7 @@ "link_to": "Loan Repayment and Closure", "link_type": "Report", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -226,10 +226,10 @@ "link_to": "Loan Security Status", "link_type": "Report", "onboard": 0, - "type": "Card Break" + "type": "Link" } ], - "modified": "2020-11-17 13:00:29.299238", + "modified": "2020-11-17 13:18:39.173544", "modified_by": "Administrator", "module": "Loan Management", "name": "Loan", diff --git a/erpnext/manufacturing/desk_page/manufacturing/manufacturing.json b/erpnext/manufacturing/desk_page/manufacturing/manufacturing.json index 020b147916e..4eb6f2809f0 100644 --- a/erpnext/manufacturing/desk_page/manufacturing/manufacturing.json +++ b/erpnext/manufacturing/desk_page/manufacturing/manufacturing.json @@ -58,7 +58,7 @@ "link_to": "Work Order", "link_type": "DocType", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -67,7 +67,7 @@ "link_to": "Production Plan", "link_type": "DocType", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -76,7 +76,7 @@ "link_to": "Stock Entry", "link_type": "DocType", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -85,7 +85,7 @@ "link_to": "Job Card", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -94,7 +94,7 @@ "link_to": "Downtime Entry", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -110,7 +110,7 @@ "link_to": "Item", "link_type": "DocType", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -119,7 +119,7 @@ "link_to": "BOM", "link_type": "DocType", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -128,7 +128,7 @@ "link_to": "Workstation", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -137,7 +137,7 @@ "link_to": "Operation", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -146,7 +146,7 @@ "link_to": "Routing", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -162,7 +162,7 @@ "link_to": "Production Planning Report", "link_type": "Report", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -171,7 +171,7 @@ "link_to": "Work Order Summary", "link_type": "Report", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -180,7 +180,7 @@ "link_to": "Quality Inspection Summary", "link_type": "Report", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -189,7 +189,7 @@ "link_to": "Downtime Analysis", "link_type": "Report", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -198,7 +198,7 @@ "link_to": "Job Card Summary", "link_type": "Report", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -207,7 +207,7 @@ "link_to": "BOM Search", "link_type": "Report", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -216,7 +216,7 @@ "link_to": "BOM Stock Report", "link_type": "Report", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -225,7 +225,7 @@ "link_to": "Production Analytics", "link_type": "Report", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -234,7 +234,7 @@ "link_to": "BOM Operations Time", "link_type": "Report", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -250,7 +250,7 @@ "link_to": "BOM Update Tool", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -259,7 +259,7 @@ "link_to": "bom-comparison-tool", "link_type": "Page", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -275,10 +275,10 @@ "link_to": "Manufacturing Settings", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" } ], - "modified": "2020-11-17 13:00:24.140642", + "modified": "2020-11-17 13:18:44.426761", "modified_by": "Administrator", "module": "Manufacturing", "name": "Manufacturing", diff --git a/erpnext/non_profit/desk_page/non_profit/non_profit.json b/erpnext/non_profit/desk_page/non_profit/non_profit.json index 078e324454c..43262503550 100644 --- a/erpnext/non_profit/desk_page/non_profit/non_profit.json +++ b/erpnext/non_profit/desk_page/non_profit/non_profit.json @@ -59,7 +59,7 @@ "link_to": "Loan Type", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -68,7 +68,7 @@ "link_to": "Loan Application", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -77,7 +77,7 @@ "link_to": "Loan", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -93,7 +93,7 @@ "link_to": "Grant Application", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -109,7 +109,7 @@ "link_to": "Member", "link_type": "DocType", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -118,7 +118,7 @@ "link_to": "Membership", "link_type": "DocType", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -127,7 +127,7 @@ "link_to": "Membership Type", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -136,7 +136,7 @@ "link_to": "Membership Settings", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -152,7 +152,7 @@ "link_to": "Volunteer", "link_type": "DocType", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -161,7 +161,7 @@ "link_to": "Volunteer Type", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -177,7 +177,7 @@ "link_to": "Chapter", "link_type": "DocType", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -193,7 +193,7 @@ "link_to": "Donor", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -202,10 +202,10 @@ "link_to": "Donor Type", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" } ], - "modified": "2020-11-17 13:00:26.036726", + "modified": "2020-11-17 13:18:42.271279", "modified_by": "Administrator", "module": "Non Profit", "name": "Non Profit", diff --git a/erpnext/payroll/desk_page/payroll/payroll.json b/erpnext/payroll/desk_page/payroll/payroll.json index 9247213c345..0397055184e 100644 --- a/erpnext/payroll/desk_page/payroll/payroll.json +++ b/erpnext/payroll/desk_page/payroll/payroll.json @@ -54,7 +54,7 @@ "link_to": "Salary Component", "link_type": "DocType", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -63,7 +63,7 @@ "link_to": "Salary Structure", "link_type": "DocType", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -72,7 +72,7 @@ "link_to": "Salary Structure Assignment", "link_type": "DocType", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -81,7 +81,7 @@ "link_to": "Payroll Entry", "link_type": "DocType", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -90,7 +90,7 @@ "link_to": "Salary Slip", "link_type": "DocType", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -106,7 +106,7 @@ "link_to": "Payroll Period", "link_type": "DocType", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -115,7 +115,7 @@ "link_to": "Income Tax Slab", "link_type": "DocType", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -124,7 +124,7 @@ "link_to": "Employee Other Income", "link_type": "DocType", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -133,7 +133,7 @@ "link_to": "Employee Tax Exemption Declaration", "link_type": "DocType", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -142,7 +142,7 @@ "link_to": "Employee Tax Exemption Proof Submission", "link_type": "DocType", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -151,7 +151,7 @@ "link_to": "Employee Tax Exemption Category", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -160,7 +160,7 @@ "link_to": "Employee Tax Exemption Sub Category", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -176,7 +176,7 @@ "link_to": "Additional Salary", "link_type": "DocType", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -185,7 +185,7 @@ "link_to": "Retention Bonus", "link_type": "DocType", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -194,7 +194,7 @@ "link_to": "Employee Incentive", "link_type": "DocType", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -203,7 +203,7 @@ "link_to": "Employee Benefit Application", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -212,7 +212,7 @@ "link_to": "Employee Benefit Claim", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -228,7 +228,7 @@ "link_to": "Salary Register", "link_type": "Report", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -237,7 +237,7 @@ "link_to": "Salary Payments Based On Payment Mode", "link_type": "Report", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -246,7 +246,7 @@ "link_to": "Salary Payments via ECS", "link_type": "Report", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -255,7 +255,7 @@ "link_to": "Income Tax Deductions", "link_type": "Report", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -264,7 +264,7 @@ "link_to": "Professional Tax Deductions", "link_type": "Report", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -273,7 +273,7 @@ "link_to": "Provident Fund Deductions", "link_type": "Report", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -282,10 +282,10 @@ "link_to": "Bank Remittance", "link_type": "Report", "onboard": 0, - "type": "Card Break" + "type": "Link" } ], - "modified": "2020-11-17 13:00:27.751514", + "modified": "2020-11-17 13:18:40.644642", "modified_by": "Administrator", "module": "Payroll", "name": "Payroll", diff --git a/erpnext/projects/desk_page/projects/projects.json b/erpnext/projects/desk_page/projects/projects.json index 4ea2963f50c..7ad5398251b 100644 --- a/erpnext/projects/desk_page/projects/projects.json +++ b/erpnext/projects/desk_page/projects/projects.json @@ -49,7 +49,7 @@ "link_to": "Project", "link_type": "DocType", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -58,7 +58,7 @@ "link_to": "Task", "link_type": "DocType", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -67,7 +67,7 @@ "link_to": "Project Template", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -76,7 +76,7 @@ "link_to": "Project Type", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -85,7 +85,7 @@ "link_to": "Project Update", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -101,7 +101,7 @@ "link_to": "Timesheet", "link_type": "DocType", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -110,7 +110,7 @@ "link_to": "Activity Type", "link_type": "DocType", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -119,7 +119,7 @@ "link_to": "Activity Cost", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -135,7 +135,7 @@ "link_to": "Daily Timesheet Summary", "link_type": "Report", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -144,7 +144,7 @@ "link_to": "Project wise Stock Tracking", "link_type": "Report", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -153,10 +153,10 @@ "link_to": "Project Billing Summary", "link_type": "Report", "onboard": 0, - "type": "Card Break" + "type": "Link" } ], - "modified": "2020-11-17 13:00:26.739225", + "modified": "2020-11-17 13:18:41.526145", "modified_by": "Administrator", "module": "Projects", "name": "Projects", diff --git a/erpnext/quality_management/desk_page/quality/quality.json b/erpnext/quality_management/desk_page/quality/quality.json index 499182e082a..59a112ec772 100644 --- a/erpnext/quality_management/desk_page/quality/quality.json +++ b/erpnext/quality_management/desk_page/quality/quality.json @@ -49,7 +49,7 @@ "link_to": "Quality Goal", "link_type": "DocType", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -58,7 +58,7 @@ "link_to": "Quality Procedure", "link_type": "DocType", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -67,7 +67,7 @@ "link_to": "Quality Procedure", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -83,7 +83,7 @@ "link_to": "Quality Feedback", "link_type": "DocType", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -92,7 +92,7 @@ "link_to": "Quality Feedback Template", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -108,7 +108,7 @@ "link_to": "Quality Meeting", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -124,7 +124,7 @@ "link_to": "Non Conformance", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -133,7 +133,7 @@ "link_to": "Quality Review", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -142,10 +142,10 @@ "link_to": "Quality Action", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" } ], - "modified": "2020-11-17 13:00:31.488858", + "modified": "2020-11-17 13:18:37.174448", "modified_by": "Administrator", "module": "Quality Management", "name": "Quality", diff --git a/erpnext/selling/desk_page/retail/retail.json b/erpnext/selling/desk_page/retail/retail.json index c5f461abb6b..5cb54d315fb 100644 --- a/erpnext/selling/desk_page/retail/retail.json +++ b/erpnext/selling/desk_page/retail/retail.json @@ -44,7 +44,7 @@ "link_to": "POS Profile", "link_type": "DocType", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -53,7 +53,7 @@ "link_to": "POS Settings", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -69,7 +69,7 @@ "link_to": "Loyalty Program", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -78,7 +78,7 @@ "link_to": "Loyalty Point Entry", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -94,7 +94,7 @@ "link_to": "POS Opening Entry", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -103,10 +103,10 @@ "link_to": "POS Closing Entry", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" } ], - "modified": "2020-11-17 13:00:29.114099", + "modified": "2020-11-17 13:18:39.383674", "modified_by": "Administrator", "module": "Selling", "name": "Retail", diff --git a/erpnext/selling/desk_page/selling/selling.json b/erpnext/selling/desk_page/selling/selling.json index 23edc259da3..29bc549cca3 100644 --- a/erpnext/selling/desk_page/selling/selling.json +++ b/erpnext/selling/desk_page/selling/selling.json @@ -60,7 +60,7 @@ "link_to": "Customer", "link_type": "DocType", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -69,7 +69,7 @@ "link_to": "Quotation", "link_type": "DocType", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -78,7 +78,7 @@ "link_to": "Sales Order", "link_type": "DocType", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -87,7 +87,7 @@ "link_to": "Sales Invoice", "link_type": "DocType", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -96,7 +96,7 @@ "link_to": "Blanket Order", "link_type": "DocType", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -105,7 +105,7 @@ "link_to": "Sales Partner", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -114,7 +114,7 @@ "link_to": "Sales Person", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -130,7 +130,7 @@ "link_to": "Item", "link_type": "DocType", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -139,7 +139,7 @@ "link_to": "Item Price", "link_type": "DocType", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -148,7 +148,7 @@ "link_to": "Price List", "link_type": "DocType", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -157,7 +157,7 @@ "link_to": "Item Group", "link_type": "DocType", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -166,7 +166,7 @@ "link_to": "Product Bundle", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -175,7 +175,7 @@ "link_to": "Promotional Scheme", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -184,7 +184,7 @@ "link_to": "Pricing Rule", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -193,7 +193,7 @@ "link_to": "Shipping Rule", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -202,7 +202,7 @@ "link_to": "Coupon Code", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -218,7 +218,7 @@ "link_to": "Selling Settings", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -227,7 +227,7 @@ "link_to": "Terms and Conditions", "link_type": "DocType", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -236,7 +236,7 @@ "link_to": "Sales Taxes and Charges Template", "link_type": "DocType", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -245,7 +245,7 @@ "link_to": "Lead Source", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -254,7 +254,7 @@ "link_to": "Customer Group", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -263,7 +263,7 @@ "link_to": "Contact", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -272,7 +272,7 @@ "link_to": "Address", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -281,7 +281,7 @@ "link_to": "Territory", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -290,7 +290,7 @@ "link_to": "Campaign", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -306,7 +306,7 @@ "link_to": "Sales Analytics", "link_type": "Report", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -315,7 +315,7 @@ "link_to": "Sales Order Analysis", "link_type": "Report", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -324,7 +324,7 @@ "link_to": "sales-funnel", "link_type": "Page", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -333,7 +333,7 @@ "link_to": "Sales Order Trends", "link_type": "Report", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -342,7 +342,7 @@ "link_to": "Quotation Trends", "link_type": "Report", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -351,7 +351,7 @@ "link_to": "Customer Acquisition and Loyalty", "link_type": "Report", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -360,7 +360,7 @@ "link_to": "Inactive Customers", "link_type": "Report", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -369,7 +369,7 @@ "link_to": "Sales Person-wise Transaction Summary", "link_type": "Report", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -378,7 +378,7 @@ "link_to": "Item-wise Sales History", "link_type": "Report", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -394,7 +394,7 @@ "link_to": "Lead Details", "link_type": "Report", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -403,7 +403,7 @@ "link_to": "Address And Contacts", "link_type": "Report", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -412,7 +412,7 @@ "link_to": "Available Stock for Packing Items", "link_type": "Report", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -421,7 +421,7 @@ "link_to": "Pending SO Items For Purchase Request", "link_type": "Report", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -430,7 +430,7 @@ "link_to": "Delivery Note Trends", "link_type": "Report", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -439,7 +439,7 @@ "link_to": "Sales Invoice Trends", "link_type": "Report", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -448,7 +448,7 @@ "link_to": "Customer Credit Balance", "link_type": "Report", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -457,7 +457,7 @@ "link_to": "Customers Without Any Sales Transactions", "link_type": "Report", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -466,7 +466,7 @@ "link_to": "Sales Partners Commission", "link_type": "Report", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -475,7 +475,7 @@ "link_to": "Territory Target Variance Based On Item Group", "link_type": "Report", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -484,7 +484,7 @@ "link_to": "Sales Person Target Variance Based On Item Group", "link_type": "Report", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -493,10 +493,10 @@ "link_to": "Sales Partner Target Variance based on Item Group", "link_type": "Report", "onboard": 0, - "type": "Card Break" + "type": "Link" } ], - "modified": "2020-11-17 13:00:30.100950", + "modified": "2020-11-17 13:18:38.357500", "modified_by": "Administrator", "module": "Selling", "name": "Selling", diff --git a/erpnext/setup/desk_page/erpnext_settings/erpnext_settings.json b/erpnext/setup/desk_page/erpnext_settings/erpnext_settings.json index efa27e9a55d..03a9fe4b656 100644 --- a/erpnext/setup/desk_page/erpnext_settings/erpnext_settings.json +++ b/erpnext/setup/desk_page/erpnext_settings/erpnext_settings.json @@ -15,7 +15,7 @@ "is_standard": 1, "label": "ERPNext Settings", "links": [], - "modified": "2020-11-17 13:00:26.889826", + "modified": "2020-11-17 13:18:41.371988", "modified_by": "Administrator", "module": "Setup", "name": "ERPNext Settings", diff --git a/erpnext/setup/desk_page/home/home.json b/erpnext/setup/desk_page/home/home.json index 5f7ab0161ea..6149226f017 100644 --- a/erpnext/setup/desk_page/home/home.json +++ b/erpnext/setup/desk_page/home/home.json @@ -74,7 +74,7 @@ "link_to": "Patient", "link_type": "DocType", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -83,7 +83,7 @@ "link_to": "Diagnosis", "link_type": "DocType", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -99,7 +99,7 @@ "link_to": "Crop", "link_type": "DocType", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -108,7 +108,7 @@ "link_to": "Crop Cycle", "link_type": "DocType", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -117,7 +117,7 @@ "link_to": "Location", "link_type": "DocType", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -126,7 +126,7 @@ "link_to": "Fertilizer", "link_type": "DocType", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -142,7 +142,7 @@ "link_to": "Student", "link_type": "DocType", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -151,7 +151,7 @@ "link_to": "Course", "link_type": "DocType", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -160,7 +160,7 @@ "link_to": "Instructor", "link_type": "DocType", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -169,7 +169,7 @@ "link_to": "Room", "link_type": "DocType", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -185,7 +185,7 @@ "link_to": "Member", "link_type": "DocType", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -194,7 +194,7 @@ "link_to": "Volunteer", "link_type": "DocType", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -203,7 +203,7 @@ "link_to": "Chapter", "link_type": "DocType", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -212,7 +212,7 @@ "link_to": "Donor", "link_type": "DocType", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -228,7 +228,7 @@ "link_to": "Warehouse", "link_type": "DocType", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -237,7 +237,7 @@ "link_to": "Brand", "link_type": "DocType", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -246,7 +246,7 @@ "link_to": "UOM", "link_type": "DocType", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -255,7 +255,7 @@ "link_to": "Stock Reconciliation", "link_type": "DocType", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -271,7 +271,7 @@ "link_to": "Employee", "link_type": "DocType", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -280,7 +280,7 @@ "link_to": "Employee Attendance Tool", "link_type": "DocType", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -289,7 +289,7 @@ "link_to": "Salary Structure", "link_type": "DocType", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -305,7 +305,7 @@ "link_to": "Lead", "link_type": "DocType", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -314,7 +314,7 @@ "link_to": "Customer Group", "link_type": "DocType", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -323,7 +323,7 @@ "link_to": "Territory", "link_type": "DocType", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -339,7 +339,7 @@ "link_to": "Item", "link_type": "DocType", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -348,7 +348,7 @@ "link_to": "Customer", "link_type": "DocType", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -357,7 +357,7 @@ "link_to": "Supplier", "link_type": "DocType", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -366,7 +366,7 @@ "link_to": "Company", "link_type": "DocType", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -375,7 +375,7 @@ "link_to": "Account", "link_type": "DocType", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -384,7 +384,7 @@ "link_to": "Opening Invoice Creation Tool", "link_type": "DocType", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -400,7 +400,7 @@ "link_to": "Data Import", "link_type": "DocType", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -409,7 +409,7 @@ "link_to": "Chart of Accounts Importer", "link_type": "DocType", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -418,7 +418,7 @@ "link_to": "Letter Head", "link_type": "DocType", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -427,10 +427,10 @@ "link_to": "Email Account", "link_type": "DocType", "onboard": 1, - "type": "Card Break" + "type": "Link" } ], - "modified": "2020-11-17 13:00:26.284801", + "modified": "2020-11-17 13:18:41.967994", "modified_by": "Administrator", "module": "Setup", "name": "Home", diff --git a/erpnext/stock/desk_page/stock/stock.json b/erpnext/stock/desk_page/stock/stock.json index 86b3767f476..b545a42254e 100644 --- a/erpnext/stock/desk_page/stock/stock.json +++ b/erpnext/stock/desk_page/stock/stock.json @@ -74,7 +74,7 @@ "link_to": "Item", "link_type": "DocType", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -83,7 +83,7 @@ "link_to": "Item Group", "link_type": "DocType", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -92,7 +92,7 @@ "link_to": "Product Bundle", "link_type": "DocType", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -101,7 +101,7 @@ "link_to": "Price List", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -110,7 +110,7 @@ "link_to": "Item Price", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -119,7 +119,7 @@ "link_to": "Shipping Rule", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -128,7 +128,7 @@ "link_to": "Pricing Rule", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -137,7 +137,7 @@ "link_to": "Item Alternative", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -146,7 +146,7 @@ "link_to": "Item Manufacturer", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -155,7 +155,7 @@ "link_to": "Customs Tariff Number", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -171,7 +171,7 @@ "link_to": "Material Request", "link_type": "DocType", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -180,7 +180,7 @@ "link_to": "Stock Entry", "link_type": "DocType", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -189,7 +189,7 @@ "link_to": "Delivery Note", "link_type": "DocType", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -198,7 +198,7 @@ "link_to": "Purchase Receipt", "link_type": "DocType", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -207,7 +207,7 @@ "link_to": "Pick List", "link_type": "DocType", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -216,7 +216,7 @@ "link_to": "Delivery Trip", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -232,7 +232,7 @@ "link_to": "Stock Ledger", "link_type": "Report", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -241,7 +241,7 @@ "link_to": "Stock Balance", "link_type": "Report", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -250,7 +250,7 @@ "link_to": "Stock Projected Qty", "link_type": "Report", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -259,7 +259,7 @@ "link_to": "stock-balance", "link_type": "Page", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -268,7 +268,7 @@ "link_to": "Stock Ageing", "link_type": "Report", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -277,7 +277,7 @@ "link_to": "Item Price Stock", "link_type": "Report", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -293,7 +293,7 @@ "link_to": "Stock Settings", "link_type": "DocType", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -302,7 +302,7 @@ "link_to": "Warehouse", "link_type": "DocType", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -311,7 +311,7 @@ "link_to": "UOM", "link_type": "DocType", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -320,7 +320,7 @@ "link_to": "Item Variant Settings", "link_type": "DocType", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -329,7 +329,7 @@ "link_to": "Brand", "link_type": "DocType", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -338,7 +338,7 @@ "link_to": "Item Attribute", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -347,7 +347,7 @@ "link_to": "UOM Conversion Factor", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -363,7 +363,7 @@ "link_to": "Serial No", "link_type": "DocType", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -372,7 +372,7 @@ "link_to": "Batch", "link_type": "DocType", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -381,7 +381,7 @@ "link_to": "Installation Note", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -390,7 +390,7 @@ "link_to": "Serial No Service Contract Expiry", "link_type": "Report", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -399,7 +399,7 @@ "link_to": "Serial No Status", "link_type": "Report", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -408,7 +408,7 @@ "link_to": "Serial No Warranty Expiry", "link_type": "Report", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -424,7 +424,7 @@ "link_to": "Stock Reconciliation", "link_type": "DocType", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -433,7 +433,7 @@ "link_to": "Landed Cost Voucher", "link_type": "DocType", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -442,7 +442,7 @@ "link_to": "Packing Slip", "link_type": "DocType", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -451,7 +451,7 @@ "link_to": "Quality Inspection", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -460,7 +460,7 @@ "link_to": "Quality Inspection Template", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -469,7 +469,7 @@ "link_to": "Quick Stock Balance", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -485,7 +485,7 @@ "link_to": "Item-wise Price List Rate", "link_type": "Report", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -494,7 +494,7 @@ "link_to": "Stock Analytics", "link_type": "Report", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -503,7 +503,7 @@ "link_to": "Stock Qty vs Serial No Count", "link_type": "Report", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -512,7 +512,7 @@ "link_to": "Delivery Note Trends", "link_type": "Report", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -521,7 +521,7 @@ "link_to": "Purchase Receipt Trends", "link_type": "Report", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -530,7 +530,7 @@ "link_to": "Sales Order Analysis", "link_type": "Report", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -539,7 +539,7 @@ "link_to": "Purchase Order Analysis", "link_type": "Report", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -548,7 +548,7 @@ "link_to": "Item Shortage Report", "link_type": "Report", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -557,7 +557,7 @@ "link_to": "Batch-Wise Balance History", "link_type": "Report", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -573,7 +573,7 @@ "link_to": "Requested Items To Be Transferred", "link_type": "Report", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -582,7 +582,7 @@ "link_to": "Batch Item Expiry Status", "link_type": "Report", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -591,7 +591,7 @@ "link_to": "Item Prices", "link_type": "Report", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -600,7 +600,7 @@ "link_to": "Itemwise Recommended Reorder Level", "link_type": "Report", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -609,7 +609,7 @@ "link_to": "Item Variant Details", "link_type": "Report", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -618,7 +618,7 @@ "link_to": "Subcontracted Raw Materials To Be Transferred", "link_type": "Report", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -627,7 +627,7 @@ "link_to": "Subcontracted Item To Be Received", "link_type": "Report", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -636,10 +636,10 @@ "link_to": "Stock and Account Value Comparison", "link_type": "Report", "onboard": 0, - "type": "Card Break" + "type": "Link" } ], - "modified": "2020-11-17 13:00:29.632812", + "modified": "2020-11-17 13:18:38.783880", "modified_by": "Administrator", "module": "Stock", "name": "Stock", diff --git a/erpnext/support/desk_page/support/support.json b/erpnext/support/desk_page/support/support.json index 4dd322a9ca1..5a88307ef04 100644 --- a/erpnext/support/desk_page/support/support.json +++ b/erpnext/support/desk_page/support/support.json @@ -59,7 +59,7 @@ "link_to": "Issue", "link_type": "DocType", "onboard": 1, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -68,7 +68,7 @@ "link_to": "Issue Type", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -77,7 +77,7 @@ "link_to": "Issue Priority", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -93,7 +93,7 @@ "link_to": "Maintenance Schedule", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -102,7 +102,7 @@ "link_to": "Maintenance Visit", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -118,7 +118,7 @@ "link_to": "Service Level Agreement", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -134,7 +134,7 @@ "link_to": "Warranty Claim", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -143,7 +143,7 @@ "link_to": "Serial No", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -159,7 +159,7 @@ "link_to": "Support Settings", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -175,10 +175,10 @@ "link_to": "First Response Time for Issues", "link_type": "Report", "onboard": 0, - "type": "Card Break" + "type": "Link" } ], - "modified": "2020-11-17 13:00:27.977688", + "modified": "2020-11-17 13:18:40.457842", "modified_by": "Administrator", "module": "Support", "name": "Support", diff --git a/erpnext/utilities/desk_page/utilities/utilities.json b/erpnext/utilities/desk_page/utilities/utilities.json index 987b6515068..3f654bea648 100644 --- a/erpnext/utilities/desk_page/utilities/utilities.json +++ b/erpnext/utilities/desk_page/utilities/utilities.json @@ -33,7 +33,7 @@ "link_to": "Video", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" }, { "hidden": 0, @@ -42,10 +42,10 @@ "link_to": "Video Settings", "link_type": "DocType", "onboard": 0, - "type": "Card Break" + "type": "Link" } ], - "modified": "2020-11-17 13:00:29.198857", + "modified": "2020-11-17 13:18:39.317897", "modified_by": "Administrator", "module": "Utilities", "name": "Utilities", From 0d43ea5ebb8fd84861b984491b5d61b8597f54e3 Mon Sep 17 00:00:00 2001 From: Rucha Mahabal Date: Mon, 30 Nov 2020 15:00:42 +0530 Subject: [PATCH 138/477] refactor: show Patient History feed as per configured date instead of creation --- .../healthcare/page/patient_history/patient_history.js | 2 +- .../healthcare/page/patient_history/patient_history.py | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/erpnext/healthcare/page/patient_history/patient_history.js b/erpnext/healthcare/page/patient_history/patient_history.js index d509ea22a2d..9c44d63b965 100644 --- a/erpnext/healthcare/page/patient_history/patient_history.js +++ b/erpnext/healthcare/page/patient_history/patient_history.js @@ -254,7 +254,7 @@ let add_to_records = function(me, data) { }; let add_date_separator = function(data) { - let date = frappe.datetime.str_to_obj(data.creation); + let date = frappe.datetime.str_to_obj(data.communication_date); let pdate = ''; let diff = frappe.datetime.get_day_diff(frappe.datetime.get_today(), frappe.datetime.obj_to_str(date)); diff --git a/erpnext/healthcare/page/patient_history/patient_history.py b/erpnext/healthcare/page/patient_history/patient_history.py index de8a5771d2f..4cdfd64a697 100644 --- a/erpnext/healthcare/page/patient_history/patient_history.py +++ b/erpnext/healthcare/page/patient_history/patient_history.py @@ -14,10 +14,10 @@ def get_feed(name, document_types=None, date_range=None, start=0, page_length=20 filters = get_filters(name, document_types, date_range) result = frappe.db.get_all('Patient Medical Record', - fields=['name', 'owner', 'creation', + fields=['name', 'owner', 'communication_date', 'reference_doctype', 'reference_name', 'subject'], filters=filters, - order_by='creation DESC', + order_by='communication_date DESC', limit=cint(page_length), start=cint(start) ) @@ -36,7 +36,7 @@ def get_filters(name, document_types=None, date_range=None): try: date_range = json.loads(date_range) if date_range: - filters['creation'] = ['between', [date_range[0], date_range[1]]] + filters['communication_date'] = ['between', [date_range[0], date_range[1]]] except json.decoder.JSONDecodeError: pass @@ -47,13 +47,13 @@ def get_filters(name, document_types=None, date_range=None): def get_feed_for_dt(doctype, docname): """get feed""" result = frappe.db.get_all('Patient Medical Record', - fields=['name', 'owner', 'creation', + fields=['name', 'owner', 'communication_date', 'reference_doctype', 'reference_name', 'subject'], filters={ 'reference_doctype': doctype, 'reference_name': docname }, - order_by='creation DESC' + order_by='communication_date DESC' ) return result From b5b8c5474a14c394fae3ddb4074d7205bc3dfbbb Mon Sep 17 00:00:00 2001 From: Rucha Mahabal Date: Mon, 30 Nov 2020 16:09:15 +0530 Subject: [PATCH 139/477] refactor: move call to fetch doctype fields to server-side --- .../patient_history_settings.js | 47 +++++++++---------- .../patient_history_settings.py | 17 ++++++- 2 files changed, 38 insertions(+), 26 deletions(-) diff --git a/erpnext/healthcare/doctype/patient_history_settings/patient_history_settings.js b/erpnext/healthcare/doctype/patient_history_settings/patient_history_settings.js index ee363462ef8..bf3c5b954e5 100644 --- a/erpnext/healthcare/doctype/patient_history_settings/patient_history_settings.js +++ b/erpnext/healthcare/doctype/patient_history_settings/patient_history_settings.js @@ -18,7 +18,27 @@ frappe.ui.form.on('Patient History Settings', { if (doc.selected_fields) document_fields = (JSON.parse(doc.selected_fields)).map(f => f.fieldname); - let doctype_fields = frm.events.get_doctype_fields(frm, doc.document_type, document_fields); + frm.call({ + method: 'get_doctype_fields', + doc: frm.doc, + args: { + document_type: doc.document_type, + fields: document_fields + }, + freeze: true, + callback: function(r) { + if (r.message) { + let doctype = 'Patient History Custom Document Type'; + if (standard) + doctype = 'Patient History Standard Document Type'; + + frm.events.show_field_selector_dialog(frm, doc, doctype, r.message); + } + } + }); + }, + + show_field_selector_dialog: function(frm, doc, doctype, doc_fields) { let d = new frappe.ui.Dialog({ title: __('{0} Fields', [__(doc.document_type)]), fields: [ @@ -26,7 +46,7 @@ frappe.ui.form.on('Patient History Settings', { label: __('Select Fields'), fieldtype: 'MultiCheck', fieldname: 'fields', - options: doctype_fields, + options: doc_fields, columns: 2 } ] @@ -49,9 +69,6 @@ frappe.ui.form.on('Patient History Settings', { }); } } - let doctype = 'Patient History Custom Document Type'; - if (standard) - doctype = 'Patient History Standard Document Type'; d.refresh(); frappe.model.set_value(doctype, doc.name, 'selected_fields', JSON.stringify(selected_fields)); @@ -59,26 +76,6 @@ frappe.ui.form.on('Patient History Settings', { }); d.show(); - }, - - get_doctype_fields(frm, document_type, fields) { - let multiselect_fields = []; - - frappe.model.with_doctype(document_type, () => { - // get doctype fields - frappe.get_doc('DocType', document_type).fields.forEach(field => { - if (!in_list(frappe.model.no_value_type, field.fieldtype) || - in_list(frappe.model.table_fields, field.fieldtype) && !field.hidden) { - multiselect_fields.push({ - label: field.label, - value: field.fieldname, - checked: in_list(fields, field.fieldname) - }); - } - }); - }); - - return multiselect_fields; } }); diff --git a/erpnext/healthcare/doctype/patient_history_settings/patient_history_settings.py b/erpnext/healthcare/doctype/patient_history_settings/patient_history_settings.py index 367c34f1e86..9f18c6bbf52 100644 --- a/erpnext/healthcare/doctype/patient_history_settings/patient_history_settings.py +++ b/erpnext/healthcare/doctype/patient_history_settings/patient_history_settings.py @@ -4,6 +4,7 @@ from __future__ import unicode_literals import frappe +import json from frappe import _ from frappe.utils import cstr from frappe.model.document import Document @@ -24,6 +25,21 @@ class PatientHistorySettings(Document): frappe.throw(_('Row #{0}: Field {1} in Document Type {2} is not a Date / Datetime field.').format( entry.idx, frappe.bold(entry.date_fieldname), frappe.bold(entry.document_type))) + def get_doctype_fields(self, document_type, fields): + multicheck_fields = [] + doc_fields = frappe.get_meta(document_type).fields + + for field in doc_fields: + if field.fieldtype not in frappe.model.no_value_fields or \ + field.fieldtype in frappe.model.table_fields and not field.hidden: + multicheck_fields.append({ + 'label': field.label, + 'value': field.fieldname, + 'checked': 1 if field.fieldname in fields else 0 + }) + + return multicheck_fields + def create_medical_record(doc, method=None): medical_record_required = validate_medical_record_required(doc) @@ -100,7 +116,6 @@ def get_date_field(doctype): def get_patient_history_fields(doc): - import json dt = get_patient_history_config_dt(doc.doctype) patient_history_fields = frappe.db.get_value(dt, { 'document_type': doc.doctype }, 'selected_fields') From 02d1491e39951a25b1c502fb9abf337e08a34b2c Mon Sep 17 00:00:00 2001 From: Saqib Ansari Date: Mon, 30 Nov 2020 17:41:38 +0530 Subject: [PATCH 140/477] fix: order summary qty alignment --- erpnext/public/scss/point-of-sale.scss | 1 + .../page/point_of_sale/pos_past_order_summary.js | 16 ++++++++++++++++ 2 files changed, 17 insertions(+) diff --git a/erpnext/public/scss/point-of-sale.scss b/erpnext/public/scss/point-of-sale.scss index f3880935485..f9757384cb8 100644 --- a/erpnext/public/scss/point-of-sale.scss +++ b/erpnext/public/scss/point-of-sale.scss @@ -1067,6 +1067,7 @@ display: flex; text-align: right; margin-left: var(--margin-md); + justify-content: flex-end; > .item-disc { color: var(--dark-green-500); diff --git a/erpnext/selling/page/point_of_sale/pos_past_order_summary.js b/erpnext/selling/page/point_of_sale/pos_past_order_summary.js index 28076db63b1..4b75c0bb73d 100644 --- a/erpnext/selling/page/point_of_sale/pos_past_order_summary.js +++ b/erpnext/selling/page/point_of_sale/pos_past_order_summary.js @@ -333,9 +333,25 @@ erpnext.PointOfSale.PastOrderSummary = class { doc.items.forEach((item, i) => { const item_dom = this.get_item_html(doc, item); this.$items_container.append(item_dom); + this.set_dynamic_rate_header_width(); }); } + set_dynamic_rate_header_width() { + const rate_cols = Array.from(this.$items_container.find(".item-rate-disc")); + this.$items_container.find(".item-rate-disc").css("width", ""); + let max_width = rate_cols.reduce((max_width, elm) => { + if ($(elm).width() > max_width) + max_width = $(elm).width(); + return max_width; + }, 0); + + max_width += 1; + if (max_width == 1) max_width = ""; + + this.$items_container.find(".item-rate-disc").css("width", max_width); + } + attach_payments_info(doc) { this.$payment_container.html(''); doc.payments.forEach(p => { From f6756838ba63075e16ca5c4b3601d2eebe143d33 Mon Sep 17 00:00:00 2001 From: Rucha Mahabal Date: Mon, 30 Nov 2020 17:51:56 +0530 Subject: [PATCH 141/477] fix: patch --- .../doctype/patient_appointment/test_patient_appointment.py | 1 + .../setup_patient_history_settings_for_standard_doctypes.py | 6 +++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/erpnext/healthcare/doctype/patient_appointment/test_patient_appointment.py b/erpnext/healthcare/doctype/patient_appointment/test_patient_appointment.py index eeed157291e..f8b7f7f2f02 100644 --- a/erpnext/healthcare/doctype/patient_appointment/test_patient_appointment.py +++ b/erpnext/healthcare/doctype/patient_appointment/test_patient_appointment.py @@ -148,6 +148,7 @@ def create_healthcare_service_items(): item.item_name = 'Consulting Charges' item.item_group = 'Services' item.is_stock_item = 0 + item.stock_uom = 'Nos' item.save() return item.name diff --git a/erpnext/patches/v13_0/setup_patient_history_settings_for_standard_doctypes.py b/erpnext/patches/v13_0/setup_patient_history_settings_for_standard_doctypes.py index 3332be05613..de08aa26b3b 100644 --- a/erpnext/patches/v13_0/setup_patient_history_settings_for_standard_doctypes.py +++ b/erpnext/patches/v13_0/setup_patient_history_settings_for_standard_doctypes.py @@ -3,7 +3,11 @@ import frappe from erpnext.healthcare.setup import setup_patient_history_settings def execute(): - if 'Healthcare' not in frappe.get_active_domains(): + if "Healthcare" not in frappe.get_active_domains(): return + frappe.reload_doc("healthcare", "doctype", "Patient History Settings") + frappe.reload_doc("healthcare", "doctype", "Patient History Standard Document Type") + frappe.reload_doc("healthcare", "doctype", "Patient History Custom Document Type") + setup_patient_history_settings() \ No newline at end of file From 188e0ecbcb11f994f16a1a1ff9a7fc5abb3bad7d Mon Sep 17 00:00:00 2001 From: Saqib Ansari Date: Mon, 30 Nov 2020 17:53:19 +0530 Subject: [PATCH 142/477] fix: submit order summary center alignment --- .../page/point_of_sale/pos_past_order_summary.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/erpnext/selling/page/point_of_sale/pos_past_order_summary.js b/erpnext/selling/page/point_of_sale/pos_past_order_summary.js index 4b75c0bb73d..eb299763714 100644 --- a/erpnext/selling/page/point_of_sale/pos_past_order_summary.js +++ b/erpnext/selling/page/point_of_sale/pos_past_order_summary.js @@ -299,12 +299,12 @@ erpnext.PointOfSale.PastOrderSummary = class { } load_summary_of(doc, after_submission=false) { - this.toggle_summary_placeholder(false) - after_submission ? - this.$summary_wrapper.css('grid-column', 'span 10 / span 10') : - this.$summary_wrapper.css('grid-column', 'span 6 / span 6') - + this.$component.css('grid-column', 'span 10 / span 10') : + this.$component.css('grid-column', 'span 6 / span 6') + + this.toggle_summary_placeholder(false) + this.doc = doc; this.attach_document_info(doc); From de68f74b4c00fec82bb0ff3a7970e82616002004 Mon Sep 17 00:00:00 2001 From: Shivam Mishra Date: Tue, 1 Dec 2020 12:51:38 +0530 Subject: [PATCH 143/477] chore: update all desk pages --- .../desk_page/accounting/accounting.json | 95 ++++++++++++++++++- .../desk_page/agriculture/agriculture.json | 13 ++- erpnext/assets/desk_page/assets/assets.json | 14 ++- erpnext/buying/desk_page/buying/buying.json | 41 +++++++- erpnext/crm/desk_page/crm/crm.json | 33 ++++++- .../desk_page/education/education.json | 54 ++++++++++- .../erpnext_integrations.json | 9 +- .../erpnext_integrations_settings.json | 7 +- .../desk_page/healthcare/healthcare.json | 42 +++++++- erpnext/hr/desk_page/hr/hr.json | 79 ++++++++++++++- .../loan_management/desk_page/loan/loan.json | 19 +++- .../manufacturing/manufacturing.json | 24 ++++- .../desk_page/non_profit/non_profit.json | 15 ++- .../payroll/desk_page/payroll/payroll.json | 26 ++++- .../projects/desk_page/projects/projects.json | 13 ++- .../desk_page/quality/quality.json | 11 ++- erpnext/selling/desk_page/retail/retail.json | 8 +- .../selling/desk_page/selling/selling.json | 48 +++++++++- .../erpnext_settings/erpnext_settings.json | 2 +- erpnext/setup/desk_page/home/home.json | 36 ++++++- erpnext/stock/desk_page/stock/stock.json | 60 +++++++++++- .../support/desk_page/support/support.json | 12 ++- .../desk_page/utilities/utilities.json | 4 +- 23 files changed, 642 insertions(+), 23 deletions(-) diff --git a/erpnext/accounts/desk_page/accounting/accounting.json b/erpnext/accounts/desk_page/accounting/accounting.json index 2de2492d2a1..ccc51685db9 100644 --- a/erpnext/accounts/desk_page/accounting/accounting.json +++ b/erpnext/accounts/desk_page/accounting/accounting.json @@ -108,6 +108,7 @@ "type": "Card Break" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Company", @@ -117,6 +118,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Chart of Accounts", @@ -126,6 +128,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Accounts Settings", @@ -135,6 +138,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Fiscal Year", @@ -144,6 +148,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Accounting Dimension", @@ -153,6 +158,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Finance Book", @@ -162,6 +168,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Accounting Period", @@ -171,6 +178,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Payment Term", @@ -187,6 +195,7 @@ "type": "Card Break" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Journal Entry", @@ -196,6 +205,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Journal Entry Template", @@ -205,6 +215,7 @@ "type": "Link" }, { + "dependencies": "GL Entry", "hidden": 0, "is_query_report": 1, "label": "General Ledger", @@ -214,6 +225,7 @@ "type": "Link" }, { + "dependencies": "Sales Invoice", "hidden": 0, "is_query_report": 1, "label": "Customer Ledger Summary", @@ -223,6 +235,7 @@ "type": "Link" }, { + "dependencies": "Sales Invoice", "hidden": 0, "is_query_report": 1, "label": "Supplier Ledger Summary", @@ -239,6 +252,7 @@ "type": "Card Break" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Sales Invoice", @@ -248,6 +262,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Customer", @@ -257,6 +272,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Payment Entry", @@ -266,6 +282,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Payment Request", @@ -275,6 +292,7 @@ "type": "Link" }, { + "dependencies": "Sales Invoice", "hidden": 0, "is_query_report": 1, "label": "Accounts Receivable", @@ -284,6 +302,7 @@ "type": "Link" }, { + "dependencies": "Sales Invoice", "hidden": 0, "is_query_report": 1, "label": "Accounts Receivable Summary", @@ -293,6 +312,7 @@ "type": "Link" }, { + "dependencies": "Sales Invoice", "hidden": 0, "is_query_report": 1, "label": "Sales Register", @@ -302,6 +322,7 @@ "type": "Link" }, { + "dependencies": "Sales Invoice", "hidden": 0, "is_query_report": 1, "label": "Item-wise Sales Register", @@ -311,6 +332,7 @@ "type": "Link" }, { + "dependencies": "Sales Invoice", "hidden": 0, "is_query_report": 1, "label": "Sales Order Analysis", @@ -320,6 +342,7 @@ "type": "Link" }, { + "dependencies": "Sales Invoice", "hidden": 0, "is_query_report": 1, "label": "Delivered Items To Be Billed", @@ -336,6 +359,7 @@ "type": "Card Break" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Purchase Invoice", @@ -345,6 +369,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Supplier", @@ -354,6 +379,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Payment Entry", @@ -363,6 +389,7 @@ "type": "Link" }, { + "dependencies": "Purchase Invoice", "hidden": 0, "is_query_report": 1, "label": "Accounts Payable", @@ -372,6 +399,7 @@ "type": "Link" }, { + "dependencies": "Purchase Invoice", "hidden": 0, "is_query_report": 1, "label": "Accounts Payable Summary", @@ -381,6 +409,7 @@ "type": "Link" }, { + "dependencies": "Purchase Invoice", "hidden": 0, "is_query_report": 1, "label": "Purchase Register", @@ -390,6 +419,7 @@ "type": "Link" }, { + "dependencies": "Purchase Invoice", "hidden": 0, "is_query_report": 1, "label": "Item-wise Purchase Register", @@ -399,6 +429,7 @@ "type": "Link" }, { + "dependencies": "Purchase Order", "hidden": 0, "is_query_report": 1, "label": "Purchase Order Analysis", @@ -408,6 +439,7 @@ "type": "Link" }, { + "dependencies": "Purchase Invoice", "hidden": 0, "is_query_report": 1, "label": "Received Items To Be Billed", @@ -424,6 +456,7 @@ "type": "Card Break" }, { + "dependencies": "GL Entry", "hidden": 0, "is_query_report": 1, "label": "Trial Balance for Party", @@ -433,6 +466,7 @@ "type": "Link" }, { + "dependencies": "Journal Entry", "hidden": 0, "is_query_report": 1, "label": "Payment Period Based On Invoice Date", @@ -442,6 +476,7 @@ "type": "Link" }, { + "dependencies": "Sales Invoice", "hidden": 0, "is_query_report": 1, "label": "Sales Partners Commission", @@ -451,6 +486,7 @@ "type": "Link" }, { + "dependencies": "Customer", "hidden": 0, "is_query_report": 1, "label": "Customer Credit Balance", @@ -460,6 +496,7 @@ "type": "Link" }, { + "dependencies": "Sales Invoice", "hidden": 0, "is_query_report": 1, "label": "Sales Payment Summary", @@ -469,6 +506,7 @@ "type": "Link" }, { + "dependencies": "Address", "hidden": 0, "is_query_report": 1, "label": "Address And Contacts", @@ -478,6 +516,7 @@ "type": "Link" }, { + "dependencies": "GL Entry", "hidden": 0, "is_query_report": 1, "label": "DATEV Export", @@ -494,6 +533,7 @@ "type": "Card Break" }, { + "dependencies": "GL Entry", "hidden": 0, "is_query_report": 1, "label": "Trial Balance", @@ -503,6 +543,7 @@ "type": "Link" }, { + "dependencies": "GL Entry", "hidden": 0, "is_query_report": 1, "label": "Profit and Loss Statement", @@ -512,6 +553,7 @@ "type": "Link" }, { + "dependencies": "GL Entry", "hidden": 0, "is_query_report": 1, "label": "Balance Sheet", @@ -521,6 +563,7 @@ "type": "Link" }, { + "dependencies": "GL Entry", "hidden": 0, "is_query_report": 1, "label": "Cash Flow", @@ -530,6 +573,7 @@ "type": "Link" }, { + "dependencies": "GL Entry", "hidden": 0, "is_query_report": 1, "label": "Consolidated Financial Statement", @@ -546,6 +590,7 @@ "type": "Card Break" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Currency", @@ -555,6 +600,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Currency Exchange", @@ -564,6 +610,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Exchange Rate Revaluation", @@ -580,6 +627,7 @@ "type": "Card Break" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Payment Gateway Account", @@ -589,6 +637,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Terms and Conditions Template", @@ -598,6 +647,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Mode of Payment", @@ -614,6 +664,7 @@ "type": "Card Break" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Bank", @@ -623,6 +674,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Bank Account", @@ -632,6 +684,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Bank Clearance", @@ -641,6 +694,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Bank Reconciliation", @@ -650,6 +704,7 @@ "type": "Link" }, { + "dependencies": "GL Entry", "hidden": 0, "is_query_report": 1, "label": "Bank Reconciliation Statement", @@ -659,6 +714,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Bank Statement Transaction Entry", @@ -668,6 +724,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Bank Statement Settings", @@ -684,6 +741,7 @@ "type": "Card Break" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Subscription Plan", @@ -693,6 +751,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Subscription", @@ -702,6 +761,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Subscription Settings", @@ -718,6 +778,7 @@ "type": "Card Break" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "GST Settings", @@ -727,6 +788,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "GST HSN Code", @@ -736,6 +798,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 1, "label": "GSTR-1", @@ -745,6 +808,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 1, "label": "GSTR-2", @@ -754,6 +818,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "GSTR 3B Report", @@ -763,6 +828,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 1, "label": "GST Sales Register", @@ -772,6 +838,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 1, "label": "GST Purchase Register", @@ -781,6 +848,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 1, "label": "GST Itemised Sales Register", @@ -790,6 +858,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 1, "label": "GST Itemised Purchase Register", @@ -799,6 +868,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "C-Form", @@ -808,6 +878,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Lower Deduction Certificate", @@ -824,6 +895,7 @@ "type": "Card Break" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Shareholder", @@ -833,6 +905,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Share Transfer", @@ -842,6 +915,7 @@ "type": "Link" }, { + "dependencies": "Share Transfer", "hidden": 0, "is_query_report": 1, "label": "Share Ledger", @@ -851,6 +925,7 @@ "type": "Link" }, { + "dependencies": "Share Transfer", "hidden": 0, "is_query_report": 1, "label": "Share Balance", @@ -867,6 +942,7 @@ "type": "Card Break" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Chart of Cost Centers", @@ -876,6 +952,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Budget", @@ -885,6 +962,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Accounting Dimension", @@ -894,6 +972,7 @@ "type": "Link" }, { + "dependencies": "Cost Center", "hidden": 0, "is_query_report": 1, "label": "Budget Variance Report", @@ -903,6 +982,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Monthly Distribution", @@ -919,6 +999,7 @@ "type": "Card Break" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Opening Invoice Creation Tool", @@ -928,6 +1009,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Chart of Accounts Importer", @@ -937,6 +1019,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Period Closing Voucher", @@ -953,6 +1036,7 @@ "type": "Card Break" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Sales Taxes and Charges Template", @@ -962,6 +1046,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Purchase Taxes and Charges Template", @@ -971,6 +1056,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Item Tax Template", @@ -980,6 +1066,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Tax Category", @@ -989,6 +1076,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Tax Rule", @@ -998,6 +1086,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Tax Withholding Category", @@ -1014,6 +1103,7 @@ "type": "Card Break" }, { + "dependencies": "Sales Invoice", "hidden": 0, "is_query_report": 1, "label": "Gross Profit", @@ -1023,6 +1113,7 @@ "type": "Link" }, { + "dependencies": "GL Entry", "hidden": 0, "is_query_report": 1, "label": "Profitability Analysis", @@ -1032,6 +1123,7 @@ "type": "Link" }, { + "dependencies": "Sales Invoice", "hidden": 0, "is_query_report": 1, "label": "Sales Invoice Trends", @@ -1041,6 +1133,7 @@ "type": "Link" }, { + "dependencies": "Purchase Invoice", "hidden": 0, "is_query_report": 1, "label": "Purchase Invoice Trends", @@ -1050,7 +1143,7 @@ "type": "Link" } ], - "modified": "2020-11-17 13:18:37.583879", + "modified": "2020-12-01 12:34:03.892648", "modified_by": "Administrator", "module": "Accounts", "name": "Accounting", diff --git a/erpnext/agriculture/desk_page/agriculture/agriculture.json b/erpnext/agriculture/desk_page/agriculture/agriculture.json index 145ef07c105..38da1c43e8e 100644 --- a/erpnext/agriculture/desk_page/agriculture/agriculture.json +++ b/erpnext/agriculture/desk_page/agriculture/agriculture.json @@ -38,6 +38,7 @@ "type": "Card Break" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Crop", @@ -47,6 +48,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Crop Cycle", @@ -56,6 +58,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Location", @@ -72,6 +75,7 @@ "type": "Card Break" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Plant Analysis", @@ -81,6 +85,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Soil Analysis", @@ -90,6 +95,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Water Analysis", @@ -99,6 +105,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Soil Texture", @@ -108,6 +115,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Weather", @@ -117,6 +125,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Agriculture Analysis Criteria", @@ -133,6 +142,7 @@ "type": "Card Break" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Disease", @@ -142,6 +152,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Fertilizer", @@ -151,7 +162,7 @@ "type": "Link" } ], - "modified": "2020-11-17 13:18:42.501139", + "modified": "2020-12-01 12:33:59.698335", "modified_by": "Administrator", "module": "Agriculture", "name": "Agriculture", diff --git a/erpnext/assets/desk_page/assets/assets.json b/erpnext/assets/desk_page/assets/assets.json index 66f448fc9c2..54572156d77 100644 --- a/erpnext/assets/desk_page/assets/assets.json +++ b/erpnext/assets/desk_page/assets/assets.json @@ -43,6 +43,7 @@ "type": "Card Break" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Asset", @@ -52,6 +53,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Location", @@ -61,6 +63,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Asset Category", @@ -70,6 +73,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Asset Movement", @@ -86,6 +90,7 @@ "type": "Card Break" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Asset Maintenance Team", @@ -95,6 +100,7 @@ "type": "Link" }, { + "dependencies": "Asset Maintenance Team", "hidden": 0, "is_query_report": 0, "label": "Asset Maintenance", @@ -104,6 +110,7 @@ "type": "Link" }, { + "dependencies": "Asset Maintenance", "hidden": 0, "is_query_report": 0, "label": "Asset Maintenance Log", @@ -113,6 +120,7 @@ "type": "Link" }, { + "dependencies": "Asset", "hidden": 0, "is_query_report": 0, "label": "Asset Value Adjustment", @@ -122,6 +130,7 @@ "type": "Link" }, { + "dependencies": "Asset", "hidden": 0, "is_query_report": 0, "label": "Asset Repair", @@ -138,6 +147,7 @@ "type": "Card Break" }, { + "dependencies": "Asset", "hidden": 0, "is_query_report": 1, "label": "Asset Depreciation Ledger", @@ -147,6 +157,7 @@ "type": "Link" }, { + "dependencies": "Asset", "hidden": 0, "is_query_report": 1, "label": "Asset Depreciations and Balances", @@ -156,6 +167,7 @@ "type": "Link" }, { + "dependencies": "Asset Maintenance", "hidden": 0, "is_query_report": 0, "label": "Asset Maintenance", @@ -165,7 +177,7 @@ "type": "Link" } ], - "modified": "2020-11-17 13:18:41.714472", + "modified": "2020-12-01 12:34:00.417242", "modified_by": "Administrator", "module": "Assets", "name": "Assets", diff --git a/erpnext/buying/desk_page/buying/buying.json b/erpnext/buying/desk_page/buying/buying.json index 5b85e6ab101..e25554c7963 100644 --- a/erpnext/buying/desk_page/buying/buying.json +++ b/erpnext/buying/desk_page/buying/buying.json @@ -70,6 +70,7 @@ "type": "Card Break" }, { + "dependencies": "Item", "hidden": 0, "is_query_report": 0, "label": "Material Request", @@ -79,6 +80,7 @@ "type": "Link" }, { + "dependencies": "Item, Supplier", "hidden": 0, "is_query_report": 0, "label": "Purchase Order", @@ -88,6 +90,7 @@ "type": "Link" }, { + "dependencies": "Item, Supplier", "hidden": 0, "is_query_report": 0, "label": "Purchase Invoice", @@ -97,6 +100,7 @@ "type": "Link" }, { + "dependencies": "Item, Supplier", "hidden": 0, "is_query_report": 0, "label": "Request for Quotation", @@ -106,6 +110,7 @@ "type": "Link" }, { + "dependencies": "Item, Supplier", "hidden": 0, "is_query_report": 0, "label": "Supplier Quotation", @@ -122,6 +127,7 @@ "type": "Card Break" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Item", @@ -131,6 +137,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Item Price", @@ -140,6 +147,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Price List", @@ -149,6 +157,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Product Bundle", @@ -158,6 +167,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Item Group", @@ -167,6 +177,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Promotional Scheme", @@ -176,6 +187,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Pricing Rule", @@ -192,6 +204,7 @@ "type": "Card Break" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Buying Settings", @@ -201,6 +214,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Purchase Taxes and Charges Template", @@ -210,6 +224,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Terms and Conditions Template", @@ -226,6 +241,7 @@ "type": "Card Break" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Supplier", @@ -235,6 +251,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Supplier Group", @@ -244,6 +261,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Contact", @@ -253,6 +271,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Address", @@ -269,6 +288,7 @@ "type": "Card Break" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Supplier Scorecard", @@ -278,6 +298,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Supplier Scorecard Variable", @@ -287,6 +308,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Supplier Scorecard Criteria", @@ -296,6 +318,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Supplier Scorecard Standing", @@ -312,6 +335,7 @@ "type": "Card Break" }, { + "dependencies": "", "hidden": 0, "is_query_report": 1, "label": "Purchase Analytics", @@ -321,6 +345,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 1, "label": "Purchase Order Analysis", @@ -330,6 +355,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 1, "label": "Supplier-Wise Sales Analytics", @@ -339,6 +365,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 1, "label": "Items to Order and Receive", @@ -348,6 +375,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 1, "label": "Purchase Order Trends", @@ -357,6 +385,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 1, "label": "Procurement Tracker", @@ -373,6 +402,7 @@ "type": "Card Break" }, { + "dependencies": "", "hidden": 0, "is_query_report": 1, "label": "Items To Be Requested", @@ -382,6 +412,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 1, "label": "Item-wise Purchase History", @@ -391,6 +422,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 1, "label": "Purchase Receipt Trends", @@ -400,6 +432,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 1, "label": "Purchase Invoice Trends", @@ -409,6 +442,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 1, "label": "Subcontracted Raw Materials To Be Transferred", @@ -418,6 +452,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 1, "label": "Subcontracted Item To Be Received", @@ -427,6 +462,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 1, "label": "Supplier Quotation Comparison", @@ -436,6 +472,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 1, "label": "Material Requests for which Supplier Quotations are not created", @@ -445,6 +482,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 1, "label": "Supplier Addresses And Contacts", @@ -461,6 +499,7 @@ "type": "Card Break" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Import Supplier Invoice", @@ -470,7 +509,7 @@ "type": "Link" } ], - "modified": "2020-11-17 13:18:43.304970", + "modified": "2020-12-01 12:33:59.349265", "modified_by": "Administrator", "module": "Buying", "name": "Buying", diff --git a/erpnext/crm/desk_page/crm/crm.json b/erpnext/crm/desk_page/crm/crm.json index fd97ba6c0cc..8679065bcaa 100644 --- a/erpnext/crm/desk_page/crm/crm.json +++ b/erpnext/crm/desk_page/crm/crm.json @@ -52,6 +52,7 @@ "type": "Card Break" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Lead", @@ -61,6 +62,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Opportunity", @@ -70,6 +72,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Customer", @@ -79,6 +82,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Contact", @@ -88,6 +92,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Communication", @@ -97,6 +102,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Lead Source", @@ -106,6 +112,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Contract", @@ -115,6 +122,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Appointment", @@ -124,6 +132,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Newsletter", @@ -140,6 +149,7 @@ "type": "Card Break" }, { + "dependencies": "Lead", "hidden": 0, "is_query_report": 1, "label": "Lead Details", @@ -149,6 +159,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Sales Funnel", @@ -158,6 +169,7 @@ "type": "Link" }, { + "dependencies": "Lead", "hidden": 0, "is_query_report": 1, "label": "Prospects Engaged But Not Converted", @@ -167,6 +179,7 @@ "type": "Link" }, { + "dependencies": "Opportunity", "hidden": 0, "is_query_report": 1, "label": "First Response Time for Opportunity", @@ -176,6 +189,7 @@ "type": "Link" }, { + "dependencies": "Sales Order", "hidden": 0, "is_query_report": 1, "label": "Inactive Customers", @@ -185,6 +199,7 @@ "type": "Link" }, { + "dependencies": "Lead", "hidden": 0, "is_query_report": 1, "label": "Campaign Efficiency", @@ -194,6 +209,7 @@ "type": "Link" }, { + "dependencies": "Lead", "hidden": 0, "is_query_report": 1, "label": "Lead Owner Efficiency", @@ -210,6 +226,7 @@ "type": "Card Break" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Maintenance Schedule", @@ -219,6 +236,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Maintenance Visit", @@ -228,6 +246,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Warranty Claim", @@ -244,6 +263,7 @@ "type": "Card Break" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Campaign", @@ -253,6 +273,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Email Campaign", @@ -262,6 +283,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Social Media Post", @@ -278,6 +300,7 @@ "type": "Card Break" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Customer Group", @@ -287,6 +310,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Territory", @@ -296,6 +320,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Sales Person", @@ -305,6 +330,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "SMS Center", @@ -314,6 +340,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "SMS Log", @@ -323,6 +350,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "SMS Settings", @@ -332,6 +360,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Email Group", @@ -341,6 +370,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Twitter Settings", @@ -350,6 +380,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "LinkedIn Settings", @@ -359,7 +390,7 @@ "type": "Link" } ], - "modified": "2020-11-17 13:18:40.216301", + "modified": "2020-12-01 12:34:01.909417", "modified_by": "Administrator", "module": "CRM", "name": "CRM", diff --git a/erpnext/education/desk_page/education/education.json b/erpnext/education/desk_page/education/education.json index 06d7797933a..a4bdb21ae68 100644 --- a/erpnext/education/desk_page/education/education.json +++ b/erpnext/education/desk_page/education/education.json @@ -93,6 +93,7 @@ "type": "Card Break" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Student", @@ -102,6 +103,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Instructor", @@ -111,6 +113,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Guardian", @@ -120,6 +123,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Student Group", @@ -129,6 +133,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Student Log", @@ -145,6 +150,7 @@ "type": "Card Break" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Program", @@ -154,6 +160,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Course", @@ -163,6 +170,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Topic", @@ -172,6 +180,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Room", @@ -188,6 +197,7 @@ "type": "Card Break" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Article", @@ -197,6 +207,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Video", @@ -206,6 +217,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Quiz", @@ -222,6 +234,7 @@ "type": "Card Break" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Education Settings", @@ -231,6 +244,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Student Category", @@ -240,6 +254,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Student Batch Name", @@ -249,6 +264,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Grading Scale", @@ -258,6 +274,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Academic Term", @@ -267,6 +284,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Academic Year", @@ -283,6 +301,7 @@ "type": "Card Break" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Student Applicant", @@ -292,6 +311,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Student Admission", @@ -301,6 +321,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Program Enrollment", @@ -310,6 +331,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Course Enrollment", @@ -326,6 +348,7 @@ "type": "Card Break" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Fee Structure", @@ -335,6 +358,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Fee Category", @@ -344,6 +368,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Fee Schedule", @@ -353,6 +378,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Fees", @@ -362,6 +388,7 @@ "type": "Link" }, { + "dependencies": "Fees", "hidden": 0, "is_query_report": 1, "label": "Student Fee Collection Report", @@ -371,6 +398,7 @@ "type": "Link" }, { + "dependencies": "Fees", "hidden": 0, "is_query_report": 1, "label": "Program wise Fee Collection Report", @@ -387,6 +415,7 @@ "type": "Card Break" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Course Schedule", @@ -396,6 +425,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Course Scheduling Tool", @@ -412,6 +442,7 @@ "type": "Card Break" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Student Attendance", @@ -421,6 +452,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Student Leave Application", @@ -430,6 +462,7 @@ "type": "Link" }, { + "dependencies": "Student Attendance", "hidden": 0, "is_query_report": 1, "label": "Student Monthly Attendance Sheet", @@ -439,6 +472,7 @@ "type": "Link" }, { + "dependencies": "Student Attendance", "hidden": 0, "is_query_report": 1, "label": "Absent Student Report", @@ -448,6 +482,7 @@ "type": "Link" }, { + "dependencies": "Student Attendance", "hidden": 0, "is_query_report": 1, "label": "Student Batch-Wise Attendance", @@ -464,6 +499,7 @@ "type": "Card Break" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Course Enrollment", @@ -473,6 +509,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Course Activity", @@ -482,6 +519,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Quiz Activity", @@ -498,6 +536,7 @@ "type": "Card Break" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Assessment Plan", @@ -507,6 +546,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Assessment Group", @@ -516,6 +556,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Assessment Result", @@ -525,6 +566,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Assessment Criteria", @@ -541,6 +583,7 @@ "type": "Card Break" }, { + "dependencies": "Assessment Result", "hidden": 0, "is_query_report": 1, "label": "Course wise Assessment Report", @@ -550,6 +593,7 @@ "type": "Link" }, { + "dependencies": "Assessment Result", "hidden": 0, "is_query_report": 1, "label": "Final Assessment Grades", @@ -559,6 +603,7 @@ "type": "Link" }, { + "dependencies": "Assessment Plan", "hidden": 0, "is_query_report": 1, "label": "Assessment Plan Status", @@ -568,6 +613,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Student Report Generation Tool", @@ -584,6 +630,7 @@ "type": "Card Break" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Student Attendance Tool", @@ -593,6 +640,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Assessment Result Tool", @@ -602,6 +650,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Student Group Creation Tool", @@ -611,6 +660,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Program Enrollment Tool", @@ -620,6 +670,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Course Scheduling Tool", @@ -636,6 +687,7 @@ "type": "Card Break" }, { + "dependencies": "Program Enrollment", "hidden": 0, "is_query_report": 1, "label": "Student and Guardian Contact Details", @@ -645,7 +697,7 @@ "type": "Link" } ], - "modified": "2020-11-17 13:18:40.981880", + "modified": "2020-12-01 12:34:01.016251", "modified_by": "Administrator", "module": "Education", "name": "Education", diff --git a/erpnext/erpnext_integrations/desk_page/erpnext_integrations/erpnext_integrations.json b/erpnext/erpnext_integrations/desk_page/erpnext_integrations/erpnext_integrations.json index df4ed76d473..06ae020861b 100644 --- a/erpnext/erpnext_integrations/desk_page/erpnext_integrations/erpnext_integrations.json +++ b/erpnext/erpnext_integrations/desk_page/erpnext_integrations/erpnext_integrations.json @@ -38,6 +38,7 @@ "type": "Card Break" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Woocommerce Settings", @@ -47,6 +48,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Amazon MWS Settings", @@ -56,6 +58,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Shopify Settings", @@ -72,6 +75,7 @@ "type": "Card Break" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "GoCardless Settings", @@ -81,6 +85,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "M-Pesa Settings", @@ -97,6 +102,7 @@ "type": "Card Break" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Plaid Settings", @@ -106,6 +112,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Exotel Settings", @@ -115,7 +122,7 @@ "type": "Link" } ], - "modified": "2020-11-17 13:18:38.150378", + "modified": "2020-12-01 12:34:03.534985", "modified_by": "Administrator", "module": "ERPNext Integrations", "name": "ERPNext Integrations", diff --git a/erpnext/erpnext_integrations/desk_page/erpnext_integrations_settings/erpnext_integrations_settings.json b/erpnext/erpnext_integrations/desk_page/erpnext_integrations_settings/erpnext_integrations_settings.json index 0150a0d5305..11a8fd41457 100644 --- a/erpnext/erpnext_integrations/desk_page/erpnext_integrations_settings/erpnext_integrations_settings.json +++ b/erpnext/erpnext_integrations/desk_page/erpnext_integrations_settings/erpnext_integrations_settings.json @@ -28,6 +28,7 @@ "type": "Card Break" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Woocommerce Settings", @@ -37,6 +38,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Shopify Settings", @@ -46,6 +48,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Amazon MWS Settings", @@ -55,6 +58,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Plaid Settings", @@ -64,6 +68,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Exotel Settings", @@ -73,7 +78,7 @@ "type": "Link" } ], - "modified": "2020-11-17 13:18:36.389137", + "modified": "2020-12-01 12:34:05.074849", "modified_by": "Administrator", "module": "ERPNext Integrations", "name": "ERPNext Integrations Settings", diff --git a/erpnext/healthcare/desk_page/healthcare/healthcare.json b/erpnext/healthcare/desk_page/healthcare/healthcare.json index baf7ad86e62..7eec79fc515 100644 --- a/erpnext/healthcare/desk_page/healthcare/healthcare.json +++ b/erpnext/healthcare/desk_page/healthcare/healthcare.json @@ -74,6 +74,7 @@ "type": "Card Break" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Patient", @@ -83,6 +84,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Healthcare Practitioner", @@ -92,6 +94,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Practitioner Schedule", @@ -101,6 +104,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Medical Department", @@ -110,6 +114,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Healthcare Service Unit Type", @@ -119,6 +124,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Healthcare Service Unit", @@ -128,6 +134,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Medical Code Standard", @@ -137,6 +144,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Medical Code", @@ -153,6 +161,7 @@ "type": "Card Break" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Appointment Type", @@ -162,6 +171,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Clinical Procedure Template", @@ -171,6 +181,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Prescription Dosage", @@ -180,6 +191,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Prescription Duration", @@ -189,6 +201,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Antibiotic", @@ -205,6 +218,7 @@ "type": "Card Break" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Patient Appointment", @@ -214,6 +228,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Clinical Procedure", @@ -223,6 +238,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Patient Encounter", @@ -232,6 +248,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Vital Signs", @@ -241,6 +258,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Complaint", @@ -250,6 +268,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Diagnosis", @@ -259,6 +278,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Fee Validity", @@ -275,6 +295,7 @@ "type": "Card Break" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Healthcare Settings", @@ -291,6 +312,7 @@ "type": "Card Break" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Lab Test Template", @@ -300,6 +322,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Lab Test Sample", @@ -309,6 +332,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Lab Test UOM", @@ -318,6 +342,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Sensitivity", @@ -334,6 +359,7 @@ "type": "Card Break" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Lab Test", @@ -343,6 +369,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Sample Collection", @@ -352,6 +379,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Dosage Form", @@ -368,6 +396,7 @@ "type": "Card Break" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Exercise Type", @@ -377,6 +406,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Therapy Type", @@ -386,6 +416,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Therapy Plan", @@ -395,6 +426,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Therapy Session", @@ -404,6 +436,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Patient Assessment Template", @@ -413,6 +446,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Patient Assessment", @@ -429,6 +463,7 @@ "type": "Card Break" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Patient History", @@ -438,6 +473,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Patient Progress", @@ -447,6 +483,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Patient Medical Record", @@ -456,6 +493,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Inpatient Record", @@ -472,6 +510,7 @@ "type": "Card Break" }, { + "dependencies": "", "hidden": 0, "is_query_report": 1, "label": "Patient Appointment Analytics", @@ -481,6 +520,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 1, "label": "Lab Test Report", @@ -490,7 +530,7 @@ "type": "Link" } ], - "modified": "2020-11-17 13:18:36.771243", + "modified": "2020-12-01 12:34:04.799604", "modified_by": "Administrator", "module": "Healthcare", "name": "Healthcare", diff --git a/erpnext/hr/desk_page/hr/hr.json b/erpnext/hr/desk_page/hr/hr.json index 787dbd35dd6..eecdd985854 100644 --- a/erpnext/hr/desk_page/hr/hr.json +++ b/erpnext/hr/desk_page/hr/hr.json @@ -103,6 +103,7 @@ "type": "Card Break" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Employee", @@ -112,6 +113,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Employment Type", @@ -121,6 +123,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Branch", @@ -130,6 +133,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Department", @@ -139,6 +143,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Designation", @@ -148,6 +153,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Employee Grade", @@ -157,6 +163,7 @@ "type": "Link" }, { + "dependencies": "Employee", "hidden": 0, "is_query_report": 0, "label": "Employee Group", @@ -166,6 +173,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Employee Health Insurance", @@ -182,6 +190,7 @@ "type": "Card Break" }, { + "dependencies": "Job Applicant", "hidden": 0, "is_query_report": 0, "label": "Employee Onboarding", @@ -191,6 +200,7 @@ "type": "Link" }, { + "dependencies": "Employee", "hidden": 0, "is_query_report": 0, "label": "Employee Skill Map", @@ -200,6 +210,7 @@ "type": "Link" }, { + "dependencies": "Employee", "hidden": 0, "is_query_report": 0, "label": "Employee Promotion", @@ -209,6 +220,7 @@ "type": "Link" }, { + "dependencies": "Employee", "hidden": 0, "is_query_report": 0, "label": "Employee Transfer", @@ -218,6 +230,7 @@ "type": "Link" }, { + "dependencies": "Employee", "hidden": 0, "is_query_report": 0, "label": "Employee Separation", @@ -227,6 +240,7 @@ "type": "Link" }, { + "dependencies": "Employee", "hidden": 0, "is_query_report": 0, "label": "Employee Onboarding Template", @@ -236,6 +250,7 @@ "type": "Link" }, { + "dependencies": "Employee", "hidden": 0, "is_query_report": 0, "label": "Employee Separation Template", @@ -252,6 +267,7 @@ "type": "Card Break" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Shift Type", @@ -261,6 +277,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Shift Request", @@ -270,6 +287,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Shift Assignment", @@ -286,6 +304,7 @@ "type": "Card Break" }, { + "dependencies": "Employee", "hidden": 0, "is_query_report": 0, "label": "Leave Application", @@ -295,6 +314,7 @@ "type": "Link" }, { + "dependencies": "Employee", "hidden": 0, "is_query_report": 0, "label": "Leave Allocation", @@ -304,6 +324,7 @@ "type": "Link" }, { + "dependencies": "Leave Type", "hidden": 0, "is_query_report": 0, "label": "Leave Policy", @@ -313,6 +334,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Leave Period", @@ -322,6 +344,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Leave Type", @@ -331,6 +354,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Holiday List", @@ -340,6 +364,7 @@ "type": "Link" }, { + "dependencies": "Employee", "hidden": 0, "is_query_report": 0, "label": "Compensatory Leave Request", @@ -349,6 +374,7 @@ "type": "Link" }, { + "dependencies": "Employee", "hidden": 0, "is_query_report": 0, "label": "Leave Encashment", @@ -358,6 +384,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Leave Block List", @@ -367,6 +394,7 @@ "type": "Link" }, { + "dependencies": "Leave Application", "hidden": 0, "is_query_report": 1, "label": "Employee Leave Balance", @@ -383,6 +411,7 @@ "type": "Card Break" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Salary Structure", @@ -392,6 +421,7 @@ "type": "Link" }, { + "dependencies": "Salary Structure, Employee", "hidden": 0, "is_query_report": 0, "label": "Salary Structure Assignment", @@ -401,6 +431,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Payroll Entry", @@ -410,6 +441,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Salary Slip", @@ -419,6 +451,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Payroll Period", @@ -428,6 +461,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Income Tax Slab", @@ -437,6 +471,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Salary Component", @@ -446,6 +481,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Additional Salary", @@ -455,6 +491,7 @@ "type": "Link" }, { + "dependencies": "Employee", "hidden": 0, "is_query_report": 0, "label": "Retention Bonus", @@ -464,6 +501,7 @@ "type": "Link" }, { + "dependencies": "Employee", "hidden": 0, "is_query_report": 0, "label": "Employee Incentive", @@ -473,6 +511,7 @@ "type": "Link" }, { + "dependencies": "Salary Slip", "hidden": 0, "is_query_report": 1, "label": "Salary Register", @@ -489,6 +528,7 @@ "type": "Card Break" }, { + "dependencies": "Employee", "hidden": 0, "is_query_report": 0, "label": "Employee Attendance Tool", @@ -498,6 +538,7 @@ "type": "Link" }, { + "dependencies": "Employee", "hidden": 0, "is_query_report": 0, "label": "Attendance", @@ -507,6 +548,7 @@ "type": "Link" }, { + "dependencies": "Employee", "hidden": 0, "is_query_report": 0, "label": "Attendance Request", @@ -516,6 +558,7 @@ "type": "Link" }, { + "dependencies": "Employee", "hidden": 0, "is_query_report": 0, "label": "Upload Attendance", @@ -525,6 +568,7 @@ "type": "Link" }, { + "dependencies": "Employee", "hidden": 0, "is_query_report": 0, "label": "Employee Checkin", @@ -534,6 +578,7 @@ "type": "Link" }, { + "dependencies": "Attendance", "hidden": 0, "is_query_report": 1, "label": "Monthly Attendance Sheet", @@ -550,6 +595,7 @@ "type": "Card Break" }, { + "dependencies": "Employee", "hidden": 0, "is_query_report": 0, "label": "Expense Claim", @@ -559,6 +605,7 @@ "type": "Link" }, { + "dependencies": "Employee", "hidden": 0, "is_query_report": 0, "label": "Employee Advance", @@ -575,6 +622,7 @@ "type": "Card Break" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "HR Settings", @@ -584,6 +632,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Daily Work Summary Group", @@ -593,6 +642,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Team Updates", @@ -609,6 +659,7 @@ "type": "Card Break" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Vehicle", @@ -618,6 +669,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Vehicle Log", @@ -627,6 +679,7 @@ "type": "Link" }, { + "dependencies": "Vehicle", "hidden": 0, "is_query_report": 1, "label": "Vehicle Expenses", @@ -643,6 +696,7 @@ "type": "Card Break" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Job Opening", @@ -652,6 +706,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Job Applicant", @@ -661,6 +716,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Job Offer", @@ -670,6 +726,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Staffing Plan", @@ -686,6 +743,7 @@ "type": "Card Break" }, { + "dependencies": "Employee", "hidden": 0, "is_query_report": 0, "label": "Loan Application", @@ -695,6 +753,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Loan", @@ -704,6 +763,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Loan Type", @@ -720,6 +780,7 @@ "type": "Card Break" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Training Program", @@ -729,6 +790,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Training Event", @@ -738,6 +800,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Training Result", @@ -747,6 +810,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Training Feedback", @@ -763,6 +827,7 @@ "type": "Card Break" }, { + "dependencies": "Employee", "hidden": 0, "is_query_report": 1, "label": "Employee Birthday", @@ -772,6 +837,7 @@ "type": "Link" }, { + "dependencies": "Employee", "hidden": 0, "is_query_report": 1, "label": "Employees working on a holiday", @@ -788,6 +854,7 @@ "type": "Card Break" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Appraisal", @@ -797,6 +864,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Appraisal Template", @@ -806,6 +874,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Energy Point Rule", @@ -815,6 +884,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Energy Point Log", @@ -831,6 +901,7 @@ "type": "Card Break" }, { + "dependencies": "Employee", "hidden": 0, "is_query_report": 0, "label": "Employee Tax Exemption Declaration", @@ -840,6 +911,7 @@ "type": "Link" }, { + "dependencies": "Employee", "hidden": 0, "is_query_report": 0, "label": "Employee Tax Exemption Proof Submission", @@ -849,6 +921,7 @@ "type": "Link" }, { + "dependencies": "Employee, Payroll Period", "hidden": 0, "is_query_report": 0, "label": "Employee Other Income", @@ -858,6 +931,7 @@ "type": "Link" }, { + "dependencies": "Employee", "hidden": 0, "is_query_report": 0, "label": "Employee Benefit Application", @@ -867,6 +941,7 @@ "type": "Link" }, { + "dependencies": "Employee", "hidden": 0, "is_query_report": 0, "label": "Employee Benefit Claim", @@ -876,6 +951,7 @@ "type": "Link" }, { + "dependencies": "Employee", "hidden": 0, "is_query_report": 0, "label": "Employee Tax Exemption Category", @@ -885,6 +961,7 @@ "type": "Link" }, { + "dependencies": "Employee", "hidden": 0, "is_query_report": 0, "label": "Employee Tax Exemption Sub Category", @@ -894,7 +971,7 @@ "type": "Link" } ], - "modified": "2020-11-17 13:18:43.807222", + "modified": "2020-12-01 12:33:58.806820", "modified_by": "Administrator", "module": "HR", "name": "HR", diff --git a/erpnext/loan_management/desk_page/loan/loan.json b/erpnext/loan_management/desk_page/loan/loan.json index 0c9bd358e9f..57b47288c7a 100644 --- a/erpnext/loan_management/desk_page/loan/loan.json +++ b/erpnext/loan_management/desk_page/loan/loan.json @@ -48,6 +48,7 @@ "type": "Card Break" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Loan Type", @@ -57,6 +58,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Loan Application", @@ -66,6 +68,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Loan", @@ -82,6 +85,7 @@ "type": "Card Break" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Process Loan Security Shortfall", @@ -91,6 +95,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Process Loan Interest Accrual", @@ -107,6 +112,7 @@ "type": "Card Break" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Loan Disbursement", @@ -116,6 +122,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Loan Repayment", @@ -125,6 +132,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Loan Write Off", @@ -134,6 +142,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Loan Interest Accrual", @@ -150,6 +159,7 @@ "type": "Card Break" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Loan Security Type", @@ -159,6 +169,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Loan Security Price", @@ -168,6 +179,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Loan Security", @@ -177,6 +189,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Loan Security Pledge", @@ -186,6 +199,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Loan Security Unpledge", @@ -195,6 +209,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Loan Security Shortfall", @@ -211,6 +226,7 @@ "type": "Card Break" }, { + "dependencies": "", "hidden": 0, "is_query_report": 1, "label": "Loan Repayment and Closure", @@ -220,6 +236,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 1, "label": "Loan Security Status", @@ -229,7 +246,7 @@ "type": "Link" } ], - "modified": "2020-11-17 13:18:39.173544", + "modified": "2020-12-01 12:34:02.390976", "modified_by": "Administrator", "module": "Loan Management", "name": "Loan", diff --git a/erpnext/manufacturing/desk_page/manufacturing/manufacturing.json b/erpnext/manufacturing/desk_page/manufacturing/manufacturing.json index 4eb6f2809f0..323f5bfc3dd 100644 --- a/erpnext/manufacturing/desk_page/manufacturing/manufacturing.json +++ b/erpnext/manufacturing/desk_page/manufacturing/manufacturing.json @@ -52,6 +52,7 @@ "type": "Card Break" }, { + "dependencies": "Item, BOM", "hidden": 0, "is_query_report": 0, "label": "Work Order", @@ -61,6 +62,7 @@ "type": "Link" }, { + "dependencies": "Item, BOM", "hidden": 0, "is_query_report": 0, "label": "Production Plan", @@ -70,6 +72,7 @@ "type": "Link" }, { + "dependencies": "Item", "hidden": 0, "is_query_report": 0, "label": "Stock Entry", @@ -79,6 +82,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Job Card", @@ -88,6 +92,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Downtime Entry", @@ -104,6 +109,7 @@ "type": "Card Break" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Item", @@ -113,6 +119,7 @@ "type": "Link" }, { + "dependencies": "Item", "hidden": 0, "is_query_report": 0, "label": "Bill of Materials", @@ -122,6 +129,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Workstation", @@ -131,6 +139,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Operation", @@ -140,6 +149,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Routing", @@ -156,6 +166,7 @@ "type": "Card Break" }, { + "dependencies": "Work Order", "hidden": 0, "is_query_report": 1, "label": "Production Planning Report", @@ -165,6 +176,7 @@ "type": "Link" }, { + "dependencies": "Work Order", "hidden": 0, "is_query_report": 1, "label": "Work Order Summary", @@ -174,6 +186,7 @@ "type": "Link" }, { + "dependencies": "Quality Inspection", "hidden": 0, "is_query_report": 1, "label": "Quality Inspection Summary", @@ -183,6 +196,7 @@ "type": "Link" }, { + "dependencies": "Downtime Entry", "hidden": 0, "is_query_report": 1, "label": "Downtime Analysis", @@ -192,6 +206,7 @@ "type": "Link" }, { + "dependencies": "Job Card", "hidden": 0, "is_query_report": 1, "label": "Job Card Summary", @@ -201,6 +216,7 @@ "type": "Link" }, { + "dependencies": "BOM", "hidden": 0, "is_query_report": 1, "label": "BOM Search", @@ -210,6 +226,7 @@ "type": "Link" }, { + "dependencies": "BOM", "hidden": 0, "is_query_report": 1, "label": "BOM Stock Report", @@ -219,6 +236,7 @@ "type": "Link" }, { + "dependencies": "Work Order", "hidden": 0, "is_query_report": 1, "label": "Production Analytics", @@ -228,6 +246,7 @@ "type": "Link" }, { + "dependencies": "BOM", "hidden": 0, "is_query_report": 1, "label": "BOM Operations Time", @@ -244,6 +263,7 @@ "type": "Card Break" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "BOM Update Tool", @@ -253,6 +273,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "BOM Comparison Tool", @@ -269,6 +290,7 @@ "type": "Card Break" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Manufacturing Settings", @@ -278,7 +300,7 @@ "type": "Link" } ], - "modified": "2020-11-17 13:18:44.426761", + "modified": "2020-12-01 12:33:58.367406", "modified_by": "Administrator", "module": "Manufacturing", "name": "Manufacturing", diff --git a/erpnext/non_profit/desk_page/non_profit/non_profit.json b/erpnext/non_profit/desk_page/non_profit/non_profit.json index 43262503550..1d5292a9c60 100644 --- a/erpnext/non_profit/desk_page/non_profit/non_profit.json +++ b/erpnext/non_profit/desk_page/non_profit/non_profit.json @@ -53,6 +53,7 @@ "type": "Card Break" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Loan Type", @@ -62,6 +63,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Loan Application", @@ -71,6 +73,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Loan", @@ -87,6 +90,7 @@ "type": "Card Break" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Grant Application", @@ -103,6 +107,7 @@ "type": "Card Break" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Member", @@ -112,6 +117,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Membership", @@ -121,6 +127,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Membership Type", @@ -130,6 +137,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Membership Settings", @@ -146,6 +154,7 @@ "type": "Card Break" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Volunteer", @@ -155,6 +164,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Volunteer Type", @@ -171,6 +181,7 @@ "type": "Card Break" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Chapter", @@ -187,6 +198,7 @@ "type": "Card Break" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Donor", @@ -196,6 +208,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Donor Type", @@ -205,7 +218,7 @@ "type": "Link" } ], - "modified": "2020-11-17 13:18:42.271279", + "modified": "2020-12-01 12:33:59.867233", "modified_by": "Administrator", "module": "Non Profit", "name": "Non Profit", diff --git a/erpnext/payroll/desk_page/payroll/payroll.json b/erpnext/payroll/desk_page/payroll/payroll.json index 0397055184e..3b512893b83 100644 --- a/erpnext/payroll/desk_page/payroll/payroll.json +++ b/erpnext/payroll/desk_page/payroll/payroll.json @@ -48,6 +48,7 @@ "type": "Card Break" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Salary Component", @@ -57,6 +58,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Salary Structure", @@ -66,6 +68,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Salary Structure Assignment", @@ -75,6 +78,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Payroll Entry", @@ -84,6 +88,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Salary Slip", @@ -100,6 +105,7 @@ "type": "Card Break" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Payroll Period", @@ -109,6 +115,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Income Tax Slab", @@ -118,6 +125,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Employee Other Income", @@ -127,6 +135,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Employee Tax Exemption Declaration", @@ -136,6 +145,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Employee Tax Exemption Proof Submission", @@ -145,6 +155,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Employee Tax Exemption Category", @@ -154,6 +165,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Employee Tax Exemption Sub Category", @@ -170,6 +182,7 @@ "type": "Card Break" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Additional Salary", @@ -179,6 +192,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Retention Bonus", @@ -188,6 +202,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Employee Incentive", @@ -197,6 +212,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Employee Benefit Application", @@ -206,6 +222,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Employee Benefit Claim", @@ -222,6 +239,7 @@ "type": "Card Break" }, { + "dependencies": "Salary Slip", "hidden": 0, "is_query_report": 1, "label": "Salary Register", @@ -231,6 +249,7 @@ "type": "Link" }, { + "dependencies": "Salary Slip", "hidden": 0, "is_query_report": 1, "label": "Salary Payments Based On Payment Mode", @@ -240,6 +259,7 @@ "type": "Link" }, { + "dependencies": "Salary Slip", "hidden": 0, "is_query_report": 1, "label": "Salary Payments via ECS", @@ -249,6 +269,7 @@ "type": "Link" }, { + "dependencies": "Salary Slip", "hidden": 0, "is_query_report": 1, "label": "Income Tax Deductions", @@ -258,6 +279,7 @@ "type": "Link" }, { + "dependencies": "Salary Slip", "hidden": 0, "is_query_report": 1, "label": "Professional Tax Deductions", @@ -267,6 +289,7 @@ "type": "Link" }, { + "dependencies": "Salary Slip", "hidden": 0, "is_query_report": 1, "label": "Provident Fund Deductions", @@ -276,6 +299,7 @@ "type": "Link" }, { + "dependencies": "Payroll Entry", "hidden": 0, "is_query_report": 1, "label": "Bank Remittance", @@ -285,7 +309,7 @@ "type": "Link" } ], - "modified": "2020-11-17 13:18:40.644642", + "modified": "2020-12-01 12:34:01.478995", "modified_by": "Administrator", "module": "Payroll", "name": "Payroll", diff --git a/erpnext/projects/desk_page/projects/projects.json b/erpnext/projects/desk_page/projects/projects.json index 7ad5398251b..be49ca7b9e3 100644 --- a/erpnext/projects/desk_page/projects/projects.json +++ b/erpnext/projects/desk_page/projects/projects.json @@ -43,6 +43,7 @@ "type": "Card Break" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Project", @@ -52,6 +53,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Task", @@ -61,6 +63,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Project Template", @@ -70,6 +73,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Project Type", @@ -79,6 +83,7 @@ "type": "Link" }, { + "dependencies": "Project", "hidden": 0, "is_query_report": 0, "label": "Project Update", @@ -95,6 +100,7 @@ "type": "Card Break" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Timesheet", @@ -104,6 +110,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Activity Type", @@ -113,6 +120,7 @@ "type": "Link" }, { + "dependencies": "Activity Type", "hidden": 0, "is_query_report": 0, "label": "Activity Cost", @@ -129,6 +137,7 @@ "type": "Card Break" }, { + "dependencies": "Timesheet", "hidden": 0, "is_query_report": 1, "label": "Daily Timesheet Summary", @@ -138,6 +147,7 @@ "type": "Link" }, { + "dependencies": "Project", "hidden": 0, "is_query_report": 1, "label": "Project wise Stock Tracking", @@ -147,6 +157,7 @@ "type": "Link" }, { + "dependencies": "Project", "hidden": 0, "is_query_report": 1, "label": "Project Billing Summary", @@ -156,7 +167,7 @@ "type": "Link" } ], - "modified": "2020-11-17 13:18:41.526145", + "modified": "2020-12-01 12:34:00.578885", "modified_by": "Administrator", "module": "Projects", "name": "Projects", diff --git a/erpnext/quality_management/desk_page/quality/quality.json b/erpnext/quality_management/desk_page/quality/quality.json index 59a112ec772..1f2c99855b4 100644 --- a/erpnext/quality_management/desk_page/quality/quality.json +++ b/erpnext/quality_management/desk_page/quality/quality.json @@ -43,6 +43,7 @@ "type": "Card Break" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Quality Goal", @@ -52,6 +53,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Quality Procedure", @@ -61,6 +63,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Tree of Procedures", @@ -77,6 +80,7 @@ "type": "Card Break" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Quality Feedback", @@ -86,6 +90,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Quality Feedback Template", @@ -102,6 +107,7 @@ "type": "Card Break" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Quality Meeting", @@ -118,6 +124,7 @@ "type": "Card Break" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Non Conformance", @@ -127,6 +134,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Quality Review", @@ -136,6 +144,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Quality Action", @@ -145,7 +154,7 @@ "type": "Link" } ], - "modified": "2020-11-17 13:18:37.174448", + "modified": "2020-12-01 12:34:04.570323", "modified_by": "Administrator", "module": "Quality Management", "name": "Quality", diff --git a/erpnext/selling/desk_page/retail/retail.json b/erpnext/selling/desk_page/retail/retail.json index 5cb54d315fb..1d220bd3abd 100644 --- a/erpnext/selling/desk_page/retail/retail.json +++ b/erpnext/selling/desk_page/retail/retail.json @@ -38,6 +38,7 @@ "type": "Card Break" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Point-of-Sale Profile", @@ -47,6 +48,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "POS Settings", @@ -63,6 +65,7 @@ "type": "Card Break" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Loyalty Program", @@ -72,6 +75,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Loyalty Point Entry", @@ -88,6 +92,7 @@ "type": "Card Break" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "POS Opening Entry", @@ -97,6 +102,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "POS Closing Entry", @@ -106,7 +112,7 @@ "type": "Link" } ], - "modified": "2020-11-17 13:18:39.383674", + "modified": "2020-12-01 12:34:02.171186", "modified_by": "Administrator", "module": "Selling", "name": "Retail", diff --git a/erpnext/selling/desk_page/selling/selling.json b/erpnext/selling/desk_page/selling/selling.json index 29bc549cca3..776cb3b62a1 100644 --- a/erpnext/selling/desk_page/selling/selling.json +++ b/erpnext/selling/desk_page/selling/selling.json @@ -54,6 +54,7 @@ "type": "Card Break" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Customer", @@ -63,6 +64,7 @@ "type": "Link" }, { + "dependencies": "Item, Customer", "hidden": 0, "is_query_report": 0, "label": "Quotation", @@ -72,6 +74,7 @@ "type": "Link" }, { + "dependencies": "Item, Customer", "hidden": 0, "is_query_report": 0, "label": "Sales Order", @@ -81,6 +84,7 @@ "type": "Link" }, { + "dependencies": "Item, Customer", "hidden": 0, "is_query_report": 0, "label": "Sales Invoice", @@ -90,6 +94,7 @@ "type": "Link" }, { + "dependencies": "Item, Customer", "hidden": 0, "is_query_report": 0, "label": "Blanket Order", @@ -99,6 +104,7 @@ "type": "Link" }, { + "dependencies": "Item", "hidden": 0, "is_query_report": 0, "label": "Sales Partner", @@ -108,6 +114,7 @@ "type": "Link" }, { + "dependencies": "Item, Customer", "hidden": 0, "is_query_report": 0, "label": "Sales Person", @@ -124,6 +131,7 @@ "type": "Card Break" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Item", @@ -133,6 +141,7 @@ "type": "Link" }, { + "dependencies": "Item, Price List", "hidden": 0, "is_query_report": 0, "label": "Item Price", @@ -142,6 +151,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Price List", @@ -151,6 +161,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Item Group", @@ -160,6 +171,7 @@ "type": "Link" }, { + "dependencies": "Item", "hidden": 0, "is_query_report": 0, "label": "Product Bundle", @@ -169,6 +181,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Promotional Scheme", @@ -178,6 +191,7 @@ "type": "Link" }, { + "dependencies": "Item", "hidden": 0, "is_query_report": 0, "label": "Pricing Rule", @@ -187,6 +201,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Shipping Rule", @@ -196,6 +211,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Coupon Code", @@ -212,6 +228,7 @@ "type": "Card Break" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Selling Settings", @@ -221,6 +238,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Terms and Conditions Template", @@ -230,6 +248,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Sales Taxes and Charges Template", @@ -239,6 +258,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Lead Source", @@ -248,6 +268,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Customer Group", @@ -257,6 +278,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Contact", @@ -266,6 +288,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Address", @@ -275,6 +298,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Territory", @@ -284,6 +308,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Campaign", @@ -300,6 +325,7 @@ "type": "Card Break" }, { + "dependencies": "", "hidden": 0, "is_query_report": 1, "label": "Sales Analytics", @@ -309,6 +335,7 @@ "type": "Link" }, { + "dependencies": "Sales Order", "hidden": 0, "is_query_report": 1, "label": "Sales Order Analysis", @@ -318,6 +345,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Sales Funnel", @@ -327,6 +355,7 @@ "type": "Link" }, { + "dependencies": "Sales Order", "hidden": 0, "is_query_report": 1, "label": "Sales Order Trends", @@ -336,6 +365,7 @@ "type": "Link" }, { + "dependencies": "Quotation", "hidden": 0, "is_query_report": 1, "label": "Quotation Trends", @@ -345,6 +375,7 @@ "type": "Link" }, { + "dependencies": "Customer", "hidden": 0, "is_query_report": 1, "label": "Customer Acquisition and Loyalty", @@ -354,6 +385,7 @@ "type": "Link" }, { + "dependencies": "Sales Order", "hidden": 0, "is_query_report": 1, "label": "Inactive Customers", @@ -363,6 +395,7 @@ "type": "Link" }, { + "dependencies": "Sales Order", "hidden": 0, "is_query_report": 1, "label": "Sales Person-wise Transaction Summary", @@ -372,6 +405,7 @@ "type": "Link" }, { + "dependencies": "Item", "hidden": 0, "is_query_report": 1, "label": "Item-wise Sales History", @@ -388,6 +422,7 @@ "type": "Card Break" }, { + "dependencies": "Lead", "hidden": 0, "is_query_report": 1, "label": "Lead Details", @@ -397,6 +432,7 @@ "type": "Link" }, { + "dependencies": "Address", "hidden": 0, "is_query_report": 1, "label": "Customer Addresses And Contacts", @@ -406,6 +442,7 @@ "type": "Link" }, { + "dependencies": "Item", "hidden": 0, "is_query_report": 1, "label": "Available Stock for Packing Items", @@ -415,6 +452,7 @@ "type": "Link" }, { + "dependencies": "Sales Order", "hidden": 0, "is_query_report": 1, "label": "Pending SO Items For Purchase Request", @@ -424,6 +462,7 @@ "type": "Link" }, { + "dependencies": "Delivery Note", "hidden": 0, "is_query_report": 1, "label": "Delivery Note Trends", @@ -433,6 +472,7 @@ "type": "Link" }, { + "dependencies": "Sales Invoice", "hidden": 0, "is_query_report": 1, "label": "Sales Invoice Trends", @@ -442,6 +482,7 @@ "type": "Link" }, { + "dependencies": "Customer", "hidden": 0, "is_query_report": 1, "label": "Customer Credit Balance", @@ -451,6 +492,7 @@ "type": "Link" }, { + "dependencies": "Customer", "hidden": 0, "is_query_report": 1, "label": "Customers Without Any Sales Transactions", @@ -460,6 +502,7 @@ "type": "Link" }, { + "dependencies": "Customer", "hidden": 0, "is_query_report": 1, "label": "Sales Partners Commission", @@ -469,6 +512,7 @@ "type": "Link" }, { + "dependencies": "Sales Order", "hidden": 0, "is_query_report": 1, "label": "Territory Target Variance Based On Item Group", @@ -478,6 +522,7 @@ "type": "Link" }, { + "dependencies": "Sales Order", "hidden": 0, "is_query_report": 1, "label": "Sales Person Target Variance Based On Item Group", @@ -487,6 +532,7 @@ "type": "Link" }, { + "dependencies": "Sales Order", "hidden": 0, "is_query_report": 1, "label": "Sales Partner Target Variance Based On Item Group", @@ -496,7 +542,7 @@ "type": "Link" } ], - "modified": "2020-11-17 13:18:38.357500", + "modified": "2020-12-01 12:34:03.259945", "modified_by": "Administrator", "module": "Selling", "name": "Selling", diff --git a/erpnext/setup/desk_page/erpnext_settings/erpnext_settings.json b/erpnext/setup/desk_page/erpnext_settings/erpnext_settings.json index 03a9fe4b656..0234a3bfb1c 100644 --- a/erpnext/setup/desk_page/erpnext_settings/erpnext_settings.json +++ b/erpnext/setup/desk_page/erpnext_settings/erpnext_settings.json @@ -15,7 +15,7 @@ "is_standard": 1, "label": "ERPNext Settings", "links": [], - "modified": "2020-11-17 13:18:41.371988", + "modified": "2020-12-01 12:34:00.741011", "modified_by": "Administrator", "module": "Setup", "name": "ERPNext Settings", diff --git a/erpnext/setup/desk_page/home/home.json b/erpnext/setup/desk_page/home/home.json index 6149226f017..702a78c087a 100644 --- a/erpnext/setup/desk_page/home/home.json +++ b/erpnext/setup/desk_page/home/home.json @@ -68,6 +68,7 @@ "type": "Card Break" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Patient", @@ -77,6 +78,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Diagnosis", @@ -93,6 +95,7 @@ "type": "Card Break" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Crop", @@ -102,6 +105,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Crop Cycle", @@ -111,6 +115,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Location", @@ -120,6 +125,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Fertilizer", @@ -136,6 +142,7 @@ "type": "Card Break" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Student", @@ -145,6 +152,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Course", @@ -154,6 +162,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Instructor", @@ -163,6 +172,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Room", @@ -179,6 +189,7 @@ "type": "Card Break" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Member", @@ -188,6 +199,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Volunteer", @@ -197,6 +209,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Chapter", @@ -206,6 +219,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Donor", @@ -222,6 +236,7 @@ "type": "Card Break" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Warehouse", @@ -231,6 +246,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Brand", @@ -240,6 +256,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Unit of Measure (UOM)", @@ -249,6 +266,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Stock Reconciliation", @@ -265,6 +283,7 @@ "type": "Card Break" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Employee", @@ -274,6 +293,7 @@ "type": "Link" }, { + "dependencies": "Employee", "hidden": 0, "is_query_report": 0, "label": "Employee Attendance Tool", @@ -283,6 +303,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Salary Structure", @@ -299,6 +320,7 @@ "type": "Card Break" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Lead", @@ -308,6 +330,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Customer Group", @@ -317,6 +340,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Territory", @@ -333,6 +357,7 @@ "type": "Card Break" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Item", @@ -342,6 +367,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Customer", @@ -351,6 +377,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Supplier", @@ -360,6 +387,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Company", @@ -369,6 +397,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Chart of Accounts", @@ -378,6 +407,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Opening Invoice Creation Tool", @@ -394,6 +424,7 @@ "type": "Card Break" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Import Data", @@ -403,6 +434,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Chart of Accounts Importer", @@ -412,6 +444,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Letter Head", @@ -421,6 +454,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Email Account", @@ -430,7 +464,7 @@ "type": "Link" } ], - "modified": "2020-11-17 13:18:41.967994", + "modified": "2020-12-01 12:34:00.132264", "modified_by": "Administrator", "module": "Setup", "name": "Home", diff --git a/erpnext/stock/desk_page/stock/stock.json b/erpnext/stock/desk_page/stock/stock.json index b545a42254e..2713569f4d9 100644 --- a/erpnext/stock/desk_page/stock/stock.json +++ b/erpnext/stock/desk_page/stock/stock.json @@ -68,6 +68,7 @@ "type": "Card Break" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Item", @@ -77,6 +78,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Item Group", @@ -86,6 +88,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Product Bundle", @@ -95,6 +98,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Price List", @@ -104,6 +108,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Item Price", @@ -113,6 +118,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Shipping Rule", @@ -122,6 +128,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Pricing Rule", @@ -131,6 +138,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Item Alternative", @@ -140,6 +148,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Item Manufacturer", @@ -149,6 +158,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Customs Tariff Number", @@ -165,6 +175,7 @@ "type": "Card Break" }, { + "dependencies": "Item", "hidden": 0, "is_query_report": 0, "label": "Material Request", @@ -174,6 +185,7 @@ "type": "Link" }, { + "dependencies": "Item", "hidden": 0, "is_query_report": 0, "label": "Stock Entry", @@ -183,6 +195,7 @@ "type": "Link" }, { + "dependencies": "Item, Customer", "hidden": 0, "is_query_report": 0, "label": "Delivery Note", @@ -192,6 +205,7 @@ "type": "Link" }, { + "dependencies": "Item, Supplier", "hidden": 0, "is_query_report": 0, "label": "Purchase Receipt", @@ -201,6 +215,7 @@ "type": "Link" }, { + "dependencies": "Item", "hidden": 0, "is_query_report": 0, "label": "Pick List", @@ -210,6 +225,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Delivery Trip", @@ -226,6 +242,7 @@ "type": "Card Break" }, { + "dependencies": "Item", "hidden": 0, "is_query_report": 1, "label": "Stock Ledger", @@ -235,6 +252,7 @@ "type": "Link" }, { + "dependencies": "Item", "hidden": 0, "is_query_report": 1, "label": "Stock Balance", @@ -244,6 +262,7 @@ "type": "Link" }, { + "dependencies": "Item", "hidden": 0, "is_query_report": 1, "label": "Stock Projected Qty", @@ -253,6 +272,7 @@ "type": "Link" }, { + "dependencies": "Item", "hidden": 0, "is_query_report": 0, "label": "Stock Summary", @@ -262,6 +282,7 @@ "type": "Link" }, { + "dependencies": "Item", "hidden": 0, "is_query_report": 1, "label": "Stock Ageing", @@ -271,6 +292,7 @@ "type": "Link" }, { + "dependencies": "Item", "hidden": 0, "is_query_report": 1, "label": "Item Price Stock", @@ -287,6 +309,7 @@ "type": "Card Break" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Stock Settings", @@ -296,6 +319,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Warehouse", @@ -305,6 +329,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Unit of Measure (UOM)", @@ -314,6 +339,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Item Variant Settings", @@ -323,6 +349,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Brand", @@ -332,6 +359,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Item Attribute", @@ -341,6 +369,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "UOM Conversion Factor", @@ -357,6 +386,7 @@ "type": "Card Break" }, { + "dependencies": "Item", "hidden": 0, "is_query_report": 0, "label": "Serial No", @@ -366,6 +396,7 @@ "type": "Link" }, { + "dependencies": "Item", "hidden": 0, "is_query_report": 0, "label": "Batch", @@ -375,6 +406,7 @@ "type": "Link" }, { + "dependencies": "Item", "hidden": 0, "is_query_report": 0, "label": "Installation Note", @@ -384,6 +416,7 @@ "type": "Link" }, { + "dependencies": "Serial No", "hidden": 0, "is_query_report": 0, "label": "Serial No Service Contract Expiry", @@ -393,6 +426,7 @@ "type": "Link" }, { + "dependencies": "Serial No", "hidden": 0, "is_query_report": 0, "label": "Serial No Status", @@ -402,6 +436,7 @@ "type": "Link" }, { + "dependencies": "Serial No", "hidden": 0, "is_query_report": 0, "label": "Serial No Warranty Expiry", @@ -418,6 +453,7 @@ "type": "Card Break" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Stock Reconciliation", @@ -427,6 +463,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Landed Cost Voucher", @@ -436,6 +473,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Packing Slip", @@ -445,6 +483,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Quality Inspection", @@ -454,6 +493,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Quality Inspection Template", @@ -463,6 +503,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Quick Stock Balance", @@ -479,6 +520,7 @@ "type": "Card Break" }, { + "dependencies": "Item Price", "hidden": 0, "is_query_report": 0, "label": "Item-wise Price List Rate", @@ -488,6 +530,7 @@ "type": "Link" }, { + "dependencies": "Stock Entry", "hidden": 0, "is_query_report": 1, "label": "Stock Analytics", @@ -497,6 +540,7 @@ "type": "Link" }, { + "dependencies": "Item", "hidden": 0, "is_query_report": 1, "label": "Stock Qty vs Serial No Count", @@ -506,6 +550,7 @@ "type": "Link" }, { + "dependencies": "Delivery Note", "hidden": 0, "is_query_report": 1, "label": "Delivery Note Trends", @@ -515,6 +560,7 @@ "type": "Link" }, { + "dependencies": "Purchase Receipt", "hidden": 0, "is_query_report": 1, "label": "Purchase Receipt Trends", @@ -524,6 +570,7 @@ "type": "Link" }, { + "dependencies": "Sales Order", "hidden": 0, "is_query_report": 1, "label": "Sales Order Analysis", @@ -533,6 +580,7 @@ "type": "Link" }, { + "dependencies": "Purchase Order", "hidden": 0, "is_query_report": 1, "label": "Purchase Order Analysis", @@ -542,6 +590,7 @@ "type": "Link" }, { + "dependencies": "Bin", "hidden": 0, "is_query_report": 1, "label": "Item Shortage Report", @@ -551,6 +600,7 @@ "type": "Link" }, { + "dependencies": "Batch", "hidden": 0, "is_query_report": 1, "label": "Batch-Wise Balance History", @@ -567,6 +617,7 @@ "type": "Card Break" }, { + "dependencies": "Material Request", "hidden": 0, "is_query_report": 1, "label": "Requested Items To Be Transferred", @@ -576,6 +627,7 @@ "type": "Link" }, { + "dependencies": "Stock Ledger Entry", "hidden": 0, "is_query_report": 1, "label": "Batch Item Expiry Status", @@ -585,6 +637,7 @@ "type": "Link" }, { + "dependencies": "Price List", "hidden": 0, "is_query_report": 1, "label": "Item Prices", @@ -594,6 +647,7 @@ "type": "Link" }, { + "dependencies": "Item", "hidden": 0, "is_query_report": 1, "label": "Itemwise Recommended Reorder Level", @@ -603,6 +657,7 @@ "type": "Link" }, { + "dependencies": "Item", "hidden": 0, "is_query_report": 1, "label": "Item Variant Details", @@ -612,6 +667,7 @@ "type": "Link" }, { + "dependencies": "Purchase Order", "hidden": 0, "is_query_report": 1, "label": "Subcontracted Raw Materials To Be Transferred", @@ -621,6 +677,7 @@ "type": "Link" }, { + "dependencies": "Purchase Order", "hidden": 0, "is_query_report": 1, "label": "Subcontracted Item To Be Received", @@ -630,6 +687,7 @@ "type": "Link" }, { + "dependencies": "Stock Ledger Entry", "hidden": 0, "is_query_report": 1, "label": "Stock and Account Value Comparison", @@ -639,7 +697,7 @@ "type": "Link" } ], - "modified": "2020-11-17 13:18:38.783880", + "modified": "2020-12-01 12:34:02.711315", "modified_by": "Administrator", "module": "Stock", "name": "Stock", diff --git a/erpnext/support/desk_page/support/support.json b/erpnext/support/desk_page/support/support.json index 5a88307ef04..e760ad6bf30 100644 --- a/erpnext/support/desk_page/support/support.json +++ b/erpnext/support/desk_page/support/support.json @@ -53,6 +53,7 @@ "type": "Card Break" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Issue", @@ -62,6 +63,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Issue Type", @@ -71,6 +73,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Issue Priority", @@ -87,6 +90,7 @@ "type": "Card Break" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Maintenance Schedule", @@ -96,6 +100,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Maintenance Visit", @@ -112,6 +117,7 @@ "type": "Card Break" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Service Level Agreement", @@ -128,6 +134,7 @@ "type": "Card Break" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Warranty Claim", @@ -137,6 +144,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Serial No", @@ -153,6 +161,7 @@ "type": "Card Break" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Support Settings", @@ -169,6 +178,7 @@ "type": "Card Break" }, { + "dependencies": "Issue", "hidden": 0, "is_query_report": 1, "label": "First Response Time for Issues", @@ -178,7 +188,7 @@ "type": "Link" } ], - "modified": "2020-11-17 13:18:40.457842", + "modified": "2020-12-01 12:34:01.698260", "modified_by": "Administrator", "module": "Support", "name": "Support", diff --git a/erpnext/utilities/desk_page/utilities/utilities.json b/erpnext/utilities/desk_page/utilities/utilities.json index 3f654bea648..2a86dfa158f 100644 --- a/erpnext/utilities/desk_page/utilities/utilities.json +++ b/erpnext/utilities/desk_page/utilities/utilities.json @@ -27,6 +27,7 @@ "type": "Card Break" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Video", @@ -36,6 +37,7 @@ "type": "Link" }, { + "dependencies": "", "hidden": 0, "is_query_report": 0, "label": "Video Settings", @@ -45,7 +47,7 @@ "type": "Link" } ], - "modified": "2020-11-17 13:18:39.317897", + "modified": "2020-12-01 12:34:02.280074", "modified_by": "Administrator", "module": "Utilities", "name": "Utilities", From 9aaca25edb6aa740ecd64fa1caf9162a7342b1ba Mon Sep 17 00:00:00 2001 From: Shivam Mishra Date: Tue, 1 Dec 2020 13:39:54 +0530 Subject: [PATCH 144/477] feat: update desk page json --- .../desk_page/accounting/accounting.json | 84 +------------------ .../desk_page/agriculture/agriculture.json | 19 +---- erpnext/assets/desk_page/assets/assets.json | 19 +---- erpnext/buying/desk_page/buying/buying.json | 44 +--------- erpnext/crm/desk_page/crm/crm.json | 29 +------ .../desk_page/education/education.json | 69 +-------------- .../erpnext_integrations.json | 19 +---- .../erpnext_integrations_settings.json | 9 +- .../desk_page/healthcare/healthcare.json | 49 +---------- erpnext/hr/desk_page/hr/hr.json | 79 +---------------- .../loan_management/desk_page/loan/loan.json | 29 +------ .../manufacturing/manufacturing.json | 29 +------ .../desk_page/non_profit/non_profit.json | 34 +------- .../payroll/desk_page/payroll/payroll.json | 24 +----- .../projects/desk_page/projects/projects.json | 19 +---- .../desk_page/quality/quality.json | 24 +----- erpnext/selling/desk_page/retail/retail.json | 19 +---- .../selling/desk_page/selling/selling.json | 29 +------ .../erpnext_settings/erpnext_settings.json | 3 +- erpnext/setup/desk_page/home/home.json | 49 +---------- erpnext/stock/desk_page/stock/stock.json | 44 +--------- .../support/desk_page/support/support.json | 34 +------- .../desk_page/utilities/utilities.json | 9 +- 23 files changed, 23 insertions(+), 743 deletions(-) diff --git a/erpnext/accounts/desk_page/accounting/accounting.json b/erpnext/accounts/desk_page/accounting/accounting.json index ccc51685db9..0add27786b5 100644 --- a/erpnext/accounts/desk_page/accounting/accounting.json +++ b/erpnext/accounts/desk_page/accounting/accounting.json @@ -1,86 +1,4 @@ { - "cards": [ - { - "hidden": 0, - "label": "Accounting Masters", - "links": "[\n {\n \"description\": \"Company (not Customer or Supplier) master.\",\n \"label\": \"Company\",\n \"name\": \"Company\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Tree of financial accounts.\",\n \"icon\": \"fa fa-sitemap\",\n \"label\": \"Chart of Accounts\",\n \"name\": \"Account\",\n \"onboard\": 1,\n \"route\": \"#Tree/Account\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Accounts Settings\",\n \"name\": \"Accounts Settings\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Financial / accounting year.\",\n \"label\": \"Fiscal Year\",\n \"name\": \"Fiscal Year\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Accounting Dimension\",\n \"name\": \"Accounting Dimension\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Finance Book\",\n \"name\": \"Finance Book\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Accounting Period\",\n \"name\": \"Accounting Period\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Payment Terms based on conditions\",\n \"label\": \"Payment Term\",\n \"name\": \"Payment Term\",\n \"type\": \"doctype\"\n }\n]" - }, - { - "hidden": 0, - "label": "General Ledger", - "links": "[\n {\n \"description\": \"Accounting journal entries.\",\n \"label\": \"Journal Entry\",\n \"name\": \"Journal Entry\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Make journal entries from a template.\",\n \"label\": \"Journal Entry Template\",\n \"name\": \"Journal Entry Template\",\n \"type\": \"doctype\"\n },\n \n {\n \"dependencies\": [\n \"GL Entry\"\n ],\n \"doctype\": \"GL Entry\",\n \"is_query_report\": true,\n \"label\": \"General Ledger\",\n \"name\": \"General Ledger\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Sales Invoice\"\n ],\n \"doctype\": \"Sales Invoice\",\n \"is_query_report\": true,\n \"label\": \"Customer Ledger Summary\",\n \"name\": \"Customer Ledger Summary\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Sales Invoice\"\n ],\n \"doctype\": \"Sales Invoice\",\n \"is_query_report\": true,\n \"label\": \"Supplier Ledger Summary\",\n \"name\": \"Supplier Ledger Summary\",\n \"type\": \"report\"\n }\n]" - }, - { - "hidden": 0, - "label": "Accounts Receivable", - "links": "[\n {\n \"description\": \"Bills raised to Customers.\",\n \"label\": \"Sales Invoice\",\n \"name\": \"Sales Invoice\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Customer database.\",\n \"label\": \"Customer\",\n \"name\": \"Customer\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Bank/Cash transactions against party or for internal transfer\",\n \"label\": \"Payment Entry\",\n \"name\": \"Payment Entry\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Payment Request\",\n \"label\": \"Payment Request\",\n \"name\": \"Payment Request\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Sales Invoice\"\n ],\n \"doctype\": \"Sales Invoice\",\n \"is_query_report\": true,\n \"label\": \"Accounts Receivable\",\n \"name\": \"Accounts Receivable\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Sales Invoice\"\n ],\n \"doctype\": \"Sales Invoice\",\n \"is_query_report\": true,\n \"label\": \"Accounts Receivable Summary\",\n \"name\": \"Accounts Receivable Summary\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Sales Invoice\"\n ],\n \"doctype\": \"Sales Invoice\",\n \"is_query_report\": true,\n \"label\": \"Sales Register\",\n \"name\": \"Sales Register\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Sales Invoice\"\n ],\n \"doctype\": \"Sales Invoice\",\n \"is_query_report\": true,\n \"label\": \"Item-wise Sales Register\",\n \"name\": \"Item-wise Sales Register\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Sales Invoice\"\n ],\n \"doctype\": \"Sales Order\",\n \"is_query_report\": true,\n \"label\": \"Sales Order Analysis\",\n \"name\": \"Sales Order Analysis\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Sales Invoice\"\n ],\n \"doctype\": \"Sales Invoice\",\n \"is_query_report\": true,\n \"label\": \"Delivered Items To Be Billed\",\n \"name\": \"Delivered Items To Be Billed\",\n \"type\": \"report\"\n }\n]" - }, - { - "hidden": 0, - "label": "Accounts Payable", - "links": "[\n {\n \"description\": \"Bills raised by Suppliers.\",\n \"label\": \"Purchase Invoice\",\n \"name\": \"Purchase Invoice\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Supplier database.\",\n \"label\": \"Supplier\",\n \"name\": \"Supplier\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Bank/Cash transactions against party or for internal transfer\",\n \"label\": \"Payment Entry\",\n \"name\": \"Payment Entry\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Purchase Invoice\"\n ],\n \"doctype\": \"Purchase Invoice\",\n \"is_query_report\": true,\n \"label\": \"Accounts Payable\",\n \"name\": \"Accounts Payable\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Purchase Invoice\"\n ],\n \"doctype\": \"Purchase Invoice\",\n \"is_query_report\": true,\n \"label\": \"Accounts Payable Summary\",\n \"name\": \"Accounts Payable Summary\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Purchase Invoice\"\n ],\n \"doctype\": \"Purchase Invoice\",\n \"is_query_report\": true,\n \"label\": \"Purchase Register\",\n \"name\": \"Purchase Register\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Purchase Invoice\"\n ],\n \"doctype\": \"Purchase Invoice\",\n \"is_query_report\": true,\n \"label\": \"Item-wise Purchase Register\",\n \"name\": \"Item-wise Purchase Register\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Purchase Order\"\n ],\n \"doctype\": \"Purchase Order\",\n \"is_query_report\": true,\n \"label\": \"Purchase Order Analysis\",\n \"name\": \"Purchase Order Analysis\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Purchase Invoice\"\n ],\n \"doctype\": \"Purchase Invoice\",\n \"is_query_report\": true,\n \"label\": \"Received Items To Be Billed\",\n \"name\": \"Received Items To Be Billed\",\n \"type\": \"report\"\n }\n]" - }, - { - "hidden": 0, - "label": "Reports", - "links": "[\n {\n \"dependencies\": [\n \"GL Entry\"\n ],\n \"doctype\": \"GL Entry\",\n \"is_query_report\": true,\n \"label\": \"Trial Balance for Party\",\n \"name\": \"Trial Balance for Party\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Journal Entry\"\n ],\n \"doctype\": \"Journal Entry\",\n \"is_query_report\": true,\n \"label\": \"Payment Period Based On Invoice Date\",\n \"name\": \"Payment Period Based On Invoice Date\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Sales Invoice\"\n ],\n \"doctype\": \"Sales Invoice\",\n \"is_query_report\": true,\n \"label\": \"Sales Partners Commission\",\n \"name\": \"Sales Partners Commission\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Customer\"\n ],\n \"doctype\": \"Customer\",\n \"is_query_report\": true,\n \"label\": \"Customer Credit Balance\",\n \"name\": \"Customer Credit Balance\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Sales Invoice\"\n ],\n \"doctype\": \"Sales Invoice\",\n \"is_query_report\": true,\n \"label\": \"Sales Payment Summary\",\n \"name\": \"Sales Payment Summary\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Address\"\n ],\n \"doctype\": \"Address\",\n \"is_query_report\": true,\n \"label\": \"Address And Contacts\",\n \"name\": \"Address And Contacts\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"GL Entry\"\n ],\n \"doctype\": \"GL Entry\",\n \"is_query_report\": true,\n \"label\": \"DATEV Export\",\n \"name\": \"DATEV\",\n \"type\": \"report\"\n }\n]" - }, - { - "hidden": 0, - "label": "Financial Statements", - "links": "[\n {\n \"dependencies\": [\n \"GL Entry\"\n ],\n \"doctype\": \"GL Entry\",\n \"is_query_report\": true,\n \"label\": \"Trial Balance\",\n \"name\": \"Trial Balance\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"GL Entry\"\n ],\n \"doctype\": \"GL Entry\",\n \"is_query_report\": true,\n \"label\": \"Profit and Loss Statement\",\n \"name\": \"Profit and Loss Statement\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"GL Entry\"\n ],\n \"doctype\": \"GL Entry\",\n \"is_query_report\": true,\n \"label\": \"Balance Sheet\",\n \"name\": \"Balance Sheet\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"GL Entry\"\n ],\n \"doctype\": \"GL Entry\",\n \"is_query_report\": true,\n \"label\": \"Cash Flow\",\n \"name\": \"Cash Flow\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"GL Entry\"\n ],\n \"doctype\": \"GL Entry\",\n \"is_query_report\": true,\n \"label\": \"Consolidated Financial Statement\",\n \"name\": \"Consolidated Financial Statement\",\n \"type\": \"report\"\n }\n]" - }, - { - "hidden": 0, - "label": "Multi Currency", - "links": "[\n {\n \"description\": \"Enable / disable currencies.\",\n \"label\": \"Currency\",\n \"name\": \"Currency\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Currency exchange rate master.\",\n \"label\": \"Currency Exchange\",\n \"name\": \"Currency Exchange\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Exchange Rate Revaluation master.\",\n \"label\": \"Exchange Rate Revaluation\",\n \"name\": \"Exchange Rate Revaluation\",\n \"type\": \"doctype\"\n }\n]" - }, - { - "hidden": 0, - "label": "Settings", - "links": "[\n {\n \"description\": \"Setup Gateway accounts.\",\n \"label\": \"Payment Gateway Account\",\n \"name\": \"Payment Gateway Account\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Template of terms or contract.\",\n \"label\": \"Terms and Conditions Template\",\n \"name\": \"Terms and Conditions\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"e.g. Bank, Cash, Credit Card\",\n \"label\": \"Mode of Payment\",\n \"name\": \"Mode of Payment\",\n \"type\": \"doctype\"\n }\n]" - }, - { - "hidden": 0, - "label": "Bank Statement", - "links": "[\n {\n \"label\": \"Bank\",\n \"name\": \"Bank\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Bank Account\",\n \"name\": \"Bank Account\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Bank Clearance\",\n \"name\": \"Bank Clearance\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Bank Reconciliation\",\n \"name\": \"bank-reconciliation\",\n \"type\": \"page\"\n },\n {\n \"dependencies\": [\n \"GL Entry\"\n ],\n \"doctype\": \"GL Entry\",\n \"is_query_report\": true,\n \"label\": \"Bank Reconciliation Statement\",\n \"name\": \"Bank Reconciliation Statement\",\n \"type\": \"report\"\n },\n {\n \"label\": \"Bank Statement Transaction Entry\",\n \"name\": \"Bank Statement Transaction Entry\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Bank Statement Settings\",\n \"name\": \"Bank Statement Settings\",\n \"type\": \"doctype\"\n }\n]" - }, - { - "hidden": 0, - "label": "Subscription Management", - "links": "[\n {\n \"label\": \"Subscription Plan\",\n \"name\": \"Subscription Plan\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Subscription\",\n \"name\": \"Subscription\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Subscription Settings\",\n \"name\": \"Subscription Settings\",\n \"type\": \"doctype\"\n }\n]" - }, - { - "hidden": 0, - "label": "Goods and Services Tax (GST India)", - "links": "[\n {\n \"label\": \"GST Settings\",\n \"name\": \"GST Settings\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"GST HSN Code\",\n \"name\": \"GST HSN Code\",\n \"type\": \"doctype\"\n },\n {\n \"is_query_report\": true,\n \"label\": \"GSTR-1\",\n \"name\": \"GSTR-1\",\n \"type\": \"report\"\n },\n {\n \"is_query_report\": true,\n \"label\": \"GSTR-2\",\n \"name\": \"GSTR-2\",\n \"type\": \"report\"\n },\n {\n \"label\": \"GSTR 3B Report\",\n \"name\": \"GSTR 3B Report\",\n \"type\": \"doctype\"\n },\n {\n \"is_query_report\": true,\n \"label\": \"GST Sales Register\",\n \"name\": \"GST Sales Register\",\n \"type\": \"report\"\n },\n {\n \"is_query_report\": true,\n \"label\": \"GST Purchase Register\",\n \"name\": \"GST Purchase Register\",\n \"type\": \"report\"\n },\n {\n \"is_query_report\": true,\n \"label\": \"GST Itemised Sales Register\",\n \"name\": \"GST Itemised Sales Register\",\n \"type\": \"report\"\n },\n {\n \"is_query_report\": true,\n \"label\": \"GST Itemised Purchase Register\",\n \"name\": \"GST Itemised Purchase Register\",\n \"type\": \"report\"\n },\n {\n \"country\": \"India\",\n \"description\": \"C-Form records\",\n \"label\": \"C-Form\",\n \"name\": \"C-Form\",\n \"type\": \"doctype\"\n },\n {\n \"country\": \"India\",\n \"label\": \"Lower Deduction Certificate\",\n \"name\": \"Lower Deduction Certificate\",\n \"type\": \"doctype\"\n }\n]" - }, - { - "hidden": 0, - "label": "Share Management", - "links": "[\n {\n \"description\": \"List of available Shareholders with folio numbers\",\n \"label\": \"Shareholder\",\n \"name\": \"Shareholder\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"List of all share transactions\",\n \"label\": \"Share Transfer\",\n \"name\": \"Share Transfer\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Share Transfer\"\n ],\n \"doctype\": \"Share Transfer\",\n \"is_query_report\": true,\n \"label\": \"Share Ledger\",\n \"name\": \"Share Ledger\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Share Transfer\"\n ],\n \"doctype\": \"Share Transfer\",\n \"is_query_report\": true,\n \"label\": \"Share Balance\",\n \"name\": \"Share Balance\",\n \"type\": \"report\"\n }\n]" - }, - { - "hidden": 0, - "label": "Cost Center and Budgeting", - "links": "[\n {\n \"description\": \"Tree of financial Cost Centers.\",\n \"icon\": \"fa fa-sitemap\",\n \"label\": \"Chart of Cost Centers\",\n \"name\": \"Cost Center\",\n \"route\": \"#Tree/Cost Center\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Define budget for a financial year.\",\n \"label\": \"Budget\",\n \"name\": \"Budget\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Accounting Dimension\",\n \"name\": \"Accounting Dimension\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Cost Center\"\n ],\n \"doctype\": \"Cost Center\",\n \"is_query_report\": true,\n \"label\": \"Budget Variance Report\",\n \"name\": \"Budget Variance Report\",\n \"type\": \"report\"\n },\n {\n \"description\": \"Seasonality for setting budgets, targets etc.\",\n \"label\": \"Monthly Distribution\",\n \"name\": \"Monthly Distribution\",\n \"type\": \"doctype\"\n }\n]" - }, - { - "hidden": 0, - "label": "Opening and Closing", - "links": "[\n {\n \"label\": \"Opening Invoice Creation Tool\",\n \"name\": \"Opening Invoice Creation Tool\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Chart of Accounts Importer\",\n \"name\": \"Chart of Accounts Importer\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Close Balance Sheet and book Profit or Loss.\",\n \"label\": \"Period Closing Voucher\",\n \"name\": \"Period Closing Voucher\",\n \"type\": \"doctype\"\n }\n]" - }, - { - "hidden": 0, - "label": "Taxes", - "links": "[\n {\n \"description\": \"Tax template for selling transactions.\",\n \"label\": \"Sales Taxes and Charges Template\",\n \"name\": \"Sales Taxes and Charges Template\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Tax template for buying transactions.\",\n \"label\": \"Purchase Taxes and Charges Template\",\n \"name\": \"Purchase Taxes and Charges Template\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Tax template for item tax rates.\",\n \"label\": \"Item Tax Template\",\n \"name\": \"Item Tax Template\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Tax Category for overriding tax rates.\",\n \"label\": \"Tax Category\",\n \"name\": \"Tax Category\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Tax Rule for transactions.\",\n \"label\": \"Tax Rule\",\n \"name\": \"Tax Rule\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Tax Withholding rates to be applied on transactions.\",\n \"label\": \"Tax Withholding Category\",\n \"name\": \"Tax Withholding Category\",\n \"type\": \"doctype\"\n }\n]" - }, - { - "hidden": 0, - "label": "Profitability", - "links": "[\n {\n \"dependencies\": [\n \"Sales Invoice\"\n ],\n \"doctype\": \"Sales Invoice\",\n \"is_query_report\": true,\n \"label\": \"Gross Profit\",\n \"name\": \"Gross Profit\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"GL Entry\"\n ],\n \"doctype\": \"GL Entry\",\n \"is_query_report\": true,\n \"label\": \"Profitability Analysis\",\n \"name\": \"Profitability Analysis\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Sales Invoice\"\n ],\n \"doctype\": \"Sales Invoice\",\n \"is_query_report\": true,\n \"label\": \"Sales Invoice Trends\",\n \"name\": \"Sales Invoice Trends\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Purchase Invoice\"\n ],\n \"doctype\": \"Purchase Invoice\",\n \"is_query_report\": true,\n \"label\": \"Purchase Invoice Trends\",\n \"name\": \"Purchase Invoice Trends\",\n \"type\": \"report\"\n }\n]" - } - ], "category": "Modules", "charts": [ { @@ -1143,7 +1061,7 @@ "type": "Link" } ], - "modified": "2020-12-01 12:34:03.892648", + "modified": "2020-12-01 13:38:35.349024", "modified_by": "Administrator", "module": "Accounts", "name": "Accounting", diff --git a/erpnext/agriculture/desk_page/agriculture/agriculture.json b/erpnext/agriculture/desk_page/agriculture/agriculture.json index 38da1c43e8e..26829cbb1b8 100644 --- a/erpnext/agriculture/desk_page/agriculture/agriculture.json +++ b/erpnext/agriculture/desk_page/agriculture/agriculture.json @@ -1,21 +1,4 @@ { - "cards": [ - { - "hidden": 0, - "label": "Crops & Lands", - "links": "[\n {\n \"label\": \"Crop\",\n \"name\": \"Crop\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Crop Cycle\",\n \"name\": \"Crop Cycle\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Location\",\n \"name\": \"Location\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n }\n]" - }, - { - "hidden": 0, - "label": "Analytics", - "links": "[\n {\n \"label\": \"Plant Analysis\",\n \"name\": \"Plant Analysis\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Soil Analysis\",\n \"name\": \"Soil Analysis\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Water Analysis\",\n \"name\": \"Water Analysis\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Soil Texture\",\n \"name\": \"Soil Texture\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Weather\",\n \"name\": \"Weather\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Agriculture Analysis Criteria\",\n \"name\": \"Agriculture Analysis Criteria\",\n \"type\": \"doctype\"\n }\n]" - }, - { - "hidden": 0, - "label": "Diseases & Fertilizers", - "links": "[\n {\n \"label\": \"Disease\",\n \"name\": \"Disease\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Fertilizer\",\n \"name\": \"Fertilizer\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n }\n]" - } - ], "category": "Domains", "charts": [], "creation": "2020-03-02 17:23:34.339274", @@ -162,7 +145,7 @@ "type": "Link" } ], - "modified": "2020-12-01 12:33:59.698335", + "modified": "2020-12-01 13:38:38.477493", "modified_by": "Administrator", "module": "Agriculture", "name": "Agriculture", diff --git a/erpnext/assets/desk_page/assets/assets.json b/erpnext/assets/desk_page/assets/assets.json index 54572156d77..58bdc68ef2a 100644 --- a/erpnext/assets/desk_page/assets/assets.json +++ b/erpnext/assets/desk_page/assets/assets.json @@ -1,21 +1,4 @@ { - "cards": [ - { - "hidden": 0, - "label": "Assets", - "links": "[\n {\n \"label\": \"Asset\",\n \"name\": \"Asset\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Location\",\n \"name\": \"Location\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Asset Category\",\n \"name\": \"Asset Category\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Transfer an asset from one warehouse to another\",\n \"label\": \"Asset Movement\",\n \"name\": \"Asset Movement\",\n \"type\": \"doctype\"\n }\n]" - }, - { - "hidden": 0, - "label": "Maintenance", - "links": "[\n {\n \"label\": \"Asset Maintenance Team\",\n \"name\": \"Asset Maintenance Team\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Asset Maintenance Team\"\n ],\n \"label\": \"Asset Maintenance\",\n \"name\": \"Asset Maintenance\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Asset Maintenance\"\n ],\n \"label\": \"Asset Maintenance Log\",\n \"name\": \"Asset Maintenance Log\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Asset\"\n ],\n \"label\": \"Asset Value Adjustment\",\n \"name\": \"Asset Value Adjustment\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Asset\"\n ],\n \"label\": \"Asset Repair\",\n \"name\": \"Asset Repair\",\n \"type\": \"doctype\"\n }\n]" - }, - { - "hidden": 0, - "label": "Reports", - "links": "[\n {\n \"dependencies\": [\n \"Asset\"\n ],\n \"doctype\": \"Asset\",\n \"is_query_report\": true,\n \"label\": \"Asset Depreciation Ledger\",\n \"name\": \"Asset Depreciation Ledger\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Asset\"\n ],\n \"doctype\": \"Asset\",\n \"is_query_report\": true,\n \"label\": \"Asset Depreciations and Balances\",\n \"name\": \"Asset Depreciations and Balances\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Asset Maintenance\"\n ],\n \"doctype\": \"Asset Maintenance\",\n \"label\": \"Asset Maintenance\",\n \"name\": \"Asset Maintenance\",\n \"type\": \"report\"\n }\n]" - } - ], "category": "Modules", "charts": [ { @@ -177,7 +160,7 @@ "type": "Link" } ], - "modified": "2020-12-01 12:34:00.417242", + "modified": "2020-12-01 13:38:37.977119", "modified_by": "Administrator", "module": "Assets", "name": "Assets", diff --git a/erpnext/buying/desk_page/buying/buying.json b/erpnext/buying/desk_page/buying/buying.json index e25554c7963..8e00f7fd9ac 100644 --- a/erpnext/buying/desk_page/buying/buying.json +++ b/erpnext/buying/desk_page/buying/buying.json @@ -1,46 +1,4 @@ { - "cards": [ - { - "hidden": 0, - "label": "Buying", - "links": "[ \n {\n \"dependencies\": [\n \"Item\"\n ],\n \"description\": \"Request for purchase.\",\n \"label\": \"Material Request\",\n \"name\": \"Material Request\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Item\",\n \"Supplier\"\n ],\n \"description\": \"Purchase Orders given to Suppliers.\",\n \"label\": \"Purchase Order\",\n \"name\": \"Purchase Order\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Item\",\n \"Supplier\"\n ],\n \"label\": \"Purchase Invoice\",\n \"name\": \"Purchase Invoice\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Item\",\n \"Supplier\"\n ],\n \"description\": \"Request for quotation.\",\n \"label\": \"Request for Quotation\",\n \"name\": \"Request for Quotation\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Item\",\n \"Supplier\"\n ],\n \"description\": \"Quotations received from Suppliers.\",\n \"label\": \"Supplier Quotation\",\n \"name\": \"Supplier Quotation\",\n \"type\": \"doctype\"\n }\n]" - }, - { - "hidden": 0, - "label": "Items & Pricing", - "links": "[\n {\n \"description\": \"All Products or Services.\",\n \"label\": \"Item\",\n \"name\": \"Item\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Multiple Item prices.\",\n \"label\": \"Item Price\",\n \"name\": \"Item Price\",\n \"onboard\": 1,\n \"route\": \"#Report/Item Price\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Price List master.\",\n \"label\": \"Price List\",\n \"name\": \"Price List\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Bundle items at time of sale.\",\n \"label\": \"Product Bundle\",\n \"name\": \"Product Bundle\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Tree of Item Groups.\",\n \"icon\": \"fa fa-sitemap\",\n \"label\": \"Item Group\",\n \"link\": \"Tree/Item Group\",\n \"name\": \"Item Group\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Rules for applying different promotional schemes.\",\n \"label\": \"Promotional Scheme\",\n \"name\": \"Promotional Scheme\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Rules for applying pricing and discount.\",\n \"label\": \"Pricing Rule\",\n \"name\": \"Pricing Rule\",\n \"type\": \"doctype\"\n }\n]" - }, - { - "hidden": 0, - "label": "Settings", - "links": "[\n {\n \"description\": \"Default settings for buying transactions.\",\n \"label\": \"Buying Settings\",\n \"name\": \"Buying Settings\",\n \"settings\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Tax template for buying transactions.\",\n \"label\": \"Purchase Taxes and Charges Template\",\n \"name\": \"Purchase Taxes and Charges Template\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Template of terms or contract.\",\n \"label\": \"Terms and Conditions Template\",\n \"name\": \"Terms and Conditions\",\n \"type\": \"doctype\"\n }\n]" - }, - { - "hidden": 0, - "label": "Supplier", - "links": "[\n {\n \"description\": \"Supplier database.\",\n \"label\": \"Supplier\",\n \"name\": \"Supplier\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Supplier Group master.\",\n \"label\": \"Supplier Group\",\n \"name\": \"Supplier Group\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"All Contacts.\",\n \"label\": \"Contact\",\n \"name\": \"Contact\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"All Addresses.\",\n \"label\": \"Address\",\n \"name\": \"Address\",\n \"type\": \"doctype\"\n }\n]" - }, - { - "hidden": 0, - "label": "Supplier Scorecard", - "links": "[\n {\n \"description\": \"All Supplier scorecards.\",\n \"label\": \"Supplier Scorecard\",\n \"name\": \"Supplier Scorecard\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Templates of supplier scorecard variables.\",\n \"label\": \"Supplier Scorecard Variable\",\n \"name\": \"Supplier Scorecard Variable\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Templates of supplier scorecard criteria.\",\n \"label\": \"Supplier Scorecard Criteria\",\n \"name\": \"Supplier Scorecard Criteria\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Templates of supplier standings.\",\n \"label\": \"Supplier Scorecard Standing\",\n \"name\": \"Supplier Scorecard Standing\",\n \"type\": \"doctype\"\n }\n]" - }, - { - "hidden": 0, - "label": "Key Reports", - "links": "[\n {\n \"is_query_report\": true,\n \"label\": \"Purchase Analytics\",\n \"name\": \"Purchase Analytics\",\n \"onboard\": 1,\n \"reference_doctype\": \"Purchase Order\",\n \"type\": \"report\"\n },\n {\n \"is_query_report\": true,\n \"label\": \"Purchase Order Analysis\",\n \"name\": \"Purchase Order Analysis\",\n \"onboard\": 1,\n \"reference_doctype\": \"Purchase Order\",\n \"type\": \"report\"\n },\n {\n \"is_query_report\": true,\n \"label\": \"Supplier-Wise Sales Analytics\",\n \"name\": \"Supplier-Wise Sales Analytics\",\n \"onboard\": 1,\n \"reference_doctype\": \"Stock Ledger Entry\",\n \"type\": \"report\"\n },\n {\n \"is_query_report\": true,\n \"label\": \"Items to Order and Receive\",\n \"name\": \"Requested Items to Order and Receive\",\n \"onboard\": 1,\n \"reference_doctype\": \"Material Request\",\n \"type\": \"report\"\n },\n {\n \"is_query_report\": true,\n \"label\": \"Purchase Order Trends\",\n \"name\": \"Purchase Order Trends\",\n \"onboard\": 1,\n \"reference_doctype\": \"Purchase Order\",\n \"type\": \"report\"\n },\n {\n \"is_query_report\": true,\n \"label\": \"Procurement Tracker\",\n \"name\": \"Procurement Tracker\",\n \"onboard\": 1,\n \"reference_doctype\": \"Purchase Order\",\n \"type\": \"report\"\n }\n]" - }, - { - "hidden": 0, - "label": "Other Reports", - "links": "[\n {\n \"is_query_report\": true,\n \"label\": \"Items To Be Requested\",\n \"name\": \"Items To Be Requested\",\n \"onboard\": 1,\n \"reference_doctype\": \"Item\",\n \"type\": \"report\"\n },\n {\n \"is_query_report\": true,\n \"label\": \"Item-wise Purchase History\",\n \"name\": \"Item-wise Purchase History\",\n \"onboard\": 1,\n \"reference_doctype\": \"Item\",\n \"type\": \"report\"\n },\n {\n \"is_query_report\": true,\n \"label\": \"Purchase Receipt Trends\",\n \"name\": \"Purchase Receipt Trends\",\n \"reference_doctype\": \"Purchase Receipt\",\n \"type\": \"report\"\n },\n {\n \"is_query_report\": true,\n \"label\": \"Purchase Invoice Trends\",\n \"name\": \"Purchase Invoice Trends\",\n \"reference_doctype\": \"Purchase Invoice\",\n \"type\": \"report\"\n },\n {\n \"is_query_report\": true,\n \"label\": \"Subcontracted Raw Materials To Be Transferred\",\n \"name\": \"Subcontracted Raw Materials To Be Transferred\",\n \"reference_doctype\": \"Purchase Order\",\n \"type\": \"report\"\n },\n {\n \"is_query_report\": true,\n \"label\": \"Subcontracted Item To Be Received\",\n \"name\": \"Subcontracted Item To Be Received\",\n \"reference_doctype\": \"Purchase Order\",\n \"type\": \"report\"\n },\n {\n \"is_query_report\": true,\n \"label\": \"Supplier Quotation Comparison\",\n \"name\": \"Supplier Quotation Comparison\",\n \"onboard\": 1,\n \"reference_doctype\": \"Supplier Quotation\",\n \"type\": \"report\"\n },\n {\n \"is_query_report\": true,\n \"label\": \"Material Requests for which Supplier Quotations are not created\",\n \"name\": \"Material Requests for which Supplier Quotations are not created\",\n \"reference_doctype\": \"Material Request\",\n \"type\": \"report\"\n },\n {\n \"is_query_report\": true,\n \"label\": \"Supplier Addresses And Contacts\",\n \"name\": \"Address And Contacts\",\n \"reference_doctype\": \"Address\",\n \"route_options\": {\n \"party_type\": \"Supplier\"\n },\n \"type\": \"report\"\n }\n]" - }, - { - "hidden": 0, - "label": "Regional", - "links": "[\n {\n \"description\": \"Import Italian Purchase Invoices\",\n \"label\": \"Import Supplier Invoice\",\n \"name\": \"Import Supplier Invoice\",\n \"type\": \"doctype\"\n } \n]" - } - ], "cards_label": "", "category": "Modules", "charts": [ @@ -509,7 +467,7 @@ "type": "Link" } ], - "modified": "2020-12-01 12:33:59.349265", + "modified": "2020-12-01 13:38:38.615167", "modified_by": "Administrator", "module": "Buying", "name": "Buying", diff --git a/erpnext/crm/desk_page/crm/crm.json b/erpnext/crm/desk_page/crm/crm.json index 8679065bcaa..724ff77b050 100644 --- a/erpnext/crm/desk_page/crm/crm.json +++ b/erpnext/crm/desk_page/crm/crm.json @@ -1,31 +1,4 @@ { - "cards": [ - { - "hidden": 0, - "label": "Sales Pipeline", - "links": "[\n {\n \"description\": \"Database of potential customers.\",\n \"label\": \"Lead\",\n \"name\": \"Lead\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Potential opportunities for selling.\",\n \"label\": \"Opportunity\",\n \"name\": \"Opportunity\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Customer database.\",\n \"label\": \"Customer\",\n \"name\": \"Customer\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"All Contacts.\",\n \"label\": \"Contact\",\n \"name\": \"Contact\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Record of all communications of type email, phone, chat, visit, etc.\",\n \"label\": \"Communication\",\n \"name\": \"Communication\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Track Leads by Lead Source.\",\n \"label\": \"Lead Source\",\n \"name\": \"Lead Source\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Helps you keep tracks of Contracts based on Supplier, Customer and Employee\",\n \"label\": \"Contract\",\n \"name\": \"Contract\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Helps you manage appointments with your leads\",\n \"label\": \"Appointment\",\n \"name\": \"Appointment\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Newsletter\",\n \"name\": \"Newsletter\",\n \"type\": \"doctype\"\n }\n]" - }, - { - "hidden": 0, - "label": "Reports", - "links": "[\n {\n \"dependencies\": [\n \"Lead\"\n ],\n \"doctype\": \"Lead\",\n \"is_query_report\": true,\n \"label\": \"Lead Details\",\n \"name\": \"Lead Details\",\n \"onboard\": 1,\n \"type\": \"report\"\n },\n {\n \"icon\": \"fa fa-bar-chart\",\n \"label\": \"Sales Funnel\",\n \"name\": \"sales-funnel\",\n \"onboard\": 1,\n \"type\": \"page\"\n },\n {\n \"dependencies\": [\n \"Lead\"\n ],\n \"doctype\": \"Lead\",\n \"is_query_report\": true,\n \"label\": \"Prospects Engaged But Not Converted\",\n \"name\": \"Prospects Engaged But Not Converted\",\n \"onboard\": 1,\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Opportunity\"\n ],\n \"doctype\": \"Opportunity\",\n \"is_query_report\": true,\n \"label\": \"First Response Time for Opportunity\",\n \"name\": \"First Response Time for Opportunity\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Sales Order\"\n ],\n \"doctype\": \"Sales Order\",\n \"is_query_report\": true,\n \"label\": \"Inactive Customers\",\n \"name\": \"Inactive Customers\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Lead\"\n ],\n \"doctype\": \"Lead\",\n \"is_query_report\": true,\n \"label\": \"Campaign Efficiency\",\n \"name\": \"Campaign Efficiency\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Lead\"\n ],\n \"doctype\": \"Lead\",\n \"is_query_report\": true,\n \"label\": \"Lead Owner Efficiency\",\n \"name\": \"Lead Owner Efficiency\",\n \"type\": \"report\"\n }\n]" - }, - { - "hidden": 0, - "label": "Maintenance", - "links": "[\n {\n \"description\": \"Plan for maintenance visits.\",\n \"label\": \"Maintenance Schedule\",\n \"name\": \"Maintenance Schedule\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Visit report for maintenance call.\",\n \"label\": \"Maintenance Visit\",\n \"name\": \"Maintenance Visit\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Warranty Claim against Serial No.\",\n \"label\": \"Warranty Claim\",\n \"name\": \"Warranty Claim\",\n \"type\": \"doctype\"\n }\n]" - }, - { - "hidden": 0, - "label": "Campaign", - "links": "[\n {\n \"description\": \"Sales campaigns.\",\n \"label\": \"Campaign\",\n \"name\": \"Campaign\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Sends Mails to lead or contact based on a Campaign schedule\",\n \"label\": \"Email Campaign\",\n \"name\": \"Email Campaign\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Create and Schedule social media posts\",\n \"label\": \"Social Media Post\",\n \"name\": \"Social Media Post\",\n \"type\": \"doctype\"\n }\n]" - }, - { - "hidden": 0, - "label": "Settings", - "links": "[\n {\n \"description\": \"Manage Customer Group Tree.\",\n \"icon\": \"fa fa-sitemap\",\n \"label\": \"Customer Group\",\n \"link\": \"Tree/Customer Group\",\n \"name\": \"Customer Group\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Manage Territory Tree.\",\n \"icon\": \"fa fa-sitemap\",\n \"label\": \"Territory\",\n \"link\": \"Tree/Territory\",\n \"name\": \"Territory\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Manage Sales Person Tree.\",\n \"icon\": \"fa fa-sitemap\",\n \"label\": \"Sales Person\",\n \"link\": \"Tree/Sales Person\",\n \"name\": \"Sales Person\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Send mass SMS to your contacts\",\n \"label\": \"SMS Center\",\n \"name\": \"SMS Center\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Logs for maintaining sms delivery status\",\n \"label\": \"SMS Log\",\n \"name\": \"SMS Log\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Setup SMS gateway settings\",\n \"label\": \"SMS Settings\",\n \"name\": \"SMS Settings\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Email Group\",\n \"name\": \"Email Group\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Twitter Settings\",\n \"name\": \"Twitter Settings\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"LinkedIn Settings\",\n \"name\": \"LinkedIn Settings\",\n \"type\": \"doctype\"\n }\n]" - } - ], "category": "Modules", "charts": [ { @@ -390,7 +363,7 @@ "type": "Link" } ], - "modified": "2020-12-01 12:34:01.909417", + "modified": "2020-12-01 13:38:36.871352", "modified_by": "Administrator", "module": "CRM", "name": "CRM", diff --git a/erpnext/education/desk_page/education/education.json b/erpnext/education/desk_page/education/education.json index a4bdb21ae68..04db5a43669 100644 --- a/erpnext/education/desk_page/education/education.json +++ b/erpnext/education/desk_page/education/education.json @@ -1,71 +1,4 @@ { - "cards": [ - { - "hidden": 0, - "label": "Student and Instructor", - "links": "[\n {\n \"label\": \"Student\",\n \"name\": \"Student\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Instructor\",\n \"name\": \"Instructor\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Guardian\",\n \"name\": \"Guardian\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Student Group\",\n \"name\": \"Student Group\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Student Log\",\n \"name\": \"Student Log\",\n \"type\": \"doctype\"\n }\n]" - }, - { - "hidden": 0, - "label": "Masters", - "links": "[\n {\n \"label\": \"Program\",\n \"name\": \"Program\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Course\",\n \"name\": \"Course\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Topic\",\n \"name\": \"Topic\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Room\",\n \"name\": \"Room\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n }\n]" - }, - { - "hidden": 0, - "label": "Content Masters", - "links": "[\n {\n \"label\": \"Article\",\n \"name\": \"Article\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Video\",\n \"name\": \"Video\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Quiz\",\n \"name\": \"Quiz\",\n \"type\": \"doctype\"\n }\n]" - }, - { - "hidden": 0, - "label": "Settings", - "links": "[\n {\n \"label\": \"Education Settings\",\n \"name\": \"Education Settings\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Student Category\",\n \"name\": \"Student Category\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Student Batch Name\",\n \"name\": \"Student Batch Name\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Grading Scale\",\n \"name\": \"Grading Scale\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Academic Term\",\n \"name\": \"Academic Term\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Academic Year\",\n \"name\": \"Academic Year\",\n \"type\": \"doctype\"\n }\n]" - }, - { - "hidden": 0, - "label": "Admission", - "links": "[\n {\n \"label\": \"Student Applicant\",\n \"name\": \"Student Applicant\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Student Admission\",\n \"name\": \"Student Admission\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Program Enrollment\",\n \"name\": \"Program Enrollment\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Course Enrollment\",\n \"name\": \"Course Enrollment\",\n \"type\": \"doctype\"\n }\n]" - }, - { - "hidden": 0, - "label": "Fees", - "links": "[\n {\n \"label\": \"Fee Structure\",\n \"name\": \"Fee Structure\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Fee Category\",\n \"name\": \"Fee Category\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Fee Schedule\",\n \"name\": \"Fee Schedule\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Fees\",\n \"name\": \"Fees\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Fees\"\n ],\n \"doctype\": \"Fees\",\n \"is_query_report\": true,\n \"label\": \"Student Fee Collection Report\",\n \"name\": \"Student Fee Collection\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Fees\"\n ],\n \"doctype\": \"Fees\",\n \"is_query_report\": true,\n \"label\": \"Program wise Fee Collection Report\",\n \"name\": \"Program wise Fee Collection\",\n \"type\": \"report\"\n }\n]" - }, - { - "hidden": 0, - "label": "Schedule", - "links": "[\n {\n \"label\": \"Course Schedule\",\n \"name\": \"Course Schedule\",\n \"route\": \"#List/Course Schedule/Calendar\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Course Scheduling Tool\",\n \"name\": \"Course Scheduling Tool\",\n \"type\": \"doctype\"\n }\n]" - }, - { - "hidden": 0, - "label": "Attendance", - "links": "[\n {\n \"label\": \"Student Attendance\",\n \"name\": \"Student Attendance\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Student Leave Application\",\n \"name\": \"Student Leave Application\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Student Attendance\"\n ],\n \"doctype\": \"Student Attendance\",\n \"is_query_report\": true,\n \"label\": \"Student Monthly Attendance Sheet\",\n \"name\": \"Student Monthly Attendance Sheet\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Student Attendance\"\n ],\n \"doctype\": \"Student Attendance\",\n \"is_query_report\": true,\n \"label\": \"Absent Student Report\",\n \"name\": \"Absent Student Report\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Student Attendance\"\n ],\n \"doctype\": \"Student Attendance\",\n \"is_query_report\": true,\n \"label\": \"Student Batch-Wise Attendance\",\n \"name\": \"Student Batch-Wise Attendance\",\n \"type\": \"report\"\n }\n]" - }, - { - "hidden": 0, - "label": "LMS Activity", - "links": "[\n {\n \"label\": \"Course Enrollment\",\n \"name\": \"Course Enrollment\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Course Activity\",\n \"name\": \"Course Activity\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Quiz Activity\",\n \"name\": \"Quiz Activity\",\n \"type\": \"doctype\"\n }\n]" - }, - { - "hidden": 0, - "label": "Assessment", - "links": "[\n {\n \"label\": \"Assessment Plan\",\n \"name\": \"Assessment Plan\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Assessment Group\",\n \"link\": \"Tree/Assessment Group\",\n \"name\": \"Assessment Group\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Assessment Result\",\n \"name\": \"Assessment Result\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Assessment Criteria\",\n \"name\": \"Assessment Criteria\",\n \"type\": \"doctype\"\n }\n]" - }, - { - "hidden": 0, - "label": "Assessment Reports", - "links": "[\n {\n \"dependencies\": [\n \"Assessment Result\"\n ],\n \"doctype\": \"Assessment Result\",\n \"is_query_report\": true,\n \"label\": \"Course wise Assessment Report\",\n \"name\": \"Course wise Assessment Report\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Assessment Result\"\n ],\n \"doctype\": \"Assessment Result\",\n \"is_query_report\": true,\n \"label\": \"Final Assessment Grades\",\n \"name\": \"Final Assessment Grades\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Assessment Plan\"\n ],\n \"doctype\": \"Assessment Plan\",\n \"is_query_report\": true,\n \"label\": \"Assessment Plan Status\",\n \"name\": \"Assessment Plan Status\",\n \"type\": \"report\"\n },\n {\n \"label\": \"Student Report Generation Tool\",\n \"name\": \"Student Report Generation Tool\",\n \"type\": \"doctype\"\n }\n]" - }, - { - "hidden": 0, - "label": "Tools", - "links": "[\n {\n \"label\": \"Student Attendance Tool\",\n \"name\": \"Student Attendance Tool\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Assessment Result Tool\",\n \"name\": \"Assessment Result Tool\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Student Group Creation Tool\",\n \"name\": \"Student Group Creation Tool\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Program Enrollment Tool\",\n \"name\": \"Program Enrollment Tool\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Course Scheduling Tool\",\n \"name\": \"Course Scheduling Tool\",\n \"type\": \"doctype\"\n }\n]" - }, - { - "hidden": 0, - "label": "Other Reports", - "links": "[\n {\n \"dependencies\": [\n \"Program Enrollment\"\n ],\n \"doctype\": \"Program Enrollment\",\n \"is_query_report\": true,\n \"label\": \"Student and Guardian Contact Details\",\n \"name\": \"Student and Guardian Contact Details\",\n \"type\": \"report\"\n }\n]" - } - ], "category": "Domains", "charts": [ { @@ -697,7 +630,7 @@ "type": "Link" } ], - "modified": "2020-12-01 12:34:01.016251", + "modified": "2020-12-01 13:38:37.448989", "modified_by": "Administrator", "module": "Education", "name": "Education", diff --git a/erpnext/erpnext_integrations/desk_page/erpnext_integrations/erpnext_integrations.json b/erpnext/erpnext_integrations/desk_page/erpnext_integrations/erpnext_integrations.json index 06ae020861b..a36ca8ddb72 100644 --- a/erpnext/erpnext_integrations/desk_page/erpnext_integrations/erpnext_integrations.json +++ b/erpnext/erpnext_integrations/desk_page/erpnext_integrations/erpnext_integrations.json @@ -1,21 +1,4 @@ { - "cards": [ - { - "hidden": 0, - "label": "Marketplace", - "links": "[\n {\n \"description\": \"Woocommerce marketplace settings\",\n \"label\": \"Woocommerce Settings\",\n \"name\": \"Woocommerce Settings\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Amazon MWS settings\",\n \"label\": \"Amazon MWS Settings\",\n \"name\": \"Amazon MWS Settings\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Shopify settings\",\n \"label\": \"Shopify Settings\",\n \"name\": \"Shopify Settings\",\n \"type\": \"doctype\"\n }\n]" - }, - { - "hidden": 0, - "label": "Payments", - "links": "[\n {\n \"description\": \"GoCardless payment gateway settings\",\n \"label\": \"GoCardless Settings\",\n \"name\": \"GoCardless Settings\",\n \"type\": \"doctype\"\n }, {\n \"description\": \"M-Pesa payment gateway settings\",\n \"label\": \"M-Pesa Settings\",\n \"name\": \"Mpesa Settings\",\n \"type\": \"doctype\"\n }\n]" - }, - { - "hidden": 0, - "label": "Settings", - "links": "[\n {\n \"description\": \"Plaid settings\",\n \"label\": \"Plaid Settings\",\n \"name\": \"Plaid Settings\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Exotel settings\",\n \"label\": \"Exotel Settings\",\n \"name\": \"Exotel Settings\",\n \"type\": \"doctype\"\n }\n]" - } - ], "category": "Modules", "charts": [], "creation": "2020-08-20 19:30:48.138801", @@ -122,7 +105,7 @@ "type": "Link" } ], - "modified": "2020-12-01 12:34:03.534985", + "modified": "2020-12-01 13:38:35.846528", "modified_by": "Administrator", "module": "ERPNext Integrations", "name": "ERPNext Integrations", diff --git a/erpnext/erpnext_integrations/desk_page/erpnext_integrations_settings/erpnext_integrations_settings.json b/erpnext/erpnext_integrations/desk_page/erpnext_integrations_settings/erpnext_integrations_settings.json index 11a8fd41457..d5e61892432 100644 --- a/erpnext/erpnext_integrations/desk_page/erpnext_integrations_settings/erpnext_integrations_settings.json +++ b/erpnext/erpnext_integrations/desk_page/erpnext_integrations_settings/erpnext_integrations_settings.json @@ -1,11 +1,4 @@ { - "cards": [ - { - "hidden": 0, - "label": "Integrations Settings", - "links": "[\n\t{\n\t \"type\": \"doctype\",\n\t\t\"name\": \"Woocommerce Settings\"\n\t},\n\t{\n\t \"type\": \"doctype\",\n\t\t\"name\": \"Shopify Settings\",\n\t\t\"description\": \"Connect Shopify with ERPNext\"\n\t},\n\t{\n\t \"type\": \"doctype\",\n\t\t\"name\": \"Amazon MWS Settings\",\n\t\t\"description\": \"Connect Amazon with ERPNext\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Plaid Settings\",\n\t\t\"description\": \"Connect your bank accounts to ERPNext\"\n\t},\n {\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Exotel Settings\",\n\t\t\"description\": \"Connect your Exotel Account to ERPNext and track call logs\"\n }\n]" - } - ], "category": "Modules", "charts": [], "creation": "2020-07-31 10:38:54.021237", @@ -78,7 +71,7 @@ "type": "Link" } ], - "modified": "2020-12-01 12:34:05.074849", + "modified": "2020-12-01 13:38:34.732552", "modified_by": "Administrator", "module": "ERPNext Integrations", "name": "ERPNext Integrations Settings", diff --git a/erpnext/healthcare/desk_page/healthcare/healthcare.json b/erpnext/healthcare/desk_page/healthcare/healthcare.json index 7eec79fc515..cf1f6246cbf 100644 --- a/erpnext/healthcare/desk_page/healthcare/healthcare.json +++ b/erpnext/healthcare/desk_page/healthcare/healthcare.json @@ -1,51 +1,4 @@ { - "cards": [ - { - "hidden": 0, - "label": "Masters", - "links": "[\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Patient\",\n\t\t\"label\": \"Patient\",\n\t\t\"onboard\": 1\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Healthcare Practitioner\",\n\t\t\"label\":\"Healthcare Practitioner\",\n\t\t\"onboard\": 1\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Practitioner Schedule\",\n\t\t\"label\": \"Practitioner Schedule\",\n\t\t\"onboard\": 1\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Medical Department\",\n\t\t\"label\": \"Medical Department\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Healthcare Service Unit Type\",\n\t\t\"label\": \"Healthcare Service Unit Type\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Healthcare Service Unit\",\n\t\t\"label\": \"Healthcare Service Unit\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Medical Code Standard\",\n\t\t\"label\": \"Medical Code Standard\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Medical Code\",\n\t\t\"label\": \"Medical Code\"\n\t}\n]" - }, - { - "hidden": 0, - "label": "Consultation Setup", - "links": "[\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Appointment Type\",\n\t\t\"label\": \"Appointment Type\"\n },\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Clinical Procedure Template\",\n\t\t\"label\": \"Clinical Procedure Template\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Prescription Dosage\",\n\t\t\"label\": \"Prescription Dosage\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Prescription Duration\",\n\t\t\"label\": \"Prescription Duration\"\n\t},\n\t{\n\t \"type\": \"doctype\",\n\t\t\"name\": \"Antibiotic\",\n\t\t\"label\": \"Antibiotic\"\n\t}\n]" - }, - { - "hidden": 0, - "label": "Consultation", - "links": "[\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Patient Appointment\",\n\t\t\"label\": \"Patient Appointment\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Clinical Procedure\",\n\t\t\"label\": \"Clinical Procedure\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Patient Encounter\",\n\t\t\"label\": \"Patient Encounter\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Vital Signs\",\n\t\t\"label\": \"Vital Signs\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Complaint\",\n\t\t\"label\": \"Complaint\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Diagnosis\",\n\t\t\"label\": \"Diagnosis\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Fee Validity\",\n\t\t\"label\": \"Fee Validity\"\n\t}\n]" - }, - { - "hidden": 0, - "label": "Settings", - "links": "[\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Healthcare Settings\",\n\t\t\"label\": \"Healthcare Settings\",\n\t\t\"onboard\": 1\n\t}\n]" - }, - { - "hidden": 0, - "label": "Laboratory Setup", - "links": "[\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Lab Test Template\",\n\t\t\"label\": \"Lab Test Template\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Lab Test Sample\",\n\t\t\"label\": \"Lab Test Sample\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Lab Test UOM\",\n\t\t\"label\": \"Lab Test UOM\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Sensitivity\",\n\t\t\"label\": \"Sensitivity\"\n\t}\n]" - }, - { - "hidden": 0, - "label": "Laboratory", - "links": "[\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Lab Test\",\n\t\t\"label\": \"Lab Test\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Sample Collection\",\n\t\t\"label\": \"Sample Collection\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Dosage Form\",\n\t\t\"label\": \"Dosage Form\"\n\t}\n]" - }, - { - "hidden": 0, - "label": "Rehabilitation and Physiotherapy", - "links": "[\n {\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Exercise Type\",\n\t\t\"label\": \"Exercise Type\",\n\t\t\"onboard\": 1\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Therapy Type\",\n\t\t\"label\": \"Therapy Type\",\n\t\t\"onboard\": 1\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Therapy Plan\",\n\t\t\"label\": \"Therapy Plan\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Therapy Session\",\n\t\t\"label\": \"Therapy Session\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Patient Assessment Template\",\n\t\t\"label\": \"Patient Assessment Template\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Patient Assessment\",\n\t\t\"label\": \"Patient Assessment\"\n\t}\n]" - }, - { - "hidden": 0, - "label": "Records and History", - "links": "[\n\t{\n\t\t\"type\": \"page\",\n\t\t\"name\": \"patient_history\",\n\t\t\"label\": \"Patient History\"\n\t},\n\t{\n\t\t\"type\": \"page\",\n\t\t\"name\": \"patient-progress\",\n\t\t\"label\": \"Patient Progress\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Patient Medical Record\",\n\t\t\"label\": \"Patient Medical Record\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Inpatient Record\",\n\t\t\"label\": \"Inpatient Record\"\n\t}\n]" - }, - { - "hidden": 0, - "label": "Reports", - "links": "[\n\t{\n\t\t\"type\": \"report\",\n\t\t\"is_query_report\": true,\n\t\t\"name\": \"Patient Appointment Analytics\",\n\t\t\"doctype\": \"Patient Appointment\"\n\t},\n\t{\n\t\t\"type\": \"report\",\n\t\t\"is_query_report\": true,\n\t\t\"name\": \"Lab Test Report\",\n\t\t\"doctype\": \"Lab Test\",\n\t\t\"label\": \"Lab Test Report\"\n\t}\n]" - } - ], "category": "Domains", "charts": [ { @@ -530,7 +483,7 @@ "type": "Link" } ], - "modified": "2020-12-01 12:34:04.799604", + "modified": "2020-12-01 13:38:34.841396", "modified_by": "Administrator", "module": "Healthcare", "name": "Healthcare", diff --git a/erpnext/hr/desk_page/hr/hr.json b/erpnext/hr/desk_page/hr/hr.json index eecdd985854..218699314cb 100644 --- a/erpnext/hr/desk_page/hr/hr.json +++ b/erpnext/hr/desk_page/hr/hr.json @@ -1,81 +1,4 @@ { - "cards": [ - { - "hidden": 0, - "label": "Employee", - "links": "[\n {\n \"label\": \"Employee\",\n \"name\": \"Employee\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Employment Type\",\n \"name\": \"Employment Type\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Branch\",\n \"name\": \"Branch\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Department\",\n \"name\": \"Department\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Designation\",\n \"name\": \"Designation\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Employee Grade\",\n \"name\": \"Employee Grade\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"label\": \"Employee Group\",\n \"name\": \"Employee Group\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Employee Health Insurance\",\n \"name\": \"Employee Health Insurance\",\n \"type\": \"doctype\"\n }\n]" - }, - { - "hidden": 0, - "label": "Employee Lifecycle", - "links": "[\n {\n \"dependencies\": [\n \"Job Applicant\"\n ],\n \"label\": \"Employee Onboarding\",\n \"name\": \"Employee Onboarding\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"label\": \"Employee Skill Map\",\n \"name\": \"Employee Skill Map\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"label\": \"Employee Promotion\",\n \"name\": \"Employee Promotion\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"label\": \"Employee Transfer\",\n \"name\": \"Employee Transfer\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"label\": \"Employee Separation\",\n \"name\": \"Employee Separation\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"label\": \"Employee Onboarding Template\",\n \"name\": \"Employee Onboarding Template\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"label\": \"Employee Separation Template\",\n \"name\": \"Employee Separation Template\",\n \"type\": \"doctype\"\n }\n]" - }, - { - "hidden": 0, - "label": "Shift Management", - "links": "[\n {\n \"label\": \"Shift Type\",\n \"name\": \"Shift Type\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Shift Request\",\n \"name\": \"Shift Request\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Shift Assignment\",\n \"name\": \"Shift Assignment\",\n \"type\": \"doctype\"\n }\n]" - }, - { - "hidden": 0, - "label": "Leaves", - "links": "[\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"label\": \"Leave Application\",\n \"name\": \"Leave Application\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"label\": \"Leave Allocation\",\n \"name\": \"Leave Allocation\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Leave Type\"\n ],\n \"label\": \"Leave Policy\",\n \"name\": \"Leave Policy\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Leave Period\",\n \"name\": \"Leave Period\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Leave Type\",\n \"name\": \"Leave Type\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Holiday List\",\n \"name\": \"Holiday List\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"label\": \"Compensatory Leave Request\",\n \"name\": \"Compensatory Leave Request\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"label\": \"Leave Encashment\",\n \"name\": \"Leave Encashment\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Leave Block List\",\n \"name\": \"Leave Block List\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Leave Application\"\n ],\n \"doctype\": \"Leave Application\",\n \"is_query_report\": true,\n \"label\": \"Employee Leave Balance\",\n \"name\": \"Employee Leave Balance\",\n \"type\": \"report\"\n }\n]" - }, - { - "hidden": 0, - "label": "Payroll", - "links": "[\n {\n \"label\": \"Salary Structure\",\n \"name\": \"Salary Structure\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Salary Structure\",\n \"Employee\"\n ],\n \"label\": \"Salary Structure Assignment\",\n \"name\": \"Salary Structure Assignment\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Payroll Entry\",\n \"name\": \"Payroll Entry\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Salary Slip\",\n \"name\": \"Salary Slip\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Payroll Period\",\n \"name\": \"Payroll Period\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Income Tax Slab\",\n \"name\": \"Income Tax Slab\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Salary Component\",\n \"name\": \"Salary Component\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Additional Salary\",\n \"name\": \"Additional Salary\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"label\": \"Retention Bonus\",\n \"name\": \"Retention Bonus\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"label\": \"Employee Incentive\",\n \"name\": \"Employee Incentive\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Salary Slip\"\n ],\n \"doctype\": \"Salary Slip\",\n \"is_query_report\": true,\n \"label\": \"Salary Register\",\n \"name\": \"Salary Register\",\n \"type\": \"report\"\n }\n]" - }, - { - "hidden": 0, - "label": "Attendance", - "links": "[\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"hide_count\": true,\n \"label\": \"Employee Attendance Tool\",\n \"name\": \"Employee Attendance Tool\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"label\": \"Attendance\",\n \"name\": \"Attendance\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"label\": \"Attendance Request\",\n \"name\": \"Attendance Request\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"hide_count\": true,\n \"label\": \"Upload Attendance\",\n \"name\": \"Upload Attendance\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"hide_count\": true,\n \"label\": \"Employee Checkin\",\n \"name\": \"Employee Checkin\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Attendance\"\n ],\n \"doctype\": \"Attendance\",\n \"is_query_report\": true,\n \"label\": \"Monthly Attendance Sheet\",\n \"name\": \"Monthly Attendance Sheet\",\n \"type\": \"report\"\n }\n]" - }, - { - "hidden": 0, - "label": "Expense Claims", - "links": "[\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"label\": \"Expense Claim\",\n \"name\": \"Expense Claim\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"label\": \"Employee Advance\",\n \"name\": \"Employee Advance\",\n \"type\": \"doctype\"\n }\n]" - }, - { - "hidden": 0, - "label": "Settings", - "links": "[\n {\n \"label\": \"HR Settings\",\n \"name\": \"HR Settings\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Daily Work Summary Group\",\n \"name\": \"Daily Work Summary Group\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Team Updates\",\n \"name\": \"team-updates\",\n \"type\": \"page\"\n }\n]" - }, - { - "hidden": 0, - "label": "Fleet Management", - "links": "[\n {\n \"label\": \"Vehicle\",\n \"name\": \"Vehicle\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Vehicle Log\",\n \"name\": \"Vehicle Log\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Vehicle\"\n ],\n \"doctype\": \"Vehicle\",\n \"is_query_report\": true,\n \"label\": \"Vehicle Expenses\",\n \"name\": \"Vehicle Expenses\",\n \"type\": \"report\"\n }\n]" - }, - { - "hidden": 0, - "label": "Recruitment", - "links": "[\n {\n \"label\": \"Job Opening\",\n \"name\": \"Job Opening\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Job Applicant\",\n \"name\": \"Job Applicant\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Job Offer\",\n \"name\": \"Job Offer\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Staffing Plan\",\n \"name\": \"Staffing Plan\",\n \"type\": \"doctype\"\n }\n]" - }, - { - "hidden": 0, - "label": "Loans", - "links": "[\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"label\": \"Loan Application\",\n \"name\": \"Loan Application\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Loan\",\n \"name\": \"Loan\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Loan Type\",\n \"name\": \"Loan Type\",\n \"type\": \"doctype\"\n }\n]" - }, - { - "hidden": 0, - "label": "Training", - "links": "[\n {\n \"label\": \"Training Program\",\n \"name\": \"Training Program\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Training Event\",\n \"name\": \"Training Event\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Training Result\",\n \"name\": \"Training Result\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Training Feedback\",\n \"name\": \"Training Feedback\",\n \"type\": \"doctype\"\n }\n]" - }, - { - "hidden": 0, - "label": "Reports", - "links": "[\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"doctype\": \"Employee\",\n \"is_query_report\": true,\n \"label\": \"Employee Birthday\",\n \"name\": \"Employee Birthday\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"doctype\": \"Employee\",\n \"is_query_report\": true,\n \"label\": \"Employees working on a holiday\",\n \"name\": \"Employees working on a holiday\",\n \"type\": \"report\"\n }\n]" - }, - { - "hidden": 0, - "label": "Performance", - "links": "[\n {\n \"label\": \"Appraisal\",\n \"name\": \"Appraisal\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Appraisal Template\",\n \"name\": \"Appraisal Template\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Energy Point Rule\",\n \"name\": \"Energy Point Rule\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Energy Point Log\",\n \"name\": \"Energy Point Log\",\n \"type\": \"doctype\"\n }\n]" - }, - { - "hidden": 0, - "label": "Employee Tax and Benefits", - "links": "[\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"label\": \"Employee Tax Exemption Declaration\",\n \"name\": \"Employee Tax Exemption Declaration\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"label\": \"Employee Tax Exemption Proof Submission\",\n \"name\": \"Employee Tax Exemption Proof Submission\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Employee\",\n \"Payroll Period\"\n ],\n \"label\": \"Employee Other Income\",\n \"name\": \"Employee Other Income\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"label\": \"Employee Benefit Application\",\n \"name\": \"Employee Benefit Application\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"label\": \"Employee Benefit Claim\",\n \"name\": \"Employee Benefit Claim\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"label\": \"Employee Tax Exemption Category\",\n \"name\": \"Employee Tax Exemption Category\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"label\": \"Employee Tax Exemption Sub Category\",\n \"name\": \"Employee Tax Exemption Sub Category\",\n \"type\": \"doctype\"\n }\n]" - } - ], "category": "Modules", "charts": [ { @@ -971,7 +894,7 @@ "type": "Link" } ], - "modified": "2020-12-01 12:33:58.806820", + "modified": "2020-12-01 13:38:38.941001", "modified_by": "Administrator", "module": "HR", "name": "HR", diff --git a/erpnext/loan_management/desk_page/loan/loan.json b/erpnext/loan_management/desk_page/loan/loan.json index 57b47288c7a..6ef1737e1ab 100644 --- a/erpnext/loan_management/desk_page/loan/loan.json +++ b/erpnext/loan_management/desk_page/loan/loan.json @@ -1,31 +1,4 @@ { - "cards": [ - { - "hidden": 0, - "label": "Loan", - "links": "[\n {\n \"description\": \"Loan Type for interest and penalty rates\",\n \"label\": \"Loan Type\",\n \"name\": \"Loan Type\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Loan Applications from customers and employees.\",\n \"label\": \"Loan Application\",\n \"name\": \"Loan Application\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Loans provided to customers and employees.\",\n \"label\": \"Loan\",\n \"name\": \"Loan\",\n \"type\": \"doctype\"\n }\n]" - }, - { - "hidden": 0, - "label": "Loan Processes", - "links": "[\n {\n \"label\": \"Process Loan Security Shortfall\",\n \"name\": \"Process Loan Security Shortfall\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Process Loan Interest Accrual\",\n \"name\": \"Process Loan Interest Accrual\",\n \"type\": \"doctype\"\n }\n]" - }, - { - "hidden": 0, - "label": "Disbursement and Repayment", - "links": "[\n {\n \"label\": \"Loan Disbursement\",\n \"name\": \"Loan Disbursement\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Loan Repayment\",\n \"name\": \"Loan Repayment\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Loan Write Off\",\n \"name\": \"Loan Write Off\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Loan Interest Accrual\",\n \"name\": \"Loan Interest Accrual\",\n \"type\": \"doctype\"\n }\n]" - }, - { - "hidden": 0, - "label": "Loan Security", - "links": "[\n {\n \"label\": \"Loan Security Type\",\n \"name\": \"Loan Security Type\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Loan Security Price\",\n \"name\": \"Loan Security Price\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Loan Security\",\n \"name\": \"Loan Security\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Loan Security Pledge\",\n \"name\": \"Loan Security Pledge\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Loan Security Unpledge\",\n \"name\": \"Loan Security Unpledge\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Loan Security Shortfall\",\n \"name\": \"Loan Security Shortfall\",\n \"type\": \"doctype\"\n }\n]" - }, - { - "hidden": 0, - "label": "Reports", - "links": "[\n {\n \"doctype\": \"Loan Repayment\",\n \"is_query_report\": true,\n \"label\": \"Loan Repayment and Closure\",\n \"name\": \"Loan Repayment and Closure\",\n \"route\": \"#query-report/Loan Repayment and Closure\",\n \"type\": \"report\"\n },\n {\n \"doctype\": \"Loan Security Pledge\",\n \"is_query_report\": true,\n \"label\": \"Loan Security Status\",\n \"name\": \"Loan Security Status\",\n \"route\": \"#query-report/Loan Security Status\",\n \"type\": \"report\"\n }\n]" - } - ], "category": "Modules", "charts": [], "creation": "2020-03-12 16:35:55.299820", @@ -246,7 +219,7 @@ "type": "Link" } ], - "modified": "2020-12-01 12:34:02.390976", + "modified": "2020-12-01 13:38:36.597212", "modified_by": "Administrator", "module": "Loan Management", "name": "Loan", diff --git a/erpnext/manufacturing/desk_page/manufacturing/manufacturing.json b/erpnext/manufacturing/desk_page/manufacturing/manufacturing.json index 323f5bfc3dd..e856a987e38 100644 --- a/erpnext/manufacturing/desk_page/manufacturing/manufacturing.json +++ b/erpnext/manufacturing/desk_page/manufacturing/manufacturing.json @@ -1,31 +1,4 @@ { - "cards": [ - { - "hidden": 0, - "label": "Production", - "links": "[\n {\n \"dependencies\": [\n \"Item\",\n \"BOM\"\n ],\n \"description\": \"Orders released for production.\",\n \"label\": \"Work Order\",\n \"name\": \"Work Order\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Item\",\n \"BOM\"\n ],\n \"description\": \"Generate Material Requests (MRP) and Work Orders.\",\n \"label\": \"Production Plan\",\n \"name\": \"Production Plan\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Item\"\n ],\n \"label\": \"Stock Entry\",\n \"name\": \"Stock Entry\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Job Card\",\n \"name\": \"Job Card\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Downtime Entry\",\n \"name\": \"Downtime Entry\",\n \"type\": \"doctype\"\n }\n]" - }, - { - "hidden": 0, - "label": "Bill of Materials", - "links": "[\n {\n \"description\": \"All Products or Services.\",\n \"label\": \"Item\",\n \"name\": \"Item\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Item\"\n ],\n \"description\": \"Bill of Materials (BOM)\",\n \"label\": \"Bill of Materials\",\n \"name\": \"BOM\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Where manufacturing operations are carried.\",\n \"label\": \"Workstation\",\n \"name\": \"Workstation\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Details of the operations carried out.\",\n \"label\": \"Operation\",\n \"name\": \"Operation\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Routing\",\n \"name\": \"Routing\",\n \"type\": \"doctype\"\n }\n]" - }, - { - "hidden": 0, - "label": "Reports", - "links": "[{\n\t\"dependencies\": [\"Work Order\"],\n\t\"name\": \"Production Planning Report\",\n\t\"is_query_report\": true,\n\t\"type\": \"report\",\n\t\"doctype\": \"Work Order\",\n\t\"label\": \"Production Planning Report\"\n}, {\n\t\"dependencies\": [\"Work Order\"],\n\t\"name\": \"Work Order Summary\",\n\t\"is_query_report\": true,\n\t\"type\": \"report\",\n\t\"doctype\": \"Work Order\",\n\t\"label\": \"Work Order Summary\"\n}, {\n\t\"dependencies\": [\"Quality Inspection\"],\n\t\"name\": \"Quality Inspection Summary\",\n\t\"is_query_report\": true,\n\t\"type\": \"report\",\n\t\"doctype\": \"Quality Inspection\",\n\t\"label\": \"Quality Inspection Summary\"\n}, {\n\t\"dependencies\": [\"Downtime Entry\"],\n\t\"name\": \"Downtime Analysis\",\n\t\"is_query_report\": true,\n\t\"type\": \"report\",\n\t\"doctype\": \"Downtime Entry\",\n\t\"label\": \"Downtime Analysis\"\n}, {\n\t\"dependencies\": [\"Job Card\"],\n\t\"name\": \"Job Card Summary\",\n\t\"is_query_report\": true,\n\t\"type\": \"report\",\n\t\"doctype\": \"Job Card\",\n\t\"label\": \"Job Card Summary\"\n}, {\n\t\"dependencies\": [\"BOM\"],\n\t\"name\": \"BOM Search\",\n\t\"is_query_report\": true,\n\t\"type\": \"report\",\n\t\"doctype\": \"BOM\",\n\t\"label\": \"BOM Search\"\n}, {\n\t\"dependencies\": [\"BOM\"],\n\t\"name\": \"BOM Stock Report\",\n\t\"is_query_report\": true,\n\t\"type\": \"report\",\n\t\"doctype\": \"BOM\",\n\t\"label\": \"BOM Stock Report\"\n}, {\n\t\"dependencies\": [\"Work Order\"],\n\t\"name\": \"Production Analytics\",\n\t\"is_query_report\": true,\n\t\"type\": \"report\",\n\t\"doctype\": \"Work Order\",\n\t\"label\": \"Production Analytics\"\n}, {\n\t\"dependencies\": [\"BOM\"],\n\t\"name\": \"BOM Operations Time\",\n\t\"is_query_report\": true,\n\t\"type\": \"report\",\n\t\"doctype\": \"BOM\",\n\t\"label\": \"BOM Operations Time\"\n}]" - }, - { - "hidden": 0, - "label": "Tools", - "links": "[\n {\n \"description\": \"Replace BOM and update latest price in all BOMs\",\n \"label\": \"BOM Update Tool\",\n \"name\": \"BOM Update Tool\",\n \"type\": \"doctype\"\n },\n {\n \"data_doctype\": \"BOM\",\n \"description\": \"Compare BOMs for changes in Raw Materials and Operations\",\n \"label\": \"BOM Comparison Tool\",\n \"name\": \"bom-comparison-tool\",\n \"type\": \"page\"\n }\n]" - }, - { - "hidden": 0, - "label": "Settings", - "links": "[\n {\n \"description\": \"Global settings for all manufacturing processes.\",\n \"label\": \"Manufacturing Settings\",\n \"name\": \"Manufacturing Settings\",\n \"type\": \"doctype\"\n }\n]" - } - ], "category": "Domains", "charts": [ { @@ -300,7 +273,7 @@ "type": "Link" } ], - "modified": "2020-12-01 12:33:58.367406", + "modified": "2020-12-01 13:38:39.365928", "modified_by": "Administrator", "module": "Manufacturing", "name": "Manufacturing", diff --git a/erpnext/non_profit/desk_page/non_profit/non_profit.json b/erpnext/non_profit/desk_page/non_profit/non_profit.json index 1d5292a9c60..be92d606107 100644 --- a/erpnext/non_profit/desk_page/non_profit/non_profit.json +++ b/erpnext/non_profit/desk_page/non_profit/non_profit.json @@ -1,36 +1,4 @@ { - "cards": [ - { - "hidden": 0, - "label": "Loan Management", - "links": "[\n {\n \"description\": \"Define various loan types\",\n \"label\": \"Loan Type\",\n \"name\": \"Loan Type\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Loan Application\",\n \"label\": \"Loan Application\",\n \"name\": \"Loan Application\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Loan\",\n \"name\": \"Loan\",\n \"type\": \"doctype\"\n }\n]" - }, - { - "hidden": 0, - "label": "Grant Application", - "links": "[\n {\n \"description\": \"Grant information.\",\n \"label\": \"Grant Application\",\n \"name\": \"Grant Application\",\n \"type\": \"doctype\"\n }\n]" - }, - { - "hidden": 0, - "label": "Membership", - "links": "[\n {\n \"description\": \"Member information.\",\n \"label\": \"Member\",\n \"name\": \"Member\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Membership Details\",\n \"label\": \"Membership\",\n \"name\": \"Membership\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Membership Type Details\",\n \"label\": \"Membership Type\",\n \"name\": \"Membership Type\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Billing and Gateway Settings\",\n \"label\": \"Membership Settings\",\n \"name\": \"Membership Settings\",\n \"type\": \"doctype\"\n }\n]" - }, - { - "hidden": 0, - "label": "Volunteer", - "links": "[\n {\n \"description\": \"Volunteer information.\",\n \"label\": \"Volunteer\",\n \"name\": \"Volunteer\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Volunteer Type information.\",\n \"label\": \"Volunteer Type\",\n \"name\": \"Volunteer Type\",\n \"type\": \"doctype\"\n }\n]" - }, - { - "hidden": 0, - "label": "Chapter", - "links": "[\n {\n \"description\": \"Chapter information.\",\n \"label\": \"Chapter\",\n \"name\": \"Chapter\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n }\n]" - }, - { - "hidden": 0, - "label": "Donor", - "links": "[\n {\n \"description\": \"Donor information.\",\n \"label\": \"Donor\",\n \"name\": \"Donor\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Donor Type information.\",\n \"label\": \"Donor Type\",\n \"name\": \"Donor Type\",\n \"type\": \"doctype\"\n }\n]" - } - ], "category": "Domains", "charts": [], "creation": "2020-03-02 17:23:47.811421", @@ -218,7 +186,7 @@ "type": "Link" } ], - "modified": "2020-12-01 12:33:59.867233", + "modified": "2020-12-01 13:38:38.351409", "modified_by": "Administrator", "module": "Non Profit", "name": "Non Profit", diff --git a/erpnext/payroll/desk_page/payroll/payroll.json b/erpnext/payroll/desk_page/payroll/payroll.json index 3b512893b83..137fad27797 100644 --- a/erpnext/payroll/desk_page/payroll/payroll.json +++ b/erpnext/payroll/desk_page/payroll/payroll.json @@ -1,26 +1,4 @@ { - "cards": [ - { - "hidden": 0, - "label": "Payroll", - "links": "[\n {\n \"label\": \"Salary Component\",\n \"name\": \"Salary Component\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n \n },\n {\n \"label\": \"Salary Structure\",\n \"name\": \"Salary Structure\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Salary Structure Assignment\",\n \"name\": \"Salary Structure Assignment\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Payroll Entry\",\n \"name\": \"Payroll Entry\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Salary Slip\",\n \"name\": \"Salary Slip\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n }\n]" - }, - { - "hidden": 0, - "label": "Taxation", - "links": "[\n {\n \"label\": \"Payroll Period\",\n \"name\": \"Payroll Period\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n \n },\n {\n \"label\": \"Income Tax Slab\",\n \"name\": \"Income Tax Slab\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n \n },\n {\n \"label\": \"Employee Other Income\",\n \"name\": \"Employee Other Income\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n \n },\n {\n \"label\": \"Employee Tax Exemption Declaration\",\n \"name\": \"Employee Tax Exemption Declaration\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n \n },\n {\n \"label\": \"Employee Tax Exemption Proof Submission\",\n \"name\": \"Employee Tax Exemption Proof Submission\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n \n },\n {\n \"label\": \"Employee Tax Exemption Category\",\n \"name\": \"Employee Tax Exemption Category\",\n \"type\": \"doctype\"\n \n },\n {\n \"label\": \"Employee Tax Exemption Sub Category\",\n \"name\": \"Employee Tax Exemption Sub Category\",\n \"type\": \"doctype\"\n \n }\n]" - }, - { - "hidden": 0, - "label": "Compensations", - "links": "[\n {\n \"label\": \"Additional Salary\",\n \"name\": \"Additional Salary\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n \n },\n {\n \"label\": \"Retention Bonus\",\n \"name\": \"Retention Bonus\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Employee Incentive\",\n \"name\": \"Employee Incentive\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Employee Benefit Application\",\n \"name\": \"Employee Benefit Application\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Employee Benefit Claim\",\n \"name\": \"Employee Benefit Claim\",\n \"type\": \"doctype\"\n }\n]" - }, - { - "hidden": 0, - "label": "Reports", - "links": "[\n {\n \"dependencies\": [\n \"Salary Slip\"\n ],\n \"doctype\": \"Salary Slip\",\n \"is_query_report\": true,\n \"label\": \"Salary Register\",\n \"name\": \"Salary Register\",\n \"type\": \"report\"\n \n },\n {\n \"dependencies\": [\n \"Salary Slip\"\n ],\n \"doctype\": \"Salary Slip\",\n \"label\": \"Salary Payments Based On Payment Mode\",\n \"is_query_report\": true,\n \"name\": \"Salary Payments Based On Payment Mode\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Salary Slip\"\n ],\n \"doctype\": \"Salary Slip\",\n \"label\": \"Salary Payments via ECS\",\n \"is_query_report\": true,\n \"name\": \"Salary Payments via ECS\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Salary Slip\"\n ],\n \"doctype\": \"Salary Slip\",\n \"label\": \"Income Tax Deductions\",\n \"is_query_report\": true,\n \"name\": \"Income Tax Deductions\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Salary Slip\"\n ],\n \"doctype\": \"Salary Slip\",\n \"label\": \"Professional Tax Deductions\",\n \"is_query_report\": true,\n \"name\": \"Professional Tax Deductions\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Salary Slip\"\n ],\n \"doctype\": \"Salary Slip\",\n \"label\": \"Provident Fund Deductions\",\n \"is_query_report\": true,\n \"name\": \"Provident Fund Deductions\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Payroll Entry\"\n ],\n \"doctype\": \"Payroll Entry\",\n \"is_query_report\": true,\n \"label\": \"Bank Remittance\",\n \"name\": \"Bank Remittance\",\n \"type\": \"report\"\n \n }\n]" - } - ], "category": "Modules", "charts": [ { @@ -309,7 +287,7 @@ "type": "Link" } ], - "modified": "2020-12-01 12:34:01.478995", + "modified": "2020-12-01 13:38:37.205628", "modified_by": "Administrator", "module": "Payroll", "name": "Payroll", diff --git a/erpnext/projects/desk_page/projects/projects.json b/erpnext/projects/desk_page/projects/projects.json index be49ca7b9e3..5c8ab993f38 100644 --- a/erpnext/projects/desk_page/projects/projects.json +++ b/erpnext/projects/desk_page/projects/projects.json @@ -1,21 +1,4 @@ { - "cards": [ - { - "hidden": 0, - "label": "Projects", - "links": "[\n {\n \"description\": \"Project master.\",\n \"label\": \"Project\",\n \"name\": \"Project\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Project activity / task.\",\n \"label\": \"Task\",\n \"name\": \"Task\",\n \"onboard\": 1,\n \"route\": \"#List/Task\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Make project from a template.\",\n \"label\": \"Project Template\",\n \"name\": \"Project Template\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Define Project type.\",\n \"label\": \"Project Type\",\n \"name\": \"Project Type\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Project\"\n ],\n \"description\": \"Project Update.\",\n \"label\": \"Project Update\",\n \"name\": \"Project Update\",\n \"type\": \"doctype\"\n }\n]" - }, - { - "hidden": 0, - "label": "Time Tracking", - "links": "[\n {\n \"description\": \"Timesheet for tasks.\",\n \"label\": \"Timesheet\",\n \"name\": \"Timesheet\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Types of activities for Time Logs\",\n \"label\": \"Activity Type\",\n \"name\": \"Activity Type\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Activity Type\"\n ],\n \"description\": \"Cost of various activities\",\n \"label\": \"Activity Cost\",\n \"name\": \"Activity Cost\",\n \"type\": \"doctype\"\n }\n]" - }, - { - "hidden": 0, - "label": "Reports", - "links": "[\n {\n \"dependencies\": [\n \"Timesheet\"\n ],\n \"doctype\": \"Timesheet\",\n \"is_query_report\": true,\n \"label\": \"Daily Timesheet Summary\",\n \"name\": \"Daily Timesheet Summary\",\n \"onboard\": 1,\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Project\"\n ],\n \"doctype\": \"Project\",\n \"is_query_report\": true,\n \"label\": \"Project wise Stock Tracking\",\n \"name\": \"Project wise Stock Tracking\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Project\"\n ],\n \"doctype\": \"Project\",\n \"is_query_report\": true,\n \"label\": \"Project Billing Summary\",\n \"name\": \"Project Billing Summary\",\n \"type\": \"report\"\n }\n]" - } - ], "category": "Modules", "charts": [ { @@ -167,7 +150,7 @@ "type": "Link" } ], - "modified": "2020-12-01 12:34:00.578885", + "modified": "2020-12-01 13:38:37.856224", "modified_by": "Administrator", "module": "Projects", "name": "Projects", diff --git a/erpnext/quality_management/desk_page/quality/quality.json b/erpnext/quality_management/desk_page/quality/quality.json index 1f2c99855b4..aaee9ab8572 100644 --- a/erpnext/quality_management/desk_page/quality/quality.json +++ b/erpnext/quality_management/desk_page/quality/quality.json @@ -1,26 +1,4 @@ { - "cards": [ - { - "hidden": 0, - "label": "Goal and Procedure", - "links": "[\n {\n \"description\": \"Quality Goal.\",\n \"label\": \"Quality Goal\",\n \"name\": \"Quality Goal\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Quality Procedure.\",\n \"label\": \"Quality Procedure\",\n \"name\": \"Quality Procedure\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Tree of Quality Procedures.\",\n \"icon\": \"fa fa-sitemap\",\n \"label\": \"Tree of Procedures\",\n \"name\": \"Quality Procedure\",\n \"route\": \"#Tree/Quality Procedure\",\n \"type\": \"doctype\"\n }\n]" - }, - { - "hidden": 0, - "label": "Feedback", - "links": "[\n {\n \"description\": \"Quality Feedback\",\n \"label\": \"Quality Feedback\",\n \"name\": \"Quality Feedback\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Quality Feedback Template\",\n \"label\": \"Quality Feedback Template\",\n \"name\": \"Quality Feedback Template\",\n \"type\": \"doctype\"\n }\n]" - }, - { - "hidden": 0, - "label": "Meeting", - "links": "[\n {\n \"description\": \"Quality Meeting\",\n \"label\": \"Quality Meeting\",\n \"name\": \"Quality Meeting\",\n \"type\": \"doctype\"\n }\n]" - }, - { - "hidden": 0, - "label": "Review and Action", - "links": "[\n {\n \"description\": \"Non Conformance\",\n \"label\": \"Non Conformance\",\n \"name\": \"Non Conformance\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Quality Review\",\n \"label\": \"Quality Review\",\n \"name\": \"Quality Review\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Quality Action\",\n \"label\": \"Quality Action\",\n \"name\": \"Quality Action\",\n \"type\": \"doctype\"\n }\n]" - } - ], "category": "Modules", "charts": [], "creation": "2020-03-02 15:49:28.632014", @@ -154,7 +132,7 @@ "type": "Link" } ], - "modified": "2020-12-01 12:34:04.570323", + "modified": "2020-12-01 13:38:35.120213", "modified_by": "Administrator", "module": "Quality Management", "name": "Quality", diff --git a/erpnext/selling/desk_page/retail/retail.json b/erpnext/selling/desk_page/retail/retail.json index 1d220bd3abd..e9beef5f91d 100644 --- a/erpnext/selling/desk_page/retail/retail.json +++ b/erpnext/selling/desk_page/retail/retail.json @@ -1,21 +1,4 @@ { - "cards": [ - { - "hidden": 0, - "label": "Settings & Configurations", - "links": "[\n {\n \"description\": \"Setup default values for POS Invoices\",\n \"label\": \"Point-of-Sale Profile\",\n \"name\": \"POS Profile\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"POS Settings\",\n \"name\": \"POS Settings\",\n \"type\": \"doctype\"\n }\n]" - }, - { - "hidden": 0, - "label": "Loyalty Program", - "links": "[\n {\n \"description\": \"To make Customer based incentive schemes.\",\n \"label\": \"Loyalty Program\",\n \"name\": \"Loyalty Program\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"To view logs of Loyalty Points assigned to a Customer.\",\n \"label\": \"Loyalty Point Entry\",\n \"name\": \"Loyalty Point Entry\",\n \"type\": \"doctype\"\n }\n]" - }, - { - "hidden": 0, - "label": "Opening & Closing", - "links": "[\n {\n \"label\": \"POS Opening Entry\",\n \"name\": \"POS Opening Entry\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"POS Closing Entry\",\n \"name\": \"POS Closing Entry\",\n \"type\": \"doctype\"\n }\n]" - } - ], "category": "Domains", "charts": [], "creation": "2020-03-02 17:18:32.505616", @@ -112,7 +95,7 @@ "type": "Link" } ], - "modified": "2020-12-01 12:34:02.171186", + "modified": "2020-12-01 13:38:36.758038", "modified_by": "Administrator", "module": "Selling", "name": "Retail", diff --git a/erpnext/selling/desk_page/selling/selling.json b/erpnext/selling/desk_page/selling/selling.json index 776cb3b62a1..0bbf17fcae4 100644 --- a/erpnext/selling/desk_page/selling/selling.json +++ b/erpnext/selling/desk_page/selling/selling.json @@ -1,31 +1,4 @@ { - "cards": [ - { - "hidden": 0, - "label": "Selling", - "links": "[\n {\n \"description\": \"Customer Database.\",\n \"label\": \"Customer\",\n \"name\": \"Customer\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Item\",\n \"Customer\"\n ],\n \"description\": \"Quotes to Leads or Customers.\",\n \"label\": \"Quotation\",\n \"name\": \"Quotation\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Item\",\n \"Customer\"\n ],\n \"description\": \"Confirmed orders from Customers.\",\n \"label\": \"Sales Order\",\n \"name\": \"Sales Order\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Item\",\n \"Customer\"\n ],\n \"label\": \"Sales Invoice\",\n \"name\": \"Sales Invoice\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Item\",\n \"Customer\"\n ],\n \"description\": \"Blanket Orders from Costumers.\",\n \"label\": \"Blanket Order\",\n \"name\": \"Blanket Order\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Item\"\n ],\n \"description\": \"Manage Sales Partners.\",\n \"label\": \"Sales Partner\",\n \"name\": \"Sales Partner\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Item\",\n \"Customer\"\n ],\n \"description\": \"Manage Sales Person Tree.\",\n \"icon\": \"fa fa-sitemap\",\n \"label\": \"Sales Person\",\n \"link\": \"Tree/Sales Person\",\n \"name\": \"Sales Person\",\n \"type\": \"doctype\"\n }\n]" - }, - { - "hidden": 0, - "label": "Items and Pricing", - "links": "[\n {\n \"description\": \"All Products or Services.\",\n \"label\": \"Item\",\n \"name\": \"Item\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Item\",\n \"Price List\"\n ],\n \"description\": \"Multiple Item prices.\",\n \"label\": \"Item Price\",\n \"name\": \"Item Price\",\n \"onboard\": 1,\n \"route\": \"#Report/Item Price\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Price List master.\",\n \"label\": \"Price List\",\n \"name\": \"Price List\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Tree of Item Groups.\",\n \"icon\": \"fa fa-sitemap\",\n \"label\": \"Item Group\",\n \"link\": \"Tree/Item Group\",\n \"name\": \"Item Group\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Item\"\n ],\n \"description\": \"Bundle items at time of sale.\",\n \"label\": \"Product Bundle\",\n \"name\": \"Product Bundle\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Rules for applying different promotional schemes.\",\n \"label\": \"Promotional Scheme\",\n \"name\": \"Promotional Scheme\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Item\"\n ],\n \"description\": \"Rules for applying pricing and discount.\",\n \"label\": \"Pricing Rule\",\n \"name\": \"Pricing Rule\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Rules for adding shipping costs.\",\n \"label\": \"Shipping Rule\",\n \"name\": \"Shipping Rule\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Define coupon codes.\",\n \"label\": \"Coupon Code\",\n \"name\": \"Coupon Code\",\n \"type\": \"doctype\"\n }\n]" - }, - { - "hidden": 0, - "label": "Settings", - "links": "[\n {\n \"description\": \"Default settings for selling transactions.\",\n \"label\": \"Selling Settings\",\n \"name\": \"Selling Settings\",\n \"settings\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Template of terms or contract.\",\n \"label\": \"Terms and Conditions Template\",\n \"name\": \"Terms and Conditions\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Tax template for selling transactions.\",\n \"label\": \"Sales Taxes and Charges Template\",\n \"name\": \"Sales Taxes and Charges Template\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Track Leads by Lead Source.\",\n \"label\": \"Lead Source\",\n \"name\": \"Lead Source\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Manage Customer Group Tree.\",\n \"icon\": \"fa fa-sitemap\",\n \"label\": \"Customer Group\",\n \"link\": \"Tree/Customer Group\",\n \"name\": \"Customer Group\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"All Contacts.\",\n \"label\": \"Contact\",\n \"name\": \"Contact\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"All Addresses.\",\n \"label\": \"Address\",\n \"name\": \"Address\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Manage Territory Tree.\",\n \"icon\": \"fa fa-sitemap\",\n \"label\": \"Territory\",\n \"link\": \"Tree/Territory\",\n \"name\": \"Territory\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Sales campaigns.\",\n \"label\": \"Campaign\",\n \"name\": \"Campaign\",\n \"type\": \"doctype\"\n }\n]" - }, - { - "hidden": 0, - "label": "Key Reports", - "links": "[\n {\n \n \"doctype\": \"Sales Order\",\n \"is_query_report\": true,\n \"label\": \"Sales Analytics\",\n \"name\": \"Sales Analytics\",\n \"onboard\": 1,\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Sales Order\"\n ],\n \"doctype\": \"Sales Order\",\n \"is_query_report\": true,\n \"label\": \"Sales Order Analysis\",\n \"name\": \"Sales Order Analysis\",\n \"onboard\": 1,\n \"type\": \"report\"\n },\n {\n \"icon\": \"fa fa-bar-chart\",\n \"label\": \"Sales Funnel\",\n \"name\": \"sales-funnel\",\n \"onboard\": 1,\n \"type\": \"page\"\n },\n {\n \"dependencies\": [\n \"Sales Order\"\n ],\n \"doctype\": \"Sales Order\",\n \"is_query_report\": true,\n \"label\": \"Sales Order Trends\",\n \"name\": \"Sales Order Trends\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Quotation\"\n ],\n \"doctype\": \"Quotation\",\n \"is_query_report\": true,\n \"label\": \"Quotation Trends\",\n \"name\": \"Quotation Trends\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Customer\"\n ],\n \"doctype\": \"Customer\",\n \"icon\": \"fa fa-bar-chart\",\n \"is_query_report\": true,\n \"label\": \"Customer Acquisition and Loyalty\",\n \"name\": \"Customer Acquisition and Loyalty\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Sales Order\"\n ],\n \"doctype\": \"Sales Order\",\n \"is_query_report\": true,\n \"label\": \"Inactive Customers\",\n \"name\": \"Inactive Customers\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Sales Order\"\n ],\n \"doctype\": \"Sales Order\",\n \"is_query_report\": true,\n \"label\": \"Sales Person-wise Transaction Summary\",\n \"name\": \"Sales Person-wise Transaction Summary\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Item\"\n ],\n \"doctype\": \"Item\",\n \"is_query_report\": true,\n \"label\": \"Item-wise Sales History\",\n \"name\": \"Item-wise Sales History\",\n \"type\": \"report\"\n }\n]" - }, - { - "hidden": 0, - "label": "Other Reports", - "links": "[\n {\n \"dependencies\": [\n \"Lead\"\n ],\n \"doctype\": \"Lead\",\n \"is_query_report\": true,\n \"label\": \"Lead Details\",\n \"name\": \"Lead Details\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Address\"\n ],\n \"doctype\": \"Address\",\n \"is_query_report\": true,\n \"label\": \"Customer Addresses And Contacts\",\n \"name\": \"Address And Contacts\",\n \"route_options\": {\n \"party_type\": \"Customer\"\n },\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Item\"\n ],\n \"doctype\": \"Item\",\n \"is_query_report\": true,\n \"label\": \"Available Stock for Packing Items\",\n \"name\": \"Available Stock for Packing Items\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Sales Order\"\n ],\n \"doctype\": \"Sales Order\",\n \"is_query_report\": true,\n \"label\": \"Pending SO Items For Purchase Request\",\n \"name\": \"Pending SO Items For Purchase Request\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Delivery Note\"\n ],\n \"doctype\": \"Delivery Note\",\n \"is_query_report\": true,\n \"label\": \"Delivery Note Trends\",\n \"name\": \"Delivery Note Trends\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Sales Invoice\"\n ],\n \"doctype\": \"Sales Invoice\",\n \"is_query_report\": true,\n \"label\": \"Sales Invoice Trends\",\n \"name\": \"Sales Invoice Trends\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Customer\"\n ],\n \"doctype\": \"Customer\",\n \"is_query_report\": true,\n \"label\": \"Customer Credit Balance\",\n \"name\": \"Customer Credit Balance\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Customer\"\n ],\n \"doctype\": \"Customer\",\n \"is_query_report\": true,\n \"label\": \"Customers Without Any Sales Transactions\",\n \"name\": \"Customers Without Any Sales Transactions\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Customer\"\n ],\n \"doctype\": \"Customer\",\n \"is_query_report\": true,\n \"label\": \"Sales Partners Commission\",\n \"name\": \"Sales Partners Commission\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Sales Order\"\n ],\n \"doctype\": \"Sales Order\",\n \"is_query_report\": true,\n \"label\": \"Territory Target Variance Based On Item Group\",\n \"name\": \"Territory Target Variance Based On Item Group\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Sales Order\"\n ],\n \"doctype\": \"Sales Order\",\n \"is_query_report\": true,\n \"label\": \"Sales Person Target Variance Based On Item Group\",\n \"name\": \"Sales Person Target Variance Based On Item Group\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Sales Order\"\n ],\n \"doctype\": \"Sales Order\",\n \"is_query_report\": true,\n \"label\": \"Sales Partner Target Variance Based On Item Group\",\n \"name\": \"Sales Partner Target Variance based on Item Group\",\n \"type\": \"report\"\n }\n \n]" - } - ], "category": "Modules", "charts": [ { @@ -542,7 +515,7 @@ "type": "Link" } ], - "modified": "2020-12-01 12:34:03.259945", + "modified": "2020-12-01 13:38:35.971277", "modified_by": "Administrator", "module": "Selling", "name": "Selling", diff --git a/erpnext/setup/desk_page/erpnext_settings/erpnext_settings.json b/erpnext/setup/desk_page/erpnext_settings/erpnext_settings.json index 0234a3bfb1c..a2224515e54 100644 --- a/erpnext/setup/desk_page/erpnext_settings/erpnext_settings.json +++ b/erpnext/setup/desk_page/erpnext_settings/erpnext_settings.json @@ -1,5 +1,4 @@ { - "cards": [], "category": "Modules", "charts": [], "creation": "2020-03-12 14:47:51.166455", @@ -15,7 +14,7 @@ "is_standard": 1, "label": "ERPNext Settings", "links": [], - "modified": "2020-12-01 12:34:00.741011", + "modified": "2020-12-01 13:38:37.759596", "modified_by": "Administrator", "module": "Setup", "name": "ERPNext Settings", diff --git a/erpnext/setup/desk_page/home/home.json b/erpnext/setup/desk_page/home/home.json index 702a78c087a..fa164d3a03c 100644 --- a/erpnext/setup/desk_page/home/home.json +++ b/erpnext/setup/desk_page/home/home.json @@ -1,51 +1,4 @@ { - "cards": [ - { - "hidden": 0, - "label": "Healthcare", - "links": "[\n {\n \"label\": \"Patient\",\n \"name\": \"Patient\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Diagnosis\",\n \"name\": \"Diagnosis\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n }\n]" - }, - { - "hidden": 0, - "label": "Agriculture", - "links": "[\n {\n \"label\": \"Crop\",\n \"name\": \"Crop\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Crop Cycle\",\n \"name\": \"Crop Cycle\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Location\",\n \"name\": \"Location\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Fertilizer\",\n \"name\": \"Fertilizer\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n }\n]" - }, - { - "hidden": 0, - "label": "Education", - "links": "[\n {\n \"label\": \"Student\",\n \"name\": \"Student\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Course\",\n \"name\": \"Course\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Instructor\",\n \"name\": \"Instructor\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Room\",\n \"name\": \"Room\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n }\n]" - }, - { - "hidden": 0, - "label": "Non Profit", - "links": "[\n {\n \"description\": \"Member information.\",\n \"label\": \"Member\",\n \"name\": \"Member\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Volunteer information.\",\n \"label\": \"Volunteer\",\n \"name\": \"Volunteer\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Chapter information.\",\n \"label\": \"Chapter\",\n \"name\": \"Chapter\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Donor information.\",\n \"label\": \"Donor\",\n \"name\": \"Donor\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n }\n]" - }, - { - "hidden": 0, - "label": "Stock", - "links": "[\n {\n \"label\": \"Warehouse\",\n \"name\": \"Warehouse\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Brand\",\n \"name\": \"Brand\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Unit of Measure (UOM)\",\n \"name\": \"UOM\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Stock Reconciliation\",\n \"name\": \"Stock Reconciliation\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n }\n]" - }, - { - "hidden": 0, - "label": "Human Resources", - "links": "[\n {\n \"label\": \"Employee\",\n \"name\": \"Employee\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"hide_count\": true,\n \"label\": \"Employee Attendance Tool\",\n \"name\": \"Employee Attendance Tool\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Salary Structure\",\n \"name\": \"Salary Structure\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n }\n]" - }, - { - "hidden": 0, - "label": "CRM", - "links": "[\n {\n \"description\": \"Database of potential customers.\",\n \"label\": \"Lead\",\n \"name\": \"Lead\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Manage Customer Group Tree.\",\n \"icon\": \"fa fa-sitemap\",\n \"label\": \"Customer Group\",\n \"link\": \"Tree/Customer Group\",\n \"name\": \"Customer Group\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Manage Territory Tree.\",\n \"icon\": \"fa fa-sitemap\",\n \"label\": \"Territory\",\n \"link\": \"Tree/Territory\",\n \"name\": \"Territory\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n }\n]" - }, - { - "hidden": 0, - "label": "Accounting", - "links": "[\n {\n \"label\": \"Item\",\n \"name\": \"Item\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Customer database.\",\n \"label\": \"Customer\",\n \"name\": \"Customer\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Supplier database.\",\n \"label\": \"Supplier\",\n \"name\": \"Supplier\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Company (not Customer or Supplier) master.\",\n \"label\": \"Company\",\n \"name\": \"Company\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Tree of financial accounts.\",\n \"icon\": \"fa fa-sitemap\",\n \"label\": \"Chart of Accounts\",\n \"name\": \"Account\",\n \"onboard\": 1,\n \"route\": \"#Tree/Account\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Create Opening Sales and Purchase Invoices\",\n \"label\": \"Opening Invoice Creation Tool\",\n \"name\": \"Opening Invoice Creation Tool\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n }\n]" - }, - { - "hidden": 0, - "label": "Data Import and Settings", - "links": "[\n {\n \"description\": \"Import Data from CSV / Excel files.\",\n \"icon\": \"octicon octicon-cloud-upload\",\n \"label\": \"Import Data\",\n \"name\": \"Data Import\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Import Chart of Accounts from CSV / Excel files\",\n \"label\": \"Chart of Accounts Importer\",\n \"label\": \"Chart of Accounts Importer\",\n \"name\": \"Chart of Accounts Importer\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Letter Heads for print templates.\",\n \"label\": \"Letter Head\",\n \"name\": \"Letter Head\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Add / Manage Email Accounts.\",\n \"label\": \"Email Account\",\n \"name\": \"Email Account\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n }\n]" - } - ], "category": "Modules", "charts": [], "creation": "2020-01-23 13:46:38.833076", @@ -464,7 +417,7 @@ "type": "Link" } ], - "modified": "2020-12-01 12:34:00.132264", + "modified": "2020-12-01 13:38:38.131999", "modified_by": "Administrator", "module": "Setup", "name": "Home", diff --git a/erpnext/stock/desk_page/stock/stock.json b/erpnext/stock/desk_page/stock/stock.json index 2713569f4d9..fbf8326088b 100644 --- a/erpnext/stock/desk_page/stock/stock.json +++ b/erpnext/stock/desk_page/stock/stock.json @@ -1,46 +1,4 @@ { - "cards": [ - { - "hidden": 0, - "label": "Items and Pricing", - "links": "[\n {\n \"label\": \"Item\",\n \"name\": \"Item\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"icon\": \"fa fa-sitemap\",\n \"label\": \"Item Group\",\n \"link\": \"Tree/Item Group\",\n \"name\": \"Item Group\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Product Bundle\",\n \"name\": \"Product Bundle\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Price List\",\n \"name\": \"Price List\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Item Price\",\n \"name\": \"Item Price\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Shipping Rule\",\n \"name\": \"Shipping Rule\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Pricing Rule\",\n \"name\": \"Pricing Rule\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Item Alternative\",\n \"name\": \"Item Alternative\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Item Manufacturer\",\n \"name\": \"Item Manufacturer\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Customs Tariff Number\",\n \"name\": \"Customs Tariff Number\",\n \"type\": \"doctype\"\n }\n]" - }, - { - "hidden": 0, - "label": "Stock Transactions", - "links": "[\n {\n \"dependencies\": [\n \"Item\"\n ],\n \"label\": \"Material Request\",\n \"name\": \"Material Request\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Item\"\n ],\n \"label\": \"Stock Entry\",\n \"name\": \"Stock Entry\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Item\",\n \"Customer\"\n ],\n \"label\": \"Delivery Note\",\n \"name\": \"Delivery Note\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Item\",\n \"Supplier\"\n ],\n \"label\": \"Purchase Receipt\",\n \"name\": \"Purchase Receipt\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Item\"\n ],\n \"label\": \"Pick List\",\n \"name\": \"Pick List\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Delivery Trip\",\n \"name\": \"Delivery Trip\",\n \"type\": \"doctype\"\n }\n]" - }, - { - "hidden": 0, - "label": "Stock Reports", - "links": "[\n {\n \"dependencies\": [\n \"Item\"\n ],\n \"doctype\": \"Stock Ledger Entry\",\n \"is_query_report\": true,\n \"label\": \"Stock Ledger\",\n \"name\": \"Stock Ledger\",\n \"onboard\": 1,\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Item\"\n ],\n \"doctype\": \"Stock Ledger Entry\",\n \"is_query_report\": true,\n \"label\": \"Stock Balance\",\n \"name\": \"Stock Balance\",\n \"onboard\": 1,\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Item\"\n ],\n \"doctype\": \"Item\",\n \"is_query_report\": true,\n \"label\": \"Stock Projected Qty\",\n \"name\": \"Stock Projected Qty\",\n \"onboard\": 1,\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Item\"\n ],\n \"label\": \"Stock Summary\",\n \"name\": \"stock-balance\",\n \"type\": \"page\"\n },\n {\n \"dependencies\": [\n \"Item\"\n ],\n \"doctype\": \"Item\",\n \"is_query_report\": true,\n \"label\": \"Stock Ageing\",\n \"name\": \"Stock Ageing\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Item\"\n ],\n \"doctype\": \"Item\",\n \"is_query_report\": true,\n \"label\": \"Item Price Stock\",\n \"name\": \"Item Price Stock\",\n \"type\": \"report\"\n }\n]" - }, - { - "hidden": 0, - "label": "Settings", - "links": "[\n {\n \"label\": \"Stock Settings\",\n \"name\": \"Stock Settings\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Warehouse\",\n \"name\": \"Warehouse\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Unit of Measure (UOM)\",\n \"name\": \"UOM\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Item Variant Settings\",\n \"name\": \"Item Variant Settings\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Brand\",\n \"name\": \"Brand\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Item Attribute\",\n \"name\": \"Item Attribute\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"UOM Conversion Factor\",\n \"name\": \"UOM Conversion Factor\",\n \"type\": \"doctype\"\n }\n]" - }, - { - "hidden": 0, - "label": "Serial No and Batch", - "links": "[\n {\n \"dependencies\": [\n \"Item\"\n ],\n \"label\": \"Serial No\",\n \"name\": \"Serial No\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Item\"\n ],\n \"label\": \"Batch\",\n \"name\": \"Batch\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Item\"\n ],\n \"label\": \"Installation Note\",\n \"name\": \"Installation Note\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Serial No\"\n ],\n \"doctype\": \"Serial No\",\n \"label\": \"Serial No Service Contract Expiry\",\n \"name\": \"Serial No Service Contract Expiry\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Serial No\"\n ],\n \"doctype\": \"Serial No\",\n \"label\": \"Serial No Status\",\n \"name\": \"Serial No Status\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Serial No\"\n ],\n \"doctype\": \"Serial No\",\n \"label\": \"Serial No Warranty Expiry\",\n \"name\": \"Serial No Warranty Expiry\",\n \"type\": \"report\"\n }\n]" - }, - { - "hidden": 0, - "label": "Tools", - "links": "[\n {\n \"label\": \"Stock Reconciliation\",\n \"name\": \"Stock Reconciliation\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Landed Cost Voucher\",\n \"name\": \"Landed Cost Voucher\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Packing Slip\",\n \"name\": \"Packing Slip\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Quality Inspection\",\n \"name\": \"Quality Inspection\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Quality Inspection Template\",\n \"name\": \"Quality Inspection Template\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Quick Stock Balance\",\n \"name\": \"Quick Stock Balance\",\n \"type\": \"doctype\"\n }\n]" - }, - { - "hidden": 0, - "label": "Key Reports", - "links": "[\n {\n \"dependencies\": [\n \"Item Price\"\n ],\n \"doctype\": \"Item Price\",\n \"is_query_report\": false,\n \"label\": \"Item-wise Price List Rate\",\n \"name\": \"Item-wise Price List Rate\",\n \"onboard\": 1,\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Stock Entry\"\n ],\n \"doctype\": \"Stock Entry\",\n \"is_query_report\": true,\n \"label\": \"Stock Analytics\",\n \"name\": \"Stock Analytics\",\n \"onboard\": 1,\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Item\"\n ],\n \"doctype\": \"Item\",\n \"is_query_report\": true,\n \"label\": \"Stock Qty vs Serial No Count\",\n \"name\": \"Stock Qty vs Serial No Count\",\n \"onboard\": 1,\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Delivery Note\"\n ],\n \"doctype\": \"Delivery Note\",\n \"is_query_report\": true,\n \"label\": \"Delivery Note Trends\",\n \"name\": \"Delivery Note Trends\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Purchase Receipt\"\n ],\n \"doctype\": \"Purchase Receipt\",\n \"is_query_report\": true,\n \"label\": \"Purchase Receipt Trends\",\n \"name\": \"Purchase Receipt Trends\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Sales Order\"\n ],\n \"doctype\": \"Sales Order\",\n \"is_query_report\": true,\n \"label\": \"Sales Order Analysis\",\n \"name\": \"Sales Order Analysis\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Purchase Order\"\n ],\n \"doctype\": \"Purchase Order\",\n \"is_query_report\": true,\n \"label\": \"Purchase Order Analysis\",\n \"name\": \"Purchase Order Analysis\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Bin\"\n ],\n \"doctype\": \"Bin\",\n \"is_query_report\": true,\n \"label\": \"Item Shortage Report\",\n \"name\": \"Item Shortage Report\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Batch\"\n ],\n \"doctype\": \"Batch\",\n \"is_query_report\": true,\n \"label\": \"Batch-Wise Balance History\",\n \"name\": \"Batch-Wise Balance History\",\n \"type\": \"report\"\n }\n]" - }, - { - "hidden": 0, - "label": "Other Reports", - "links": "[\n {\n \"dependencies\": [\n \"Material Request\"\n ],\n \"doctype\": \"Material Request\",\n \"is_query_report\": true,\n \"label\": \"Requested Items To Be Transferred\",\n \"name\": \"Requested Items To Be Transferred\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Stock Ledger Entry\"\n ],\n \"doctype\": \"Stock Ledger Entry\",\n \"is_query_report\": true,\n \"label\": \"Batch Item Expiry Status\",\n \"name\": \"Batch Item Expiry Status\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Price List\"\n ],\n \"doctype\": \"Price List\",\n \"is_query_report\": true,\n \"label\": \"Item Prices\",\n \"name\": \"Item Prices\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Item\"\n ],\n \"doctype\": \"Item\",\n \"is_query_report\": true,\n \"label\": \"Itemwise Recommended Reorder Level\",\n \"name\": \"Itemwise Recommended Reorder Level\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Item\"\n ],\n \"doctype\": \"Item\",\n \"is_query_report\": true,\n \"label\": \"Item Variant Details\",\n \"name\": \"Item Variant Details\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Purchase Order\"\n ],\n \"doctype\": \"Purchase Order\",\n \"is_query_report\": true,\n \"label\": \"Subcontracted Raw Materials To Be Transferred\",\n \"name\": \"Subcontracted Raw Materials To Be Transferred\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Purchase Order\"\n ],\n \"doctype\": \"Purchase Order\",\n \"is_query_report\": true,\n \"label\": \"Subcontracted Item To Be Received\",\n \"name\": \"Subcontracted Item To Be Received\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Stock Ledger Entry\"\n ],\n \"doctype\": \"Stock Ledger Entry\",\n \"is_query_report\": true,\n \"label\": \"Stock and Account Value Comparison\",\n \"name\": \"Stock and Account Value Comparison\",\n \"type\": \"report\"\n }\n]" - } - ], "cards_label": "Masters & Reports", "category": "Modules", "charts": [ @@ -697,7 +655,7 @@ "type": "Link" } ], - "modified": "2020-12-01 12:34:02.711315", + "modified": "2020-12-01 13:38:36.282890", "modified_by": "Administrator", "module": "Stock", "name": "Stock", diff --git a/erpnext/support/desk_page/support/support.json b/erpnext/support/desk_page/support/support.json index e760ad6bf30..20e60c062bf 100644 --- a/erpnext/support/desk_page/support/support.json +++ b/erpnext/support/desk_page/support/support.json @@ -1,36 +1,4 @@ { - "cards": [ - { - "hidden": 0, - "label": "Issues", - "links": "[\n {\n \"description\": \"Support queries from customers.\",\n \"label\": \"Issue\",\n \"name\": \"Issue\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Issue Type.\",\n \"label\": \"Issue Type\",\n \"name\": \"Issue Type\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Issue Priority.\",\n \"label\": \"Issue Priority\",\n \"name\": \"Issue Priority\",\n \"type\": \"doctype\"\n }\n]" - }, - { - "hidden": 0, - "label": "Maintenance", - "links": "[\n {\n \"label\": \"Maintenance Schedule\",\n \"name\": \"Maintenance Schedule\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Maintenance Visit\",\n \"name\": \"Maintenance Visit\",\n \"type\": \"doctype\"\n }\n]" - }, - { - "hidden": 0, - "label": "Service Level Agreement", - "links": "[\n {\n \"description\": \"Service Level Agreement.\",\n \"label\": \"Service Level Agreement\",\n \"name\": \"Service Level Agreement\",\n \"type\": \"doctype\"\n }\n]" - }, - { - "hidden": 0, - "label": "Warranty", - "links": "[\n {\n \"description\": \"Warranty Claim against Serial No.\",\n \"label\": \"Warranty Claim\",\n \"name\": \"Warranty Claim\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Single unit of an Item.\",\n \"label\": \"Serial No\",\n \"name\": \"Serial No\",\n \"type\": \"doctype\"\n }\n]" - }, - { - "hidden": 0, - "label": "Settings", - "links": "[\n {\n \"label\": \"Support Settings\",\n \"name\": \"Support Settings\",\n \"type\": \"doctype\"\n }\n]" - }, - { - "hidden": 0, - "label": "Reports", - "links": "[\n {\n \"dependencies\": [\n \"Issue\"\n ],\n \"doctype\": \"Issue\",\n \"is_query_report\": true,\n \"label\": \"First Response Time for Issues\",\n \"name\": \"First Response Time for Issues\",\n \"type\": \"report\"\n }\n]" - } - ], "category": "Modules", "charts": [], "creation": "2020-03-02 15:48:23.224699", @@ -188,7 +156,7 @@ "type": "Link" } ], - "modified": "2020-12-01 12:34:01.698260", + "modified": "2020-12-01 13:38:37.073482", "modified_by": "Administrator", "module": "Support", "name": "Support", diff --git a/erpnext/utilities/desk_page/utilities/utilities.json b/erpnext/utilities/desk_page/utilities/utilities.json index 2a86dfa158f..df17303924a 100644 --- a/erpnext/utilities/desk_page/utilities/utilities.json +++ b/erpnext/utilities/desk_page/utilities/utilities.json @@ -1,11 +1,4 @@ { - "cards": [ - { - "hidden": 0, - "label": "Video", - "links": "[\n {\n \"description\": \"Video\",\n \"label\": \"Video\",\n \"name\": \"Video\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Video settings\",\n \"label\": \"Video Settings\",\n \"name\": \"Video Settings\",\n \"type\": \"doctype\"\n }\n]" - } - ], "category": "Modules", "charts": [], "creation": "2020-09-10 12:21:22.335307", @@ -47,7 +40,7 @@ "type": "Link" } ], - "modified": "2020-12-01 12:34:02.280074", + "modified": "2020-12-01 13:38:36.711884", "modified_by": "Administrator", "module": "Utilities", "name": "Utilities", From ab5053ef9cbd5ce27f9253a3409bd7be24f597e2 Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Wed, 2 Dec 2020 12:34:40 +0530 Subject: [PATCH 145/477] fix: Accounting dimension import in PCV --- .../doctype/period_closing_voucher/period_closing_voucher.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/erpnext/accounts/doctype/period_closing_voucher/period_closing_voucher.py b/erpnext/accounts/doctype/period_closing_voucher/period_closing_voucher.py index 7dd5b017703..a74fa062b6a 100644 --- a/erpnext/accounts/doctype/period_closing_voucher/period_closing_voucher.py +++ b/erpnext/accounts/doctype/period_closing_voucher/period_closing_voucher.py @@ -8,7 +8,7 @@ from frappe import _ from erpnext.accounts.utils import get_account_currency from erpnext.controllers.accounts_controller import AccountsController from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import (get_accounting_dimensions, - get_dimension_filters) + get_dimensions) class PeriodClosingVoucher(AccountsController): def validate(self): @@ -58,7 +58,7 @@ class PeriodClosingVoucher(AccountsController): for dimension in accounting_dimensions: dimension_fields.append('t1.{0}'.format(dimension)) - dimension_filters, default_dimensions = get_dimension_filters() + dimension_filters, default_dimensions = get_dimensions() pl_accounts = self.get_pl_balances(dimension_fields) From 59820004b8b1084511664142e29e8d8dbde9e9c6 Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Wed, 2 Dec 2020 12:34:59 +0530 Subject: [PATCH 146/477] fix: Exception naming --- .../test_accounting_dimension_filter.py | 6 +++--- erpnext/accounts/doctype/gl_entry/gl_entry.py | 8 ++++---- erpnext/exceptions.py | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/erpnext/accounts/doctype/accounting_dimension_filter/test_accounting_dimension_filter.py b/erpnext/accounts/doctype/accounting_dimension_filter/test_accounting_dimension_filter.py index f67e1de4044..fa700e115ce 100644 --- a/erpnext/accounts/doctype/accounting_dimension_filter/test_accounting_dimension_filter.py +++ b/erpnext/accounts/doctype/accounting_dimension_filter/test_accounting_dimension_filter.py @@ -7,7 +7,7 @@ import frappe import unittest from erpnext.accounts.doctype.sales_invoice.test_sales_invoice import create_sales_invoice from erpnext.accounts.doctype.accounting_dimension.test_accounting_dimension import create_dimension, disable_dimension -from erpnext.exceptions import InvalidAccountDimension, MandatoryDimension +from erpnext.exceptions import InvalidAccountDimensionError, MandatoryAccountDimensionError class TestAccountingDimensionFilter(unittest.TestCase): def setUp(self): @@ -20,7 +20,7 @@ class TestAccountingDimensionFilter(unittest.TestCase): si.location = 'Block 1' si.save() - self.assertRaises(InvalidAccountDimension, si.submit) + self.assertRaises(InvalidAccountDimensionError, si.submit) def test_mandatory_dimension_validation(self): si = create_sales_invoice(do_not_save=1) @@ -31,7 +31,7 @@ class TestAccountingDimensionFilter(unittest.TestCase): si.items[0].cost_center = '_Test Cost Center 2 - _TC' si.save() - self.assertRaises(MandatoryDimension, si.submit) + self.assertRaises(MandatoryAccountDimensionError, si.submit) def tearDown(self): disable_dimension_filter() diff --git a/erpnext/accounts/doctype/gl_entry/gl_entry.py b/erpnext/accounts/doctype/gl_entry/gl_entry.py index f586de82e35..fd6f01e345f 100644 --- a/erpnext/accounts/doctype/gl_entry/gl_entry.py +++ b/erpnext/accounts/doctype/gl_entry/gl_entry.py @@ -11,7 +11,7 @@ from frappe.model.meta import get_field_precision from erpnext.accounts.party import validate_party_gle_currency, validate_party_frozen_disabled from erpnext.accounts.utils import get_account_currency from erpnext.accounts.utils import get_fiscal_year -from erpnext.exceptions import InvalidAccountCurrency, InvalidAccountDimension, MandatoryDimension +from erpnext.exceptions import InvalidAccountCurrency, InvalidAccountDimensionError, MandatoryAccountDimensionError from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import get_checks_for_pl_and_bs_accounts from erpnext.accounts.doctype.accounting_dimension_filter.accounting_dimension_filter import get_dimension_filter_map from six import iteritems @@ -101,16 +101,16 @@ class GLEntry(Document): if self.account == account: if value['is_mandatory'] and not self.get(dimension): frappe.throw(_("{0} is mandatory for account {1}").format( - frappe.bold(frappe.unscrub(dimension)), frappe.bold(self.account)), MandatoryDimension) + frappe.bold(frappe.unscrub(dimension)), frappe.bold(self.account)), MandatoryAccountDimensionError) if value['allow_or_restrict'] == 'Allow': if self.get(dimension) and self.get(dimension) not in value['allowed_dimensions']: frappe.throw(_("Invalid value {0} for account {1}").format( - frappe.bold(self.get(dimension)), frappe.bold(self.account)), InvalidAccountDimension) + frappe.bold(self.get(dimension)), frappe.bold(self.account)), InvalidAccountDimensionError) else: if self.get(dimension) and self.get(dimension) in value['allowed_dimensions']: frappe.throw(_("Invalid value {0} for account {1}").format( - frappe.bold(self.get(dimension)), frappe.bold(self.account)), InvalidAccountDimension) + frappe.bold(self.get(dimension)), frappe.bold(self.account)), InvalidAccountDimensionError) def check_pl_account(self): if self.is_opening=='Yes' and \ diff --git a/erpnext/exceptions.py b/erpnext/exceptions.py index dcf3d6bad1a..04291cd5bd1 100644 --- a/erpnext/exceptions.py +++ b/erpnext/exceptions.py @@ -6,5 +6,5 @@ class PartyFrozen(frappe.ValidationError): pass class InvalidAccountCurrency(frappe.ValidationError): pass class InvalidCurrency(frappe.ValidationError): pass class PartyDisabled(frappe.ValidationError):pass -class InvalidAccountDimension(frappe.ValidationError): pass -class MandatoryDimension(frappe.ValidationError): pass +class InvalidAccountDimensionError(frappe.ValidationError): pass +class MandatoryAccountDimensionError(frappe.ValidationError): pass From 2895645f86d27aa0d80564f9ac06b53fef966e62 Mon Sep 17 00:00:00 2001 From: Shivam Mishra Date: Thu, 3 Dec 2020 15:39:53 +0530 Subject: [PATCH 147/477] feat: rename desk page to workspace --- erpnext/accounts/desk_page/accounting/accounting.json | 2 +- erpnext/agriculture/desk_page/agriculture/agriculture.json | 2 +- erpnext/assets/desk_page/assets/assets.json | 2 +- erpnext/buying/desk_page/buying/buying.json | 2 +- erpnext/crm/desk_page/crm/crm.json | 2 +- erpnext/education/desk_page/education/education.json | 2 +- .../desk_page/erpnext_integrations/erpnext_integrations.json | 2 +- .../erpnext_integrations_settings.json | 2 +- erpnext/healthcare/desk_page/healthcare/healthcare.json | 2 +- erpnext/hr/desk_page/hr/hr.json | 2 +- erpnext/loan_management/desk_page/loan/loan.json | 2 +- .../manufacturing/desk_page/manufacturing/manufacturing.json | 2 +- erpnext/non_profit/desk_page/non_profit/non_profit.json | 2 +- erpnext/payroll/desk_page/payroll/payroll.json | 2 +- erpnext/projects/desk_page/projects/projects.json | 2 +- erpnext/quality_management/desk_page/quality/quality.json | 2 +- erpnext/selling/desk_page/retail/retail.json | 2 +- erpnext/selling/desk_page/selling/selling.json | 2 +- erpnext/setup/desk_page/erpnext_settings/erpnext_settings.json | 2 +- erpnext/setup/desk_page/home/home.json | 2 +- erpnext/stock/desk_page/stock/stock.json | 2 +- erpnext/support/desk_page/support/support.json | 2 +- erpnext/utilities/desk_page/utilities/utilities.json | 2 +- 23 files changed, 23 insertions(+), 23 deletions(-) diff --git a/erpnext/accounts/desk_page/accounting/accounting.json b/erpnext/accounts/desk_page/accounting/accounting.json index 0add27786b5..8d24ca82918 100644 --- a/erpnext/accounts/desk_page/accounting/accounting.json +++ b/erpnext/accounts/desk_page/accounting/accounting.json @@ -10,7 +10,7 @@ "developer_mode_only": 0, "disable_user_customization": 0, "docstatus": 0, - "doctype": "Desk Page", + "doctype": "Workspace", "extends_another_page": 0, "hide_custom": 0, "icon": "accounting", diff --git a/erpnext/agriculture/desk_page/agriculture/agriculture.json b/erpnext/agriculture/desk_page/agriculture/agriculture.json index 26829cbb1b8..2cc252491d3 100644 --- a/erpnext/agriculture/desk_page/agriculture/agriculture.json +++ b/erpnext/agriculture/desk_page/agriculture/agriculture.json @@ -5,7 +5,7 @@ "developer_mode_only": 0, "disable_user_customization": 0, "docstatus": 0, - "doctype": "Desk Page", + "doctype": "Workspace", "extends_another_page": 0, "hide_custom": 0, "icon": "agriculture", diff --git a/erpnext/assets/desk_page/assets/assets.json b/erpnext/assets/desk_page/assets/assets.json index 58bdc68ef2a..c4015817583 100644 --- a/erpnext/assets/desk_page/assets/assets.json +++ b/erpnext/assets/desk_page/assets/assets.json @@ -10,7 +10,7 @@ "developer_mode_only": 0, "disable_user_customization": 0, "docstatus": 0, - "doctype": "Desk Page", + "doctype": "Workspace", "extends_another_page": 0, "hide_custom": 0, "icon": "assets", diff --git a/erpnext/buying/desk_page/buying/buying.json b/erpnext/buying/desk_page/buying/buying.json index 8e00f7fd9ac..6c9c0f3011b 100644 --- a/erpnext/buying/desk_page/buying/buying.json +++ b/erpnext/buying/desk_page/buying/buying.json @@ -12,7 +12,7 @@ "developer_mode_only": 0, "disable_user_customization": 0, "docstatus": 0, - "doctype": "Desk Page", + "doctype": "Workspace", "extends_another_page": 0, "hide_custom": 0, "icon": "buying", diff --git a/erpnext/crm/desk_page/crm/crm.json b/erpnext/crm/desk_page/crm/crm.json index 724ff77b050..b4fb7d8abe9 100644 --- a/erpnext/crm/desk_page/crm/crm.json +++ b/erpnext/crm/desk_page/crm/crm.json @@ -9,7 +9,7 @@ "developer_mode_only": 0, "disable_user_customization": 0, "docstatus": 0, - "doctype": "Desk Page", + "doctype": "Workspace", "extends_another_page": 0, "hide_custom": 0, "icon": "crm", diff --git a/erpnext/education/desk_page/education/education.json b/erpnext/education/desk_page/education/education.json index 04db5a43669..bf7496146d9 100644 --- a/erpnext/education/desk_page/education/education.json +++ b/erpnext/education/desk_page/education/education.json @@ -10,7 +10,7 @@ "developer_mode_only": 0, "disable_user_customization": 0, "docstatus": 0, - "doctype": "Desk Page", + "doctype": "Workspace", "extends_another_page": 0, "hide_custom": 0, "icon": "education", diff --git a/erpnext/erpnext_integrations/desk_page/erpnext_integrations/erpnext_integrations.json b/erpnext/erpnext_integrations/desk_page/erpnext_integrations/erpnext_integrations.json index a36ca8ddb72..4a5e54edd2f 100644 --- a/erpnext/erpnext_integrations/desk_page/erpnext_integrations/erpnext_integrations.json +++ b/erpnext/erpnext_integrations/desk_page/erpnext_integrations/erpnext_integrations.json @@ -5,7 +5,7 @@ "developer_mode_only": 0, "disable_user_customization": 0, "docstatus": 0, - "doctype": "Desk Page", + "doctype": "Workspace", "extends": "Integrations", "extends_another_page": 1, "hide_custom": 1, diff --git a/erpnext/erpnext_integrations/desk_page/erpnext_integrations_settings/erpnext_integrations_settings.json b/erpnext/erpnext_integrations/desk_page/erpnext_integrations_settings/erpnext_integrations_settings.json index d5e61892432..d258d571318 100644 --- a/erpnext/erpnext_integrations/desk_page/erpnext_integrations_settings/erpnext_integrations_settings.json +++ b/erpnext/erpnext_integrations/desk_page/erpnext_integrations_settings/erpnext_integrations_settings.json @@ -5,7 +5,7 @@ "developer_mode_only": 0, "disable_user_customization": 0, "docstatus": 0, - "doctype": "Desk Page", + "doctype": "Workspace", "extends": "Settings", "extends_another_page": 1, "hide_custom": 0, diff --git a/erpnext/healthcare/desk_page/healthcare/healthcare.json b/erpnext/healthcare/desk_page/healthcare/healthcare.json index cf1f6246cbf..b93dda2e879 100644 --- a/erpnext/healthcare/desk_page/healthcare/healthcare.json +++ b/erpnext/healthcare/desk_page/healthcare/healthcare.json @@ -11,7 +11,7 @@ "developer_mode_only": 0, "disable_user_customization": 0, "docstatus": 0, - "doctype": "Desk Page", + "doctype": "Workspace", "extends_another_page": 0, "hide_custom": 0, "icon": "healthcare", diff --git a/erpnext/hr/desk_page/hr/hr.json b/erpnext/hr/desk_page/hr/hr.json index 218699314cb..7f1af845f88 100644 --- a/erpnext/hr/desk_page/hr/hr.json +++ b/erpnext/hr/desk_page/hr/hr.json @@ -10,7 +10,7 @@ "developer_mode_only": 0, "disable_user_customization": 0, "docstatus": 0, - "doctype": "Desk Page", + "doctype": "Workspace", "extends_another_page": 0, "hide_custom": 0, "icon": "hr", diff --git a/erpnext/loan_management/desk_page/loan/loan.json b/erpnext/loan_management/desk_page/loan/loan.json index 6ef1737e1ab..80d8a8049e4 100644 --- a/erpnext/loan_management/desk_page/loan/loan.json +++ b/erpnext/loan_management/desk_page/loan/loan.json @@ -5,7 +5,7 @@ "developer_mode_only": 0, "disable_user_customization": 0, "docstatus": 0, - "doctype": "Desk Page", + "doctype": "Workspace", "extends_another_page": 0, "hide_custom": 0, "icon": "loan", diff --git a/erpnext/manufacturing/desk_page/manufacturing/manufacturing.json b/erpnext/manufacturing/desk_page/manufacturing/manufacturing.json index e856a987e38..a355203e4d7 100644 --- a/erpnext/manufacturing/desk_page/manufacturing/manufacturing.json +++ b/erpnext/manufacturing/desk_page/manufacturing/manufacturing.json @@ -9,7 +9,7 @@ "developer_mode_only": 0, "disable_user_customization": 0, "docstatus": 0, - "doctype": "Desk Page", + "doctype": "Workspace", "extends_another_page": 0, "hide_custom": 0, "icon": "organization", diff --git a/erpnext/non_profit/desk_page/non_profit/non_profit.json b/erpnext/non_profit/desk_page/non_profit/non_profit.json index be92d606107..da2a514810b 100644 --- a/erpnext/non_profit/desk_page/non_profit/non_profit.json +++ b/erpnext/non_profit/desk_page/non_profit/non_profit.json @@ -5,7 +5,7 @@ "developer_mode_only": 0, "disable_user_customization": 0, "docstatus": 0, - "doctype": "Desk Page", + "doctype": "Workspace", "extends_another_page": 0, "hide_custom": 0, "icon": "non-profit", diff --git a/erpnext/payroll/desk_page/payroll/payroll.json b/erpnext/payroll/desk_page/payroll/payroll.json index 137fad27797..814973063da 100644 --- a/erpnext/payroll/desk_page/payroll/payroll.json +++ b/erpnext/payroll/desk_page/payroll/payroll.json @@ -10,7 +10,7 @@ "developer_mode_only": 0, "disable_user_customization": 0, "docstatus": 0, - "doctype": "Desk Page", + "doctype": "Workspace", "extends_another_page": 0, "hide_custom": 0, "icon": "money-coins-1", diff --git a/erpnext/projects/desk_page/projects/projects.json b/erpnext/projects/desk_page/projects/projects.json index 5c8ab993f38..dbbd7e1458e 100644 --- a/erpnext/projects/desk_page/projects/projects.json +++ b/erpnext/projects/desk_page/projects/projects.json @@ -10,7 +10,7 @@ "developer_mode_only": 0, "disable_user_customization": 0, "docstatus": 0, - "doctype": "Desk Page", + "doctype": "Workspace", "extends_another_page": 0, "hide_custom": 0, "icon": "project", diff --git a/erpnext/quality_management/desk_page/quality/quality.json b/erpnext/quality_management/desk_page/quality/quality.json index aaee9ab8572..e5fef435505 100644 --- a/erpnext/quality_management/desk_page/quality/quality.json +++ b/erpnext/quality_management/desk_page/quality/quality.json @@ -5,7 +5,7 @@ "developer_mode_only": 0, "disable_user_customization": 0, "docstatus": 0, - "doctype": "Desk Page", + "doctype": "Workspace", "extends_another_page": 0, "hide_custom": 0, "icon": "quality", diff --git a/erpnext/selling/desk_page/retail/retail.json b/erpnext/selling/desk_page/retail/retail.json index e9beef5f91d..e20f8347c25 100644 --- a/erpnext/selling/desk_page/retail/retail.json +++ b/erpnext/selling/desk_page/retail/retail.json @@ -5,7 +5,7 @@ "developer_mode_only": 0, "disable_user_customization": 0, "docstatus": 0, - "doctype": "Desk Page", + "doctype": "Workspace", "extends_another_page": 0, "hide_custom": 0, "icon": "retail", diff --git a/erpnext/selling/desk_page/selling/selling.json b/erpnext/selling/desk_page/selling/selling.json index 0bbf17fcae4..879034a0dfc 100644 --- a/erpnext/selling/desk_page/selling/selling.json +++ b/erpnext/selling/desk_page/selling/selling.json @@ -11,7 +11,7 @@ "developer_mode_only": 0, "disable_user_customization": 0, "docstatus": 0, - "doctype": "Desk Page", + "doctype": "Workspace", "extends_another_page": 0, "hide_custom": 1, "icon": "sell", diff --git a/erpnext/setup/desk_page/erpnext_settings/erpnext_settings.json b/erpnext/setup/desk_page/erpnext_settings/erpnext_settings.json index a2224515e54..014f4095c15 100644 --- a/erpnext/setup/desk_page/erpnext_settings/erpnext_settings.json +++ b/erpnext/setup/desk_page/erpnext_settings/erpnext_settings.json @@ -5,7 +5,7 @@ "developer_mode_only": 0, "disable_user_customization": 0, "docstatus": 0, - "doctype": "Desk Page", + "doctype": "Workspace", "extends": "Settings", "extends_another_page": 1, "hide_custom": 0, diff --git a/erpnext/setup/desk_page/home/home.json b/erpnext/setup/desk_page/home/home.json index fa164d3a03c..c041bb32fb3 100644 --- a/erpnext/setup/desk_page/home/home.json +++ b/erpnext/setup/desk_page/home/home.json @@ -5,7 +5,7 @@ "developer_mode_only": 0, "disable_user_customization": 0, "docstatus": 0, - "doctype": "Desk Page", + "doctype": "Workspace", "extends_another_page": 0, "hide_custom": 0, "icon": "getting-started", diff --git a/erpnext/stock/desk_page/stock/stock.json b/erpnext/stock/desk_page/stock/stock.json index fbf8326088b..3221dc4365c 100644 --- a/erpnext/stock/desk_page/stock/stock.json +++ b/erpnext/stock/desk_page/stock/stock.json @@ -10,7 +10,7 @@ "developer_mode_only": 0, "disable_user_customization": 0, "docstatus": 0, - "doctype": "Desk Page", + "doctype": "Workspace", "extends_another_page": 0, "hide_custom": 0, "icon": "stock", diff --git a/erpnext/support/desk_page/support/support.json b/erpnext/support/desk_page/support/support.json index 20e60c062bf..01a8676f05d 100644 --- a/erpnext/support/desk_page/support/support.json +++ b/erpnext/support/desk_page/support/support.json @@ -5,7 +5,7 @@ "developer_mode_only": 0, "disable_user_customization": 0, "docstatus": 0, - "doctype": "Desk Page", + "doctype": "Workspace", "extends_another_page": 0, "hide_custom": 0, "icon": "support", diff --git a/erpnext/utilities/desk_page/utilities/utilities.json b/erpnext/utilities/desk_page/utilities/utilities.json index df17303924a..2f9250ee45c 100644 --- a/erpnext/utilities/desk_page/utilities/utilities.json +++ b/erpnext/utilities/desk_page/utilities/utilities.json @@ -5,7 +5,7 @@ "developer_mode_only": 0, "disable_user_customization": 0, "docstatus": 0, - "doctype": "Desk Page", + "doctype": "Workspace", "extends_another_page": 0, "hide_custom": 0, "idx": 0, From 2fa3cac81496cc611f9f227e985022aa3127e495 Mon Sep 17 00:00:00 2001 From: Shivam Mishra Date: Thu, 3 Dec 2020 15:48:57 +0530 Subject: [PATCH 148/477] feat: update workspace folders --- .../accounts/{desk_page => workspace}/accounting/accounting.json | 0 .../{desk_page => workspace}/agriculture/agriculture.json | 0 erpnext/assets/{desk_page => workspace}/assets/assets.json | 0 erpnext/buying/{desk_page => workspace}/buying/buying.json | 0 erpnext/crm/{desk_page => workspace}/crm/crm.json | 0 .../education/{desk_page => workspace}/education/education.json | 0 .../erpnext_integrations/erpnext_integrations.json | 0 .../erpnext_integrations_settings.json | 0 .../{desk_page => workspace}/healthcare/healthcare.json | 0 erpnext/hr/{desk_page => workspace}/hr/hr.json | 0 erpnext/loan_management/{desk_page => workspace}/loan/loan.json | 0 .../{desk_page => workspace}/manufacturing/manufacturing.json | 0 .../{desk_page => workspace}/non_profit/non_profit.json | 0 erpnext/payroll/{desk_page => workspace}/payroll/payroll.json | 0 erpnext/projects/{desk_page => workspace}/projects/projects.json | 0 .../{desk_page => workspace}/quality/quality.json | 0 erpnext/selling/{desk_page => workspace}/retail/retail.json | 0 erpnext/selling/{desk_page => workspace}/selling/selling.json | 0 .../erpnext_settings/erpnext_settings.json | 0 erpnext/setup/{desk_page => workspace}/home/home.json | 0 erpnext/stock/{desk_page => workspace}/stock/stock.json | 0 erpnext/support/{desk_page => workspace}/support/support.json | 0 .../utilities/{desk_page => workspace}/utilities/utilities.json | 0 23 files changed, 0 insertions(+), 0 deletions(-) rename erpnext/accounts/{desk_page => workspace}/accounting/accounting.json (100%) rename erpnext/agriculture/{desk_page => workspace}/agriculture/agriculture.json (100%) rename erpnext/assets/{desk_page => workspace}/assets/assets.json (100%) rename erpnext/buying/{desk_page => workspace}/buying/buying.json (100%) rename erpnext/crm/{desk_page => workspace}/crm/crm.json (100%) rename erpnext/education/{desk_page => workspace}/education/education.json (100%) rename erpnext/erpnext_integrations/{desk_page => workspace}/erpnext_integrations/erpnext_integrations.json (100%) rename erpnext/erpnext_integrations/{desk_page => workspace}/erpnext_integrations_settings/erpnext_integrations_settings.json (100%) rename erpnext/healthcare/{desk_page => workspace}/healthcare/healthcare.json (100%) rename erpnext/hr/{desk_page => workspace}/hr/hr.json (100%) rename erpnext/loan_management/{desk_page => workspace}/loan/loan.json (100%) rename erpnext/manufacturing/{desk_page => workspace}/manufacturing/manufacturing.json (100%) rename erpnext/non_profit/{desk_page => workspace}/non_profit/non_profit.json (100%) rename erpnext/payroll/{desk_page => workspace}/payroll/payroll.json (100%) rename erpnext/projects/{desk_page => workspace}/projects/projects.json (100%) rename erpnext/quality_management/{desk_page => workspace}/quality/quality.json (100%) rename erpnext/selling/{desk_page => workspace}/retail/retail.json (100%) rename erpnext/selling/{desk_page => workspace}/selling/selling.json (100%) rename erpnext/setup/{desk_page => workspace}/erpnext_settings/erpnext_settings.json (100%) rename erpnext/setup/{desk_page => workspace}/home/home.json (100%) rename erpnext/stock/{desk_page => workspace}/stock/stock.json (100%) rename erpnext/support/{desk_page => workspace}/support/support.json (100%) rename erpnext/utilities/{desk_page => workspace}/utilities/utilities.json (100%) diff --git a/erpnext/accounts/desk_page/accounting/accounting.json b/erpnext/accounts/workspace/accounting/accounting.json similarity index 100% rename from erpnext/accounts/desk_page/accounting/accounting.json rename to erpnext/accounts/workspace/accounting/accounting.json diff --git a/erpnext/agriculture/desk_page/agriculture/agriculture.json b/erpnext/agriculture/workspace/agriculture/agriculture.json similarity index 100% rename from erpnext/agriculture/desk_page/agriculture/agriculture.json rename to erpnext/agriculture/workspace/agriculture/agriculture.json diff --git a/erpnext/assets/desk_page/assets/assets.json b/erpnext/assets/workspace/assets/assets.json similarity index 100% rename from erpnext/assets/desk_page/assets/assets.json rename to erpnext/assets/workspace/assets/assets.json diff --git a/erpnext/buying/desk_page/buying/buying.json b/erpnext/buying/workspace/buying/buying.json similarity index 100% rename from erpnext/buying/desk_page/buying/buying.json rename to erpnext/buying/workspace/buying/buying.json diff --git a/erpnext/crm/desk_page/crm/crm.json b/erpnext/crm/workspace/crm/crm.json similarity index 100% rename from erpnext/crm/desk_page/crm/crm.json rename to erpnext/crm/workspace/crm/crm.json diff --git a/erpnext/education/desk_page/education/education.json b/erpnext/education/workspace/education/education.json similarity index 100% rename from erpnext/education/desk_page/education/education.json rename to erpnext/education/workspace/education/education.json diff --git a/erpnext/erpnext_integrations/desk_page/erpnext_integrations/erpnext_integrations.json b/erpnext/erpnext_integrations/workspace/erpnext_integrations/erpnext_integrations.json similarity index 100% rename from erpnext/erpnext_integrations/desk_page/erpnext_integrations/erpnext_integrations.json rename to erpnext/erpnext_integrations/workspace/erpnext_integrations/erpnext_integrations.json diff --git a/erpnext/erpnext_integrations/desk_page/erpnext_integrations_settings/erpnext_integrations_settings.json b/erpnext/erpnext_integrations/workspace/erpnext_integrations_settings/erpnext_integrations_settings.json similarity index 100% rename from erpnext/erpnext_integrations/desk_page/erpnext_integrations_settings/erpnext_integrations_settings.json rename to erpnext/erpnext_integrations/workspace/erpnext_integrations_settings/erpnext_integrations_settings.json diff --git a/erpnext/healthcare/desk_page/healthcare/healthcare.json b/erpnext/healthcare/workspace/healthcare/healthcare.json similarity index 100% rename from erpnext/healthcare/desk_page/healthcare/healthcare.json rename to erpnext/healthcare/workspace/healthcare/healthcare.json diff --git a/erpnext/hr/desk_page/hr/hr.json b/erpnext/hr/workspace/hr/hr.json similarity index 100% rename from erpnext/hr/desk_page/hr/hr.json rename to erpnext/hr/workspace/hr/hr.json diff --git a/erpnext/loan_management/desk_page/loan/loan.json b/erpnext/loan_management/workspace/loan/loan.json similarity index 100% rename from erpnext/loan_management/desk_page/loan/loan.json rename to erpnext/loan_management/workspace/loan/loan.json diff --git a/erpnext/manufacturing/desk_page/manufacturing/manufacturing.json b/erpnext/manufacturing/workspace/manufacturing/manufacturing.json similarity index 100% rename from erpnext/manufacturing/desk_page/manufacturing/manufacturing.json rename to erpnext/manufacturing/workspace/manufacturing/manufacturing.json diff --git a/erpnext/non_profit/desk_page/non_profit/non_profit.json b/erpnext/non_profit/workspace/non_profit/non_profit.json similarity index 100% rename from erpnext/non_profit/desk_page/non_profit/non_profit.json rename to erpnext/non_profit/workspace/non_profit/non_profit.json diff --git a/erpnext/payroll/desk_page/payroll/payroll.json b/erpnext/payroll/workspace/payroll/payroll.json similarity index 100% rename from erpnext/payroll/desk_page/payroll/payroll.json rename to erpnext/payroll/workspace/payroll/payroll.json diff --git a/erpnext/projects/desk_page/projects/projects.json b/erpnext/projects/workspace/projects/projects.json similarity index 100% rename from erpnext/projects/desk_page/projects/projects.json rename to erpnext/projects/workspace/projects/projects.json diff --git a/erpnext/quality_management/desk_page/quality/quality.json b/erpnext/quality_management/workspace/quality/quality.json similarity index 100% rename from erpnext/quality_management/desk_page/quality/quality.json rename to erpnext/quality_management/workspace/quality/quality.json diff --git a/erpnext/selling/desk_page/retail/retail.json b/erpnext/selling/workspace/retail/retail.json similarity index 100% rename from erpnext/selling/desk_page/retail/retail.json rename to erpnext/selling/workspace/retail/retail.json diff --git a/erpnext/selling/desk_page/selling/selling.json b/erpnext/selling/workspace/selling/selling.json similarity index 100% rename from erpnext/selling/desk_page/selling/selling.json rename to erpnext/selling/workspace/selling/selling.json diff --git a/erpnext/setup/desk_page/erpnext_settings/erpnext_settings.json b/erpnext/setup/workspace/erpnext_settings/erpnext_settings.json similarity index 100% rename from erpnext/setup/desk_page/erpnext_settings/erpnext_settings.json rename to erpnext/setup/workspace/erpnext_settings/erpnext_settings.json diff --git a/erpnext/setup/desk_page/home/home.json b/erpnext/setup/workspace/home/home.json similarity index 100% rename from erpnext/setup/desk_page/home/home.json rename to erpnext/setup/workspace/home/home.json diff --git a/erpnext/stock/desk_page/stock/stock.json b/erpnext/stock/workspace/stock/stock.json similarity index 100% rename from erpnext/stock/desk_page/stock/stock.json rename to erpnext/stock/workspace/stock/stock.json diff --git a/erpnext/support/desk_page/support/support.json b/erpnext/support/workspace/support/support.json similarity index 100% rename from erpnext/support/desk_page/support/support.json rename to erpnext/support/workspace/support/support.json diff --git a/erpnext/utilities/desk_page/utilities/utilities.json b/erpnext/utilities/workspace/utilities/utilities.json similarity index 100% rename from erpnext/utilities/desk_page/utilities/utilities.json rename to erpnext/utilities/workspace/utilities/utilities.json From a6a37b7c8174dd05ca710c45a1e69d25468f0baf Mon Sep 17 00:00:00 2001 From: Saqib Ansari Date: Thu, 3 Dec 2020 19:24:07 +0530 Subject: [PATCH 149/477] fix: scroll elements --- erpnext/public/scss/point-of-sale.scss | 38 +++++++++---------- .../page/point_of_sale/pos_item_cart.js | 8 +--- 2 files changed, 20 insertions(+), 26 deletions(-) diff --git a/erpnext/public/scss/point-of-sale.scss b/erpnext/public/scss/point-of-sale.scss index f9757384cb8..3e7d5dae828 100644 --- a/erpnext/public/scss/point-of-sale.scss +++ b/erpnext/public/scss/point-of-sale.scss @@ -75,22 +75,14 @@ background-color: var(--gray-50); } - .sticky-element { - position: sticky; - top: -1px; - z-index: 1; - } - > .items-selector { @extend .pos-card; grid-column: span 6 / span 6; display: flex; flex-direction: column; - overflow-y: scroll; - overflow-x: hidden; + overflow: hidden; > .filter-section { - @extend .sticky-element; display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); background-color: var(--fg-color); @@ -124,6 +116,14 @@ gap: var(--margin-lg); padding: var(--padding-lg); padding-top: var(--padding-xs); + overflow-y: scroll; + overflow-x: hidden; + + &:after { + content: ""; + display: block; + height: 1px; + } > .item-wrapper { @extend .pointer-no-select; @@ -185,6 +185,7 @@ display: flex; flex-direction: column; padding: var(--padding-md) var(--padding-lg); + overflow: hidden; > .customer-field { display: flex; @@ -193,7 +194,6 @@ } > .customer-details { - @extend .sticky-element; display: flex; flex-direction: column; background-color: var(--fg-color); @@ -284,6 +284,11 @@ > .customer-transactions { height: 100%; + overflow-x: hidden; + overflow-y: scroll; + margin-right: -12px; + padding-right: 12px; + margin-left: -10px; > .no-transactions-placeholder { height: 100%; @@ -899,11 +904,9 @@ grid-column: span 4 / span 4; display: none; flex-direction: column; - overflow-y: scroll; - overflow-x: hidden; + overflow: hidden; > .filter-section { - @extend .sticky-element; display: flex; flex-direction: column; background-color: var(--fg-color); @@ -927,17 +930,17 @@ > .invoices-container { padding: var(--padding-lg); padding-top: 0px; + overflow-x: hidden; + overflow-y: scroll; } } > .past-order-summary { - // @extend .pos-card; display: none; grid-column: span 6 / span 6; flex-direction: column; align-items: center; justify-content: center; - // padding: var(--padding-lg); > .no-summary-placeholder { display: flex; @@ -1029,14 +1032,12 @@ align-items: center; justify-content: space-between; padding: var(--padding-sm) var(--padding-md); - // border-bottom: 1px solid var(--gray-300); } > .taxes-wrapper { display: flex; flex-direction: column; padding: 0px var(--padding-md); - // border-bottom: 1px solid var(--gray-300); > .tax-row { display: flex; @@ -1050,7 +1051,6 @@ display: flex; align-items: center; padding: var(--padding-sm) var(--padding-md); - // border-bottom: 1px solid var(--gray-300); > .item-name { @extend .nowrap; @@ -1081,9 +1081,7 @@ } > .grand-total { - // font-size: var(--text-lg); font-weight: 700; - // padding: var(--padding-md); } > .payments { diff --git a/erpnext/selling/page/point_of_sale/pos_item_cart.js b/erpnext/selling/page/point_of_sale/pos_item_cart.js index efe716de6ce..3124e913256 100644 --- a/erpnext/selling/page/point_of_sale/pos_item_cart.js +++ b/erpnext/selling/page/point_of_sale/pos_item_cart.js @@ -791,9 +791,7 @@ erpnext.PointOfSale.ItemCart = class { this.$cart_container.css('display', 'none'); this.$customer_section.css({ 'height': '100%', - 'padding-top': '0px', - 'overflow-x': 'hidden', - 'overflow-y': 'scroll' + 'padding-top': '0px' }); this.$customer_section.find('.customer-details').html( `
    @@ -829,9 +827,7 @@ erpnext.PointOfSale.ItemCart = class { this.$cart_container.css('display', 'flex'); this.$customer_section.css({ 'height': '', - 'padding-top': '', - 'overflow-x': '', - 'overflow-y': '' + 'padding-top': '' }); this.update_customer_section(); From f4d645f87a7b751c3d28df172f1d09177b665cde Mon Sep 17 00:00:00 2001 From: Saqib Ansari Date: Thu, 3 Dec 2020 19:30:12 +0530 Subject: [PATCH 150/477] perf: async pos app start --- .../page/point_of_sale/pos_controller.js | 39 +++---------------- 1 file changed, 6 insertions(+), 33 deletions(-) diff --git a/erpnext/selling/page/point_of_sale/pos_controller.js b/erpnext/selling/page/point_of_sale/pos_controller.js index 155d35dd8f7..74d212227aa 100644 --- a/erpnext/selling/page/point_of_sale/pos_controller.js +++ b/erpnext/selling/page/point_of_sale/pos_controller.js @@ -118,28 +118,11 @@ erpnext.PointOfSale.Controller = class { this.make_app(); } - set_opening_entry_status() { - this.page.set_title_sub( - ` - - Opened at ${moment(this.pos_opening_time).format("Do MMMM, h:mma")} - - `); - } - make_app() { - return frappe.run_serially([ - () => frappe.dom.freeze(), - () => { - this.set_opening_entry_status(); - this.prepare_dom(); - this.prepare_components(); - this.prepare_menu(); - }, - () => this.make_new_invoice(), - () => frappe.dom.unfreeze(), - () => this.page.set_title(__('Point of Sale')), - ]); + this.prepare_dom(); + this.prepare_components(); + this.prepare_menu(); + this.make_new_invoice(); } prepare_dom() { @@ -416,8 +399,6 @@ erpnext.PointOfSale.Controller = class { }) } - - toggle_recent_order_list(show) { this.toggle_components(!show); this.recent_order_list.toggle_component(show); @@ -434,10 +415,12 @@ erpnext.PointOfSale.Controller = class { make_new_invoice() { return frappe.run_serially([ + () => frappe.dom.freeze(), () => this.make_sales_invoice_frm(), () => this.set_pos_profile_data(), () => this.set_pos_profile_status(), () => this.cart.load_invoice(), + () => frappe.dom.unfreeze() ]); } @@ -494,16 +477,6 @@ erpnext.PointOfSale.Controller = class { return this.frm.trigger("set_pos_data"); } - raise_exception_for_pos_profile() { - setTimeout(() => frappe.set_route('List', 'POS Profile'), 2000); - frappe.throw(__("POS Profile is required to use Point-of-Sale")); - } - - set_invoice_status() { - const [status, indicator] = frappe.listview_settings["POS Invoice"].get_indicator(this.frm.doc); - this.page.set_indicator(status, indicator); - } - set_pos_profile_status() { this.page.set_indicator(this.pos_profile, "blue"); } From 7b2d518059f1a131a0ece9e6872c5ed8c4a93d04 Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Fri, 4 Dec 2020 11:28:26 +0530 Subject: [PATCH 151/477] fix: Dimension filters in accounting reports --- erpnext/public/js/utils.js | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/erpnext/public/js/utils.js b/erpnext/public/js/utils.js index 891bbe5b598..2635d47f886 100755 --- a/erpnext/public/js/utils.js +++ b/erpnext/public/js/utils.js @@ -194,15 +194,21 @@ $.extend(erpnext.utils, { add_dimensions: function(report_name, index) { let filters = frappe.query_reports[report_name].filters; - erpnext.dimension_filters.forEach((dimension) => { - let found = filters.some(el => el.fieldname === dimension['fieldname']); + frappe.call({ + method: "erpnext.accounts.doctype.accounting_dimension.accounting_dimension.get_dimensions", + callback: function(r) { + let accounting_dimensions = r.message[0]; + accounting_dimensions.forEach((dimension) => { + let found = filters.some(el => el.fieldname === dimension['fieldname']); - if (!found) { - filters.splice(index, 0 ,{ - "fieldname": dimension["fieldname"], - "label": __(dimension["label"]), - "fieldtype": "Link", - "options": dimension["document_type"] + if (!found) { + filters.splice(index, 0 ,{ + "fieldname": dimension["fieldname"], + "label": __(dimension["label"]), + "fieldtype": "Link", + "options": dimension["document_type"] + }); + } }); } }); From 7fef622b136c4e7da72651a03c120878e2a6d386 Mon Sep 17 00:00:00 2001 From: pateljannat Date: Fri, 4 Dec 2020 19:18:36 +0530 Subject: [PATCH 152/477] fix: drop ship partial order fixed --- erpnext/selling/doctype/sales_order/sales_order.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/selling/doctype/sales_order/sales_order.py b/erpnext/selling/doctype/sales_order/sales_order.py index ae227e0110e..3e1c82f9616 100755 --- a/erpnext/selling/doctype/sales_order/sales_order.py +++ b/erpnext/selling/doctype/sales_order/sales_order.py @@ -831,7 +831,7 @@ def make_purchase_order_for_default_supplier(source_name, selected_items=[], tar for supplier in suppliers: po = frappe.get_list("Purchase Order", filters={"sales_order":source_name, "supplier":supplier, "docstatus": ("<", "2")}) - if len(po) == 0: + if len(po) == 0 or any( item.get("delivered_by_supplier") == 1 for item in selected_items): doc = get_mapped_doc("Sales Order", source_name, { "Sales Order": { "doctype": "Purchase Order", From c32ac223ed181d3a1a122775b93d6e4672d2e38f Mon Sep 17 00:00:00 2001 From: pateljannat Date: Mon, 7 Dec 2020 14:53:15 +0530 Subject: [PATCH 153/477] feat: adding task field in project template --- .../project_template_task.json | 195 ++---------------- erpnext/projects/doctype/task/task.json | 21 +- 2 files changed, 32 insertions(+), 184 deletions(-) diff --git a/erpnext/projects/doctype/project_template_task/project_template_task.json b/erpnext/projects/doctype/project_template_task/project_template_task.json index 8644d897bb0..80c510db1b0 100644 --- a/erpnext/projects/doctype/project_template_task/project_template_task.json +++ b/erpnext/projects/doctype/project_template_task/project_template_task.json @@ -1,203 +1,32 @@ { - "allow_copy": 0, - "allow_events_in_timeline": 0, - "allow_guest_to_view": 0, - "allow_import": 0, - "allow_rename": 0, - "beta": 0, + "actions": [], "creation": "2019-02-18 17:24:41.830096", - "custom": 0, - "docstatus": 0, "doctype": "DocType", - "document_type": "", "editable_grid": 1, "engine": "InnoDB", + "field_order": [ + "task" + ], "fields": [ { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "subject", - "fieldtype": "Data", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, + "fieldname": "task", + "fieldtype": "Link", "in_list_view": 1, - "in_standard_filter": 0, - "label": "Subject", - "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": 1, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "start", - "fieldtype": "Int", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Begin On (Days)", - "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": 1, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "duration", - "fieldtype": "Int", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Duration (Days)", - "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": 1, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "task_weight", - "fieldtype": "Float", - "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": "Task Weight", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "description", - "fieldtype": "Text Editor", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Description", - "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 + "label": "Task", + "options": "Task", + "reqd": 1 } ], - "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": "2019-02-18 18:30:22.688966", + "links": [], + "modified": "2020-12-07 13:28:40.961810", "modified_by": "Administrator", "module": "Projects", "name": "Project Template Task", - "name_case": "", "owner": "Administrator", "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_views": 0 + "track_changes": 1 } \ No newline at end of file diff --git a/erpnext/projects/doctype/task/task.json b/erpnext/projects/doctype/task/task.json index 27f1a71a528..a9e3d9bc0fe 100644 --- a/erpnext/projects/doctype/task/task.json +++ b/erpnext/projects/doctype/task/task.json @@ -12,6 +12,7 @@ "issue", "type", "is_group", + "is_template", "column_break0", "status", "priority", @@ -22,9 +23,11 @@ "sb_timeline", "exp_start_date", "expected_time", + "start", "column_break_11", "exp_end_date", "progress", + "duration", "is_milestone", "sb_details", "description", @@ -360,6 +363,22 @@ "label": "Completed By", "no_copy": 1, "options": "User" + }, + { + "default": "0", + "fieldname": "is_template", + "fieldtype": "Check", + "label": "Is Template" + }, + { + "fieldname": "start", + "fieldtype": "Int", + "label": "Begin On (Days)" + }, + { + "fieldname": "duration", + "fieldtype": "Int", + "label": "Duration (Days)" } ], "icon": "fa fa-check", @@ -367,7 +386,7 @@ "is_tree": 1, "links": [], "max_attachments": 5, - "modified": "2020-07-03 12:36:04.960457", + "modified": "2020-12-07 13:26:53.614689", "modified_by": "Administrator", "module": "Projects", "name": "Task", From 5597e386b437ce7fda30960005d64d5fcc00d6a9 Mon Sep 17 00:00:00 2001 From: pateljannat Date: Mon, 7 Dec 2020 15:53:45 +0530 Subject: [PATCH 154/477] fix: added test for drop ship partial order --- .../doctype/sales_order/test_sales_order.py | 50 +++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/erpnext/selling/doctype/sales_order/test_sales_order.py b/erpnext/selling/doctype/sales_order/test_sales_order.py index a33d401b572..1d11ad6a7e4 100644 --- a/erpnext/selling/doctype/sales_order/test_sales_order.py +++ b/erpnext/selling/doctype/sales_order/test_sales_order.py @@ -772,6 +772,56 @@ class TestSalesOrder(unittest.TestCase): so.load_from_db() so.cancel() + def test_drop_shipping_partial_order(self): + from erpnext.selling.doctype.sales_order.sales_order import make_purchase_order_for_default_supplier, \ + update_status as so_update_status + + # make items + po_item1 = make_item("_Test Item for Drop Shipping 1", {"is_stock_item": 1, "delivered_by_supplier": 1}) + po_item2 = make_item("_Test Item for Drop Shipping 2", {"is_stock_item": 1, "delivered_by_supplier": 1}) + + so_items = [ + { + "item_code": po_item1.item_code, + "warehouse": "", + "qty": 2, + "rate": 400, + "delivered_by_supplier": 1, + "supplier": '_Test Supplier' + }, + { + "item_code": po_item2.item_code, + "warehouse": "_Test Warehouse - _TC", + "qty": 2, + "rate": 300, + "conversion_factor": 1.0 + } + ] + + # create so and po + so = make_sales_order(item_list=so_items, do_not_submit=True) + so.submit() + + # create po for only one item + po = make_purchase_order_for_default_supplier(so.name, selected_items=[so_items[0]]) + po.submit() + + self.assertEqual(so.customer, po.customer) + self.assertEqual(po.items[0].sales_order, so.name) + self.assertEqual(po.items[0].item_code, po_item.item_code) + #test po_item length + self.assertEqual(len(po.items), 1) + + # create po for remaining item + po = make_purchase_order_for_default_supplier(so.name, selected_items=[so_items[1]]) + po.submit() + + # teardown + so_update_status("Draft", so.name) + po.cancel() + so.load_from_db() + so.cancel() + def test_reserved_qty_for_closing_so(self): bin = frappe.get_all("Bin", filters={"item_code": "_Test Item", "warehouse": "_Test Warehouse - _TC"}, fields=["reserved_qty"]) From 89624ad6226cdd09a413589b1b87a73607cf9d6d Mon Sep 17 00:00:00 2001 From: pateljannat Date: Mon, 7 Dec 2020 16:50:03 +0530 Subject: [PATCH 155/477] fix: sider issue fixed --- erpnext/selling/doctype/sales_order/test_sales_order.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/selling/doctype/sales_order/test_sales_order.py b/erpnext/selling/doctype/sales_order/test_sales_order.py index 1d11ad6a7e4..a0af49982b8 100644 --- a/erpnext/selling/doctype/sales_order/test_sales_order.py +++ b/erpnext/selling/doctype/sales_order/test_sales_order.py @@ -808,7 +808,7 @@ class TestSalesOrder(unittest.TestCase): self.assertEqual(so.customer, po.customer) self.assertEqual(po.items[0].sales_order, so.name) - self.assertEqual(po.items[0].item_code, po_item.item_code) + self.assertEqual(po.items[0].item_code, po_item1.item_code) #test po_item length self.assertEqual(len(po.items), 1) From 32e77d73cf992551fc6bf77a7c2607deed1aa7a2 Mon Sep 17 00:00:00 2001 From: pateljannat Date: Mon, 7 Dec 2020 17:39:37 +0530 Subject: [PATCH 156/477] fix: added supplier to second item in test --- erpnext/selling/doctype/sales_order/test_sales_order.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/erpnext/selling/doctype/sales_order/test_sales_order.py b/erpnext/selling/doctype/sales_order/test_sales_order.py index a0af49982b8..0ca58121f41 100644 --- a/erpnext/selling/doctype/sales_order/test_sales_order.py +++ b/erpnext/selling/doctype/sales_order/test_sales_order.py @@ -791,10 +791,11 @@ class TestSalesOrder(unittest.TestCase): }, { "item_code": po_item2.item_code, - "warehouse": "_Test Warehouse - _TC", + "warehouse": "", "qty": 2, - "rate": 300, - "conversion_factor": 1.0 + "rate": 400, + "delivered_by_supplier": 1, + "supplier": '_Test Supplier' } ] From 71b1a0ca7dd3e6cd4cbc91d50e6ffe4b62737ef0 Mon Sep 17 00:00:00 2001 From: pateljannat Date: Mon, 7 Dec 2020 19:09:29 +0530 Subject: [PATCH 157/477] fix: cancelling both test po created --- .../doctype/sales_order/test_sales_order.py | 22 ++++++++++--------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/erpnext/selling/doctype/sales_order/test_sales_order.py b/erpnext/selling/doctype/sales_order/test_sales_order.py index 0ca58121f41..5954602bea6 100644 --- a/erpnext/selling/doctype/sales_order/test_sales_order.py +++ b/erpnext/selling/doctype/sales_order/test_sales_order.py @@ -804,22 +804,24 @@ class TestSalesOrder(unittest.TestCase): so.submit() # create po for only one item - po = make_purchase_order_for_default_supplier(so.name, selected_items=[so_items[0]]) - po.submit() + po1 = make_purchase_order_for_default_supplier(so.name, selected_items=[so_items[0]]) + po1.submit() - self.assertEqual(so.customer, po.customer) - self.assertEqual(po.items[0].sales_order, so.name) - self.assertEqual(po.items[0].item_code, po_item1.item_code) - #test po_item length - self.assertEqual(len(po.items), 1) + self.assertEqual(so.customer, po1.customer) + self.assertEqual(po1.items[0].sales_order, so.name) + self.assertEqual(po1.items[0].item_code, po_item1.item_code) + #test po item length + self.assertEqual(len(po1.items), 1) # create po for remaining item - po = make_purchase_order_for_default_supplier(so.name, selected_items=[so_items[1]]) - po.submit() + po2 = make_purchase_order_for_default_supplier(so.name, selected_items=[so_items[1]]) + po2.submit() # teardown so_update_status("Draft", so.name) - po.cancel() + + po1.cancel() + po2.cancel() so.load_from_db() so.cancel() From fac4035f23b9b655da466ba6a436533b821b61d8 Mon Sep 17 00:00:00 2001 From: marination Date: Mon, 7 Dec 2020 21:35:49 +0530 Subject: [PATCH 158/477] feat: Apply Putaway Rules within transaction itself - Added checkbox 'Apply Putaway Rule' in PR and SE - Added link to rule in child tables - Rule is applied on Save - Validation for over receipt - Apply Rule on Stock Entry as well for Material Transfer and Receipt --- .../doctype/purchase_order/purchase_order.py | 2 - erpnext/controllers/stock_controller.py | 38 +++++ erpnext/public/js/controllers/buying.js | 23 +++ .../purchase_receipt/purchase_receipt.js | 4 + .../purchase_receipt/purchase_receipt.py | 7 + .../purchase_receipt_item.json | 12 +- .../doctype/putaway_rule/putaway_rule.py | 153 ++++++++++++------ .../stock/doctype/stock_entry/stock_entry.js | 4 + .../doctype/stock_entry/stock_entry.json | 10 +- .../stock/doctype/stock_entry/stock_entry.py | 8 + .../stock_entry_detail.json | 14 +- 11 files changed, 217 insertions(+), 58 deletions(-) diff --git a/erpnext/buying/doctype/purchase_order/purchase_order.py b/erpnext/buying/doctype/purchase_order/purchase_order.py index bb67eb92c07..d32e98e8d94 100644 --- a/erpnext/buying/doctype/purchase_order/purchase_order.py +++ b/erpnext/buying/doctype/purchase_order/purchase_order.py @@ -349,9 +349,7 @@ def close_or_unclose_purchase_orders(names, status): frappe.local.message_log = [] def set_missing_values(source, target): - from erpnext.stock.doctype.putaway_rule.putaway_rule import apply_putaway_rule target.ignore_pricing_rule = 1 - target.items = apply_putaway_rule(target.items, target.company) target.run_method("set_missing_values") target.run_method("calculate_taxes_and_totals") diff --git a/erpnext/controllers/stock_controller.py b/erpnext/controllers/stock_controller.py index 2d2fff8fd54..c7fadde16eb 100644 --- a/erpnext/controllers/stock_controller.py +++ b/erpnext/controllers/stock_controller.py @@ -6,6 +6,7 @@ import frappe, erpnext from frappe.utils import cint, flt, cstr, get_link_to_form, today, getdate from frappe import _ import frappe.defaults +from collections import defaultdict from erpnext.accounts.utils import get_fiscal_year from erpnext.accounts.general_ledger import make_gl_entries, make_reverse_gl_entries, process_gl_map from erpnext.controllers.accounts_controller import AccountsController @@ -23,6 +24,7 @@ class StockController(AccountsController): self.validate_inspection() self.validate_serialized_batch() self.validate_customer_provided_item() + self.validate_putaway_capacity() def make_gl_entries(self, gl_entries=None): if self.docstatus == 2: @@ -399,6 +401,42 @@ class StockController(AccountsController): if frappe.db.get_value('Item', d.item_code, 'is_customer_provided_item'): d.allow_zero_valuation_rate = 1 + def validate_putaway_capacity(self): + # if over receipt is attempted while 'apply putaway rule' is disabled + # and if rule was applied on the transaction, validate it. + from erpnext.stock.doctype.putaway_rule.putaway_rule import get_putaway_capacity + valid_doctype = self.doctype in ("Purchase Receipt", "Stock Entry") + rule_applied = any(item.get("putaway_rule") for item in self.get("items")) + + if valid_doctype and rule_applied and not self.apply_putaway_rule: + rule_map = defaultdict(dict) + for item in self.get("items"): + if item.get("putaway_rule"): + rule = item.get("putaway_rule") + disabled = frappe.db.get_value("Putaway Rule", rule, "disable") + if disabled: return # dont validate for disabled rule + stock_qty = flt(item.transfer_qty) if self.doctype == "Stock Entry" else flt(item.stock_qty) + warehouse_field = "t_warehouse" if self.doctype == "Stock Entry" else "warehouse" + if not rule_map[rule]: + rule_map[rule]["warehouse"] = item.get(warehouse_field) + rule_map[rule]["item"] = item.get("item_code") + rule_map[rule]["qty_put"] = 0 + rule_map[rule]["capacity"] = get_putaway_capacity(rule) + rule_map[rule]["qty_put"] += flt(stock_qty) + + for rule, values in rule_map.items(): + if flt(values["qty_put"]) > flt(values["capacity"]): + message = _("{0} qty of Item {1} is being received into Warehouse {2} with capacity {3}.") \ + .format( + frappe.bold(values["qty_put"]), frappe.bold(values["item"]), + frappe.bold(values["warehouse"]), frappe.bold(values["capacity"]) + ) + message += "

    " + rule_link = frappe.utils.get_link_to_form("Putaway Rule", rule) + message += _(" Please adjust the qty or edit {0} to proceed.").format(rule_link) + frappe.throw(msg=message, title=_("Over Receipt")) + return rule_map + def compare_existing_and_expected_gle(existing_gle, expected_gle): matched = True for entry in expected_gle: diff --git a/erpnext/public/js/controllers/buying.js b/erpnext/public/js/controllers/buying.js index 58ac38f0a85..ac48d451b9a 100644 --- a/erpnext/public/js/controllers/buying.js +++ b/erpnext/public/js/controllers/buying.js @@ -524,3 +524,26 @@ erpnext.buying.get_items_from_product_bundle = function(frm) { dialog.show(); } + +erpnext.apply_putaway_rule = (frm) => { + if (!frm.doc.company) { + frappe.throw({message:__("Please select a Company first."), title: __("Mandatory")}) + } + if (!frm.doc.items.length) return; + + frappe.call({ + method: "erpnext.stock.doctype.putaway_rule.putaway_rule.apply_putaway_rule", + args: { + items: frm.doc.items, + company: frm.doc.company + }, + callback: (result) => { + if(!result.exc) { + if(result.message) { + frm.doc.items = result.message; + frm.get_field("items").refresh(); + } + } + } + }); +} \ No newline at end of file diff --git a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.js b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.js index bc1d81d3565..45eb646d4b9 100644 --- a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.js +++ b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.js @@ -213,6 +213,10 @@ erpnext.stock.PurchaseReceiptController = erpnext.buying.BuyingController.extend }); }, + apply_putaway_rule: function() { + // if (this.frm.doc.apply_putaway_rule) erpnext.apply_putaway_rule(this.frm); + } + }); // for backward compatibility: combine new and previous states diff --git a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py index 2cc4679c8c6..511bae6f58c 100644 --- a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py +++ b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py @@ -70,6 +70,12 @@ class PurchaseReceipt(BuyingController): where name=`tabPurchase Invoice Item`.parent and is_return=1 and update_stock=1)""" }) + def before_save(self): + from erpnext.stock.doctype.putaway_rule.putaway_rule import apply_putaway_rule + + if self.get("items") and self.apply_putaway_rule: + self.items = apply_putaway_rule(self.doctype, self.get("items"), self.company) + def validate(self): self.validate_posting_time() super(PurchaseReceipt, self).validate() @@ -90,6 +96,7 @@ class PurchaseReceipt(BuyingController): if getdate(self.posting_date) > getdate(nowdate()): throw(_("Posting Date cannot be future date")) + def validate_cwip_accounts(self): for item in self.get('items'): if item.is_fixed_asset and is_cwip_accounting_enabled(item.asset_category): diff --git a/erpnext/stock/doctype/purchase_receipt_item/purchase_receipt_item.json b/erpnext/stock/doctype/purchase_receipt_item/purchase_receipt_item.json index c1e1f901ba6..fcbf6ccf6ea 100644 --- a/erpnext/stock/doctype/purchase_receipt_item/purchase_receipt_item.json +++ b/erpnext/stock/doctype/purchase_receipt_item/purchase_receipt_item.json @@ -72,6 +72,7 @@ "purchase_order_item", "material_request_item", "purchase_receipt_item", + "putaway_rule", "section_break_45", "allow_zero_valuation_rate", "bom", @@ -834,12 +835,21 @@ "collapsible": 1, "fieldname": "image_column", "fieldtype": "Column Break" + }, + { + "fieldname": "putaway_rule", + "fieldtype": "Link", + "label": "Putaway Rule", + "no_copy": 1, + "options": "Putaway Rule", + "print_hide": 1, + "read_only": 1 } ], "idx": 1, "istable": 1, "links": [], - "modified": "2020-04-28 19:01:21.154963", + "modified": "2020-11-26 12:16:14.897160", "modified_by": "Administrator", "module": "Stock", "name": "Purchase Receipt Item", diff --git a/erpnext/stock/doctype/putaway_rule/putaway_rule.py b/erpnext/stock/doctype/putaway_rule/putaway_rule.py index 606e190458c..8838bb75f1d 100644 --- a/erpnext/stock/doctype/putaway_rule/putaway_rule.py +++ b/erpnext/stock/doctype/putaway_rule/putaway_rule.py @@ -5,11 +5,14 @@ from __future__ import unicode_literals import frappe import copy +import json from collections import defaultdict +from six import string_types from frappe import _ -from frappe.utils import flt, floor, nowdate +from frappe.utils import flt, floor, nowdate, cint from frappe.model.document import Document from erpnext.stock.utils import get_stock_balance +from erpnext.stock.doctype.serial_no.serial_no import get_serial_nos class PutawayRule(Document): def validate(self): @@ -52,70 +55,50 @@ class PutawayRule(Document): def set_stock_capacity(self): self.stock_capacity = (flt(self.conversion_factor) or 1) * flt(self.capacity) -def get_ordered_putaway_rules(item_code, company): - """Returns an ordered list of putaway rules to apply on an item.""" - rules = frappe.get_all("Putaway Rule", - fields=["name", "item_code", "stock_capacity", "priority", "warehouse"], - filters={"item_code": item_code, "company": company, "disable": 0}, - order_by="priority asc, capacity desc") - - if not rules: - return False, None - - for rule in rules: - balance_qty = get_stock_balance(rule.item_code, rule.warehouse, nowdate()) - free_space = flt(rule.stock_capacity) - flt(balance_qty) - if free_space > 0: - rule["free_space"] = free_space - else: - del rule - - if not rules: - # After iterating through rules, if no rules are left - # then there is not enough space left in any rule - return True, None - - rules = sorted(rules, key = lambda i: (i['priority'], -i['free_space'])) - return False, rules +@frappe.whitelist() +def get_putaway_capacity(rule): + stock_capacity, item_code, warehouse = frappe.db.get_value("Putaway Rule", rule, + ["stock_capacity", "item_code", "warehouse"]) + balance_qty = get_stock_balance(item_code, warehouse, nowdate()) + free_space = flt(stock_capacity) - flt(balance_qty) + return free_space if free_space > 0 else 0 @frappe.whitelist() -def apply_putaway_rule(items, company): +def apply_putaway_rule(doctype, items, company): """ Applies Putaway Rule on line items. items: List of Purchase Receipt Item objects company: Company in the Purchase Receipt """ + if isinstance(items, string_types): + items = json.loads(items) + items_not_accomodated, updated_table = [], [] item_wise_rules = defaultdict(list) - def add_row(item, to_allocate, warehouse): - new_updated_table_row = copy.deepcopy(item) - new_updated_table_row.name = '' - new_updated_table_row.idx = 1 if not updated_table else flt(updated_table[-1].idx) + 1 - new_updated_table_row.qty = to_allocate - new_updated_table_row.stock_qty = flt(to_allocate) * flt(new_updated_table_row.conversion_factor) - new_updated_table_row.warehouse = warehouse - updated_table.append(new_updated_table_row) - for item in items: - conversion = flt(item.conversion_factor) - uom_must_be_whole_number = frappe.db.get_value('UOM', item.uom, 'must_be_whole_number') - pending_qty, pending_stock_qty, item_code = flt(item.qty), flt(item.stock_qty), item.item_code + if isinstance(item, dict): + item = frappe._dict(item) - if not pending_qty: - add_row(item, pending_qty, item.warehouse) + source_warehouse = item.get("s_warehouse") + serial_nos = get_serial_nos(item.get("serial_no")) + conversion = flt(item.conversion_factor) or 1 + pending_qty, item_code = flt(item.qty), item.item_code + pending_stock_qty = flt(item.transfer_qty) if doctype == "Stock Entry" else flt(item.stock_qty) + if not pending_qty or not item_code: + updated_table = add_row(item, pending_qty, item.warehouse, updated_table) continue - at_capacity, rules = get_ordered_putaway_rules(item_code, company) + uom_must_be_whole_number = frappe.db.get_value('UOM', item.uom, 'must_be_whole_number') + + at_capacity, rules = get_ordered_putaway_rules(item_code, company, source_warehouse=source_warehouse) if not rules: + warehouse = item.warehouse if at_capacity: - # rules available, but no free space - add_row(item, pending_qty, '') + warehouse = '' # rules available, but no free space items_not_accomodated.append([item_code, pending_qty]) - else: - # no rules to apply - add_row(item, pending_qty, item.warehouse) + updated_table = add_row(item, pending_qty, warehouse, updated_table) continue # maintain item wise rules, to handle if item is entered twice @@ -126,7 +109,7 @@ def apply_putaway_rule(items, company): for rule in item_wise_rules[item_code]: if pending_stock_qty > 0 and rule.free_space: stock_qty_to_allocate = flt(rule.free_space) if pending_stock_qty >= flt(rule.free_space) else pending_stock_qty - qty_to_allocate = stock_qty_to_allocate / (conversion or 1) + qty_to_allocate = stock_qty_to_allocate / (conversion) if uom_must_be_whole_number: qty_to_allocate = floor(qty_to_allocate) @@ -134,7 +117,8 @@ def apply_putaway_rule(items, company): if not qty_to_allocate: break - add_row(item, qty_to_allocate, rule.warehouse) + updated_table = add_row(item, qty_to_allocate, rule.warehouse, updated_table, + rule.name, serial_nos=serial_nos) pending_stock_qty -= stock_qty_to_allocate pending_qty -= qty_to_allocate @@ -144,15 +128,71 @@ def apply_putaway_rule(items, company): # if pending qty after applying all rules, add row without warehouse if pending_stock_qty > 0: - add_row(item, pending_qty, '') + # updated_table = add_row(item, pending_qty, '', updated_table, serial_nos=serial_nos) items_not_accomodated.append([item.item_code, pending_qty]) if items_not_accomodated: - format_unassigned_items_error(items_not_accomodated) + show_unassigned_items_message(items_not_accomodated) return updated_table if updated_table else items -def format_unassigned_items_error(items_not_accomodated): +def get_ordered_putaway_rules(item_code, company, source_warehouse=None): + """Returns an ordered list of putaway rules to apply on an item.""" + filters = { + "item_code": item_code, + "company": company, + "disable": 0 + } + if source_warehouse: + filters.update({"warehouse": ["!=", source_warehouse]}) + + rules = frappe.get_all("Putaway Rule", + fields=["name", "item_code", "stock_capacity", "priority", "warehouse"], + filters=filters, + order_by="priority asc, capacity desc") + + if not rules: + return False, None + + vacant_rules = [] + for rule in rules: + balance_qty = get_stock_balance(rule.item_code, rule.warehouse, nowdate()) + free_space = flt(rule.stock_capacity) - flt(balance_qty) + if free_space > 0: + rule["free_space"] = free_space + vacant_rules.append(rule) + + if not vacant_rules: + # After iterating through rules, if no rules are left + # then there is not enough space left in any rule + return True, None + + vacant_rules = sorted(vacant_rules, key = lambda i: (i['priority'], -i['free_space'])) + + return False, vacant_rules + +def add_row(item, to_allocate, warehouse, updated_table, rule=None, serial_nos=None): + new_updated_table_row = copy.deepcopy(item) + new_updated_table_row.idx = 1 if not updated_table else cint(updated_table[-1].idx) + 1 + new_updated_table_row.name = "New " + str(item.doctype) + " " + str(new_updated_table_row.idx) + new_updated_table_row.qty = to_allocate + new_updated_table_row.stock_qty = flt(to_allocate) * flt(new_updated_table_row.conversion_factor) + if item.doctype == "Stock Entry Detail": + new_updated_table_row.t_warehouse = warehouse + else: + new_updated_table_row.warehouse = warehouse + new_updated_table_row.rejected_qty = 0 + new_updated_table_row.received_qty = to_allocate + + if rule: + new_updated_table_row.putaway_rule = rule + if serial_nos: + new_updated_table_row.serial_no = get_serial_nos_to_allocate(serial_nos, to_allocate) + + updated_table.append(new_updated_table_row) + return updated_table + +def show_unassigned_items_message(items_not_accomodated): msg = _("The following Items, having Putaway Rules, could not be accomodated:") + "

    " formatted_item_rows = "" @@ -173,4 +213,11 @@ def format_unassigned_items_error(items_not_accomodated): """.format(_("Item"), _("Unassigned Qty"), formatted_item_rows) - frappe.msgprint(msg, title=_("Insufficient Capacity"), is_minimizable=True, wide=True) \ No newline at end of file + frappe.msgprint(msg, title=_("Insufficient Capacity"), is_minimizable=True, wide=True) + +def get_serial_nos_to_allocate(serial_nos, to_allocate): + if serial_nos: + allocated_serial_nos = serial_nos[0: cint(to_allocate)] + serial_nos[:] = serial_nos[cint(to_allocate):] # pop out allocated serial nos and modify list + return "\n".join(allocated_serial_nos) if allocated_serial_nos else "" + else: return "" \ No newline at end of file diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.js b/erpnext/stock/doctype/stock_entry/stock_entry.js index 91217582ca4..2be70f37f27 100644 --- a/erpnext/stock/doctype/stock_entry/stock_entry.js +++ b/erpnext/stock/doctype/stock_entry/stock_entry.js @@ -571,6 +571,10 @@ frappe.ui.form.on('Stock Entry', { } }); } + }, + + apply_putaway_rule: function(frm) { + // if (frm.doc.apply_putaway_rule) erpnext.apply_putaway_rule(frm); } }) diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.json b/erpnext/stock/doctype/stock_entry/stock_entry.json index 61e0df67238..cd01fa72779 100644 --- a/erpnext/stock/doctype/stock_entry/stock_entry.json +++ b/erpnext/stock/doctype/stock_entry/stock_entry.json @@ -27,6 +27,7 @@ "set_posting_time", "inspection_required", "from_bom", + "apply_putaway_rule", "sb1", "bom_no", "fg_completed_qty", @@ -640,13 +641,20 @@ "fieldtype": "Check", "label": "Add to Transit", "no_copy": 1 + }, + { + "default": "0", + "depends_on": "eval:in_list([\"Material Transfer\", \"Material Receipt\"], doc.purpose)", + "fieldname": "apply_putaway_rule", + "fieldtype": "Check", + "label": "Apply Putaway Rule" } ], "icon": "fa fa-file-text", "idx": 1, "is_submittable": 1, "links": [], - "modified": "2020-08-11 19:10:07.954981", + "modified": "2020-12-07 14:58:13.267321", "modified_by": "Administrator", "module": "Stock", "name": "Stock Entry", diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.py b/erpnext/stock/doctype/stock_entry/stock_entry.py index e3159b95c30..aa3425cbd8e 100644 --- a/erpnext/stock/doctype/stock_entry/stock_entry.py +++ b/erpnext/stock/doctype/stock_entry/stock_entry.py @@ -42,6 +42,13 @@ class StockEntry(StockController): for item in self.get("items"): item.update(get_bin_details(item.item_code, item.s_warehouse)) + def before_save(self): + from erpnext.stock.doctype.putaway_rule.putaway_rule import apply_putaway_rule + apply_rule = self.apply_putaway_rule and (self.purpose in ["Material Transfer", "Material Receipt"]) + + if self.get("items") and apply_rule: + self.items = apply_putaway_rule(self.doctype, self.get("items"), self.company) + def validate(self): self.pro_doc = frappe._dict() if self.work_order: @@ -79,6 +86,7 @@ class StockEntry(StockController): self.validate_serialized_batch() self.set_actual_qty() self.calculate_rate_and_amount(update_finished_item_rate=False) + self.validate_putaway_capacity() def on_submit(self): diff --git a/erpnext/stock/doctype/stock_entry_detail/stock_entry_detail.json b/erpnext/stock/doctype/stock_entry_detail/stock_entry_detail.json index 79e8f9af8fc..4075e28b7be 100644 --- a/erpnext/stock/doctype/stock_entry_detail/stock_entry_detail.json +++ b/erpnext/stock/doctype/stock_entry_detail/stock_entry_detail.json @@ -1,4 +1,5 @@ { + "actions": [], "autoname": "hash", "creation": "2013-03-29 18:22:12", "doctype": "DocType", @@ -61,6 +62,7 @@ "against_stock_entry", "ste_detail", "po_detail", + "putaway_rule", "column_break_51", "transferred_qty", "reference_purchase_receipt", @@ -498,13 +500,23 @@ "fieldname": "set_basic_rate_manually", "fieldtype": "Check", "label": "Set Basic Rate Manually" + }, + { + "depends_on": "eval:in_list([\"Material Transfer\", \"Material Receipt\"], parent.purpose)", + "fieldname": "putaway_rule", + "fieldtype": "Link", + "label": "Putaway Rule", + "no_copy": 1, + "options": "Putaway Rule", + "print_hide": 1, + "read_only": 1 } ], "idx": 1, "index_web_pages_for_search": 1, "istable": 1, "links": [], - "modified": "2020-09-23 17:55:03.384138", + "modified": "2020-12-07 15:00:44.489442", "modified_by": "Administrator", "module": "Stock", "name": "Stock Entry Detail", From c82b52855cf43774e78d54a7fcd41c62884ac47a Mon Sep 17 00:00:00 2001 From: pateljannat Date: Tue, 8 Dec 2020 11:07:59 +0530 Subject: [PATCH 159/477] fix: template filter for tasks --- .../doctype/project_template/project_template.js | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/erpnext/projects/doctype/project_template/project_template.js b/erpnext/projects/doctype/project_template/project_template.js index d7a876dfbd3..acc6849f2bb 100644 --- a/erpnext/projects/doctype/project_template/project_template.js +++ b/erpnext/projects/doctype/project_template/project_template.js @@ -5,4 +5,13 @@ frappe.ui.form.on('Project Template', { // refresh: function(frm) { // } + setup: function (frm) { + me.frm.set_query("task", "tasks", function (doc, cdt, cdn) { + return { + filters: { + "is_template": 1 + } + } + }); + } }); From 0f3cfc502bc81a475cf5f6b8beabfd43730fe5b8 Mon Sep 17 00:00:00 2001 From: marination Date: Tue, 8 Dec 2020 19:11:51 +0530 Subject: [PATCH 160/477] feat: Trigger rule application from client side - Table is reset and overwritten with applied rules on checkbox trigger - Sider fixes --- erpnext/public/js/controllers/buying.js | 23 ------------- erpnext/public/js/controllers/transaction.js | 30 +++++++++++++++++ erpnext/stock/dashboard/item_dashboard.js | 22 +++++++------ .../purchase_receipt/purchase_receipt.js | 2 +- .../purchase_receipt/purchase_receipt.py | 2 +- .../doctype/putaway_rule/putaway_rule.py | 22 +++++++------ .../stock/doctype/stock_entry/stock_entry.js | 6 ++-- .../stock/doctype/stock_entry/stock_entry.py | 2 +- .../warehouse_capacity_summary.js | 32 +++++++++---------- 9 files changed, 77 insertions(+), 64 deletions(-) diff --git a/erpnext/public/js/controllers/buying.js b/erpnext/public/js/controllers/buying.js index 1cb68a6cda2..0c6bcad7219 100644 --- a/erpnext/public/js/controllers/buying.js +++ b/erpnext/public/js/controllers/buying.js @@ -516,27 +516,4 @@ erpnext.buying.get_items_from_product_bundle = function(frm) { }); dialog.show(); -} - -erpnext.apply_putaway_rule = (frm) => { - if (!frm.doc.company) { - frappe.throw({message:__("Please select a Company first."), title: __("Mandatory")}) - } - if (!frm.doc.items.length) return; - - frappe.call({ - method: "erpnext.stock.doctype.putaway_rule.putaway_rule.apply_putaway_rule", - args: { - items: frm.doc.items, - company: frm.doc.company - }, - callback: (result) => { - if(!result.exc) { - if(result.message) { - frm.doc.items = result.message; - frm.get_field("items").refresh(); - } - } - } - }); } \ No newline at end of file diff --git a/erpnext/public/js/controllers/transaction.js b/erpnext/public/js/controllers/transaction.js index 7f08cd1359f..31efb6aa344 100644 --- a/erpnext/public/js/controllers/transaction.js +++ b/erpnext/public/js/controllers/transaction.js @@ -2029,3 +2029,33 @@ erpnext.show_serial_batch_selector = function (frm, d, callback, on_close, show_ }, show_dialog); }); } + +erpnext.apply_putaway_rule = (frm) => { + if (!frm.doc.company) { + frappe.throw({message: __("Please select a Company first."), title: __("Mandatory")}); + } + if (!frm.doc.items.length) return; + + frappe.call({ + method: "erpnext.stock.doctype.putaway_rule.putaway_rule.apply_putaway_rule", + args: { + doctype: frm.doctype, + items: frm.doc.items, + company: frm.doc.company, + sync: true + }, + callback: (result) => { + if (!result.exc && result.message) { + frm.clear_table("items"); + + let items = result.message; + items.forEach((row) => { + delete row["name"]; + let child = frm.add_child("items"); + Object.assign(child, row); + }); + frm.get_field("items").grid.refresh(); + } + } + }); +}; \ No newline at end of file diff --git a/erpnext/stock/dashboard/item_dashboard.js b/erpnext/stock/dashboard/item_dashboard.js index abc286fcc6e..070589b3dc0 100644 --- a/erpnext/stock/dashboard/item_dashboard.js +++ b/erpnext/stock/dashboard/item_dashboard.js @@ -30,8 +30,8 @@ erpnext.stock.ItemDashboard = Class.extend({ let company = unescape($(this).attr('data-company')); frappe.db.get_value('Putaway Rule', {'item_code': item, 'warehouse': warehouse, 'company': company}, 'name', (r) => { - frappe.set_route("Form", "Putaway Rule", r.name); - }); + frappe.set_route("Form", "Putaway Rule", r.name); + }); }); function handle_move_add(element, action) { @@ -88,7 +88,7 @@ erpnext.stock.ItemDashboard = Class.extend({ start: this.start, sort_by: this.sort_by, sort_order: this.sort_order - } + }; var me = this; frappe.call({ @@ -104,10 +104,12 @@ erpnext.stock.ItemDashboard = Class.extend({ this.max_count = 0; this.result.empty(); } + + let context = ""; if (this.page_name === "warehouse-capacity-summary") { - var context = this.get_capacity_dashboard_data(data); + context = this.get_capacity_dashboard_data(data); } else { - var context = this.get_item_dashboard_data(data, this.max_count, true); + context = this.get_item_dashboard_data(data, this.max_count, true); } this.max_count = this.max_count; @@ -152,7 +154,7 @@ erpnext.stock.ItemDashboard = Class.extend({ }); let can_write = 0; - if(frappe.boot.user.can_write.indexOf("Stock Entry")>=0){ + if (frappe.boot.user.can_write.indexOf("Stock Entry") >= 0) { can_write = 1; } @@ -165,23 +167,23 @@ erpnext.stock.ItemDashboard = Class.extend({ }, get_capacity_dashboard_data: function(data) { - if(!data) data = []; + if (!data) data = []; data.forEach(function(d) { d.color = d.percent_occupied >=80 ? "#f8814f" : "#2490ef"; }); let can_write = 0; - if(frappe.boot.user.can_write.indexOf("Putaway Rule")>=0){ + if (frappe.boot.user.can_write.indexOf("Putaway Rule") >= 0) { can_write = 1; } return { data: data, can_write: can_write, - } + }; } -}) +}); erpnext.stock.move_item = function(item, source, target, actual_qty, rate, callback) { var dialog = new frappe.ui.Dialog({ diff --git a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.js b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.js index 45eb646d4b9..218fb9e1210 100644 --- a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.js +++ b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.js @@ -214,7 +214,7 @@ erpnext.stock.PurchaseReceiptController = erpnext.buying.BuyingController.extend }, apply_putaway_rule: function() { - // if (this.frm.doc.apply_putaway_rule) erpnext.apply_putaway_rule(this.frm); + if (this.frm.doc.apply_putaway_rule) erpnext.apply_putaway_rule(this.frm); } }); diff --git a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py index b1ad6103d39..4372bdcc590 100644 --- a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py +++ b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py @@ -87,7 +87,7 @@ class PurchaseReceipt(BuyingController): from erpnext.stock.doctype.putaway_rule.putaway_rule import apply_putaway_rule if self.get("items") and self.apply_putaway_rule: - self.items = apply_putaway_rule(self.doctype, self.get("items"), self.company) + apply_putaway_rule(self.doctype, self.get("items"), self.company) def validate(self): self.validate_posting_time() diff --git a/erpnext/stock/doctype/putaway_rule/putaway_rule.py b/erpnext/stock/doctype/putaway_rule/putaway_rule.py index 8838bb75f1d..4ed4dafac77 100644 --- a/erpnext/stock/doctype/putaway_rule/putaway_rule.py +++ b/erpnext/stock/doctype/putaway_rule/putaway_rule.py @@ -64,7 +64,7 @@ def get_putaway_capacity(rule): return free_space if free_space > 0 else 0 @frappe.whitelist() -def apply_putaway_rule(doctype, items, company): +def apply_putaway_rule(doctype, items, company, sync=None): """ Applies Putaway Rule on line items. items: List of Purchase Receipt Item objects @@ -82,7 +82,7 @@ def apply_putaway_rule(doctype, items, company): source_warehouse = item.get("s_warehouse") serial_nos = get_serial_nos(item.get("serial_no")) - conversion = flt(item.conversion_factor) or 1 + item.conversion_factor = flt(item.conversion_factor) or 1 pending_qty, item_code = flt(item.qty), item.item_code pending_stock_qty = flt(item.transfer_qty) if doctype == "Stock Entry" else flt(item.stock_qty) if not pending_qty or not item_code: @@ -109,11 +109,11 @@ def apply_putaway_rule(doctype, items, company): for rule in item_wise_rules[item_code]: if pending_stock_qty > 0 and rule.free_space: stock_qty_to_allocate = flt(rule.free_space) if pending_stock_qty >= flt(rule.free_space) else pending_stock_qty - qty_to_allocate = stock_qty_to_allocate / (conversion) + qty_to_allocate = stock_qty_to_allocate / item.conversion_factor if uom_must_be_whole_number: qty_to_allocate = floor(qty_to_allocate) - stock_qty_to_allocate = qty_to_allocate * conversion + stock_qty_to_allocate = qty_to_allocate * item.conversion_factor if not qty_to_allocate: break @@ -124,17 +124,19 @@ def apply_putaway_rule(doctype, items, company): pending_qty -= qty_to_allocate rule["free_space"] -= stock_qty_to_allocate - if not pending_stock_qty: break + if not pending_stock_qty > 0: break # if pending qty after applying all rules, add row without warehouse if pending_stock_qty > 0: - # updated_table = add_row(item, pending_qty, '', updated_table, serial_nos=serial_nos) items_not_accomodated.append([item.item_code, pending_qty]) if items_not_accomodated: show_unassigned_items_message(items_not_accomodated) - return updated_table if updated_table else items + items[:] = updated_table if updated_table else items # modify items table + + if sync and json.loads(sync): # sync with client side + return items def get_ordered_putaway_rules(item_code, company, source_warehouse=None): """Returns an ordered list of putaway rules to apply on an item.""" @@ -174,12 +176,14 @@ def get_ordered_putaway_rules(item_code, company, source_warehouse=None): def add_row(item, to_allocate, warehouse, updated_table, rule=None, serial_nos=None): new_updated_table_row = copy.deepcopy(item) new_updated_table_row.idx = 1 if not updated_table else cint(updated_table[-1].idx) + 1 - new_updated_table_row.name = "New " + str(item.doctype) + " " + str(new_updated_table_row.idx) + new_updated_table_row.name = None new_updated_table_row.qty = to_allocate - new_updated_table_row.stock_qty = flt(to_allocate) * flt(new_updated_table_row.conversion_factor) + if item.doctype == "Stock Entry Detail": new_updated_table_row.t_warehouse = warehouse + new_updated_table_row.transfer_qty = flt(to_allocate) * flt(new_updated_table_row.conversion_factor) else: + new_updated_table_row.stock_qty = flt(to_allocate) * flt(new_updated_table_row.conversion_factor) new_updated_table_row.warehouse = warehouse new_updated_table_row.rejected_qty = 0 new_updated_table_row.received_qty = to_allocate diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.js b/erpnext/stock/doctype/stock_entry/stock_entry.js index 2be70f37f27..fd920a585ac 100644 --- a/erpnext/stock/doctype/stock_entry/stock_entry.js +++ b/erpnext/stock/doctype/stock_entry/stock_entry.js @@ -573,10 +573,10 @@ frappe.ui.form.on('Stock Entry', { } }, - apply_putaway_rule: function(frm) { - // if (frm.doc.apply_putaway_rule) erpnext.apply_putaway_rule(frm); + apply_putaway_rule: function (frm) { + if (frm.doc.apply_putaway_rule) erpnext.apply_putaway_rule(frm); } -}) +}); frappe.ui.form.on('Stock Entry Detail', { qty: function(frm, cdt, cdn) { diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.py b/erpnext/stock/doctype/stock_entry/stock_entry.py index aa3425cbd8e..f07039f5642 100644 --- a/erpnext/stock/doctype/stock_entry/stock_entry.py +++ b/erpnext/stock/doctype/stock_entry/stock_entry.py @@ -47,7 +47,7 @@ class StockEntry(StockController): apply_rule = self.apply_putaway_rule and (self.purpose in ["Material Transfer", "Material Receipt"]) if self.get("items") and apply_rule: - self.items = apply_putaway_rule(self.doctype, self.get("items"), self.company) + apply_putaway_rule(self.doctype, self.get("items"), self.company) def validate(self): self.pro_doc = frappe._dict() diff --git a/erpnext/stock/page/warehouse_capacity_summary/warehouse_capacity_summary.js b/erpnext/stock/page/warehouse_capacity_summary/warehouse_capacity_summary.js index c3b3b5d8ec4..b610e7dd587 100644 --- a/erpnext/stock/page/warehouse_capacity_summary/warehouse_capacity_summary.js +++ b/erpnext/stock/page/warehouse_capacity_summary/warehouse_capacity_summary.js @@ -10,8 +10,8 @@ frappe.pages['warehouse-capacity-summary'].on_page_load = function(wrapper) { page.company_field = page.add_field({ fieldname: 'company', label: __('Company'), - fieldtype:'Link', - options:'Company', + fieldtype: 'Link', + options: 'Company', reqd: 1, default: frappe.defaults.get_default("company"), change: function() { @@ -23,8 +23,8 @@ frappe.pages['warehouse-capacity-summary'].on_page_load = function(wrapper) { page.warehouse_field = page.add_field({ fieldname: 'warehouse', label: __('Warehouse'), - fieldtype:'Link', - options:'Warehouse', + fieldtype: 'Link', + options: 'Warehouse', change: function() { page.capacity_dashboard.start = 0; page.capacity_dashboard.refresh(); @@ -34,8 +34,8 @@ frappe.pages['warehouse-capacity-summary'].on_page_load = function(wrapper) { page.item_field = page.add_field({ fieldname: 'item_code', label: __('Item'), - fieldtype:'Link', - options:'Item', + fieldtype: 'Link', + options: 'Item', change: function() { page.capacity_dashboard.start = 0; page.capacity_dashboard.refresh(); @@ -45,8 +45,8 @@ frappe.pages['warehouse-capacity-summary'].on_page_load = function(wrapper) { page.parent_warehouse_field = page.add_field({ fieldname: 'parent_warehouse', label: __('Parent Warehouse'), - fieldtype:'Link', - options:'Warehouse', + fieldtype: 'Link', + options: 'Warehouse', get_query: function() { return { filters: { @@ -67,8 +67,8 @@ frappe.pages['warehouse-capacity-summary'].on_page_load = function(wrapper) { sort_order: 'desc', options: [ {fieldname: 'stock_capacity', label: __('Capacity (Stock UOM)')}, - {fieldname: 'percent_occupied', label:__('% Occupied')}, - {fieldname: 'actual_qty', label:__('Balance Qty (Stock ')} + {fieldname: 'percent_occupied', label: __('% Occupied')}, + {fieldname: 'actual_qty', label: __('Balance Qty (Stock ')} ] }, change: function(sort_by, sort_order) { @@ -90,14 +90,14 @@ frappe.pages['warehouse-capacity-summary'].on_page_load = function(wrapper) { sort_order: 'desc', method: 'erpnext.stock.dashboard.warehouse_capacity_dashboard.get_data', template: 'warehouse_capacity_summary' - }) + }); page.capacity_dashboard.before_refresh = function() { this.item_code = page.item_field.get_value(); this.warehouse = page.warehouse_field.get_value(); this.parent_warehouse = page.parent_warehouse_field.get_value(); this.company = page.company_field.get_value(); - } + }; page.capacity_dashboard.refresh(); @@ -105,16 +105,16 @@ frappe.pages['warehouse-capacity-summary'].on_page_load = function(wrapper) { page.main.on('click', 'a[data-type="'+ doctype.toLowerCase() +'"]', function() { var name = $(this).attr('data-name'); var field = page[doctype.toLowerCase() + '_field']; - if(field.get_value()===name) { - frappe.set_route('Form', doctype, name) + if (field.get_value()===name) { + frappe.set_route('Form', doctype, name); } else { field.set_input(name); page.capacity_dashboard.refresh(); } }); - } + }; setup_click('Item'); setup_click('Warehouse'); }); -} \ No newline at end of file +}; \ No newline at end of file From 811629a9616f411eb40b0d0adb301dc5f0ff8cf3 Mon Sep 17 00:00:00 2001 From: pateljannat Date: Wed, 9 Dec 2020 15:52:05 +0530 Subject: [PATCH 161/477] feat: tasks in project template and tests --- erpnext/projects/doctype/project/project.py | 38 ++++++-- .../projects/doctype/project/test_project.py | 92 +++++++++++++++---- .../project_template/test_project_template.py | 49 +++++----- erpnext/projects/doctype/task/test_task.py | 6 +- 4 files changed, 126 insertions(+), 59 deletions(-) diff --git a/erpnext/projects/doctype/project/project.py b/erpnext/projects/doctype/project/project.py index 5bbd29c4c42..04a0fb6c4f0 100644 --- a/erpnext/projects/doctype/project/project.py +++ b/erpnext/projects/doctype/project/project.py @@ -55,16 +55,34 @@ class Project(Document): # create tasks from template for task in template.tasks: - frappe.get_doc(dict( - doctype = 'Task', - subject = task.subject, - project = self.name, - status = 'Open', - exp_start_date = add_days(self.expected_start_date, task.start), - exp_end_date = add_days(self.expected_start_date, task.start + task.duration), - description = task.description, - task_weight = task.task_weight - )).insert() + template_task_details = frappe.get_doc("Task", task.task) + project_task = self.create_task_from_template(template_task_details) + + if template_task_details.depends_on: + for child_task in template_task_details.depends_on: + child_task_details = frappe.get_doc("Task",child_task.task) + self.create_task_from_template(child_task_details, project_task) + + def create_task_from_template(self, task_details, project_task=None): + doc = frappe.get_doc(dict( + doctype = 'Task', + subject = task_details.subject, + project = self.name, + status = 'Open', + exp_start_date = add_days(self.expected_start_date, task_details.start), + exp_end_date = add_days(self.expected_start_date, task_details.start + task_details.duration), + description = task_details.description, + task_weight = task_details.task_weight, + type = task_details.type, + issue = task_details.issue, + is_group = task_details.is_group + )) + if task_details.parent_task and project_task: + doc.parent_task = project_task.name + if not task_details.is_group: + doc.depends_on = task_details.depends_on + doc.insert() + return doc def is_row_updated(self, row, existing_task_data, fields): if self.get("__islocal") or not existing_task_data: return True diff --git a/erpnext/projects/doctype/project/test_project.py b/erpnext/projects/doctype/project/test_project.py index 0c4f6f1bdfe..ce95b056141 100644 --- a/erpnext/projects/doctype/project/test_project.py +++ b/erpnext/projects/doctype/project/test_project.py @@ -7,33 +7,87 @@ import frappe, unittest test_records = frappe.get_test_records('Project') test_ignore = ["Sales Order"] -from erpnext.projects.doctype.project_template.test_project_template import get_project_template, make_project_template +from erpnext.projects.doctype.project_template.test_project_template import make_project_template from erpnext.projects.doctype.project.project import set_project_status - -from frappe.utils import getdate +from erpnext.projects.doctype.task.test_task import create_task +from frappe.utils import getdate, nowdate, add_days class TestProject(unittest.TestCase): - def test_project_with_template(self): - frappe.db.sql('delete from tabTask where project = "Test Project with Template"') - frappe.delete_doc('Project', 'Test Project with Template') + def test_project_with_template_having_no_parent_and_depend_tasks(self): + """ + Test Action: Basic Test of a Project created from template. The template has a single task. + """ + frappe.db.sql('delete from tabTask where project = "Test Project with Templ - no parent and dependend tasks"') + frappe.delete_doc('Project', 'Test Project with Templ - no parent and dependend tasks') - project = get_project('Test Project with Template') + if not frappe.db.exists("Task", "Test Temp Task with no parent and dependency"): + task1 = create_task(subject="Test Temp Task with no parent and dependency", is_template=1, begin=0, duration=3) + template = make_project_template("Test Project Template - no parent and dependend tasks", [task1]) + project = get_project("Test Project with Templ - no parent and dependend tasks", template) tasks = frappe.get_all('Task', '*', dict(project=project.name), order_by='creation asc') - task1 = tasks[0] - self.assertEqual(task1.subject, 'Task 1') - self.assertEqual(task1.description, 'Task 1 description') - self.assertEqual(getdate(task1.exp_start_date), getdate('2019-01-01')) - self.assertEqual(getdate(task1.exp_end_date), getdate('2019-01-04')) + self.assertEqual(task[0].subject, 'Test Temp Task with no parent and dependency') + self.assertEqual(getdate(task[0].exp_end_date), add_days(nowdate() + 0 + 3)) + self.assertEqual(len(tasks), 1) - self.assertEqual(len(tasks), 4) - task4 = tasks[3] - self.assertEqual(task4.subject, 'Task 4') - self.assertEqual(getdate(task4.exp_end_date), getdate('2019-01-06')) + def test_project_template_having_parent_child_tasks(self): -def get_project(name): - template = get_project_template() + frappe.db.sql('delete from tabTask where project = "Test Project with Templ - tasks with parent-child"') + frappe.delete_doc('Project', 'Test Project with Templ - tasks with parent-child') + + if not frappe.db.exists("Task", "Test Temp Task parent"): + task1 = create_task(subject="Test Temp Task parent", is_group=1, is_template=1, begin=1, duration=1) + + if not frappe.db.exists("Task", "Test Temp Task child 1"): + task2 = create_task(subject="Test Temp Task child 1", parent_task=task1.name, is_template=1, begin=1, duration=3) + + if not frappe.db.exists("Task", "Test Temp Task child 2"): + task3 = create_task(subject="Test Temp Task child 2", parent_task=task1.name, is_template=1, begin=2, duration=3) + + template = make_project_template("Test Project Template - tasks with parent-child", [task1, task2, task3]) + project = get_project("Test Project with Templ - tasks with parent-child", template) + tasks = frappe.get_all('Task', '*', dict(project=project.name), order_by='creation asc') + + self.assertEqual(task[0].subject, 'Test Temp Task parent') + self.assertEqual(getdate(task[0].exp_end_date), add_days(nowdate()+ 1 + 1)) + print(task[0].depends_on) + + self.assertEqual(task[1].subject, 'Test Temp Task child 1') + self.assertEqual(getdate(task[1].exp_end_date), add_days(nowdate()+ 1 + 3)) + self.assertEqual(task[1].parent_task, task[0].name) + + self.assertEqual(task[2].subject, 'Test Temp Task child 2') + self.assertEqual(getdate(task[2].exp_end_date), add_days(nowdate()+ 2 + 3)) + self.assertEqual(task[2].parent_task, task[0].name) + + self.assertEqual(len(tasks), 3) + + def test_project_template_having_dependent_tasks(self): + + frappe.db.sql('delete from tabTask where project = "Test Project with Templ - dependent tasks"') + frappe.delete_doc('Project', 'Test Project with Templ - dependent tasks') + + if not frappe.db.exists("Task", "Test Temp Task for dependency"): + task1 = create_task(subject="Test Temp Task for dependency", is_template=1, begin=3, duration=1) + + if not frappe.db.exists("Task", "Test Temp Task with dependency"): + task2 = create_task(subject="Test Temp Task with dependency", depends_on=task1.name, is_template=1, begin=2, duration=2) + + template = make_project_template("Test Project Template - tasks with parent-child", [task1, task2]) + project = get_project("Test Project with Templ - tasks with parent-child", template) + tasks = frappe.get_all('Task', '*', dict(project=project.name), order_by='creation asc') + + self.assertEqual(task[0].subject, 'Test Temp Task for dependency') + self.assertEqual(getdate(task[0].exp_end_date), add_days(nowdate()+ 3 + 1)) + + self.assertEqual(task[1].subject, 'Test Temp Task with dependency') + self.assertEqual(getdate(task[1].exp_end_date), add_days(nowdate()+ 2 + 2)) + self.assertEqual(task[1].depends_on, task[0].name) + + self.assertEqual(len(tasks), 2) + +def get_project(name, template): project = frappe.get_doc(dict( doctype = 'Project', @@ -49,8 +103,6 @@ def make_project(args): args = frappe._dict(args) if args.project_template_name: template = make_project_template(args.project_template_name) - else: - template = get_project_template() project = frappe.get_doc(dict( doctype = 'Project', diff --git a/erpnext/projects/doctype/project_template/test_project_template.py b/erpnext/projects/doctype/project_template/test_project_template.py index 2c5831a5dc9..dd98d02c021 100644 --- a/erpnext/projects/doctype/project_template/test_project_template.py +++ b/erpnext/projects/doctype/project_template/test_project_template.py @@ -5,44 +5,37 @@ from __future__ import unicode_literals import frappe import unittest +from erpnext.projects.doctype.task.test_task import create_task class TestProjectTemplate(unittest.TestCase): pass -def get_project_template(): - if not frappe.db.exists('Project Template', 'Test Project Template'): - frappe.get_doc(dict( - doctype = 'Project Template', - name = 'Test Project Template', - tasks = [ - dict(subject='Task 1', description='Task 1 description', - start=0, duration=3), - dict(subject='Task 2', description='Task 2 description', - start=0, duration=2), - dict(subject='Task 3', description='Task 3 description', - start=2, duration=4), - dict(subject='Task 4', description='Task 4 description', - start=3, duration=2), - ] - )).insert() - - return frappe.get_doc('Project Template', 'Test Project Template') - -def make_project_template(project_template_name, project_tasks=[]): +def get_project_template(project_template_name="Test Project Template", project_tasks=[]): if not frappe.db.exists('Project Template', project_template_name): frappe.get_doc(dict( doctype = 'Project Template', name = project_template_name, tasks = project_tasks or [ - dict(subject='Task 1', description='Task 1 description', - start=0, duration=3), - dict(subject='Task 2', description='Task 2 description', - start=0, duration=2), - dict(subject='Task 3', description='Task 3 description', - start=2, duration=4), - dict(subject='Task 4', description='Task 4 description', - start=3, duration=2), + create_task(subject="_Test Template Task 1", is_template=1, begin=0, duration=3), + create_task(subject="_Test Template Task 2", is_template=1, begin=0, duration=2), + create_task(subject="_Test Template Task 3", is_template=1, begin=2, duration=4), + create_task(subject="_Test Template Task 4", is_template=1, begin=3, duration=2), ] )).insert() + return frappe.get_doc('Project Template', project_template_name) + +def make_project_template(project_template_name, project_tasks=[]): + if not frappe.db.exists('Project Template', project_template_name): + doc = frappe.get_doc(dict( + doctype = 'Project Template', + name = project_template_name, + tasks = project_tasks or [ + create_task(subject="_Test Template Task 1", is_template=1, begin=0, duration=3), + create_task(subject="_Test Template Task 2", is_template=1, begin=0, duration=2), + ] + )) + print("doc",doc.tasks) + doc.insert() + return frappe.get_doc('Project Template', project_template_name) \ No newline at end of file diff --git a/erpnext/projects/doctype/task/test_task.py b/erpnext/projects/doctype/task/test_task.py index 47a28fd1114..181a2dc3162 100644 --- a/erpnext/projects/doctype/task/test_task.py +++ b/erpnext/projects/doctype/task/test_task.py @@ -97,7 +97,7 @@ class TestTask(unittest.TestCase): self.assertEqual(frappe.db.get_value("Task", task.name, "status"), "Overdue") -def create_task(subject, start=None, end=None, depends_on=None, project=None, save=True): +def create_task(subject, start=None, end=None, depends_on=None, project=None, parent_task=None, is_group=0, is_template=0, begin=0, duration=0, save=True): if not frappe.db.exists("Task", subject): task = frappe.new_doc('Task') task.status = "Open" @@ -105,6 +105,10 @@ def create_task(subject, start=None, end=None, depends_on=None, project=None, sa task.exp_start_date = start or nowdate() task.exp_end_date = end or nowdate() task.project = project or "_Test Project" + task.is_template = is_template, + task.start = begin + task.duration = duration, + task.is_group = is_group if save: task.save() else: From a5d8d3277560c794377a2449e534a1354dfba9a3 Mon Sep 17 00:00:00 2001 From: marination Date: Wed, 9 Dec 2020 16:27:18 +0530 Subject: [PATCH 162/477] chore: Test and fixes - Tests as per new design flow - Fixed duplicate data bug in Warehouse Capacity Summary - Set Amount currently on applying rule in client side - Apply rules on server side before validate --- erpnext/public/js/controllers/transaction.js | 3 +- erpnext/stock/dashboard/item_dashboard.js | 2 +- .../purchase_receipt/purchase_receipt.py | 2 +- .../purchase_receipt/test_purchase_receipt.py | 2 + .../doctype/putaway_rule/test_putaway_rule.py | 135 +++++++++--------- .../stock/doctype/stock_entry/stock_entry.py | 2 +- 6 files changed, 72 insertions(+), 74 deletions(-) diff --git a/erpnext/public/js/controllers/transaction.js b/erpnext/public/js/controllers/transaction.js index 31efb6aa344..54634482b0a 100644 --- a/erpnext/public/js/controllers/transaction.js +++ b/erpnext/public/js/controllers/transaction.js @@ -2050,9 +2050,10 @@ erpnext.apply_putaway_rule = (frm) => { let items = result.message; items.forEach((row) => { - delete row["name"]; + delete row["name"]; // dont overwrite name from server side let child = frm.add_child("items"); Object.assign(child, row); + frm.script_manager.trigger("qty", child.doctype, child.name); }); frm.get_field("items").grid.refresh(); } diff --git a/erpnext/stock/dashboard/item_dashboard.js b/erpnext/stock/dashboard/item_dashboard.js index 070589b3dc0..20415bc07e8 100644 --- a/erpnext/stock/dashboard/item_dashboard.js +++ b/erpnext/stock/dashboard/item_dashboard.js @@ -69,7 +69,7 @@ erpnext.stock.ItemDashboard = Class.extend({ // more this.content.find('.btn-more').on('click', function() { - me.start += this.page_length; + me.start += me.page_length; me.refresh(); }); diff --git a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py index 4372bdcc590..d36d5159dbb 100644 --- a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py +++ b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py @@ -83,7 +83,7 @@ class PurchaseReceipt(BuyingController): } ]) - def before_save(self): + def before_validate(self): from erpnext.stock.doctype.putaway_rule.putaway_rule import apply_putaway_rule if self.get("items") and self.apply_putaway_rule: diff --git a/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py b/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py index 9b8eeed1a12..7b3a83065b9 100644 --- a/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py +++ b/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py @@ -979,6 +979,7 @@ def make_purchase_receipt(**args): pr.currency = args.currency or "INR" pr.is_return = args.is_return pr.return_against = args.return_against + pr.apply_putaway_rule = args.apply_putaway_rule qty = args.qty or 5 received_qty = args.received_qty or qty rejected_qty = args.rejected_qty or flt(received_qty) - flt(qty) @@ -994,6 +995,7 @@ def make_purchase_receipt(**args): "rejected_warehouse": args.rejected_warehouse or "_Test Rejected Warehouse - _TC" if rejected_qty != 0 else "", "rate": args.rate if args.rate != None else 50, "conversion_factor": args.conversion_factor or 1.0, + "stock_qty": flt(qty) * (flt(args.conversion_factor) or 1.0), "serial_no": args.serial_no, "stock_uom": args.stock_uom or "_Test UOM", "uom": uom, diff --git a/erpnext/stock/doctype/putaway_rule/test_putaway_rule.py b/erpnext/stock/doctype/putaway_rule/test_putaway_rule.py index 7b81784d5fa..17619e01bc1 100644 --- a/erpnext/stock/doctype/putaway_rule/test_putaway_rule.py +++ b/erpnext/stock/doctype/putaway_rule/test_putaway_rule.py @@ -9,8 +9,8 @@ from erpnext.stock.doctype.item.test_item import make_item from erpnext.stock.get_item_details import get_conversion_factor from erpnext.stock.doctype.warehouse.test_warehouse import create_warehouse from erpnext.stock.doctype.stock_entry.test_stock_entry import make_stock_entry -from erpnext.buying.doctype.purchase_order.purchase_order import make_purchase_receipt from erpnext.buying.doctype.purchase_order.test_purchase_order import create_purchase_order +from erpnext.stock.doctype.purchase_receipt.test_purchase_receipt import make_purchase_receipt class TestPutawayRule(unittest.TestCase): def setUp(self): @@ -42,17 +42,15 @@ class TestPutawayRule(unittest.TestCase): rule_2 = create_putaway_rule(item_code="_Rice", warehouse=warehouse_2, capacity=300, uom="Kg", priority=2) - po = create_purchase_order(item_code="_Rice", qty=300) - self.assertEqual(len(po.items), 1) - - pr = make_purchase_receipt(po.name) + pr = make_purchase_receipt(item_code="_Rice", qty=300, apply_putaway_rule=1, + do_not_submit=1) self.assertEqual(len(pr.items), 2) self.assertEqual(pr.items[0].qty, 200) self.assertEqual(pr.items[0].warehouse, warehouse_1) self.assertEqual(pr.items[1].qty, 100) self.assertEqual(pr.items[1].warehouse, warehouse_2) - po.cancel() + pr.delete() rule_1.delete() rule_2.delete() @@ -70,10 +68,8 @@ class TestPutawayRule(unittest.TestCase): # out of 500 kg capacity, occupy 100 kg in warehouse_1 stock_receipt = make_stock_entry(item_code="_Rice", target=warehouse_1, qty=100, basic_rate=50) - po = create_purchase_order(item_code="_Rice", qty=700) - self.assertEqual(len(po.items), 1) - - pr = make_purchase_receipt(po.name) + pr = make_purchase_receipt(item_code="_Rice", qty=700, apply_putaway_rule=1, + do_not_submit=1) self.assertEqual(len(pr.items), 2) self.assertEqual(pr.items[0].qty, 500) # warehouse_2 has 500 kg free space, it is given priority @@ -82,8 +78,8 @@ class TestPutawayRule(unittest.TestCase): # warehouse_1 has 400 kg free space, it is given less priority self.assertEqual(pr.items[1].warehouse, warehouse_1) - po.cancel() stock_receipt.cancel() + pr.delete() rule_1.delete() rule_2.delete() @@ -97,21 +93,14 @@ class TestPutawayRule(unittest.TestCase): rule_2 = create_putaway_rule(item_code="_Rice", warehouse=warehouse_2, capacity=200, uom="Kg") - po = create_purchase_order(item_code="_Rice", qty=350) - self.assertEqual(len(po.items), 1) - - pr = make_purchase_receipt(po.name) - - self.assertEqual(len(pr.items), 3) + pr = make_purchase_receipt(item_code="_Rice", qty=350, apply_putaway_rule=1, + do_not_submit=1) + self.assertEqual(len(pr.items), 2) self.assertEqual(pr.items[0].qty, 200) self.assertEqual(pr.items[0].warehouse, warehouse_2) self.assertEqual(pr.items[1].qty, 100) self.assertEqual(pr.items[1].warehouse, warehouse_1) - # extra qty has no warehouse assigned - self.assertEqual(pr.items[2].qty, 50) - self.assertEqual(pr.items[2].warehouse, '') - - po.cancel() + pr.delete() rule_1.delete() rule_2.delete() @@ -135,24 +124,19 @@ class TestPutawayRule(unittest.TestCase): uom="Bag") self.assertEqual(rule_2.stock_capacity, 4000) + # populate 'Rack 1' with 1 Bag, making the free space 2 Bags stock_receipt = make_stock_entry(item_code="_Rice", target=warehouse_1, qty=1000, basic_rate=50) - po = create_purchase_order(item_code="_Rice", qty=6, do_not_save=True) - po.items[0].uom = "Bag" - po.save() - po.submit() - - self.assertEqual(po.items[0].stock_qty, 6000) - - pr = make_purchase_receipt(po.name) + pr = make_purchase_receipt(item_code="_Rice", qty=6, uom="Bag", stock_uom="Kg", + conversion_factor=1000, apply_putaway_rule=1, do_not_submit=1) self.assertEqual(len(pr.items), 2) self.assertEqual(pr.items[0].qty, 4) self.assertEqual(pr.items[0].warehouse, warehouse_2) self.assertEqual(pr.items[1].qty, 2) self.assertEqual(pr.items[1].warehouse, warehouse_1) - po.cancel() stock_receipt.cancel() + pr.delete() rule_1.delete() rule_2.delete() @@ -180,24 +164,15 @@ class TestPutawayRule(unittest.TestCase): self.assertEqual(rule_2.stock_capacity, 500) # total capacity is 1500 Kg - po = create_purchase_order(item_code="_Rice", qty=2, do_not_save=True) - # PO for 2 Bags (2000 Kg) - po.items[0].uom = "Bag" - po.save() - po.submit() - - self.assertEqual(po.items[0].stock_qty, 2000) - - pr = make_purchase_receipt(po.name) - self.assertEqual(len(pr.items), 2) + pr = make_purchase_receipt(item_code="_Rice", qty=2, uom="Bag", stock_uom="Kg", + conversion_factor=1000, apply_putaway_rule=1, do_not_submit=1) + self.assertEqual(len(pr.items), 1) self.assertEqual(pr.items[0].qty, 1) self.assertEqual(pr.items[0].warehouse, warehouse_1) # leftover space was for 500 kg (0.5 Bag) # Since Bag is a whole UOM, 1(out of 2) Bag will be unassigned - self.assertEqual(pr.items[1].qty, 1) - self.assertEqual(pr.items[1].warehouse, '') - po.cancel() + pr.delete() rule_1.delete() rule_2.delete() @@ -208,38 +183,58 @@ class TestPutawayRule(unittest.TestCase): rule_1 = create_putaway_rule(item_code="_Rice", warehouse=warehouse_1, capacity=200, uom="Kg") - rule_2 = create_putaway_rule(item_code="_Rice", warehouse=warehouse_2, capacity=100, - uom="Kg", priority=2) - # total capacity is 300 Kg + # total capacity is 200 Kg - po = create_purchase_order(item_code="_Rice", qty=200, rate=100, do_not_save=True) - po.append("items", { - "item_code":"_Rice", + pr = make_purchase_receipt(item_code="_Rice", qty=100, apply_putaway_rule=1, + do_not_submit=1) + pr.append("items", { + "item_code": "_Rice", "warehouse": "_Test Warehouse - _TC", - "qty": 300, - "rate": 120, - "schedule_date": add_days(nowdate(), 1), - }) - po.save() - po.submit() - # PO for 500 Kg (two rows of same item, different rates) - self.assertEqual(len(po.items), 2) - - pr = make_purchase_receipt(po.name) - self.assertEqual(len(pr.items), 3) - self.assertEqual(pr.items[0].qty, 200) + "qty": 200, + "uom": "Kg", + "stock_uom": "Kg", + "stock_qty": 200, + "received_qty": 200, + "rate": 100, + "conversion_factor": 1.0, + }) # same item entered again in PR but with different rate + pr.save() + self.assertEqual(len(pr.items), 2) + self.assertEqual(pr.items[0].qty, 100) self.assertEqual(pr.items[0].warehouse, warehouse_1) - # same rules applied to second item row + self.assertEqual(pr.items[0].putaway_rule, rule_1.name) + # same rule applied to second item row # with previous assignment considered - self.assertEqual(pr.items[1].qty, 100) - self.assertEqual(pr.items[1].warehouse, warehouse_2) - # unassigned 200 Kg - self.assertEqual(pr.items[2].qty, 200) - self.assertEqual(pr.items[2].warehouse, '') + self.assertEqual(pr.items[1].qty, 100) # 100 unassigned in second row from 200 + self.assertEqual(pr.items[1].warehouse, warehouse_1) + self.assertEqual(pr.items[1].putaway_rule, rule_1.name) - po.cancel() + pr.delete() + rule_1.delete() + + def test_validate_over_receipt_in_warehouse(self): + """Test if overreceipt is blocked in the presence of putaway rules.""" + warehouse_1 = frappe.db.get_value("Warehouse", {"warehouse_name": "Rack 1"}) + warehouse_2 = frappe.db.get_value("Warehouse", {"warehouse_name": "Rack 2"}) + + rule_1 = create_putaway_rule(item_code="_Rice", warehouse=warehouse_1, capacity=200, + uom="Kg") + + pr = make_purchase_receipt(item_code="_Rice", qty=300, apply_putaway_rule=1, + do_not_submit=1) + self.assertEqual(len(pr.items), 1) + self.assertEqual(pr.items[0].qty, 200) # 100 is unassigned fro 300 Kg + self.assertEqual(pr.items[0].warehouse, warehouse_1) + self.assertEqual(pr.items[0].putaway_rule, rule_1.name) + + # force overreceipt and disable apply putaway rule in PR + pr.items[0].qty = 300 + pr.items[0].stock_qty = 300 + pr.apply_putaway_rule = 0 + self.assertRaises(frappe.ValidationError, pr.save) + + pr.delete() rule_1.delete() - rule_2.delete() def create_putaway_rule(**args): args = frappe._dict(args) diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.py b/erpnext/stock/doctype/stock_entry/stock_entry.py index f07039f5642..aed69e11ddf 100644 --- a/erpnext/stock/doctype/stock_entry/stock_entry.py +++ b/erpnext/stock/doctype/stock_entry/stock_entry.py @@ -42,7 +42,7 @@ class StockEntry(StockController): for item in self.get("items"): item.update(get_bin_details(item.item_code, item.s_warehouse)) - def before_save(self): + def before_validate(self): from erpnext.stock.doctype.putaway_rule.putaway_rule import apply_putaway_rule apply_rule = self.apply_putaway_rule and (self.purpose in ["Material Transfer", "Material Receipt"]) From f936e8a334bb8abab78d9938d6808d9e8688a6ee Mon Sep 17 00:00:00 2001 From: pateljannat Date: Wed, 9 Dec 2020 17:09:22 +0530 Subject: [PATCH 163/477] fix: sider issues fixed --- .../projects/doctype/project/test_project.py | 33 +++++++++---------- .../project_template/project_template.js | 4 +-- .../project_template/test_project_template.py | 6 ++-- 3 files changed, 20 insertions(+), 23 deletions(-) diff --git a/erpnext/projects/doctype/project/test_project.py b/erpnext/projects/doctype/project/test_project.py index ce95b056141..52f877b8b75 100644 --- a/erpnext/projects/doctype/project/test_project.py +++ b/erpnext/projects/doctype/project/test_project.py @@ -27,8 +27,8 @@ class TestProject(unittest.TestCase): project = get_project("Test Project with Templ - no parent and dependend tasks", template) tasks = frappe.get_all('Task', '*', dict(project=project.name), order_by='creation asc') - self.assertEqual(task[0].subject, 'Test Temp Task with no parent and dependency') - self.assertEqual(getdate(task[0].exp_end_date), add_days(nowdate() + 0 + 3)) + self.assertEqual(tasks[0].subject, 'Test Temp Task with no parent and dependency') + self.assertEqual(getdate(tasks[0].exp_end_date), add_days(nowdate() + 0 + 3)) self.assertEqual(len(tasks), 1) def test_project_template_having_parent_child_tasks(self): @@ -48,18 +48,17 @@ class TestProject(unittest.TestCase): template = make_project_template("Test Project Template - tasks with parent-child", [task1, task2, task3]) project = get_project("Test Project with Templ - tasks with parent-child", template) tasks = frappe.get_all('Task', '*', dict(project=project.name), order_by='creation asc') + print(tasks, type(tasks), len(tasks)) + self.assertEqual(tasks[0].subject, 'Test Temp Task parent') + self.assertEqual(getdate(tasks[0].exp_end_date), add_days(nowdate()+ 1 + 1)) - self.assertEqual(task[0].subject, 'Test Temp Task parent') - self.assertEqual(getdate(task[0].exp_end_date), add_days(nowdate()+ 1 + 1)) - print(task[0].depends_on) + self.assertEqual(tasks[1].subject, 'Test Temp Task child 1') + self.assertEqual(getdate(tasks[1].exp_end_date), add_days(nowdate()+ 1 + 3)) + self.assertEqual(tasks[1].parent_task, tasks[0].name) - self.assertEqual(task[1].subject, 'Test Temp Task child 1') - self.assertEqual(getdate(task[1].exp_end_date), add_days(nowdate()+ 1 + 3)) - self.assertEqual(task[1].parent_task, task[0].name) - - self.assertEqual(task[2].subject, 'Test Temp Task child 2') - self.assertEqual(getdate(task[2].exp_end_date), add_days(nowdate()+ 2 + 3)) - self.assertEqual(task[2].parent_task, task[0].name) + self.assertEqual(tasks[2].subject, 'Test Temp Task child 2') + self.assertEqual(getdate(tasks[2].exp_end_date), add_days(nowdate()+ 2 + 3)) + self.assertEqual(tasks[2].parent_task, tasks[0].name) self.assertEqual(len(tasks), 3) @@ -78,12 +77,12 @@ class TestProject(unittest.TestCase): project = get_project("Test Project with Templ - tasks with parent-child", template) tasks = frappe.get_all('Task', '*', dict(project=project.name), order_by='creation asc') - self.assertEqual(task[0].subject, 'Test Temp Task for dependency') - self.assertEqual(getdate(task[0].exp_end_date), add_days(nowdate()+ 3 + 1)) + self.assertEqual(tasks[0].subject, 'Test Temp Task for dependency') + self.assertEqual(getdate(tasks[0].exp_end_date), add_days(nowdate()+ 3 + 1)) - self.assertEqual(task[1].subject, 'Test Temp Task with dependency') - self.assertEqual(getdate(task[1].exp_end_date), add_days(nowdate()+ 2 + 2)) - self.assertEqual(task[1].depends_on, task[0].name) + self.assertEqual(tasks[1].subject, 'Test Temp Task with dependency') + self.assertEqual(getdate(tasks[1].exp_end_date), add_days(nowdate()+ 2 + 2)) + self.assertEqual(tasks[1].depends_on, tasks[0].name) self.assertEqual(len(tasks), 2) diff --git a/erpnext/projects/doctype/project_template/project_template.js b/erpnext/projects/doctype/project_template/project_template.js index acc6849f2bb..7668df3e139 100644 --- a/erpnext/projects/doctype/project_template/project_template.js +++ b/erpnext/projects/doctype/project_template/project_template.js @@ -6,12 +6,12 @@ frappe.ui.form.on('Project Template', { // } setup: function (frm) { - me.frm.set_query("task", "tasks", function (doc, cdt, cdn) { + frm.set_query("task", "tasks", function () { return { filters: { "is_template": 1 } - } + }; }); } }); diff --git a/erpnext/projects/doctype/project_template/test_project_template.py b/erpnext/projects/doctype/project_template/test_project_template.py index dd98d02c021..379365f9998 100644 --- a/erpnext/projects/doctype/project_template/test_project_template.py +++ b/erpnext/projects/doctype/project_template/test_project_template.py @@ -27,15 +27,13 @@ def get_project_template(project_template_name="Test Project Template", project_ def make_project_template(project_template_name, project_tasks=[]): if not frappe.db.exists('Project Template', project_template_name): - doc = frappe.get_doc(dict( + frappe.get_doc(dict( doctype = 'Project Template', name = project_template_name, tasks = project_tasks or [ create_task(subject="_Test Template Task 1", is_template=1, begin=0, duration=3), create_task(subject="_Test Template Task 2", is_template=1, begin=0, duration=2), ] - )) - print("doc",doc.tasks) - doc.insert() + )).insert() return frappe.get_doc('Project Template', project_template_name) \ No newline at end of file From 39154e52969f2ec2ac2ad6985d4a662bc4e1a8e1 Mon Sep 17 00:00:00 2001 From: Rushabh Mehta Date: Thu, 10 Dec 2020 12:37:16 +0530 Subject: [PATCH 164/477] fix(minor): add debounce to calls --- .../accounts/doctype/sales_invoice/sales_invoice.js | 10 +++++----- erpnext/public/js/controllers/transaction.js | 3 ++- erpnext/setup/doctype/company/company.py | 2 +- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.js b/erpnext/accounts/doctype/sales_invoice/sales_invoice.js index 502e65ed8d0..87b14c53f09 100644 --- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.js +++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.js @@ -664,12 +664,12 @@ frappe.ui.form.on('Sales Invoice', { }; }, // When multiple companies are set up. in case company name is changed set default company address - company:function(frm){ - if (frm.doc.company) - { + company: function(frm){ + if (frm.doc.company) { frappe.call({ - method:"erpnext.setup.doctype.company.company.get_default_company_address", - args:{name:frm.doc.company, existing_address: frm.doc.company_address}, + method: "erpnext.setup.doctype.company.company.get_default_company_address", + args: {name:frm.doc.company, existing_address: frm.doc.company_address || ""}, + debounce: 2000, callback: function(r){ if (r.message){ frm.set_value("company_address",r.message) diff --git a/erpnext/public/js/controllers/transaction.js b/erpnext/public/js/controllers/transaction.js index 7f08cd1359f..ea87742253a 100644 --- a/erpnext/public/js/controllers/transaction.js +++ b/erpnext/public/js/controllers/transaction.js @@ -446,9 +446,10 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({ method: "erpnext.controllers.accounts_controller.get_default_taxes_and_charges", args: { "master_doctype": taxes_and_charges_field.options, - "tax_template": me.frm.doc.taxes_and_charges, + "tax_template": me.frm.doc.taxes_and_charges || "", "company": me.frm.doc.company }, + debounce: 2000, callback: function(r) { if(!r.exc && r.message) { frappe.run_serially([ diff --git a/erpnext/setup/doctype/company/company.py b/erpnext/setup/doctype/company/company.py index 4a438f70e62..dc45cc1f7e5 100644 --- a/erpnext/setup/doctype/company/company.py +++ b/erpnext/setup/doctype/company/company.py @@ -75,7 +75,7 @@ class Company(NestedSet): def validate_default_accounts(self): accounts = [ - ["Default Bank Account", "default_bank_account"], ["Default Cash Account", "default_cash_account"], + ["Default Bank Account", "default_bank_account"], ["Default Cash Account", "default_cash_account"], ["Default Receivable Account", "default_receivable_account"], ["Default Payable Account", "default_payable_account"], ["Default Expense Account", "default_expense_account"], ["Default Income Account", "default_income_account"], ["Stock Received But Not Billed Account", "stock_received_but_not_billed"], ["Stock Adjustment Account", "stock_adjustment_account"], From e15ef1e19f124436d8705d633a02388a1107056f Mon Sep 17 00:00:00 2001 From: pateljannat Date: Thu, 10 Dec 2020 20:55:25 +0530 Subject: [PATCH 165/477] fix: corrected tests --- erpnext/projects/doctype/project/project.py | 35 +++++++----- .../projects/doctype/project/test_project.py | 57 ++++++++++++------- .../project_template/test_project_template.py | 19 ++++--- erpnext/projects/doctype/task/test_task.py | 8 +-- 4 files changed, 71 insertions(+), 48 deletions(-) diff --git a/erpnext/projects/doctype/project/project.py b/erpnext/projects/doctype/project/project.py index 04a0fb6c4f0..dfb54a2f77f 100644 --- a/erpnext/projects/doctype/project/project.py +++ b/erpnext/projects/doctype/project/project.py @@ -54,17 +54,15 @@ class Project(Document): self.project_type = template.project_type # create tasks from template + project_tasks = [] for task in template.tasks: template_task_details = frappe.get_doc("Task", task.task) - project_task = self.create_task_from_template(template_task_details) + project_tasks.append(self.create_task_from_template(template_task_details)) - if template_task_details.depends_on: - for child_task in template_task_details.depends_on: - child_task_details = frappe.get_doc("Task",child_task.task) - self.create_task_from_template(child_task_details, project_task) + #self.dependency_mapping(template.tasks, project_tasks) - def create_task_from_template(self, task_details, project_task=None): - doc = frappe.get_doc(dict( + def create_task_from_template(self, task_details): + return frappe.get_doc(dict( doctype = 'Task', subject = task_details.subject, project = self.name, @@ -75,14 +73,21 @@ class Project(Document): task_weight = task_details.task_weight, type = task_details.type, issue = task_details.issue, - is_group = task_details.is_group - )) - if task_details.parent_task and project_task: - doc.parent_task = project_task.name - if not task_details.is_group: - doc.depends_on = task_details.depends_on - doc.insert() - return doc + is_group = task_details.is_group, + start = task_details.start, + duration = task_details.duration + )).insert() + + """ def dependency_mapping(self, template_tasks, project_tasks): + for tmp_task in template_tasks: + for prj_task in project_tasks: + if tmp_task.subject == prj_task.subject: + if tmp_task.depends_on and not prj_task.depends_on: + for child_task in tmp_task.depends_on: + child_task_detai + prj_task.depends_on = tmp_task.depends_on + """ + def is_row_updated(self, row, existing_task_data, fields): if self.get("__islocal") or not existing_task_data: return True diff --git a/erpnext/projects/doctype/project/test_project.py b/erpnext/projects/doctype/project/test_project.py index 52f877b8b75..f9bb1b3ac4d 100644 --- a/erpnext/projects/doctype/project/test_project.py +++ b/erpnext/projects/doctype/project/test_project.py @@ -20,15 +20,16 @@ class TestProject(unittest.TestCase): frappe.db.sql('delete from tabTask where project = "Test Project with Templ - no parent and dependend tasks"') frappe.delete_doc('Project', 'Test Project with Templ - no parent and dependend tasks') - if not frappe.db.exists("Task", "Test Temp Task with no parent and dependency"): - task1 = create_task(subject="Test Temp Task with no parent and dependency", is_template=1, begin=0, duration=3) + task1 = task_exists("Test Temp Task with no parent and dependency") + if not task1: + task1 = create_task(subject="Test Temp Task with no parent and dependency", is_template=1, begin=5, duration=3) template = make_project_template("Test Project Template - no parent and dependend tasks", [task1]) project = get_project("Test Project with Templ - no parent and dependend tasks", template) tasks = frappe.get_all('Task', '*', dict(project=project.name), order_by='creation asc') self.assertEqual(tasks[0].subject, 'Test Temp Task with no parent and dependency') - self.assertEqual(getdate(tasks[0].exp_end_date), add_days(nowdate() + 0 + 3)) + self.assertEqual(getdate(tasks[0].exp_end_date), calculate_end_date(project, tasks[0])) self.assertEqual(len(tasks), 1) def test_project_template_having_parent_child_tasks(self): @@ -36,28 +37,31 @@ class TestProject(unittest.TestCase): frappe.db.sql('delete from tabTask where project = "Test Project with Templ - tasks with parent-child"') frappe.delete_doc('Project', 'Test Project with Templ - tasks with parent-child') - if not frappe.db.exists("Task", "Test Temp Task parent"): + task1 = task_exists("Test Temp Task parent") + if not task1: task1 = create_task(subject="Test Temp Task parent", is_group=1, is_template=1, begin=1, duration=1) - if not frappe.db.exists("Task", "Test Temp Task child 1"): + task2 = task_exists("Test Temp Task child 1") + if not task2: task2 = create_task(subject="Test Temp Task child 1", parent_task=task1.name, is_template=1, begin=1, duration=3) - if not frappe.db.exists("Task", "Test Temp Task child 2"): + task3 = task_exists("Test Temp Task child 2") + if not task3: task3 = create_task(subject="Test Temp Task child 2", parent_task=task1.name, is_template=1, begin=2, duration=3) - template = make_project_template("Test Project Template - tasks with parent-child", [task1, task2, task3]) + template = make_project_template("Test Project Template - tasks with parent-child", [task1]) project = get_project("Test Project with Templ - tasks with parent-child", template) tasks = frappe.get_all('Task', '*', dict(project=project.name), order_by='creation asc') - print(tasks, type(tasks), len(tasks)) + print(tasks[0].duration) self.assertEqual(tasks[0].subject, 'Test Temp Task parent') - self.assertEqual(getdate(tasks[0].exp_end_date), add_days(nowdate()+ 1 + 1)) + self.assertEqual(getdate(tasks[0].exp_end_date), calculate_end_date(project, tasks[0])) self.assertEqual(tasks[1].subject, 'Test Temp Task child 1') - self.assertEqual(getdate(tasks[1].exp_end_date), add_days(nowdate()+ 1 + 3)) + self.assertEqual(getdate(tasks[1].exp_end_date), calculate_end_date(project, tasks[1])) self.assertEqual(tasks[1].parent_task, tasks[0].name) self.assertEqual(tasks[2].subject, 'Test Temp Task child 2') - self.assertEqual(getdate(tasks[2].exp_end_date), add_days(nowdate()+ 2 + 3)) + self.assertEqual(getdate(tasks[2].exp_end_date), calculate_end_date(project, tasks[2])) self.assertEqual(tasks[2].parent_task, tasks[0].name) self.assertEqual(len(tasks), 3) @@ -67,22 +71,24 @@ class TestProject(unittest.TestCase): frappe.db.sql('delete from tabTask where project = "Test Project with Templ - dependent tasks"') frappe.delete_doc('Project', 'Test Project with Templ - dependent tasks') - if not frappe.db.exists("Task", "Test Temp Task for dependency"): + task1 = task_exists("Test Temp Task for dependency") + if not task1: task1 = create_task(subject="Test Temp Task for dependency", is_template=1, begin=3, duration=1) - if not frappe.db.exists("Task", "Test Temp Task with dependency"): + task2 = task_exists("Test Temp Task with dependency") + if not task2: task2 = create_task(subject="Test Temp Task with dependency", depends_on=task1.name, is_template=1, begin=2, duration=2) - template = make_project_template("Test Project Template - tasks with parent-child", [task1, task2]) + template = make_project_template("Test Project with Templ - dependent tasks", [task2]) project = get_project("Test Project with Templ - tasks with parent-child", template) tasks = frappe.get_all('Task', '*', dict(project=project.name), order_by='creation asc') - self.assertEqual(tasks[0].subject, 'Test Temp Task for dependency') - self.assertEqual(getdate(tasks[0].exp_end_date), add_days(nowdate()+ 3 + 1)) + self.assertEqual(tasks[0].subject, 'Test Temp Task with dependency') + self.assertEqual(getdate(tasks[0].exp_end_date), calculate_end_date(project, tasks[0])) + self.assertEqual(tasks[0].depends_on, tasks[1].name) - self.assertEqual(tasks[1].subject, 'Test Temp Task with dependency') - self.assertEqual(getdate(tasks[1].exp_end_date), add_days(nowdate()+ 2 + 2)) - self.assertEqual(tasks[1].depends_on, tasks[0].name) + self.assertEqual(tasks[1].subject, 'Test Temp Task for dependency') + self.assertEqual(getdate(tasks[1].exp_end_date), calculate_end_date(project, tasks[1]) ) self.assertEqual(len(tasks), 2) @@ -93,7 +99,7 @@ def get_project(name, template): project_name = name, status = 'Open', project_template = template.name, - expected_start_date = '2019-01-01' + expected_start_date = nowdate() )).insert() return project @@ -114,4 +120,13 @@ def make_project(args): if not frappe.db.exists("Project", args.project_name): project.insert() - return project \ No newline at end of file + return project + +def task_exists(subject): + result = frappe.db.get_list("Task", filters={"subject": subject},fields=["name"]) + if not len(result): + return False + return frappe.get_doc("Task", result[0].name) + +def calculate_end_date(project, task): + return getdate(add_days(project.expected_start_date, task.start + task.duration)) \ No newline at end of file diff --git a/erpnext/projects/doctype/project_template/test_project_template.py b/erpnext/projects/doctype/project_template/test_project_template.py index 379365f9998..6c6b78368ed 100644 --- a/erpnext/projects/doctype/project_template/test_project_template.py +++ b/erpnext/projects/doctype/project_template/test_project_template.py @@ -17,9 +17,7 @@ def get_project_template(project_template_name="Test Project Template", project_ name = project_template_name, tasks = project_tasks or [ create_task(subject="_Test Template Task 1", is_template=1, begin=0, duration=3), - create_task(subject="_Test Template Task 2", is_template=1, begin=0, duration=2), - create_task(subject="_Test Template Task 3", is_template=1, begin=2, duration=4), - create_task(subject="_Test Template Task 4", is_template=1, begin=3, duration=2), + create_task(subject="_Test Template Task 2", is_template=1, begin=0, duration=2) ] )).insert() @@ -27,13 +25,18 @@ def get_project_template(project_template_name="Test Project Template", project_ def make_project_template(project_template_name, project_tasks=[]): if not frappe.db.exists('Project Template', project_template_name): - frappe.get_doc(dict( - doctype = 'Project Template', - name = project_template_name, - tasks = project_tasks or [ + project_tasks = project_tasks or [ create_task(subject="_Test Template Task 1", is_template=1, begin=0, duration=3), create_task(subject="_Test Template Task 2", is_template=1, begin=0, duration=2), ] - )).insert() + doc = frappe.get_doc(dict( + doctype = 'Project Template', + name = project_template_name + )) + for task in project_tasks: + doc.append("tasks",{ + "task": task.name + }) + doc.insert() return frappe.get_doc('Project Template', project_template_name) \ No newline at end of file diff --git a/erpnext/projects/doctype/task/test_task.py b/erpnext/projects/doctype/task/test_task.py index 181a2dc3162..d43d132e80e 100644 --- a/erpnext/projects/doctype/task/test_task.py +++ b/erpnext/projects/doctype/task/test_task.py @@ -104,11 +104,12 @@ def create_task(subject, start=None, end=None, depends_on=None, project=None, pa task.subject = subject task.exp_start_date = start or nowdate() task.exp_end_date = end or nowdate() - task.project = project or "_Test Project" - task.is_template = is_template, + task.project = project + task.is_template = is_template task.start = begin - task.duration = duration, + task.duration = duration task.is_group = is_group + task.parent_task = parent_task if save: task.save() else: @@ -120,5 +121,4 @@ def create_task(subject, start=None, end=None, depends_on=None, project=None, pa }) if save: task.save() - return task From c9209237daa91e09832927c11ec223abbe6a99bb Mon Sep 17 00:00:00 2001 From: Suraj Shetty Date: Thu, 10 Dec 2020 22:45:27 +0530 Subject: [PATCH 166/477] fix: Progress bar style --- erpnext/education/doctype/fee_schedule/fee_schedule.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/education/doctype/fee_schedule/fee_schedule.js b/erpnext/education/doctype/fee_schedule/fee_schedule.js index 75dd4469e84..0b4c2cdfc71 100644 --- a/erpnext/education/doctype/fee_schedule/fee_schedule.js +++ b/erpnext/education/doctype/fee_schedule/fee_schedule.js @@ -43,7 +43,7 @@ frappe.ui.form.on('Fee Schedule', { frm.reload_doc(); } if (data.progress) { - let progress_bar = $(cur_frm.dashboard.progress_area).find('.progress-bar'); + let progress_bar = $(cur_frm.dashboard.progress_area.body).find('.progress-bar'); if (progress_bar) { $(progress_bar).removeClass('progress-bar-danger').addClass('progress-bar-success progress-bar-striped'); $(progress_bar).css('width', data.progress+'%'); From fa72671929581c318cd0b828b07477987199a003 Mon Sep 17 00:00:00 2001 From: pateljannat Date: Fri, 11 Dec 2020 11:16:54 +0530 Subject: [PATCH 167/477] fix: partial order for drop ship --- .../doctype/sales_order/sales_order.py | 77 +++++++++---------- 1 file changed, 35 insertions(+), 42 deletions(-) diff --git a/erpnext/selling/doctype/sales_order/sales_order.py b/erpnext/selling/doctype/sales_order/sales_order.py index 3e1c82f9616..2379a304bbc 100755 --- a/erpnext/selling/doctype/sales_order/sales_order.py +++ b/erpnext/selling/doctype/sales_order/sales_order.py @@ -830,52 +830,45 @@ def make_purchase_order_for_default_supplier(source_name, selected_items=[], tar frappe.throw(_("Please set a Supplier against the Items to be considered in the Purchase Order.")) for supplier in suppliers: - po = frappe.get_list("Purchase Order", filters={"sales_order":source_name, "supplier":supplier, "docstatus": ("<", "2")}) - if len(po) == 0 or any( item.get("delivered_by_supplier") == 1 for item in selected_items): - doc = get_mapped_doc("Sales Order", source_name, { - "Sales Order": { - "doctype": "Purchase Order", - "field_no_map": [ - "address_display", - "contact_display", - "contact_mobile", - "contact_email", - "contact_person", - "taxes_and_charges", - "shipping_address" - ], - "validation": { - "docstatus": ["=", 1] - } - }, - "Sales Order Item": { - "doctype": "Purchase Order Item", - "field_map": [ - ["name", "sales_order_item"], - ["parent", "sales_order"], - ["stock_uom", "stock_uom"], - ["uom", "uom"], - ["conversion_factor", "conversion_factor"], - ["delivery_date", "schedule_date"] - ], - "field_no_map": [ - "rate", - "price_list_rate", - "item_tax_template" - ], - "postprocess": update_item, - "condition": lambda doc: doc.ordered_qty < doc.stock_qty and doc.supplier == supplier and doc.item_code in items_to_map + doc = get_mapped_doc("Sales Order", source_name, { + "Sales Order": { + "doctype": "Purchase Order", + "field_no_map": [ + "address_display", + "contact_display", + "contact_mobile", + "contact_email", + "contact_person", + "taxes_and_charges", + "shipping_address" + ], + "validation": { + "docstatus": ["=", 1] } - }, target_doc, set_missing_values) + }, + "Sales Order Item": { + "doctype": "Purchase Order Item", + "field_map": [ + ["name", "sales_order_item"], + ["parent", "sales_order"], + ["stock_uom", "stock_uom"], + ["uom", "uom"], + ["conversion_factor", "conversion_factor"], + ["delivery_date", "schedule_date"] + ], + "field_no_map": [ + "rate", + "price_list_rate", + "item_tax_template" + ], + "postprocess": update_item, + "condition": lambda doc: doc.ordered_qty < doc.stock_qty and doc.supplier == supplier and doc.item_code in items_to_map + } + }, target_doc, set_missing_values) - doc.insert() - else: - suppliers =[] - if suppliers: + doc.insert() frappe.db.commit() return doc - else: - frappe.msgprint(_("Purchase Order already created for all Sales Order items")) @frappe.whitelist() def make_purchase_order(source_name, selected_items=[], target_doc=None): From 06961a261e8560c591e2828e1733a90720fc4872 Mon Sep 17 00:00:00 2001 From: pateljannat Date: Fri, 11 Dec 2020 11:46:43 +0530 Subject: [PATCH 168/477] fix: conflicts --- erpnext/selling/doctype/sales_order/sales_order.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/erpnext/selling/doctype/sales_order/sales_order.py b/erpnext/selling/doctype/sales_order/sales_order.py index 2379a304bbc..5d341b746a6 100755 --- a/erpnext/selling/doctype/sales_order/sales_order.py +++ b/erpnext/selling/doctype/sales_order/sales_order.py @@ -840,7 +840,8 @@ def make_purchase_order_for_default_supplier(source_name, selected_items=[], tar "contact_email", "contact_person", "taxes_and_charges", - "shipping_address" + "shipping_address", + "terms" ], "validation": { "docstatus": ["=", 1] @@ -859,7 +860,10 @@ def make_purchase_order_for_default_supplier(source_name, selected_items=[], tar "field_no_map": [ "rate", "price_list_rate", - "item_tax_template" + "item_tax_template", + "discount_percentage", + "discount_amount", + "pricing_rules" ], "postprocess": update_item, "condition": lambda doc: doc.ordered_qty < doc.stock_qty and doc.supplier == supplier and doc.item_code in items_to_map From c47d38dc1820c3328b2e782c740fa10ad3471890 Mon Sep 17 00:00:00 2001 From: marination Date: Mon, 14 Dec 2020 11:48:04 +0530 Subject: [PATCH 169/477] chore: Stock Entry Tests and fixes - Maintain item-warehouse wise rules for Stock Entry Material Transfer - Test cases for Stock Entry with more use cases - Sider fixes --- erpnext/public/js/controllers/transaction.js | 5 +- .../doctype/putaway_rule/putaway_rule.py | 38 +-- .../doctype/putaway_rule/test_putaway_rule.py | 233 ++++++++++++++---- .../stock/doctype/stock_entry/stock_entry.js | 2 +- .../stock/doctype/stock_entry/stock_entry.py | 3 +- .../doctype/stock_entry/stock_entry_utils.py | 5 +- 6 files changed, 216 insertions(+), 70 deletions(-) diff --git a/erpnext/public/js/controllers/transaction.js b/erpnext/public/js/controllers/transaction.js index 54634482b0a..2dabb9a6474 100644 --- a/erpnext/public/js/controllers/transaction.js +++ b/erpnext/public/js/controllers/transaction.js @@ -2030,7 +2030,7 @@ erpnext.show_serial_batch_selector = function (frm, d, callback, on_close, show_ }); } -erpnext.apply_putaway_rule = (frm) => { +erpnext.apply_putaway_rule = (frm, purpose=null) => { if (!frm.doc.company) { frappe.throw({message: __("Please select a Company first."), title: __("Mandatory")}); } @@ -2042,7 +2042,8 @@ erpnext.apply_putaway_rule = (frm) => { doctype: frm.doctype, items: frm.doc.items, company: frm.doc.company, - sync: true + sync: true, + purpose: purpose }, callback: (result) => { if (!result.exc && result.message) { diff --git a/erpnext/stock/doctype/putaway_rule/putaway_rule.py b/erpnext/stock/doctype/putaway_rule/putaway_rule.py index 4ed4dafac77..56752583fa7 100644 --- a/erpnext/stock/doctype/putaway_rule/putaway_rule.py +++ b/erpnext/stock/doctype/putaway_rule/putaway_rule.py @@ -64,11 +64,14 @@ def get_putaway_capacity(rule): return free_space if free_space > 0 else 0 @frappe.whitelist() -def apply_putaway_rule(doctype, items, company, sync=None): +def apply_putaway_rule(doctype, items, company, sync=None, purpose=None): """ Applies Putaway Rule on line items. - items: List of Purchase Receipt Item objects - company: Company in the Purchase Receipt + items: List of Purchase Receipt/Stock Entry Items + company: Company in the Purchase Receipt/Stock Entry + doctype: Doctype to apply rule on + purpose: Purpose of Stock Entry + sync (optional): Sync with client side only for client side calls """ if isinstance(items, string_types): items = json.loads(items) @@ -82,31 +85,36 @@ def apply_putaway_rule(doctype, items, company, sync=None): source_warehouse = item.get("s_warehouse") serial_nos = get_serial_nos(item.get("serial_no")) - item.conversion_factor = flt(item.conversion_factor) or 1 + item.conversion_factor = flt(item.conversion_factor) or 1.0 pending_qty, item_code = flt(item.qty), item.item_code pending_stock_qty = flt(item.transfer_qty) if doctype == "Stock Entry" else flt(item.stock_qty) - if not pending_qty or not item_code: - updated_table = add_row(item, pending_qty, item.warehouse, updated_table) - continue - uom_must_be_whole_number = frappe.db.get_value('UOM', item.uom, 'must_be_whole_number') + if not pending_qty or not item_code: + updated_table = add_row(item, pending_qty, source_warehouse or item.warehouse, updated_table) + continue + at_capacity, rules = get_ordered_putaway_rules(item_code, company, source_warehouse=source_warehouse) if not rules: - warehouse = item.warehouse + warehouse = source_warehouse or item.warehouse if at_capacity: - warehouse = '' # rules available, but no free space + # rules available, but no free space items_not_accomodated.append([item_code, pending_qty]) - updated_table = add_row(item, pending_qty, warehouse, updated_table) + else: + updated_table = add_row(item, pending_qty, warehouse, updated_table) continue - # maintain item wise rules, to handle if item is entered twice + # maintain item/item-warehouse wise rules, to handle if item is entered twice # in the table, due to different price, etc. - if not item_wise_rules[item_code]: - item_wise_rules[item_code] = rules + key = item_code + if doctype == "Stock Entry" and purpose == "Material Transfer" and source_warehouse: + key = (item_code, source_warehouse) - for rule in item_wise_rules[item_code]: + if not item_wise_rules[key]: + item_wise_rules[key] = rules + + for rule in item_wise_rules[key]: if pending_stock_qty > 0 and rule.free_space: stock_qty_to_allocate = flt(rule.free_space) if pending_stock_qty >= flt(rule.free_space) else pending_stock_qty qty_to_allocate = stock_qty_to_allocate / item.conversion_factor diff --git a/erpnext/stock/doctype/putaway_rule/test_putaway_rule.py b/erpnext/stock/doctype/putaway_rule/test_putaway_rule.py index 17619e01bc1..86f7dc3e084 100644 --- a/erpnext/stock/doctype/putaway_rule/test_putaway_rule.py +++ b/erpnext/stock/doctype/putaway_rule/test_putaway_rule.py @@ -4,12 +4,11 @@ from __future__ import unicode_literals import frappe import unittest -from frappe.utils import add_days, nowdate from erpnext.stock.doctype.item.test_item import make_item from erpnext.stock.get_item_details import get_conversion_factor from erpnext.stock.doctype.warehouse.test_warehouse import create_warehouse from erpnext.stock.doctype.stock_entry.test_stock_entry import make_stock_entry -from erpnext.buying.doctype.purchase_order.test_purchase_order import create_purchase_order +from erpnext.stock.doctype.batch.test_batch import make_new_batch from erpnext.stock.doctype.purchase_receipt.test_purchase_receipt import make_purchase_receipt class TestPutawayRule(unittest.TestCase): @@ -27,6 +26,9 @@ class TestPutawayRule(unittest.TestCase): if not frappe.db.exists("Warehouse", {"warehouse_name": "Rack 2"}): create_warehouse("Rack 2") + self.warehouse_1 = frappe.db.get_value("Warehouse", {"warehouse_name": "Rack 1"}) + self.warehouse_2 = frappe.db.get_value("Warehouse", {"warehouse_name": "Rack 2"}) + if not frappe.db.exists("UOM", "Bag"): new_uom = frappe.new_doc("UOM") new_uom.uom_name = "Bag" @@ -34,21 +36,18 @@ class TestPutawayRule(unittest.TestCase): def test_putaway_rules_priority(self): """Test if rule is applied by priority, irrespective of free space.""" - warehouse_1 = frappe.db.get_value("Warehouse", {"warehouse_name": "Rack 1"}) - warehouse_2 = frappe.db.get_value("Warehouse", {"warehouse_name": "Rack 2"}) - - rule_1 = create_putaway_rule(item_code="_Rice", warehouse=warehouse_1, capacity=200, + rule_1 = create_putaway_rule(item_code="_Rice", warehouse=self.warehouse_1, capacity=200, uom="Kg") - rule_2 = create_putaway_rule(item_code="_Rice", warehouse=warehouse_2, capacity=300, + rule_2 = create_putaway_rule(item_code="_Rice", warehouse=self.warehouse_2, capacity=300, uom="Kg", priority=2) pr = make_purchase_receipt(item_code="_Rice", qty=300, apply_putaway_rule=1, do_not_submit=1) self.assertEqual(len(pr.items), 2) self.assertEqual(pr.items[0].qty, 200) - self.assertEqual(pr.items[0].warehouse, warehouse_1) + self.assertEqual(pr.items[0].warehouse, self.warehouse_1) self.assertEqual(pr.items[1].qty, 100) - self.assertEqual(pr.items[1].warehouse, warehouse_2) + self.assertEqual(pr.items[1].warehouse, self.warehouse_2) pr.delete() rule_1.delete() @@ -57,26 +56,23 @@ class TestPutawayRule(unittest.TestCase): def test_putaway_rules_with_same_priority(self): """Test if rule with more free space is applied, among two rules with same priority and capacity.""" - warehouse_1 = frappe.db.get_value("Warehouse", {"warehouse_name": "Rack 1"}) - warehouse_2 = frappe.db.get_value("Warehouse", {"warehouse_name": "Rack 2"}) - - rule_1 = create_putaway_rule(item_code="_Rice", warehouse=warehouse_1, capacity=500, + rule_1 = create_putaway_rule(item_code="_Rice", warehouse=self.warehouse_1, capacity=500, uom="Kg") - rule_2 = create_putaway_rule(item_code="_Rice", warehouse=warehouse_2, capacity=500, + rule_2 = create_putaway_rule(item_code="_Rice", warehouse=self.warehouse_2, capacity=500, uom="Kg") # out of 500 kg capacity, occupy 100 kg in warehouse_1 - stock_receipt = make_stock_entry(item_code="_Rice", target=warehouse_1, qty=100, basic_rate=50) + stock_receipt = make_stock_entry(item_code="_Rice", target=self.warehouse_1, qty=100, basic_rate=50) pr = make_purchase_receipt(item_code="_Rice", qty=700, apply_putaway_rule=1, do_not_submit=1) self.assertEqual(len(pr.items), 2) self.assertEqual(pr.items[0].qty, 500) # warehouse_2 has 500 kg free space, it is given priority - self.assertEqual(pr.items[0].warehouse, warehouse_2) + self.assertEqual(pr.items[0].warehouse, self.warehouse_2) self.assertEqual(pr.items[1].qty, 200) # warehouse_1 has 400 kg free space, it is given less priority - self.assertEqual(pr.items[1].warehouse, warehouse_1) + self.assertEqual(pr.items[1].warehouse, self.warehouse_1) stock_receipt.cancel() pr.delete() @@ -85,21 +81,20 @@ class TestPutawayRule(unittest.TestCase): def test_putaway_rules_with_insufficient_capacity(self): """Test if qty exceeding capacity, is handled.""" - warehouse_1 = frappe.db.get_value("Warehouse", {"warehouse_name": "Rack 1"}) - warehouse_2 = frappe.db.get_value("Warehouse", {"warehouse_name": "Rack 2"}) - - rule_1 = create_putaway_rule(item_code="_Rice", warehouse=warehouse_1, capacity=100, + rule_1 = create_putaway_rule(item_code="_Rice", warehouse=self.warehouse_1, capacity=100, uom="Kg") - rule_2 = create_putaway_rule(item_code="_Rice", warehouse=warehouse_2, capacity=200, + rule_2 = create_putaway_rule(item_code="_Rice", warehouse=self.warehouse_2, capacity=200, uom="Kg") pr = make_purchase_receipt(item_code="_Rice", qty=350, apply_putaway_rule=1, do_not_submit=1) self.assertEqual(len(pr.items), 2) self.assertEqual(pr.items[0].qty, 200) - self.assertEqual(pr.items[0].warehouse, warehouse_2) + self.assertEqual(pr.items[0].warehouse, self.warehouse_2) self.assertEqual(pr.items[1].qty, 100) - self.assertEqual(pr.items[1].warehouse, warehouse_1) + self.assertEqual(pr.items[1].warehouse, self.warehouse_1) + # total 300 assigned, 50 unassigned + pr.delete() rule_1.delete() rule_2.delete() @@ -114,26 +109,23 @@ class TestPutawayRule(unittest.TestCase): }) item.save() - warehouse_1 = frappe.db.get_value("Warehouse", {"warehouse_name": "Rack 1"}) - warehouse_2 = frappe.db.get_value("Warehouse", {"warehouse_name": "Rack 2"}) - - rule_1 = create_putaway_rule(item_code="_Rice", warehouse=warehouse_1, capacity=3, + rule_1 = create_putaway_rule(item_code="_Rice", warehouse=self.warehouse_1, capacity=3, uom="Bag") self.assertEqual(rule_1.stock_capacity, 3000) - rule_2 = create_putaway_rule(item_code="_Rice", warehouse=warehouse_2, capacity=4, + rule_2 = create_putaway_rule(item_code="_Rice", warehouse=self.warehouse_2, capacity=4, uom="Bag") self.assertEqual(rule_2.stock_capacity, 4000) # populate 'Rack 1' with 1 Bag, making the free space 2 Bags - stock_receipt = make_stock_entry(item_code="_Rice", target=warehouse_1, qty=1000, basic_rate=50) + stock_receipt = make_stock_entry(item_code="_Rice", target=self.warehouse_1, qty=1000, basic_rate=50) pr = make_purchase_receipt(item_code="_Rice", qty=6, uom="Bag", stock_uom="Kg", conversion_factor=1000, apply_putaway_rule=1, do_not_submit=1) self.assertEqual(len(pr.items), 2) self.assertEqual(pr.items[0].qty, 4) - self.assertEqual(pr.items[0].warehouse, warehouse_2) + self.assertEqual(pr.items[0].warehouse, self.warehouse_2) self.assertEqual(pr.items[1].qty, 2) - self.assertEqual(pr.items[1].warehouse, warehouse_1) + self.assertEqual(pr.items[1].warehouse, self.warehouse_1) stock_receipt.cancel() pr.delete() @@ -152,15 +144,12 @@ class TestPutawayRule(unittest.TestCase): frappe.db.set_value("UOM", "Bag", "must_be_whole_number", 1) - warehouse_1 = frappe.db.get_value("Warehouse", {"warehouse_name": "Rack 1"}) - warehouse_2 = frappe.db.get_value("Warehouse", {"warehouse_name": "Rack 2"}) - # Putaway Rule in different UOM - rule_1 = create_putaway_rule(item_code="_Rice", warehouse=warehouse_1, capacity=1, + rule_1 = create_putaway_rule(item_code="_Rice", warehouse=self.warehouse_1, capacity=1, uom="Bag") self.assertEqual(rule_1.stock_capacity, 1000) # Putaway Rule in Stock UOM - rule_2 = create_putaway_rule(item_code="_Rice", warehouse=warehouse_2, capacity=500) + rule_2 = create_putaway_rule(item_code="_Rice", warehouse=self.warehouse_2, capacity=500) self.assertEqual(rule_2.stock_capacity, 500) # total capacity is 1500 Kg @@ -168,7 +157,7 @@ class TestPutawayRule(unittest.TestCase): conversion_factor=1000, apply_putaway_rule=1, do_not_submit=1) self.assertEqual(len(pr.items), 1) self.assertEqual(pr.items[0].qty, 1) - self.assertEqual(pr.items[0].warehouse, warehouse_1) + self.assertEqual(pr.items[0].warehouse, self.warehouse_1) # leftover space was for 500 kg (0.5 Bag) # Since Bag is a whole UOM, 1(out of 2) Bag will be unassigned @@ -177,11 +166,8 @@ class TestPutawayRule(unittest.TestCase): rule_2.delete() def test_putaway_rules_with_reoccurring_item(self): - """Test rules on same item entered multiple times.""" - warehouse_1 = frappe.db.get_value("Warehouse", {"warehouse_name": "Rack 1"}) - warehouse_2 = frappe.db.get_value("Warehouse", {"warehouse_name": "Rack 2"}) - - rule_1 = create_putaway_rule(item_code="_Rice", warehouse=warehouse_1, capacity=200, + """Test rules on same item entered multiple times with different rate.""" + rule_1 = create_putaway_rule(item_code="_Rice", warehouse=self.warehouse_1, capacity=200, uom="Kg") # total capacity is 200 Kg @@ -201,12 +187,12 @@ class TestPutawayRule(unittest.TestCase): pr.save() self.assertEqual(len(pr.items), 2) self.assertEqual(pr.items[0].qty, 100) - self.assertEqual(pr.items[0].warehouse, warehouse_1) + self.assertEqual(pr.items[0].warehouse, self.warehouse_1) self.assertEqual(pr.items[0].putaway_rule, rule_1.name) # same rule applied to second item row # with previous assignment considered self.assertEqual(pr.items[1].qty, 100) # 100 unassigned in second row from 200 - self.assertEqual(pr.items[1].warehouse, warehouse_1) + self.assertEqual(pr.items[1].warehouse, self.warehouse_1) self.assertEqual(pr.items[1].putaway_rule, rule_1.name) pr.delete() @@ -214,17 +200,14 @@ class TestPutawayRule(unittest.TestCase): def test_validate_over_receipt_in_warehouse(self): """Test if overreceipt is blocked in the presence of putaway rules.""" - warehouse_1 = frappe.db.get_value("Warehouse", {"warehouse_name": "Rack 1"}) - warehouse_2 = frappe.db.get_value("Warehouse", {"warehouse_name": "Rack 2"}) - - rule_1 = create_putaway_rule(item_code="_Rice", warehouse=warehouse_1, capacity=200, + rule_1 = create_putaway_rule(item_code="_Rice", warehouse=self.warehouse_1, capacity=200, uom="Kg") pr = make_purchase_receipt(item_code="_Rice", qty=300, apply_putaway_rule=1, do_not_submit=1) self.assertEqual(len(pr.items), 1) self.assertEqual(pr.items[0].qty, 200) # 100 is unassigned fro 300 Kg - self.assertEqual(pr.items[0].warehouse, warehouse_1) + self.assertEqual(pr.items[0].warehouse, self.warehouse_1) self.assertEqual(pr.items[0].putaway_rule, rule_1.name) # force overreceipt and disable apply putaway rule in PR @@ -236,6 +219,156 @@ class TestPutawayRule(unittest.TestCase): pr.delete() rule_1.delete() + def test_putaway_rule_on_stock_entry_material_transfer(self): + """Test if source warehouse is considered while applying rules.""" + rule_1 = create_putaway_rule(item_code="_Rice", warehouse=self.warehouse_1, capacity=200, + uom="Kg") # higher priority + rule_2 = create_putaway_rule(item_code="_Rice", warehouse=self.warehouse_2, capacity=100, + uom="Kg", priority=2) + + stock_entry = make_stock_entry(item_code="_Rice", source=self.warehouse_1, qty=200, + target="_Test Warehouse - _TC", purpose="Material Transfer", + apply_putaway_rule=1, do_not_submit=1) + + stock_entry_item = stock_entry.get("items")[0] + + # since source warehouse is Rack 1, rule 1 (for Rack 1) will be avoided + # even though it has more free space and higher priority + self.assertEqual(stock_entry_item.t_warehouse, self.warehouse_2) + self.assertEqual(stock_entry_item.qty, 100) # unassigned 100 out of 200 Kg + self.assertEqual(stock_entry_item.putaway_rule, rule_2.name) + + stock_entry.delete() + rule_1.delete() + rule_2.delete() + + def test_putaway_rule_on_stock_entry_material_transfer_reoccuring_item(self): + """Test if reoccuring item is correctly considered.""" + rule_1 = create_putaway_rule(item_code="_Rice", warehouse=self.warehouse_1, capacity=300, + uom="Kg") + rule_2 = create_putaway_rule(item_code="_Rice", warehouse=self.warehouse_2, capacity=600, + uom="Kg", priority=2) + + # create SE with first row having source warehouse as Rack 2 + stock_entry = make_stock_entry(item_code="_Rice", source=self.warehouse_2, qty=200, + target="_Test Warehouse - _TC", purpose="Material Transfer", + apply_putaway_rule=1, do_not_submit=1) + + # Add rows with source warehouse as Rack 1 + stock_entry.extend("items", [ + { + "item_code": "_Rice", + "s_warehouse": self.warehouse_1, + "t_warehouse": "_Test Warehouse - _TC", + "qty": 100, + "basic_rate": 50, + "conversion_factor": 1.0, + "transfer_qty": 100 + }, + { + "item_code": "_Rice", + "s_warehouse": self.warehouse_1, + "t_warehouse": "_Test Warehouse - _TC", + "qty": 200, + "basic_rate": 60, + "conversion_factor": 1.0, + "transfer_qty": 200 + } + ]) + + stock_entry.save() + + # since source warehouse was Rack 2, exclude rule_2 + self.assertEqual(stock_entry.items[0].t_warehouse, self.warehouse_1) + self.assertEqual(stock_entry.items[0].qty, 200) + self.assertEqual(stock_entry.items[0].putaway_rule, rule_1.name) + + # since source warehouse was Rack 1, exclude rule_1 even though it has + # higher priority + self.assertEqual(stock_entry.items[1].t_warehouse, self.warehouse_2) + self.assertEqual(stock_entry.items[1].qty, 100) + self.assertEqual(stock_entry.items[1].putaway_rule, rule_2.name) + + self.assertEqual(stock_entry.items[2].t_warehouse, self.warehouse_2) + self.assertEqual(stock_entry.items[2].qty, 200) + self.assertEqual(stock_entry.items[2].putaway_rule, rule_2.name) + + stock_entry.delete() + rule_1.delete() + rule_2.delete() + + def test_putaway_rule_on_stock_entry_material_transfer_batch_serial_item(self): + """Test if batch and serial items are split correctly.""" + if not frappe.db.exists("Item", "Water Bottle"): + make_item("Water Bottle", { + "is_stock_item": 1, + "has_batch_no" : 1, + "create_new_batch": 1, + "has_serial_no": 1, + "serial_no_series": "BOTTL-.####", + "stock_uom": "Nos" + }) + + rule_1 = create_putaway_rule(item_code="Water Bottle", warehouse=self.warehouse_1, capacity=3, + uom="Nos") + rule_2 = create_putaway_rule(item_code="Water Bottle", warehouse=self.warehouse_2, capacity=2, + uom="Nos") + + make_new_batch(batch_id="BOTTL-BATCH-1", item_code="Water Bottle") + + pr = make_purchase_receipt(item_code="Water Bottle", qty=5, do_not_submit=1) + pr.items[0].batch_no = "BOTTL-BATCH-1" + pr.save() + pr.submit() + + serial_nos = frappe.get_list("Serial No", filters={"purchase_document_no": pr.name, "status": "Active"}) + serial_nos = [d.name for d in serial_nos] + + stock_entry = make_stock_entry(item_code="Water Bottle", source="_Test Warehouse - _TC", qty=5, + target="Finished Goods - _TC", purpose="Material Transfer", + apply_putaway_rule=1, do_not_save=1) + stock_entry.items[0].batch_no = "BOTTL-BATCH-1" + stock_entry.items[0].serial_no = "\n".join(serial_nos) + stock_entry.save() + + self.assertEqual(stock_entry.items[0].t_warehouse, self.warehouse_1) + self.assertEqual(stock_entry.items[0].qty, 3) + self.assertEqual(stock_entry.items[0].putaway_rule, rule_1.name) + self.assertEqual(stock_entry.items[0].serial_no, "\n".join(serial_nos[:3])) + self.assertEqual(stock_entry.items[0].batch_no, "BOTTL-BATCH-1") + + self.assertEqual(stock_entry.items[1].t_warehouse, self.warehouse_2) + self.assertEqual(stock_entry.items[1].qty, 2) + self.assertEqual(stock_entry.items[1].putaway_rule, rule_2.name) + self.assertEqual(stock_entry.items[1].serial_no, "\n".join(serial_nos[3:])) + self.assertEqual(stock_entry.items[1].batch_no, "BOTTL-BATCH-1") + + stock_entry.delete() + pr.cancel() + rule_1.delete() + rule_2.delete() + + def test_putaway_rule_on_stock_entry_material_receipt(self): + """Test if rules are applied in Stock Entry of type Receipt.""" + rule_1 = create_putaway_rule(item_code="_Rice", warehouse=self.warehouse_1, capacity=200, + uom="Kg") # more capacity + rule_2 = create_putaway_rule(item_code="_Rice", warehouse=self.warehouse_2, capacity=100, + uom="Kg") + + stock_entry = make_stock_entry(item_code="_Rice", qty=100, + target="_Test Warehouse - _TC", purpose="Material Receipt", + apply_putaway_rule=1, do_not_submit=1) + + stock_entry_item = stock_entry.get("items")[0] + + self.assertEqual(stock_entry_item.t_warehouse, self.warehouse_1) + self.assertEqual(stock_entry_item.qty, 100) + self.assertEqual(stock_entry_item.putaway_rule, rule_1.name) + + stock_entry.delete() + rule_1.delete() + rule_2.delete() + def create_putaway_rule(**args): args = frappe._dict(args) putaway = frappe.new_doc("Putaway Rule") diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.js b/erpnext/stock/doctype/stock_entry/stock_entry.js index fd920a585ac..5d9ea8daeeb 100644 --- a/erpnext/stock/doctype/stock_entry/stock_entry.js +++ b/erpnext/stock/doctype/stock_entry/stock_entry.js @@ -574,7 +574,7 @@ frappe.ui.form.on('Stock Entry', { }, apply_putaway_rule: function (frm) { - if (frm.doc.apply_putaway_rule) erpnext.apply_putaway_rule(frm); + if (frm.doc.apply_putaway_rule) erpnext.apply_putaway_rule(frm, frm.doc.purpose); } }); diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.py b/erpnext/stock/doctype/stock_entry/stock_entry.py index aed69e11ddf..e37e1223bc6 100644 --- a/erpnext/stock/doctype/stock_entry/stock_entry.py +++ b/erpnext/stock/doctype/stock_entry/stock_entry.py @@ -47,7 +47,8 @@ class StockEntry(StockController): apply_rule = self.apply_putaway_rule and (self.purpose in ["Material Transfer", "Material Receipt"]) if self.get("items") and apply_rule: - apply_putaway_rule(self.doctype, self.get("items"), self.company) + apply_putaway_rule(self.doctype, self.get("items"), self.company, + purpose=self.purpose) def validate(self): self.pro_doc = frappe._dict() diff --git a/erpnext/stock/doctype/stock_entry/stock_entry_utils.py b/erpnext/stock/doctype/stock_entry/stock_entry_utils.py index b78c6be983f..b12a8547fea 100644 --- a/erpnext/stock/doctype/stock_entry/stock_entry_utils.py +++ b/erpnext/stock/doctype/stock_entry/stock_entry_utils.py @@ -53,6 +53,8 @@ def make_stock_entry(**args): args.target = args.to_warehouse if args.item_code: args.item = args.item_code + if args.apply_putaway_rule: + s.apply_putaway_rule = args.apply_putaway_rule if isinstance(args.qty, string_types): if '.' in args.qty: @@ -118,7 +120,8 @@ def make_stock_entry(**args): "t_warehouse": args.target, "qty": args.qty, "basic_rate": args.rate or args.basic_rate, - "conversion_factor": 1.0, + "conversion_factor": args.conversion_factor or 1.0, + "transfer_qty": flt(args.qty) * (flt(args.conversion_factor) or 1.0), "serial_no": args.serial_no, 'batch_no': args.batch_no, 'cost_center': args.cost_center, From f9751f1f95e9f69701da999bcb342c6b620bcf95 Mon Sep 17 00:00:00 2001 From: pateljannat Date: Mon, 14 Dec 2020 16:20:02 +0530 Subject: [PATCH 170/477] feat: project template having dependent tasks --- erpnext/projects/doctype/project/project.py | 33 +- .../project_template/project_template.py | 23 +- erpnext/projects/doctype/task/task.py | 451 +++++++++--------- 3 files changed, 282 insertions(+), 225 deletions(-) diff --git a/erpnext/projects/doctype/project/project.py b/erpnext/projects/doctype/project/project.py index dfb54a2f77f..2d3339773a1 100644 --- a/erpnext/projects/doctype/project/project.py +++ b/erpnext/projects/doctype/project/project.py @@ -55,11 +55,13 @@ class Project(Document): # create tasks from template project_tasks = [] + tmp_task_details = [] for task in template.tasks: template_task_details = frappe.get_doc("Task", task.task) + tmp_task_details.append(template_task_details) project_tasks.append(self.create_task_from_template(template_task_details)) - #self.dependency_mapping(template.tasks, project_tasks) + self.dependency_mapping(tmp_task_details, project_tasks) def create_task_from_template(self, task_details): return frappe.get_doc(dict( @@ -78,16 +80,33 @@ class Project(Document): duration = task_details.duration )).insert() - """ def dependency_mapping(self, template_tasks, project_tasks): + def dependency_mapping(self, template_tasks, project_tasks): for tmp_task in template_tasks: for prj_task in project_tasks: if tmp_task.subject == prj_task.subject: - if tmp_task.depends_on and not prj_task.depends_on: - for child_task in tmp_task.depends_on: - child_task_detai - prj_task.depends_on = tmp_task.depends_on - """ + self.check_depends_on_value(tmp_task, prj_task, project_tasks) + self.check_for_parent_tasks(tmp_task, prj_task, project_tasks) + def check_depends_on_value(self, tmp_task, prj_task, project_tasks): + if tmp_task.depends_on and not prj_task.depends_on: + for child_task in tmp_task.depends_on: + child_task_subject = frappe.db.get_value("Task", child_task.task, "subject") + corresponding_prj_task = list(filter(lambda x: x.subject == child_task_subject, project_tasks)) + if len(corresponding_prj_task): + prj_task.append("depends_on",{ + "task": corresponding_prj_task[0].name + }) + prj_task.save() + + def check_for_parent_tasks(self, tmp_task, prj_task, project_tasks): + if tmp_task.parent_task and not prj_task.parent_task: + parent_task_subject = frappe.db.get_value("Task", tmp_task.parent_task, "subject") + corresponding_prj_task = list(filter(lambda x: x.subject == parent_task_subject, project_tasks)) + if len(corresponding_prj_task): + prj_task.parent_task = corresponding_prj_task[0].name + print(prj_task.name, prj_task.parent_task, corresponding_prj_task[0].name) + prj_task.save() + print(prj_task.name, corresponding_prj_task[0].name) def is_row_updated(self, row, existing_task_data, fields): if self.get("__islocal") or not existing_task_data: return True diff --git a/erpnext/projects/doctype/project_template/project_template.py b/erpnext/projects/doctype/project_template/project_template.py index ac78135fc42..1beebf7a258 100644 --- a/erpnext/projects/doctype/project_template/project_template.py +++ b/erpnext/projects/doctype/project_template/project_template.py @@ -3,8 +3,27 @@ # For license information, please see license.txt from __future__ import unicode_literals -# import frappe +import frappe from frappe.model.document import Document +from frappe import _ class ProjectTemplate(Document): - pass + + def validate(self): + self.validate_dependencies() + + def validate_dependencies(self): + for task in self.tasks: + task_details = frappe.get_doc("Task", task.task) + if task_details.depends_on: + for dependency_task in task_details.depends_on: + if not self.check_dependent_task_presence(dependency_task.task): + task_details_format = """{0}""".format(task_details.name) + dependency_task_format = """{0}""".format(dependency_task.task) + frappe.throw(_("Task {0} depends on Task {1}. Please add Task {1} to the Tasks list.").format(frappe.bold(task_details_format), frappe.bold(dependency_task_format))) + + def check_dependent_task_presence(self, task): + for task_details in self.tasks: + if task_details.task == task: + return True + return False diff --git a/erpnext/projects/doctype/task/task.py b/erpnext/projects/doctype/task/task.py index fb84094ffe6..072a848f263 100755 --- a/erpnext/projects/doctype/task/task.py +++ b/erpnext/projects/doctype/task/task.py @@ -17,291 +17,310 @@ class CircularReferenceError(frappe.ValidationError): pass class EndDateCannotBeGreaterThanProjectEndDateError(frappe.ValidationError): pass class Task(NestedSet): - nsm_parent_field = 'parent_task' + nsm_parent_field = 'parent_task' - def get_feed(self): - return '{0}: {1}'.format(_(self.status), self.subject) + def get_feed(self): + return '{0}: {1}'.format(_(self.status), self.subject) - def get_customer_details(self): - cust = frappe.db.sql("select customer_name from `tabCustomer` where name=%s", self.customer) - if cust: - ret = {'customer_name': cust and cust[0][0] or ''} - return ret + def get_customer_details(self): + cust = frappe.db.sql("select customer_name from `tabCustomer` where name=%s", self.customer) + if cust: + ret = {'customer_name': cust and cust[0][0] or ''} + return ret - def validate(self): - self.validate_dates() - self.validate_parent_project_dates() - self.validate_progress() - self.validate_status() - self.update_depends_on() + def validate(self): + self.validate_dates() + self.validate_parent_project_dates() + self.validate_progress() + self.validate_status() + self.update_depends_on() + self.validate_dependencies_for_template_task() - def validate_dates(self): - if self.exp_start_date and self.exp_end_date and getdate(self.exp_start_date) > getdate(self.exp_end_date): - frappe.throw(_("{0} can not be greater than {1}").format(frappe.bold("Expected Start Date"), \ - frappe.bold("Expected End Date"))) + def validate_dates(self): + if self.exp_start_date and self.exp_end_date and getdate(self.exp_start_date) > getdate(self.exp_end_date): + frappe.throw(_("{0} can not be greater than {1}").format(frappe.bold("Expected Start Date"), \ + frappe.bold("Expected End Date"))) - if self.act_start_date and self.act_end_date and getdate(self.act_start_date) > getdate(self.act_end_date): - frappe.throw(_("{0} can not be greater than {1}").format(frappe.bold("Actual Start Date"), \ - frappe.bold("Actual End Date"))) + if self.act_start_date and self.act_end_date and getdate(self.act_start_date) > getdate(self.act_end_date): + frappe.throw(_("{0} can not be greater than {1}").format(frappe.bold("Actual Start Date"), \ + frappe.bold("Actual End Date"))) - def validate_parent_project_dates(self): - if not self.project or frappe.flags.in_test: - return + def validate_parent_project_dates(self): + if not self.project or frappe.flags.in_test: + return - expected_end_date = frappe.db.get_value("Project", self.project, "expected_end_date") + expected_end_date = frappe.db.get_value("Project", self.project, "expected_end_date") - if expected_end_date: - validate_project_dates(getdate(expected_end_date), self, "exp_start_date", "exp_end_date", "Expected") - validate_project_dates(getdate(expected_end_date), self, "act_start_date", "act_end_date", "Actual") + if expected_end_date: + validate_project_dates(getdate(expected_end_date), self, "exp_start_date", "exp_end_date", "Expected") + validate_project_dates(getdate(expected_end_date), self, "act_start_date", "act_end_date", "Actual") - def validate_status(self): - if self.status!=self.get_db_value("status") and self.status == "Completed": - for d in self.depends_on: - if frappe.db.get_value("Task", d.task, "status") not in ("Completed", "Cancelled"): - frappe.throw(_("Cannot complete task {0} as its dependant task {1} are not ccompleted / cancelled.").format(frappe.bold(self.name), frappe.bold(d.task))) + def validate_status(self): + if self.status!=self.get_db_value("status") and self.status == "Completed": + for d in self.depends_on: + if frappe.db.get_value("Task", d.task, "status") not in ("Completed", "Cancelled"): + frappe.throw(_("Cannot complete task {0} as its dependant task {1} are not ccompleted / cancelled.").format(frappe.bold(self.name), frappe.bold(d.task))) - close_all_assignments(self.doctype, self.name) + close_all_assignments(self.doctype, self.name) - def validate_progress(self): - if flt(self.progress or 0) > 100: - frappe.throw(_("Progress % for a task cannot be more than 100.")) + def validate_progress(self): + if flt(self.progress or 0) > 100: + frappe.throw(_("Progress % for a task cannot be more than 100.")) - if flt(self.progress) == 100: - self.status = 'Completed' + if flt(self.progress) == 100: + self.status = 'Completed' - if self.status == 'Completed': - self.progress = 100 + if self.status == 'Completed': + self.progress = 100 - def update_depends_on(self): - depends_on_tasks = self.depends_on_tasks or "" - for d in self.depends_on: - if d.task and not d.task in depends_on_tasks: - depends_on_tasks += d.task + "," - self.depends_on_tasks = depends_on_tasks + def validate_dependencies_for_template_task(self): + if self.is_template: + self.validate_parent_template_task() + self.validate_depends_on_tasks() + + def validate_parent_template_task(self): + if self.parent_task: + if not frappe.db.get_value("Task", self.parent_task, "is_template"): + parent_task_format = """{0}""".format(self.parent_task) + frappe.throw(_("Parent Task {0} is not a Template Task").format(parent_task_format)) + + def validate_depends_on_tasks(self): + if self.depends_on: + for task in self.depends_on: + if not frappe.db.get_value("Task", task.task, "is_template"): + dependent_task_format = """{0}""".format(task.task) + frappe.throw(_("Dependent Task {0} is not a Template Task").format(dependent_task_format)) - def update_nsm_model(self): - frappe.utils.nestedset.update_nsm(self) + def update_depends_on(self): + depends_on_tasks = self.depends_on_tasks or "" + for d in self.depends_on: + if d.task and not d.task in depends_on_tasks: + depends_on_tasks += d.task + "," + self.depends_on_tasks = depends_on_tasks - def on_update(self): - self.update_nsm_model() - self.check_recursion() - self.reschedule_dependent_tasks() - self.update_project() - self.unassign_todo() - self.populate_depends_on() + def update_nsm_model(self): + frappe.utils.nestedset.update_nsm(self) - def unassign_todo(self): - if self.status == "Completed": - close_all_assignments(self.doctype, self.name) - if self.status == "Cancelled": - clear(self.doctype, self.name) + def on_update(self): + self.update_nsm_model() + self.check_recursion() + self.reschedule_dependent_tasks() + self.update_project() + self.unassign_todo() + self.populate_depends_on() - def update_total_expense_claim(self): - self.total_expense_claim = frappe.db.sql("""select sum(total_sanctioned_amount) from `tabExpense Claim` - where project = %s and task = %s and docstatus=1""",(self.project, self.name))[0][0] + def unassign_todo(self): + if self.status == "Completed": + close_all_assignments(self.doctype, self.name) + if self.status == "Cancelled": + clear(self.doctype, self.name) - def update_time_and_costing(self): - tl = frappe.db.sql("""select min(from_time) as start_date, max(to_time) as end_date, - sum(billing_amount) as total_billing_amount, sum(costing_amount) as total_costing_amount, - sum(hours) as time from `tabTimesheet Detail` where task = %s and docstatus=1""" - ,self.name, as_dict=1)[0] - if self.status == "Open": - self.status = "Working" - self.total_costing_amount= tl.total_costing_amount - self.total_billing_amount= tl.total_billing_amount - self.actual_time= tl.time - self.act_start_date= tl.start_date - self.act_end_date= tl.end_date + def update_total_expense_claim(self): + self.total_expense_claim = frappe.db.sql("""select sum(total_sanctioned_amount) from `tabExpense Claim` + where project = %s and task = %s and docstatus=1""",(self.project, self.name))[0][0] - def update_project(self): - if self.project and not self.flags.from_project: - frappe.get_cached_doc("Project", self.project).update_project() + def update_time_and_costing(self): + tl = frappe.db.sql("""select min(from_time) as start_date, max(to_time) as end_date, + sum(billing_amount) as total_billing_amount, sum(costing_amount) as total_costing_amount, + sum(hours) as time from `tabTimesheet Detail` where task = %s and docstatus=1""" + ,self.name, as_dict=1)[0] + if self.status == "Open": + self.status = "Working" + self.total_costing_amount= tl.total_costing_amount + self.total_billing_amount= tl.total_billing_amount + self.actual_time= tl.time + self.act_start_date= tl.start_date + self.act_end_date= tl.end_date - def check_recursion(self): - if self.flags.ignore_recursion_check: return - check_list = [['task', 'parent'], ['parent', 'task']] - for d in check_list: - task_list, count = [self.name], 0 - while (len(task_list) > count ): - tasks = frappe.db.sql(" select %s from `tabTask Depends On` where %s = %s " % - (d[0], d[1], '%s'), cstr(task_list[count])) - count = count + 1 - for b in tasks: - if b[0] == self.name: - frappe.throw(_("Circular Reference Error"), CircularReferenceError) - if b[0]: - task_list.append(b[0]) + def update_project(self): + if self.project and not self.flags.from_project: + frappe.get_cached_doc("Project", self.project).update_project() - if count == 15: - break + def check_recursion(self): + if self.flags.ignore_recursion_check: return + check_list = [['task', 'parent'], ['parent', 'task']] + for d in check_list: + task_list, count = [self.name], 0 + while (len(task_list) > count ): + tasks = frappe.db.sql(" select %s from `tabTask Depends On` where %s = %s " % + (d[0], d[1], '%s'), cstr(task_list[count])) + count = count + 1 + for b in tasks: + if b[0] == self.name: + frappe.throw(_("Circular Reference Error"), CircularReferenceError) + if b[0]: + task_list.append(b[0]) - def reschedule_dependent_tasks(self): - end_date = self.exp_end_date or self.act_end_date - if end_date: - for task_name in frappe.db.sql(""" - select name from `tabTask` as parent - where parent.project = %(project)s - and parent.name in ( - select parent from `tabTask Depends On` as child - where child.task = %(task)s and child.project = %(project)s) - """, {'project': self.project, 'task':self.name }, as_dict=1): - task = frappe.get_doc("Task", task_name.name) - if task.exp_start_date and task.exp_end_date and task.exp_start_date < getdate(end_date) and task.status == "Open": - task_duration = date_diff(task.exp_end_date, task.exp_start_date) - task.exp_start_date = add_days(end_date, 1) - task.exp_end_date = add_days(task.exp_start_date, task_duration) - task.flags.ignore_recursion_check = True - task.save() + if count == 15: + break - def has_webform_permission(self): - project_user = frappe.db.get_value("Project User", {"parent": self.project, "user":frappe.session.user} , "user") - if project_user: - return True + def reschedule_dependent_tasks(self): + end_date = self.exp_end_date or self.act_end_date + if end_date: + for task_name in frappe.db.sql(""" + select name from `tabTask` as parent + where parent.project = %(project)s + and parent.name in ( + select parent from `tabTask Depends On` as child + where child.task = %(task)s and child.project = %(project)s) + """, {'project': self.project, 'task':self.name }, as_dict=1): + task = frappe.get_doc("Task", task_name.name) + if task.exp_start_date and task.exp_end_date and task.exp_start_date < getdate(end_date) and task.status == "Open": + task_duration = date_diff(task.exp_end_date, task.exp_start_date) + task.exp_start_date = add_days(end_date, 1) + task.exp_end_date = add_days(task.exp_start_date, task_duration) + task.flags.ignore_recursion_check = True + task.save() - def populate_depends_on(self): - if self.parent_task: - parent = frappe.get_doc('Task', self.parent_task) - if not self.name in [row.task for row in parent.depends_on]: - parent.append("depends_on", { - "doctype": "Task Depends On", - "task": self.name, - "subject": self.subject - }) - parent.save() + def has_webform_permission(self): + project_user = frappe.db.get_value("Project User", {"parent": self.project, "user":frappe.session.user} , "user") + if project_user: + return True - def on_trash(self): - if check_if_child_exists(self.name): - throw(_("Child Task exists for this Task. You can not delete this Task.")) + def populate_depends_on(self): + if self.parent_task: + parent = frappe.get_doc('Task', self.parent_task) + if not self.name in [row.task for row in parent.depends_on]: + parent.append("depends_on", { + "doctype": "Task Depends On", + "task": self.name, + "subject": self.subject + }) + parent.save() - self.update_nsm_model() + def on_trash(self): + if check_if_child_exists(self.name): + throw(_("Child Task exists for this Task. You can not delete this Task.")) - def after_delete(self): - self.update_project() + self.update_nsm_model() - def update_status(self): - if self.status not in ('Cancelled', 'Completed') and self.exp_end_date: - from datetime import datetime - if self.exp_end_date < datetime.now().date(): - self.db_set('status', 'Overdue', update_modified=False) - self.update_project() + def after_delete(self): + self.update_project() + + def update_status(self): + if self.status not in ('Cancelled', 'Completed') and self.exp_end_date: + from datetime import datetime + if self.exp_end_date < datetime.now().date(): + self.db_set('status', 'Overdue', update_modified=False) + self.update_project() @frappe.whitelist() def check_if_child_exists(name): - child_tasks = frappe.get_all("Task", filters={"parent_task": name}) - child_tasks = [get_link_to_form("Task", task.name) for task in child_tasks] - return child_tasks + child_tasks = frappe.get_all("Task", filters={"parent_task": name}) + child_tasks = [get_link_to_form("Task", task.name) for task in child_tasks] + return child_tasks @frappe.whitelist() @frappe.validate_and_sanitize_search_inputs def get_project(doctype, txt, searchfield, start, page_len, filters): - from erpnext.controllers.queries import get_match_cond - return frappe.db.sql(""" select name from `tabProject` - where %(key)s like %(txt)s - %(mcond)s - order by name - limit %(start)s, %(page_len)s""" % { - 'key': searchfield, - 'txt': frappe.db.escape('%' + txt + '%'), - 'mcond':get_match_cond(doctype), - 'start': start, - 'page_len': page_len - }) + from erpnext.controllers.queries import get_match_cond + return frappe.db.sql(""" select name from `tabProject` + where %(key)s like %(txt)s + %(mcond)s + order by name + limit %(start)s, %(page_len)s""" % { + 'key': searchfield, + 'txt': frappe.db.escape('%' + txt + '%'), + 'mcond':get_match_cond(doctype), + 'start': start, + 'page_len': page_len + }) @frappe.whitelist() def set_multiple_status(names, status): - names = json.loads(names) - for name in names: - task = frappe.get_doc("Task", name) - task.status = status - task.save() + names = json.loads(names) + for name in names: + task = frappe.get_doc("Task", name) + task.status = status + task.save() def set_tasks_as_overdue(): - tasks = frappe.get_all("Task", filters={"status": ["not in", ["Cancelled", "Completed"]]}, fields=["name", "status", "review_date"]) - for task in tasks: - if task.status == "Pending Review": - if getdate(task.review_date) > getdate(today()): - continue - frappe.get_doc("Task", task.name).update_status() + tasks = frappe.get_all("Task", filters={"status": ["not in", ["Cancelled", "Completed"]]}, fields=["name", "status", "review_date"]) + for task in tasks: + if task.status == "Pending Review": + if getdate(task.review_date) > getdate(today()): + continue + frappe.get_doc("Task", task.name).update_status() @frappe.whitelist() def make_timesheet(source_name, target_doc=None, ignore_permissions=False): - def set_missing_values(source, target): - target.append("time_logs", { - "hours": source.actual_time, - "completed": source.status == "Completed", - "project": source.project, - "task": source.name - }) + def set_missing_values(source, target): + target.append("time_logs", { + "hours": source.actual_time, + "completed": source.status == "Completed", + "project": source.project, + "task": source.name + }) - doclist = get_mapped_doc("Task", source_name, { - "Task": { - "doctype": "Timesheet" - } - }, target_doc, postprocess=set_missing_values, ignore_permissions=ignore_permissions) + doclist = get_mapped_doc("Task", source_name, { + "Task": { + "doctype": "Timesheet" + } + }, target_doc, postprocess=set_missing_values, ignore_permissions=ignore_permissions) - return doclist + return doclist @frappe.whitelist() def get_children(doctype, parent, task=None, project=None, is_root=False): - filters = [['docstatus', '<', '2']] + filters = [['docstatus', '<', '2']] - if task: - filters.append(['parent_task', '=', task]) - elif parent and not is_root: - # via expand child - filters.append(['parent_task', '=', parent]) - else: - filters.append(['ifnull(`parent_task`, "")', '=', '']) + if task: + filters.append(['parent_task', '=', task]) + elif parent and not is_root: + # via expand child + filters.append(['parent_task', '=', parent]) + else: + filters.append(['ifnull(`parent_task`, "")', '=', '']) - if project: - filters.append(['project', '=', project]) + if project: + filters.append(['project', '=', project]) - tasks = frappe.get_list(doctype, fields=[ - 'name as value', - 'subject as title', - 'is_group as expandable' - ], filters=filters, order_by='name') + tasks = frappe.get_list(doctype, fields=[ + 'name as value', + 'subject as title', + 'is_group as expandable' + ], filters=filters, order_by='name') - # return tasks - return tasks + # return tasks + return tasks @frappe.whitelist() def add_node(): - from frappe.desk.treeview import make_tree_args - args = frappe.form_dict - args.update({ - "name_field": "subject" - }) - args = make_tree_args(**args) + from frappe.desk.treeview import make_tree_args + args = frappe.form_dict + args.update({ + "name_field": "subject" + }) + args = make_tree_args(**args) - if args.parent_task == 'All Tasks' or args.parent_task == args.project: - args.parent_task = None + if args.parent_task == 'All Tasks' or args.parent_task == args.project: + args.parent_task = None - frappe.get_doc(args).insert() + frappe.get_doc(args).insert() @frappe.whitelist() def add_multiple_tasks(data, parent): - data = json.loads(data) - new_doc = {'doctype': 'Task', 'parent_task': parent if parent!="All Tasks" else ""} - new_doc['project'] = frappe.db.get_value('Task', {"name": parent}, 'project') or "" + data = json.loads(data) + new_doc = {'doctype': 'Task', 'parent_task': parent if parent!="All Tasks" else ""} + new_doc['project'] = frappe.db.get_value('Task', {"name": parent}, 'project') or "" - for d in data: - if not d.get("subject"): continue - new_doc['subject'] = d.get("subject") - new_task = frappe.get_doc(new_doc) - new_task.insert() + for d in data: + if not d.get("subject"): continue + new_doc['subject'] = d.get("subject") + new_task = frappe.get_doc(new_doc) + new_task.insert() def on_doctype_update(): - frappe.db.add_index("Task", ["lft", "rgt"]) + frappe.db.add_index("Task", ["lft", "rgt"]) def validate_project_dates(project_end_date, task, task_start, task_end, actual_or_expected_date): - if task.get(task_start) and date_diff(project_end_date, getdate(task.get(task_start))) < 0: - frappe.throw(_("Task's {0} Start Date cannot be after Project's End Date.").format(actual_or_expected_date)) + if task.get(task_start) and date_diff(project_end_date, getdate(task.get(task_start))) < 0: + frappe.throw(_("Task's {0} Start Date cannot be after Project's End Date.").format(actual_or_expected_date)) - if task.get(task_end) and date_diff(project_end_date, getdate(task.get(task_end))) < 0: - frappe.throw(_("Task's {0} End Date cannot be after Project's End Date.").format(actual_or_expected_date)) + if task.get(task_end) and date_diff(project_end_date, getdate(task.get(task_end))) < 0: + frappe.throw(_("Task's {0} End Date cannot be after Project's End Date.").format(actual_or_expected_date)) From 46f3c65b003442ecfcdbcdc1d13422f872ea88bf Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Mon, 14 Dec 2020 23:09:19 +0530 Subject: [PATCH 171/477] feat: Multi currency in landed cost voucher --- .../landed_cost_taxes_and_charges.json | 32 +++++++++- .../landed_cost_voucher.js | 58 +++++++++++++++++-- .../landed_cost_voucher.json | 26 ++++++++- .../landed_cost_voucher.py | 31 ++++++---- 4 files changed, 129 insertions(+), 18 deletions(-) diff --git a/erpnext/stock/doctype/landed_cost_taxes_and_charges/landed_cost_taxes_and_charges.json b/erpnext/stock/doctype/landed_cost_taxes_and_charges/landed_cost_taxes_and_charges.json index 0cc243d4cb5..ae8747fc830 100644 --- a/erpnext/stock/doctype/landed_cost_taxes_and_charges/landed_cost_taxes_and_charges.json +++ b/erpnext/stock/doctype/landed_cost_taxes_and_charges/landed_cost_taxes_and_charges.json @@ -1,12 +1,16 @@ { + "actions": [], "creation": "2014-07-11 11:51:00.453717", "doctype": "DocType", "editable_grid": 1, "engine": "InnoDB", "field_order": [ "expense_account", + "account_currency", + "exchange_rate", "description", "col_break3", + "base_amount", "amount" ], "fields": [ @@ -27,7 +31,7 @@ "fieldtype": "Currency", "in_list_view": 1, "label": "Amount", - "options": "Company:company:default_currency", + "options": "account_currency", "reqd": 1 }, { @@ -37,10 +41,34 @@ "label": "Expense Account", "options": "Account", "reqd": 1 + }, + { + "fieldname": "account_currency", + "fieldtype": "Link", + "label": "Account Currency", + "options": "Currency", + "read_only": 1, + "reqd": 1 + }, + { + "fieldname": "exchange_rate", + "fieldtype": "Float", + "label": "Exchange Rate", + "precision": "9" + }, + { + "fieldname": "base_amount", + "fieldtype": "Currency", + "label": "Base Amount", + "options": "Company:company:default_currency", + "read_only": 1, + "reqd": 1 } ], + "index_web_pages_for_search": 1, "istable": 1, - "modified": "2019-09-30 18:28:32.070655", + "links": [], + "modified": "2020-12-13 21:04:01.769989", "modified_by": "Administrator", "module": "Stock", "name": "Landed Cost Taxes and Charges", diff --git a/erpnext/stock/doctype/landed_cost_voucher/landed_cost_voucher.js b/erpnext/stock/doctype/landed_cost_voucher/landed_cost_voucher.js index 5de13525183..a5ac60c4f51 100644 --- a/erpnext/stock/doctype/landed_cost_voucher/landed_cost_voucher.js +++ b/erpnext/stock/doctype/landed_cost_voucher/landed_cost_voucher.js @@ -32,9 +32,8 @@ erpnext.stock.LandedCostVoucher = erpnext.stock.StockController.extend({ this.frm.set_query("expense_account", "taxes", function() { return { - query: "erpnext.controllers.queries.tax_account_query", filters: { - "account_type": ["Tax", "Chargeable", "Income Account", "Expenses Included In Valuation", "Expenses Included In Asset Valuation"], + "account_type": ['in', ["Tax", "Chargeable", "Income Account", "Expenses Included In Valuation", "Expenses Included In Asset Valuation"]], "company": me.frm.doc.company } }; @@ -97,7 +96,7 @@ erpnext.stock.LandedCostVoucher = erpnext.stock.StockController.extend({ set_total_taxes_and_charges: function() { var total_taxes_and_charges = 0.0; $.each(this.frm.doc.taxes || [], function(i, d) { - total_taxes_and_charges += flt(d.amount) + total_taxes_and_charges += flt(d.base_amount) }); cur_frm.set_value("total_taxes_and_charges", total_taxes_and_charges); }, @@ -134,7 +133,58 @@ erpnext.stock.LandedCostVoucher = erpnext.stock.StockController.extend({ items_remove: () => { this.trigger('set_applicable_charges_for_item'); } - }); cur_frm.script_manager.make(erpnext.stock.LandedCostVoucher); + +frappe.ui.form.on('Landed Cost Voucher', { + set_account_currency: function(frm, cdt, cdn) { + let row = locals[cdt][cdn]; + if (row.expense_account) { + frappe.db.get_value('Account', row.expense_account, 'account_currency', function(value) { + frappe.model.set_value(cdt, cdn, "account_currency", value.account_currency); + frm.events.set_exchange_rate(frm, cdt, cdn); + }); + } + }, + + set_exchange_rate: function(frm, cdt, cdn) { + let row = locals[cdt][cdn]; + let company_currency = frappe.get_doc(":Company", frm.doc.company).default_currency; + + if(row.account_currency == company_currency) { + row.exchange_rate = 1; + } else if (!row.exchange_rate || row.exchange_rate == 1) { + frappe.call({ + method: "erpnext.accounts.doctype.journal_entry.journal_entry.get_exchange_rate", + args: { + posting_date: frm.doc.posting_date, + account: row.expense_account, + account_currency: row.account_currency, + company: frm.doc.company + }, + callback: function(r) { + if(r.message) { + frappe.model.set_value(cdt, cdn, "exchange_rate", r.message); + } + } + }) + } + }, + + set_base_amount: function(frm, cdt, cdn) { + let row = locals[cdt][cdn]; + frappe.model.set_value(cdt, cdn, "base_amount", + flt(flt(row.amount)*row.exchange_rate, precision("base_amount", row))); + } +}) + +frappe.ui.form.on('Landed Cost Taxes and Charges', { + expense_account: function(frm, cdt, cdn) { + frm.events.set_account_currency(frm, cdt, cdn); + }, + + amount: function(frm, cdt, cdn) { + frm.events.set_base_amount(frm, cdt, cdn); + } +}); diff --git a/erpnext/stock/doctype/landed_cost_voucher/landed_cost_voucher.json b/erpnext/stock/doctype/landed_cost_voucher/landed_cost_voucher.json index 01492807def..6a7994ba9e5 100644 --- a/erpnext/stock/doctype/landed_cost_voucher/landed_cost_voucher.json +++ b/erpnext/stock/doctype/landed_cost_voucher/landed_cost_voucher.json @@ -1,4 +1,5 @@ { + "actions": [], "autoname": "naming_series:", "creation": "2014-07-11 11:33:42.547339", "doctype": "DocType", @@ -7,6 +8,9 @@ "field_order": [ "naming_series", "company", + "column_break_2", + "posting_date", + "section_break_5", "purchase_receipts", "purchase_receipt_items", "get_items_from_purchase_receipts", @@ -86,7 +90,7 @@ { "fieldname": "total_taxes_and_charges", "fieldtype": "Currency", - "label": "Total Taxes and Charges", + "label": "Total Taxes and Charges (Company Currency)", "options": "Company:company:default_currency", "read_only": 1, "reqd": 1 @@ -119,11 +123,29 @@ "fieldname": "landed_cost_help", "fieldtype": "HTML", "label": "Landed Cost Help" + }, + { + "fieldname": "column_break_2", + "fieldtype": "Column Break" + }, + { + "default": "Today", + "fieldname": "posting_date", + "fieldtype": "Date", + "label": "Posting Date", + "reqd": 1 + }, + { + "fieldname": "section_break_5", + "fieldtype": "Section Break", + "hide_border": 1 } ], "icon": "icon-usd", + "index_web_pages_for_search": 1, "is_submittable": 1, - "modified": "2019-11-21 15:34:10.846093", + "links": [], + "modified": "2020-12-13 23:18:47.442466", "modified_by": "Administrator", "module": "Stock", "name": "Landed Cost Voucher", diff --git a/erpnext/stock/doctype/landed_cost_voucher/landed_cost_voucher.py b/erpnext/stock/doctype/landed_cost_voucher/landed_cost_voucher.py index bc3d3266add..e39208991bd 100644 --- a/erpnext/stock/doctype/landed_cost_voucher/landed_cost_voucher.py +++ b/erpnext/stock/doctype/landed_cost_voucher/landed_cost_voucher.py @@ -9,6 +9,7 @@ from frappe.model.meta import get_field_precision from frappe.model.document import Document from erpnext.stock.doctype.serial_no.serial_no import get_serial_nos from erpnext.accounts.doctype.account.account import get_account_currency +from erpnext.accounts.doctype.journal_entry.journal_entry import get_exchange_rate class LandedCostVoucher(Document): def get_items_from_purchase_receipts(self): @@ -39,12 +40,13 @@ class LandedCostVoucher(Document): def validate(self): self.check_mandatory() + self.set_exchange_rate() + self.set_amounts_in_company_currency() if not self.get("items"): self.get_items_from_purchase_receipts() else: self.validate_applicable_charges_for_item() self.validate_purchase_receipts() - self.validate_expense_accounts() self.set_total_taxes_and_charges() def check_mandatory(self): @@ -73,16 +75,25 @@ class LandedCostVoucher(Document): frappe.throw(_("Row {0}: Cost center is required for an item {1}") .format(item.idx, item.item_code)) - def validate_expense_accounts(self): - company_currency = erpnext.get_company_currency(self.company) - for account in self.taxes: - if get_account_currency(account.expense_account) != company_currency: - frappe.throw(msg=_(""" Row {0}: Expense account currency should be same as company's default currency. - Please select expense account with account currency as {1}""") - .format(account.idx, frappe.bold(company_currency)), title=_("Invalid Account Currency")) - def set_total_taxes_and_charges(self): - self.total_taxes_and_charges = sum([flt(d.amount) for d in self.get("taxes")]) + self.total_taxes_and_charges = sum([flt(d.base_amount) for d in self.get("taxes")]) + + def set_exchange_rate(self): + company_currency = erpnext.get_company_currency(self.company) + for d in self.get('taxes'): + if d.account_currency == company_currency: + d.exchange_rate = 1 + elif not d.exchange_rate or d.exchange_rate == 1 or self.posting_date: + d.exchange_rate = get_exchange_rate(self.posting_date, account=d.expense_account, + account_currency=d.account_currency, company=self.company) + + if not d.exchange_rate: + frappe.throw(_("Row {0}: Exchange Rate is mandatory").format(d.idx)) + + def set_amounts_in_company_currency(self): + for d in self.get('taxes'): + d.amount = flt(d.amount, d.precision("amount")) + d.base_amount = flt(d.amount * flt(d.exchange_rate), d.precision("base_amount")) def validate_applicable_charges_for_item(self): based_on = self.distribute_charges_based_on.lower() From 23f0debf8807eeac894cfb5d628fddb80bf0fd72 Mon Sep 17 00:00:00 2001 From: pateljannat Date: Tue, 15 Dec 2020 10:00:21 +0530 Subject: [PATCH 172/477] fix: tests --- erpnext/projects/doctype/project/test_project.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/erpnext/projects/doctype/project/test_project.py b/erpnext/projects/doctype/project/test_project.py index f9bb1b3ac4d..ea54774d52d 100644 --- a/erpnext/projects/doctype/project/test_project.py +++ b/erpnext/projects/doctype/project/test_project.py @@ -79,16 +79,16 @@ class TestProject(unittest.TestCase): if not task2: task2 = create_task(subject="Test Temp Task with dependency", depends_on=task1.name, is_template=1, begin=2, duration=2) - template = make_project_template("Test Project with Templ - dependent tasks", [task2]) - project = get_project("Test Project with Templ - tasks with parent-child", template) + template = make_project_template("Test Project with Templ - dependent tasks", [task1, task2]) + project = get_project("Test Project with Templ - dependent tasks", template) tasks = frappe.get_all('Task', '*', dict(project=project.name), order_by='creation asc') - self.assertEqual(tasks[0].subject, 'Test Temp Task with dependency') - self.assertEqual(getdate(tasks[0].exp_end_date), calculate_end_date(project, tasks[0])) - self.assertEqual(tasks[0].depends_on, tasks[1].name) + self.assertEqual(tasks[1].subject, 'Test Temp Task with dependency') + self.assertEqual(getdate(tasks[1].exp_end_date), calculate_end_date(project, tasks[1])) + self.assertTrue(tasks[1].depends_on_tasks.find(tasks[0].name) >= 0 ) - self.assertEqual(tasks[1].subject, 'Test Temp Task for dependency') - self.assertEqual(getdate(tasks[1].exp_end_date), calculate_end_date(project, tasks[1]) ) + self.assertEqual(tasks[0].subject, 'Test Temp Task for dependency') + self.assertEqual(getdate(tasks[0].exp_end_date), calculate_end_date(project, tasks[0]) ) self.assertEqual(len(tasks), 2) From caf67e608f871adca275e001dddc96c96af4ea77 Mon Sep 17 00:00:00 2001 From: pateljannat Date: Tue, 15 Dec 2020 10:00:31 +0530 Subject: [PATCH 173/477] fix: tests --- erpnext/projects/doctype/project/project.py | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/erpnext/projects/doctype/project/project.py b/erpnext/projects/doctype/project/project.py index 2d3339773a1..5a9375a0e6c 100644 --- a/erpnext/projects/doctype/project/project.py +++ b/erpnext/projects/doctype/project/project.py @@ -82,31 +82,29 @@ class Project(Document): def dependency_mapping(self, template_tasks, project_tasks): for tmp_task in template_tasks: - for prj_task in project_tasks: - if tmp_task.subject == prj_task.subject: - self.check_depends_on_value(tmp_task, prj_task, project_tasks) - self.check_for_parent_tasks(tmp_task, prj_task, project_tasks) + prj_task = list(filter(lambda x: x.subject == tmp_task.subject, project_tasks))[0] + self.check_depends_on_value(tmp_task, prj_task, project_tasks) + self.check_for_parent_tasks(tmp_task, prj_task, project_tasks) def check_depends_on_value(self, tmp_task, prj_task, project_tasks): - if tmp_task.depends_on and not prj_task.depends_on: - for child_task in tmp_task.depends_on: + if tmp_task.get("depends_on") and not prj_task.get("depends_on"): + for child_task in tmp_task.get("depends_on"): child_task_subject = frappe.db.get_value("Task", child_task.task, "subject") corresponding_prj_task = list(filter(lambda x: x.subject == child_task_subject, project_tasks)) if len(corresponding_prj_task): prj_task.append("depends_on",{ "task": corresponding_prj_task[0].name }) + print(prj_task.name) prj_task.save() def check_for_parent_tasks(self, tmp_task, prj_task, project_tasks): - if tmp_task.parent_task and not prj_task.parent_task: - parent_task_subject = frappe.db.get_value("Task", tmp_task.parent_task, "subject") + if tmp_task.get("parent_task") and not prj_task.get("parent_task"): + parent_task_subject = frappe.db.get_value("Task", tmp_task.get("parent_task"), "subject") corresponding_prj_task = list(filter(lambda x: x.subject == parent_task_subject, project_tasks)) if len(corresponding_prj_task): prj_task.parent_task = corresponding_prj_task[0].name - print(prj_task.name, prj_task.parent_task, corresponding_prj_task[0].name) prj_task.save() - print(prj_task.name, corresponding_prj_task[0].name) def is_row_updated(self, row, existing_task_data, fields): if self.get("__islocal") or not existing_task_data: return True From a6fef7ae6bbdba8a4f922ebdfbf337033c41ac4d Mon Sep 17 00:00:00 2001 From: pateljannat Date: Tue, 15 Dec 2020 11:50:18 +0530 Subject: [PATCH 174/477] feat: parent-child relation tasks --- erpnext/projects/doctype/project/project.py | 2 +- erpnext/projects/doctype/project/test_project.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/erpnext/projects/doctype/project/project.py b/erpnext/projects/doctype/project/project.py index 5a9375a0e6c..13e72fec8a2 100644 --- a/erpnext/projects/doctype/project/project.py +++ b/erpnext/projects/doctype/project/project.py @@ -83,6 +83,7 @@ class Project(Document): def dependency_mapping(self, template_tasks, project_tasks): for tmp_task in template_tasks: prj_task = list(filter(lambda x: x.subject == tmp_task.subject, project_tasks))[0] + prj_task = frappe.get_doc("Task", prj_task.name) self.check_depends_on_value(tmp_task, prj_task, project_tasks) self.check_for_parent_tasks(tmp_task, prj_task, project_tasks) @@ -95,7 +96,6 @@ class Project(Document): prj_task.append("depends_on",{ "task": corresponding_prj_task[0].name }) - print(prj_task.name) prj_task.save() def check_for_parent_tasks(self, tmp_task, prj_task, project_tasks): diff --git a/erpnext/projects/doctype/project/test_project.py b/erpnext/projects/doctype/project/test_project.py index ea54774d52d..c3f56b8e860 100644 --- a/erpnext/projects/doctype/project/test_project.py +++ b/erpnext/projects/doctype/project/test_project.py @@ -49,10 +49,10 @@ class TestProject(unittest.TestCase): if not task3: task3 = create_task(subject="Test Temp Task child 2", parent_task=task1.name, is_template=1, begin=2, duration=3) - template = make_project_template("Test Project Template - tasks with parent-child", [task1]) + template = make_project_template("Test Project Template - tasks with parent-child", [task1, task2, task3]) project = get_project("Test Project with Templ - tasks with parent-child", template) tasks = frappe.get_all('Task', '*', dict(project=project.name), order_by='creation asc') - print(tasks[0].duration) + self.assertEqual(tasks[0].subject, 'Test Temp Task parent') self.assertEqual(getdate(tasks[0].exp_end_date), calculate_end_date(project, tasks[0])) From d050816e17af897fedf40fb8bee5c1e0a0d05dcb Mon Sep 17 00:00:00 2001 From: Saqib Ansari Date: Tue, 15 Dec 2020 12:02:26 +0530 Subject: [PATCH 175/477] fix: overflow of customer selector --- erpnext/public/scss/point-of-sale.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/public/scss/point-of-sale.scss b/erpnext/public/scss/point-of-sale.scss index 3e7d5dae828..c6270176ee5 100644 --- a/erpnext/public/scss/point-of-sale.scss +++ b/erpnext/public/scss/point-of-sale.scss @@ -185,7 +185,7 @@ display: flex; flex-direction: column; padding: var(--padding-md) var(--padding-lg); - overflow: hidden; + overflow: visible; > .customer-field { display: flex; From 34fc52850095625d5e173d7f166863454fca79ac Mon Sep 17 00:00:00 2001 From: Rushabh Mehta Date: Wed, 16 Dec 2020 09:43:57 +0530 Subject: [PATCH 176/477] fix(minor): debounce taxes call --- erpnext/regional/india/taxes.js | 1 + erpnext/templates/includes/footer/footer_extension.html | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/erpnext/regional/india/taxes.js b/erpnext/regional/india/taxes.js index b70b2ec48cc..52b130c3549 100644 --- a/erpnext/regional/india/taxes.js +++ b/erpnext/regional/india/taxes.js @@ -34,6 +34,7 @@ erpnext.setup_auto_gst_taxation = (doctype) => { doctype: frm.doc.doctype, company: frm.doc.company }, + debounce: 2000, callback: function(r) { if(r.message) { frm.set_value('taxes_and_charges', r.message.taxes_and_charges); diff --git a/erpnext/templates/includes/footer/footer_extension.html b/erpnext/templates/includes/footer/footer_extension.html index 6171b61e385..c7f0d06dff2 100644 --- a/erpnext/templates/includes/footer/footer_extension.html +++ b/erpnext/templates/includes/footer/footer_extension.html @@ -1,12 +1,12 @@ {% if not hide_footer_signup %}
    -
    -
    From 87b477a31126e478c2bcc77861975e015474bc6a Mon Sep 17 00:00:00 2001 From: pateljannat Date: Wed, 16 Dec 2020 13:37:21 +0530 Subject: [PATCH 177/477] feat: patch for project template tasks --- erpnext/patches.txt | 1 + .../v13_0/update_project_template_tasks.py | 32 +++++++++++++++++++ 2 files changed, 33 insertions(+) create mode 100644 erpnext/patches/v13_0/update_project_template_tasks.py diff --git a/erpnext/patches.txt b/erpnext/patches.txt index 86ac613ae5b..435511210bc 100644 --- a/erpnext/patches.txt +++ b/erpnext/patches.txt @@ -741,3 +741,4 @@ erpnext.patches.v13_0.updates_for_multi_currency_payroll erpnext.patches.v13_0.create_leave_policy_assignment_based_on_employee_current_leave_policy erpnext.patches.v13_0.add_po_to_global_search erpnext.patches.v13_0.update_returned_qty_in_pr_dn +erpnext.patches.v13_0.update_project_template_tasks diff --git a/erpnext/patches/v13_0/update_project_template_tasks.py b/erpnext/patches/v13_0/update_project_template_tasks.py new file mode 100644 index 00000000000..55f0ff45057 --- /dev/null +++ b/erpnext/patches/v13_0/update_project_template_tasks.py @@ -0,0 +1,32 @@ +# Copyright (c) 2019, Frappe and Contributors +# License: GNU General Public License v3. See license.txt + +from __future__ import unicode_literals +import frappe + +def execute(): + templates = frappe.get_list("Project Template", fields = ["name"]) + for template_name in templates: + template = frappe.get_doc("Project Template", template_name) + replace_tasks = False + new_tasks = [] + for task in template.tasks: + if task.subject: + replace_tasks = True + new_task = frappe.get_doc(dict( + doctype = "Task", + subject = task.subject, + start = task.start, + duration = task.duration, + task_weight = task.task_weight, + description = task.description, + is_template = 1 + )).insert() + new_tasks.append(new_task.name) + if replace_tasks: + template.tasks = [] + for tsk in new_tasks: + template.append("tasks", { + "task": tsk + }) + template.save() \ No newline at end of file From 9962ba86d0db913d53bf87736e1fdd2194436f09 Mon Sep 17 00:00:00 2001 From: "hasnain2808@gmail.com" Date: Wed, 16 Dec 2020 14:41:04 +0530 Subject: [PATCH 178/477] fix: charts not displaying when tree_type changed --- .../purchase_analytics/purchase_analytics.js | 72 +++++++++-------- .../report/sales_analytics/sales_analytics.js | 79 ++++++++++--------- 2 files changed, 81 insertions(+), 70 deletions(-) diff --git a/erpnext/buying/report/purchase_analytics/purchase_analytics.js b/erpnext/buying/report/purchase_analytics/purchase_analytics.js index e17973c337b..7ee9f2c372a 100644 --- a/erpnext/buying/report/purchase_analytics/purchase_analytics.js +++ b/erpnext/buying/report/purchase_analytics/purchase_analytics.js @@ -75,62 +75,66 @@ frappe.query_reports["Purchase Analytics"] = { return Object.assign(options, { checkboxColumn: true, events: { - onCheckRow: function(data) { + onCheckRow: function (data) { + if (!data) return; + + const data_doctype = $( + data[2].html + )[0].attributes.getNamedItem("data-doctype").value; + const tree_type = frappe.query_report.filters[0].value; + if (data_doctype != tree_type) return; + row_name = data[2].content; length = data.length; - var tree_type = frappe.query_report.filters[0].value; - - if(tree_type == "Supplier" || tree_type == "Item") { - row_values = data.slice(4,length-1).map(function (column) { - return column.content; - }) - } - else { - row_values = data.slice(3,length-1).map(function (column) { - return column.content; - }) + if (tree_type == "Supplier" || tree_type == "Item") { + row_values = data + .slice(4, length - 1) + .map(function (column) { + return column.content; + }); + } else { + row_values = data + .slice(3, length - 1) + .map(function (column) { + return column.content; + }); } - entry = { - 'name':row_name, - 'values':row_values - } + entry = { + name: row_name, + values: row_values, + }; let raw_data = frappe.query_report.chart.data; let new_datasets = raw_data.datasets; - var found = false; + let found = false; - for(var i=0; i < new_datasets.length;i++){ - if(new_datasets[i].name == row_name){ + for (let i = 0; i < new_datasets.length; i++) { + if (new_datasets[i].name == row_name) { found = true; - new_datasets.splice(i,1); + new_datasets.splice(i, 1); break; } } - if(!found){ + if (!found) { new_datasets.push(entry); } - let new_data = { labels: raw_data.labels, - datasets: new_datasets - } - - setTimeout(() => { - frappe.query_report.chart.update(new_data) - },500) - - - setTimeout(() => { - frappe.query_report.chart.draw(true); - }, 1000) + datasets: new_datasets, + }; + chart_options = { + data: new_data, + type: "line", + }; + frappe.query_report.render_chart(chart_options); frappe.query_report.raw_chart_data = new_data; }, - } + }, }); } } diff --git a/erpnext/selling/report/sales_analytics/sales_analytics.js b/erpnext/selling/report/sales_analytics/sales_analytics.js index 0e565a3fb6f..aad6bfd5ef1 100644 --- a/erpnext/selling/report/sales_analytics/sales_analytics.js +++ b/erpnext/selling/report/sales_analytics/sales_analytics.js @@ -74,67 +74,74 @@ frappe.query_reports["Sales Analytics"] = { return Object.assign(options, { checkboxColumn: true, events: { - onCheckRow: function(data) { + onCheckRow: function (data) { + if (!data) return; + + const data_doctype = $( + data[2].html + )[0].attributes.getNamedItem("data-doctype").value; + const tree_type = frappe.query_report.filters[0].value; + if (data_doctype != tree_type) return; + row_name = data[2].content; length = data.length; - var tree_type = frappe.query_report.filters[0].value; - - if(tree_type == "Customer") { - row_values = data.slice(4,length-1).map(function (column) { - return column.content; - }) + if (tree_type == "Customer") { + row_values = data + .slice(4, length - 1) + .map(function (column) { + return column.content; + }); } else if (tree_type == "Item") { - row_values = data.slice(5,length-1).map(function (column) { - return column.content; - }) - } - else { - row_values = data.slice(3,length-1).map(function (column) { - return column.content; - }) + row_values = data + .slice(5, length - 1) + .map(function (column) { + return column.content; + }); + } else { + row_values = data + .slice(3, length - 1) + .map(function (column) { + return column.content; + }); } entry = { - 'name':row_name, - 'values':row_values - } + name: row_name, + values: row_values, + }; let raw_data = frappe.query_report.chart.data; let new_datasets = raw_data.datasets; - var found = false; + let found = false; - for(var i=0; i < new_datasets.length;i++){ - if(new_datasets[i].name == row_name){ + for (let i = 0; i < new_datasets.length; i++) { + if (new_datasets[i].name == row_name) { found = true; - new_datasets.splice(i,1); + new_datasets.splice(i, 1); break; } } - if(!found){ + if (!found) { new_datasets.push(entry); } let new_data = { labels: raw_data.labels, - datasets: new_datasets - } - - setTimeout(() => { - frappe.query_report.chart.update(new_data) - }, 500) - - - setTimeout(() => { - frappe.query_report.chart.draw(true); - }, 1000) + datasets: new_datasets, + }; + chart_options = { + data: new_data, + type: "line", + }; + frappe.query_report.render_chart(chart_options); frappe.query_report.raw_chart_data = new_data; }, - } - }) + }, + }); }, } From 924f99bead32bb4eba656019a15931f797eb04ae Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Wed, 16 Dec 2020 15:42:50 +0530 Subject: [PATCH 179/477] fix: Help message --- .../accounting_dimension_filter.js | 12 ++++++++++++ .../accounting_dimension_filter.json | 19 +++++++++++++++++-- 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/erpnext/accounts/doctype/accounting_dimension_filter/accounting_dimension_filter.js b/erpnext/accounts/doctype/accounting_dimension_filter/accounting_dimension_filter.js index a2526e92c36..74b7b516763 100644 --- a/erpnext/accounts/doctype/accounting_dimension_filter/accounting_dimension_filter.js +++ b/erpnext/accounts/doctype/accounting_dimension_filter/accounting_dimension_filter.js @@ -6,6 +6,18 @@ frappe.ui.form.on('Accounting Dimension Filter', { if (frm.doc.accounting_dimension) { frm.set_df_property('dimensions', 'label', frm.doc.accounting_dimension, cdn, 'dimension_value'); } + + let help_content = + ` + +
    +

    + + {{__('Note: On checking Is Mandatory the accounting dimension will become mandatory against that specific account for all accounting transactions')}} +

    +
    `; + + frm.set_df_property('dimension_filter_help', 'options', help_content); }, onload: function(frm) { frm.set_query('applicable_on_account', 'accounts', function() { diff --git a/erpnext/accounts/doctype/accounting_dimension_filter/accounting_dimension_filter.json b/erpnext/accounts/doctype/accounting_dimension_filter/accounting_dimension_filter.json index 7736b2dffb2..c0327ad0ad8 100644 --- a/erpnext/accounts/doctype/accounting_dimension_filter/accounting_dimension_filter.json +++ b/erpnext/accounts/doctype/accounting_dimension_filter/accounting_dimension_filter.json @@ -14,7 +14,9 @@ "section_break_4", "accounts", "column_break_6", - "dimensions" + "dimensions", + "section_break_10", + "dimension_filter_help" ], "fields": [ { @@ -89,11 +91,24 @@ "reqd": 1, "show_days": 1, "show_seconds": 1 + }, + { + "fieldname": "dimension_filter_help", + "fieldtype": "HTML", + "label": "Dimension Filter Help", + "show_days": 1, + "show_seconds": 1 + }, + { + "fieldname": "section_break_10", + "fieldtype": "Section Break", + "show_days": 1, + "show_seconds": 1 } ], "index_web_pages_for_search": 1, "links": [], - "modified": "2020-11-24 12:34:42.458713", + "modified": "2020-12-16 15:27:23.659285", "modified_by": "Administrator", "module": "Accounts", "name": "Accounting Dimension Filter", From d44f45c57be854c1c6c625ffccf86b56203c3dd7 Mon Sep 17 00:00:00 2001 From: pateljannat Date: Wed, 16 Dec 2020 16:28:09 +0530 Subject: [PATCH 180/477] fix: sider issues --- erpnext/projects/doctype/project/test_project.py | 7 ++++--- erpnext/projects/doctype/task/task.py | 4 ++-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/erpnext/projects/doctype/project/test_project.py b/erpnext/projects/doctype/project/test_project.py index c3f56b8e860..ce56a50b4e2 100644 --- a/erpnext/projects/doctype/project/test_project.py +++ b/erpnext/projects/doctype/project/test_project.py @@ -106,17 +106,18 @@ def get_project(name, template): def make_project(args): args = frappe._dict(args) - if args.project_template_name: - template = make_project_template(args.project_template_name) project = frappe.get_doc(dict( doctype = 'Project', project_name = args.project_name, status = 'Open', - project_template = template.name, expected_start_date = args.start_date )) + if args.project_template_name: + template = make_project_template(args.project_template_name) + project.project_template = template.name + if not frappe.db.exists("Project", args.project_name): project.insert() diff --git a/erpnext/projects/doctype/task/task.py b/erpnext/projects/doctype/task/task.py index 072a848f263..80b764ba4f0 100755 --- a/erpnext/projects/doctype/task/task.py +++ b/erpnext/projects/doctype/task/task.py @@ -94,7 +94,7 @@ class Task(NestedSet): def update_depends_on(self): depends_on_tasks = self.depends_on_tasks or "" for d in self.depends_on: - if d.task and not d.task in depends_on_tasks: + if d.task and d.task not in depends_on_tasks: depends_on_tasks += d.task + "," self.depends_on_tasks = depends_on_tasks @@ -180,7 +180,7 @@ class Task(NestedSet): def populate_depends_on(self): if self.parent_task: parent = frappe.get_doc('Task', self.parent_task) - if not self.name in [row.task for row in parent.depends_on]: + if self.name not in [row.task for row in parent.depends_on]: parent.append("depends_on", { "doctype": "Task Depends On", "task": self.name, From 2528d5ee15a5ce9d5d9634eec016946b1416154d Mon Sep 17 00:00:00 2001 From: pateljannat Date: Wed, 16 Dec 2020 18:29:49 +0530 Subject: [PATCH 181/477] fix: tests --- erpnext/projects/doctype/task/test_task.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/projects/doctype/task/test_task.py b/erpnext/projects/doctype/task/test_task.py index d43d132e80e..aded78b8574 100644 --- a/erpnext/projects/doctype/task/test_task.py +++ b/erpnext/projects/doctype/task/test_task.py @@ -104,7 +104,7 @@ def create_task(subject, start=None, end=None, depends_on=None, project=None, pa task.subject = subject task.exp_start_date = start or nowdate() task.exp_end_date = end or nowdate() - task.project = project + task.project = project or "_Test Project" task.is_template = is_template task.start = begin task.duration = duration From 70cfc4df15cbbea19c32a61d0f73edc075a3699e Mon Sep 17 00:00:00 2001 From: Suraj Shetty Date: Wed, 16 Dec 2020 20:55:47 +0530 Subject: [PATCH 182/477] fix: Remove dashboard page from home --- erpnext/setup/workspace/home/home.json | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/erpnext/setup/workspace/home/home.json b/erpnext/setup/workspace/home/home.json index c041bb32fb3..13c1172fad8 100644 --- a/erpnext/setup/workspace/home/home.json +++ b/erpnext/setup/workspace/home/home.json @@ -417,7 +417,7 @@ "type": "Link" } ], - "modified": "2020-12-01 13:38:38.131999", + "modified": "2020-12-16 10:24:52.088466", "modified_by": "Administrator", "module": "Setup", "name": "Home", @@ -445,11 +445,6 @@ "link_to": "Sales Invoice", "type": "DocType" }, - { - "label": "Dashboard", - "link_to": "dashboard", - "type": "Page" - }, { "label": "Leaderboard", "link_to": "leaderboard", From 5a2030c2f22e1af5eeedcab053978758826dd34b Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Thu, 17 Dec 2020 09:21:11 +0530 Subject: [PATCH 183/477] fix: Add server side methods and other fixes --- erpnext/controllers/accounts_controller.py | 2 +- .../landed_cost_voucher.js | 19 ++++--- .../landed_cost_voucher.py | 38 ++++++++++++-- .../test_landed_cost_voucher.py | 51 +++++++++++++++++-- .../purchase_receipt/purchase_receipt.py | 16 ++++-- 5 files changed, 106 insertions(+), 20 deletions(-) diff --git a/erpnext/controllers/accounts_controller.py b/erpnext/controllers/accounts_controller.py index 32c5d3a3b14..49c9f8c9d0f 100644 --- a/erpnext/controllers/accounts_controller.py +++ b/erpnext/controllers/accounts_controller.py @@ -442,7 +442,7 @@ class AccountsController(TransactionBase): account_currency = get_account_currency(gl_dict.account) if gl_dict.account and self.doctype not in ["Journal Entry", - "Period Closing Voucher", "Payment Entry"]: + "Period Closing Voucher", "Payment Entry", "Purchase Receipt", "Purchase Invoice"]: self.validate_account_currency(gl_dict.account, account_currency) set_balance_in_account_currency(gl_dict, account_currency, self.get("conversion_rate"), self.company_currency) diff --git a/erpnext/stock/doctype/landed_cost_voucher/landed_cost_voucher.js b/erpnext/stock/doctype/landed_cost_voucher/landed_cost_voucher.js index a5ac60c4f51..82b52427041 100644 --- a/erpnext/stock/doctype/landed_cost_voucher/landed_cost_voucher.js +++ b/erpnext/stock/doctype/landed_cost_voucher/landed_cost_voucher.js @@ -96,9 +96,9 @@ erpnext.stock.LandedCostVoucher = erpnext.stock.StockController.extend({ set_total_taxes_and_charges: function() { var total_taxes_and_charges = 0.0; $.each(this.frm.doc.taxes || [], function(i, d) { - total_taxes_and_charges += flt(d.base_amount) + total_taxes_and_charges += flt(d.base_amount); }); - cur_frm.set_value("total_taxes_and_charges", total_taxes_and_charges); + this.frm.set_value("total_taxes_and_charges", total_taxes_and_charges); }, set_applicable_charges_for_item: function() { @@ -148,11 +148,16 @@ frappe.ui.form.on('Landed Cost Voucher', { } }, + onload: function(frm) { + let company_currency = frappe.get_doc(":Company", frm.doc.company).default_currency; + frm.set_currency_labels(["total_taxes_and_charges"], company_currency); + }, + set_exchange_rate: function(frm, cdt, cdn) { let row = locals[cdt][cdn]; let company_currency = frappe.get_doc(":Company", frm.doc.company).default_currency; - if(row.account_currency == company_currency) { + if (row.account_currency == company_currency) { row.exchange_rate = 1; } else if (!row.exchange_rate || row.exchange_rate == 1) { frappe.call({ @@ -164,12 +169,12 @@ frappe.ui.form.on('Landed Cost Voucher', { company: frm.doc.company }, callback: function(r) { - if(r.message) { + if (r.message) { frappe.model.set_value(cdt, cdn, "exchange_rate", r.message); } } - }) - } + }); + }; }, set_base_amount: function(frm, cdt, cdn) { @@ -177,7 +182,7 @@ frappe.ui.form.on('Landed Cost Voucher', { frappe.model.set_value(cdt, cdn, "base_amount", flt(flt(row.amount)*row.exchange_rate, precision("base_amount", row))); } -}) +}); frappe.ui.form.on('Landed Cost Taxes and Charges', { expense_account: function(frm, cdt, cdn) { diff --git a/erpnext/stock/doctype/landed_cost_voucher/landed_cost_voucher.py b/erpnext/stock/doctype/landed_cost_voucher/landed_cost_voucher.py index e39208991bd..519077afa49 100644 --- a/erpnext/stock/doctype/landed_cost_voucher/landed_cost_voucher.py +++ b/erpnext/stock/doctype/landed_cost_voucher/landed_cost_voucher.py @@ -40,14 +40,17 @@ class LandedCostVoucher(Document): def validate(self): self.check_mandatory() + self.validate_purchase_receipts() + self.set_account_currency() self.set_exchange_rate() self.set_amounts_in_company_currency() + self.set_total_taxes_and_charges() if not self.get("items"): self.get_items_from_purchase_receipts() - else: - self.validate_applicable_charges_for_item() - self.validate_purchase_receipts() - self.set_total_taxes_and_charges() + + self.set_applicable_charges_on_item() + self.validate_applicable_charges_for_item() + def check_mandatory(self): if not self.get("purchase_receipts"): @@ -78,6 +81,33 @@ class LandedCostVoucher(Document): def set_total_taxes_and_charges(self): self.total_taxes_and_charges = sum([flt(d.base_amount) for d in self.get("taxes")]) + def set_applicable_charges_on_item(self): + if self.get('taxes'): + total_item_cost = 0.0 + total_charges = 0.0 + item_count = 0 + based_on_field = frappe.scrub(self.distribute_charges_based_on) + + for item in self.get('items'): + total_item_cost += item.get(based_on_field) + + for item in self.get('items'): + item.applicable_charges = flt(flt(item.get(based_on_field)) * flt(self.total_taxes_and_charges) / flt(total_item_cost), + item.precision('applicable_charges')) + total_charges += item.applicable_charges + item_count += 1 + + if total_charges != self.total_taxes_and_charges: + diff = self.total_taxes_and_charges - total_charges + self.get('items')[item_count - 1].applicable_charges += diff + + def set_account_currency(self): + company_currency = erpnext.get_company_currency(self.company) + for d in self.get('taxes'): + if not d.account_currency: + account_currency = frappe.db.get_value('Account', d.expense_account, 'account_currency') + d.account_currency = account_currency or company_currency + def set_exchange_rate(self): company_currency = erpnext.get_company_currency(self.company) for d in self.get('taxes'): diff --git a/erpnext/stock/doctype/landed_cost_voucher/test_landed_cost_voucher.py b/erpnext/stock/doctype/landed_cost_voucher/test_landed_cost_voucher.py index 3f2c5daf669..79d306b5dbb 100644 --- a/erpnext/stock/doctype/landed_cost_voucher/test_landed_cost_voucher.py +++ b/erpnext/stock/doctype/landed_cost_voucher/test_landed_cost_voucher.py @@ -10,6 +10,7 @@ from erpnext.stock.doctype.purchase_receipt.test_purchase_receipt \ import set_perpetual_inventory, get_gl_entries, test_records as pr_test_records, make_purchase_receipt from erpnext.accounts.doctype.purchase_invoice.test_purchase_invoice import make_purchase_invoice from erpnext.accounts.doctype.account.test_account import get_inventory_account +from erpnext.accounts.doctype.account.test_account import create_account class TestLandedCostVoucher(unittest.TestCase): def test_landed_cost_voucher(self): @@ -27,7 +28,7 @@ class TestLandedCostVoucher(unittest.TestCase): }, fieldname=["qty_after_transaction", "stock_value"], as_dict=1) - submit_landed_cost_voucher("Purchase Receipt", pr.name, pr.company) + create_landed_cost_voucher("Purchase Receipt", pr.name, pr.company) pr_lc_value = frappe.db.get_value("Purchase Receipt Item", {"parent": pr.name}, "landed_cost_voucher_amount") self.assertEqual(pr_lc_value, 25.0) @@ -89,7 +90,7 @@ class TestLandedCostVoucher(unittest.TestCase): }, fieldname=["qty_after_transaction", "stock_value"], as_dict=1) - submit_landed_cost_voucher("Purchase Invoice", pi.name, pi.company) + create_landed_cost_voucher("Purchase Invoice", pi.name, pi.company) pi_lc_value = frappe.db.get_value("Purchase Invoice Item", {"parent": pi.name}, "landed_cost_voucher_amount") @@ -137,7 +138,7 @@ class TestLandedCostVoucher(unittest.TestCase): serial_no_rate = frappe.db.get_value("Serial No", "SN001", "purchase_rate") - submit_landed_cost_voucher("Purchase Receipt", pr.name, pr.company) + create_landed_cost_voucher("Purchase Receipt", pr.name, pr.company) serial_no = frappe.db.get_value("Serial No", "SN001", ["warehouse", "purchase_rate"], as_dict=1) @@ -160,7 +161,7 @@ class TestLandedCostVoucher(unittest.TestCase): }) pr.submit() - lcv = submit_landed_cost_voucher("Purchase Receipt", pr.name, pr.company, 123.22) + lcv = create_landed_cost_voucher("Purchase Receipt", pr.name, pr.company, 123.22) self.assertEqual(lcv.items[0].applicable_charges, 41.07) self.assertEqual(lcv.items[2].applicable_charges, 41.08) @@ -206,6 +207,46 @@ class TestLandedCostVoucher(unittest.TestCase): self.assertEqual(pr.items[0].landed_cost_voucher_amount, 100) self.assertEqual(pr.items[1].landed_cost_voucher_amount, 100) + def test_multi_currency_lcv(self): + ## Create USD Shipping charges_account + usd_shipping = create_account(account_name="Shipping Charges USD", + parent_account="Duties and Taxes - TCP1", company="_Test Company with perpetual inventory", + account_currency="USD") + + pr = make_purchase_receipt(company="_Test Company with perpetual inventory", warehouse = "Stores - TCP1", + supplier_warehouse = "Stores - TCP1") + pr.submit() + + lcv = make_landed_cost_voucher(company = pr.company, receipt_document_type = "Purchase Receipt", + receipt_document=pr.name, charges=100, do_not_save=True) + + lcv.append("taxes", { + "description": "Shipping Charges", + "expense_account": usd_shipping, + "amount": 10 + }) + + lcv.save() + lcv.submit() + pr.load_from_db() + + # Considering exchange rate from USD to INR as 62.9 + self.assertEqual(lcv.total_taxes_and_charges, 729) + self.assertEqual(pr.items[0].landed_cost_voucher_amount, 729) + + gl_entries = frappe.get_all("GL Entry", fields=["account", "credit", "credit_in_account_currency"], + filters={"voucher_no": pr.name, "account": ("in", ["Shipping Charges USD - TCP1", "Expenses Included In Valuation - TCP1"])}) + + expected_gl_entries = { + "Shipping Charges USD - TCP1": [629, 10], + "Expenses Included In Valuation - TCP1": [100, 100] + } + + for entry in gl_entries: + amounts = expected_gl_entries.get(entry.account) + self.assertEqual(entry.credit, amounts[0]) + self.assertEqual(entry.credit_in_account_currency, amounts[1]) + def make_landed_cost_voucher(** args): args = frappe._dict(args) ref_doc = frappe.get_doc(args.receipt_document_type, args.receipt_document) @@ -236,7 +277,7 @@ def make_landed_cost_voucher(** args): return lcv -def submit_landed_cost_voucher(receipt_document_type, receipt_document, company, charges=50): +def create_landed_cost_voucher(receipt_document_type, receipt_document, company, charges=50): ref_doc = frappe.get_doc(receipt_document_type, receipt_document) lcv = frappe.new_doc("Landed Cost Voucher") diff --git a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py index 97e0fa738cd..2cb8d2b26da 100644 --- a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py +++ b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py @@ -279,12 +279,15 @@ class PurchaseReceipt(BuyingController): # Amount added through landed-cost-voucher if d.landed_cost_voucher_amount and landed_cost_entries: for account, amount in iteritems(landed_cost_entries[(d.item_code, d.name)]): + account_currency = get_account_currency(account) gl_entries.append(self.get_gl_dict({ "account": account, + "account_currency": account_currency, "against": warehouse_account[d.warehouse]["account"], "cost_center": d.cost_center, "remarks": self.get("remarks") or _("Accounting Entry for Stock"), - "credit": flt(amount), + "credit": flt(amount["base_amount"]), + "credit_in_account_currency": flt(amount["amount"]), "project": d.project }, item=d)) @@ -729,9 +732,16 @@ def get_item_account_wise_additional_cost(purchase_document): if item.receipt_document == purchase_document: for account in landed_cost_voucher_doc.taxes: item_account_wise_cost.setdefault((item.item_code, item.purchase_receipt_item), {}) - item_account_wise_cost[(item.item_code, item.purchase_receipt_item)].setdefault(account.expense_account, 0.0) - item_account_wise_cost[(item.item_code, item.purchase_receipt_item)][account.expense_account] += \ + item_account_wise_cost[(item.item_code, item.purchase_receipt_item)].setdefault(account.expense_account, { + "amount": 0.0, + "base_amount": 0.0 + }) + + item_account_wise_cost[(item.item_code, item.purchase_receipt_item)][account.expense_account]["amount"] += \ account.amount * item.get(based_on_field) / total_item_cost + item_account_wise_cost[(item.item_code, item.purchase_receipt_item)][account.expense_account]["base_amount"] += \ + account.base_amount * item.get(based_on_field) / total_item_cost + return item_account_wise_cost From d6cd02d29d26bc814328ded38f12c090a27a6970 Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Thu, 17 Dec 2020 09:21:24 +0530 Subject: [PATCH 184/477] fix: Add tests --- erpnext/accounts/doctype/account/test_account.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/erpnext/accounts/doctype/account/test_account.py b/erpnext/accounts/doctype/account/test_account.py index 0605d89a7e2..fbcaa6cc186 100644 --- a/erpnext/accounts/doctype/account/test_account.py +++ b/erpnext/accounts/doctype/account/test_account.py @@ -254,7 +254,8 @@ def create_account(**kwargs): account_name = kwargs.get('account_name'), account_type = kwargs.get('account_type'), parent_account = kwargs.get('parent_account'), - company = kwargs.get('company') + company = kwargs.get('company'), + account_currency = kwargs.get('account_currency') )) account.save() From f2bff8e220a26b1ed9a662e010b7e15fe91df73e Mon Sep 17 00:00:00 2001 From: pateljannat Date: Thu, 17 Dec 2020 11:54:59 +0530 Subject: [PATCH 185/477] fix: patch relaod doctype --- erpnext/patches/v13_0/update_project_template_tasks.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/erpnext/patches/v13_0/update_project_template_tasks.py b/erpnext/patches/v13_0/update_project_template_tasks.py index 55f0ff45057..df1886f616c 100644 --- a/erpnext/patches/v13_0/update_project_template_tasks.py +++ b/erpnext/patches/v13_0/update_project_template_tasks.py @@ -5,9 +5,10 @@ from __future__ import unicode_literals import frappe def execute(): + frappe.reload_doctype("Project Template") templates = frappe.get_list("Project Template", fields = ["name"]) for template_name in templates: - template = frappe.get_doc("Project Template", template_name) + template = frappe.get_doc("Project Template", template_name.name) replace_tasks = False new_tasks = [] for task in template.tasks: From 6f99c0850c3e40eff4a0c4f43ba850a1bacda620 Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Thu, 17 Dec 2020 12:19:58 +0530 Subject: [PATCH 186/477] fix: Linting Issues --- .../stock/doctype/landed_cost_voucher/landed_cost_voucher.js | 2 +- .../stock/doctype/landed_cost_voucher/landed_cost_voucher.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/erpnext/stock/doctype/landed_cost_voucher/landed_cost_voucher.js b/erpnext/stock/doctype/landed_cost_voucher/landed_cost_voucher.js index 82b52427041..c817f05e5a2 100644 --- a/erpnext/stock/doctype/landed_cost_voucher/landed_cost_voucher.js +++ b/erpnext/stock/doctype/landed_cost_voucher/landed_cost_voucher.js @@ -174,7 +174,7 @@ frappe.ui.form.on('Landed Cost Voucher', { } } }); - }; + } }, set_base_amount: function(frm, cdt, cdn) { diff --git a/erpnext/stock/doctype/landed_cost_voucher/landed_cost_voucher.py b/erpnext/stock/doctype/landed_cost_voucher/landed_cost_voucher.py index 519077afa49..ed545515957 100644 --- a/erpnext/stock/doctype/landed_cost_voucher/landed_cost_voucher.py +++ b/erpnext/stock/doctype/landed_cost_voucher/landed_cost_voucher.py @@ -193,8 +193,8 @@ class LandedCostVoucher(Document): docs = frappe.db.get_all('Asset', filters={ receipt_document_type: item.receipt_document, 'item_code': item.item_code }, fields=['name', 'docstatus']) if not docs or len(docs) != item.qty: - frappe.throw(_('There are not enough asset created or linked to {0}. \ - Please create or link {1} Assets with respective document.').format(item.receipt_document, item.qty)) + frappe.throw(_('There are not enough asset created or linked to {0}. Please create or link {1} Assets with respective document.').format( + item.receipt_document, item.qty)) if docs: for d in docs: if d.docstatus == 1: From 51892efd60e8cd86fde4d9167eca064f691d1b4f Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Thu, 17 Dec 2020 12:35:22 +0530 Subject: [PATCH 187/477] fix: Translation issues --- .../stock/doctype/landed_cost_voucher/landed_cost_voucher.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/erpnext/stock/doctype/landed_cost_voucher/landed_cost_voucher.py b/erpnext/stock/doctype/landed_cost_voucher/landed_cost_voucher.py index ed545515957..17bfa8fbb02 100644 --- a/erpnext/stock/doctype/landed_cost_voucher/landed_cost_voucher.py +++ b/erpnext/stock/doctype/landed_cost_voucher/landed_cost_voucher.py @@ -198,8 +198,7 @@ class LandedCostVoucher(Document): if docs: for d in docs: if d.docstatus == 1: - frappe.throw(_('{2} {0} has submitted Assets.\ - Remove Item {1} from table to continue.').format( + frappe.throw(_('{2} {0} has submitted Assets. Remove Item {1} from table to continue.').format( item.receipt_document, item.item_code, item.receipt_document_type)) def update_rate_in_serial_no_for_non_asset_items(self, receipt_document): From 2dbb1d6bc72b28542eec44878c28f1eed069bcca Mon Sep 17 00:00:00 2001 From: pateljannat Date: Thu, 17 Dec 2020 15:49:52 +0530 Subject: [PATCH 188/477] fix: indentation --- erpnext/patches/v13_0/update_project_template_tasks.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/erpnext/patches/v13_0/update_project_template_tasks.py b/erpnext/patches/v13_0/update_project_template_tasks.py index df1886f616c..8dd0181eceb 100644 --- a/erpnext/patches/v13_0/update_project_template_tasks.py +++ b/erpnext/patches/v13_0/update_project_template_tasks.py @@ -5,10 +5,9 @@ from __future__ import unicode_literals import frappe def execute(): - frappe.reload_doctype("Project Template") - templates = frappe.get_list("Project Template", fields = ["name"]) - for template_name in templates: + for template_name in frappe.db.sql(""" select name from `tabProject Template` """, as_dict=1): template = frappe.get_doc("Project Template", template_name.name) + print(template.tasks) replace_tasks = False new_tasks = [] for task in template.tasks: From 09f0e9111d6fb79868c58f55ead0f18351c6d216 Mon Sep 17 00:00:00 2001 From: pateljannat Date: Thu, 17 Dec 2020 17:20:21 +0530 Subject: [PATCH 189/477] fix: patch --- erpnext/patches/v13_0/update_project_template_tasks.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/patches/v13_0/update_project_template_tasks.py b/erpnext/patches/v13_0/update_project_template_tasks.py index 8dd0181eceb..0bcd1d3f3a5 100644 --- a/erpnext/patches/v13_0/update_project_template_tasks.py +++ b/erpnext/patches/v13_0/update_project_template_tasks.py @@ -5,9 +5,9 @@ from __future__ import unicode_literals import frappe def execute(): + frappe.reload_doc("projects", "doctype", "project_template”) for template_name in frappe.db.sql(""" select name from `tabProject Template` """, as_dict=1): template = frappe.get_doc("Project Template", template_name.name) - print(template.tasks) replace_tasks = False new_tasks = [] for task in template.tasks: From 79b71462cbdec8fabbb20f80f7e258bb55a65620 Mon Sep 17 00:00:00 2001 From: pateljannat Date: Thu, 17 Dec 2020 18:21:34 +0530 Subject: [PATCH 190/477] fix: patch --- erpnext/patches/v13_0/update_project_template_tasks.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/patches/v13_0/update_project_template_tasks.py b/erpnext/patches/v13_0/update_project_template_tasks.py index 0bcd1d3f3a5..1303efd93fb 100644 --- a/erpnext/patches/v13_0/update_project_template_tasks.py +++ b/erpnext/patches/v13_0/update_project_template_tasks.py @@ -5,7 +5,7 @@ from __future__ import unicode_literals import frappe def execute(): - frappe.reload_doc("projects", "doctype", "project_template”) + frappe.reload_doc("projects", "doctype", "project_template") for template_name in frappe.db.sql(""" select name from `tabProject Template` """, as_dict=1): template = frappe.get_doc("Project Template", template_name.name) replace_tasks = False From b8e656512e8ab34601149c3f3ca0f9831441545a Mon Sep 17 00:00:00 2001 From: pateljannat Date: Thu, 17 Dec 2020 20:22:06 +0530 Subject: [PATCH 191/477] fix: test cleanup --- .../project_template/test_project_template.py | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/erpnext/projects/doctype/project_template/test_project_template.py b/erpnext/projects/doctype/project_template/test_project_template.py index 6c6b78368ed..95663cdcbbb 100644 --- a/erpnext/projects/doctype/project_template/test_project_template.py +++ b/erpnext/projects/doctype/project_template/test_project_template.py @@ -10,19 +10,6 @@ from erpnext.projects.doctype.task.test_task import create_task class TestProjectTemplate(unittest.TestCase): pass -def get_project_template(project_template_name="Test Project Template", project_tasks=[]): - if not frappe.db.exists('Project Template', project_template_name): - frappe.get_doc(dict( - doctype = 'Project Template', - name = project_template_name, - tasks = project_tasks or [ - create_task(subject="_Test Template Task 1", is_template=1, begin=0, duration=3), - create_task(subject="_Test Template Task 2", is_template=1, begin=0, duration=2) - ] - )).insert() - - return frappe.get_doc('Project Template', project_template_name) - def make_project_template(project_template_name, project_tasks=[]): if not frappe.db.exists('Project Template', project_template_name): project_tasks = project_tasks or [ From 2cd41bca065f14228a27f183068f936e0c9ea11f Mon Sep 17 00:00:00 2001 From: Rushabh Mehta Date: Fri, 18 Dec 2020 13:17:58 +0530 Subject: [PATCH 192/477] fix(routes): desk to app --- .../assessment_result_tool/assessment_result_tool.js | 2 +- .../course_scheduling_tool/course_scheduling_tool.js | 2 +- .../doctype/tally_migration/tally_migration.js | 4 ++-- erpnext/manufacturing/doctype/bom/bom.js | 2 +- erpnext/projects/doctype/task/task_list.js | 2 +- erpnext/public/js/call_popup/call_popup.js | 4 ++-- erpnext/public/js/communication.js | 2 +- erpnext/public/js/setup_wizard.js | 8 +++----- erpnext/selling/doctype/sales_order/sales_order.js | 2 +- erpnext/stock/dashboard/item_dashboard.js | 2 +- erpnext/stock/doctype/batch/batch.js | 2 +- erpnext/stock/doctype/item/item.js | 4 ++-- erpnext/stock/doctype/item_price/item_price.js | 2 +- erpnext/support/doctype/issue/issue.js | 5 +---- 14 files changed, 19 insertions(+), 24 deletions(-) diff --git a/erpnext/education/doctype/assessment_result_tool/assessment_result_tool.js b/erpnext/education/doctype/assessment_result_tool/assessment_result_tool.js index e213309c5e9..053f0c2f1b8 100644 --- a/erpnext/education/doctype/assessment_result_tool/assessment_result_tool.js +++ b/erpnext/education/doctype/assessment_result_tool/assessment_result_tool.js @@ -128,7 +128,7 @@ frappe.ui.form.on('Assessment Result Tool', { result_table.find(`span[data-student=${assessment_result.student}].total-score-grade`).html(assessment_result.grade); let link_span = result_table.find(`span[data-student=${assessment_result.student}].total-result-link`); $(link_span).css("display", "block"); - $(link_span).find("a").attr("href", "/desk/Form/Assessment Result/"+assessment_result.name); + $(link_span).find("a").attr("href", "/app/assessment-result/"+assessment_result.name); } }); } diff --git a/erpnext/education/doctype/course_scheduling_tool/course_scheduling_tool.js b/erpnext/education/doctype/course_scheduling_tool/course_scheduling_tool.js index f408dae7bda..4e2ccaa30cf 100644 --- a/erpnext/education/doctype/course_scheduling_tool/course_scheduling_tool.js +++ b/erpnext/education/doctype/course_scheduling_tool/course_scheduling_tool.js @@ -25,7 +25,7 @@ frappe.ui.form.on('Course Scheduling Tool', { ${__("Course")}${__("Date")} ${course_schedules.map( - c => `${c.name} + c => `${c.name} ${c.schedule_date}` ).join('')} diff --git a/erpnext/erpnext_integrations/doctype/tally_migration/tally_migration.js b/erpnext/erpnext_integrations/doctype/tally_migration/tally_migration.js index e8641114beb..5482b9cc695 100644 --- a/erpnext/erpnext_integrations/doctype/tally_migration/tally_migration.js +++ b/erpnext/erpnext_integrations/doctype/tally_migration/tally_migration.js @@ -23,10 +23,10 @@ frappe.ui.form.on("Tally Migration", { frappe.msgprint({ message: __("An error has occurred during {0}. Check {1} for more details", [ - repl("%(tally_document)s", { + repl("%(tally_document)s", { tally_document: frm.docname }), - "Error Log" + "Error Log" ] ), title: __("Tally Migration Error"), diff --git a/erpnext/manufacturing/doctype/bom/bom.js b/erpnext/manufacturing/doctype/bom/bom.js index 55f7a1b8a90..42662f6f8fb 100644 --- a/erpnext/manufacturing/doctype/bom/bom.js +++ b/erpnext/manufacturing/doctype/bom/bom.js @@ -134,7 +134,7 @@ frappe.ui.form.on("BOM", { frm.set_intro(__('This is a Template BOM and will be used to make the work order for {0} of the item {1}', [ `variants`, - `${frm.doc.item}`, + `${frm.doc.item}`, ]), true); frm.$wrapper.find(".variants-intro").on("click", () => { diff --git a/erpnext/projects/doctype/task/task_list.js b/erpnext/projects/doctype/task/task_list.js index 7c620317dee..1b6c5fd9fe5 100644 --- a/erpnext/projects/doctype/task/task_list.js +++ b/erpnext/projects/doctype/task/task_list.js @@ -26,7 +26,7 @@ frappe.listview_settings['Task'] = { }, gantt_custom_popup_html: function(ganttobj, task) { var html = `
    ${ganttobj.name}
    `; + href="/app/task/${ganttobj.id}""> ${ganttobj.name} `; if(task.project) html += `

    Project: ${task.project}

    `; html += `

    Progress: ${ganttobj.progress}

    `; diff --git a/erpnext/public/js/call_popup/call_popup.js b/erpnext/public/js/call_popup/call_popup.js index 16e9cdb5033..be1745e54f1 100644 --- a/erpnext/public/js/call_popup/call_popup.js +++ b/erpnext/public/js/call_popup/call_popup.js @@ -85,7 +85,7 @@ class CallPopup {
    + href="/app/call-log/${this.call_log.name}"> ${__('View call log')} `, @@ -167,7 +167,7 @@ class CallPopup { const issue_field = this.dialog.get_field("last_issue"); issue_field.set_value(issue.subject); issue_field.$wrapper.append(` - + ${__('View all issues from {0}', [issue.customer])} `); diff --git a/erpnext/public/js/communication.js b/erpnext/public/js/communication.js index 38778e2ab0a..7ce8b0913c3 100644 --- a/erpnext/public/js/communication.js +++ b/erpnext/public/js/communication.js @@ -84,7 +84,7 @@ frappe.ui.form.on("Communication", { frm.reload_doc(); frappe.show_alert({ message: __("Opportunity {0} created", - ['' + r.message + '']), + ['' + r.message + '']), indicator: 'green' }); } diff --git a/erpnext/public/js/setup_wizard.js b/erpnext/public/js/setup_wizard.js index 092f83903ea..ef03b01698c 100644 --- a/erpnext/public/js/setup_wizard.js +++ b/erpnext/public/js/setup_wizard.js @@ -127,11 +127,9 @@ erpnext.setup.slides_settings = [ options: "", fieldtype: 'Select' }, { fieldname: 'view_coa', label: __('View Chart of Accounts'), fieldtype: 'Button' }, - - { fieldtype: "Section Break", label: __('Financial Year') }, - { fieldname: 'fy_start_date', label: __('Start Date'), fieldtype: 'Date', reqd: 1 }, - { fieldtype: "Column Break" }, - { fieldname: 'fy_end_date', label: __('End Date'), fieldtype: 'Date', reqd: 1 }, + { fieldname: 'fy_start_date', label: __('Financial Year Begins On'), fieldtype: 'Date', reqd: 1 }, + // end date should be hidden (auto calculated) + { fieldname: 'fy_end_date', label: __('End Date'), fieldtype: 'Date', reqd: 1, hidden: 1 }, ], onload: function (slide) { diff --git a/erpnext/selling/doctype/sales_order/sales_order.js b/erpnext/selling/doctype/sales_order/sales_order.js index df812ad4507..1cb71aeea1f 100644 --- a/erpnext/selling/doctype/sales_order/sales_order.js +++ b/erpnext/selling/doctype/sales_order/sales_order.js @@ -436,7 +436,7 @@ erpnext.selling.SalesOrderController = erpnext.selling.SellingController.extend( callback: function(r) { if(r.message) { frappe.msgprint(__('Material Request {0} submitted.', - ['' + r.message.name+ ''])); + ['' + r.message.name+ ''])); } d.hide(); me.frm.reload_doc(); diff --git a/erpnext/stock/dashboard/item_dashboard.js b/erpnext/stock/dashboard/item_dashboard.js index faa9b5df2fa..f64d5931aee 100644 --- a/erpnext/stock/dashboard/item_dashboard.js +++ b/erpnext/stock/dashboard/item_dashboard.js @@ -198,7 +198,7 @@ erpnext.stock.move_item = function(item, source, target, actual_qty, rate, callb freeze: true, callback: function(r) { frappe.show_alert(__('Stock Entry {0} created', - ['' + r.message.name+ ''])); + ['' + r.message.name+ ''])); dialog.hide(); callback(r); }, diff --git a/erpnext/stock/doctype/batch/batch.js b/erpnext/stock/doctype/batch/batch.js index 7b2edff7e0e..3b07e4e80c1 100644 --- a/erpnext/stock/doctype/batch/batch.js +++ b/erpnext/stock/doctype/batch/batch.js @@ -102,7 +102,7 @@ frappe.ui.form.on('Batch', { }, callback: (r) => { frappe.show_alert(__('Stock Entry {0} created', - ['' + r.message.name+ ''])); + ['' + r.message.name+ ''])); frm.refresh(); }, }); diff --git a/erpnext/stock/doctype/item/item.js b/erpnext/stock/doctype/item/item.js index 43e18d16fc4..9e0941146a7 100644 --- a/erpnext/stock/doctype/item/item.js +++ b/erpnext/stock/doctype/item/item.js @@ -85,7 +85,7 @@ frappe.ui.form.on("Item", { } if (frm.doc.variant_of) { frm.set_intro(__('This Item is a Variant of {0} (Template).', - [`${frm.doc.variant_of}`]), true); + [`${frm.doc.variant_of}`]), true); } if (frappe.defaults.get_default("item_naming_by")!="Naming Series" || frm.doc.variant_of) { @@ -649,7 +649,7 @@ $.extend(erpnext.item, { if (r.message) { var variant = r.message; frappe.msgprint_dialog = frappe.msgprint(__("Item Variant {0} already exists with same attributes", - [repl('%(item)s', { + [repl('%(item)s', { item_encoded: encodeURIComponent(variant), item: variant })] diff --git a/erpnext/stock/doctype/item_price/item_price.js b/erpnext/stock/doctype/item_price/item_price.js index 773fddcf96b..017d248ffc0 100644 --- a/erpnext/stock/doctype/item_price/item_price.js +++ b/erpnext/stock/doctype/item_price/item_price.js @@ -14,6 +14,6 @@ frappe.ui.form.on("Item Price", { frm.add_fetch("item_code", "stock_uom", "uom"); frm.set_df_property("bulk_import_help", "options", - '' + __("Import in Bulk") + ''); + '' + __("Import in Bulk") + ''); } }); diff --git a/erpnext/support/doctype/issue/issue.js b/erpnext/support/doctype/issue/issue.js index 5b295d72544..158416ba796 100644 --- a/erpnext/support/doctype/issue/issue.js +++ b/erpnext/support/doctype/issue/issue.js @@ -189,10 +189,7 @@ frappe.ui.form.on("Issue", { subject: dialog.fields_dict.subject.value, communication_id: e.currentTarget.closest(".timeline-item").getAttribute("data-name") }, (r) => { - let url = window.location.href - let arr = url.split("/"); - let result = arr[0] + "//" + arr[2] - frappe.msgprint(`New issue created: ${r.message}`) + frappe.msgprint(`New issue created: ${r.message}`) frm.reload_doc(); dialog.hide(); }); From d6277cdc7f08f14081b7e425f8a901472c4a73cb Mon Sep 17 00:00:00 2001 From: marination Date: Fri, 18 Dec 2020 21:37:19 +0530 Subject: [PATCH 193/477] feat: Value Based and Numeric Quality Inspection - Acceptance Formula is optional - Choose between Value based and Numeric QI - If numeric, select single or multiple readings - Added Min, Max and Mean Values for numeric inspection to avoid formula usage - Deprecated code cleanup in js file --- .../item_quality_inspection_parameter.json | 54 +++++++++- .../quality_inspection/quality_inspection.js | 102 +++++++++--------- .../quality_inspection.json | 4 +- .../quality_inspection/quality_inspection.py | 98 +++++++++++++---- .../quality_inspection_reading.json | 93 ++++++++++++++-- .../quality_inspection_template.py | 4 +- 6 files changed, 268 insertions(+), 87 deletions(-) diff --git a/erpnext/stock/doctype/item_quality_inspection_parameter/item_quality_inspection_parameter.json b/erpnext/stock/doctype/item_quality_inspection_parameter/item_quality_inspection_parameter.json index 888bc2de474..f4501281579 100644 --- a/erpnext/stock/doctype/item_quality_inspection_parameter/item_quality_inspection_parameter.json +++ b/erpnext/stock/doctype/item_quality_inspection_parameter/item_quality_inspection_parameter.json @@ -8,8 +8,14 @@ "field_order": [ "specification", "value", + "value_based", + "single_reading", "column_break_3", - "acceptance_formula" + "formula_based_criteria", + "acceptance_formula", + "min_value", + "max_value", + "mean_value" ], "fields": [ { @@ -24,10 +30,11 @@ "width": "200px" }, { + "depends_on": "eval:(!doc.formula_based_criteria && doc.value_based)", "fieldname": "value", "fieldtype": "Data", "in_list_view": 1, - "label": "Acceptance Criteria", + "label": "Acceptance Criteria Value", "oldfieldname": "value", "oldfieldtype": "Data" }, @@ -36,17 +43,56 @@ "fieldtype": "Column Break" }, { - "description": "Simple Python formula based on numeric Readings.
    Example 1: reading_1 > 0.2 and reading_1 < 0.5
    \nExample 2: (reading_1 + reading_2) / 2 < 10", + "depends_on": "formula_based_criteria", + "description": "Simple Python formula applied on Reading fields.
    Numeric eg.: reading_1 > 0.2 and reading_1 < 0.5
    \nValue based eg.: reading_value in (\"A\", \"B\", \"C)", "fieldname": "acceptance_formula", "fieldtype": "Code", "in_list_view": 1, "label": "Acceptance Criteria Formula" + }, + { + "default": "0", + "fieldname": "formula_based_criteria", + "fieldtype": "Check", + "label": "Formula Based Criteria" + }, + { + "default": "0", + "depends_on": "eval:!doc.value_based", + "fieldname": "single_reading", + "fieldtype": "Check", + "label": "Single Reading" + }, + { + "depends_on": "eval:(!doc.formula_based_criteria && !doc.single_reading && !doc.value_based)", + "fieldname": "mean_value", + "fieldtype": "Float", + "label": "Mean Value" + }, + { + "depends_on": "eval:(!doc.formula_based_criteria && !doc.value_based)", + "fieldname": "min_value", + "fieldtype": "Float", + "label": "Minimum Value" + }, + { + "depends_on": "eval:(!doc.formula_based_criteria && !doc.value_based)", + "fieldname": "max_value", + "fieldtype": "Float", + "label": "Maximum Value" + }, + { + "default": "0", + "description": "Non-numeric Inspection.", + "fieldname": "value_based", + "fieldtype": "Check", + "label": "Value Based" } ], "idx": 1, "istable": 1, "links": [], - "modified": "2020-11-16 16:33:42.421842", + "modified": "2020-12-18 21:03:29.828723", "modified_by": "Administrator", "module": "Stock", "name": "Item Quality Inspection Parameter", diff --git a/erpnext/stock/doctype/quality_inspection/quality_inspection.js b/erpnext/stock/doctype/quality_inspection/quality_inspection.js index 376848afaa4..f0bf9aed802 100644 --- a/erpnext/stock/doctype/quality_inspection/quality_inspection.js +++ b/erpnext/stock/doctype/quality_inspection/quality_inspection.js @@ -4,6 +4,54 @@ cur_frm.cscript.refresh = cur_frm.cscript.inspection_type; frappe.ui.form.on("Quality Inspection", { + setup: function(frm) { + frm.set_query("batch_no", function() { + return { + filters: { + "item": frm.doc.item_code + } + } + }); + + // Serial No based on item_code + frm.set_query("item_serial_no", function() { + var filters = {}; + if (frm.doc.item_code) { + filters = { + 'item_code': frm.doc.item_code + } + } + return { filters: filters } + }); + + // item code based on GRN/DN + frm.set_query("item_code", function(doc) { + let doctype = doc.reference_type; + + if (doc.reference_type !== "Job Card") { + doctype = (doc.reference_type == "Stock Entry") ? + "Stock Entry Detail" : doc.reference_type + " Item"; + } + + if (doc.reference_type && doc.reference_name) { + let filters = { + "from": doctype, + "inspection_type": doc.inspection_type + }; + + if (doc.reference_type == doctype) + filters["reference_name"] = doc.reference_name; + else + filters["parent"] = doc.reference_name; + + return { + query: "erpnext.stock.doctype.quality_inspection.quality_inspection.item_query", + filters: filters + }; + } + }); + }, + item_code: function(frm) { if (frm.doc.item_code) { return frm.call({ @@ -26,55 +74,5 @@ frappe.ui.form.on("Quality Inspection", { } }); } - } -}) - -// item code based on GRN/DN -cur_frm.fields_dict['item_code'].get_query = function(doc, cdt, cdn) { - let doctype = doc.reference_type; - - if (doc.reference_type !== "Job Card") { - doctype = (doc.reference_type == "Stock Entry") ? - "Stock Entry Detail" : doc.reference_type + " Item"; - } - - if (doc.reference_type && doc.reference_name) { - let filters = { - "from": doctype, - "inspection_type": doc.inspection_type - }; - - if (doc.reference_type == doctype) - filters["reference_name"] = doc.reference_name; - else - filters["parent"] = doc.reference_name; - - return { - query: "erpnext.stock.doctype.quality_inspection.quality_inspection.item_query", - filters: filters - }; - } -}, - -// Serial No based on item_code -cur_frm.fields_dict['item_serial_no'].get_query = function(doc, cdt, cdn) { - var filters = {}; - if (doc.item_code) { - filters = { - 'item_code': doc.item_code - } - } - return { filters: filters } -} - -cur_frm.set_query("batch_no", function(doc) { - return { - filters: { - "item": doc.item_code - } - } -}) - -cur_frm.add_fetch('item_code', 'item_name', 'item_name'); -cur_frm.add_fetch('item_code', 'description', 'description'); - + }, +}) \ No newline at end of file diff --git a/erpnext/stock/doctype/quality_inspection/quality_inspection.json b/erpnext/stock/doctype/quality_inspection/quality_inspection.json index f6d76194d94..edfe7e98b2e 100644 --- a/erpnext/stock/doctype/quality_inspection/quality_inspection.json +++ b/erpnext/stock/doctype/quality_inspection/quality_inspection.json @@ -136,6 +136,7 @@ "width": "50%" }, { + "fetch_from": "item_code.item_name", "fieldname": "item_name", "fieldtype": "Data", "in_global_search": 1, @@ -143,6 +144,7 @@ "read_only": 1 }, { + "fetch_from": "item_code.description", "fieldname": "description", "fieldtype": "Small Text", "label": "Description", @@ -236,7 +238,7 @@ "index_web_pages_for_search": 1, "is_submittable": 1, "links": [], - "modified": "2020-11-19 17:06:05.409963", + "modified": "2020-12-18 19:59:55.710300", "modified_by": "Administrator", "module": "Stock", "name": "Quality Inspection", diff --git a/erpnext/stock/doctype/quality_inspection/quality_inspection.py b/erpnext/stock/doctype/quality_inspection/quality_inspection.py index ae4eb9b9956..a7a023bcbf3 100644 --- a/erpnext/stock/doctype/quality_inspection/quality_inspection.py +++ b/erpnext/stock/doctype/quality_inspection/quality_inspection.py @@ -6,7 +6,7 @@ import frappe from frappe.model.document import Document from frappe.model.mapper import get_mapped_doc from frappe import _ -from frappe.utils import flt +from frappe.utils import flt, cint from erpnext.stock.doctype.quality_inspection_template.quality_inspection_template \ import get_template_details @@ -16,7 +16,7 @@ class QualityInspection(Document): self.get_item_specification_details() if self.readings: - self.set_status_based_on_acceptance_formula() + self.inspect_and_set_status() def get_item_specification_details(self): if not self.quality_inspection_template: @@ -29,9 +29,7 @@ class QualityInspection(Document): parameters = get_template_details(self.quality_inspection_template) for d in parameters: child = self.append('readings', {}) - child.specification = d.specification - child.value = d.value - child.acceptance_formula = d.acceptance_formula + child.update(d) child.status = "Accepted" def get_quality_inspection_template(self): @@ -76,28 +74,84 @@ class QualityInspection(Document): """.format(parent_doc=self.reference_type, child_doc=doctype), (quality_inspection, self.modified, self.reference_name, self.item_code)) - def set_status_based_on_acceptance_formula(self): + def inspect_and_set_status(self): for reading in self.readings: - if not reading.acceptance_formula: continue + if reading.formula_based_criteria: + self.set_status_based_on_acceptance_formula(reading) + else: + self.set_status_based_on_acceptance_values(reading) + + def set_status_based_on_acceptance_values(self, reading): + if cint(reading.value_based): + result = reading.get("reading_value") == reading.get("value") + else: + # numeric readings + if cint(reading.single_reading): + reading_1 = flt(reading.get("reading_1")) + result = flt(reading.get("min_value")) <= reading_1 <= flt(reading.get("max_value")) + else: + result = self.min_max_criteria_passed(reading) and self.mean_criteria_passed(reading) + + reading.status = "Accepted" if result else "Rejected" + + def min_max_criteria_passed(self, reading): + """Determine whether all readings fall in the acceptable range.""" + for i in range(1, 11): + reading_field = reading.get("reading_" + str(i)) + if reading_field is not None: + result = flt(reading.get("min_value")) <= flt(reading_field) <= flt(reading.get("max_value")) + if not result: return False + return True + + def mean_criteria_passed(self, reading): + """Determine whether mean of all readings is acceptable.""" + if reading.get("mean_value"): + from statistics import mean + readings_list = [] - condition = reading.acceptance_formula - data = {} for i in range(1, 11): - field = "reading_" + str(i) - data[field] = flt(reading.get(field)) or 0 + reading_value = reading.get("reading_" + str(i)) + if reading_value is not None: + readings_list.append(flt(reading_value)) - try: - result = frappe.safe_eval(condition, None, data) - reading.status = "Accepted" if result else "Rejected" - except SyntaxError: - frappe.throw(_("Row #{0}: Acceptance Criteria Formula is incorrect.").format(reading.idx), - title=_("Invalid Formula")) - except NameError as e: - field = frappe.bold(e.args[0].split()[1]) - frappe.throw(_("Row #{0}: {1} is not a valid reading field. Please refer to the field description.") - .format(reading.idx, field), - title=_("Invalid Formula")) + actual_mean = mean(readings_list) if readings_list else 0 + return True if actual_mean == reading.get("mean_value") else False + return True # no mean value, nothing to check + + def set_status_based_on_acceptance_formula(self, reading): + if not reading.acceptance_formula: + frappe.throw(_("Row #{0}: Acceptance Criteria Formula is required.").format(reading.idx), + title=_("Missing Formula")) + + condition = reading.acceptance_formula + data = self.get_formula_evaluation_data(reading) + + try: + result = frappe.safe_eval(condition, None, data) + reading.status = "Accepted" if result else "Rejected" + except NameError as e: + field = frappe.bold(e.args[0].split()[1]) + frappe.throw(_("Row #{0}: {1} is not a valid reading field. Please refer to the field description.") + .format(reading.idx, field), + title=_("Invalid Formula")) + except Exception: + frappe.throw(_("Row #{0}: Acceptance Criteria Formula is incorrect.").format(reading.idx), + title=_("Invalid Formula")) + + def get_formula_evaluation_data(self, reading): + data = {} + if cint(reading.value_based): + data = {"reading_value": reading.get("reading_value")} + else: + # numeric readings + data = {"reading_1": flt(reading.get("reading_1"))} + if not cint(reading.single_reading): + # if multiple numeric readings add all readings to data + for i in range(2, 11): + field = "reading_" + str(i) + data[field] = flt(reading.get(field)) + return data @frappe.whitelist() @frappe.validate_and_sanitize_search_inputs diff --git a/erpnext/stock/doctype/quality_inspection_reading/quality_inspection_reading.json b/erpnext/stock/doctype/quality_inspection_reading/quality_inspection_reading.json index c1976dd1fb5..db95fabee0b 100644 --- a/erpnext/stock/doctype/quality_inspection_reading/quality_inspection_reading.json +++ b/erpnext/stock/doctype/quality_inspection_reading/quality_inspection_reading.json @@ -7,21 +7,30 @@ "engine": "InnoDB", "field_order": [ "specification", - "value", "status", + "value", + "value_based", "column_break_4", + "formula_based_criteria", "acceptance_formula", + "min_value", + "max_value", + "mean_value", "section_break_3", + "reading_value", + "section_break_14", + "single_reading", + "section_break_12", "reading_1", "reading_2", "reading_3", - "column_break_10", "reading_4", + "column_break_10", "reading_5", "reading_6", - "column_break_14", "reading_7", "reading_8", + "column_break_14", "reading_9", "reading_10" ], @@ -38,10 +47,11 @@ }, { "columns": 2, + "depends_on": "eval:(!doc.formula_based_criteria && doc.value_based)", "fieldname": "value", "fieldtype": "Data", "in_list_view": 1, - "label": "Acceptance Criteria", + "label": "Acceptance Criteria Value", "oldfieldname": "value", "oldfieldtype": "Data" }, @@ -56,6 +66,7 @@ }, { "columns": 1, + "depends_on": "eval:!doc.single_reading", "fieldname": "reading_2", "fieldtype": "Data", "in_list_view": 1, @@ -65,6 +76,7 @@ }, { "columns": 1, + "depends_on": "eval:!doc.single_reading", "fieldname": "reading_3", "fieldtype": "Data", "in_list_view": 1, @@ -73,6 +85,7 @@ "oldfieldtype": "Data" }, { + "depends_on": "eval:!doc.single_reading", "fieldname": "reading_4", "fieldtype": "Data", "label": "Reading 4", @@ -80,6 +93,7 @@ "oldfieldtype": "Data" }, { + "depends_on": "eval:!doc.single_reading", "fieldname": "reading_5", "fieldtype": "Data", "label": "Reading 5", @@ -87,6 +101,7 @@ "oldfieldtype": "Data" }, { + "depends_on": "eval:!doc.single_reading", "fieldname": "reading_6", "fieldtype": "Data", "label": "Reading 6", @@ -94,6 +109,7 @@ "oldfieldtype": "Data" }, { + "depends_on": "eval:!doc.single_reading", "fieldname": "reading_7", "fieldtype": "Data", "label": "Reading 7", @@ -101,6 +117,7 @@ "oldfieldtype": "Data" }, { + "depends_on": "eval:!doc.single_reading", "fieldname": "reading_8", "fieldtype": "Data", "label": "Reading 8", @@ -108,6 +125,7 @@ "oldfieldtype": "Data" }, { + "depends_on": "eval:!doc.single_reading", "fieldname": "reading_9", "fieldtype": "Data", "label": "Reading 9", @@ -115,6 +133,7 @@ "oldfieldtype": "Data" }, { + "depends_on": "eval:!doc.single_reading", "fieldname": "reading_10", "fieldtype": "Data", "label": "Reading 10", @@ -133,15 +152,18 @@ "options": "Accepted\nRejected" }, { + "depends_on": "value_based", "fieldname": "section_break_3", - "fieldtype": "Section Break" + "fieldtype": "Section Break", + "label": "Value Based Inspection" }, { "fieldname": "column_break_4", "fieldtype": "Column Break" }, { - "description": "Simple Python formula based on numeric Readings.
    Example 1: reading_1 > 0.2 and reading_1 < 0.5
    \nExample 2: (reading_1 + reading_2) / 2 < 10", + "depends_on": "formula_based_criteria", + "description": "Simple Python formula applied on Reading fields.
    Numeric eg.: reading_1 > 0.2 and reading_1 < 0.5
    \nValue based eg.: reading_value in (\"A\", \"B\", \"C)", "fieldname": "acceptance_formula", "fieldtype": "Code", "label": "Acceptance Criteria Formula" @@ -153,12 +175,69 @@ { "fieldname": "column_break_14", "fieldtype": "Column Break" + }, + { + "default": "0", + "fieldname": "formula_based_criteria", + "fieldtype": "Check", + "label": "Formula Based Criteria" + }, + { + "depends_on": "eval:(!doc.formula_based_criteria && !doc.single_reading && !doc.value_based)", + "fieldname": "mean_value", + "fieldtype": "Float", + "label": "Mean Value" + }, + { + "default": "0", + "fieldname": "single_reading", + "fieldtype": "Check", + "label": "Single Reading" + }, + { + "depends_on": "eval:!doc.value_based", + "fieldname": "section_break_12", + "fieldtype": "Section Break", + "hide_border": 1 + }, + { + "depends_on": "eval:(!doc.formula_based_criteria && !doc.value_based)", + "description": "Applied on each reading.", + "fieldname": "min_value", + "fieldtype": "Float", + "label": "Minimum Value" + }, + { + "depends_on": "eval:(!doc.formula_based_criteria && !doc.value_based)", + "description": "Applied on each reading.", + "fieldname": "max_value", + "fieldtype": "Float", + "label": "Maximum Value" + }, + { + "default": "0", + "description": "Non-numeric Inspection.", + "fieldname": "value_based", + "fieldtype": "Check", + "label": "Value Based" + }, + { + "depends_on": "value_based", + "fieldname": "reading_value", + "fieldtype": "Data", + "label": "Reading Value" + }, + { + "depends_on": "eval:!doc.value_based", + "fieldname": "section_break_14", + "fieldtype": "Section Break", + "label": "Numeric Inspection" } ], "idx": 1, "istable": 1, "links": [], - "modified": "2020-11-16 16:34:29.947856", + "modified": "2020-12-18 21:02:04.865777", "modified_by": "Administrator", "module": "Stock", "name": "Quality Inspection Reading", diff --git a/erpnext/stock/doctype/quality_inspection_template/quality_inspection_template.py b/erpnext/stock/doctype/quality_inspection_template/quality_inspection_template.py index e2848469b88..7dd0febc203 100644 --- a/erpnext/stock/doctype/quality_inspection_template/quality_inspection_template.py +++ b/erpnext/stock/doctype/quality_inspection_template/quality_inspection_template.py @@ -13,6 +13,8 @@ def get_template_details(template): if not template: return [] return frappe.get_all('Item Quality Inspection Parameter', - fields=["specification", "value", "acceptance_formula"], + fields=["specification", "value", "acceptance_formula", + "value_based", "formula_based_criteria", "single_reading", + "min_value", "max_value", "mean_value"], filters={'parenttype': 'Quality Inspection Template', 'parent': template}, order_by="idx") \ No newline at end of file From 0c4f97368d05f2277ccca54b583be0a104acf7a9 Mon Sep 17 00:00:00 2001 From: marination Date: Mon, 21 Dec 2020 11:44:48 +0530 Subject: [PATCH 194/477] chore: UX improvement - Removed 'single reading' checkbox, unnecessary - Removed 'Mean' field and added computed mean to formula data - Changed 'Value Based' to 'Non-Numeric' - Re-arranged fields --- .../item_quality_inspection_parameter.json | 43 +++++------- .../quality_inspection/quality_inspection.py | 57 +++++++--------- .../quality_inspection_reading.json | 65 +++++-------------- .../quality_inspection_template.py | 3 +- 4 files changed, 58 insertions(+), 110 deletions(-) diff --git a/erpnext/stock/doctype/item_quality_inspection_parameter/item_quality_inspection_parameter.json b/erpnext/stock/doctype/item_quality_inspection_parameter/item_quality_inspection_parameter.json index f4501281579..9b980a1e013 100644 --- a/erpnext/stock/doctype/item_quality_inspection_parameter/item_quality_inspection_parameter.json +++ b/erpnext/stock/doctype/item_quality_inspection_parameter/item_quality_inspection_parameter.json @@ -8,14 +8,12 @@ "field_order": [ "specification", "value", - "value_based", - "single_reading", + "non_numeric", "column_break_3", - "formula_based_criteria", - "acceptance_formula", "min_value", "max_value", - "mean_value" + "formula_based_criteria", + "acceptance_formula" ], "fields": [ { @@ -27,10 +25,10 @@ "oldfieldtype": "Data", "print_width": "200px", "reqd": 1, - "width": "200px" + "width": "100px" }, { - "depends_on": "eval:(!doc.formula_based_criteria && doc.value_based)", + "depends_on": "eval:(!doc.formula_based_criteria && doc.non_numeric)", "fieldname": "value", "fieldtype": "Data", "in_list_view": 1, @@ -44,10 +42,9 @@ }, { "depends_on": "formula_based_criteria", - "description": "Simple Python formula applied on Reading fields.
    Numeric eg.: reading_1 > 0.2 and reading_1 < 0.5
    \nValue based eg.: reading_value in (\"A\", \"B\", \"C)", + "description": "Simple Python formula applied on Reading fields.
    Numeric eg. 1: reading_1 > 0.2 and reading_1 < 0.5
    \nNumeric eg. 2: mean > 3.5 (mean of populated fields)
    \nValue based eg.: reading_value in (\"A\", \"B\", \"C)", "fieldname": "acceptance_formula", "fieldtype": "Code", - "in_list_view": 1, "label": "Acceptance Criteria Formula" }, { @@ -57,42 +54,32 @@ "label": "Formula Based Criteria" }, { - "default": "0", - "depends_on": "eval:!doc.value_based", - "fieldname": "single_reading", - "fieldtype": "Check", - "label": "Single Reading" - }, - { - "depends_on": "eval:(!doc.formula_based_criteria && !doc.single_reading && !doc.value_based)", - "fieldname": "mean_value", - "fieldtype": "Float", - "label": "Mean Value" - }, - { - "depends_on": "eval:(!doc.formula_based_criteria && !doc.value_based)", + "depends_on": "eval:(!doc.formula_based_criteria && !doc.non_numeric)", "fieldname": "min_value", "fieldtype": "Float", + "in_list_view": 1, "label": "Minimum Value" }, { - "depends_on": "eval:(!doc.formula_based_criteria && !doc.value_based)", + "depends_on": "eval:(!doc.formula_based_criteria && !doc.non_numeric)", "fieldname": "max_value", "fieldtype": "Float", + "in_list_view": 1, "label": "Maximum Value" }, { "default": "0", - "description": "Non-numeric Inspection.", - "fieldname": "value_based", + "fieldname": "non_numeric", "fieldtype": "Check", - "label": "Value Based" + "in_list_view": 1, + "label": "Non-Numeric", + "width": "80px" } ], "idx": 1, "istable": 1, "links": [], - "modified": "2020-12-18 21:03:29.828723", + "modified": "2020-12-21 11:37:55.387677", "modified_by": "Administrator", "module": "Stock", "name": "Item Quality Inspection Parameter", diff --git a/erpnext/stock/doctype/quality_inspection/quality_inspection.py b/erpnext/stock/doctype/quality_inspection/quality_inspection.py index a7a023bcbf3..f582658d871 100644 --- a/erpnext/stock/doctype/quality_inspection/quality_inspection.py +++ b/erpnext/stock/doctype/quality_inspection/quality_inspection.py @@ -79,46 +79,27 @@ class QualityInspection(Document): if reading.formula_based_criteria: self.set_status_based_on_acceptance_formula(reading) else: + # if not formula based check acceptance values set self.set_status_based_on_acceptance_values(reading) def set_status_based_on_acceptance_values(self, reading): - if cint(reading.value_based): + if cint(reading.non_numeric): result = reading.get("reading_value") == reading.get("value") else: # numeric readings - if cint(reading.single_reading): - reading_1 = flt(reading.get("reading_1")) - result = flt(reading.get("min_value")) <= reading_1 <= flt(reading.get("max_value")) - else: - result = self.min_max_criteria_passed(reading) and self.mean_criteria_passed(reading) + result = self.min_max_criteria_passed(reading) reading.status = "Accepted" if result else "Rejected" def min_max_criteria_passed(self, reading): """Determine whether all readings fall in the acceptable range.""" for i in range(1, 11): - reading_field = reading.get("reading_" + str(i)) - if reading_field is not None: - result = flt(reading.get("min_value")) <= flt(reading_field) <= flt(reading.get("max_value")) + reading_value = reading.get("reading_" + str(i)) + if reading_value is not None and reading_value.strip(): + result = flt(reading.get("min_value")) <= flt(reading_value) <= flt(reading.get("max_value")) if not result: return False return True - def mean_criteria_passed(self, reading): - """Determine whether mean of all readings is acceptable.""" - if reading.get("mean_value"): - from statistics import mean - readings_list = [] - - for i in range(1, 11): - reading_value = reading.get("reading_" + str(i)) - if reading_value is not None: - readings_list.append(flt(reading_value)) - - actual_mean = mean(readings_list) if readings_list else 0 - return True if actual_mean == reading.get("mean_value") else False - - return True # no mean value, nothing to check - def set_status_based_on_acceptance_formula(self, reading): if not reading.acceptance_formula: frappe.throw(_("Row #{0}: Acceptance Criteria Formula is required.").format(reading.idx), @@ -141,18 +122,30 @@ class QualityInspection(Document): def get_formula_evaluation_data(self, reading): data = {} - if cint(reading.value_based): + if cint(reading.non_numeric): data = {"reading_value": reading.get("reading_value")} else: # numeric readings - data = {"reading_1": flt(reading.get("reading_1"))} - if not cint(reading.single_reading): - # if multiple numeric readings add all readings to data - for i in range(2, 11): - field = "reading_" + str(i) - data[field] = flt(reading.get(field)) + for i in range(1, 11): + field = "reading_" + str(i) + data[field] = flt(reading.get(field)) + data["mean"] = self.calculate_mean(reading) + return data + def calculate_mean(self, reading): + """Calculate mean of all non-empty readings.""" + from statistics import mean + readings_list = [] + + for i in range(1, 11): + reading_value = reading.get("reading_" + str(i)) + if reading_value is not None and reading_value.strip(): + readings_list.append(flt(reading_value)) + + actual_mean = mean(readings_list) if readings_list else 0 + return actual_mean + @frappe.whitelist() @frappe.validate_and_sanitize_search_inputs def item_query(doctype, txt, searchfield, start, page_len, filters): diff --git a/erpnext/stock/doctype/quality_inspection_reading/quality_inspection_reading.json b/erpnext/stock/doctype/quality_inspection_reading/quality_inspection_reading.json index db95fabee0b..0792f26d2ab 100644 --- a/erpnext/stock/doctype/quality_inspection_reading/quality_inspection_reading.json +++ b/erpnext/stock/doctype/quality_inspection_reading/quality_inspection_reading.json @@ -9,18 +9,15 @@ "specification", "status", "value", - "value_based", + "non_numeric", "column_break_4", - "formula_based_criteria", - "acceptance_formula", "min_value", "max_value", - "mean_value", + "formula_based_criteria", + "acceptance_formula", "section_break_3", "reading_value", "section_break_14", - "single_reading", - "section_break_12", "reading_1", "reading_2", "reading_3", @@ -47,7 +44,7 @@ }, { "columns": 2, - "depends_on": "eval:(!doc.formula_based_criteria && doc.value_based)", + "depends_on": "eval:(!doc.formula_based_criteria && doc.non_numeric)", "fieldname": "value", "fieldtype": "Data", "in_list_view": 1, @@ -66,7 +63,6 @@ }, { "columns": 1, - "depends_on": "eval:!doc.single_reading", "fieldname": "reading_2", "fieldtype": "Data", "in_list_view": 1, @@ -76,7 +72,6 @@ }, { "columns": 1, - "depends_on": "eval:!doc.single_reading", "fieldname": "reading_3", "fieldtype": "Data", "in_list_view": 1, @@ -85,7 +80,6 @@ "oldfieldtype": "Data" }, { - "depends_on": "eval:!doc.single_reading", "fieldname": "reading_4", "fieldtype": "Data", "label": "Reading 4", @@ -93,7 +87,6 @@ "oldfieldtype": "Data" }, { - "depends_on": "eval:!doc.single_reading", "fieldname": "reading_5", "fieldtype": "Data", "label": "Reading 5", @@ -101,7 +94,6 @@ "oldfieldtype": "Data" }, { - "depends_on": "eval:!doc.single_reading", "fieldname": "reading_6", "fieldtype": "Data", "label": "Reading 6", @@ -109,7 +101,6 @@ "oldfieldtype": "Data" }, { - "depends_on": "eval:!doc.single_reading", "fieldname": "reading_7", "fieldtype": "Data", "label": "Reading 7", @@ -117,7 +108,6 @@ "oldfieldtype": "Data" }, { - "depends_on": "eval:!doc.single_reading", "fieldname": "reading_8", "fieldtype": "Data", "label": "Reading 8", @@ -125,7 +115,6 @@ "oldfieldtype": "Data" }, { - "depends_on": "eval:!doc.single_reading", "fieldname": "reading_9", "fieldtype": "Data", "label": "Reading 9", @@ -133,7 +122,6 @@ "oldfieldtype": "Data" }, { - "depends_on": "eval:!doc.single_reading", "fieldname": "reading_10", "fieldtype": "Data", "label": "Reading 10", @@ -152,7 +140,7 @@ "options": "Accepted\nRejected" }, { - "depends_on": "value_based", + "depends_on": "non_numeric", "fieldname": "section_break_3", "fieldtype": "Section Break", "label": "Value Based Inspection" @@ -163,7 +151,7 @@ }, { "depends_on": "formula_based_criteria", - "description": "Simple Python formula applied on Reading fields.
    Numeric eg.: reading_1 > 0.2 and reading_1 < 0.5
    \nValue based eg.: reading_value in (\"A\", \"B\", \"C)", + "description": "Simple Python formula applied on Reading fields.
    Numeric eg. 1: reading_1 > 0.2 and reading_1 < 0.5
    \nNumeric eg. 2: mean > 3.5 (mean of populated fields)
    \nValue based eg.: reading_value in (\"A\", \"B\", \"C)", "fieldname": "acceptance_formula", "fieldtype": "Code", "label": "Acceptance Criteria Formula" @@ -183,61 +171,42 @@ "label": "Formula Based Criteria" }, { - "depends_on": "eval:(!doc.formula_based_criteria && !doc.single_reading && !doc.value_based)", - "fieldname": "mean_value", - "fieldtype": "Float", - "label": "Mean Value" - }, - { - "default": "0", - "fieldname": "single_reading", - "fieldtype": "Check", - "label": "Single Reading" - }, - { - "depends_on": "eval:!doc.value_based", - "fieldname": "section_break_12", - "fieldtype": "Section Break", - "hide_border": 1 - }, - { - "depends_on": "eval:(!doc.formula_based_criteria && !doc.value_based)", + "depends_on": "eval:(!doc.formula_based_criteria && !doc.non_numeric)", "description": "Applied on each reading.", "fieldname": "min_value", "fieldtype": "Float", "label": "Minimum Value" }, { - "depends_on": "eval:(!doc.formula_based_criteria && !doc.value_based)", + "depends_on": "eval:(!doc.formula_based_criteria && !doc.non_numeric)", "description": "Applied on each reading.", "fieldname": "max_value", "fieldtype": "Float", "label": "Maximum Value" }, { - "default": "0", - "description": "Non-numeric Inspection.", - "fieldname": "value_based", - "fieldtype": "Check", - "label": "Value Based" - }, - { - "depends_on": "value_based", + "depends_on": "non_numeric", "fieldname": "reading_value", "fieldtype": "Data", "label": "Reading Value" }, { - "depends_on": "eval:!doc.value_based", + "depends_on": "eval:!doc.non_numeric", "fieldname": "section_break_14", "fieldtype": "Section Break", "label": "Numeric Inspection" + }, + { + "default": "0", + "fieldname": "non_numeric", + "fieldtype": "Check", + "label": "Non-Numeric" } ], "idx": 1, "istable": 1, "links": [], - "modified": "2020-12-18 21:02:04.865777", + "modified": "2020-12-21 11:36:24.885019", "modified_by": "Administrator", "module": "Stock", "name": "Quality Inspection Reading", diff --git a/erpnext/stock/doctype/quality_inspection_template/quality_inspection_template.py b/erpnext/stock/doctype/quality_inspection_template/quality_inspection_template.py index 7dd0febc203..c5a7974a732 100644 --- a/erpnext/stock/doctype/quality_inspection_template/quality_inspection_template.py +++ b/erpnext/stock/doctype/quality_inspection_template/quality_inspection_template.py @@ -14,7 +14,6 @@ def get_template_details(template): return frappe.get_all('Item Quality Inspection Parameter', fields=["specification", "value", "acceptance_formula", - "value_based", "formula_based_criteria", "single_reading", - "min_value", "max_value", "mean_value"], + "non_numeric", "formula_based_criteria", "min_value", "max_value"], filters={'parenttype': 'Quality Inspection Template', 'parent': template}, order_by="idx") \ No newline at end of file From 68f91c96400226254875016d0e0b95bdc3816580 Mon Sep 17 00:00:00 2001 From: marination Date: Mon, 21 Dec 2020 12:24:45 +0530 Subject: [PATCH 195/477] chore: Added tests for new ux - Test for value based inspection - tweaks in test for formula based inspection - tweaks in create_quality_inspection as status in child row is auto set now --- .../test_quality_inspection.py | 59 ++++++++++++++++--- 1 file changed, 50 insertions(+), 9 deletions(-) diff --git a/erpnext/stock/doctype/quality_inspection/test_quality_inspection.py b/erpnext/stock/doctype/quality_inspection/test_quality_inspection.py index 2c40009426e..d0bfb466e05 100644 --- a/erpnext/stock/doctype/quality_inspection/test_quality_inspection.py +++ b/erpnext/stock/doctype/quality_inspection/test_quality_inspection.py @@ -44,24 +44,61 @@ class TestQualityInspection(unittest.TestCase): qa.delete() dn.delete() + def test_value_based_qi_readings(self): + # Test QI based on acceptance values (Non formula) + dn = create_delivery_note(item_code="_Test Item with QA", do_not_submit=True) + readings = [{ + "specification": "Iron Content", # numeric reading + "min_value": 0.1, + "max_value": 0.9, + "reading_1": "0.4" + }, + { + "specification": "Particle Inspection Needed", # non-numeric reading + "non_numeric": 1, + "value": "Yes", + "reading_value": "Yes" + }] + + qa = create_quality_inspection(reference_type="Delivery Note", reference_name=dn.name, + readings=readings, do_not_save=True) + qa.save() + + # status must be auto set as per formula + self.assertEqual(qa.readings[0].status, "Accepted") + self.assertEqual(qa.readings[1].status, "Accepted") + + qa.delete() + dn.delete() + def test_formula_based_qi_readings(self): dn = create_delivery_note(item_code="_Test Item with QA", do_not_submit=True) readings = [{ - "specification": "Iron Content", + "specification": "Iron Content", # numeric reading + "formula_based_criteria": 1, "acceptance_formula": "reading_1 > 0.35 and reading_1 < 0.50", - "reading_1": 0.4 + "reading_1": "0.4" }, { - "specification": "Calcium Content", + "specification": "Calcium Content", # numeric reading + "formula_based_criteria": 1, "acceptance_formula": "reading_1 > 0.20 and reading_1 < 0.50", - "reading_1": 0.7 + "reading_1": "0.7" }, { - "specification": "Mg Content", - "acceptance_formula": "(reading_1 + reading_2 + reading_3) / 3 < 0.9", - "reading_1": 0.5, - "reading_2": 0.7, + "specification": "Mg Content", # numeric reading + "formula_based_criteria": 1, + "acceptance_formula": "mean < 0.9", + "reading_1": "0.5", + "reading_2": "0.7", "reading_3": "random text" # check if random string input causes issues + }, + { + "specification": "Calcium Content", # non-numeric reading + "formula_based_criteria": 1, + "non_numeric": 1, + "acceptance_formula": "reading_value in ('Grade A', 'Grade B', 'Grade C')", + "reading_value": "Grade B" }] qa = create_quality_inspection(reference_type="Delivery Note", reference_name=dn.name, @@ -72,6 +109,7 @@ class TestQualityInspection(unittest.TestCase): self.assertEqual(qa.readings[0].status, "Accepted") self.assertEqual(qa.readings[1].status, "Rejected") self.assertEqual(qa.readings[2].status, "Accepted") + self.assertEqual(qa.readings[3].status, "Accepted") qa.delete() dn.delete() @@ -86,8 +124,11 @@ def create_quality_inspection(**args): qa.item_code = args.item_code or "_Test Item with QA" qa.sample_size = 1 qa.inspected_by = frappe.session.user + qa.status = args.status or "Accepted" - readings = args.readings or {"specification": "Size", "status": args.status} + readings = args.readings or {"specification": "Size", "min_value": 0, "max_value": 10} + if args.status == "Rejected": + readings["reading_1"] = "12" # status is auto set in child on save if isinstance(readings, list): for entry in readings: From 0e222173ea431b46344f7b73866390c15e80106e Mon Sep 17 00:00:00 2001 From: Shivam Mishra Date: Mon, 21 Dec 2020 13:44:03 +0530 Subject: [PATCH 196/477] fix: don't set primary action if workflow is set --- erpnext/payroll/doctype/payroll_entry/payroll_entry.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/payroll/doctype/payroll_entry/payroll_entry.js b/erpnext/payroll/doctype/payroll_entry/payroll_entry.js index cb48abbc363..31abaf40bf2 100644 --- a/erpnext/payroll/doctype/payroll_entry/payroll_entry.js +++ b/erpnext/payroll/doctype/payroll_entry/payroll_entry.js @@ -39,7 +39,7 @@ frappe.ui.form.on('Payroll Entry', { } ).toggleClass('btn-primary', !(frm.doc.employees || []).length); } - if ((frm.doc.employees || []).length) { + if ((frm.doc.employees || []).length && !frappe.model.has_workflow(frm.doctype)) { frm.page.clear_primary_action(); frm.page.set_primary_action(__('Create Salary Slips'), () => { frm.save('Submit').then(()=>{ From eae31f02cc1a5254292b7c621513e70b91d10b22 Mon Sep 17 00:00:00 2001 From: marination Date: Mon, 21 Dec 2020 13:58:44 +0530 Subject: [PATCH 197/477] fix: Sider (missing semi-colons) --- .../doctype/quality_inspection/quality_inspection.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/erpnext/stock/doctype/quality_inspection/quality_inspection.js b/erpnext/stock/doctype/quality_inspection/quality_inspection.js index f0bf9aed802..2ec8a070052 100644 --- a/erpnext/stock/doctype/quality_inspection/quality_inspection.js +++ b/erpnext/stock/doctype/quality_inspection/quality_inspection.js @@ -10,18 +10,18 @@ frappe.ui.form.on("Quality Inspection", { filters: { "item": frm.doc.item_code } - } + }; }); // Serial No based on item_code frm.set_query("item_serial_no", function() { - var filters = {}; + let filters = {}; if (frm.doc.item_code) { filters = { 'item_code': frm.doc.item_code - } + }; } - return { filters: filters } + return { filters: filters }; }); // item code based on GRN/DN @@ -75,4 +75,4 @@ frappe.ui.form.on("Quality Inspection", { }); } }, -}) \ No newline at end of file +}); \ No newline at end of file From 9466e42e7095f7f4ff32230ab7dace6642455ba9 Mon Sep 17 00:00:00 2001 From: pateljannat Date: Mon, 21 Dec 2020 20:52:20 +0530 Subject: [PATCH 198/477] fix: change request modifications --- .../v13_0/update_project_template_tasks.py | 8 +- erpnext/projects/doctype/project/project.py | 51 +++++------ .../projects/doctype/project/test_project.py | 87 ++++++++++--------- .../project_template/project_template.py | 5 +- erpnext/projects/doctype/task/task.json | 4 +- erpnext/projects/doctype/task/test_task.py | 2 +- 6 files changed, 82 insertions(+), 75 deletions(-) diff --git a/erpnext/patches/v13_0/update_project_template_tasks.py b/erpnext/patches/v13_0/update_project_template_tasks.py index 1303efd93fb..26c42592816 100644 --- a/erpnext/patches/v13_0/update_project_template_tasks.py +++ b/erpnext/patches/v13_0/update_project_template_tasks.py @@ -6,7 +6,13 @@ import frappe def execute(): frappe.reload_doc("projects", "doctype", "project_template") - for template_name in frappe.db.sql(""" select name from `tabProject Template` """, as_dict=1): + for template_name in frappe.db.sql(""" + select + name + from + `tabProject Template` """, + as_dict=1): + template = frappe.get_doc("Project Template", template_name.name) replace_tasks = False new_tasks = [] diff --git a/erpnext/projects/doctype/project/project.py b/erpnext/projects/doctype/project/project.py index 13e72fec8a2..2cdfb7af444 100644 --- a/erpnext/projects/doctype/project/project.py +++ b/erpnext/projects/doctype/project/project.py @@ -59,8 +59,8 @@ class Project(Document): for task in template.tasks: template_task_details = frappe.get_doc("Task", task.task) tmp_task_details.append(template_task_details) - project_tasks.append(self.create_task_from_template(template_task_details)) - + task = self.create_task_from_template(template_task_details) + project_tasks.append(task) self.dependency_mapping(tmp_task_details, project_tasks) def create_task_from_template(self, task_details): @@ -75,36 +75,33 @@ class Project(Document): task_weight = task_details.task_weight, type = task_details.type, issue = task_details.issue, - is_group = task_details.is_group, - start = task_details.start, - duration = task_details.duration + is_group = task_details.is_group )).insert() def dependency_mapping(self, template_tasks, project_tasks): - for tmp_task in template_tasks: - prj_task = list(filter(lambda x: x.subject == tmp_task.subject, project_tasks))[0] - prj_task = frappe.get_doc("Task", prj_task.name) - self.check_depends_on_value(tmp_task, prj_task, project_tasks) - self.check_for_parent_tasks(tmp_task, prj_task, project_tasks) + for template_task in template_tasks: + project_task = list(filter(lambda x: x.subject == template_task.subject, project_tasks))[0] + if template_task.get("depends_on") and not project_task.get("depends_on"): + self.check_depends_on_value(template_task, project_task, project_tasks) + if template_task.get("parent_task") and not project_task.get("parent_task"): + self.check_for_parent_tasks(template_task, project_task, project_tasks) - def check_depends_on_value(self, tmp_task, prj_task, project_tasks): - if tmp_task.get("depends_on") and not prj_task.get("depends_on"): - for child_task in tmp_task.get("depends_on"): - child_task_subject = frappe.db.get_value("Task", child_task.task, "subject") - corresponding_prj_task = list(filter(lambda x: x.subject == child_task_subject, project_tasks)) - if len(corresponding_prj_task): - prj_task.append("depends_on",{ - "task": corresponding_prj_task[0].name - }) - prj_task.save() + def check_depends_on_value(self, template_task, project_task, project_tasks): + for child_task in template_task.get("depends_on"): + child_task_subject = frappe.db.get_value("Task", child_task.task, "subject") + corresponding_project_task = list(filter(lambda x: x.subject == child_task_subject, project_tasks)) + if len(corresponding_project_task): + project_task.append("depends_on",{ + "task": corresponding_project_task[0].name + }) + project_task.save() - def check_for_parent_tasks(self, tmp_task, prj_task, project_tasks): - if tmp_task.get("parent_task") and not prj_task.get("parent_task"): - parent_task_subject = frappe.db.get_value("Task", tmp_task.get("parent_task"), "subject") - corresponding_prj_task = list(filter(lambda x: x.subject == parent_task_subject, project_tasks)) - if len(corresponding_prj_task): - prj_task.parent_task = corresponding_prj_task[0].name - prj_task.save() + def check_for_parent_tasks(self, template_task, project_task, project_tasks): + parent_task_subject = frappe.db.get_value("Task", template_task.get("parent_task"), "subject") + corresponding_project_task = list(filter(lambda x: x.subject == parent_task_subject, project_tasks)) + if len(corresponding_project_task): + project_task.parent_task = corresponding_project_task[0].name + project_task.save() def is_row_updated(self, row, existing_task_data, fields): if self.get("__islocal") or not existing_task_data: return True diff --git a/erpnext/projects/doctype/project/test_project.py b/erpnext/projects/doctype/project/test_project.py index ce56a50b4e2..1d2980ce461 100644 --- a/erpnext/projects/doctype/project/test_project.py +++ b/erpnext/projects/doctype/project/test_project.py @@ -17,78 +17,79 @@ class TestProject(unittest.TestCase): """ Test Action: Basic Test of a Project created from template. The template has a single task. """ - frappe.db.sql('delete from tabTask where project = "Test Project with Templ - no parent and dependend tasks"') - frappe.delete_doc('Project', 'Test Project with Templ - no parent and dependend tasks') + project_name = "Test Project with Template - No Parent and Dependend Tasks" + frappe.db.sql(""" delete from tabTask where project = %s """, project_name) + frappe.delete_doc('Project', project_name) - task1 = task_exists("Test Temp Task with no parent and dependency") + task1 = task_exists("Test Template Task with No Parent and Dependency") if not task1: - task1 = create_task(subject="Test Temp Task with no parent and dependency", is_template=1, begin=5, duration=3) + task1 = create_task(subject="Test Template Task with No Parent and Dependency", is_template=1, begin=5, duration=3) - template = make_project_template("Test Project Template - no parent and dependend tasks", [task1]) - project = get_project("Test Project with Templ - no parent and dependend tasks", template) - tasks = frappe.get_all('Task', '*', dict(project=project.name), order_by='creation asc') + template = make_project_template("Test Project Template - No Parent and Dependend Tasks", [task1]) + project = get_project(project_name, template) + tasks = frappe.get_all('Task', ['subject','exp_end_date','depends_on_tasks'], dict(project=project.name), order_by='creation asc') - self.assertEqual(tasks[0].subject, 'Test Temp Task with no parent and dependency') - self.assertEqual(getdate(tasks[0].exp_end_date), calculate_end_date(project, tasks[0])) + self.assertEqual(tasks[0].subject, 'Test Template Task with No Parent and Dependency') + self.assertEqual(getdate(tasks[0].exp_end_date), calculate_end_date(project, 5, 3)) self.assertEqual(len(tasks), 1) def test_project_template_having_parent_child_tasks(self): + project_name = "Test Project with Template - Tasks with Parent-Child Relation" + frappe.db.sql(""" delete from tabTask where project = %s """, project_name) + frappe.delete_doc('Project', project_name) - frappe.db.sql('delete from tabTask where project = "Test Project with Templ - tasks with parent-child"') - frappe.delete_doc('Project', 'Test Project with Templ - tasks with parent-child') - - task1 = task_exists("Test Temp Task parent") + task1 = task_exists("Test Template Task Parent") if not task1: - task1 = create_task(subject="Test Temp Task parent", is_group=1, is_template=1, begin=1, duration=1) + task1 = create_task(subject="Test Template Task Parent", is_group=1, is_template=1, begin=1, duration=1) - task2 = task_exists("Test Temp Task child 1") + task2 = task_exists("Test Template Task Child 1") if not task2: - task2 = create_task(subject="Test Temp Task child 1", parent_task=task1.name, is_template=1, begin=1, duration=3) + task2 = create_task(subject="Test Template Task Child 1", parent_task=task1.name, is_template=1, begin=1, duration=3) - task3 = task_exists("Test Temp Task child 2") + task3 = task_exists("Test Template Task Child 2") if not task3: - task3 = create_task(subject="Test Temp Task child 2", parent_task=task1.name, is_template=1, begin=2, duration=3) + task3 = create_task(subject="Test Template Task Child 2", parent_task=task1.name, is_template=1, begin=2, duration=3) - template = make_project_template("Test Project Template - tasks with parent-child", [task1, task2, task3]) - project = get_project("Test Project with Templ - tasks with parent-child", template) - tasks = frappe.get_all('Task', '*', dict(project=project.name), order_by='creation asc') + template = make_project_template("Test Project Template - Tasks with Parent-Child Relation", [task1, task2, task3]) + project = get_project(project_name, template) + tasks = frappe.get_all('Task', ['subject','exp_end_date','depends_on_tasks', 'name'], dict(project=project.name), order_by='creation asc') - self.assertEqual(tasks[0].subject, 'Test Temp Task parent') - self.assertEqual(getdate(tasks[0].exp_end_date), calculate_end_date(project, tasks[0])) + self.assertEqual(tasks[0].subject, 'Test Template Task Parent') + self.assertEqual(getdate(tasks[0].exp_end_date), calculate_end_date(project, 1, 1)) - self.assertEqual(tasks[1].subject, 'Test Temp Task child 1') - self.assertEqual(getdate(tasks[1].exp_end_date), calculate_end_date(project, tasks[1])) + self.assertEqual(tasks[1].subject, 'Test Template Task Child 1') + self.assertEqual(getdate(tasks[1].exp_end_date), calculate_end_date(project, 1, 3)) self.assertEqual(tasks[1].parent_task, tasks[0].name) - self.assertEqual(tasks[2].subject, 'Test Temp Task child 2') - self.assertEqual(getdate(tasks[2].exp_end_date), calculate_end_date(project, tasks[2])) + self.assertEqual(tasks[2].subject, 'Test Template Task Child 2') + self.assertEqual(getdate(tasks[2].exp_end_date), calculate_end_date(project, 2, 3)) self.assertEqual(tasks[2].parent_task, tasks[0].name) self.assertEqual(len(tasks), 3) def test_project_template_having_dependent_tasks(self): + project_name = "Test Project with Template - Dependent Tasks" + frappe.db.sql(""" delete from tabTask where project = %s """, project_name) + frappe.delete_doc('Project', project_name) - frappe.db.sql('delete from tabTask where project = "Test Project with Templ - dependent tasks"') - frappe.delete_doc('Project', 'Test Project with Templ - dependent tasks') - - task1 = task_exists("Test Temp Task for dependency") + task1 = task_exists("Test Template Task for Dependency") if not task1: - task1 = create_task(subject="Test Temp Task for dependency", is_template=1, begin=3, duration=1) + task1 = create_task(subject="Test Template Task for Dependency", is_template=1, begin=3, duration=1) - task2 = task_exists("Test Temp Task with dependency") + task2 = task_exists("Test Template Task with Dependency") if not task2: - task2 = create_task(subject="Test Temp Task with dependency", depends_on=task1.name, is_template=1, begin=2, duration=2) + task2 = create_task(subject="Test Template Task with Dependency", depends_on=task1.name, is_template=1, begin=2, duration=2) - template = make_project_template("Test Project with Templ - dependent tasks", [task1, task2]) - project = get_project("Test Project with Templ - dependent tasks", template) - tasks = frappe.get_all('Task', '*', dict(project=project.name), order_by='creation asc') + template = make_project_template("Test Project with Template - Dependent Tasks", [task1, task2]) + project = get_project(project_name, template) + tasks = frappe.get_all('Task', ['subject','exp_end_date','depends_on_tasks', 'name'], dict(project=project.name), order_by='creation asc') - self.assertEqual(tasks[1].subject, 'Test Temp Task with dependency') - self.assertEqual(getdate(tasks[1].exp_end_date), calculate_end_date(project, tasks[1])) + self.assertEqual(tasks[1].subject, 'Test Template Task with Dependency') + self.assertEqual(getdate(tasks[1].exp_end_date), calculate_end_date(project, 2, 2)) self.assertTrue(tasks[1].depends_on_tasks.find(tasks[0].name) >= 0 ) - self.assertEqual(tasks[0].subject, 'Test Temp Task for dependency') - self.assertEqual(getdate(tasks[0].exp_end_date), calculate_end_date(project, tasks[0]) ) + self.assertEqual(tasks[0].subject, 'Test Template Task for Dependency') + self.assertEqual(getdate(tasks[0].exp_end_date), calculate_end_date(project, 3, 1) ) self.assertEqual(len(tasks), 2) @@ -129,5 +130,5 @@ def task_exists(subject): return False return frappe.get_doc("Task", result[0].name) -def calculate_end_date(project, task): - return getdate(add_days(project.expected_start_date, task.start + task.duration)) \ No newline at end of file +def calculate_end_date(project, start, duration): + return getdate(add_days(project.expected_start_date, start + duration)) \ No newline at end of file diff --git a/erpnext/projects/doctype/project_template/project_template.py b/erpnext/projects/doctype/project_template/project_template.py index 1beebf7a258..aace40240c4 100644 --- a/erpnext/projects/doctype/project_template/project_template.py +++ b/erpnext/projects/doctype/project_template/project_template.py @@ -6,6 +6,7 @@ from __future__ import unicode_literals import frappe from frappe.model.document import Document from frappe import _ +from frappe.utils import get_link_to_form class ProjectTemplate(Document): @@ -18,8 +19,8 @@ class ProjectTemplate(Document): if task_details.depends_on: for dependency_task in task_details.depends_on: if not self.check_dependent_task_presence(dependency_task.task): - task_details_format = """{0}""".format(task_details.name) - dependency_task_format = """{0}""".format(dependency_task.task) + task_details_format = get_link_to_form("Task",task_details.name) + dependency_task_format = get_link_to_form("Task", dependency_task.task) frappe.throw(_("Task {0} depends on Task {1}. Please add Task {1} to the Tasks list.").format(frappe.bold(task_details_format), frappe.bold(dependency_task_format))) def check_dependent_task_presence(self, task): diff --git a/erpnext/projects/doctype/task/task.json b/erpnext/projects/doctype/task/task.json index a9e3d9bc0fe..bb55256f7d9 100644 --- a/erpnext/projects/doctype/task/task.json +++ b/erpnext/projects/doctype/task/task.json @@ -371,11 +371,13 @@ "label": "Is Template" }, { + "depends_on": "is_template", "fieldname": "start", "fieldtype": "Int", "label": "Begin On (Days)" }, { + "depends_on": "is_template", "fieldname": "duration", "fieldtype": "Int", "label": "Duration (Days)" @@ -386,7 +388,7 @@ "is_tree": 1, "links": [], "max_attachments": 5, - "modified": "2020-12-07 13:26:53.614689", + "modified": "2020-12-21 11:59:24.196834", "modified_by": "Administrator", "module": "Projects", "name": "Task", diff --git a/erpnext/projects/doctype/task/test_task.py b/erpnext/projects/doctype/task/test_task.py index aded78b8574..25714f8cde3 100644 --- a/erpnext/projects/doctype/task/test_task.py +++ b/erpnext/projects/doctype/task/test_task.py @@ -104,7 +104,7 @@ def create_task(subject, start=None, end=None, depends_on=None, project=None, pa task.subject = subject task.exp_start_date = start or nowdate() task.exp_end_date = end or nowdate() - task.project = project or "_Test Project" + task.project = project or None if is_template else "_Test Project" task.is_template = is_template task.start = begin task.duration = duration From fa102e4713be1eadc6b873c0f94ad3a44fe74c31 Mon Sep 17 00:00:00 2001 From: Shivam Mishra Date: Tue, 17 Nov 2020 16:34:05 +0530 Subject: [PATCH 199/477] feat: add templates for online store --- .../shopping_cart/web_template/__init__.py | 0 .../web_template/hero_slider/__init__.py | 0 .../web_template/hero_slider/hero_slider.html | 0 .../web_template/hero_slider/hero_slider.json | 142 ++++++++ .../web_template/item_card_group/__init__.py | 0 .../item_card_group/item_card_group.html | 0 .../item_card_group/item_card_group.json | 312 ++++++++++++++++++ .../web_template/product_card/__init__.py | 0 .../product_card/product_card.html | 0 .../product_card/product_card.json | 33 ++ .../product_category_cards/__init__.py | 0 .../product_category_cards.html | 0 .../product_category_cards.json | 95 ++++++ 13 files changed, 582 insertions(+) create mode 100644 erpnext/shopping_cart/web_template/__init__.py create mode 100644 erpnext/shopping_cart/web_template/hero_slider/__init__.py create mode 100644 erpnext/shopping_cart/web_template/hero_slider/hero_slider.html create mode 100644 erpnext/shopping_cart/web_template/hero_slider/hero_slider.json create mode 100644 erpnext/shopping_cart/web_template/item_card_group/__init__.py create mode 100644 erpnext/shopping_cart/web_template/item_card_group/item_card_group.html create mode 100644 erpnext/shopping_cart/web_template/item_card_group/item_card_group.json create mode 100644 erpnext/shopping_cart/web_template/product_card/__init__.py create mode 100644 erpnext/shopping_cart/web_template/product_card/product_card.html create mode 100644 erpnext/shopping_cart/web_template/product_card/product_card.json create mode 100644 erpnext/shopping_cart/web_template/product_category_cards/__init__.py create mode 100644 erpnext/shopping_cart/web_template/product_category_cards/product_category_cards.html create mode 100644 erpnext/shopping_cart/web_template/product_category_cards/product_category_cards.json diff --git a/erpnext/shopping_cart/web_template/__init__.py b/erpnext/shopping_cart/web_template/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/erpnext/shopping_cart/web_template/hero_slider/__init__.py b/erpnext/shopping_cart/web_template/hero_slider/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/erpnext/shopping_cart/web_template/hero_slider/hero_slider.html b/erpnext/shopping_cart/web_template/hero_slider/hero_slider.html new file mode 100644 index 00000000000..e69de29bb2d diff --git a/erpnext/shopping_cart/web_template/hero_slider/hero_slider.json b/erpnext/shopping_cart/web_template/hero_slider/hero_slider.json new file mode 100644 index 00000000000..a8ce2cd3cbb --- /dev/null +++ b/erpnext/shopping_cart/web_template/hero_slider/hero_slider.json @@ -0,0 +1,142 @@ +{ + "__unsaved": 1, + "creation": "2020-11-17 15:21:51.207221", + "docstatus": 0, + "doctype": "Web Template", + "fields": [ + { + "__unsaved": 1, + "fieldname": "slide_1_image", + "fieldtype": "Attach Image", + "label": "Image", + "reqd": 0 + }, + { + "__unsaved": 1, + "fieldname": "slide_1_title", + "fieldtype": "Data", + "label": "Title", + "reqd": 0 + }, + { + "__unsaved": 1, + "fieldname": "slide_1_subtitle", + "fieldtype": "Data", + "label": "Subtitle", + "reqd": 0 + }, + { + "__unsaved": 1, + "fieldname": "slide_1_primary_action_label", + "fieldtype": "Data", + "label": "Primary Action Label", + "reqd": 0 + }, + { + "__unsaved": 1, + "fieldname": "slide_1_primary_action", + "fieldtype": "Data", + "label": "Primary Action", + "reqd": 0 + }, + { + "__unsaved": 1, + "fieldname": "slide_2", + "fieldtype": "Section Break", + "label": "Slide 2", + "reqd": 0 + }, + { + "__unsaved": 1, + "fieldname": "slide_2_image", + "fieldtype": "Attach Image", + "label": "Image ", + "reqd": 0 + }, + { + "__unsaved": 1, + "fieldname": "slide_2_title", + "fieldtype": "Data", + "label": "Title ", + "reqd": 0 + }, + { + "__unsaved": 1, + "fieldname": "slide_2_subtitle", + "fieldtype": "Data", + "label": "Subtitle ", + "reqd": 0 + }, + { + "__unsaved": 1, + "fieldname": "slide_2_primary_action_label", + "fieldtype": "Data", + "label": "Primary Action Label ", + "reqd": 0 + }, + { + "__unsaved": 1, + "fieldname": "slide_2_primary_action", + "fieldtype": "Data", + "label": "Primary Action ", + "reqd": 0 + }, + { + "__islocal": 1, + "__unsaved": 1, + "fieldname": "slide_3", + "fieldtype": "Section Break", + "label": "Slide 3", + "reqd": 0 + }, + { + "__islocal": 1, + "__unsaved": 1, + "fieldname": "slide_3_image", + "fieldtype": "Attach Image", + "label": "Image ", + "reqd": 0 + }, + { + "__islocal": 1, + "__unsaved": 1, + "fieldname": "slide_3_title", + "fieldtype": "Data", + "label": "Title ", + "reqd": 0 + }, + { + "__islocal": 1, + "__unsaved": 1, + "fieldname": "slide_3_subtitle", + "fieldtype": "Data", + "label": "Subtitle ", + "reqd": 0 + }, + { + "__islocal": 1, + "__unsaved": 1, + "fieldname": "slide_3_primary_action_label", + "fieldtype": "Data", + "label": "Primary Action Label ", + "reqd": 0 + }, + { + "__islocal": 1, + "__unsaved": 1, + "fieldname": "slide_3_primary_action", + "fieldtype": "Data", + "label": "Primary Action ", + "reqd": 0 + } + ], + "idx": 0, + "modified": "2020-11-17 15:23:48.584868", + "modified_by": "Administrator", + "module": "Shopping Cart", + "name": "Hero Slider", + "owner": "Administrator", + "standard": 1, + "template": "", + "type": "Section" +} \ No newline at end of file diff --git a/erpnext/shopping_cart/web_template/item_card_group/__init__.py b/erpnext/shopping_cart/web_template/item_card_group/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/erpnext/shopping_cart/web_template/item_card_group/item_card_group.html b/erpnext/shopping_cart/web_template/item_card_group/item_card_group.html new file mode 100644 index 00000000000..e69de29bb2d diff --git a/erpnext/shopping_cart/web_template/item_card_group/item_card_group.json b/erpnext/shopping_cart/web_template/item_card_group/item_card_group.json new file mode 100644 index 00000000000..f1a70a99adb --- /dev/null +++ b/erpnext/shopping_cart/web_template/item_card_group/item_card_group.json @@ -0,0 +1,312 @@ +{ + "__unsaved": 1, + "creation": "2020-11-17 15:35:05.285322", + "docstatus": 0, + "doctype": "Web Template", + "fields": [ + { + "fieldname": "title", + "fieldtype": "Data", + "label": "Title", + "reqd": 1 + }, + { + "fieldname": "subtitle", + "fieldtype": "Data", + "label": "Subtitle", + "reqd": 0 + }, + { + "fieldname": "card_1", + "fieldtype": "Section Break", + "label": "Card 1", + "reqd": 0 + }, + { + "fieldname": "card_1_item", + "fieldtype": "Link", + "label": "Item", + "options": "Item", + "reqd": 0 + }, + { + "fieldname": "card_1_featured", + "fieldtype": "Check", + "label": "Featured", + "reqd": 0 + }, + { + "__islocal": 1, + "__unsaved": 1, + "fieldname": "card_2", + "fieldtype": "Section Break", + "label": "Card 2", + "reqd": 0 + }, + { + "__islocal": 1, + "__unsaved": 1, + "fieldname": "card_2_item", + "fieldtype": "Link", + "label": "Item", + "reqd": 0 + }, + { + "__islocal": 1, + "__unsaved": 1, + "fieldname": "card_2_featured", + "fieldtype": "Check", + "label": "Featured", + "reqd": 0 + }, + { + "__islocal": 1, + "__unsaved": 1, + "fieldname": "card_3", + "fieldtype": "Section Break", + "label": "Card 3", + "reqd": 0 + }, + { + "__islocal": 1, + "__unsaved": 1, + "fieldname": "card_3_item", + "fieldtype": "Link", + "label": "Item", + "reqd": 0 + }, + { + "__islocal": 1, + "__unsaved": 1, + "fieldname": "card_3_featured", + "fieldtype": "Check", + "label": "Featured", + "reqd": 0 + }, + { + "__islocal": 1, + "__unsaved": 1, + "fieldname": "card_4", + "fieldtype": "Section Break", + "label": "Card 4", + "reqd": 0 + }, + { + "__islocal": 1, + "__unsaved": 1, + "fieldname": "card_4_item", + "fieldtype": "Link", + "label": "Item", + "reqd": 0 + }, + { + "__islocal": 1, + "__unsaved": 1, + "fieldname": "card_4_featured", + "fieldtype": "Check", + "label": "Featured", + "reqd": 0 + }, + { + "__islocal": 1, + "__unsaved": 1, + "fieldname": "card_5", + "fieldtype": "Section Break", + "label": "Card 5", + "reqd": 0 + }, + { + "__islocal": 1, + "__unsaved": 1, + "fieldname": "card_5_item", + "fieldtype": "Link", + "label": "Item", + "reqd": 0 + }, + { + "__islocal": 1, + "__unsaved": 1, + "fieldname": "card_5_featured", + "fieldtype": "Check", + "label": "Featured", + "reqd": 0 + }, + { + "__islocal": 1, + "__unsaved": 1, + "fieldname": "card_6", + "fieldtype": "Section Break", + "label": "Card 6", + "reqd": 0 + }, + { + "__islocal": 1, + "__unsaved": 1, + "fieldname": "card_6_item", + "fieldtype": "Link", + "label": "Item", + "reqd": 0 + }, + { + "__islocal": 1, + "__unsaved": 1, + "fieldname": "card_6_featured", + "fieldtype": "Check", + "label": "Featured", + "reqd": 0 + }, + { + "__islocal": 1, + "__unsaved": 1, + "fieldname": "card_7", + "fieldtype": "Section Break", + "label": "Card 7", + "reqd": 0 + }, + { + "__islocal": 1, + "__unsaved": 1, + "fieldname": "card_7_item", + "fieldtype": "Link", + "label": "Item", + "reqd": 0 + }, + { + "__islocal": 1, + "__unsaved": 1, + "fieldname": "card_7_featured", + "fieldtype": "Check", + "label": "Featured", + "reqd": 0 + }, + { + "__islocal": 1, + "__unsaved": 1, + "fieldname": "card_8", + "fieldtype": "Section Break", + "label": "Card 8", + "reqd": 0 + }, + { + "__islocal": 1, + "__unsaved": 1, + "fieldname": "card_8_item", + "fieldtype": "Link", + "label": "Item", + "reqd": 0 + }, + { + "__islocal": 1, + "__unsaved": 1, + "fieldname": "card_8_featured", + "fieldtype": "Check", + "label": "Featured", + "reqd": 0 + }, + { + "__islocal": 1, + "__unsaved": 1, + "fieldname": "card_9", + "fieldtype": "Section Break", + "label": "Card 9", + "reqd": 0 + }, + { + "__islocal": 1, + "__unsaved": 1, + "fieldname": "card_9_item", + "fieldtype": "Link", + "label": "Item", + "reqd": 0 + }, + { + "__islocal": 1, + "__unsaved": 1, + "fieldname": "card_9_featured", + "fieldtype": "Check", + "label": "Featured", + "reqd": 0 + }, + { + "__islocal": 1, + "__unsaved": 1, + "fieldname": "card_10", + "fieldtype": "Section Break", + "label": "Card 10", + "reqd": 0 + }, + { + "__islocal": 1, + "__unsaved": 1, + "fieldname": "card_10_item", + "fieldtype": "Link", + "label": "Item", + "reqd": 0 + }, + { + "__islocal": 1, + "__unsaved": 1, + "fieldname": "card_10_featured", + "fieldtype": "Check", + "label": "Featured", + "reqd": 0 + }, + { + "__islocal": 1, + "__unsaved": 1, + "fieldname": "card_11", + "fieldtype": "Section Break", + "label": "Card 11", + "reqd": 0 + }, + { + "__islocal": 1, + "__unsaved": 1, + "fieldname": "card_11_item", + "fieldtype": "Link", + "label": "Item", + "reqd": 0 + }, + { + "__islocal": 1, + "__unsaved": 1, + "fieldname": "card_11_featured", + "fieldtype": "Check", + "label": "Featured", + "reqd": 0 + }, + { + "__islocal": 1, + "__unsaved": 1, + "fieldname": "card_12", + "fieldtype": "Section Break", + "label": "Card 12", + "reqd": 0 + }, + { + "__islocal": 1, + "__unsaved": 1, + "fieldname": "card_12_item", + "fieldtype": "Link", + "label": "Item", + "reqd": 0 + }, + { + "__islocal": 1, + "__unsaved": 1, + "fieldname": "card_12_featured", + "fieldtype": "Check", + "label": "Featured", + "reqd": 0 + } + ], + "idx": 0, + "modified": "2020-11-17 16:37:46.325181", + "modified_by": "Administrator", + "module": "Shopping Cart", + "name": "Item Card Group", + "owner": "Administrator", + "standard": 1, + "template": "", + "type": "Section" +} \ No newline at end of file diff --git a/erpnext/shopping_cart/web_template/product_card/__init__.py b/erpnext/shopping_cart/web_template/product_card/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/erpnext/shopping_cart/web_template/product_card/product_card.html b/erpnext/shopping_cart/web_template/product_card/product_card.html new file mode 100644 index 00000000000..e69de29bb2d diff --git a/erpnext/shopping_cart/web_template/product_card/product_card.json b/erpnext/shopping_cart/web_template/product_card/product_card.json new file mode 100644 index 00000000000..1059c1b2519 --- /dev/null +++ b/erpnext/shopping_cart/web_template/product_card/product_card.json @@ -0,0 +1,33 @@ +{ + "__unsaved": 1, + "creation": "2020-11-17 15:28:47.809342", + "docstatus": 0, + "doctype": "Web Template", + "fields": [ + { + "__unsaved": 1, + "fieldname": "item", + "fieldtype": "Link", + "label": "Item", + "options": "Item", + "reqd": 0 + }, + { + "__unsaved": 1, + "fieldname": "featured", + "fieldtype": "Check", + "label": "Featured", + "options": "", + "reqd": 0 + } + ], + "idx": 0, + "modified": "2020-11-17 15:33:34.982515", + "modified_by": "Administrator", + "module": "Shopping Cart", + "name": "Product Card", + "owner": "Administrator", + "standard": 1, + "template": "", + "type": "Component" +} \ No newline at end of file diff --git a/erpnext/shopping_cart/web_template/product_category_cards/__init__.py b/erpnext/shopping_cart/web_template/product_category_cards/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/erpnext/shopping_cart/web_template/product_category_cards/product_category_cards.html b/erpnext/shopping_cart/web_template/product_category_cards/product_category_cards.html new file mode 100644 index 00000000000..e69de29bb2d diff --git a/erpnext/shopping_cart/web_template/product_category_cards/product_category_cards.json b/erpnext/shopping_cart/web_template/product_category_cards/product_category_cards.json new file mode 100644 index 00000000000..1a3143c2098 --- /dev/null +++ b/erpnext/shopping_cart/web_template/product_category_cards/product_category_cards.json @@ -0,0 +1,95 @@ +{ + "__unsaved": 1, + "creation": "2020-11-17 15:25:50.855934", + "docstatus": 0, + "doctype": "Web Template", + "fields": [ + { + "__unsaved": 1, + "fieldname": "title", + "fieldtype": "Data", + "label": "Title", + "reqd": 1 + }, + { + "__unsaved": 1, + "fieldname": "subtitle", + "fieldtype": "Data", + "label": "Subtitle", + "reqd": 0 + }, + { + "__unsaved": 1, + "fieldname": "category_1_group", + "fieldtype": "Link", + "label": "Item Group", + "options": "Item Group", + "reqd": 0 + }, + { + "__unsaved": 1, + "fieldname": "category_2_group", + "fieldtype": "Link", + "label": "Item Group", + "options": "Item Group", + "reqd": 0 + }, + { + "__unsaved": 1, + "fieldname": "category_3_group", + "fieldtype": "Link", + "label": "Item Group", + "options": "Item Group", + "reqd": 0 + }, + { + "__unsaved": 1, + "fieldname": "category_4_group", + "fieldtype": "Link", + "label": "Item Group", + "options": "Item Group", + "reqd": 0 + }, + { + "__unsaved": 1, + "fieldname": "category_5_group", + "fieldtype": "Link", + "label": "Item Group", + "options": "Item Group", + "reqd": 0 + }, + { + "__unsaved": 1, + "fieldname": "category_6_group", + "fieldtype": "Link", + "label": "Item Group", + "options": "Item Group", + "reqd": 0 + }, + { + "__unsaved": 1, + "fieldname": "category_7_group", + "fieldtype": "Link", + "label": "Item Group", + "options": "Item Group", + "reqd": 0 + }, + { + "__unsaved": 1, + "fieldname": "category_8_group", + "fieldtype": "Link", + "label": "Item Group", + "options": "Item Group", + "reqd": 0 + } + ], + "idx": 0, + "modified": "2020-11-17 15:27:36.250460", + "modified_by": "Administrator", + "module": "Shopping Cart", + "name": "Product Category Cards", + "owner": "Administrator", + "standard": 1, + "template": "", + "type": "Section" +} \ No newline at end of file From 09c8aaa87aa40a1a7dc287cddcfb2613938f8446 Mon Sep 17 00:00:00 2001 From: Shivam Mishra Date: Wed, 18 Nov 2020 17:09:45 +0530 Subject: [PATCH 200/477] feat: add slider template --- .../web_template/hero_slider/hero_slider.html | 112 +++++++++ .../web_template/hero_slider/hero_slider.json | 230 ++++++++++++++++-- 2 files changed, 323 insertions(+), 19 deletions(-) diff --git a/erpnext/shopping_cart/web_template/hero_slider/hero_slider.html b/erpnext/shopping_cart/web_template/hero_slider/hero_slider.html index e69de29bb2d..e8b79743ab3 100644 --- a/erpnext/shopping_cart/web_template/hero_slider/hero_slider.html +++ b/erpnext/shopping_cart/web_template/hero_slider/hero_slider.html @@ -0,0 +1,112 @@ +{%- macro slide(image, title, subtitle, action, label, index, align="Left", theme="Dark") -%} +{%- set align_class = resolve_class({ + 'text-right': align == 'Right', + 'text-centre': align == 'Center', + 'text-left': align == 'Left', +}) -%} + +{%- set heading_class = resolve_class({ + 'text-white': theme == 'Dark', + '': theme == 'Light', +}) -%} + +{%- endmacro -%} + + + + + + \ No newline at end of file diff --git a/erpnext/shopping_cart/web_template/hero_slider/hero_slider.json b/erpnext/shopping_cart/web_template/hero_slider/hero_slider.json index a8ce2cd3cbb..496fc7995e2 100644 --- a/erpnext/shopping_cart/web_template/hero_slider/hero_slider.json +++ b/erpnext/shopping_cart/web_template/hero_slider/hero_slider.json @@ -5,35 +5,56 @@ "doctype": "Web Template", "fields": [ { - "__unsaved": 1, + "fieldname": "slider_name", + "fieldtype": "Data", + "label": "Slider Name", + "reqd": 1 + }, + { + "default": "1", + "fieldname": "show_indicators", + "fieldtype": "Check", + "label": "Show Indicators", + "reqd": 0 + }, + { + "default": "1", + "fieldname": "show_controls", + "fieldtype": "Check", + "label": "Show Controls", + "reqd": 0 + }, + { + "fieldname": "slide_1", + "fieldtype": "Section Break", + "label": "Slide 1", + "reqd": 0 + }, + { "fieldname": "slide_1_image", "fieldtype": "Attach Image", "label": "Image", "reqd": 0 }, { - "__unsaved": 1, "fieldname": "slide_1_title", "fieldtype": "Data", "label": "Title", "reqd": 0 }, { - "__unsaved": 1, "fieldname": "slide_1_subtitle", - "fieldtype": "Data", + "fieldtype": "Small Text", "label": "Subtitle", "reqd": 0 }, { - "__unsaved": 1, "fieldname": "slide_1_primary_action_label", "fieldtype": "Data", "label": "Primary Action Label", "reqd": 0 }, { - "__unsaved": 1, "fieldname": "slide_1_primary_action", "fieldtype": "Data", "label": "Primary Action", @@ -41,46 +62,73 @@ }, { "__unsaved": 1, + "fieldname": "slide_1_content_align", + "fieldtype": "Select", + "label": "Content Align", + "options": "Left\nCentre\nRight", + "reqd": 0 + }, + { + "__unsaved": 1, + "fieldname": "slide_1_theme", + "fieldtype": "Select", + "label": "Slide Theme", + "options": "Dark\nLight", + "reqd": 0 + }, + { "fieldname": "slide_2", "fieldtype": "Section Break", "label": "Slide 2", "reqd": 0 }, { - "__unsaved": 1, "fieldname": "slide_2_image", "fieldtype": "Attach Image", "label": "Image ", "reqd": 0 }, { - "__unsaved": 1, "fieldname": "slide_2_title", "fieldtype": "Data", "label": "Title ", "reqd": 0 }, { - "__unsaved": 1, "fieldname": "slide_2_subtitle", - "fieldtype": "Data", + "fieldtype": "Small Text", "label": "Subtitle ", "reqd": 0 }, { - "__unsaved": 1, "fieldname": "slide_2_primary_action_label", "fieldtype": "Data", "label": "Primary Action Label ", "reqd": 0 }, { - "__unsaved": 1, "fieldname": "slide_2_primary_action", "fieldtype": "Data", "label": "Primary Action ", "reqd": 0 }, + { + "__unsaved": 1, + "default": "Left", + "fieldname": "slide_2_content_align", + "fieldtype": "Select", + "label": "Content Align", + "options": "Left\nCentre\nRight", + "reqd": 0 + }, + { + "__unsaved": 1, + "fieldname": "slide_2_theme", + "fieldtype": "Select", + "label": "Slide Theme", + "options": "Dark\nLight", + "reqd": 0 + }, { "__islocal": 1, "__unsaved": 1, @@ -94,7 +142,7 @@ "__unsaved": 1, "fieldname": "slide_3_image", "fieldtype": "Attach Image", - "label": "Image ", + "label": "Image", "reqd": 0 }, { @@ -102,15 +150,15 @@ "__unsaved": 1, "fieldname": "slide_3_title", "fieldtype": "Data", - "label": "Title ", + "label": "Title", "reqd": 0 }, { "__islocal": 1, "__unsaved": 1, "fieldname": "slide_3_subtitle", - "fieldtype": "Data", - "label": "Subtitle ", + "fieldtype": "Small Text", + "label": "Subtitle", "reqd": 0 }, { @@ -118,7 +166,7 @@ "__unsaved": 1, "fieldname": "slide_3_primary_action_label", "fieldtype": "Data", - "label": "Primary Action Label ", + "label": "Primary Action Label", "reqd": 0 }, { @@ -126,12 +174,156 @@ "__unsaved": 1, "fieldname": "slide_3_primary_action", "fieldtype": "Data", - "label": "Primary Action ", + "label": "Primary Action", + "reqd": 0 + }, + { + "__islocal": 1, + "__unsaved": 1, + "fieldname": "slide_3_content_align", + "fieldtype": "Select", + "label": "Content Align", + "reqd": 0 + }, + { + "__islocal": 1, + "__unsaved": 1, + "fieldname": "slide_3_theme", + "fieldtype": "Select", + "label": "Slide Theme", + "reqd": 0 + }, + { + "__islocal": 1, + "__unsaved": 1, + "fieldname": "slide_4", + "fieldtype": "Section Break", + "label": "Slide 4", + "reqd": 0 + }, + { + "__islocal": 1, + "__unsaved": 1, + "fieldname": "slide_4_image", + "fieldtype": "Attach Image", + "label": "Image", + "reqd": 0 + }, + { + "__islocal": 1, + "__unsaved": 1, + "fieldname": "slide_4_title", + "fieldtype": "Data", + "label": "Title", + "reqd": 0 + }, + { + "__islocal": 1, + "__unsaved": 1, + "fieldname": "slide_4_subtitle", + "fieldtype": "Small Text", + "label": "Subtitle", + "reqd": 0 + }, + { + "__islocal": 1, + "__unsaved": 1, + "fieldname": "slide_4_primary_action_label", + "fieldtype": "Data", + "label": "Primary Action Label", + "reqd": 0 + }, + { + "__islocal": 1, + "__unsaved": 1, + "fieldname": "slide_4_primary_action", + "fieldtype": "Data", + "label": "Primary Action", + "reqd": 0 + }, + { + "__islocal": 1, + "__unsaved": 1, + "fieldname": "slide_4_content_align", + "fieldtype": "Select", + "label": "Content Align", + "reqd": 0 + }, + { + "__islocal": 1, + "__unsaved": 1, + "fieldname": "slide_4_theme", + "fieldtype": "Select", + "label": "Slide Theme", + "reqd": 0 + }, + { + "__islocal": 1, + "__unsaved": 1, + "fieldname": "slide_5", + "fieldtype": "Section Break", + "label": "Slide 5", + "reqd": 0 + }, + { + "__islocal": 1, + "__unsaved": 1, + "fieldname": "slide_5_image", + "fieldtype": "Attach Image", + "label": "Image", + "reqd": 0 + }, + { + "__islocal": 1, + "__unsaved": 1, + "fieldname": "slide_5_title", + "fieldtype": "Data", + "label": "Title", + "reqd": 0 + }, + { + "__islocal": 1, + "__unsaved": 1, + "fieldname": "slide_5_subtitle", + "fieldtype": "Small Text", + "label": "Subtitle", + "reqd": 0 + }, + { + "__islocal": 1, + "__unsaved": 1, + "fieldname": "slide_5_primary_action_label", + "fieldtype": "Data", + "label": "Primary Action Label", + "reqd": 0 + }, + { + "__islocal": 1, + "__unsaved": 1, + "fieldname": "slide_5_primary_action", + "fieldtype": "Data", + "label": "Primary Action", + "reqd": 0 + }, + { + "__islocal": 1, + "__unsaved": 1, + "fieldname": "slide_5_content_align", + "fieldtype": "Select", + "label": "Content Align", + "reqd": 0 + }, + { + "__islocal": 1, + "__unsaved": 1, + "fieldname": "slide_5_theme", + "fieldtype": "Select", + "label": "Slide Theme", "reqd": 0 } ], "idx": 0, - "modified": "2020-11-17 15:23:48.584868", + "modified": "2020-11-18 17:09:31.323198", "modified_by": "Administrator", "module": "Shopping Cart", "name": "Hero Slider", From e40926b4cc3fb9c678fd901007cc84f6881b1f43 Mon Sep 17 00:00:00 2001 From: Shivam Mishra Date: Wed, 18 Nov 2020 17:10:02 +0530 Subject: [PATCH 201/477] fix: don't use primary action for create --- erpnext/stock/doctype/item/item.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/stock/doctype/item/item.js b/erpnext/stock/doctype/item/item.js index 9e0941146a7..2d5ab5ac69e 100644 --- a/erpnext/stock/doctype/item/item.js +++ b/erpnext/stock/doctype/item/item.js @@ -81,7 +81,7 @@ frappe.ui.form.on("Item", { }, __('Create')); } - frm.page.set_inner_btn_group_as_primary(__('Create')); + // frm.page.set_inner_btn_group_as_primary(__('Create')); } if (frm.doc.variant_of) { frm.set_intro(__('This Item is a Variant of {0} (Template).', From b4946c31b40903899effa767878cc5e0ac55216b Mon Sep 17 00:00:00 2001 From: Shivam Mishra Date: Wed, 18 Nov 2020 17:39:17 +0530 Subject: [PATCH 202/477] refactor: use h1 for slidetitle --- erpnext/shopping_cart/web_template/hero_slider/hero_slider.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/shopping_cart/web_template/hero_slider/hero_slider.html b/erpnext/shopping_cart/web_template/hero_slider/hero_slider.html index e8b79743ab3..3f0419e5642 100644 --- a/erpnext/shopping_cart/web_template/hero_slider/hero_slider.html +++ b/erpnext/shopping_cart/web_template/hero_slider/hero_slider.html @@ -14,7 +14,7 @@ {%- if title or subtitle -%} {%- endmacro -%} -
    +
    {%- if title -%}

    {{ title }}

    {%- endif -%} @@ -37,17 +37,4 @@
    diff --git a/erpnext/templates/generators/item/item.html b/erpnext/templates/generators/item/item.html index d3691a6e99e..55c45e256a4 100644 --- a/erpnext/templates/generators/item/item.html +++ b/erpnext/templates/generators/item/item.html @@ -7,17 +7,19 @@ {% endblock %} {% block page_content %} -{% from "erpnext/templates/includes/macros.html" import product_image %} -
    -
    -
    - {% include "templates/generators/item/item_image.html" %} - {% include "templates/generators/item/item_details.html" %} +
    + {% from "erpnext/templates/includes/macros.html" import product_image %} +
    +
    +
    + {% include "templates/generators/item/item_image.html" %} + {% include "templates/generators/item/item_details.html" %} +
    + + {% include "templates/generators/item/item_specifications.html" %} + + {{ doc.website_content or '' }}
    - - {% include "templates/generators/item/item_specifications.html" %} - - {{ doc.website_content or '' }}
    {% endblock %} diff --git a/erpnext/templates/generators/item/item_add_to_cart.html b/erpnext/templates/generators/item/item_add_to_cart.html index dbf15de1e48..3210e2497f6 100644 --- a/erpnext/templates/generators/item/item_add_to_cart.html +++ b/erpnext/templates/generators/item/item_add_to_cart.html @@ -6,10 +6,10 @@
    {% if cart_settings.show_price and product_info.price %} -

    +
    {{ product_info.price.formatted_price_sales_uom }} - ({{ product_info.price.formatted_price }} / {{ product_info.uom }}) -

    + ({{ product_info.price.formatted_price }} / {{ product_info.uom }}) +
    {% else %} {{ _("Unit of Measurement") }} : {{ product_info.uom }} {% endif %} @@ -17,11 +17,11 @@ {% if cart_settings.show_stock_availability %}
    {% if product_info.in_stock == 0 %} - + {{ _('Not in stock') }} {% elif product_info.in_stock == 1 %} - + {{ _('In stock') }} {% if product_info.show_stock_qty and product_info.stock_qty %} ({{ product_info.stock_qty[0][0] }}) diff --git a/erpnext/templates/generators/item/item_details.html b/erpnext/templates/generators/item/item_details.html index 4cbecb02155..9a0bb5cfc3f 100644 --- a/erpnext/templates/generators/item/item_details.html +++ b/erpnext/templates/generators/item/item_details.html @@ -1,14 +1,21 @@
    -

    +
    {{ item_name }} -

    -

    +

    +

    {{ _("Item Code") }}: {{ doc.name }}

    +{% if has_variants %} + + {% include "templates/generators/item/item_configure.html" %} +{% else %} + + {% include "templates/generators/item/item_add_to_cart.html" %} +{% endif %} -
    +
    {% if frappe.utils.strip_html(doc.web_long_description or '') %} {{ doc.web_long_description | safe }} {% elif frappe.utils.strip_html(doc.description or '') %} @@ -17,12 +24,4 @@ {{ _("No description given") }} {% endif %}
    - -{% if has_variants %} - - {% include "templates/generators/item/item_configure.html" %} -{% else %} - - {% include "templates/generators/item/item_add_to_cart.html" %} -{% endif %}
    diff --git a/erpnext/templates/generators/item/item_image.html b/erpnext/templates/generators/item/item_image.html index 5d46a45053d..fa70ebe9987 100644 --- a/erpnext/templates/generators/item/item_image.html +++ b/erpnext/templates/generators/item/item_image.html @@ -1,42 +1,42 @@ -
    -{% if slides %} -{{ product_image(slides[0].image, 'product-image') }} -
    - {% for item in slides %} - {{ item.heading }} - {% endfor %} -
    - - -{% else %} -{{ product_image(website_image or image or 'no-image.jpg', alt=website_image_alt or item_name) }} -{% endif %} + $('.item-slideshow-image').removeClass('active'); + $img.addClass('active'); + }); + }) + + {% else %} + {{ product_image(website_image or image or 'no-image.jpg', alt=website_image_alt or item_name) }} + {% endif %} - + - +
    ", - "line_breaks": 0, - "modified": "2018-10-08 14:56:56.912851", - "module": "Regional", - "name": "IRS 1099 Form", - "print_format_builder": 1, - "print_format_type": "Server", - "show_section_headings": 0, - "standard": "No" - } -] +{ + "align_labels_right": 0, + "creation": "2020-11-09 16:01:26.096002", + "css": "", + "custom_format": 1, + "default_print_language": "en", + "disabled": 0, + "doc_type": "Supplier", + "docstatus": 0, + "doctype": "Print Format", + "font": "Default", + "format_data": "[{\"fieldname\": \"print_heading_template\", \"fieldtype\": \"Custom HTML\", \"options\": \"
    \\t\\t\\t\\t

    TAX Invoice
    {{ doc.name }}\\t\\t\\t\\t

    \"}, {\"fieldtype\": \"Section Break\", \"label\": \"\"}, {\"fieldtype\": \"Column Break\"}, {\"print_hide\": 0, \"fieldname\": \"customer_name\", \"label\": \"Customer Name\"}, {\"print_hide\": 0, \"fieldname\": \"customer_name_in_arabic\", \"label\": \"Customer Name in Arabic\"}, {\"fieldtype\": \"Column Break\"}, {\"print_hide\": 0, \"fieldname\": \"posting_date\", \"label\": \"Date\"}, {\"fieldtype\": \"Section Break\", \"label\": \"Address\"}, {\"fieldtype\": \"Column Break\"}, {\"print_hide\": 0, \"fieldname\": \"company\", \"label\": \"Company\"}, {\"print_hide\": 0, \"fieldname\": \"company_trn\", \"label\": \"Company TRN\"}, {\"fieldtype\": \"Column Break\"}, {\"print_hide\": 0, \"fieldname\": \"company_address_display\", \"label\": \"Company Address\"}, {\"fieldtype\": \"Section Break\", \"label\": \"\"}, {\"fieldtype\": \"Column Break\"}, {\"visible_columns\": [{\"print_hide\": 0, \"fieldname\": \"item_code\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"description\", \"print_width\": \"200px\"}, {\"print_hide\": 0, \"fieldname\": \"uom\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"tax_code\", \"print_width\": \"\"}], \"print_hide\": 0, \"fieldname\": \"items\", \"label\": \"Items\"}, {\"fieldtype\": \"Section Break\", \"label\": \"\"}, {\"fieldtype\": \"Column Break\"}, {\"fieldtype\": \"Column Break\"}, {\"print_hide\": 0, \"fieldname\": \"total\", \"label\": \"Total\"}, {\"fieldtype\": \"Section Break\", \"label\": \"\"}, {\"fieldtype\": \"Column Break\"}, {\"visible_columns\": [{\"print_hide\": 0, \"fieldname\": \"charge_type\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"row_id\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"account_head\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"cost_center\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"description\", \"print_width\": \"300px\"}, {\"print_hide\": 0, \"fieldname\": \"rate\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"tax_amount\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"total\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"tax_amount_after_discount_amount\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"base_tax_amount\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"base_total\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"base_tax_amount_after_discount_amount\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"item_wise_tax_detail\", \"print_width\": \"\"}], \"print_hide\": 0, \"fieldname\": \"taxes\", \"label\": \"Sales Taxes and Charges\"}, {\"fieldtype\": \"Section Break\", \"label\": \"\"}, {\"fieldtype\": \"Column Break\"}, {\"fieldtype\": \"Column Break\"}, {\"print_hide\": 0, \"fieldname\": \"grand_total\", \"label\": \"Grand Total\"}, {\"print_hide\": 0, \"fieldname\": \"rounded_total\", \"label\": \"Rounded Total\"}, {\"print_hide\": 0, \"fieldname\": \"in_words\", \"align\": \"left\", \"label\": \"In Words\"}]", + "html": "
    \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n \n \n \n\n \n
    PAYER'S name, street address,\n city or town, state or province, country, ZIP
    or foreign postal code, and telephone no.
    \n {{ company or \"\" }}
    \n {{ payer_street_address or \"\" }}\n
    1 RentsOMB No. 1545-0115
    \n {{ fiscal_year[:2] }}\n {{ fiscal_year[-2:] }}
    Form 1099-MISC\n
    Miscellaneous Income
    2 Royalties
    3 Other Income
    {{ payments or \"\" }}
    4 Federal Income tax withheldCopy A
    For
    Internal Revenue
    Service\n Center

    File with Form 1096
    PAYER'S TIN
    {{ company_tin or \"\" }}
    RECIPIENT'S TIN

    {{ tax_id or \"None\" }}
    Fishing boat proceeds6 Medical and health care payments
    RECIPIENT'S name
    {{ supplier or \"\" }}
    7 Nonemployee compensation
    \n
    Substitute payments in lieu of dividends or interestFor Privacy Act
    and Paperwork
    Reduction Act
    Notice, see\n the
    2018 General
    Instructions for
    Certain
    Information
    Returns.
    Street address (including apt. no.)
    \n {{ recipient_street_address or \"\" }}\n
    $___________$___________
    9 Payer made direct sales of
    $5,000 or more of consumer\n products
    to a buyer
    (recipient) for resale
    10 Crop insurance proceeds
    City or town, state or province, country, and ZIP or\n foreign postal code
    \n {{ recipient_city_state or \"\" }}\n
    $___________
    1112
    Account number (see instructions)FACTA filing
    requirement
    2nd TIN not.13 Excess golden parachute payments
    $___________
    14 Gross proceeds paid to an
    attorney
    $___________
    15a Section 409A deferrals15b Section 409 income16 State tax withheld17 State/Payer's state no.18 State income
    $$$$
    Form 1099-MISC Cat. No. 14425J www.irs.gov/Form1099MISC Department of the\n Treasury - Internal Revenue Service
    \n
    \n
    \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n {{ supplier or \"\" }}\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n \n \n \n\n \n
    PAYER'S name, street address,\n city or town, state or province, country, ZIP
    or foreign postal code, and telephone no.
    \n {{ company or \"\"}}\n {{ payer_street_address or \"\" }}\n
    1 RentsOMB No. 1545-0115
    \n {{ fiscal_year[:2] }}\n {{ fiscal_year[-2:] }}
    Form 1099-MISC\n
    Miscellaneous Income
    2 Royalties
    3 Other Income
    \n {{ payments or \"\" }}\n
    4 Federal Income tax withheldCopy 1
    For State Tax
    Department
    PAYER'S TIN
    \n {{ company_tin or \"\" }}\n
    RECIPIENT'S TIN
    \n {{ tax_id or \"\" }}\n
    Fishing boat proceeds6 Medical and health care payments
    RECIPIENT'S name7 Nonemployee compensation
    \n
    Substitute payments in lieu of dividends or interest
    Street address (including apt. no.)
    \n {{ recipient_street_address or \"\" }}\n
    $___________$___________
    9 Payer made direct sales of
    $5,000 or more of consumer\n products
    to a buyer
    (recipient) for resale
    10 Crop insurance proceeds
    City or town, state or province, country, and ZIP or\n foreign postal code
    \n {{ recipient_city_state or \"\" }}\n
    $___________
    1112
    Account number (see instructions)FACTA filing
    requirement
    2nd TIN not.13 Excess golden parachute payments
    $___________
    14 Gross proceeds paid to an
    attorney
    $___________
    15a Section 409A deferrals15b Section 409 income16 State tax withheld17 State/Payer's state no.18 State income
    $$$$
    Form 1099-MISC Cat. No. 14425J www.irs.gov/Form1099MISC Department of the\n Treasury - Internal Revenue Service
    \n
    \n", + "idx": 0, + "line_breaks": 0, + "modified": "2021-01-19 07:25:16.333666", + "modified_by": "Administrator", + "module": "Regional", + "name": "IRS 1099 Form", + "owner": "Administrator", + "print_format_builder": 1, + "print_format_type": "Jinja", + "raw_printing": 0, + "show_section_headings": 0, + "standard": "No" +} \ No newline at end of file diff --git a/erpnext/regional/report/irs_1099/irs_1099.js b/erpnext/regional/report/irs_1099/irs_1099.js index 2d74652cfe2..070ff43f78c 100644 --- a/erpnext/regional/report/irs_1099/irs_1099.js +++ b/erpnext/regional/report/irs_1099/irs_1099.js @@ -4,7 +4,7 @@ frappe.query_reports["IRS 1099"] = { "filters": [ { - "fieldname":"company", + "fieldname": "company", "label": __("Company"), "fieldtype": "Link", "options": "Company", @@ -13,7 +13,7 @@ frappe.query_reports["IRS 1099"] = { "width": 80, }, { - "fieldname":"fiscal_year", + "fieldname": "fiscal_year", "label": __("Fiscal Year"), "fieldtype": "Link", "options": "Fiscal Year", @@ -22,7 +22,7 @@ frappe.query_reports["IRS 1099"] = { "width": 80, }, { - "fieldname":"supplier_group", + "fieldname": "supplier_group", "label": __("Supplier Group"), "fieldtype": "Link", "options": "Supplier Group", @@ -32,16 +32,16 @@ frappe.query_reports["IRS 1099"] = { }, ], - onload: function(query_report) { + onload: function (query_report) { query_report.page.add_inner_button(__("Print IRS 1099 Forms"), () => { build_1099_print(query_report); }); } }; -function build_1099_print(query_report){ +function build_1099_print(query_report) { let filters = JSON.stringify(query_report.get_values()); let w = window.open('/api/method/erpnext.regional.report.irs_1099.irs_1099.irs_1099_print?' + - '&filters=' + encodeURIComponent(filters)); + '&filters=' + encodeURIComponent(filters)); // w.print(); } diff --git a/erpnext/regional/report/irs_1099/irs_1099.py b/erpnext/regional/report/irs_1099/irs_1099.py index d3509e500f8..c1c8aedc9f3 100644 --- a/erpnext/regional/report/irs_1099/irs_1099.py +++ b/erpnext/regional/report/irs_1099/irs_1099.py @@ -1,29 +1,34 @@ # Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors # For license information, please see license.txt -from __future__ import unicode_literals -import frappe import json -from frappe import _, _dict -from frappe.utils import nowdate -from frappe.utils.data import fmt_money -from erpnext.accounts.utils import get_fiscal_year + from PyPDF2 import PdfFileWriter + +import frappe +from erpnext.accounts.utils import get_fiscal_year +from frappe import _ +from frappe.utils import cstr, nowdate +from frappe.utils.data import fmt_money +from frappe.utils.jinja import render_template from frappe.utils.pdf import get_pdf from frappe.utils.print_format import read_multi_pdf -from frappe.utils.jinja import render_template + +IRS_1099_FORMS_FILE_EXTENSION = ".pdf" def execute(filters=None): - filters = filters if isinstance(filters, _dict) else _dict(filters) - + filters = filters if isinstance(filters, frappe._dict) else frappe._dict(filters) if not filters: filters.setdefault('fiscal_year', get_fiscal_year(nowdate())[0]) filters.setdefault('company', frappe.db.get_default("company")) - region = frappe.db.get_value("Company", fieldname = ["country"], filters = { "name": filters.company }) + region = frappe.db.get_value("Company", + filters={"name": filters.company}, + fieldname=["country"]) + if region != 'United States': - return [],[] + return [], [] data = [] columns = get_columns() @@ -34,20 +39,23 @@ def execute(filters=None): s.tax_id as "tax_id", SUM(gl.debit_in_account_currency) AS "payments" FROM - `tabGL Entry` gl INNER JOIN `tabSupplier` s + `tabGL Entry` gl + INNER JOIN `tabSupplier` s WHERE s.name = gl.party - AND s.irs_1099 = 1 - AND gl.fiscal_year = %(fiscal_year)s - AND gl.party_type = "Supplier" - + AND s.irs_1099 = 1 + AND gl.fiscal_year = %(fiscal_year)s + AND gl.party_type = "Supplier" GROUP BY gl.party - ORDER BY - gl.party DESC""", {"fiscal_year": filters.fiscal_year, + gl.party DESC + """, { + "fiscal_year": filters.fiscal_year, "supplier_group": filters.supplier_group, - "company": filters.company}, as_dict=True) + "company": filters.company + }, as_dict=True) + return columns, data @@ -74,7 +82,6 @@ def get_columns(): "width": 120 }, { - "fieldname": "payments", "label": _("Total Payments"), "fieldtype": "Currency", @@ -88,23 +95,32 @@ def irs_1099_print(filters): if not filters: frappe._dict({ "company": frappe.db.get_default("Company"), - "fiscal_year": frappe.db.get_default("fiscal_year")}) + "fiscal_year": frappe.db.get_default("Fiscal Year") + }) else: filters = frappe._dict(json.loads(filters)) + + fiscal_year_doc = get_fiscal_year(fiscal_year=filters.fiscal_year, as_dict=True) + fiscal_year = cstr(fiscal_year_doc.year_start_date.year) + company_address = get_payer_address_html(filters.company) company_tin = frappe.db.get_value("Company", filters.company, "tax_id") + columns, data = execute(filters) template = frappe.get_doc("Print Format", "IRS 1099 Form").html output = PdfFileWriter() + for row in data: + row["fiscal_year"] = fiscal_year row["company"] = filters.company row["company_tin"] = company_tin row["payer_street_address"] = company_address - row["recipient_street_address"], row["recipient_city_state"] = get_street_address_html("Supplier", row.supplier) + row["recipient_street_address"], row["recipient_city_state"] = get_street_address_html( + "Supplier", row.supplier) row["payments"] = fmt_money(row["payments"], precision=0, currency="USD") - frappe._dict(row) pdf = get_pdf(render_template(template, row), output=output if output else None) - frappe.local.response.filename = filters.fiscal_year + " " + filters.company + " IRS 1099 Forms" + + frappe.local.response.filename = f"{filters.fiscal_year} {filters.company} IRS 1099 Forms{IRS_1099_FORMS_FILE_EXTENSION}" frappe.local.response.filecontent = read_multi_pdf(output) frappe.local.response.type = "download" @@ -120,36 +136,45 @@ def get_payer_address_html(company): ORDER BY address_type="Postal" DESC, address_type="Billing" DESC LIMIT 1 - """, {"company": company}, as_dict=True) + """, {"company": company}, as_dict=True) + + address_display = "" if address_list: company_address = address_list[0]["name"] - return frappe.get_doc("Address", company_address).get_display() - else: - return "" + address_display = frappe.get_doc("Address", company_address).get_display() + + return address_display def get_street_address_html(party_type, party): address_list = frappe.db.sql(""" SELECT link.parent - FROM `tabDynamic Link` link, `tabAddress` address - WHERE link.parenttype = "Address" - AND link.link_name = %(party)s - ORDER BY address.address_type="Postal" DESC, + FROM + `tabDynamic Link` link, + `tabAddress` address + WHERE + link.parenttype = "Address" + AND link.link_name = %(party)s + ORDER BY + address.address_type="Postal" DESC, address.address_type="Billing" DESC LIMIT 1 - """, {"party": party}, as_dict=True) + """, {"party": party}, as_dict=True) + + street_address = city_state = "" if address_list: supplier_address = address_list[0]["parent"] doc = frappe.get_doc("Address", supplier_address) + if doc.address_line2: - street = doc.address_line1 + "
    \n" + doc.address_line2 + "
    \n" + street_address = doc.address_line1 + "
    \n" + doc.address_line2 + "
    \n" else: - street = doc.address_line1 + "
    \n" - city = doc.city + ", " if doc.city else "" - city = city + doc.state + " " if doc.state else city - city = city + doc.pincode if doc.pincode else city - city += "
    \n" - return street, city - else: - return "", "" + street_address = doc.address_line1 + "
    \n" + + city_state = doc.city + ", " if doc.city else "" + city_state = city_state + doc.state + " " if doc.state else city_state + city_state = city_state + doc.pincode if doc.pincode else city_state + city_state += "
    \n" + + return street_address, city_state From c69ab6d184f2927bb8a148d2e3d20fc32ee0eba5 Mon Sep 17 00:00:00 2001 From: Afshan Date: Tue, 19 Jan 2021 19:29:31 +0530 Subject: [PATCH 352/477] fix: select sal comp while making sal struct --- erpnext/payroll/doctype/salary_structure/salary_structure.js | 4 ++++ erpnext/payroll/doctype/salary_structure/salary_structure.py | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/erpnext/payroll/doctype/salary_structure/salary_structure.js b/erpnext/payroll/doctype/salary_structure/salary_structure.js index ba824c5d6fa..6c7b382264f 100755 --- a/erpnext/payroll/doctype/salary_structure/salary_structure.js +++ b/erpnext/payroll/doctype/salary_structure/salary_structure.js @@ -70,6 +70,9 @@ frappe.ui.form.on('Salary Structure', { }); }, + company: function(frm) { + frm.trigger('set_earning_deduction_component'); + }, currency: function(frm) { calculate_totals(frm.doc); @@ -117,6 +120,7 @@ frappe.ui.form.on('Salary Structure', { fields_read_only.forEach(function(field) { frappe.meta.get_docfield("Salary Detail", field, frm.doc.name).read_only = 1; }); + frm.trigger('set_earning_deduction_component'); }, assign_to_employees:function (frm) { diff --git a/erpnext/payroll/doctype/salary_structure/salary_structure.py b/erpnext/payroll/doctype/salary_structure/salary_structure.py index 77914bb5319..340f4e85696 100644 --- a/erpnext/payroll/doctype/salary_structure/salary_structure.py +++ b/erpnext/payroll/doctype/salary_structure/salary_structure.py @@ -216,7 +216,7 @@ def get_earning_deduction_components(doctype, txt, searchfield, start, page_len, return frappe.db.sql(""" select t1.salary_component from `tabSalary Component` t1, `tabSalary Component Account` t2 - where t1.salary_component = t2.parent + where t1.name = t2.parent and t1.type = %s and t2.company = %s order by salary_component From 2e67a41c27b4878b9e2f078a40c7f2bb51c8e60c Mon Sep 17 00:00:00 2001 From: Suraj Shetty Date: Wed, 20 Jan 2021 10:12:01 +0530 Subject: [PATCH 353/477] fix: Update birthday avatar code --- .../templates/emails/birthday_reminder.html | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/erpnext/templates/emails/birthday_reminder.html b/erpnext/templates/emails/birthday_reminder.html index e4c91c722fb..fd03637a535 100644 --- a/erpnext/templates/emails/birthday_reminder.html +++ b/erpnext/templates/emails/birthday_reminder.html @@ -1,12 +1,21 @@
    {% for person in birthday_persons %} - - - {% if not person.image %} {{ person.name[:1] }} {% endif %} + {% if person.image %} + - + {% else %} + + {{ person.name[:1] }} + + {% endif %} {% endfor %}
    From e2ed2324c3eb50f6bb5a67e95f218db6153f8a5d Mon Sep 17 00:00:00 2001 From: Saqib Date: Wed, 20 Jan 2021 13:17:42 +0530 Subject: [PATCH 354/477] fix: (e-invoicing) qrcode image generation (#24395) * fix: invalid taxable value of item for e-invoice * fix: qrcode image duplicate error * fix: net total discount calculation * fix: auto fetch auth token --- erpnext/regional/india/e_invoice/utils.py | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/erpnext/regional/india/e_invoice/utils.py b/erpnext/regional/india/e_invoice/utils.py index d0cac90e4df..83635a199ef 100644 --- a/erpnext/regional/india/e_invoice/utils.py +++ b/erpnext/regional/india/e_invoice/utils.py @@ -161,9 +161,9 @@ def get_item_list(invoice): item.qty = abs(item.qty) item.discount_amount = abs(item.discount_amount * item.qty) - item.unit_rate = abs(item.base_amount / item.qty) - item.gross_amount = abs(item.base_amount) - item.taxable_value = abs(item.base_amount) + item.unit_rate = abs(item.base_net_amount / item.qty) + item.gross_amount = abs(item.base_net_amount) + item.taxable_value = abs(item.base_net_amount) item.batch_expiry_date = frappe.db.get_value('Batch', d.batch_no, 'expiry_date') if d.batch_no else None item.batch_expiry_date = format_date(item.batch_expiry_date, 'dd/mm/yyyy') if item.batch_expiry_date else None @@ -198,7 +198,7 @@ def update_item_taxes(invoice, item): if t.account_head in gst_accounts_list: item_tax_rate = item_tax_detail[0] # item tax amount excluding discount amount - item_tax_amount = (item_tax_rate / 100) * item.base_amount + item_tax_amount = (item_tax_rate / 100) * item.base_net_amount if t.account_head in gst_accounts.cess_account: item_tax_amount_after_discount = item_tax_detail[1] @@ -217,7 +217,10 @@ def update_item_taxes(invoice, item): def get_invoice_value_details(invoice): invoice_value_details = frappe._dict(dict()) - invoice_value_details.base_total = abs(invoice.base_total) + if invoice.apply_discount_on == 'Net Total' and invoice.discount_amount: + invoice_value_details.base_total = abs(invoice.base_total) + else: + invoice_value_details.base_total = abs(invoice.base_net_total) invoice_value_details.invoice_discount_amt = invoice.base_discount_amount invoice_value_details.round_off = invoice.base_rounding_adjustment invoice_value_details.base_grand_total = abs(invoice.base_rounded_total) or abs(invoice.base_grand_total) @@ -473,7 +476,7 @@ class GSPConnector(): "data": json.dumps(data, indent=4) if isinstance(data, dict) else data, "response": json.dumps(res, indent=4) if res else None }) - request_log.insert(ignore_permissions=True) + request_log.save(ignore_permissions=True) frappe.db.commit() def fetch_auth_token(self): @@ -486,7 +489,8 @@ class GSPConnector(): res = self.make_request('post', self.authenticate_url, headers) self.e_invoice_settings.auth_token = "{} {}".format(res.get('token_type'), res.get('access_token')) self.e_invoice_settings.token_expiry = add_to_date(None, seconds=res.get('expires_in')) - self.e_invoice_settings.save() + self.e_invoice_settings.save(ignore_permissions=True) + self.e_invoice_settings.reload() except Exception: self.log_error(res) @@ -757,7 +761,7 @@ class GSPConnector(): 'label': _('IRN Generated') } self.update_invoice() - + def attach_qrcode_image(self): qrcode = self.invoice.signed_qr_code doctype = self.invoice.doctype @@ -768,7 +772,7 @@ class GSPConnector(): 'file_name': 'QRCode_{}.png'.format(docname.replace('/', '-')), 'attached_to_doctype': doctype, 'attached_to_name': docname, - 'content': 'qrcode', + 'content': str(base64.b64encode(os.urandom(64))), 'is_private': 1 }) _file.insert() From 912647f4f23f2b6a6a7c10290682e757fdf840f4 Mon Sep 17 00:00:00 2001 From: Afshan Date: Wed, 20 Jan 2021 13:58:32 +0530 Subject: [PATCH 355/477] fix: allow statistical component in salary structure. --- .../payroll/doctype/salary_structure/salary_structure.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/erpnext/payroll/doctype/salary_structure/salary_structure.py b/erpnext/payroll/doctype/salary_structure/salary_structure.py index 340f4e85696..bf1c7469645 100644 --- a/erpnext/payroll/doctype/salary_structure/salary_structure.py +++ b/erpnext/payroll/doctype/salary_structure/salary_structure.py @@ -216,8 +216,9 @@ def get_earning_deduction_components(doctype, txt, searchfield, start, page_len, return frappe.db.sql(""" select t1.salary_component from `tabSalary Component` t1, `tabSalary Component Account` t2 - where t1.name = t2.parent + where (t1.name = t2.parent and t1.type = %s - and t2.company = %s + and t2.company = %s) + or (t1.statistical_component = 1) order by salary_component - """, (filters['type'], filters['company']) ) + """, (filters['type'], filters['company'])) From 36e3e05a0edcbe2736df77a9c57c7eae63f25f30 Mon Sep 17 00:00:00 2001 From: Afshan Date: Wed, 20 Jan 2021 16:48:42 +0530 Subject: [PATCH 356/477] fix: query for salary componet in salary structure --- .../doctype/salary_structure/salary_structure.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/erpnext/payroll/doctype/salary_structure/salary_structure.py b/erpnext/payroll/doctype/salary_structure/salary_structure.py index bf1c7469645..e71803172c5 100644 --- a/erpnext/payroll/doctype/salary_structure/salary_structure.py +++ b/erpnext/payroll/doctype/salary_structure/salary_structure.py @@ -217,8 +217,12 @@ def get_earning_deduction_components(doctype, txt, searchfield, start, page_len, select t1.salary_component from `tabSalary Component` t1, `tabSalary Component Account` t2 where (t1.name = t2.parent - and t1.type = %s - and t2.company = %s) - or (t1.statistical_component = 1) + and t1.type = %(type)s + and t2.company = %(company)s) + or (t1.type = %(type)s + and t1.statistical_component = 1) order by salary_component - """, (filters['type'], filters['company'])) + """,{ + "type": filters['type'], + "company": filters['company'] + }) From 599322871a55d83be572dc12b631807308d9d631 Mon Sep 17 00:00:00 2001 From: prssanna Date: Wed, 20 Jan 2021 17:44:08 +0530 Subject: [PATCH 357/477] fix: product query issues --- erpnext/setup/doctype/item_group/item_group.py | 4 +++- erpnext/shopping_cart/product_query.py | 11 +++++++++-- erpnext/www/all-products/index.py | 4 +++- 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/erpnext/setup/doctype/item_group/item_group.py b/erpnext/setup/doctype/item_group/item_group.py index f545b989d32..bff806d5472 100644 --- a/erpnext/setup/doctype/item_group/item_group.py +++ b/erpnext/setup/doctype/item_group/item_group.py @@ -77,10 +77,12 @@ class ItemGroup(NestedSet, WebsiteGenerator): search = frappe.form_dict.search field_filters = frappe.parse_json(frappe.form_dict.field_filters) attribute_filters = frappe.parse_json(frappe.form_dict.attribute_filters) + start = frappe.parse_json(frappe.form_dict.start) else: search = None attribute_filters = None field_filters = {} + start = 0 if not field_filters: field_filters = {} @@ -89,7 +91,7 @@ class ItemGroup(NestedSet, WebsiteGenerator): field_filters['item_group'] = self.name engine = ProductQuery() - context.items = engine.query(attribute_filters, field_filters, search) + context.items = engine.query(attribute_filters, field_filters, search, start) filter_engine = ProductFiltersBuilder(self.name) diff --git a/erpnext/shopping_cart/product_query.py b/erpnext/shopping_cart/product_query.py index c5d34459b10..da9e798327d 100644 --- a/erpnext/shopping_cart/product_query.py +++ b/erpnext/shopping_cart/product_query.py @@ -2,6 +2,7 @@ # License: GNU General Public License v3. See license.txt import frappe +from erpnext.shopping_cart.product_info import get_product_info_for_website class ProductQuery: """Query engine for product listing @@ -21,7 +22,7 @@ class ProductQuery: self.settings = frappe.get_doc("Products Settings") self.cart_settings = frappe.get_doc("Shopping Cart Settings") self.page_length = self.settings.products_per_page or 20 - self.fields = ['name', 'item_name', 'website_image', 'variant_of', 'has_variants', 'item_group', 'image', 'web_long_description', 'description', 'route'] + self.fields = ['name', 'item_name', 'item_code', 'website_image', 'variant_of', 'has_variants', 'item_group', 'image', 'web_long_description', 'description', 'route'] self.filters = [['show_in_website', '=', 1]] self.or_filters = [] @@ -57,6 +58,8 @@ class ProductQuery: ["Item Variant Attribute", "attribute_value", "in", values], ], or_filters=self.or_filters, + start=start, + limit=self.page_length ) items_dict = {item.name: item for item in items} @@ -66,7 +69,11 @@ class ProductQuery: result = [items_dict.get(item) for item in list(set.intersection(*all_items))] else: - result = frappe.get_all("Item", fields=self.fields, filters=self.filters, or_filters=self.or_filters, limit=self.page_length) + result = frappe.get_all("Item", fields=self.fields, filters=self.filters, or_filters=self.or_filters, start=start, limit=self.page_length) + + for item in result: + product_info = get_product_info_for_website(item.item_code, skip_quotation_creation=True).get('product_info') + item.formatted_price = product_info['price'].get('formatted_price') if product_info['price'] else None return result diff --git a/erpnext/www/all-products/index.py b/erpnext/www/all-products/index.py index 2d4a357e5e9..2271b4c23c5 100644 --- a/erpnext/www/all-products/index.py +++ b/erpnext/www/all-products/index.py @@ -12,11 +12,13 @@ def get_context(context): search = frappe.form_dict.search field_filters = frappe.parse_json(frappe.form_dict.field_filters) attribute_filters = frappe.parse_json(frappe.form_dict.attribute_filters) + start = frappe.parse_json(frappe.form_dict.start) else: search = field_filters = attribute_filters = None + start = 0 engine = ProductQuery() - context.items = engine.query(attribute_filters, field_filters, search) + context.items = engine.query(attribute_filters, field_filters, search, start) product_settings = get_product_settings() filter_engine = ProductFiltersBuilder() From ac7bc78afeec9b9cf77cf58d90b88fb013280bae Mon Sep 17 00:00:00 2001 From: prssanna Date: Wed, 20 Jan 2021 17:46:19 +0530 Subject: [PATCH 358/477] fix: show product price in item card --- erpnext/portal/product_configurator/utils.py | 7 +++++-- .../web_template/item_card_group/item_card_group.html | 2 +- erpnext/www/all-products/item_row.html | 2 +- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/erpnext/portal/product_configurator/utils.py b/erpnext/portal/product_configurator/utils.py index 9ba4cdc5145..4693d44509a 100644 --- a/erpnext/portal/product_configurator/utils.py +++ b/erpnext/portal/product_configurator/utils.py @@ -1,6 +1,7 @@ import frappe from frappe.utils import cint from erpnext.portal.product_configurator.item_variants_cache import ItemVariantsCacheManager +from erpnext.shopping_cart.product_info import get_product_info_for_website def get_field_filter_data(): product_settings = get_product_settings() @@ -356,10 +357,10 @@ def get_items(filters=None, search=None): results = frappe.db.sql(''' SELECT - `tabItem`.`name`, `tabItem`.`item_name`, + `tabItem`.`name`, `tabItem`.`item_name`, `tabItem`.`item_code`, `tabItem`.`website_image`, `tabItem`.`image`, `tabItem`.`web_long_description`, `tabItem`.`description`, - `tabItem`.`route` + `tabItem`.`route`, `tabItem`.`item_group` FROM `tabItem` {left_join} @@ -384,6 +385,8 @@ def get_items(filters=None, search=None): for r in results: r.description = r.web_long_description or r.description r.image = r.website_image or r.image + product_info = get_product_info_for_website(r.item_code, skip_quotation_creation=True).get('product_info') + r.formatted_price = product_info['price'].get('formatted_price') if product_info['price'] else None return results diff --git a/erpnext/shopping_cart/web_template/item_card_group/item_card_group.html b/erpnext/shopping_cart/web_template/item_card_group/item_card_group.html index d39d1b7b501..890ae502c82 100644 --- a/erpnext/shopping_cart/web_template/item_card_group/item_card_group.html +++ b/erpnext/shopping_cart/web_template/item_card_group/item_card_group.html @@ -26,7 +26,7 @@ {%- set item = frappe.get_doc("Item", item) -%} {{ item_card( item.item_name, item.image, item.route, item.description, - item.standard_rate, item.item_group, values['card_' + index + '_featured'], + None, item.item_group, values['card_' + index + '_featured'], True, "Center" ) }} {%- endif -%} diff --git a/erpnext/www/all-products/item_row.html b/erpnext/www/all-products/item_row.html index b5280eacb7f..20fc9a4878c 100644 --- a/erpnext/www/all-products/item_row.html +++ b/erpnext/www/all-products/item_row.html @@ -2,6 +2,6 @@ {{ item_card( item.item_name or item.name, item.website_image or item.image, item.route, item.website_description or item.description, - item.standard_rate, item.item_group + item.formatted_price, item.item_group ) }} From 706eae7cacc0fb0f7bd922e69c618acc2047200d Mon Sep 17 00:00:00 2001 From: prssanna Date: Wed, 20 Jan 2021 17:47:25 +0530 Subject: [PATCH 359/477] fix: product page fixes --- erpnext/templates/generators/item/item.html | 3 + .../generators/item/item_add_to_cart.html | 9 ++- .../generators/item/item_configure.html | 4 +- .../generators/item/item_configure.js | 67 +++++++++++-------- .../generators/item/item_details.html | 5 +- 5 files changed, 52 insertions(+), 36 deletions(-) diff --git a/erpnext/templates/generators/item/item.html b/erpnext/templates/generators/item/item.html index 889908031e3..135982d7090 100644 --- a/erpnext/templates/generators/item/item.html +++ b/erpnext/templates/generators/item/item.html @@ -3,6 +3,9 @@ {% block title %} {{ title }} {% endblock %} {% block breadcrumbs %} +
    + {% include "templates/includes/breadcrumbs.html" %} +
    {% endblock %} {% block page_content %} diff --git a/erpnext/templates/generators/item/item_add_to_cart.html b/erpnext/templates/generators/item/item_add_to_cart.html index 3210e2497f6..f5adbf01e3d 100644 --- a/erpnext/templates/generators/item/item_add_to_cart.html +++ b/erpnext/templates/generators/item/item_add_to_cart.html @@ -30,7 +30,7 @@ {% endif %}
    {% endif %} -
    +
    {% if product_info.price and (cart_settings.allow_items_not_in_stock or product_info.in_stock) %} {% endif %} diff --git a/erpnext/templates/generators/item/item_configure.html b/erpnext/templates/generators/item/item_configure.html index 73f9ec99b34..b61ac73072d 100644 --- a/erpnext/templates/generators/item/item_configure.html +++ b/erpnext/templates/generators/item/item_configure.html @@ -1,9 +1,9 @@ {% if shopping_cart and shopping_cart.cart_settings.enabled %} {% set cart_settings = shopping_cart.cart_settings %} -
    +
    {% if cart_settings.enable_variants | int %} - + ` : ''; const items_found = filtered_items_count === 1 ? __('{0} item found.', [filtered_items_count]) : __('{0} items found.', [filtered_items_count]); - const item_found_status = ` - ` + : ``; return ` - ${item_add_to_cart} ${item_found_status} + ${item_add_to_cart} `; } @@ -254,8 +265,8 @@ class ItemConfigure { } append_status_area() { - this.dialog.$status_area = $('
    '); - this.dialog.$wrapper.find('.modal-body').prepend(this.dialog.$status_area); + this.dialog.$status_area = $('
    '); + this.dialog.$wrapper.find('.modal-body').append(this.dialog.$status_area); this.dialog.$wrapper.on('click', '[data-action]', (e) => { e.preventDefault(); const $target = $(e.currentTarget); @@ -263,7 +274,7 @@ class ItemConfigure { const method = this[action]; method.call(this, e); }); - this.dialog.$body.css({ maxHeight: '75vh', overflow: 'auto', overflowX: 'hidden' }); + this.dialog.$wrapper.addClass('item-configurator-dialog'); } get_next_attribute_and_values(selected_attributes) { diff --git a/erpnext/templates/generators/item/item_details.html b/erpnext/templates/generators/item/item_details.html index 6a85ca50e65..3b775858276 100644 --- a/erpnext/templates/generators/item/item_details.html +++ b/erpnext/templates/generators/item/item_details.html @@ -1,8 +1,5 @@ -
    +
    -
    - {% include "templates/includes/breadcrumbs.html" %} -

    {{ item_name }}

    From b00eb1b0cc2ccf7e31432eb1724e96af27c3ed93 Mon Sep 17 00:00:00 2001 From: prssanna Date: Wed, 20 Jan 2021 17:52:54 +0530 Subject: [PATCH 360/477] feat: shopping cart page --- .../images/ui-states/cart-empty-state.png | Bin 0 -> 1593 bytes erpnext/public/scss/shopping_cart.scss | 268 ++++++++++++++++-- erpnext/shopping_cart/cart.py | 36 ++- erpnext/templates/includes/cart.js | 89 ++++-- .../templates/includes/cart/address_card.html | 19 +- .../includes/cart/address_picker_card.html | 12 + .../templates/includes/cart/cart_address.html | 56 ++-- .../includes/cart/cart_address_picker.html | 4 + .../templates/includes/cart/cart_items.html | 16 +- erpnext/templates/includes/macros.html | 4 + .../includes/navbar/navbar_items.html | 8 +- .../templates/includes/order/order_taxes.html | 79 +++--- erpnext/templates/pages/cart.html | 173 ++++++----- erpnext/www/all-products/index.html | 10 +- 14 files changed, 573 insertions(+), 201 deletions(-) create mode 100644 erpnext/public/images/ui-states/cart-empty-state.png create mode 100644 erpnext/templates/includes/cart/address_picker_card.html create mode 100644 erpnext/templates/includes/cart/cart_address_picker.html diff --git a/erpnext/public/images/ui-states/cart-empty-state.png b/erpnext/public/images/ui-states/cart-empty-state.png new file mode 100644 index 0000000000000000000000000000000000000000..e1ead0e175d204e267a9010e70f54ff98d08250c GIT binary patch literal 1593 zcmV-92FCe`P)Fyc*d{ru;znM4Ry#8+h7A#n>pu7kukWQzw`U#dBvLe6H zTCZa;tN7??A$t1ydjH4f(@Q7`g@__SUzS#Ol~Q{o2eb|_lJ{Eaz7X=E7Em+q3(+l$ zFt4KG1YstTh#>sEpE|!)@u?xC+{EW<8H9Nel~hoaG6{1kDyyIlr2F~iWFv5 zlq*3|iV$W+)R-VdE7ionyWkL?!g7g<%^;!w7GMIu#0%)EtE*GjMZ<@%OrjKKbjMe0AyfgJUNn24|*3VY$|T#@ruA*HYp zQ6x!9eU5MThy9=cJTM|mhya6b`si(^5jG;~|wDchS*)~Jp$?_-uxk)(_RkB|_2v@wn~4eAtcB1yZz8`>F4bON>b za%pK(55}z3FE~|A@Bg1sD1%zL?Z!qk{KKM}@+gsBKHb2!&2eO0mq-Y)iu3pV?PuTD z<)j0IGOUh2zAQAuHlH>)!|<8vvGdoz{@#KdkRUq7XZhg598+uRrqnTE>R7_w;p=t! z-o%WGVtUs?w8Fy?d=7lKl6l9GNjlZTMx}*`B2tSA9i)bVHhfR1#Kcj>8`nuXjvN;R zXIiVHxIUv5QQ<(NQz``st4S#juo9-CGA4}T#P!2nrRnCH4C)Ru=<<$Z+7lHHBwX1R zwPF%&e3a5hDCi-znkca^Kx6%;50k_d7B#UlPfE11_0^om#95MDDy2BU%y~>1 zc3*v5+uq#R%X0IUz%s)i8gw^IhG|K{8Ys+5hMC5uQfc9hs!;}kQb+gU^C5K_AqUn) zF}{V32-2Da?b{HYmnn zbbzh6WcJeF=qq+1J z4M}bjM$JC3P!;HGG znb$Cx`%xr?gkj)K$}lkyc0mFmBO_BhI5$QEa5I@W$RIONEkY8JyTj>H7?`1m{_(Ev5+<&%>o8@c z5>?TZq?@z6|C~Sgy)^o`l_q!m-pl zywJyxfq4)X&ZsV}x4-VZ$s~)IWnnj>%%D?<0N=^IYBDRr%rY0oZ~hK{Ks()NV~C*Qi*y%H9N$3Ckl6+p?Ly$Q5vJ6Ks(`(r!qZX<5@im$oqyvzJ)h;H5xxM;D} z+&JXVCyHW<5avTv%=Vwy%^QhDF+PR46qQsElUfwxLzoLuX$3KvMKLag*%Xyk5R+RJ z<3gAXQF#S1)R|CCZl|#=9sciLf|Pz6CLbiDK>&78X^MAf|9pOjMW { + const type = $(e.currentTarget).parents('.address-container').attr('data-address-type'); + $(d.get_field('address_picker').wrapper).html( + this.get_address_template(type) + ); + d.show(); }); }, + get_update_address_dialog() { + return new frappe.ui.Dialog({ + title: "Select Address", + fields: [{ + 'fieldtype': 'HTML', + 'fieldname': 'address_picker', + }], + primary_action_label: __('Set Address'), + primary_action: () => { + const $card = d.$wrapper.find('.address-card.active'); + const address_type = $card.closest('[data-address-type]').attr('data-address-type'); + const address_name = $card.closest('[data-address-name]').attr('data-address-name'); + frappe.call({ + type: "POST", + method: "erpnext.shopping_cart.cart.update_cart_address", + freeze: true, + args: { + address_type, + address_name + }, + callback: function(r) { + d.hide(); + if(!r.exc) { + $(".cart-tax-items").html(r.message.taxes); + shopping_cart.parent.find( + `.address-container[data-address-type="${address_type}"]` + ).html(r.message.address); + } + } + }); + } + }); + }, + + get_address_template(type) { + return { + shipping: `
    +
    + {% for address in shipping_addresses %} +
    + {% include "templates/includes/cart/address_picker_card.html" %} +
    + {% endfor %} +
    +
    `, + billing: `
    +
    + {% for address in billing_addresses %} +
    + {% include "templates/includes/cart/address_picker_card.html" %} +
    + {% endfor %} +
    +
    `, + }[type]; + }, + bind_place_order: function() { $(".btn-place-order").on("click", function() { shopping_cart.place_order(this); @@ -221,6 +269,7 @@ $.extend(shopping_cart, { frappe.ready(function() { $(".cart-icon").hide(); + shopping_cart.parent = $(".cart-container"); shopping_cart.bind_events(); }); diff --git a/erpnext/templates/includes/cart/address_card.html b/erpnext/templates/includes/cart/address_card.html index 646210e65f1..667144bd878 100644 --- a/erpnext/templates/includes/cart/address_card.html +++ b/erpnext/templates/includes/cart/address_card.html @@ -1,12 +1,17 @@
    -
    - +
    + {{ _('Change') }}
    -
    -
    {{ address.title }}
    -

    +

    +
    {{ address.title }}
    +
    {{ address.display }} -

    - {{ _('Edit') }} +
    + + + + + {{ _('Edit') }} +
    diff --git a/erpnext/templates/includes/cart/address_picker_card.html b/erpnext/templates/includes/cart/address_picker_card.html new file mode 100644 index 00000000000..2334ea2955d --- /dev/null +++ b/erpnext/templates/includes/cart/address_picker_card.html @@ -0,0 +1,12 @@ +
    +
    + +
    +
    +
    {{ address.title }}
    +

    + {{ address.display }} +

    + {{ _('Edit') }} +
    +
    \ No newline at end of file diff --git a/erpnext/templates/includes/cart/cart_address.html b/erpnext/templates/includes/cart/cart_address.html index aa25c885fee..3c8267c43d2 100644 --- a/erpnext/templates/includes/cart/cart_address.html +++ b/erpnext/templates/includes/cart/cart_address.html @@ -14,31 +14,39 @@
    {% endif %} -
    -
    {{ _("Shipping Address") }}
    +
    +
    {{ _("Shipping Address") }}
    +
    + {% for address in shipping_addresses %} + {% if doc.shipping_address_name == address.name %}
    - {% for address in shipping_addresses %} -
    - {% include "templates/includes/cart/address_card.html" %} -
    - {% endfor %} +
    + {% include "templates/includes/cart/address_card.html" %} +
    + {% endif %} + {% endfor %}
    -
    -
    {{ _("Billing Address") }}
    -
    - {% for address in billing_addresses %} -
    - {% include "templates/includes/cart/address_card.html" %} -
    - {% endfor %} -
    +
    +
    -
    - - +
    +
    {{ _("Billing Address") }}
    +
    + {% for address in billing_addresses %} + {% if doc.customer_address == address.name %} +
    +
    + {% include "templates/includes/cart/address_card.html" %} +
    +
    + {% endif %} + {% endfor %}
    - + diff --git a/erpnext/templates/includes/cart/cart_address_picker.html b/erpnext/templates/includes/cart/cart_address_picker.html new file mode 100644 index 00000000000..72cc5f51423 --- /dev/null +++ b/erpnext/templates/includes/cart/cart_address_picker.html @@ -0,0 +1,4 @@ +
    +
    {{ _("Shipping Address") }}
    +
    + diff --git a/erpnext/templates/includes/cart/cart_items.html b/erpnext/templates/includes/cart/cart_items.html index ca5744bebbd..75441c42bc9 100644 --- a/erpnext/templates/includes/cart/cart_items.html +++ b/erpnext/templates/includes/cart/cart_items.html @@ -1,15 +1,15 @@ {% for d in doc.items %} -
    +
    {{ d.item_name }}
    -
    +
    {{ d.item_code }}
    {%- set variant_of = frappe.db.get_value('Item', d.item_code, 'variant_of') %} {% if variant_of %} - + {{ _('Variant of') }} {{ variant_of }} {% endif %} @@ -20,20 +20,20 @@
    - + - + - +
    {% if cart_settings.enable_checkout %} - +
    {{ d.get_formatted('amount') }}
    - + {{ _('Rate:') }} {{ d.get_formatted('rate') }} diff --git a/erpnext/templates/includes/macros.html b/erpnext/templates/includes/macros.html index 74c84ba27ce..0adfbc9dfd9 100644 --- a/erpnext/templates/includes/macros.html +++ b/erpnext/templates/includes/macros.html @@ -90,6 +90,10 @@
    {% if image %} {{ title }} + {% else %} +
    + {{ frappe.utils.get_abbr(title) }} +
    {% endif %} {{ item_card_body(title, description, url, rate, category, is_featured, align) }}
    diff --git a/erpnext/templates/includes/navbar/navbar_items.html b/erpnext/templates/includes/navbar/navbar_items.html index 4daf0e74e02..133d99e5eb9 100644 --- a/erpnext/templates/includes/navbar/navbar_items.html +++ b/erpnext/templates/includes/navbar/navbar_items.html @@ -2,9 +2,11 @@ {% block navbar_right_extension %}
  • {% endblock %} \ No newline at end of file diff --git a/erpnext/templates/includes/order/order_taxes.html b/erpnext/templates/includes/order/order_taxes.html index ebec838d03e..d2c458e0a49 100644 --- a/erpnext/templates/includes/order/order_taxes.html +++ b/erpnext/templates/includes/order/order_taxes.html @@ -29,12 +29,12 @@ {{ _("Discount") }} - {% set tot_quotation_discount = [] %} - {%- for item in doc.items -%} - {% if tot_quotation_discount.append((((item.price_list_rate * item.qty) - * item.discount_percentage) / 100)) %}{% endif %} - {% endfor %} - {{ frappe.utils.fmt_money((tot_quotation_discount | sum),currency=doc.currency) }} + {% set tot_quotation_discount = [] %} + {%- for item in doc.items -%} + {% if tot_quotation_discount.append((((item.price_list_rate * item.qty) + * item.discount_percentage) / 100)) %}{% endif %} + {% endfor %} + {{ frappe.utils.fmt_money((tot_quotation_discount | sum),currency=doc.currency) }} {% endif %} @@ -47,51 +47,52 @@ {{ _("Total Amount") }} - - {% set total_amount = [] %} - {%- for item in doc.items -%} - {% if total_amount.append((item.price_list_rate * item.qty)) %}{% endif %} - {% endfor %} - {{ frappe.utils.fmt_money((total_amount | sum),currency=doc.currency) }} - + + {% set total_amount = [] %} + {%- for item in doc.items -%} + {% if total_amount.append((item.price_list_rate * item.qty)) %}{% endif %} + {% endfor %} + {{ frappe.utils.fmt_money((total_amount | sum),currency=doc.currency) }} + - - {{ _("Applied Coupon Code") }} - - - - {%- for row in frappe.get_all(doctype="Coupon Code", - fields=["coupon_code"], filters={ "name":doc.coupon_code}) -%} - {{ row.coupon_code }} - {% endfor %} - - + + {{ _("Applied Coupon Code") }} + + + + {%- for row in frappe.get_all(doctype="Coupon Code", + fields=["coupon_code"], filters={ "name":doc.coupon_code}) -%} + {{ row.coupon_code }} + {% endfor %} + + - - {{ _("Discount") }} - - - - {% set tot_SO_discount = [] %} - {%- for item in doc.items -%} - {% if tot_SO_discount.append((((item.price_list_rate * item.qty) - * item.discount_percentage) / 100)) %}{% endif %} - {% endfor %} - {{ frappe.utils.fmt_money((tot_SO_discount | sum),currency=doc.currency) }} - - + + {{ _("Discount") }} + + + + {% set tot_SO_discount = [] %} + {%- for item in doc.items -%} + {% if tot_SO_discount.append((((item.price_list_rate * item.qty) + * item.discount_percentage) / 100)) %}{% endif %} + {% endfor %} + {{ frappe.utils.fmt_money((tot_SO_discount | sum),currency=doc.currency) }} + + {% endif %} {% endif %} - + + {{ _("Grand Total") }} - + {{ doc.get_formatted("grand_total") }} diff --git a/erpnext/templates/pages/cart.html b/erpnext/templates/pages/cart.html index 3033d1587d6..2cabf5a9e0e 100644 --- a/erpnext/templates/pages/cart.html +++ b/erpnext/templates/pages/cart.html @@ -2,7 +2,7 @@ {% block title %} {{ _("Shopping Cart") }} {% endblock %} -{% block header %}

    {{ _("Shopping Cart") }}

    {% endblock %} +{% block header %}

    {{ _("Shopping Cart") }}

    {% endblock %} -
    -
    -
    + + + + + + + {% for d in doc.items %} -
    -
    +
    + + + + {% endfor %} - + +
    {{ _("Item") }} - -
    +
    {{ _("Quantity") }} - -
    +
    {{ _("Amount") }} - - +
    {{ item_name_and_description(d) }} - -
    +
    {{ d.qty }} {% if d.delivered_qty is defined and d.delivered_qty != None %}

    {{ _("Delivered") }} {{ d.delivered_qty }}

    {% endif %} - -
    +
    {{ d.get_formatted("amount") }}

    {{ _("Rate:") }} {{ d.get_formatted("rate") }}

    - - +
    From bc370b3ee586d97c2fd5c9db74a0718d4fff2d10 Mon Sep 17 00:00:00 2001 From: marination Date: Thu, 28 Jan 2021 11:44:26 +0530 Subject: [PATCH 413/477] chore: Set Stock Entry Form Indicators in setup - Makes it easier to override via customisations - Style consistency with other forms that set indicator in setup as well --- .../stock/doctype/stock_entry/stock_entry.js | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.js b/erpnext/stock/doctype/stock_entry/stock_entry.js index bd2fce8bef1..cb6cab3341a 100644 --- a/erpnext/stock/doctype/stock_entry/stock_entry.js +++ b/erpnext/stock/doctype/stock_entry/stock_entry.js @@ -5,6 +5,14 @@ frappe.provide("erpnext.accounts.dimensions"); frappe.ui.form.on('Stock Entry', { setup: function(frm) { + frm.set_indicator_formatter('item_code', function(doc) { + if (!doc.s_warehouse) { + return 'blue'; + } else { + return (doc.qty<=doc.actual_qty) ? 'green' : 'orange' + } + }); + frm.set_query('work_order', function() { return { filters: [ @@ -779,15 +787,6 @@ erpnext.stock.StockEntry = erpnext.stock.StockController.extend({ } } - this.frm.set_indicator_formatter('item_code', - function(doc) { - if (!doc.s_warehouse) { - return 'blue'; - } else { - return (doc.qty<=doc.actual_qty) ? "green" : "orange" - } - }) - this.frm.add_fetch("purchase_order", "supplier", "supplier"); frappe.dynamic_link = { doc: this.frm.doc, fieldname: 'supplier', doctype: 'Supplier' } From 27bac2aaecfc831d899903f886a1feb3de357b91 Mon Sep 17 00:00:00 2001 From: marination Date: Thu, 28 Jan 2021 12:04:14 +0530 Subject: [PATCH 414/477] fix: Missing semi-colon --- erpnext/stock/doctype/stock_entry/stock_entry.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.js b/erpnext/stock/doctype/stock_entry/stock_entry.js index cb6cab3341a..bc1d089899f 100644 --- a/erpnext/stock/doctype/stock_entry/stock_entry.js +++ b/erpnext/stock/doctype/stock_entry/stock_entry.js @@ -9,7 +9,7 @@ frappe.ui.form.on('Stock Entry', { if (!doc.s_warehouse) { return 'blue'; } else { - return (doc.qty<=doc.actual_qty) ? 'green' : 'orange' + return (doc.qty<=doc.actual_qty) ? 'green' : 'orange'; } }); From bd9bdc5797d859988460a0e359205a12b89fe207 Mon Sep 17 00:00:00 2001 From: Deepesh Garg <42651287+deepeshgarg007@users.noreply.github.com> Date: Thu, 28 Jan 2021 12:05:57 +0530 Subject: [PATCH 415/477] feat: Batch wise item pricing (#24470) * feat: Batch wise item pricing * fix: Rate for items with no batch * fix: Add test case for batch pricing * fix: Sider Issues * fix: Add item filter for batch --- erpnext/public/js/controllers/buying.js | 4 + erpnext/public/js/controllers/transaction.js | 6 + erpnext/selling/sales_common.js | 4 + erpnext/stock/doctype/batch/test_batch.py | 70 ++++++++++- .../stock/doctype/item_price/item_price.js | 8 ++ .../stock/doctype/item_price/item_price.json | 116 ++++++++++++++---- .../stock/doctype/item_price/item_price.py | 5 +- erpnext/stock/get_item_details.py | 5 +- 8 files changed, 187 insertions(+), 31 deletions(-) diff --git a/erpnext/public/js/controllers/buying.js b/erpnext/public/js/controllers/buying.js index 0c6bcad7219..a2a723dd774 100644 --- a/erpnext/public/js/controllers/buying.js +++ b/erpnext/public/js/controllers/buying.js @@ -195,6 +195,10 @@ erpnext.buying.BuyingController = erpnext.TransactionController.extend({ this._super(doc, cdt, cdn); }, + batch_no: function(doc, cdt, cdn) { + this._super(doc, cdt, cdn); + }, + received_qty: function(doc, cdt, cdn) { this.calculate_accepted_qty(doc, cdt, cdn) }, diff --git a/erpnext/public/js/controllers/transaction.js b/erpnext/public/js/controllers/transaction.js index 26280998f9c..77318332d25 100644 --- a/erpnext/public/js/controllers/transaction.js +++ b/erpnext/public/js/controllers/transaction.js @@ -1099,6 +1099,11 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({ } }, + batch_no: function(doc, cdt, cdn) { + let item = frappe.get_doc(cdt, cdn); + this.apply_price_list(item, true); + }, + toggle_conversion_factor: function(item) { // toggle read only property for conversion factor field if the uom and stock uom are same if(this.frm.get_field('items').grid.fields_map.conversion_factor) { @@ -1403,6 +1408,7 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({ "pricing_rules": d.pricing_rules, "warehouse": d.warehouse, "serial_no": d.serial_no, + "batch_no": d.batch_no, "price_list_rate": d.price_list_rate, "conversion_factor": d.conversion_factor || 1.0 }); diff --git a/erpnext/selling/sales_common.js b/erpnext/selling/sales_common.js index 7f00fca8f05..ce084646e15 100644 --- a/erpnext/selling/sales_common.js +++ b/erpnext/selling/sales_common.js @@ -399,6 +399,10 @@ erpnext.selling.SellingController = erpnext.TransactionController.extend({ } }, + batch_no: function(doc, cdt, cdn) { + this._super(doc, cdt, cdn); + }, + qty: function(doc, cdt, cdn) { this._super(doc, cdt, cdn); diff --git a/erpnext/stock/doctype/batch/test_batch.py b/erpnext/stock/doctype/batch/test_batch.py index e41f1a8aaaf..97f85bafd95 100644 --- a/erpnext/stock/doctype/batch/test_batch.py +++ b/erpnext/stock/doctype/batch/test_batch.py @@ -8,6 +8,8 @@ import unittest from erpnext.stock.doctype.batch.batch import get_batch_qty, UnableToSelectBatchError, get_batch_no from frappe.utils import cint, flt +from erpnext.accounts.doctype.purchase_invoice.test_purchase_invoice import make_purchase_invoice +from erpnext.stock.get_item_details import get_item_details class TestBatch(unittest.TestCase): def test_item_has_batch_enabled(self): @@ -182,7 +184,7 @@ class TestBatch(unittest.TestCase): stock_entry.cancel() current_batch_qty = flt(frappe.db.get_value("Batch", "B100", "batch_qty")) self.assertEqual(current_batch_qty, existing_batch_qty) - + @classmethod def make_new_batch_and_entry(cls, item_name, batch_name, warehouse): '''Make a new stock entry for given target warehouse and batch name of item''' @@ -252,6 +254,72 @@ class TestBatch(unittest.TestCase): return batch + def test_batch_wise_item_price(self): + if not frappe.db.get_value('Item', '_Test Batch Price Item'): + frappe.get_doc({ + 'doctype': 'Item', + 'is_stock_item': 1, + 'item_code': '_Test Batch Price Item', + 'item_group': 'Products', + 'has_batch_no': 1, + 'create_new_batch': 1 + }).insert(ignore_permissions=True) + + batch1 = create_batch('_Test Batch Price Item', 200, 1) + batch2 = create_batch('_Test Batch Price Item', 300, 1) + batch3 = create_batch('_Test Batch Price Item', 400, 0) + + args = frappe._dict({ + "item_code": "_Test Batch Price Item", + "company": "_Test Company with perpetual inventory", + "price_list": "_Test Price List", + "currency": "_Test Currency", + "doctype": "Sales Invoice", + "conversion_rate": 1, + "price_list_currency": "_Test Currency", + "plc_conversion_rate": 1, + "customer": "_Test Customer", + "name": None + }) + + #test price for batch1 + args.update({'batch_no': batch1}) + details = get_item_details(args) + self.assertEqual(details.get('price_list_rate'), 200) + + #test price for batch2 + args.update({'batch_no': batch2}) + details = get_item_details(args) + self.assertEqual(details.get('price_list_rate'), 300) + + #test price for batch3 + args.update({'batch_no': batch3}) + details = get_item_details(args) + self.assertEqual(details.get('price_list_rate'), 400) + +def create_batch(item_code, rate, create_item_price_for_batch): + pi = make_purchase_invoice(company="_Test Company with perpetual inventory", + warehouse= "Stores - TCP1", cost_center = "Main - TCP1", update_stock=1, + expense_account ="_Test Account Cost for Goods Sold - TCP1", item_code=item_code) + + batch = frappe.db.get_value('Batch', {'item': item_code, 'reference_name': pi.name}) + + if not create_item_price_for_batch: + create_price_list_for_batch(item_code, None, rate) + else: + create_price_list_for_batch(item_code, batch, rate) + + return batch + +def create_price_list_for_batch(item_code, batch, rate): + frappe.get_doc({ + 'doctype': 'Item Price', + 'item_code': '_Test Batch Price Item', + 'price_list': '_Test Price List', + 'batch_no': batch, + 'price_list_rate': rate + }).insert() + def make_new_batch(**args): args = frappe._dict(args) diff --git a/erpnext/stock/doctype/item_price/item_price.js b/erpnext/stock/doctype/item_price/item_price.js index 2729f4b15e2..e4db0480db0 100644 --- a/erpnext/stock/doctype/item_price/item_price.js +++ b/erpnext/stock/doctype/item_price/item_price.js @@ -15,5 +15,13 @@ frappe.ui.form.on("Item Price", { frm.set_df_property("bulk_import_help", "options", '' + __("Import in Bulk") + ''); + + frm.set_query('batch_no', function() { + return { + filters: { + 'item': frm.doc.item_code + } + } + }); } }); diff --git a/erpnext/stock/doctype/item_price/item_price.json b/erpnext/stock/doctype/item_price/item_price.json index 5f62381f8b3..83177b372ad 100644 --- a/erpnext/stock/doctype/item_price/item_price.json +++ b/erpnext/stock/doctype/item_price/item_price.json @@ -18,6 +18,7 @@ "price_list", "customer", "supplier", + "batch_no", "column_break_3", "buying", "selling", @@ -47,31 +48,41 @@ "oldfieldtype": "Select", "options": "Item", "reqd": 1, - "search_index": 1 + "search_index": 1, + "show_days": 1, + "show_seconds": 1 }, { "fieldname": "uom", "fieldtype": "Link", "label": "UOM", - "options": "UOM" + "options": "UOM", + "show_days": 1, + "show_seconds": 1 }, { "default": "0", "description": "Quantity that must be bought or sold per UOM", "fieldname": "packing_unit", "fieldtype": "Int", - "label": "Packing Unit" + "label": "Packing Unit", + "show_days": 1, + "show_seconds": 1 }, { "fieldname": "column_break_17", - "fieldtype": "Column Break" + "fieldtype": "Column Break", + "show_days": 1, + "show_seconds": 1 }, { "fieldname": "item_name", "fieldtype": "Data", "in_list_view": 1, "label": "Item Name", - "read_only": 1 + "read_only": 1, + "show_days": 1, + "show_seconds": 1 }, { "fetch_from": "item_code.brand", @@ -79,19 +90,25 @@ "fieldtype": "Read Only", "in_list_view": 1, "label": "Brand", - "read_only": 1 + "read_only": 1, + "show_days": 1, + "show_seconds": 1 }, { "fieldname": "item_description", "fieldtype": "Text", "label": "Item Description", - "read_only": 1 + "read_only": 1, + "show_days": 1, + "show_seconds": 1 }, { "fieldname": "price_list_details", "fieldtype": "Section Break", "label": "Price List", - "options": "fa fa-tags" + "options": "fa fa-tags", + "show_days": 1, + "show_seconds": 1 }, { "fieldname": "price_list", @@ -100,7 +117,9 @@ "in_standard_filter": 1, "label": "Price List", "options": "Price List", - "reqd": 1 + "reqd": 1, + "show_days": 1, + "show_seconds": 1 }, { "bold": 1, @@ -108,37 +127,49 @@ "fieldname": "customer", "fieldtype": "Link", "label": "Customer", - "options": "Customer" + "options": "Customer", + "show_days": 1, + "show_seconds": 1 }, { "depends_on": "eval:doc.buying == 1", "fieldname": "supplier", "fieldtype": "Link", "label": "Supplier", - "options": "Supplier" + "options": "Supplier", + "show_days": 1, + "show_seconds": 1 }, { "fieldname": "column_break_3", - "fieldtype": "Column Break" + "fieldtype": "Column Break", + "show_days": 1, + "show_seconds": 1 }, { "default": "0", "fieldname": "buying", "fieldtype": "Check", "label": "Buying", - "read_only": 1 + "read_only": 1, + "show_days": 1, + "show_seconds": 1 }, { "default": "0", "fieldname": "selling", "fieldtype": "Check", "label": "Selling", - "read_only": 1 + "read_only": 1, + "show_days": 1, + "show_seconds": 1 }, { "fieldname": "item_details", "fieldtype": "Section Break", - "options": "fa fa-tag" + "options": "fa fa-tag", + "show_days": 1, + "show_seconds": 1 }, { "bold": 1, @@ -146,11 +177,15 @@ "fieldtype": "Link", "label": "Currency", "options": "Currency", - "read_only": 1 + "read_only": 1, + "show_days": 1, + "show_seconds": 1 }, { "fieldname": "col_br_1", - "fieldtype": "Column Break" + "fieldtype": "Column Break", + "show_days": 1, + "show_seconds": 1 }, { "fieldname": "price_list_rate", @@ -162,53 +197,80 @@ "oldfieldname": "ref_rate", "oldfieldtype": "Currency", "options": "currency", - "reqd": 1 + "reqd": 1, + "show_days": 1, + "show_seconds": 1 }, { "fieldname": "section_break_15", - "fieldtype": "Section Break" + "fieldtype": "Section Break", + "show_days": 1, + "show_seconds": 1 }, { "default": "Today", "fieldname": "valid_from", "fieldtype": "Date", - "label": "Valid From" + "label": "Valid From", + "show_days": 1, + "show_seconds": 1 }, { "default": "0", "fieldname": "lead_time_days", "fieldtype": "Int", - "label": "Lead Time in days" + "label": "Lead Time in days", + "show_days": 1, + "show_seconds": 1 }, { "fieldname": "column_break_18", - "fieldtype": "Column Break" + "fieldtype": "Column Break", + "show_days": 1, + "show_seconds": 1 }, { "fieldname": "valid_upto", "fieldtype": "Date", - "label": "Valid Upto" + "label": "Valid Upto", + "show_days": 1, + "show_seconds": 1 }, { "fieldname": "section_break_24", - "fieldtype": "Section Break" + "fieldtype": "Section Break", + "show_days": 1, + "show_seconds": 1 }, { "fieldname": "note", "fieldtype": "Text", - "label": "Note" + "label": "Note", + "show_days": 1, + "show_seconds": 1 }, { "fieldname": "reference", "fieldtype": "Data", "in_list_view": 1, - "label": "Reference" + "label": "Reference", + "show_days": 1, + "show_seconds": 1 + }, + { + "fieldname": "batch_no", + "fieldtype": "Link", + "label": "Batch No", + "options": "Batch", + "show_days": 1, + "show_seconds": 1 } ], "icon": "fa fa-flag", "idx": 1, + "index_web_pages_for_search": 1, "links": [], - "modified": "2020-07-06 22:31:32.943475", + "modified": "2020-12-08 18:12:15.395772", "modified_by": "Administrator", "module": "Stock", "name": "Item Price", diff --git a/erpnext/stock/doctype/item_price/item_price.py b/erpnext/stock/doctype/item_price/item_price.py index bed5ea9ab66..e82a19b0dc0 100644 --- a/erpnext/stock/doctype/item_price/item_price.py +++ b/erpnext/stock/doctype/item_price/item_price.py @@ -54,7 +54,8 @@ class ItemPrice(Document): "valid_upto", "packing_unit", "customer", - "supplier",]: + "supplier", + "batch_no"]: if self.get(field): conditions += " and {0} = %({0})s ".format(field) else: @@ -68,7 +69,7 @@ class ItemPrice(Document): self.as_dict(),) if price_list_rate: - frappe.throw(_("Item Price appears multiple times based on Price List, Supplier/Customer, Currency, Item, UOM, Qty, and Dates."), ItemPriceDuplicateItem,) + frappe.throw(_("Item Price appears multiple times based on Price List, Supplier/Customer, Currency, Item, Batch, UOM, Qty, and Dates."), ItemPriceDuplicateItem,) def before_save(self): if self.selling: diff --git a/erpnext/stock/get_item_details.py b/erpnext/stock/get_item_details.py index bf45251c9d8..dfe8fea67b9 100644 --- a/erpnext/stock/get_item_details.py +++ b/erpnext/stock/get_item_details.py @@ -674,6 +674,8 @@ def get_item_price(args, item_code, ignore_party=False): and price_list=%(price_list)s and ifnull(uom, '') in ('', %(uom)s)""" + conditions += "and ifnull(batch_no, '') in ('', %(batch_no)s)" + if not ignore_party: if args.get("customer"): conditions += " and customer=%(customer)s" @@ -692,7 +694,7 @@ def get_item_price(args, item_code, ignore_party=False): return frappe.db.sql(""" select name, price_list_rate, uom from `tabItem Price` {conditions} - order by valid_from desc, uom desc """.format(conditions=conditions), args) + order by valid_from desc, batch_no desc, uom desc """.format(conditions=conditions), args) def get_price_list_rate_for(args, item_code): """ @@ -711,6 +713,7 @@ def get_price_list_rate_for(args, item_code): "uom": args.get('uom'), "transaction_date": args.get('transaction_date'), "posting_date": args.get('posting_date'), + "batch_no": args.get('batch_no') } item_price_data = 0 From 16bcd01f6da00016130183c8552ddd3256a0ca70 Mon Sep 17 00:00:00 2001 From: Deepesh Garg <42651287+deepeshgarg007@users.noreply.github.com> Date: Thu, 28 Jan 2021 12:09:35 +0530 Subject: [PATCH 416/477] feat: Provision to disable serial no and batch selector (#24398) * feat: feat: Provision to disbale serial no and batch selector * fix: Sider issues * fix: Linting issues --- erpnext/public/js/controllers/transaction.js | 12 +++++++++++- .../stock/doctype/stock_settings/stock_settings.json | 9 ++++++++- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/erpnext/public/js/controllers/transaction.js b/erpnext/public/js/controllers/transaction.js index 77318332d25..1d1f18b1a0d 100644 --- a/erpnext/public/js/controllers/transaction.js +++ b/erpnext/public/js/controllers/transaction.js @@ -589,11 +589,21 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({ return frappe.db.get_value("Item", item.item_code, ["has_batch_no", "has_serial_no"]) .then((r) => { if (r.message && - (r.message.has_batch_no || r.message.has_serial_no)) { + (r.message.has_batch_no || r.message.has_serial_no)) { frappe.flags.hide_serial_batch_dialog = false; } }); }, + () => { + // check if batch serial selector is disabled or not + if (show_batch_dialog && !frappe.flags.hide_serial_batch_dialog) + return frappe.db.get_single_value('Stock Settings', 'disable_serial_no_and_batch_selector') + .then((value) => { + if (value) { + frappe.flags.hide_serial_batch_dialog = true; + } + }); + }, () => { if(show_batch_dialog && !frappe.flags.hide_serial_batch_dialog) { var d = locals[cdt][cdn]; diff --git a/erpnext/stock/doctype/stock_settings/stock_settings.json b/erpnext/stock/doctype/stock_settings/stock_settings.json index 3ff396ba77e..84af57b48dd 100644 --- a/erpnext/stock/doctype/stock_settings/stock_settings.json +++ b/erpnext/stock/doctype/stock_settings/stock_settings.json @@ -16,6 +16,7 @@ "action_if_quality_inspection_is_not_submitted", "show_barcode_field", "clean_description_html", + "disable_serial_no_and_batch_selector", "section_break_7", "auto_insert_price_list_rate_if_missing", "allow_negative_stock", @@ -227,6 +228,12 @@ "fieldname": "control_historical_stock_transactions_section", "fieldtype": "Section Break", "label": "Control Historical Stock Transactions" + }, + { + "default": "0", + "fieldname": "disable_serial_no_and_batch_selector", + "fieldtype": "Check", + "label": "Disable Serial No And Batch Selector" } ], "icon": "icon-cog", @@ -234,7 +241,7 @@ "index_web_pages_for_search": 1, "issingle": 1, "links": [], - "modified": "2020-12-29 12:53:31.162247", + "modified": "2021-01-18 13:15:38.352796", "modified_by": "Administrator", "module": "Stock", "name": "Stock Settings", From f6f4376463456c980fe8a380609484f11e577689 Mon Sep 17 00:00:00 2001 From: Raffael Meyer <14891507+barredterra@users.noreply.github.com> Date: Thu, 28 Jan 2021 07:46:26 +0100 Subject: [PATCH 417/477] feat: remove german sales invoice validation (#24441) This can be better achieved via Customize Form (mandatory and mandatory_depends_on) --- erpnext/hooks.py | 3 -- .../regional/germany/accounts_controller.py | 53 ------------------- .../germany/test_accounts_controller.py | 12 ----- 3 files changed, 68 deletions(-) delete mode 100644 erpnext/regional/germany/accounts_controller.py delete mode 100644 erpnext/regional/germany/test_accounts_controller.py diff --git a/erpnext/hooks.py b/erpnext/hooks.py index 14377e1b994..1c20555b827 100644 --- a/erpnext/hooks.py +++ b/erpnext/hooks.py @@ -416,9 +416,6 @@ regional_overrides = { 'Italy': { 'erpnext.controllers.taxes_and_totals.update_itemised_tax_data': 'erpnext.regional.italy.utils.update_itemised_tax_data', 'erpnext.controllers.accounts_controller.validate_regional': 'erpnext.regional.italy.utils.sales_invoice_validate', - }, - 'Germany': { - 'erpnext.controllers.accounts_controller.validate_regional': 'erpnext.regional.germany.accounts_controller.validate_regional', } } user_privacy_documents = [ diff --git a/erpnext/regional/germany/accounts_controller.py b/erpnext/regional/germany/accounts_controller.py deleted file mode 100644 index 7f76493608e..00000000000 --- a/erpnext/regional/germany/accounts_controller.py +++ /dev/null @@ -1,53 +0,0 @@ -import frappe -from frappe import _ -from frappe import msgprint - - -REQUIRED_FIELDS = { - "Sales Invoice": [ - { - "field_name": "company_address", - "regulation": "§ 14 Abs. 4 Nr. 1 UStG" - }, - { - "field_name": "company_tax_id", - "regulation": "§ 14 Abs. 4 Nr. 2 UStG" - }, - { - "field_name": "taxes", - "regulation": "§ 14 Abs. 4 Nr. 8 UStG" - }, - { - "field_name": "customer_address", - "regulation": "§ 14 Abs. 4 Nr. 1 UStG", - "condition": "base_grand_total > 250" - } - ] -} - - -def validate_regional(doc): - """Check if required fields for this document are present.""" - required_fields = REQUIRED_FIELDS.get(doc.doctype) - if not required_fields: - return - - meta = frappe.get_meta(doc.doctype) - field_map = {field.fieldname: field.label for field in meta.fields} - - for field in required_fields: - condition = field.get("condition") - if condition and not frappe.safe_eval(condition, doc.as_dict()): - continue - - field_name = field.get("field_name") - regulation = field.get("regulation") - if field_name and not doc.get(field_name): - missing(field_map.get(field_name), regulation) - - -def missing(field_label, regulation): - """Notify the user that a required field is missing.""" - translated_msg = _('Remember to set {field_label}. It is required by {regulation}.', context='Specific for Germany. Example: Remember to set Company Tax ID. It is required by § 14 Abs. 4 Nr. 2 UStG.') # noqa: E501 - formatted_msg = translated_msg.format(field_label=frappe.bold(_(field_label)), regulation=regulation) - msgprint(formatted_msg) diff --git a/erpnext/regional/germany/test_accounts_controller.py b/erpnext/regional/germany/test_accounts_controller.py deleted file mode 100644 index 8bd378c971f..00000000000 --- a/erpnext/regional/germany/test_accounts_controller.py +++ /dev/null @@ -1,12 +0,0 @@ -import frappe -import unittest -from erpnext.regional.germany.accounts_controller import validate_regional - - -class TestAccountsController(unittest.TestCase): - - def setUp(self): - self.sales_invoice = frappe.get_last_doc('Sales Invoice') - - def test_validate_regional(self): - validate_regional(self.sales_invoice) From e5529ad461e5f57c972c880371308e4e8db0f62a Mon Sep 17 00:00:00 2001 From: Afshan <33727827+AfshanKhan@users.noreply.github.com> Date: Thu, 28 Jan 2021 12:22:39 +0530 Subject: [PATCH 418/477] fix: validate tax template for tax category (#24402) * fix: validate tax template for tax category * Update sales_taxes_and_charges_template.py --- .../sales_taxes_and_charges_template.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/erpnext/accounts/doctype/sales_taxes_and_charges_template/sales_taxes_and_charges_template.py b/erpnext/accounts/doctype/sales_taxes_and_charges_template/sales_taxes_and_charges_template.py index b46de6c85bb..429a9f3591d 100644 --- a/erpnext/accounts/doctype/sales_taxes_and_charges_template/sales_taxes_and_charges_template.py +++ b/erpnext/accounts/doctype/sales_taxes_and_charges_template/sales_taxes_and_charges_template.py @@ -34,6 +34,9 @@ def valdiate_taxes_and_charges_template(doc): validate_disabled(doc) + # Validate with existing taxes and charges template for unique tax category + validate_for_tax_category(doc) + for tax in doc.get("taxes"): validate_taxes_and_charges(tax) validate_inclusive_tax(tax, doc) @@ -41,3 +44,7 @@ def valdiate_taxes_and_charges_template(doc): def validate_disabled(doc): if doc.is_default and doc.disabled: frappe.throw(_("Disabled template must not be default template")) + +def validate_for_tax_category(doc): + if frappe.db.exists(doc.doctype, {"company": doc.company, "tax_category": doc.tax_category, "disabled": 0}): + frappe.throw(_("A template with tax category {0} already exists. Only one template is allowed with each tax category").format(frappe.bold(doc.tax_category))) From 5756bf50e6d1d41cfbf7b028ee59baa7d48ebf3c Mon Sep 17 00:00:00 2001 From: Anurag Mishra <32095923+Anurag810@users.noreply.github.com> Date: Thu, 28 Jan 2021 12:24:39 +0530 Subject: [PATCH 419/477] fix: removed all day event from shift assignment calendar (#24397) Co-authored-by: Afshan <33727827+AfshanKhan@users.noreply.github.com> --- .../shift_assignment/shift_assignment.py | 48 ++++++++++++++----- .../shift_assignment_calendar.js | 10 +--- 2 files changed, 37 insertions(+), 21 deletions(-) diff --git a/erpnext/hr/doctype/shift_assignment/shift_assignment.py b/erpnext/hr/doctype/shift_assignment/shift_assignment.py index 2c385e80f46..ab65260c091 100644 --- a/erpnext/hr/doctype/shift_assignment/shift_assignment.py +++ b/erpnext/hr/doctype/shift_assignment/shift_assignment.py @@ -88,7 +88,7 @@ def get_events(start, end, filters=None): def add_assignments(events, start, end, conditions=None): query = """select name, start_date, end_date, employee_name, - employee, docstatus + employee, docstatus, shift_type from `tabShift Assignment` where start_date >= %(start_date)s or end_date <= %(end_date)s @@ -97,18 +97,40 @@ def add_assignments(events, start, end, conditions=None): if conditions: query += conditions - for d in frappe.db.sql(query, {"start_date":start, "end_date":end}, as_dict=True): - e = { - "name": d.name, - "doctype": "Shift Assignment", - "start_date": d.start_date, - "end_date": d.end_date if d.end_date else nowdate(), - "title": cstr(d.employee_name) + ": "+ \ - cstr(d.shift_type), - "docstatus": d.docstatus - } - if e not in events: - events.append(e) + records = frappe.db.sql(query, {"start_date":start, "end_date":end}, as_dict=True) + shift_timing_map = get_shift_type_timing([d.shift_type for d in records]) + + for d in records: + daily_event_start = d.start_date + daily_event_end = d.end_date if d.end_date else getdate() + delta = timedelta(days=1) + while daily_event_start <= daily_event_end: + start_timing = frappe.utils.get_datetime(daily_event_start)+ shift_timing_map[d.shift_type]['start_time'] + end_timing = frappe.utils.get_datetime(daily_event_start)+ shift_timing_map[d.shift_type]['end_time'] + daily_event_start += delta + e = { + "name": d.name, + "doctype": "Shift Assignment", + "start_date": start_timing, + "end_date": end_timing, + "title": cstr(d.employee_name) + ": "+ \ + cstr(d.shift_type), + "docstatus": d.docstatus, + "allDay": 0 + } + if e not in events: + events.append(e) + + return events + +def get_shift_type_timing(shift_types): + shift_timing_map = {} + data = frappe.get_all("Shift Type", filters = {"name": ("IN", shift_types)}, fields = ['name', 'start_time', 'end_time']) + + for d in data: + shift_timing_map[d.name] = d + + return shift_timing_map def get_employee_shift(employee, for_date=nowdate(), consider_default_shift=False, next_shift_direction=None): diff --git a/erpnext/hr/doctype/shift_assignment/shift_assignment_calendar.js b/erpnext/hr/doctype/shift_assignment/shift_assignment_calendar.js index 17a986deb21..bb692e1402e 100644 --- a/erpnext/hr/doctype/shift_assignment/shift_assignment_calendar.js +++ b/erpnext/hr/doctype/shift_assignment/shift_assignment_calendar.js @@ -6,14 +6,8 @@ frappe.views.calendar["Shift Assignment"] = { "start": "start_date", "end": "end_date", "id": "name", - "docstatus": 1 - }, - options: { - header: { - left: 'prev,next today', - center: 'title', - right: 'month' - } + "docstatus": 1, + "allDay": "allDay", }, get_events_method: "erpnext.hr.doctype.shift_assignment.shift_assignment.get_events" } \ No newline at end of file From 3914aca647f25592dffe66acb3d35b41a11f2a0c Mon Sep 17 00:00:00 2001 From: Jannat Patel <31363128+pateljannat@users.noreply.github.com> Date: Thu, 28 Jan 2021 12:25:15 +0530 Subject: [PATCH 420/477] fix: check for tax rate (#24376) --- erpnext/regional/report/gstr_1/gstr_1.py | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/erpnext/regional/report/gstr_1/gstr_1.py b/erpnext/regional/report/gstr_1/gstr_1.py index ad3de5f398d..96dc3f728d9 100644 --- a/erpnext/regional/report/gstr_1/gstr_1.py +++ b/erpnext/regional/report/gstr_1/gstr_1.py @@ -255,15 +255,16 @@ class Gstr1Report(object): for item_code, tax_amounts in item_wise_tax_detail.items(): tax_rate = tax_amounts[0] - if cgst_or_sgst: - tax_rate *= 2 - if parent not in self.cgst_sgst_invoices: - self.cgst_sgst_invoices.append(parent) + if tax_rate: + if cgst_or_sgst: + tax_rate *= 2 + if parent not in self.cgst_sgst_invoices: + self.cgst_sgst_invoices.append(parent) - rate_based_dict = self.items_based_on_tax_rate\ - .setdefault(parent, {}).setdefault(tax_rate, []) - if item_code not in rate_based_dict: - rate_based_dict.append(item_code) + rate_based_dict = self.items_based_on_tax_rate\ + .setdefault(parent, {}).setdefault(tax_rate, []) + if item_code not in rate_based_dict: + rate_based_dict.append(item_code) except ValueError: continue if unidentified_gst_accounts: From 8e55677f10fac3002983a4fbf9160dd5a9e53cb0 Mon Sep 17 00:00:00 2001 From: Saqib Date: Thu, 28 Jan 2021 12:26:45 +0530 Subject: [PATCH 421/477] feat: deleting account & stock entries on deletion of transaction (#24298) * feat: control for deleting account & stock entries on deletion of a transaction * chore: change label & fieldname Co-authored-by: Nabin Hait --- .../doctype/accounts_settings/accounts_settings.json | 11 +++++++++-- erpnext/controllers/accounts_controller.py | 6 ++++++ 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/erpnext/accounts/doctype/accounts_settings/accounts_settings.json b/erpnext/accounts/doctype/accounts_settings/accounts_settings.json index 41f9ce030a1..a3c29b6d640 100644 --- a/erpnext/accounts/doctype/accounts_settings/accounts_settings.json +++ b/erpnext/accounts/doctype/accounts_settings/accounts_settings.json @@ -21,6 +21,7 @@ "book_asset_depreciation_entry_automatically", "add_taxes_from_item_tax_template", "automatically_fetch_payment_terms", + "delete_linked_ledger_entries", "deferred_accounting_settings_section", "automatically_process_deferred_accounting_entry", "book_deferred_entries_based_on", @@ -219,6 +220,12 @@ "fieldtype": "Select", "label": "Book Deferred Entries Based On", "options": "Days\nMonths" + }, + { + "default": "0", + "fieldname": "delete_linked_ledger_entries", + "fieldtype": "Check", + "label": "Delete Accounting and Stock Ledger Entries on deletion of Transaction" } ], "icon": "icon-cog", @@ -226,7 +233,7 @@ "index_web_pages_for_search": 1, "issingle": 1, "links": [], - "modified": "2020-10-13 11:32:52.268826", + "modified": "2021-01-05 13:04:00.118892", "modified_by": "Administrator", "module": "Accounts", "name": "Accounts Settings", @@ -254,4 +261,4 @@ "sort_field": "modified", "sort_order": "ASC", "track_changes": 1 -} +} \ No newline at end of file diff --git a/erpnext/controllers/accounts_controller.py b/erpnext/controllers/accounts_controller.py index 0f1aa23064c..b9bfbaf0bd3 100644 --- a/erpnext/controllers/accounts_controller.py +++ b/erpnext/controllers/accounts_controller.py @@ -118,6 +118,12 @@ class AccountsController(TransactionBase): def before_cancel(self): validate_einvoice_fields(self) + + def on_trash(self): + # delete sl and gl entries on deletion of transaction + if frappe.db.get_single_value('Accounts Settings', 'delete_linked_ledger_entries'): + frappe.db.sql("delete from `tabGL Entry` where voucher_type=%s and voucher_no=%s", (self.doctype, self.name)) + frappe.db.sql("delete from `tabStock Ledger Entry` where voucher_type=%s and voucher_no=%s", (self.doctype, self.name)) def validate_deferred_start_and_end_date(self): for d in self.items: From 9f8cbe91013c49126c8be3b4164343fd1ee6eab9 Mon Sep 17 00:00:00 2001 From: Jannat Patel <31363128+pateljannat@users.noreply.github.com> Date: Thu, 28 Jan 2021 12:29:52 +0530 Subject: [PATCH 422/477] Material request wrong status issue (#24019) * fix: material request status fix * fix: changing precision to global defaults for material request status * fix: adding back the removed flt * fix: sider issues fixed Co-authored-by: pateljannat --- .../doctype/purchase_order/purchase_order.js | 2 +- .../request_for_quotation.js | 4 ++-- .../supplier_quotation/supplier_quotation.js | 2 +- .../material_request/material_request_list.js | 15 ++++++++------- 4 files changed, 12 insertions(+), 11 deletions(-) diff --git a/erpnext/buying/doctype/purchase_order/purchase_order.js b/erpnext/buying/doctype/purchase_order/purchase_order.js index 14534ef1b75..83efa66f6b0 100644 --- a/erpnext/buying/doctype/purchase_order/purchase_order.js +++ b/erpnext/buying/doctype/purchase_order/purchase_order.js @@ -381,7 +381,7 @@ erpnext.buying.PurchaseOrderController = erpnext.buying.BuyingController.extend( material_request_type: "Purchase", docstatus: 1, status: ["!=", "Stopped"], - per_ordered: ["<", 99.99], + per_ordered: ["<", 100], company: me.frm.doc.company } }) diff --git a/erpnext/buying/doctype/request_for_quotation/request_for_quotation.js b/erpnext/buying/doctype/request_for_quotation/request_for_quotation.js index e537771eaf2..b76c3784a47 100644 --- a/erpnext/buying/doctype/request_for_quotation/request_for_quotation.js +++ b/erpnext/buying/doctype/request_for_quotation/request_for_quotation.js @@ -224,7 +224,7 @@ erpnext.buying.RequestforQuotationController = erpnext.buying.BuyingController.e material_request_type: "Purchase", docstatus: 1, status: ["!=", "Stopped"], - per_ordered: ["<", 99.99], + per_ordered: ["<", 100], company: me.frm.doc.company } }) @@ -280,7 +280,7 @@ erpnext.buying.RequestforQuotationController = erpnext.buying.BuyingController.e material_request_type: "Purchase", docstatus: 1, status: ["!=", "Stopped"], - per_ordered: ["<", 99.99] + per_ordered: ["<", 100] } }); dialog.hide(); diff --git a/erpnext/buying/doctype/supplier_quotation/supplier_quotation.js b/erpnext/buying/doctype/supplier_quotation/supplier_quotation.js index a3b2085400e..a0187b0a824 100644 --- a/erpnext/buying/doctype/supplier_quotation/supplier_quotation.js +++ b/erpnext/buying/doctype/supplier_quotation/supplier_quotation.js @@ -44,7 +44,7 @@ erpnext.buying.SupplierQuotationController = erpnext.buying.BuyingController.ext material_request_type: "Purchase", docstatus: 1, status: ["!=", "Stopped"], - per_ordered: ["<", 99.99], + per_ordered: ["<", 100], company: me.frm.doc.company } }) diff --git a/erpnext/stock/doctype/material_request/material_request_list.js b/erpnext/stock/doctype/material_request/material_request_list.js index 0d7095875c6..de7a3d05bf5 100644 --- a/erpnext/stock/doctype/material_request/material_request_list.js +++ b/erpnext/stock/doctype/material_request/material_request_list.js @@ -1,9 +1,10 @@ frappe.listview_settings['Material Request'] = { add_fields: ["material_request_type", "status", "per_ordered", "per_received", "transfer_status"], get_indicator: function(doc) { - if(doc.status=="Stopped") { + var precision = frappe.defaults.get_default("float_precision"); + if (doc.status=="Stopped") { return [__("Stopped"), "red", "status,=,Stopped"]; - } else if(doc.transfer_status && doc.docstatus != 2) { + } else if (doc.transfer_status && doc.docstatus != 2) { if (doc.transfer_status == "Not Started") { return [__("Not Started"), "orange"]; } else if (doc.transfer_status == "In Transit") { @@ -11,14 +12,14 @@ frappe.listview_settings['Material Request'] = { } else if (doc.transfer_status == "Completed") { return [__("Completed"), "green"]; } - } else if(doc.docstatus==1 && flt(doc.per_ordered, 2) == 0) { + } else if (doc.docstatus==1 && flt(doc.per_ordered, precision) == 0) { return [__("Pending"), "orange", "per_ordered,=,0"]; - } else if(doc.docstatus==1 && flt(doc.per_ordered, 2) < 100) { + } else if (doc.docstatus==1 && flt(doc.per_ordered, precision) < 100) { return [__("Partially ordered"), "yellow", "per_ordered,<,100"]; - } else if(doc.docstatus==1 && flt(doc.per_ordered, 2) == 100) { - if (doc.material_request_type == "Purchase" && flt(doc.per_received, 2) < 100 && flt(doc.per_received, 2) > 0) { + } else if (doc.docstatus==1 && flt(doc.per_ordered, precision) == 100) { + if (doc.material_request_type == "Purchase" && flt(doc.per_received, precision) < 100 && flt(doc.per_received, precision) > 0) { return [__("Partially Received"), "yellow", "per_received,<,100"]; - } else if (doc.material_request_type == "Purchase" && flt(doc.per_received, 2) == 100) { + } else if (doc.material_request_type == "Purchase" && flt(doc.per_received, precision) == 100) { return [__("Received"), "green", "per_received,=,100"]; } else if (doc.material_request_type == "Purchase") { return [__("Ordered"), "green", "per_ordered,=,100"]; From f7ea340181acd3fdde2c185a8d1c36fb75e04e6e Mon Sep 17 00:00:00 2001 From: Mohamed Almubarak <59777434+madar2020@users.noreply.github.com> Date: Thu, 28 Jan 2021 10:02:13 +0300 Subject: [PATCH 423/477] fix(template): cards on second row overlaps the one before (#23454) * Update macros.html fix second row of cards overlapps with the one before * Update macros.html fix(template): second row of cards overlaps with the one before * Update macros.html fix(template): second row of cards overlaps with the one before --- erpnext/templates/includes/macros.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/templates/includes/macros.html b/erpnext/templates/includes/macros.html index ea6b00fc58a..5d8ee5cab6d 100644 --- a/erpnext/templates/includes/macros.html +++ b/erpnext/templates/includes/macros.html @@ -40,7 +40,7 @@
    {% if card.image %} -
    +
    {% endif %}
    {{ card.title }}
    From b4be2922173ed74a04a02cfb5d1fdd5976459f85 Mon Sep 17 00:00:00 2001 From: Deepesh Garg <42651287+deepeshgarg007@users.noreply.github.com> Date: Thu, 28 Jan 2021 13:09:56 +0530 Subject: [PATCH 424/477] fix: Item valuation for internal stock transfers (#24200) * fix: Item valuation for internal stocktransfers * fix: Consider conversion factor for invoices * fix: Add missing set warehouse fields * fix: Add validations and other fixes * fix: Fixes in flow * fix: Internal sales item link in Purchase Invoice * fix: Debugging * fix: Debug travis * fix: Remove commented code * fix: Rate forcing in sales order * fix: Unreallized profit in Sales Register * fix: Item wise gst sales register fix * fix: From warehouse in Purchase Order * fix: Target field in Sales Invoice * fix: remove self * fix: GST Purchasse register and other fixes * fix: Add shipping_address to no field map * fix: Ref doc map * fix: Test Cases * fix: address mapping between sales and purchase document * fix: Import Error * fix: Tax updation for internal invoices * fix: Purchase Order and Invoice linking * fix: Internal Party validation fix * fix: validation * fix(india): GST Taxes for intra state transfer * fix(india): GST Taxes for intra state transfer Co-authored-by: Nabin Hait --- .../purchase_invoice/purchase_invoice.js | 5 +- .../purchase_invoice/purchase_invoice.json | 30 ++-- .../purchase_invoice/purchase_invoice.py | 54 +++--- .../purchase_invoice_item.json | 26 ++- .../doctype/sales_invoice/sales_invoice.js | 19 +-- .../doctype/sales_invoice/sales_invoice.json | 15 +- .../doctype/sales_invoice/sales_invoice.py | 157 ++++++++++++++++-- .../sales_invoice/test_sales_invoice.py | 114 ++++++++----- .../sales_invoice_item.json | 5 +- .../item_wise_purchase_register.py | 4 +- .../item_wise_sales_register.py | 3 +- .../purchase_register/purchase_register.py | 41 ++++- .../report/sales_register/sales_register.py | 59 ++++++- .../doctype/purchase_order/purchase_order.js | 20 +-- .../purchase_order/purchase_order.json | 19 ++- erpnext/buying/doctype/supplier/supplier.py | 5 +- erpnext/controllers/accounts_controller.py | 22 ++- erpnext/controllers/buying_controller.py | 52 +++++- erpnext/controllers/selling_controller.py | 28 +++- erpnext/controllers/stock_controller.py | 30 +++- erpnext/public/js/controllers/transaction.js | 49 +++++- erpnext/public/js/utils/party.js | 6 + erpnext/regional/india/taxes.js | 6 +- erpnext/regional/india/utils.py | 2 +- erpnext/selling/doctype/customer/customer.py | 5 +- .../doctype/sales_order/sales_order.js | 23 +-- .../doctype/sales_order/sales_order.json | 23 ++- .../doctype/delivery_note/delivery_note.js | 29 ++-- .../doctype/delivery_note/delivery_note.json | 38 +++-- .../doctype/delivery_note/delivery_note.py | 31 +++- .../delivery_note_item.json | 7 +- .../purchase_receipt/purchase_receipt.json | 22 ++- .../purchase_receipt_item.json | 14 +- erpnext/stock/stock_ledger.py | 29 ++-- 34 files changed, 749 insertions(+), 243 deletions(-) diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js index 4a952a30a26..06aa20bfc5a 100644 --- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js +++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js @@ -275,8 +275,11 @@ erpnext.accounts.PurchaseInvoice = erpnext.buying.BuyingController.extend({ supplier: function() { var me = this; - if(this.frm.updating_party_details) + + // Do not update if inter company reference is there as the details will already be updated + if(this.frm.updating_party_details || this.frm.doc.inter_company_invoice_reference) return; + erpnext.utils.get_party_details(this.frm, "erpnext.accounts.party.get_party_details", { posting_date: this.frm.doc.posting_date, diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json index c64ffd878c4..451c9368816 100644 --- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json +++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json @@ -57,8 +57,8 @@ "set_warehouse", "rejected_warehouse", "col_break_warehouse", + "set_from_warehouse", "is_subcontracted", - "supplier_warehouse", "items_section", "update_stock", "scan_barcode", @@ -515,6 +515,7 @@ }, { "depends_on": "update_stock", + "description": "Sets 'Accepted Warehouse' in each row of the items table.", "fieldname": "set_warehouse", "fieldtype": "Link", "label": "Set Accepted Warehouse", @@ -543,17 +544,6 @@ "options": "No\nYes", "print_hide": 1 }, - { - "depends_on": "eval:doc.is_subcontracted==\"Yes\"", - "fieldname": "supplier_warehouse", - "fieldtype": "Link", - "label": "Supplier Warehouse", - "no_copy": 1, - "options": "Warehouse", - "print_hide": 1, - "print_width": "50px", - "width": "50px" - }, { "fieldname": "items_section", "fieldtype": "Section Break", @@ -1232,7 +1222,9 @@ "fieldname": "inter_company_invoice_reference", "fieldtype": "Link", "label": "Inter Company Invoice Reference", + "no_copy": 1, "options": "Sales Invoice", + "print_hide": 1, "read_only": 1 }, { @@ -1356,13 +1348,25 @@ "fieldtype": "Link", "label": "Represents Company", "options": "Company" + }, + { + "depends_on": "eval:doc.update_stock && (doc.is_subcontracted==\"Yes\" || doc.is_internal_supplier)", + "description": "Sets 'From Warehouse' in each row of the items table.", + "fieldname": "set_from_warehouse", + "fieldtype": "Link", + "label": "Set From Warehouse", + "no_copy": 1, + "options": "Warehouse", + "print_hide": 1, + "print_width": "50px", + "width": "50px" } ], "icon": "fa fa-file-text", "idx": 204, "is_submittable": 1, "links": [], - "modified": "2020-12-11 12:46:12.796378", + "modified": "2020-12-26 20:49:03.305063", "modified_by": "Administrator", "module": "Accounts", "name": "Purchase Invoice", diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py index b52678e8d3b..56feb573c27 100644 --- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py +++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py @@ -443,7 +443,7 @@ class PurchaseInvoice(BuyingController): else: self.stock_received_but_not_billed = None self.expenses_included_in_valuation = None - + self.negative_expense_to_be_booked = 0.0 gl_entries = [] @@ -457,7 +457,7 @@ class PurchaseInvoice(BuyingController): self.make_internal_transfer_gl_entries(gl_entries) gl_entries = make_regional_gl_entries(gl_entries, self) - + gl_entries = merge_similar_entries(gl_entries) self.make_payment_gl_entries(gl_entries) @@ -480,7 +480,7 @@ class PurchaseInvoice(BuyingController): grand_total = self.rounded_total if (self.rounding_adjustment and self.rounded_total) else self.grand_total if grand_total and not self.is_internal_transfer(): - # Didnot use base_grand_total to book rounding loss gle + # Did not use base_grand_total to book rounding loss gle grand_total_in_company_currency = flt(grand_total * self.conversion_rate, self.precision("grand_total")) gl_entries.append( @@ -511,8 +511,8 @@ class PurchaseInvoice(BuyingController): voucher_wise_stock_value = {} if self.update_stock: for d in frappe.get_all('Stock Ledger Entry', - fields = ["voucher_detail_no", "stock_value_difference"], filters={'voucher_no': self.name}): - voucher_wise_stock_value.setdefault(d.voucher_detail_no, d.stock_value_difference) + fields = ["voucher_detail_no", "stock_value_difference", "warehouse"], filters={'voucher_no': self.name}): + voucher_wise_stock_value.setdefault((d.voucher_detail_no, d.warehouse), d.stock_value_difference) valuation_tax_accounts = [d.account_head for d in self.get("taxes") if d.category in ('Valuation', 'Total and Valuation') @@ -563,16 +563,17 @@ class PurchaseInvoice(BuyingController): ) else: - gl_entries.append( - self.get_gl_dict({ - "account": item.expense_account, - "against": self.supplier, - "debit": warehouse_debit_amount, - "remarks": self.get("remarks") or _("Accounting Entry for Stock"), - "cost_center": item.cost_center, - "project": item.project or self.project - }, account_currency, item=item) - ) + if not self.is_internal_transfer(): + gl_entries.append( + self.get_gl_dict({ + "account": item.expense_account, + "against": self.supplier, + "debit": warehouse_debit_amount, + "remarks": self.get("remarks") or _("Accounting Entry for Stock"), + "cost_center": item.cost_center, + "project": item.project or self.project + }, account_currency, item=item) + ) # Amount added through landed-cost-voucher if landed_cost_entries: @@ -624,13 +625,14 @@ class PurchaseInvoice(BuyingController): if expense_booked_in_pr: expense_account = service_received_but_not_billed_account - gl_entries.append(self.get_gl_dict({ - "account": expense_account, - "against": self.supplier, - "debit": amount, - "cost_center": item.cost_center, - "project": item.project or self.project - }, account_currency, item=item)) + if not self.is_internal_transfer(): + gl_entries.append(self.get_gl_dict({ + "account": expense_account, + "against": self.supplier, + "debit": amount, + "cost_center": item.cost_center, + "project": item.project or self.project + }, account_currency, item=item)) # If asset is bought through this document and not linked to PR if self.update_stock and item.landed_cost_voucher_amount: @@ -795,10 +797,10 @@ class PurchaseInvoice(BuyingController): # Stock ledger value is not matching with the warehouse amount if (self.update_stock and voucher_wise_stock_value.get(item.name) and - warehouse_debit_amount != flt(voucher_wise_stock_value.get(item.name), net_amt_precision)): + warehouse_debit_amount != flt(voucher_wise_stock_value.get((item.name, item.warehouse)), net_amt_precision)): cost_of_goods_sold_account = self.get_company_default("default_expense_account") - stock_amount = flt(voucher_wise_stock_value.get(item.name), net_amt_precision) + stock_amount = flt(voucher_wise_stock_value.get((item.name, item.warehouse)), net_amt_precision) stock_adjustment_amt = warehouse_debit_amount - stock_amount gl_entries.append( @@ -999,10 +1001,10 @@ class PurchaseInvoice(BuyingController): self.delete_auto_created_batches() self.make_gl_entries_on_cancel() - + if self.update_stock == 1: self.repost_future_sle_and_gle() - + self.update_project() frappe.db.set(self, 'status', 'Cancelled') diff --git a/erpnext/accounts/doctype/purchase_invoice_item/purchase_invoice_item.json b/erpnext/accounts/doctype/purchase_invoice_item/purchase_invoice_item.json index f6d76e50502..1f7853dbf71 100644 --- a/erpnext/accounts/doctype/purchase_invoice_item/purchase_invoice_item.json +++ b/erpnext/accounts/doctype/purchase_invoice_item/purchase_invoice_item.json @@ -1,4 +1,5 @@ { + "actions": [], "autoname": "hash", "creation": "2013-05-22 12:43:10", "doctype": "DocType", @@ -87,6 +88,7 @@ "po_detail", "purchase_receipt", "pr_detail", + "sales_invoice_item", "item_weight_details", "weight_per_unit", "total_weight", @@ -553,8 +555,8 @@ "fieldtype": "Link", "hidden": 1, "label": "Brand", - "print_hide": 1, - "options": "Brand" + "options": "Brand", + "print_hide": 1 }, { "fetch_from": "item_code.item_group", @@ -562,9 +564,9 @@ "fieldname": "item_group", "fieldtype": "Link", "label": "Item Group", + "options": "Item Group", "print_hide": 1, - "read_only": 1, - "options": "Item Group" + "read_only": 1 }, { "description": "Tax detail table fetched from item master as a string and stored in this field.\nUsed for Taxes and Charges", @@ -759,10 +761,11 @@ "read_only": 1 }, { + "depends_on": "eval:parent.is_internal_supplier && parent.update_stock", "fieldname": "from_warehouse", "fieldtype": "Link", "ignore_user_permissions": 1, - "label": "Supplier Warehouse", + "label": "From Warehouse", "options": "Warehouse" }, { @@ -779,11 +782,20 @@ "no_copy": 1, "print_hide": 1, "read_only": 1 + }, + { + "fieldname": "sales_invoice_item", + "fieldtype": "Data", + "label": "Sales Invoice Item", + "no_copy": 1, + "print_hide": 1, + "read_only": 1 } ], "idx": 1, "istable": 1, - "modified": "2020-08-20 11:48:01.398356", + "links": [], + "modified": "2020-12-26 17:20:36.415791", "modified_by": "Administrator", "module": "Accounts", "name": "Purchase Invoice Item", @@ -791,4 +803,4 @@ "permissions": [], "sort_field": "modified", "sort_order": "DESC" -} +} \ No newline at end of file diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.js b/erpnext/accounts/doctype/sales_invoice/sales_invoice.js index 72199a92aa2..f2a62cdacd1 100644 --- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.js +++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.js @@ -130,16 +130,15 @@ erpnext.accounts.SalesInvoiceController = erpnext.selling.SellingController.exte this.set_default_print_format(); if (doc.docstatus == 1 && !doc.inter_company_invoice_reference) { - frappe.model.with_doc("Customer", me.frm.doc.customer, function() { - var customer = frappe.model.get_doc("Customer", me.frm.doc.customer); - var internal = customer.is_internal_customer; - var disabled = customer.disabled; - if (internal == 1 && disabled == 0) { - me.frm.add_custom_button("Inter Company Invoice", function() { - me.make_inter_company_invoice(); - }, __('Create')); - } - }); + let internal = me.frm.doc.is_internal_customer; + if (internal) { + let button_label = (me.frm.doc.company === me.frm.doc.represents_company) ? "Internal Purchase Invoice" : + "Inter Company Purchase Invoice"; + + me.frm.add_custom_button(button_label, function() { + me.make_inter_company_invoice(); + }, __('Create')); + } } }, diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.json b/erpnext/accounts/doctype/sales_invoice/sales_invoice.json index 6799fb986aa..447cee42a75 100644 --- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.json +++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.json @@ -60,6 +60,8 @@ "ignore_pricing_rule", "sec_warehouse", "set_warehouse", + "column_break_55", + "set_target_warehouse", "items_section", "update_stock", "scan_barcode", @@ -1969,13 +1971,24 @@ "label": "Represents Company", "options": "Company", "read_only": 1 + }, + { + "fieldname": "column_break_55", + "fieldtype": "Column Break" + }, + { + "depends_on": "eval: doc.is_internal_customer && doc.update_stock", + "fieldname": "set_target_warehouse", + "fieldtype": "Link", + "label": "Set Target Warehouse", + "options": "Warehouse" } ], "icon": "fa fa-file-text", "idx": 181, "is_submittable": 1, "links": [], - "modified": "2020-12-11 12:48:31.769958", + "modified": "2020-12-25 22:57:32.555067", "modified_by": "Administrator", "module": "Accounts", "name": "Sales Invoice", diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py index 566734e7d14..7116a6a62b0 100644 --- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py +++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py @@ -6,7 +6,7 @@ import frappe, erpnext import frappe.defaults from frappe.utils import cint, flt, getdate, add_days, cstr, nowdate, get_link_to_form, formatdate from frappe import _, msgprint, throw -from erpnext.accounts.party import get_party_account, get_due_date +from erpnext.accounts.party import get_party_account, get_due_date, get_party_details from frappe.model.mapper import get_mapped_doc from erpnext.controllers.selling_controller import SellingController from erpnext.accounts.utils import get_account_currency @@ -21,6 +21,8 @@ from erpnext.accounts.general_ledger import get_round_off_account_and_cost_cente from erpnext.accounts.doctype.loyalty_program.loyalty_program import \ get_loyalty_program_details_with_points, get_loyalty_details, validate_loyalty_points from erpnext.accounts.deferred_revenue import validate_service_stop_date +from frappe.model.utils import get_fetch_values +from frappe.contacts.doctype.address.address import get_address_display from erpnext.healthcare.utils import manage_invoice_submit_cancel @@ -1534,7 +1536,7 @@ def validate_inter_company_transaction(doc, doctype): details = get_inter_company_details(doc, doctype) price_list = doc.selling_price_list if doctype in ["Sales Invoice", "Sales Order", "Delivery Note"] else doc.buying_price_list valid_price_list = frappe.db.get_value("Price List", {"name": price_list, "buying": 1, "selling": 1}) - if not valid_price_list: + if not valid_price_list and not doc.is_internal_transfer(): frappe.throw(_("Selected Price List should have buying and selling fields checked.")) party = details.get("party") @@ -1557,6 +1559,7 @@ def make_inter_company_transaction(doctype, source_name, target_doc=None): if doctype in ["Sales Invoice", "Sales Order"]: source_doc = frappe.get_doc(doctype, source_name) target_doctype = "Purchase Invoice" if doctype == "Sales Invoice" else "Purchase Order" + target_detail_field = "sales_invoice_item" if doctype == "Sales Invoice" else "sales_order_item" source_document_warehouse_field = 'target_warehouse' target_document_warehouse_field = 'from_warehouse' else: @@ -1570,6 +1573,7 @@ def make_inter_company_transaction(doctype, source_name, target_doc=None): def set_missing_values(source, target): target.run_method("set_missing_values") + set_purchase_references(target) def update_details(source_doc, target_doc, source_parent): target_doc.inter_company_invoice_reference = source_doc.name @@ -1577,19 +1581,38 @@ def make_inter_company_transaction(doctype, source_name, target_doc=None): currency = frappe.db.get_value('Supplier', details.get('party'), 'default_currency') target_doc.company = details.get("company") target_doc.supplier = details.get("party") + target_doc.is_internal_supplier = 1 + target_doc.ignore_pricing_rule = 1 target_doc.buying_price_list = source_doc.selling_price_list + # Invert Addresses + update_address(target_doc, 'supplier_address', 'address_display', source_doc.company_address) + update_address(target_doc, 'shipping_address', 'shipping_address_display', source_doc.customer_address) + if currency: target_doc.currency = currency + + update_taxes(target_doc, party=target_doc.supplier, party_type='Supplier', company=target_doc.company, + doctype=target_doc.doctype, party_address=target_doc.supplier_address, + company_address=target_doc.shipping_address) + else: currency = frappe.db.get_value('Customer', details.get('party'), 'default_currency') target_doc.company = details.get("company") target_doc.customer = details.get("party") target_doc.selling_price_list = source_doc.buying_price_list + update_address(target_doc, 'company_address', 'company_address_display', source_doc.supplier_address) + update_address(target_doc, 'shipping_address_name', 'shipping_address', source_doc.shipping_address) + update_address(target_doc, 'customer_address', 'address_display', source_doc.shipping_address) + if currency: target_doc.currency = currency + update_taxes(target_doc, party=target_doc.customer, party_type='Customer', company=target_doc.company, + doctype=target_doc.doctype, party_address=target_doc.customer_address, + company_address=target_doc.company_address, shipping_address_name=target_doc.shipping_address_name) + item_field_map = { "doctype": target_doctype + " Item", "field_no_map": [ @@ -1597,25 +1620,33 @@ def make_inter_company_transaction(doctype, source_name, target_doc=None): "expense_account", "cost_center", "warehouse" - ] + ], + "field_map": { + 'rate': 'rate', + } } - if source_doc.get('update_stock'): - item_field_map.update({ - 'field_map': { - source_document_warehouse_field: target_document_warehouse_field, - 'batch_no': 'batch_no', - 'serial_no': 'serial_no' - } + if doctype in ["Sales Invoice", "Sales Order"]: + item_field_map["field_map"].update({ + "name": target_detail_field, }) + if source_doc.get('update_stock'): + item_field_map["field_map"].update({ + source_document_warehouse_field: target_document_warehouse_field, + 'batch_no': 'batch_no', + 'serial_no': 'serial_no' + }) doclist = get_mapped_doc(doctype, source_name, { doctype: { "doctype": target_doctype, "postprocess": update_details, + "set_target_warehouse": "set_from_warehouse", "field_no_map": [ - "taxes_and_charges" + "taxes_and_charges", + "set_warehouse", + "shipping_address" ] }, doctype +" Item": item_field_map @@ -1624,6 +1655,110 @@ def make_inter_company_transaction(doctype, source_name, target_doc=None): return doclist +def set_purchase_references(doc): + # add internal PO or PR links if any + if doc.is_internal_transfer(): + if doc.doctype == 'Purchase Receipt': + so_item_map = get_delivery_note_details(doc.inter_company_invoice_reference) + + if so_item_map: + pd_item_map, parent_child_map, warehouse_map = \ + get_pd_details('Purchase Order Item', so_item_map, 'sales_order_item') + + update_pr_items(doc, so_item_map, pd_item_map, parent_child_map, warehouse_map) + + elif doc.doctype == 'Purchase Invoice': + dn_item_map, so_item_map = get_sales_invoice_details(doc.inter_company_invoice_reference) + # First check for Purchase receipt + if list(dn_item_map.values()): + pd_item_map, parent_child_map, warehouse_map = \ + get_pd_details('Purchase Receipt Item', dn_item_map, 'delivery_note_item') + + update_pi_items(doc, 'pr_detail', 'purchase_receipt', + dn_item_map, pd_item_map, parent_child_map, warehouse_map) + + if list(so_item_map.values()): + pd_item_map, parent_child_map, warehouse_map = \ + get_pd_details('Purchase Order Item', so_item_map, 'sales_order_item') + + update_pi_items(doc, 'po_detail', 'purchase_order', + so_item_map, pd_item_map, parent_child_map, warehouse_map) + +def update_pi_items(doc, detail_field, parent_field, sales_item_map, + purchase_item_map, parent_child_map, warehouse_map): + for item in doc.get('items'): + item.set(detail_field, purchase_item_map.get(sales_item_map.get(item.sales_invoice_item))) + item.set(parent_field, parent_child_map.get(sales_item_map.get(item.sales_invoice_item))) + if doc.update_stock: + item.warehouse = warehouse_map.get(sales_item_map.get(item.sales_invoice_item)) + +def update_pr_items(doc, sales_item_map, purchase_item_map, parent_child_map, warehouse_map): + for item in doc.get('items'): + item.purchase_order_item = purchase_item_map.get(sales_item_map.get(item.delivery_note_item)) + item.warehouse = warehouse_map.get(sales_item_map.get(item.delivery_note_item)) + item.purchase_order = parent_child_map.get(sales_item_map.get(item.delivery_note_item)) + +def get_delivery_note_details(internal_reference): + so_item_map = {} + + si_item_details = frappe.get_all('Delivery Note Item', fields=['name', 'so_detail'], + filters={'parent': internal_reference}) + + for d in si_item_details: + so_item_map.setdefault(d.name, d.so_detail) + + return so_item_map + +def get_sales_invoice_details(internal_reference): + dn_item_map = {} + so_item_map = {} + + si_item_details = frappe.get_all('Sales Invoice Item', fields=['name', 'so_detail', + 'dn_detail'], filters={'parent': internal_reference}) + + for d in si_item_details: + if d.dn_detail: + dn_item_map.setdefault(d.name, d.dn_detail) + if d.so_detail: + so_item_map.setdefault(d.name, d.so_detail) + + return dn_item_map, so_item_map + +def get_pd_details(doctype, sd_detail_map, sd_detail_field): + pd_item_map = {} + accepted_warehouse_map = {} + parent_child_map = {} + + pd_item_details = frappe.get_all(doctype, + fields=[sd_detail_field, 'name', 'warehouse', 'parent'], filters={sd_detail_field: ('in', list(sd_detail_map.values()))}) + + for d in pd_item_details: + pd_item_map.setdefault(d.get(sd_detail_field), d.name) + parent_child_map.setdefault(d.get(sd_detail_field), d.parent) + accepted_warehouse_map.setdefault(d.get(sd_detail_field), d.warehouse) + + return pd_item_map, parent_child_map, accepted_warehouse_map + +def update_taxes(doc, party=None, party_type=None, company=None, doctype=None, party_address=None, + company_address=None, shipping_address_name=None, master_doctype=None): + # Update Party Details + party_details = get_party_details(party=party, party_type=party_type, company=company, + doctype=doctype, party_address=party_address, company_address=company_address, + shipping_address=shipping_address_name) + + # Update taxes and charges if any + doc.taxes_and_charges = party_details.get('taxes_and_charges') + doc.set('taxes', party_details.get('taxes')) + +def update_address(doc, address_field, address_display_field, address_name): + doc.set(address_field, address_name) + fetch_values = get_fetch_values(doc.doctype, address_field, address_name) + + for key, value in fetch_values.items(): + doc.set(key, value) + + doc.set(address_display_field, get_address_display(doc.get(address_field))) + @frappe.whitelist() def get_loyalty_programs(customer): ''' sets applicable loyalty program to the customer or returns a list of applicable programs ''' diff --git a/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py index 3a6dbeb51c2..e94e2cdd957 100644 --- a/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py +++ b/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py @@ -22,6 +22,7 @@ from erpnext.regional.india.utils import get_ewb_data from erpnext.stock.doctype.stock_entry.stock_entry_utils import make_stock_entry from erpnext.stock.doctype.purchase_receipt.test_purchase_receipt import make_purchase_receipt from erpnext.stock.doctype.delivery_note.delivery_note import make_sales_invoice +from erpnext.stock.utils import get_incoming_rate class TestSalesInvoice(unittest.TestCase): def make(self): @@ -688,7 +689,7 @@ class TestSalesInvoice(unittest.TestCase): self.assertTrue(gle) def test_pos_gl_entry_with_perpetual_inventory(self): - make_pos_profile(company="_Test Company with perpetual inventory", income_account = "Sales - TCP1", + make_pos_profile(company="_Test Company with perpetual inventory", income_account = "Sales - TCP1", expense_account = "Cost of Goods Sold - TCP1", warehouse="Stores - TCP1", cost_center = "Main - TCP1", write_off_account="_Test Write Off - TCP1") pr = make_purchase_receipt(company= "_Test Company with perpetual inventory", item_code= "_Test FG Item",warehouse= "Stores - TCP1",cost_center= "Main - TCP1") @@ -745,7 +746,7 @@ class TestSalesInvoice(unittest.TestCase): self.assertEqual(pos_return.get('payments')[0].amount, -1000) def test_pos_change_amount(self): - make_pos_profile(company="_Test Company with perpetual inventory", income_account = "Sales - TCP1", + make_pos_profile(company="_Test Company with perpetual inventory", income_account = "Sales - TCP1", expense_account = "Cost of Goods Sold - TCP1", warehouse="Stores - TCP1", cost_center = "Main - TCP1", write_off_account="_Test Write Off - TCP1") pr = make_purchase_receipt(company= "_Test Company with perpetual inventory", @@ -1770,59 +1771,82 @@ class TestSalesInvoice(unittest.TestCase): self.assertEqual(target_doc.company, "_Test Company 1") self.assertEqual(target_doc.supplier, "_Test Internal Supplier") - # def test_internal_transfer_gl_entry(self): - # ## Create internal transfer account - # account = create_account(account_name="Unrealized Profit", - # parent_account="Current Liabilities - TCP1", company="_Test Company with perpetual inventory") + def test_internal_transfer_gl_entry(self): + ## Create internal transfer account + account = create_account(account_name="Unrealized Profit", + parent_account="Current Liabilities - TCP1", company="_Test Company with perpetual inventory") - # frappe.db.set_value('Company', '_Test Company with perpetual inventory', - # 'unrealized_profit_loss_account', account) + frappe.db.set_value('Company', '_Test Company with perpetual inventory', + 'unrealized_profit_loss_account', account) - # customer = create_internal_customer("_Test Internal Customer 2", "_Test Company with perpetual inventory", - # "_Test Company with perpetual inventory") + customer = create_internal_customer("_Test Internal Customer 2", "_Test Company with perpetual inventory", + "_Test Company with perpetual inventory") - # create_internal_supplier("_Test Internal Supplier 2", "_Test Company with perpetual inventory", - # "_Test Company with perpetual inventory") + create_internal_supplier("_Test Internal Supplier 2", "_Test Company with perpetual inventory", + "_Test Company with perpetual inventory") - # si = create_sales_invoice( - # company = "_Test Company with perpetual inventory", - # customer = customer, - # debit_to = "Debtors - TCP1", - # warehouse = "Stores - TCP1", - # income_account = "Sales - TCP1", - # expense_account = "Cost of Goods Sold - TCP1", - # cost_center = "Main - TCP1", - # currency = "INR", - # do_not_save = 1 - # ) + si = create_sales_invoice( + company = "_Test Company with perpetual inventory", + customer = customer, + debit_to = "Debtors - TCP1", + warehouse = "Stores - TCP1", + income_account = "Sales - TCP1", + expense_account = "Cost of Goods Sold - TCP1", + cost_center = "Main - TCP1", + currency = "INR", + do_not_save = 1 + ) - # si.selling_price_list = "_Test Price List Rest of the World" - # si.update_stock = 1 - # si.items[0].target_warehouse = 'Work In Progress - TCP1' - # add_taxes(si) - # si.save() - # si.submit() + si.selling_price_list = "_Test Price List Rest of the World" + si.update_stock = 1 + si.items[0].target_warehouse = 'Work In Progress - TCP1' + add_taxes(si) + si.save() - # target_doc = make_inter_company_transaction("Sales Invoice", si.name) - # target_doc.company = '_Test Company with perpetual inventory' - # target_doc.items[0].warehouse = 'Finished Goods - TCP1' - # add_taxes(target_doc) - # target_doc.save() - # target_doc.submit() + rate = 0.0 + for d in si.get('items'): + rate = get_incoming_rate({ + "item_code": d.item_code, + "warehouse": d.warehouse, + "posting_date": si.posting_date, + "posting_time": si.posting_time, + "qty": -1 * flt(d.get('stock_qty')), + "serial_no": d.serial_no, + "company": si.company, + "voucher_type": 'Sales Invoice', + "voucher_no": si.name, + "allow_zero_valuation": d.get("allow_zero_valuation") + }, raise_error_if_no_rate=False) - # si_gl_entries = [ - # ["_Test Account Excise Duty - TCP1", 0.0, 12.0, nowdate()], - # ["Unrealized Profit - TCP1", 12.0, 0.0, nowdate()] - # ] + rate = flt(rate, 2) - # check_gl_entries(self, si.name, si_gl_entries, add_days(nowdate(), -1)) + si.submit() - # pi_gl_entries = [ - # ["_Test Account Excise Duty - TCP1", 12.0 , 0.0, nowdate()], - # ["Unrealized Profit - TCP1", 0.0, 12.0, nowdate()] - # ] + target_doc = make_inter_company_transaction("Sales Invoice", si.name) + target_doc.company = '_Test Company with perpetual inventory' + target_doc.items[0].warehouse = 'Finished Goods - TCP1' + add_taxes(target_doc) + target_doc.save() + target_doc.submit() - # check_gl_entries(self, target_doc.name, pi_gl_entries, add_days(nowdate(), -1)) + tax_amount = flt(rate * (12/100), 2) + si_gl_entries = [ + ["_Test Account Excise Duty - TCP1", 0.0, tax_amount, nowdate()], + ["Unrealized Profit - TCP1", tax_amount, 0.0, nowdate()] + ] + + check_gl_entries(self, si.name, si_gl_entries, add_days(nowdate(), -1)) + + pi_gl_entries = [ + ["_Test Account Excise Duty - TCP1", tax_amount , 0.0, nowdate()], + ["Unrealized Profit - TCP1", 0.0, tax_amount, nowdate()] + ] + + # Sale and Purchase both should be at valuation rate + self.assertEqual(si.items[0].rate, rate) + self.assertEqual(target_doc.items[0].rate, rate) + + check_gl_entries(self, target_doc.name, pi_gl_entries, add_days(nowdate(), -1)) def test_eway_bill_json(self): si = make_sales_invoice_for_ewaybill() diff --git a/erpnext/accounts/doctype/sales_invoice_item/sales_invoice_item.json b/erpnext/accounts/doctype/sales_invoice_item/sales_invoice_item.json index 36950757989..7a98afff364 100644 --- a/erpnext/accounts/doctype/sales_invoice_item/sales_invoice_item.json +++ b/erpnext/accounts/doctype/sales_invoice_item/sales_invoice_item.json @@ -565,11 +565,12 @@ "print_hide": 1 }, { + "depends_on": "eval: parent.is_internal_customer && parent.update_stock", "fieldname": "target_warehouse", "fieldtype": "Link", "hidden": 1, "ignore_user_permissions": 1, - "label": "Customer Warehouse (Optional)", + "label": "Target Warehouse", "no_copy": 1, "options": "Warehouse", "print_hide": 1 @@ -815,7 +816,7 @@ "idx": 1, "istable": 1, "links": [], - "modified": "2020-09-23 19:59:04.879322", + "modified": "2020-12-26 17:25:04.090630", "modified_by": "Administrator", "module": "Accounts", "name": "Sales Invoice Item", diff --git a/erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py b/erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py index eeb5140bbe2..cb4d9b43dbd 100644 --- a/erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py +++ b/erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py @@ -49,7 +49,8 @@ def _execute(filters=None, additional_table_columns=None, additional_query_colum elif d.po_detail: purchase_receipt = ", ".join(po_pr_map.get(d.po_detail, [])) - expense_account = d.expense_account or aii_account_map.get(d.company) + expense_account = d.unrealized_profit_loss_account or d.expense_account \ + or aii_account_map.get(d.company) row = { 'item_code': d.item_code, @@ -315,6 +316,7 @@ def get_items(filters, additional_query_columns): `tabPurchase Invoice Item`.`name`, `tabPurchase Invoice Item`.`parent`, `tabPurchase Invoice`.posting_date, `tabPurchase Invoice`.credit_to, `tabPurchase Invoice`.company, `tabPurchase Invoice`.supplier, `tabPurchase Invoice`.remarks, `tabPurchase Invoice`.base_net_total, + `tabPurchase Invoice`.unrealized_profit_loss_account, `tabPurchase Invoice Item`.`item_code`, `tabPurchase Invoice Item`.description, `tabPurchase Invoice Item`.`item_name`, `tabPurchase Invoice Item`.`item_group`, `tabPurchase Invoice Item`.`project`, `tabPurchase Invoice Item`.`purchase_order`, diff --git a/erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py b/erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py index f54ceb0d2f5..998003ac698 100644 --- a/erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py +++ b/erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py @@ -76,7 +76,7 @@ def _execute(filters=None, additional_table_columns=None, additional_query_colum 'company': d.company, 'sales_order': d.sales_order, 'delivery_note': d.delivery_note, - 'income_account': d.income_account, + 'income_account': d.unrealized_profit_loss_account or d.income_account, 'cost_center': d.cost_center, 'stock_qty': d.stock_qty, 'stock_uom': d.stock_uom @@ -379,6 +379,7 @@ def get_items(filters, additional_query_columns): select `tabSales Invoice Item`.name, `tabSales Invoice Item`.parent, `tabSales Invoice`.posting_date, `tabSales Invoice`.debit_to, + `tabSales Invoice`.unrealized_profit_loss_account, `tabSales Invoice`.project, `tabSales Invoice`.customer, `tabSales Invoice`.remarks, `tabSales Invoice`.territory, `tabSales Invoice`.company, `tabSales Invoice`.base_net_total, `tabSales Invoice Item`.item_code, `tabSales Invoice Item`.description, diff --git a/erpnext/accounts/report/purchase_register/purchase_register.py b/erpnext/accounts/report/purchase_register/purchase_register.py index 9399e707390..8ac749d6290 100644 --- a/erpnext/accounts/report/purchase_register/purchase_register.py +++ b/erpnext/accounts/report/purchase_register/purchase_register.py @@ -14,13 +14,15 @@ def _execute(filters=None, additional_table_columns=None, additional_query_colum if not filters: filters = {} invoice_list = get_invoices(filters, additional_query_columns) - columns, expense_accounts, tax_accounts = get_columns(invoice_list, additional_table_columns) + columns, expense_accounts, tax_accounts, unrealized_profit_loss_accounts \ + = get_columns(invoice_list, additional_table_columns) if not invoice_list: msgprint(_("No record found")) return columns, invoice_list invoice_expense_map = get_invoice_expense_map(invoice_list) + internal_invoice_map = get_internal_invoice_map(invoice_list) invoice_expense_map, invoice_tax_map = get_invoice_tax_map(invoice_list, invoice_expense_map, expense_accounts) invoice_po_pr_map = get_invoice_po_pr_map(invoice_list) @@ -52,10 +54,17 @@ def _execute(filters=None, additional_table_columns=None, additional_query_colum # map expense values base_net_total = 0 for expense_acc in expense_accounts: - expense_amount = flt(invoice_expense_map.get(inv.name, {}).get(expense_acc)) + if inv.is_internal_supplier and inv.company == inv.represents_company: + expense_amount = 0 + else: + expense_amount = flt(invoice_expense_map.get(inv.name, {}).get(expense_acc)) base_net_total += expense_amount row.append(expense_amount) + # Add amount in unrealized account + for account in unrealized_profit_loss_accounts: + row.append(flt(internal_invoice_map.get((inv.name, account)))) + # net total row.append(base_net_total or inv.base_net_total) @@ -96,7 +105,8 @@ def get_columns(invoice_list, additional_table_columns): "width": 80 } ] - expense_accounts = tax_accounts = expense_columns = tax_columns = [] + expense_accounts = tax_accounts = expense_columns = tax_columns = unrealized_profit_loss_accounts = \ + unrealized_profit_loss_account_columns = [] if invoice_list: expense_accounts = frappe.db.sql_list("""select distinct expense_account @@ -112,17 +122,25 @@ def get_columns(invoice_list, additional_table_columns): and parent in (%s) order by account_head""" % ', '.join(['%s']*len(invoice_list)), tuple([inv.name for inv in invoice_list])) + unrealized_profit_loss_accounts = frappe.db.sql_list("""SELECT distinct unrealized_profit_loss_account + from `tabPurchase Invoice` where docstatus = 1 and name in (%s) + and ifnull(unrealized_profit_loss_account, '') != '' + order by unrealized_profit_loss_account""" % + ', '.join(['%s']*len(invoice_list)), tuple([inv.name for inv in invoice_list])) expense_columns = [(account + ":Currency/currency:120") for account in expense_accounts] + unrealized_profit_loss_account_columns = [(account + ":Currency/currency:120") for account in unrealized_profit_loss_accounts] + for account in tax_accounts: if account not in expense_accounts: tax_columns.append(account + ":Currency/currency:120") - columns = columns + expense_columns + [_("Net Total") + ":Currency/currency:120"] + tax_columns + \ + columns = columns + expense_columns + unrealized_profit_loss_account_columns + \ + [_("Net Total") + ":Currency/currency:120"] + tax_columns + \ [_("Total Tax") + ":Currency/currency:120", _("Grand Total") + ":Currency/currency:120", _("Rounded Total") + ":Currency/currency:120", _("Outstanding Amount") + ":Currency/currency:120"] - return columns, expense_accounts, tax_accounts + return columns, expense_accounts, tax_accounts, unrealized_profit_loss_accounts def get_conditions(filters): conditions = "" @@ -199,6 +217,19 @@ def get_invoice_expense_map(invoice_list): return invoice_expense_map +def get_internal_invoice_map(invoice_list): + unrealized_amount_details = frappe.db.sql("""SELECT name, unrealized_profit_loss_account, + base_net_total as amount from `tabPurchase Invoice` where name in (%s) + and is_internal_supplier = 1 and company = represents_company""" % + ', '.join(['%s']*len(invoice_list)), tuple([inv.name for inv in invoice_list]), as_dict=1) + + internal_invoice_map = {} + for d in unrealized_amount_details: + if d.unrealized_profit_loss_account: + internal_invoice_map.setdefault((d.name, d.unrealized_profit_loss_account), d.amount) + + return internal_invoice_map + def get_invoice_tax_map(invoice_list, invoice_expense_map, expense_accounts): tax_details = frappe.db.sql(""" select parent, account_head, case add_deduct_tax when "Add" then sum(base_tax_amount_after_discount_amount) diff --git a/erpnext/accounts/report/sales_register/sales_register.py b/erpnext/accounts/report/sales_register/sales_register.py index b6e61b13069..cb2c98b64ae 100644 --- a/erpnext/accounts/report/sales_register/sales_register.py +++ b/erpnext/accounts/report/sales_register/sales_register.py @@ -15,13 +15,14 @@ def _execute(filters, additional_table_columns=None, additional_query_columns=No if not filters: filters = frappe._dict({}) invoice_list = get_invoices(filters, additional_query_columns) - columns, income_accounts, tax_accounts = get_columns(invoice_list, additional_table_columns) + columns, income_accounts, tax_accounts, unrealized_profit_loss_accounts = get_columns(invoice_list, additional_table_columns) if not invoice_list: msgprint(_("No record found")) return columns, invoice_list invoice_income_map = get_invoice_income_map(invoice_list) + internal_invoice_map = get_internal_invoice_map(invoice_list) invoice_income_map, invoice_tax_map = get_invoice_tax_map(invoice_list, invoice_income_map, income_accounts) #Cost Center & Warehouse Map @@ -70,12 +71,22 @@ def _execute(filters, additional_table_columns=None, additional_query_columns=No # map income values base_net_total = 0 for income_acc in income_accounts: - income_amount = flt(invoice_income_map.get(inv.name, {}).get(income_acc)) + if inv.is_internal_customer and inv.company == inv.represents_company: + income_amount = 0 + else: + income_amount = flt(invoice_income_map.get(inv.name, {}).get(income_acc)) + base_net_total += income_amount row.update({ frappe.scrub(income_acc): income_amount }) + # Add amount in unrealized account + for account in unrealized_profit_loss_accounts: + row.update({ + frappe.scrub(account): flt(internal_invoice_map.get((inv.name, account))) + }) + # net total row.update({'net_total': base_net_total or inv.base_net_total}) @@ -230,6 +241,8 @@ def get_columns(invoice_list, additional_table_columns): tax_accounts = [] income_columns = [] tax_columns = [] + unrealized_profit_loss_accounts = [] + unrealized_profit_loss_account_columns = [] if invoice_list: income_accounts = frappe.db.sql_list("""select distinct income_account @@ -243,12 +256,18 @@ def get_columns(invoice_list, additional_table_columns): and parent in (%s) order by account_head""" % ', '.join(['%s']*len(invoice_list)), tuple([inv.name for inv in invoice_list])) + unrealized_profit_loss_accounts = frappe.db.sql_list("""SELECT distinct unrealized_profit_loss_account + from `tabSales Invoice` where docstatus = 1 and name in (%s) + and ifnull(unrealized_profit_loss_account, '') != '' + order by unrealized_profit_loss_account""" % + ', '.join(['%s']*len(invoice_list)), tuple([inv.name for inv in invoice_list])) + for account in income_accounts: income_columns.append({ "label": account, "fieldname": frappe.scrub(account), "fieldtype": "Currency", - "options": 'currency', + "options": "currency", "width": 120 }) @@ -258,15 +277,24 @@ def get_columns(invoice_list, additional_table_columns): "label": account, "fieldname": frappe.scrub(account), "fieldtype": "Currency", - "options": 'currency', + "options": "currency", "width": 120 }) + for account in unrealized_profit_loss_accounts: + unrealized_profit_loss_account_columns.append({ + "label": account, + "fieldname": frappe.scrub(account), + "fieldtype": "Currency", + "options": "currency", + "width": 120 + }) + net_total_column = [{ "label": _("Net Total"), "fieldname": "net_total", "fieldtype": "Currency", - "options": 'currency', + "options": "currency", "width": 120 }] @@ -301,9 +329,10 @@ def get_columns(invoice_list, additional_table_columns): } ] - columns = columns + income_columns + net_total_column + tax_columns + total_columns + columns = columns + income_columns + unrealized_profit_loss_account_columns + \ + net_total_column + tax_columns + total_columns - return columns, income_accounts, tax_accounts + return columns, income_accounts, tax_accounts, unrealized_profit_loss_accounts def get_conditions(filters): conditions = "" @@ -368,7 +397,8 @@ def get_invoices(filters, additional_query_columns): return frappe.db.sql(""" select name, posting_date, debit_to, project, customer, customer_name, owner, remarks, territory, tax_id, customer_group, - base_net_total, base_grand_total, base_rounded_total, outstanding_amount {0} + base_net_total, base_grand_total, base_rounded_total, outstanding_amount, + is_internal_customer, represents_company, company {0} from `tabSales Invoice` where docstatus = 1 %s order by posting_date desc, name desc""".format(additional_query_columns or '') % conditions, filters, as_dict=1) @@ -385,6 +415,19 @@ def get_invoice_income_map(invoice_list): return invoice_income_map +def get_internal_invoice_map(invoice_list): + unrealized_amount_details = frappe.db.sql("""SELECT name, unrealized_profit_loss_account, + base_net_total as amount from `tabSales Invoice` where name in (%s) + and is_internal_customer = 1 and company = represents_company""" % + ', '.join(['%s']*len(invoice_list)), tuple([inv.name for inv in invoice_list]), as_dict=1) + + internal_invoice_map = {} + for d in unrealized_amount_details: + if d.unrealized_profit_loss_account: + internal_invoice_map.setdefault((d.name, d.unrealized_profit_loss_account), d.amount) + + return internal_invoice_map + def get_invoice_tax_map(invoice_list, invoice_income_map, income_accounts): tax_details = frappe.db.sql("""select parent, account_head, sum(base_tax_amount_after_discount_amount) as tax_amount diff --git a/erpnext/buying/doctype/purchase_order/purchase_order.js b/erpnext/buying/doctype/purchase_order/purchase_order.js index 83efa66f6b0..dd0f0658485 100644 --- a/erpnext/buying/doctype/purchase_order/purchase_order.js +++ b/erpnext/buying/doctype/purchase_order/purchase_order.js @@ -164,16 +164,16 @@ erpnext.buying.PurchaseOrderController = erpnext.buying.BuyingController.extend( if (doc.docstatus === 1 && !doc.inter_company_order_reference) { let me = this; - frappe.model.with_doc("Supplier", me.frm.doc.supplier, () => { - let supplier = frappe.model.get_doc("Supplier", me.frm.doc.supplier); - let internal = supplier.is_internal_supplier; - let disabled = supplier.disabled; - if (internal === 1 && disabled === 0) { - me.frm.add_custom_button("Inter Company Order", function() { - me.make_inter_company_order(me.frm); - }, __('Create')); - } - }); + let internal = me.frm.doc.is_internal_supplier; + if (internal) { + let button_label = (me.frm.doc.company === me.frm.doc.represents_company) ? "Internal Sales Order" : + "Inter Company Sales Order"; + + me.frm.add_custom_button(button_label, function() { + me.make_inter_company_order(me.frm); + }, __('Create')); + } + } } diff --git a/erpnext/buying/doctype/purchase_order/purchase_order.json b/erpnext/buying/doctype/purchase_order/purchase_order.json index 75da71ceff8..ee2beea67f9 100644 --- a/erpnext/buying/doctype/purchase_order/purchase_order.json +++ b/erpnext/buying/doctype/purchase_order/purchase_order.json @@ -134,6 +134,8 @@ "ref_sq", "column_break_74", "party_account_currency", + "is_internal_supplier", + "represents_company", "inter_company_order_reference" ], "fields": [ @@ -1101,13 +1103,28 @@ { "fieldname": "items_col_break", "fieldtype": "Column Break" + }, + { + "default": "0", + "fetch_from": "supplier.is_internal_supplier", + "fieldname": "is_internal_supplier", + "fieldtype": "Check", + "label": "Is Internal Supplier" + }, + { + "fetch_from": "supplier.represents_company", + "fieldname": "represents_company", + "fieldtype": "Link", + "label": "Represents Company", + "options": "Company", + "read_only": 1 } ], "icon": "fa fa-file-text", "idx": 105, "is_submittable": 1, "links": [], - "modified": "2020-12-03 16:46:44.229351", + "modified": "2021-01-20 22:07:23.487138", "modified_by": "Administrator", "module": "Buying", "name": "Purchase Order", diff --git a/erpnext/buying/doctype/supplier/supplier.py b/erpnext/buying/doctype/supplier/supplier.py index 0ee9d180d99..edeb135d951 100644 --- a/erpnext/buying/doctype/supplier/supplier.py +++ b/erpnext/buying/doctype/supplier/supplier.py @@ -52,7 +52,10 @@ class Supplier(TransactionBase): self.validate_internal_supplier() def validate_internal_supplier(self): - if self.is_internal_supplier and frappe.db.get_value("Supplier", {"represents_company": self.represents_company}, "name"): + internal_supplier = frappe.db.get_value("Supplier", + {"is_internal_supplier": 1, "represents_company": self.represents_company, "name": ("!=", self.name)}, "name") + + if internal_supplier: frappe.throw(_("Internal Supplier for company {0} already exists").format( frappe.bold(self.represents_company))) diff --git a/erpnext/controllers/accounts_controller.py b/erpnext/controllers/accounts_controller.py index b9bfbaf0bd3..eaa80800c69 100644 --- a/erpnext/controllers/accounts_controller.py +++ b/erpnext/controllers/accounts_controller.py @@ -75,6 +75,9 @@ class AccountsController(TransactionBase): self.ensure_supplier_is_not_blocked() self.validate_date_with_fiscal_year() + self.validate_inter_company_reference() + + self.set_incoming_rate() if self.meta.get_field("currency"): self.calculate_taxes_and_totals() @@ -110,12 +113,12 @@ class AccountsController(TransactionBase): self.set_inter_company_account() validate_regional(self) - + validate_einvoice_fields(self) if self.doctype != 'Material Request': apply_pricing_rule_on_transaction(self) - + def before_cancel(self): validate_einvoice_fields(self) @@ -212,6 +215,17 @@ class AccountsController(TransactionBase): validate_fiscal_year(self.get(date_field), self.fiscal_year, self.company, self.meta.get_label(date_field), self) + def validate_inter_company_reference(self): + if self.doctype not in ('Purchase Invoice', 'Purchase Receipt', 'Purchase Order'): + return + + if self.is_internal_transfer(): + if not (self.get('inter_company_reference') or self.get('inter_company_invoice_reference') + or self.get('inter_company_order_reference')): + msg = _("Internal Sale or Delivery Reference missing. ") + msg += _("Please create purchase from internal sale or delivery document itself") + frappe.throw(msg, title=_("Internal Sales Reference Missing")) + def validate_due_date(self): if self.get('is_pos'): return @@ -968,9 +982,9 @@ class AccountsController(TransactionBase): It will an internal transfer if its an internal customer and representation company is same as billing company """ - if self.doctype == 'Sales Invoice': + if self.doctype in ('Sales Invoice', 'Delivery Note', 'Sales Order'): internal_party_field = 'is_internal_customer' - else: + elif self.doctype in ('Purchase Invoice', 'Purchase Receipt', 'Purchase Order'): internal_party_field = 'is_internal_supplier' if self.get(internal_party_field) and (self.represents_company == self.company): diff --git a/erpnext/controllers/buying_controller.py b/erpnext/controllers/buying_controller.py index 4dee375e5a2..ab1f02779be 100644 --- a/erpnext/controllers/buying_controller.py +++ b/erpnext/controllers/buying_controller.py @@ -44,7 +44,6 @@ class BuyingController(StockController): self.validate_items() self.set_qty_as_per_stock_uom() self.validate_stock_or_nonstock_items() - self.update_tax_category_for_internal_transfer() self.validate_warehouse() self.validate_from_warehouse() self.set_supplier_address() @@ -100,11 +99,6 @@ class BuyingController(StockController): msg = _('Tax Category has been changed to "Total" because all the Items are non-stock items') self.update_tax_category(msg) - def update_tax_category_for_internal_transfer(self): - if self.doctype == 'Purchase Invoice' and self.is_internal_transfer(): - msg = _('Tax Category has been changed to "Total" as its an internal purchase.') - self.update_tax_category(msg) - def update_tax_category(self, msg): tax_for_valuation = [d for d in self.get("taxes") if d.category in ["Valuation", "Valuation and Total"]] @@ -224,6 +218,48 @@ class BuyingController(StockController): else: item.valuation_rate = 0.0 + def set_incoming_rate(self): + if self.doctype not in ("Purchase Receipt", "Purchase Invoice", "Purchase Order"): + return + + ref_doctype_map = { + "Purchase Order": "Sales Order Item", + "Purchase Receipt": "Delivery Note Item", + "Purchase Invoice": "Sales Invoice Item", + } + + ref_doctype = ref_doctype_map.get(self.doctype) + items = self.get("items") + for d in items: + if not cint(self.get("is_return")): + # Get outgoing rate based on original item cost based on valuation method + + if not d.get(frappe.scrub(ref_doctype)): + outgoing_rate = get_incoming_rate({ + "item_code": d.item_code, + "warehouse": d.get('from_warehouse'), + "posting_date": self.get('posting_date') or self.get('transation_date'), + "posting_time": self.get('posting_time'), + "qty": -1 * flt(d.get('stock_qty')), + "serial_no": d.get('serial_no'), + "company": self.company, + "voucher_type": self.doctype, + "voucher_no": self.name, + "allow_zero_valuation": d.get("allow_zero_valuation") + }, raise_error_if_no_rate=False) + + rate = flt(outgoing_rate * d.conversion_factor, d.precision('rate')) + else: + rate = frappe.db.get_value(ref_doctype, d.get(frappe.scrub(ref_doctype)), 'rate') + + if self.is_internal_transfer(): + if rate != d.rate: + d.rate = rate + d.discount_percentage = 0 + d.discount_amount = 0 + frappe.msgprint(_("Row {0}: Item rate has been updated as per valuation rate since its an internal stock transfer") + .format(d.idx), alert=1) + def get_supplied_items_cost(self, item_row_id, reset_outgoing_rate=True): supplied_items_cost = 0.0 for d in self.get("supplied_items"): @@ -243,7 +279,7 @@ class BuyingController(StockController): d.amount = flt(flt(d.consumed_qty) * flt(d.rate), d.precision("amount")) supplied_items_cost += flt(d.amount) - + return supplied_items_cost def validate_for_subcontracting(self): @@ -559,6 +595,8 @@ class BuyingController(StockController): from_warehouse_sle = self.get_sl_entries(d, { "actual_qty": -1 * pr_qty, "warehouse": d.from_warehouse, + "outgoing_rate": d.rate, + "recalculate_rate": 1, "dependant_sle_voucher_detail_no": d.name }) diff --git a/erpnext/controllers/selling_controller.py b/erpnext/controllers/selling_controller.py index 812021f5c86..e085048f99b 100644 --- a/erpnext/controllers/selling_controller.py +++ b/erpnext/controllers/selling_controller.py @@ -3,7 +3,7 @@ from __future__ import unicode_literals import frappe -from frappe.utils import cint, flt, cstr, comma_or, get_link_to_form +from frappe.utils import cint, flt, cstr, get_link_to_form, nowtime from frappe import _, throw from erpnext.stock.get_item_details import get_bin_details from erpnext.stock.utils import get_incoming_rate @@ -49,7 +49,6 @@ class SellingController(StockController): self.set_customer_address() self.validate_for_duplicate_items() self.validate_target_warehouse() - self.set_incoming_rate() def set_missing_values(self, for_validate=False): @@ -191,7 +190,7 @@ class SellingController(StockController): for it in self.get("items"): if not it.item_code: continue - + last_purchase_rate, is_stock_item = frappe.get_cached_value("Item", it.item_code, ["last_purchase_rate", "is_stock_item"]) last_purchase_rate_in_sales_uom = last_purchase_rate * (it.conversion_factor or 1) if flt(it.base_net_rate) < flt(last_purchase_rate_in_sales_uom): @@ -312,7 +311,7 @@ class SellingController(StockController): sales_order.update_reserved_qty(so_item_rows) def set_incoming_rate(self): - if self.doctype not in ("Delivery Note", "Sales Invoice"): + if self.doctype not in ("Delivery Note", "Sales Invoice", "Sales Order"): return items = self.get("items") + (self.get("packed_items") or []) @@ -322,15 +321,26 @@ class SellingController(StockController): d.incoming_rate = get_incoming_rate({ "item_code": d.item_code, "warehouse": d.warehouse, - "posting_date": self.posting_date, - "posting_time": self.posting_time, - "qty": -1*flt(d.qty), - "serial_no": d.serial_no, + "posting_date": self.get('posting_date') or self.get('transaction_date'), + "posting_time": self.get('posting_time') or nowtime(), + "qty": -1 * flt(d.get('stock_qty') or d.get('actual_qty')), + "serial_no": d.get('serial_no'), "company": self.company, "voucher_type": self.doctype, "voucher_no": self.name, "allow_zero_valuation": d.get("allow_zero_valuation") }, raise_error_if_no_rate=False) + + # For internal transfers use incoming rate as the valuation rate + if self.is_internal_transfer(): + rate = flt(d.incoming_rate * d.conversion_factor, d.precision('rate')) + if d.rate != rate: + d.rate = rate + d.discount_percentage = 0 + d.discount_amount = 0 + frappe.msgprint(_("Row {0}: Item rate has been updated as per valuation rate since its an internal stock transfer") + .format(d.idx), alert=1) + elif self.get("return_against"): # Get incoming rate of return entry from reference document # based on original item cost as per valuation method @@ -391,7 +401,7 @@ class SellingController(StockController): }) if item_row.warehouse: sle.dependant_sle_voucher_detail_no = item_row.name - + return sle def set_po_nos(self, for_validate=False): diff --git a/erpnext/controllers/stock_controller.py b/erpnext/controllers/stock_controller.py index e0fcf47365f..4b5e3479706 100644 --- a/erpnext/controllers/stock_controller.py +++ b/erpnext/controllers/stock_controller.py @@ -24,6 +24,7 @@ class StockController(AccountsController): self.validate_inspection() self.validate_serialized_batch() self.validate_customer_provided_item() + self.validate_internal_transfer() self.validate_putaway_capacity() def make_gl_entries(self, gl_entries=None, from_repost=False): @@ -74,6 +75,7 @@ class StockController(AccountsController): warehouse_with_no_account = [] precision = frappe.get_precision("GL Entry", "debit_in_account_currency") for item_row in voucher_details: + sle_list = sle_map.get(item_row.name) if sle_list: for sle in sle_list: @@ -218,7 +220,7 @@ class StockController(AccountsController): """, (self.doctype, self.name), as_dict=True) for sle in stock_ledger_entries: - stock_ledger.setdefault(sle.voucher_detail_no, []).append(sle) + stock_ledger.setdefault(sle.voucher_detail_no, []).append(sle) return stock_ledger def make_batches(self, warehouse_field): @@ -393,6 +395,32 @@ class StockController(AccountsController): if frappe.db.get_value('Item', d.item_code, 'is_customer_provided_item'): d.allow_zero_valuation_rate = 1 + def validate_internal_transfer(self): + if self.doctype in ('Sales Invoice', 'Delivery Note', 'Purchase Invoice', 'Purchase Receipt') \ + and self.is_internal_transfer(): + self.validate_in_transit_warehouses() + self.validate_multi_currency() + self.validate_packed_items() + + def validate_in_transit_warehouses(self): + if (self.doctype == 'Sales Invoice' and self.get('update_stock')) or self.doctype == 'Delivery Note': + for item in self.get('items'): + if not item.target_warehouse: + frappe.throw(_("Row {0}: Target Warehouse is mandatory for internal transfers").format(item.idx)) + + if (self.doctype == 'Purchase Invoice' and self.get('update_stock')) or self.doctype == 'Purchase Receipt': + for item in self.get('items'): + if not item.from_warehouse: + frappe.throw(_("Row {0}: From Warehouse is mandatory for internal transfers").format(item.idx)) + + def validate_multi_currency(self): + if self.currency != self.company_currency: + frappe.throw(_("Internal transfers can only be done in company's default currency")) + + def validate_packed_items(self): + if self.doctype in ('Sales Invoice', 'Delivery Note Item') and self.get('packed_items'): + frappe.throw(_("Packed Items cannot be transferred internally")) + def validate_putaway_capacity(self): # if over receipt is attempted while 'apply putaway rule' is disabled # and if rule was applied on the transaction, validate it. diff --git a/erpnext/public/js/controllers/transaction.js b/erpnext/public/js/controllers/transaction.js index 1d1f18b1a0d..9627600a17a 100644 --- a/erpnext/public/js/controllers/transaction.js +++ b/erpnext/public/js/controllers/transaction.js @@ -105,10 +105,18 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({ frappe.ui.form.on(this.frm.doctype + " Item", { items_add: function(frm, cdt, cdn) { var item = frappe.get_doc(cdt, cdn); - if(!item.warehouse && frm.doc.set_warehouse) { + if (!item.warehouse && frm.doc.set_warehouse) { item.warehouse = frm.doc.set_warehouse; } + if (!item.target_warehouse && frm.doc.set_target_warehouse) { + item.target_warehouse = frm.doc.set_target_warehouse; + } + + if (!item.from_warehouse && frm.doc.set_from_warehouse) { + item.from_warehouse = frm.doc.set_from_warehouse; + } + erpnext.accounts.dimensions.copy_dimension_from_first_row(frm, cdt, cdn, 'items'); } }); @@ -227,6 +235,8 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({ } }; + this.frm.trigger('set_default_internal_warehouse'); + return frappe.run_serially([ () => set_value('currency', currency), () => set_value('price_list_currency', currency), @@ -658,7 +668,7 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({ args: item_args }, callback: function(r) { - frappe.model.set_value(item.doctype, item.name, 'rate', r.message); + frappe.model.set_value(item.doctype, item.name, 'rate', r.message * item.conversion_factor); } }); }, @@ -724,6 +734,31 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({ this.calculate_taxes_and_totals(false); }, + update_stock: function() { + this.frm.trigger('set_default_internal_warehouse'); + }, + + set_default_internal_warehouse: function() { + let me = this; + if ((this.frm.doc.doctype === 'Sales Invoice' && me.frm.doc.update_stock) + || this.frm.doc.doctype == 'Delivery Note') { + if (this.frm.doc.is_internal_customer && this.frm.doc.company === this.frm.doc.represents_company) { + frappe.db.get_value('Company', this.frm.doc.company, 'default_in_transit_warehouse', function(value) { + me.frm.set_value('set_target_warehouse', value.default_in_transit_warehouse); + }); + } + } + + if ((this.frm.doc.doctype === 'Purchase Invoice' && me.frm.doc.update_stock) + || this.frm.doc.doctype == 'Purchase Receipt') { + if (this.frm.doc.is_internal_supplier && this.frm.doc.company === this.frm.doc.represents_company) { + frappe.db.get_value('Company', this.frm.doc.company, 'default_in_transit_warehouse', function(value) { + me.frm.set_value('set_from_warehouse', value.default_in_transit_warehouse); + }); + } + } + }, + company: function() { var me = this; var set_pricing = function() { @@ -810,7 +845,7 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({ in_list(['Purchase Order', 'Purchase Receipt', 'Purchase Invoice'], this.frm.doctype)) { erpnext.utils.get_shipping_address(this.frm, function(){ set_party_account(set_pricing); - }) + }); // Get default company billing address in Purchase Invoice, Order and Receipt frappe.call({ @@ -1977,6 +2012,14 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({ this.autofill_warehouse(this.frm.doc.items, "warehouse", this.frm.doc.set_warehouse); }, + set_target_warehouse: function() { + this.autofill_warehouse(this.frm.doc.items, "target_warehouse", this.frm.doc.set_target_warehouse); + }, + + set_from_warehouse: function() { + this.autofill_warehouse(this.frm.doc.items, "from_warehouse", this.frm.doc.set_from_warehouse); + }, + autofill_warehouse : function (child_table, warehouse_field, warehouse) { if (warehouse && child_table && child_table.length) { let doctype = child_table[0].doctype; diff --git a/erpnext/public/js/utils/party.js b/erpnext/public/js/utils/party.js index 770704e595b..808dd5add05 100644 --- a/erpnext/public/js/utils/party.js +++ b/erpnext/public/js/utils/party.js @@ -276,6 +276,12 @@ erpnext.utils.validate_mandatory = function(frm, label, value, trigger_on) { erpnext.utils.get_shipping_address = function(frm, callback){ if (frm.doc.company) { + if (!(frm.doc.inter_com_order_reference || frm.doc.internal_invoice_reference || + frm.doc.internal_order_reference)) { + if (callback) { + return callback(); + } + } frappe.call({ method: "erpnext.accounts.custom.address.get_shipping_address", args: { diff --git a/erpnext/regional/india/taxes.js b/erpnext/regional/india/taxes.js index 87baece65d3..f09d3d08ad2 100644 --- a/erpnext/regional/india/taxes.js +++ b/erpnext/regional/india/taxes.js @@ -40,14 +40,12 @@ erpnext.setup_auto_gst_taxation = (doctype) => { callback: function(r) { if(r.message) { frm.set_value('taxes_and_charges', r.message.taxes_and_charges); + frm.set_value('taxes', r.message.taxes); frm.set_value('place_of_supply', r.message.place_of_supply); - } else if (frm.doc.is_internal_supplier || frm.doc.is_internal_customer) { - frm.set_value('taxes_and_charges', ''); - frm.set_value('taxes', []); } } }); } }); -}; +} diff --git a/erpnext/regional/india/utils.py b/erpnext/regional/india/utils.py index 0d8263835d2..e89885f3805 100644 --- a/erpnext/regional/india/utils.py +++ b/erpnext/regional/india/utils.py @@ -171,7 +171,7 @@ def get_regional_address_details(party_details, doctype, company): if is_internal_transfer(party_details, doctype): party_details.taxes_and_charges = '' - party_details.taxes = '' + party_details.taxes = [] return party_details if doctype in ("Sales Invoice", "Delivery Note", "Sales Order"): diff --git a/erpnext/selling/doctype/customer/customer.py b/erpnext/selling/doctype/customer/customer.py index 29214ee06d9..bf8b7fc128a 100644 --- a/erpnext/selling/doctype/customer/customer.py +++ b/erpnext/selling/doctype/customer/customer.py @@ -84,7 +84,10 @@ class Customer(TransactionBase): frappe.throw(_("{0} is not a company bank account").format(frappe.bold(self.default_bank_account))) def validate_internal_customer(self): - if self.is_internal_customer and frappe.db.get_value('Customer', {"represents_company": self.represents_company}, "name"): + internal_customer = frappe.db.get_value("Customer", + {"is_internal_customer": 1, "represents_company": self.represents_company, "name": ("!=", self.name)}, "name") + + if internal_customer: frappe.throw(_("Internal Customer for company {0} already exists").format( frappe.bold(self.represents_company))) diff --git a/erpnext/selling/doctype/sales_order/sales_order.js b/erpnext/selling/doctype/sales_order/sales_order.js index d4fb07cc275..78f9df9588a 100644 --- a/erpnext/selling/doctype/sales_order/sales_order.js +++ b/erpnext/selling/doctype/sales_order/sales_order.js @@ -171,8 +171,10 @@ erpnext.selling.SalesOrderController = erpnext.selling.SellingController.extend( this.frm.add_custom_button(__('Request for Raw Materials'), () => this.make_raw_material_request(), __('Create')); } - // make purchase order + // Make Purchase Order + if (!this.frm.doc.is_internal_customer) { this.frm.add_custom_button(__('Purchase Order'), () => this.make_purchase_order(), __('Create')); + } // maintenance if(flt(doc.per_delivered, 2) < 100 && (order_is_maintenance || order_is_a_custom_sale)) { @@ -193,16 +195,15 @@ erpnext.selling.SalesOrderController = erpnext.selling.SellingController.extend( if (doc.docstatus === 1 && !doc.inter_company_order_reference) { let me = this; - frappe.model.with_doc("Customer", me.frm.doc.customer, () => { - let customer = frappe.model.get_doc("Customer", me.frm.doc.customer); - let internal = customer.is_internal_customer; - let disabled = customer.disabled; - if (internal === 1 && disabled === 0) { - me.frm.add_custom_button("Inter Company Order", function() { - me.make_inter_company_order(); - }, __('Create')); - } - }); + let internal = me.frm.doc.is_internal_customer; + if (internal) { + let button_label = (me.frm.doc.company === me.frm.doc.represents_company) ? "Internal Purchase Order" : + "Inter Company Purchase Order"; + + me.frm.add_custom_button(button_label, function() { + me.make_inter_company_order(); + }, __('Create')); + } } } // payment request diff --git a/erpnext/selling/doctype/sales_order/sales_order.json b/erpnext/selling/doctype/sales_order/sales_order.json index 3d64ac3780e..0a5c6651ba3 100644 --- a/erpnext/selling/doctype/sales_order/sales_order.json +++ b/erpnext/selling/doctype/sales_order/sales_order.json @@ -107,6 +107,8 @@ "tc_name", "terms", "more_info", + "is_internal_customer", + "represents_company", "inter_company_order_reference", "project", "party_account_currency", @@ -1103,7 +1105,8 @@ "hide_days": 1, "hide_seconds": 1, "label": "Inter Company Order Reference", - "options": "Purchase Order" + "options": "Purchase Order", + "read_only": 1 }, { "description": "Track this Sales Order against any Project", @@ -1455,13 +1458,29 @@ "hide_seconds": 1, "label": "Skip Delivery Note", "print_hide": 1 + }, + { + "default": "0", + "fetch_from": "customer.is_internal_customer", + "fieldname": "is_internal_customer", + "fieldtype": "Check", + "label": "Is Internal Customer", + "read_only": 1 + }, + { + "fetch_from": "customer.represents_company", + "fieldname": "represents_company", + "fieldtype": "Link", + "label": "Represents Company", + "options": "Company", + "read_only": 1 } ], "icon": "fa fa-file-text", "idx": 105, "is_submittable": 1, "links": [], - "modified": "2020-10-30 13:59:18.628077", + "modified": "2021-01-20 23:40:39.929296", "modified_by": "Administrator", "module": "Selling", "name": "Sales Order", diff --git a/erpnext/stock/doctype/delivery_note/delivery_note.js b/erpnext/stock/doctype/delivery_note/delivery_note.js index ee18042fdd5..334bdeac9d3 100644 --- a/erpnext/stock/doctype/delivery_note/delivery_note.js +++ b/erpnext/stock/doctype/delivery_note/delivery_note.js @@ -95,13 +95,19 @@ frappe.ui.form.on("Delivery Note", { frm.page.set_inner_btn_group_as_primary(__('Create')); } - if (frm.doc.docstatus === 1 && frm.doc.is_internal_customer && !frm.doc.inter_company_reference) { - frm.add_custom_button(__('Purchase Receipt'), function() { - frappe.model.open_mapped_doc({ - method: 'erpnext.stock.doctype.delivery_note.delivery_note.make_inter_company_purchase_receipt', - frm: frm, - }) - }, __('Create')); + if (frm.doc.docstatus == 1 && !frm.doc.inter_company_reference) { + let internal = me.frm.doc.is_internal_customer; + if (internal) { + let button_label = (me.frm.doc.company === me.frm.doc.represents_company) ? "Internal Purchase Receipt" : + "Inter Company Purchase Receipt"; + + me.frm.add_custom_button(button_label, function() { + frappe.model.open_mapped_doc({ + method: 'erpnext.stock.doctype.delivery_note.delivery_note.make_inter_company_purchase_receipt', + frm: frm, + }); + }, __('Create')); + } } } }); @@ -297,15 +303,6 @@ erpnext.stock.DeliveryNoteController = erpnext.selling.SellingController.extend( } }) }, - - to_warehouse: function() { - let packed_items_table = this.frm.doc["packed_items"]; - this.autofill_warehouse(this.frm.doc["items"], "target_warehouse", this.frm.doc.to_warehouse); - if (packed_items_table && packed_items_table.length) { - this.autofill_warehouse(packed_items_table, "target_warehouse", this.frm.doc.to_warehouse); - } - } - }); $.extend(cur_frm.cscript, new erpnext.stock.DeliveryNoteController({frm: cur_frm})); diff --git a/erpnext/stock/doctype/delivery_note/delivery_note.json b/erpnext/stock/doctype/delivery_note/delivery_note.json index c9f8d0810e3..f595aade917 100644 --- a/erpnext/stock/doctype/delivery_note/delivery_note.json +++ b/erpnext/stock/doctype/delivery_note/delivery_note.json @@ -53,7 +53,7 @@ "sec_warehouse", "set_warehouse", "col_break_warehouse", - "to_warehouse", + "set_target_warehouse", "items_section", "scan_barcode", "items", @@ -117,6 +117,7 @@ "source", "column_break5", "is_internal_customer", + "represents_company", "inter_company_reference", "per_billed", "customer_group", @@ -502,18 +503,6 @@ "fieldname": "col_break_warehouse", "fieldtype": "Column Break" }, - { - "description": "Required only for sample item.", - "fieldname": "to_warehouse", - "fieldtype": "Link", - "in_standard_filter": 1, - "label": "To Warehouse", - "no_copy": 1, - "oldfieldname": "to_warehouse", - "oldfieldtype": "Link", - "options": "Warehouse", - "print_hide": 1 - }, { "fieldname": "items_section", "fieldtype": "Section Break", @@ -1261,13 +1250,34 @@ "no_copy": 1, "print_hide": 1, "read_only": 1 + }, + { + "depends_on": "eval: doc.is_internal_customer", + "fieldname": "set_target_warehouse", + "fieldtype": "Link", + "in_standard_filter": 1, + "label": "Set Target Warehouse", + "no_copy": 1, + "oldfieldname": "to_warehouse", + "oldfieldtype": "Link", + "options": "Warehouse", + "print_hide": 1 + }, + { + "description": "Company which internal customer represents.", + "fetch_from": "customer.represents_company", + "fieldname": "represents_company", + "fieldtype": "Link", + "label": "Represents Company", + "options": "Company", + "read_only": 1 } ], "icon": "fa fa-truck", "idx": 146, "is_submittable": 1, "links": [], - "modified": "2020-11-30 12:54:45.407289", + "modified": "2020-12-26 17:07:59.194403", "modified_by": "Administrator", "module": "Stock", "name": "Delivery Note", diff --git a/erpnext/stock/doctype/delivery_note/delivery_note.py b/erpnext/stock/doctype/delivery_note/delivery_note.py index a30cadf0a04..fa5a7fbe719 100644 --- a/erpnext/stock/doctype/delivery_note/delivery_note.py +++ b/erpnext/stock/doctype/delivery_note/delivery_note.py @@ -664,7 +664,8 @@ def make_inter_company_purchase_receipt(source_name, target_doc=None): return make_inter_company_transaction("Delivery Note", source_name, target_doc) def make_inter_company_transaction(doctype, source_name, target_doc=None): - from erpnext.accounts.doctype.sales_invoice.sales_invoice import validate_inter_company_transaction, get_inter_company_details + from erpnext.accounts.doctype.sales_invoice.sales_invoice import (validate_inter_company_transaction, + get_inter_company_details, update_address, update_taxes, set_purchase_references) if doctype == 'Delivery Note': source_doc = frappe.get_doc(doctype, source_name) @@ -682,6 +683,7 @@ def make_inter_company_transaction(doctype, source_name, target_doc=None): def set_missing_values(source, target): target.run_method("set_missing_values") + set_purchase_references(target) if target.doctype == 'Purchase Receipt': master_doctype = 'Purchase Taxes and Charges Template' @@ -697,21 +699,35 @@ def make_inter_company_transaction(doctype, source_name, target_doc=None): if target_doc.doctype == 'Purchase Receipt': target_doc.company = details.get("company") target_doc.supplier = details.get("party") - target_doc.supplier_address = source_doc.company_address - target_doc.shipping_address = source_doc.shipping_address_name or source_doc.customer_address target_doc.buying_price_list = source_doc.selling_price_list target_doc.is_internal_supplier = 1 target_doc.inter_company_reference = source_doc.name + + # Invert the address on target doc creation + update_address(target_doc, 'supplier_address', 'address_display', source_doc.company_address) + update_address(target_doc, 'shipping_address', 'shipping_address_display', source_doc.customer_address) + + update_taxes(target_doc, party=target_doc.supplier, party_type='Supplier', company=target_doc.company, + doctype=target_doc.doctype, party_address=target_doc.supplier_address, + company_address=target_doc.shipping_address) else: target_doc.company = details.get("company") target_doc.customer = details.get("party") target_doc.company_address = source_doc.supplier_address - target_doc.shipping_address_name = source_doc.shipping_address target_doc.selling_price_list = source_doc.buying_price_list target_doc.is_internal_customer = 1 target_doc.inter_company_reference = source_doc.name - doclist = get_mapped_doc(doctype, source_name, { + # Invert the address on target doc creation + update_address(target_doc, 'company_address', 'company_address_display', source_doc.supplier_address) + update_address(target_doc, 'shipping_address_name', 'shipping_address', source_doc.shipping_address) + update_address(target_doc, 'customer_address', 'address_display', source_doc.shipping_address) + + update_taxes(target_doc, party=target_doc.customer, party_type='Customer', company=target_doc.company, + doctype=target_doc.doctype, party_address=target_doc.customer_address, + company_address=target_doc.company_address, shipping_address_name=target_doc.shipping_address_name) + + doclist = get_mapped_doc(doctype, source_name, { doctype: { "doctype": target_doctype, "postprocess": update_details, @@ -722,7 +738,10 @@ def make_inter_company_transaction(doctype, source_name, target_doc=None): doctype +" Item": { "doctype": target_doctype + " Item", "field_map": { - source_document_warehouse_field: target_document_warehouse_field + source_document_warehouse_field: target_document_warehouse_field, + 'name': 'delivery_note_item', + 'batch_no': 'batch_no', + 'serial_no': 'serial_no' }, "field_no_map": [ "warehouse" diff --git a/erpnext/stock/doctype/delivery_note_item/delivery_note_item.json b/erpnext/stock/doctype/delivery_note_item/delivery_note_item.json index 4bbf3de5940..9de088df0ee 100644 --- a/erpnext/stock/doctype/delivery_note_item/delivery_note_item.json +++ b/erpnext/stock/doctype/delivery_note_item/delivery_note_item.json @@ -458,7 +458,7 @@ "fieldname": "warehouse", "fieldtype": "Link", "in_list_view": 1, - "label": "From Warehouse", + "label": "Warehouse", "oldfieldname": "warehouse", "oldfieldtype": "Link", "options": "Warehouse", @@ -467,11 +467,12 @@ "width": "100px" }, { + "depends_on": "eval:parent.is_internal_customer", "fieldname": "target_warehouse", "fieldtype": "Link", "hidden": 1, "ignore_user_permissions": 1, - "label": "Customer Warehouse (Optional)", + "label": "Target Warehouse", "no_copy": 1, "options": "Warehouse", "print_hide": 1 @@ -748,7 +749,7 @@ "index_web_pages_for_search": 1, "istable": 1, "links": [], - "modified": "2020-12-07 19:59:27.119856", + "modified": "2020-12-26 17:31:27.029803", "modified_by": "Administrator", "module": "Stock", "name": "Delivery Note Item", diff --git a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.json b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.json index 55f0f0cb269..32d349f3031 100755 --- a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.json +++ b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.json @@ -48,6 +48,7 @@ "set_warehouse", "rejected_warehouse", "col_break_warehouse", + "set_from_warehouse", "is_subcontracted", "supplier_warehouse", "items_section", @@ -115,6 +116,7 @@ "per_returned", "is_internal_supplier", "inter_company_reference", + "represents_company", "subscription_detail", "auto_repeat", "printing_settings", @@ -1087,7 +1089,9 @@ "fieldname": "inter_company_reference", "fieldtype": "Link", "label": "Inter Company Reference", + "no_copy": 1, "options": "Delivery Note", + "print_hide": 1, "read_only": 1 }, { @@ -1121,13 +1125,29 @@ "no_copy": 1, "print_hide": 1, "read_only": 1 + }, + { + "depends_on": "eval: doc.is_internal_supplier", + "description": "Sets 'From Warehouse' in each row of the items table.", + "fieldname": "set_from_warehouse", + "fieldtype": "Link", + "label": "Set From Warehouse", + "options": "Warehouse" + }, + { + "fetch_from": "supplier.represents_company", + "fieldname": "represents_company", + "fieldtype": "Link", + "label": "Represents Company", + "options": "Company", + "read_only": 1 } ], "icon": "fa fa-truck", "idx": 261, "is_submittable": 1, "links": [], - "modified": "2020-12-08 18:31:32.234503", + "modified": "2020-12-26 20:49:39.106049", "modified_by": "Administrator", "module": "Stock", "name": "Purchase Receipt", diff --git a/erpnext/stock/doctype/purchase_receipt_item/purchase_receipt_item.json b/erpnext/stock/doctype/purchase_receipt_item/purchase_receipt_item.json index 662e50c6931..e99119202e7 100644 --- a/erpnext/stock/doctype/purchase_receipt_item/purchase_receipt_item.json +++ b/erpnext/stock/doctype/purchase_receipt_item/purchase_receipt_item.json @@ -76,6 +76,7 @@ "purchase_order_item", "material_request_item", "purchase_receipt_item", + "delivery_note_item", "putaway_rule", "section_break_45", "allow_zero_valuation_rate", @@ -819,11 +820,12 @@ "read_only": 1 }, { + "depends_on": "eval:parent.is_internal_supplier", "fieldname": "from_warehouse", "fieldtype": "Link", "hidden": 1, "ignore_user_permissions": 1, - "label": "Supplier Warehouse", + "label": "From Warehouse", "options": "Warehouse" }, { @@ -871,12 +873,20 @@ "fieldtype": "Float", "label": "Received Qty in Stock UOM", "print_hide": 1 + }, + { + "fieldname": "delivery_note_item", + "fieldtype": "Data", + "label": "Delivery Note Item", + "no_copy": 1, + "print_hide": 1, + "read_only": 1 } ], "idx": 1, "istable": 1, "links": [], - "modified": "2020-12-09 10:00:38.204294", + "modified": "2020-12-26 16:50:56.479347", "modified_by": "Administrator", "module": "Stock", "name": "Purchase Receipt Item", diff --git a/erpnext/stock/stock_ledger.py b/erpnext/stock/stock_ledger.py index 5b9ada0ee56..2b2a7a202dd 100644 --- a/erpnext/stock/stock_ledger.py +++ b/erpnext/stock/stock_ledger.py @@ -41,7 +41,7 @@ def make_sl_entries(sl_entries, allow_negative_stock=False, via_landed_cost_vouc if sle.get("actual_qty") or sle.get("voucher_type")=="Stock Reconciliation": sle_doc = make_entry(sle, allow_negative_stock, via_landed_cost_voucher) - + args = sle_doc.as_dict() update_bin(args, allow_negative_stock, via_landed_cost_voucher) @@ -65,7 +65,7 @@ def make_entry(args, allow_negative_stock=False, via_landed_cost_voucher=False): def repost_future_sle(args=None, voucher_type=None, voucher_no=None, allow_negative_stock=False, via_landed_cost_voucher=False): if not args and voucher_type and voucher_no: args = get_args_for_voucher(voucher_type, voucher_no) - + distinct_item_warehouses = [(d.item_code, d.warehouse) for d in args] i = 0 @@ -80,7 +80,7 @@ def repost_future_sle(args=None, voucher_type=None, voucher_no=None, allow_negat for item_wh, new_sle in iteritems(obj.new_items): if item_wh not in distinct_item_warehouses: args.append(new_sle) - + i += 1 def get_args_for_voucher(voucher_type, voucher_no): @@ -127,7 +127,7 @@ class update_entries_after(object): self.initialize_previous_data(self.args) self.build() - + def get_precision(self): company_base_currency = frappe.get_cached_value('Company', self.company, "default_currency") self.precision = get_field_precision(frappe.get_meta("Stock Ledger Entry").get_field("stock_value"), @@ -213,13 +213,13 @@ class update_entries_after(object): # includes current entry! args = self.data[self.args.warehouse].previous_sle \ or frappe._dict({"item_code": self.item_code, "warehouse": self.args.warehouse}) - + return list(self.get_sle_after_datetime(args)) def get_dependent_entries_to_fix(self, entries_to_fix, sle): dependant_sle = get_sle_by_voucher_detail_no(sle.dependant_sle_voucher_detail_no, excluded_sle=sle.name) - + if not dependant_sle: return elif dependant_sle.item_code == self.item_code and dependant_sle.warehouse == self.args.warehouse: @@ -251,7 +251,7 @@ class update_entries_after(object): # Get dynamic incoming/outgoing rate self.get_dynamic_incoming_outgoing_rate(sle) - + if sle.serial_no: self.get_serialized_values(sle) self.wh_data.qty_after_transaction += flt(sle.actual_qty) @@ -329,7 +329,7 @@ class update_entries_after(object): rate = get_rate_for_return(sle.voucher_type, sle.voucher_no, sle.item_code, voucher_detail_no=sle.voucher_detail_no) else: if sle.voucher_type in ("Purchase Receipt", "Purchase Invoice"): - rate_field = "valuation_rate" + rate_field = "valuation_rate" else: rate_field = "incoming_rate" @@ -344,7 +344,7 @@ class update_entries_after(object): ref_doctype = "Packed Item" else: ref_doctype = "Purchase Receipt Item Supplied" - + rate = frappe.db.get_value(ref_doctype, {"parent_detail_docname": sle.voucher_detail_no, "item_code": sle.item_code}, rate_field) @@ -374,7 +374,7 @@ class update_entries_after(object): stock_entry.db_update() for d in stock_entry.items: d.db_update() - + def update_rate_on_delivery_and_sales_return(self, sle, outgoing_rate): # Update item's incoming rate on transaction item_code = frappe.db.get_value(sle.voucher_type + " Item", sle.voucher_detail_no, "item_code") @@ -487,7 +487,6 @@ class update_entries_after(object): self.wh_data.valuation_rate = new_stock_value / new_stock_qty else: self.wh_data.valuation_rate = sle.outgoing_rate - else: if flt(self.wh_data.qty_after_transaction) >= 0 and sle.outgoing_rate: self.wh_data.valuation_rate = sle.outgoing_rate @@ -631,7 +630,7 @@ class update_entries_after(object): frappe.throw(message, NegativeStockError, title='Insufficient Stock') else: raise NegativeStockError(message) - + def update_bin(self): # update bin for each warehouse for warehouse, data in iteritems(self.data): @@ -766,7 +765,7 @@ def update_qty_in_future_sle(args, allow_negative_stock=None): frappe.db.sql(""" update `tabStock Ledger Entry` set qty_after_transaction = qty_after_transaction + {qty} - where + where item_code = %(item_code)s and warehouse = %(warehouse)s and voucher_no != %(voucher_no)s @@ -794,7 +793,7 @@ def validate_negative_qty_in_future_sle(args, allow_negative_stock=None): frappe.get_desk_link('Warehouse', args.warehouse), sle[0]["posting_date"], sle[0]["posting_time"], frappe.get_desk_link(sle[0]["voucher_type"], sle[0]["voucher_no"])) - + frappe.throw(message, NegativeStockError, title='Insufficient Stock') def get_future_sle_with_negative_qty(args): @@ -803,7 +802,7 @@ def get_future_sle_with_negative_qty(args): qty_after_transaction, posting_date, posting_time, voucher_type, voucher_no from `tabStock Ledger Entry` - where + where item_code = %(item_code)s and warehouse = %(warehouse)s and voucher_no != %(voucher_no)s From e6f925e5e6f121ce4726d2e8d2ad6aab92723430 Mon Sep 17 00:00:00 2001 From: Anupam Date: Thu, 28 Jan 2021 15:58:03 +0530 Subject: [PATCH 425/477] review changes --- 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 a30969825b9..876eaea8e6a 100644 --- a/erpnext/templates/pages/cart.html +++ b/erpnext/templates/pages/cart.html @@ -48,7 +48,7 @@ {% if doc.items %}
    - {{ _("Add More") }} + {{ _("Continue Shopping") }} {% if cart_settings.enable_checkout %}
    `; } else { return `
    ${frappe.get_abbr(item.item_name)}
    `; } @@ -105,7 +107,7 @@ erpnext.PointOfSale.ItemSelector = class {
    ${format_currency(item.price_list_rate, item.currency, 0) || 0}
    ` - ) + ); } make_search_bar() { @@ -140,7 +142,7 @@ erpnext.PointOfSale.ItemSelector = class { filters: { pos_profile: doc ? doc.pos_profile : '' } - } + }; }, }, parent: this.$component.find('.item-group-field'), @@ -176,7 +178,7 @@ erpnext.PointOfSale.ItemSelector = class { uom = uom === "undefined" ? undefined : uom; me.events.item_selected({ field: 'qty', value: "+1", item: { item_code, batch_no, serial_no, uom }}); - }) + }); this.search_field.$input.on('input', (e) => { clearTimeout(this.last_search); @@ -247,6 +249,7 @@ erpnext.PointOfSale.ItemSelector = class { this.get_items({ search_value: search_term }) .then(({ message }) => { + // eslint-disable-next-line no-unused-vars const { items, serial_no, batch_no, barcode } = message; if (search_term && !barcode) { this.search_index[search_term] = items; @@ -260,26 +263,26 @@ erpnext.PointOfSale.ItemSelector = class { add_filtered_item_to_cart() { this.$items_container.find(".item-wrapper").click(); } - + resize_selector(minimize) { minimize ? - this.$component.find('.filter-section').css('grid-template-columns', 'repeat(1, minmax(0, 1fr))') : - this.$component.find('.filter-section').css('grid-template-columns', 'repeat(12, minmax(0, 1fr))'); + this.$component.find('.filter-section').css('grid-template-columns', 'repeat(1, minmax(0, 1fr))') : + this.$component.find('.filter-section').css('grid-template-columns', 'repeat(12, minmax(0, 1fr))'); minimize ? - this.$component.find('.search-field').css('margin', 'var(--margin-sm) 0px') : - this.$component.find('.search-field').css('margin', '0px var(--margin-sm)'); + this.$component.find('.search-field').css('margin', 'var(--margin-sm) 0px') : + this.$component.find('.search-field').css('margin', '0px var(--margin-sm)'); minimize ? - this.$component.css('grid-column', 'span 2 / span 2') : - this.$component.css('grid-column', 'span 6 / span 6') + this.$component.css('grid-column', 'span 2 / span 2') : + this.$component.css('grid-column', 'span 6 / span 6'); minimize ? - this.$items_container.css('grid-template-columns', 'repeat(1, minmax(0, 1fr))') : - this.$items_container.css('grid-template-columns', 'repeat(4, minmax(0, 1fr))') + this.$items_container.css('grid-template-columns', 'repeat(1, minmax(0, 1fr))') : + this.$items_container.css('grid-template-columns', 'repeat(4, minmax(0, 1fr))'); } toggle_component(show) { show ? this.$component.css('display', 'flex') : this.$component.css('display', 'none'); } -} \ No newline at end of file +}; \ No newline at end of file diff --git a/erpnext/selling/page/point_of_sale/pos_past_order_summary.js b/erpnext/selling/page/point_of_sale/pos_past_order_summary.js index 79eaf05cb25..be2b769a8a3 100644 --- a/erpnext/selling/page/point_of_sale/pos_past_order_summary.js +++ b/erpnext/selling/page/point_of_sale/pos_past_order_summary.js @@ -48,7 +48,7 @@ erpnext.PointOfSale.PastOrderSummary = class { const email_dialog = new frappe.ui.Dialog({ title: 'Email Receipt', fields: [ - {fieldname:'email_id', fieldtype:'Data', options: 'Email', label:'Email ID'}, + {fieldname: 'email_id', fieldtype: 'Data', options: 'Email', label: 'Email ID'}, // {fieldname:'remarks', fieldtype:'Text', label:'Remarks (if any)'} ], primary_action: () => { @@ -61,7 +61,7 @@ erpnext.PointOfSale.PastOrderSummary = class { const print_dialog = new frappe.ui.Dialog({ title: 'Print Receipt', fields: [ - {fieldname:'print', fieldtype:'Data', label:'Print Preview'} + {fieldname: 'print', fieldtype: 'Data', label: 'Print Preview'} ], primary_action: () => { const frm = this.events.get_frm(); @@ -132,18 +132,17 @@ erpnext.PointOfSale.PastOrderSummary = class { get_taxes_html(doc) { if (!doc.taxes.length) return ''; - return ` -
    - ${ - doc.taxes.map((t, i) => { - const description = /[0-9]+/.test(t.description) ? t.description : `${t.description} @ ${t.rate}%`; - return `
    -
    ${description}
    -
    ${format_currency(t.tax_amount_after_discount_amount, doc.currency)}
    -
    ` - }).join('') - } -
    `; + let taxes_html = doc.taxes.map(t => { + const description = /[0-9]+/.test(t.description) ? t.description : `${t.description} @ ${t.rate}%`; + return ` +
    +
    ${description}
    +
    ${format_currency(t.tax_amount_after_discount_amount, doc.currency)}
    +
    + `; + }).join(''); + + return `
    ${taxes_html}
    `; } get_grand_total_html(doc) { @@ -178,9 +177,6 @@ erpnext.PointOfSale.PastOrderSummary = class { this.$summary_container.on('click', '.delete-btn', () => { this.events.delete_order(this.doc.name); this.show_summary_placeholder(); - // this.toggle_component(false); - // this.$component.find('.no-summary-placeholder').removeClass('d-none'); - // this.$summary_wrapper.addClass('d-none'); }); this.$summary_container.on('click', '.new-btn', () => { @@ -237,7 +233,7 @@ erpnext.PointOfSale.PastOrderSummary = class { const print_format = frm.pos_print_format; frappe.call({ - method:"frappe.core.doctype.communication.email.make", + method: "frappe.core.doctype.communication.email.make", args: { recipients: recipients, subject: __(frm.meta.name) + ': ' + doc.name, @@ -246,14 +242,14 @@ erpnext.PointOfSale.PastOrderSummary = class { send_email: 1, print_format, sender_full_name: frappe.user.full_name(), - _lang : doc.language + _lang: doc.language }, callback: r => { - if(!r.exc) { + if (!r.exc) { frappe.utils.play_sound("email"); - if(r.message["emails_not_sent_to"]) { + if (r.message["emails_not_sent_to"]) { frappe.msgprint(__( - "Email not sent to {0} (unsubscribed / disabled)", + "Email not sent to {0} (unsubscribed / disabled)", [ frappe.utils.escape_html(r.message["emails_not_sent_to"]) ] )); } else { @@ -309,10 +305,10 @@ erpnext.PointOfSale.PastOrderSummary = class { load_summary_of(doc, after_submission=false) { after_submission ? this.$component.css('grid-column', 'span 10 / span 10') : - this.$component.css('grid-column', 'span 6 / span 6') - - this.toggle_summary_placeholder(false) - + this.$component.css('grid-column', 'span 6 / span 6'); + + this.toggle_summary_placeholder(false); + this.doc = doc; this.attach_document_info(doc); @@ -338,7 +334,7 @@ erpnext.PointOfSale.PastOrderSummary = class { attach_items_info(doc) { this.$items_container.html(''); - doc.items.forEach((item, i) => { + doc.items.forEach(item => { const item_dom = this.get_item_html(doc, item); this.$items_container.append(item_dom); this.set_dynamic_rate_header_width(); From a3585e40f7aec22ee3951378a555e5c8775aaf66 Mon Sep 17 00:00:00 2001 From: prssanna Date: Mon, 1 Feb 2021 19:50:27 +0530 Subject: [PATCH 439/477] style: fix formatting --- .../accounts/doctype/account/account_tree.js | 2 +- erpnext/crm/doctype/contract/contract_list.js | 20 +++++++++---------- .../course_scheduling_tool.js | 4 ++-- .../healthcare_service_unit_tree.js | 8 ++++---- erpnext/hr/page/team_updates/team_updates.js | 2 +- erpnext/public/scss/shopping_cart.scss | 2 +- .../page/point_of_sale/point_of_sale.js | 2 +- erpnext/shopping_cart/search.py | 3 +-- erpnext/templates/includes/cart.js | 6 ++++-- 9 files changed, 25 insertions(+), 24 deletions(-) diff --git a/erpnext/accounts/doctype/account/account_tree.js b/erpnext/accounts/doctype/account/account_tree.js index 7dc05335066..7516134baf5 100644 --- a/erpnext/accounts/doctype/account/account_tree.js +++ b/erpnext/accounts/doctype/account/account_tree.js @@ -123,7 +123,7 @@ frappe.treeview_settings["Account"] = { }, "add"); }, onrender: function(node) { - if(frappe.boot.user.can_read.indexOf("GL Entry") !== -1){ + if (frappe.boot.user.can_read.indexOf("GL Entry") !== -1) { // show Dr if positive since balance is calculated as debit - credit else show Cr let balance = node.data.balance_in_account_currency || node.data.balance; diff --git a/erpnext/crm/doctype/contract/contract_list.js b/erpnext/crm/doctype/contract/contract_list.js index a09d123ed26..26a2907c7cc 100644 --- a/erpnext/crm/doctype/contract/contract_list.js +++ b/erpnext/crm/doctype/contract/contract_list.js @@ -1,12 +1,12 @@ frappe.listview_settings['Contract'] = { - add_fields: ["status"], - get_indicator: function (doc) { - if (doc.status == "Unsigned") { - return [__(doc.status), "red", "status,=," + doc.status]; - } else if (doc.status == "Active") { - return [__(doc.status), "green", "status,=," + doc.status]; - } else if (doc.status == "Inactive") { - return [__(doc.status), "gray", "status,=," + doc.status]; - } - }, + add_fields: ["status"], + get_indicator: function (doc) { + if (doc.status == "Unsigned") { + return [__(doc.status), "red", "status,=," + doc.status]; + } else if (doc.status == "Active") { + return [__(doc.status), "green", "status,=," + doc.status]; + } else if (doc.status == "Inactive") { + return [__(doc.status), "gray", "status,=," + doc.status]; + } + }, }; \ No newline at end of file diff --git a/erpnext/education/doctype/course_scheduling_tool/course_scheduling_tool.js b/erpnext/education/doctype/course_scheduling_tool/course_scheduling_tool.js index 4e2ccaa30cf..8699103cb2c 100644 --- a/erpnext/education/doctype/course_scheduling_tool/course_scheduling_tool.js +++ b/erpnext/education/doctype/course_scheduling_tool/course_scheduling_tool.js @@ -24,8 +24,8 @@ frappe.ui.form.on('Course Scheduling Tool', {
    - ${course_schedules.map( - c => ` + ${course_schedules.map(c => + `` ).join('')} diff --git a/erpnext/healthcare/doctype/healthcare_service_unit/healthcare_service_unit_tree.js b/erpnext/healthcare/doctype/healthcare_service_unit/healthcare_service_unit_tree.js index bfb0ba13ceb..b75f2718271 100644 --- a/erpnext/healthcare/doctype/healthcare_service_unit/healthcare_service_unit_tree.js +++ b/erpnext/healthcare/doctype/healthcare_service_unit/healthcare_service_unit_tree.js @@ -12,19 +12,19 @@ frappe.treeview_settings["Healthcare Service Unit"] = { get_tree_nodes: 'erpnext.healthcare.utils.get_children', ignore_fields:["parent_healthcare_service_unit"], onrender: function(node) { - if (node.data.occupied_out_of_vacant!==undefined){ + if (node.data.occupied_out_of_vacant!==undefined) { $('' + " " + node.data.occupied_out_of_vacant + '').insertBefore(node.$ul); } if (node.data && node.data.inpatient_occupancy!==undefined) { - if (node.data.inpatient_occupancy == 1){ - if (node.data.occupancy_status == "Occupied"){ + if (node.data.inpatient_occupancy == 1) { + if (node.data.occupancy_status == "Occupied") { $('' + " " + node.data.occupancy_status + '').insertBefore(node.$ul); } - if (node.data.occupancy_status == "Vacant"){ + if (node.data.occupancy_status == "Vacant") { $('' + " " + node.data.occupancy_status + '').insertBefore(node.$ul); diff --git a/erpnext/hr/page/team_updates/team_updates.js b/erpnext/hr/page/team_updates/team_updates.js index 29780b81619..13d0074660b 100644 --- a/erpnext/hr/page/team_updates/team_updates.js +++ b/erpnext/hr/page/team_updates/team_updates.js @@ -41,7 +41,7 @@ frappe.team_updates = { me.add_row(d); }); } else { - frappe.show_alert({message:__('No more updates'), indicator:'gray'}); + frappe.show_alert({message: __('No more updates'), indicator: 'gray'}); me.more.parent().addClass('hidden'); } } diff --git a/erpnext/public/scss/shopping_cart.scss b/erpnext/public/scss/shopping_cart.scss index ee30f531862..159a8a47cd3 100644 --- a/erpnext/public/scss/shopping_cart.scss +++ b/erpnext/public/scss/shopping_cart.scss @@ -58,7 +58,7 @@ body.product-page { .card-grid { display: grid; grid-gap: 15px; - grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));; + grid-template-columns: repeat(auto-fit, minmax(120px, 1fr)); } } diff --git a/erpnext/selling/page/point_of_sale/point_of_sale.js b/erpnext/selling/page/point_of_sale/point_of_sale.js index 6d8ad7e1af0..501c7df78b5 100644 --- a/erpnext/selling/page/point_of_sale/point_of_sale.js +++ b/erpnext/selling/page/point_of_sale/point_of_sale.js @@ -10,7 +10,7 @@ frappe.pages['point-of-sale'].on_page_load = function(wrapper) { frappe.require('assets/js/point-of-sale.min.js', function() { wrapper.pos = new erpnext.PointOfSale.Controller(wrapper); window.cur_pos = wrapper.pos; - }) + }); }; frappe.pages['point-of-sale'].refresh = function(wrapper) { diff --git a/erpnext/shopping_cart/search.py b/erpnext/shopping_cart/search.py index 012d09fafc8..63e9fe1b31b 100644 --- a/erpnext/shopping_cart/search.py +++ b/erpnext/shopping_cart/search.py @@ -1,7 +1,6 @@ import frappe from frappe.search.full_text_search import FullTextSearch from whoosh.fields import TEXT, ID, KEYWORD, Schema -from frappe.website.render import render_page from frappe.utils import strip_html_tags from whoosh.qparser import MultifieldParser, FieldsPlugin, WildcardPlugin from whoosh.analysis import StemmingAnalyzer @@ -52,7 +51,7 @@ class ProductSearch(FullTextSearch): if item.web_long_description: content = strip_html_tags(item.web_long_description) - elif description: + elif item.description: content = strip_html_tags(item.description) return frappe._dict( diff --git a/erpnext/templates/includes/cart.js b/erpnext/templates/includes/cart.js index 0de02676afe..c390cd171d3 100644 --- a/erpnext/templates/includes/cart.js +++ b/erpnext/templates/includes/cart.js @@ -35,7 +35,7 @@ $.extend(shopping_cart, { }, get_update_address_dialog() { - return new frappe.ui.Dialog({ + let d = new frappe.ui.Dialog({ title: "Select Address", fields: [{ 'fieldtype': 'HTML', @@ -56,7 +56,7 @@ $.extend(shopping_cart, { }, callback: function(r) { d.hide(); - if(!r.exc) { + if (!r.exc) { $(".cart-tax-items").html(r.message.taxes); shopping_cart.parent.find( `.address-container[data-address-type="${address_type}"]` @@ -66,6 +66,8 @@ $.extend(shopping_cart, { }); } }); + + return d; }, get_address_template(type) { From 1ab79da7d1324e386d2789e9e47277b9d642d124 Mon Sep 17 00:00:00 2001 From: Suraj Shetty Date: Mon, 1 Feb 2021 19:51:25 +0530 Subject: [PATCH 440/477] style: Fix formatting issues --- .eslintrc | 3 +- .../page/point_of_sale/point_of_sale.js | 4 +- .../page/point_of_sale/pos_controller.js | 8 +- .../selling/page/point_of_sale/pos_payment.js | 110 +++++++++--------- 4 files changed, 60 insertions(+), 65 deletions(-) diff --git a/.eslintrc b/.eslintrc index 91ebb2b84f7..3b6ab7498d9 100644 --- a/.eslintrc +++ b/.eslintrc @@ -150,6 +150,7 @@ "it": true, "context": true, "before": true, - "beforeEach": true + "beforeEach": true, + "onScan": true } } diff --git a/erpnext/selling/page/point_of_sale/point_of_sale.js b/erpnext/selling/page/point_of_sale/point_of_sale.js index 6d8ad7e1af0..e3405e0ce89 100644 --- a/erpnext/selling/page/point_of_sale/point_of_sale.js +++ b/erpnext/selling/page/point_of_sale/point_of_sale.js @@ -10,7 +10,7 @@ frappe.pages['point-of-sale'].on_page_load = function(wrapper) { frappe.require('assets/js/point-of-sale.min.js', function() { wrapper.pos = new erpnext.PointOfSale.Controller(wrapper); window.cur_pos = wrapper.pos; - }) + }); }; frappe.pages['point-of-sale'].refresh = function(wrapper) { @@ -19,4 +19,4 @@ frappe.pages['point-of-sale'].refresh = function(wrapper) { wrapper.pos.wrapper.html(""); wrapper.pos.check_opening_entry(); } -} \ No newline at end of file +}; \ No newline at end of file diff --git a/erpnext/selling/page/point_of_sale/pos_controller.js b/erpnext/selling/page/point_of_sale/pos_controller.js index dc1e3bf20aa..bf70f0785fa 100644 --- a/erpnext/selling/page/point_of_sale/pos_controller.js +++ b/erpnext/selling/page/point_of_sale/pos_controller.js @@ -191,8 +191,8 @@ erpnext.PointOfSale.Controller = class { this.frm.save(undefined, undefined, undefined, () => { frappe.show_alert({ - message:__("There was an error saving the document."), - indicator:'red' + message: __("There was an error saving the document."), + indicator: 'red' }); frappe.utils.play_sound("error"); }).then(() => { @@ -201,7 +201,7 @@ erpnext.PointOfSale.Controller = class { () => this.make_new_invoice(), () => frappe.dom.unfreeze(), ]); - }) + }); } close_pos() { @@ -682,5 +682,5 @@ erpnext.PointOfSale.Controller = class { }) .catch(e => console.log(e)); } -} +}; diff --git a/erpnext/selling/page/point_of_sale/pos_payment.js b/erpnext/selling/page/point_of_sale/pos_payment.js index 365c27b12f3..fb26f22625b 100644 --- a/erpnext/selling/page/point_of_sale/pos_payment.js +++ b/erpnext/selling/page/point_of_sale/pos_payment.js @@ -1,3 +1,4 @@ +/* eslint-disable no-unused-vars */ erpnext.PointOfSale.Payment = class { constructor({ events, wrapper }) { this.wrapper = wrapper; @@ -11,7 +12,7 @@ erpnext.PointOfSale.Payment = class { this.initialize_numpad(); this.bind_events(); this.attach_shortcuts(); - + } prepare_dom() { @@ -31,7 +32,7 @@ erpnext.PointOfSale.Payment = class {
    Complete Order
    ` - ) + ); this.$component = this.wrapper.find('.payment-container'); this.$payment_modes = this.$component.find('.payment-modes'); this.$totals_section = this.$component.find('.totals-section'); @@ -44,7 +45,7 @@ erpnext.PointOfSale.Payment = class { frappe.db.get_doc("POS Settings", undefined).then((doc) => { const fields = doc.invoice_fields; if (!fields.length) return; - + this.$invoice_fields = this.$invoice_fields_section.find('.invoice-fields'); this.$invoice_fields.html(''); const frm = this.events.get_frm(); @@ -54,8 +55,10 @@ erpnext.PointOfSale.Payment = class { `
    ` ); let df_events = { - onchange: function() { frm.set_value(this.df.fieldname, this.value); } - } + onchange: function() { + frm.set_value(this.df.fieldname, this.value); + } + }; if (df.fieldtype == "Button") { df_events = { click: function() { @@ -63,11 +66,11 @@ erpnext.PointOfSale.Payment = class { frm.script_manager.trigger(df.fieldname, frm.doc.doctype, frm.doc.docname); } } - } + }; } this[`${df.fieldname}_field`] = frappe.ui.form.make_control({ - df: { + df: { ...df, ...df_events }, @@ -75,7 +78,7 @@ erpnext.PointOfSale.Payment = class { render_input: true, }); this[`${df.fieldname}_field`].set_value(frm.doc[df.fieldname]); - }) + }); }); } @@ -95,13 +98,12 @@ erpnext.PointOfSale.Payment = class { [ 7, 8, 9 ], [ '.', 0, 'Delete' ] ], - }) + }); this.numpad_value = ''; } on_numpad_clicked($btn) { - const me = this; const button_value = $btn.attr('data-button-value'); highlight_numpad_btn($btn); @@ -155,10 +157,10 @@ erpnext.PointOfSale.Payment = class { me.selected_mode = me[`${mode}_control`]; me.selected_mode && me.selected_mode.$input.get(0).focus(); const current_value = me.selected_mode ? me.selected_mode.get_value() : undefined; - !current_value && doc.grand_total > doc.paid_amount && me.selected_mode ? + !current_value && doc.grand_total > doc.paid_amount && me.selected_mode ? me.selected_mode.set_value(doc.grand_total - doc.paid_amount) : ''; } - }) + }); frappe.realtime.on("process_phone_payment", function(data) { frappe.dom.unfreeze(); @@ -168,7 +170,7 @@ erpnext.PointOfSale.Payment = class { if (data["ResultCode"] == 0) { title = __("Payment Received"); - $('.btn.btn-xs.btn-default[data-fieldname=request_for_payment]').html(`Payment Received`) + $('.btn.btn-xs.btn-default[data-fieldname=request_for_payment]').html(`Payment Received`); me.events.submit_invoice(); } @@ -178,10 +180,10 @@ erpnext.PointOfSale.Payment = class { }); }); - this.$payment_modes.on('click', '.shortcut', function(e) { + this.$payment_modes.on('click', '.shortcut', () => { const value = $(this).attr('data-value'); me.selected_mode.set_value(value); - }) + }); this.$component.on('click', '.submit-order-btn', () => { const doc = this.events.get_frm().doc; @@ -189,14 +191,14 @@ erpnext.PointOfSale.Payment = class { const items = doc.items; if (paid_amount == 0 || !items.length) { - const message = items.length ? __("You cannot submit the order without payment.") : __("You cannot submit empty order.") + const message = items.length ? __("You cannot submit the order without payment.") : __("You cannot submit empty order."); frappe.show_alert({ message, indicator: "orange" }); frappe.utils.play_sound("error"); return; } this.events.submit_invoice(); - }) + }); frappe.ui.form.on('POS Invoice', 'paid_amount', (frm) => { this.update_totals_section(frm.doc); @@ -205,7 +207,7 @@ erpnext.PointOfSale.Payment = class { const is_cash_shortcuts_invisible = !this.$payment_modes.find('.cash-shortcuts').is(':visible'); this.attach_cash_shortcuts(frm.doc); !is_cash_shortcuts_invisible && this.$payment_modes.find('.cash-shortcuts').css('display', 'grid'); - }) + }); frappe.ui.form.on('POS Invoice', 'loyalty_amount', (frm) => { const formatted_currency = format_currency(frm.doc.loyalty_amount, frm.doc.currency); @@ -239,14 +241,14 @@ erpnext.PointOfSale.Payment = class { const payment_is_visible = this.$component.is(":visible"); let active_mode = this.$payment_modes.find(".border-primary"); active_mode = active_mode.length ? active_mode.attr("data-mode") : undefined; - + if (!active_mode) return; - + const mode_of_payments = Array.from(this.$payment_modes.find(".mode-of-payment")).map(m => $(m).attr("data-mode")); const mode_index = mode_of_payments.indexOf(active_mode); const next_mode_index = (mode_index + 1) % mode_of_payments.length; const next_mode_to_be_clicked = this.$payment_modes.find(`.mode-of-payment[data-mode="${mode_of_payments[next_mode_index]}"]`); - + if (payment_is_visible && mode_index != next_mode_index) { next_mode_to_be_clicked.click(); } @@ -258,14 +260,8 @@ erpnext.PointOfSale.Payment = class { }); } - toggle_numpad(show) { - // if (show) { - // this.$numpad.css('display', 'flex'); - // this.$totals_section.addClass('w-60 justify-center').removeClass('justify-end w-full'); - // } else { - // this.$numpad.css('display', 'none'); - // this.$totals_section.removeClass('w-60 justify-center').addClass('justify-end w-full'); - // } + toggle_numpad() { + // pass } render_payment_section() { @@ -309,9 +305,8 @@ erpnext.PointOfSale.Payment = class { const payments = doc.payments; const currency = doc.currency; - this.$payment_modes.html( - `${ - payments.map((p, i) => { + this.$payment_modes.html(`${ + payments.map((p, i) => { const mode = p.mode_of_payment.replace(/ +/g, "_").toLowerCase(); const payment_type = p.type; const margin = i % 2 === 0 ? 'pr-2' : 'pl-2'; @@ -319,16 +314,15 @@ erpnext.PointOfSale.Payment = class { return ( `
    -
    - ${p.mode_of_payment} -
    ${amount}
    -
    -
    -
    ` - ) - }).join('') - }` - ) +
    + ${p.mode_of_payment} +
    ${amount}
    +
    +
    + ` + ); + }).join('') + }`); payments.forEach(p => { const mode = p.mode_of_payment.replace(/ +/g, "_").toLowerCase(); @@ -359,10 +353,10 @@ erpnext.PointOfSale.Payment = class { this.$payment_modes.find(`.${mode}.mode-of-payment-control`).parent().click(); }, 500); } - }) + }); this.render_loyalty_points_payment_mode(); - + this.attach_cash_shortcuts(doc); } @@ -376,12 +370,12 @@ erpnext.PointOfSale.Payment = class { this.$payment_modes.find('[data-payment-type="Cash"]').find('.mode-of-payment-control').after( `
    ${ - shortcuts.map(s => { - return `
    ${format_currency(s, currency, 0)}
    ` - }).join('') - } + shortcuts.map(s => { + return `
    ${format_currency(s, currency, 0)}
    `; + }).join('') +}
    ` - ) + ); } get_cash_shortcuts(grand_total) { @@ -393,13 +387,13 @@ erpnext.PointOfSale.Payment = class { const get_nearest = (amount, x) => { let nearest_x = Math.ceil((amount / x)) * x; return nearest_x === amount ? nearest_x + x : nearest_x; - } + }; return steps.reduce((finalArr, x) => { let nearest_x = get_nearest(grand_total, x); nearest_x = finalArr.indexOf(nearest_x) != -1 ? nearest_x + x : nearest_x; return [...finalArr, nearest_x]; - }, []); + }, []); } render_loyalty_points_payment_mode() { @@ -408,7 +402,7 @@ erpnext.PointOfSale.Payment = class { const { loyalty_program, loyalty_points, conversion_factor } = this.events.get_customer_details(); this.$payment_modes.find(`.mode-of-payment[data-mode="loyalty-amount"]`).parent().remove(); - + if (!loyalty_program) return; let description, read_only, max_redeemable_amount; @@ -416,7 +410,7 @@ erpnext.PointOfSale.Payment = class { description = __("You don't have enough points to redeem."); read_only = true; } else { - max_redeemable_amount = flt(flt(loyalty_points) * flt(conversion_factor), precision("loyalty_amount", doc)) + max_redeemable_amount = flt(flt(loyalty_points) * flt(conversion_factor), precision("loyalty_amount", doc)); description = __("You can redeem upto {0}.", [format_currency(max_redeemable_amount)]); read_only = false; } @@ -432,7 +426,7 @@ erpnext.PointOfSale.Payment = class {
    ` - ) + ); this['loyalty-amount_control'] = frappe.ui.form.make_control({ df: { @@ -474,7 +468,7 @@ erpnext.PointOfSale.Payment = class { `
    + Add Payment Method
    ` - ) + ); } update_totals_section(doc) { @@ -482,7 +476,7 @@ erpnext.PointOfSale.Payment = class { const paid_amount = doc.paid_amount; const remaining = doc.grand_total - doc.paid_amount; const change = doc.change_amount || remaining <= 0 ? -1 * remaining : undefined; - const currency = doc.currency + const currency = doc.currency; const label = change ? __('Change') : __('To Be Paid'); this.$totals.html( @@ -500,10 +494,10 @@ erpnext.PointOfSale.Payment = class {
    ${label}
    ${format_currency(change || remaining, currency)}
    ` - ) + ); } toggle_component(show) { show ? this.$component.css('display', 'flex') : this.$component.css('display', 'none'); } - } \ No newline at end of file +}; \ No newline at end of file From 11eae6d51a700b86e7a4257762ca114baa07616a Mon Sep 17 00:00:00 2001 From: prssanna Date: Mon, 1 Feb 2021 20:01:37 +0530 Subject: [PATCH 441/477] fix: add default product-image css class --- erpnext/templates/includes/macros.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/templates/includes/macros.html b/erpnext/templates/includes/macros.html index 174b14163e4..c44bfb53848 100644 --- a/erpnext/templates/includes/macros.html +++ b/erpnext/templates/includes/macros.html @@ -7,7 +7,7 @@ {% endmacro %} -{% macro product_image(website_image, css_class="", alt="") %} +{% macro product_image(website_image, css_class="product-image", alt="") %}
    {{ alt }}
    From fb016edb7a776a17bceccf98fc55c72ffd195874 Mon Sep 17 00:00:00 2001 From: Marica Date: Mon, 1 Feb 2021 20:05:29 +0530 Subject: [PATCH 442/477] chore: Use sql to set naming series in older projects (#24512) * chore: Use sql to set naming series in older projects * fix: Remove unncessary db.commit() --- erpnext/patches.txt | 2 +- .../add_naming_series_to_old_projects.py | 23 ++++--------------- 2 files changed, 6 insertions(+), 19 deletions(-) diff --git a/erpnext/patches.txt b/erpnext/patches.txt index 348f98fa740..a2b3dda4efe 100644 --- a/erpnext/patches.txt +++ b/erpnext/patches.txt @@ -749,4 +749,4 @@ erpnext.patches.v13_0.update_project_template_tasks erpnext.patches.v13_0.set_company_in_leave_ledger_entry erpnext.patches.v13_0.convert_qi_parameter_to_link_field erpnext.patches.v13_0.setup_patient_history_settings_for_standard_doctypes -erpnext.patches.v13_0.add_naming_series_to_old_projects +erpnext.patches.v13_0.add_naming_series_to_old_projects # 1-02-2021 diff --git a/erpnext/patches/v13_0/add_naming_series_to_old_projects.py b/erpnext/patches/v13_0/add_naming_series_to_old_projects.py index 79b67533ed6..5ed9040f1ed 100644 --- a/erpnext/patches/v13_0/add_naming_series_to_old_projects.py +++ b/erpnext/patches/v13_0/add_naming_series_to_old_projects.py @@ -4,23 +4,10 @@ from frappe.custom.doctype.property_setter.property_setter import make_property_ def execute(): frappe.reload_doc("projects", "doctype", "project") - projects = frappe.db.get_all("Project", - fields=["name", "naming_series", "modified"], - filters={ - "naming_series": ["is", "not set"] - }, - order_by="timestamp(modified) asc") - # disable set only once as the old docs must be saved - # (to bypass 'Cant change naming series' validation on save) - make_property_setter("Project", "naming_series", "set_only_once", 0, "Check") + frappe.db.sql("""UPDATE `tabProject` + SET + naming_series = 'PROJ-.####' + WHERE + naming_series is NULL""") - for entry in projects: - # need to save the doc so that users can edit old projects - doc = frappe.get_doc("Project", entry.name) - if not doc.naming_series: - doc.naming_series = "PROJ-.####" - doc.save() - - delete_property_setter("Project", "set_only_once", "naming_series") - frappe.db.commit() From f57efd1150af89c626515f7c78803897fccf56d7 Mon Sep 17 00:00:00 2001 From: Suraj Shetty Date: Mon, 1 Feb 2021 20:09:20 +0530 Subject: [PATCH 443/477] style: Fix invalid translation syntax usages --- erpnext/assets/doctype/asset/asset.py | 7 ++++--- erpnext/hr/doctype/employee_transfer/employee_transfer.py | 5 +++-- erpnext/setup/doctype/company/company.py | 5 +++-- 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/erpnext/assets/doctype/asset/asset.py b/erpnext/assets/doctype/asset/asset.py index 1793dad4940..e8e8ec6cc0b 100644 --- a/erpnext/assets/doctype/asset/asset.py +++ b/erpnext/assets/doctype/asset/asset.py @@ -133,9 +133,10 @@ class Asset(AccountsController): if self.is_existing_asset: return if self.gross_purchase_amount and self.gross_purchase_amount != self.purchase_receipt_amount: - frappe.throw(_("Gross Purchase Amount should be {} to purchase amount of one single Asset. {}\ - Please do not book expense of multiple assets against one single Asset.") - .format(frappe.bold("equal"), "
    "), title=_("Invalid Gross Purchase Amount")) + error_message = _("Gross Purchase Amount should be equal to purchase amount of one single Asset.") + error_message += "
    " + error_message += _("Please do not book expense of multiple assets against one single Asset.") + frappe.throw(error_message, title=_("Invalid Gross Purchase Amount")) def make_asset_movement(self): reference_doctype = 'Purchase Receipt' if self.purchase_receipt else 'Purchase Invoice' diff --git a/erpnext/hr/doctype/employee_transfer/employee_transfer.py b/erpnext/hr/doctype/employee_transfer/employee_transfer.py index 37d616f14d4..3539970a32a 100644 --- a/erpnext/hr/doctype/employee_transfer/employee_transfer.py +++ b/erpnext/hr/doctype/employee_transfer/employee_transfer.py @@ -50,8 +50,9 @@ class EmployeeTransfer(Document): employee = frappe.get_doc("Employee", self.employee) if self.create_new_employee_id: if self.new_employee_id: - frappe.throw(_("Please delete the Employee {0}\ - to cancel this document").format(self.new_employee_id)) + frappe.throw(_("Please delete the Employee {0} to cancel this document").format( + "{0}".format(self.new_employee_id) + )) #mark the employee as active employee.status = "Active" employee.relieving_date = '' diff --git a/erpnext/setup/doctype/company/company.py b/erpnext/setup/doctype/company/company.py index dc45cc1f7e5..819ba78e666 100644 --- a/erpnext/setup/doctype/company/company.py +++ b/erpnext/setup/doctype/company/company.py @@ -89,8 +89,9 @@ class Company(NestedSet): frappe.throw(_("Account {0} does not belong to company: {1}").format(self.get(account[1]), self.name)) if get_account_currency(self.get(account[1])) != self.default_currency: - frappe.throw(_("""{0} currency must be same as company's default currency. - Please select another account""").format(frappe.bold(account[0]))) + error_message = _("{0} currency must be same as company's default currency. Please select another account.") \ + .format(frappe.bold(account[0])) + frappe.throw(error_message) def validate_currency(self): if self.is_new(): From 8586c08639439da78dbeecaa5f1b588bf5fdf32e Mon Sep 17 00:00:00 2001 From: Suraj Shetty Date: Mon, 1 Feb 2021 20:09:42 +0530 Subject: [PATCH 444/477] chore: Update translation syntax checker --- .github/helper/translation.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/helper/translation.py b/.github/helper/translation.py index 340f4f8772d..9146b3b32b8 100644 --- a/.github/helper/translation.py +++ b/.github/helper/translation.py @@ -2,7 +2,7 @@ import re import sys errors_encounter = 0 -pattern = re.compile(r"_\(([\"']{,3})(?P((?!\1).)*)\1(\s*,\s*context\s*=\s*([\"'])(?P((?!\5).)*)\5)*(\s*,\s*(.)*?\s*(,\s*([\"'])(?P((?!\11).)*)\11)*)*\)") +pattern = re.compile(r"_\(([\"']{,3})(?P((?!\1).)*)\1(\s*,\s*context\s*=\s*([\"'])(?P((?!\5).)*)\5)*(\s*,(\s*?.*?\n*?)*(,\s*([\"'])(?P((?!\11).)*)\11)*)*\)") words_pattern = re.compile(r"_{1,2}\([\"'`]{1,3}.*?[a-zA-Z]") start_pattern = re.compile(r"_{1,2}\([f\"'`]{1,3}") f_string_pattern = re.compile(r"_\(f[\"']") @@ -28,7 +28,7 @@ for _file in files_to_scan: has_f_string = f_string_pattern.search(line) if has_f_string: errors_encounter += 1 - print(f'\nF-strings are not supported for translations at line number {line_number + 1}\n{line.strip()[:100]}') + print(f'\nF-strings are not supported for translations at line number {line_number}\n{line.strip()[:100]}') continue else: continue @@ -36,7 +36,7 @@ for _file in files_to_scan: match = pattern.search(line) error_found = False - if not match and line.endswith(',\n'): + if not match and line.endswith((',\n', '[\n')): # concat remaining text to validate multiline pattern line = "".join(file_lines[line_number - 1:]) line = line[start_matches.start() + 1:] @@ -44,11 +44,11 @@ for _file in files_to_scan: if not match: error_found = True - print(f'\nTranslation syntax error at line number {line_number + 1}\n{line.strip()[:100]}') + print(f'\nTranslation syntax error at line number {line_number}\n{line.strip()[:100]}') if not error_found and not words_pattern.search(line): error_found = True - print(f'\nTranslation is useless because it has no words at line number {line_number + 1}\n{line.strip()[:100]}') + print(f'\nTranslation is useless because it has no words at line number {line_number}\n{line.strip()[:100]}') if error_found: errors_encounter += 1 From 526ea46ae2c4aa284d1ef5b5829016fd54f9e70c Mon Sep 17 00:00:00 2001 From: prssanna Date: Mon, 1 Feb 2021 20:12:47 +0530 Subject: [PATCH 445/477] fix: formatting issues --- .../course_scheduling_tool.js | 7 +++-- .../page/point_of_sale/pos_controller.js | 2 +- .../page/point_of_sale/pos_item_cart.js | 31 ++++++++++--------- .../page/point_of_sale/pos_item_details.js | 4 +-- .../page/point_of_sale/pos_number_pad.js | 6 ++-- .../generators/item/item_configure.js | 2 ++ 6 files changed, 28 insertions(+), 24 deletions(-) diff --git a/erpnext/education/doctype/course_scheduling_tool/course_scheduling_tool.js b/erpnext/education/doctype/course_scheduling_tool/course_scheduling_tool.js index 8699103cb2c..907d79b3b83 100644 --- a/erpnext/education/doctype/course_scheduling_tool/course_scheduling_tool.js +++ b/erpnext/education/doctype/course_scheduling_tool/course_scheduling_tool.js @@ -19,8 +19,8 @@ frappe.ui.form.on('Course Scheduling Tool', { } const { course_schedules } = r.message; if (course_schedules) { - const html = ` -
    ${__('Following course schedules were created')}
    ${__("Course")}${__("Date")}
    ${c.name}
    ${c.name} ${c.schedule_date}
    + /* eslint-disable indent */ + const html = `
    @@ -29,7 +29,8 @@ frappe.ui.form.on('Course Scheduling Tool', { ` ).join('')} -
    ${__('Following course schedules were created')}
    ${__("Course")}${__("Date")}
    ${c.schedule_date}
    ` + `; + /* eslint-disable indent */ frappe.msgprint(html); } diff --git a/erpnext/selling/page/point_of_sale/pos_controller.js b/erpnext/selling/page/point_of_sale/pos_controller.js index bf70f0785fa..338a3ccf24c 100644 --- a/erpnext/selling/page/point_of_sale/pos_controller.js +++ b/erpnext/selling/page/point_of_sale/pos_controller.js @@ -182,7 +182,7 @@ erpnext.PointOfSale.Controller = class { if (this.frm.doc.items.length == 0) { frappe.show_alert({ - message:__("You must add atleast one item to save it as draft."), + message: __("You must add atleast one item to save it as draft."), indicator:'red' }); frappe.utils.play_sound("error"); diff --git a/erpnext/selling/page/point_of_sale/pos_item_cart.js b/erpnext/selling/page/point_of_sale/pos_item_cart.js index 00c409dcd3d..abd1f43a51a 100644 --- a/erpnext/selling/page/point_of_sale/pos_item_cart.js +++ b/erpnext/selling/page/point_of_sale/pos_item_cart.js @@ -155,11 +155,11 @@ erpnext.PointOfSale.ItemCart = class { bind_events() { const me = this; - this.$customer_section.on('click', '.reset-customer-btn', function (e) { + this.$customer_section.on('click', '.reset-customer-btn', function () { me.reset_customer_selector(); }); - this.$customer_section.on('click', '.close-details-btn', function (e) { + this.$customer_section.on('click', '.close-details-btn', function () { me.toggle_customer_info(false); }); @@ -365,7 +365,7 @@ erpnext.PointOfSale.ItemCart = class { } show_discount_control() { - this.$add_discount_elem.css({ 'padding': '0px', 'border': 'none' }) + this.$add_discount_elem.css({ 'padding': '0px', 'border': 'none' }); this.$add_discount_elem.html( `
    ` ); @@ -447,13 +447,13 @@ erpnext.PointOfSale.ItemCart = class { function get_customer_description() { if (!email_id && !mobile_no) { - return `
    Click to add email / phone
    ` + return `
    Click to add email / phone
    `; } else if (email_id && !mobile_no) { - return `
    ${email_id}
    ` + return `
    ${email_id}
    `; } else if (mobile_no && !email_id) { - return `
    ${mobile_no}
    ` + return `
    ${mobile_no}
    `; } else { - return `
    ${email_id} - ${mobile_no}
    ` + return `
    ${email_id} - ${mobile_no}
    `; } } @@ -462,9 +462,9 @@ erpnext.PointOfSale.ItemCart = class { get_customer_image() { const { customer, image } = this.customer_info || {}; if (image) { - return `
    ${image}
    ` + return `
    ${image}
    `; } else { - return `
    ${frappe.get_abbr(customer)}
    ` + return `
    ${frappe.get_abbr(customer)}
    `; } } @@ -501,7 +501,7 @@ erpnext.PointOfSale.ItemCart = class { this.$numpad_section.find('.numpad-grand-total').html( `
    Grand Total: ${format_currency(value, currency)}
    ` - ) + ); } render_taxes(value, taxes) { @@ -509,6 +509,7 @@ erpnext.PointOfSale.ItemCart = class { const currency = this.events.get_frm().doc.currency; this.$totals_section.find('.taxes-container').css('display', 'flex').html( `${ + // eslint-disable-next-line no-unused-vars taxes.map((t, i) => { const description = /[0-9]+/.test(t.description) ? t.description : `${t.description} @ ${t.rate}%`; return `
    @@ -519,7 +520,7 @@ erpnext.PointOfSale.ItemCart = class {
    ` }).join('') }` - ) + ); } else { this.$totals_section.find('.taxes-container').css('display', 'none').html(''); } @@ -633,7 +634,7 @@ erpnext.PointOfSale.ItemCart = class { } } item_data.description = frappe.ellipsis(item_data.description, 45); - return `
    ${item_data.description}
    ` + return `
    ${item_data.description}
    `; } return ``; } @@ -641,9 +642,9 @@ erpnext.PointOfSale.ItemCart = class { function get_item_image_html() { const { image, item_name } = item_data; if (image) { - return `
    ${image}
    ` + return `
    ${image}
    `; } else { - return `
    ${frappe.get_abbr(item_name)}
    ` + return `
    ${frappe.get_abbr(item_name)}
    `; } } } @@ -980,7 +981,7 @@ erpnext.PointOfSale.ItemCart = class { this.fetch_customer_details(frm.doc.customer).then(() => { this.events.customer_details_updated(this.customer_info); this.update_customer_section(); - }) + }); this.$cart_items_wrapper.html(''); if (frm.doc.items.length) { diff --git a/erpnext/selling/page/point_of_sale/pos_item_details.js b/erpnext/selling/page/point_of_sale/pos_item_details.js index f3aa1fc0c60..cb0a0103e00 100644 --- a/erpnext/selling/page/point_of_sale/pos_item_details.js +++ b/erpnext/selling/page/point_of_sale/pos_item_details.js @@ -183,11 +183,11 @@ erpnext.PointOfSale.ItemDetails = class { if (!item.has_batch_no) { this.$form_container.append( `
    ` - ) + ); } this.$form_container.append( `
    Auto Fetch Serial Numbers
    ` - ) + ); this.$form_container.find('.serial_no-control').find('textarea').css('height', '6rem'); } } diff --git a/erpnext/selling/page/point_of_sale/pos_number_pad.js b/erpnext/selling/page/point_of_sale/pos_number_pad.js index edde7d84dfb..962bcaf0963 100644 --- a/erpnext/selling/page/point_of_sale/pos_number_pad.js +++ b/erpnext/selling/page/point_of_sale/pos_number_pad.js @@ -22,11 +22,11 @@ erpnext.PointOfSale.NumberPad = class { return keys.reduce((a, row, i) => { return a + row.reduce((a2, number, j) => { const class_to_append = css_classes && css_classes[i] ? css_classes[i][j] : ''; - const fieldname = fieldnames && fieldnames[number] ? + const fieldname = fieldnames && fieldnames[number] ? fieldnames[number] : typeof number === 'string' ? frappe.scrub(number) : number; - return a2 + `
    ${number}
    ` - }, '') + return a2 + `
    ${number}
    `; + }, ''); }, ''); } diff --git a/erpnext/templates/generators/item/item_configure.js b/erpnext/templates/generators/item/item_configure.js index 276837ea61d..8eadb842899 100644 --- a/erpnext/templates/generators/item/item_configure.js +++ b/erpnext/templates/generators/item/item_configure.js @@ -209,6 +209,7 @@ class ItemConfigure { __('{0} item found.', [filtered_items_count]) : __('{0} items found.', [filtered_items_count]); + /* eslint-disable indent */ const item_found_status = exact_match.length === 1 ? ``; }).join('') }` ); @@ -844,7 +844,7 @@ erpnext.PointOfSale.ItemCart = class {
    Recent Transactions
    ` ); // transactions need to be in diff div from sticky elem for scrolling - this.$customer_section.append(`
    `) + this.$customer_section.append(`
    `); this.render_customer_fields(); this.fetch_customer_transactions(); From 73d60aa498c61abad86035d5d8864182a8e70dd2 Mon Sep 17 00:00:00 2001 From: prssanna Date: Mon, 1 Feb 2021 20:38:17 +0530 Subject: [PATCH 451/477] style: fix formatting --- .../page/point_of_sale/pos_item_cart.js | 24 +++++++------------ 1 file changed, 9 insertions(+), 15 deletions(-) diff --git a/erpnext/selling/page/point_of_sale/pos_item_cart.js b/erpnext/selling/page/point_of_sale/pos_item_cart.js index abd1f43a51a..52d345cbfce 100644 --- a/erpnext/selling/page/point_of_sale/pos_item_cart.js +++ b/erpnext/selling/page/point_of_sale/pos_item_cart.js @@ -507,20 +507,14 @@ erpnext.PointOfSale.ItemCart = class { render_taxes(value, taxes) { if (taxes.length) { const currency = this.events.get_frm().doc.currency; - this.$totals_section.find('.taxes-container').css('display', 'flex').html( - `${ - // eslint-disable-next-line no-unused-vars - taxes.map((t, i) => { - const description = /[0-9]+/.test(t.description) ? t.description : `${t.description} @ ${t.rate}%`; - return `
    -
    - ${description} -
    -
    ${format_currency(value, currency)}
    -
    ` - }).join('') - }` - ); + const taxes_html = taxes.map(t => { + const description = /[0-9]+/.test(t.description) ? t.description : `${t.description} @ ${t.rate}%`; + return `
    +
    ${description}
    +
    ${format_currency(value, currency)}
    +
    ` + }).join(''); + this.$totals_section.find('.taxes-container').css('display', 'flex').html(taxes_html); } else { this.$totals_section.find('.taxes-container').css('display', 'none').html(''); } @@ -844,7 +838,7 @@ erpnext.PointOfSale.ItemCart = class {
    Recent Transactions
    ` ); // transactions need to be in diff div from sticky elem for scrolling - this.$customer_section.append(`
    `) + this.$customer_section.append(`
    `); this.render_customer_fields(); this.fetch_customer_transactions(); From 0ea2587679b5922d539e61880e18741e01526d13 Mon Sep 17 00:00:00 2001 From: Marica Date: Mon, 1 Feb 2021 20:38:53 +0530 Subject: [PATCH 452/477] fix: Numeric/Non-numeric QI UX (#24516) * chore: Show 1 field each of both types of Insoections in grid view * fix: Make QI check Numeric by default and make checkbox "Numeric" - Reducing cognitive load --- .../item_quality_inspection_parameter.json | 16 ++++----- .../quality_inspection/quality_inspection.py | 4 +-- .../test_quality_inspection.py | 4 +-- .../quality_inspection_reading.json | 34 +++++++++---------- .../quality_inspection_template.py | 2 +- 5 files changed, 30 insertions(+), 30 deletions(-) diff --git a/erpnext/stock/doctype/item_quality_inspection_parameter/item_quality_inspection_parameter.json b/erpnext/stock/doctype/item_quality_inspection_parameter/item_quality_inspection_parameter.json index 3e81619cfd1..471e6853b51 100644 --- a/erpnext/stock/doctype/item_quality_inspection_parameter/item_quality_inspection_parameter.json +++ b/erpnext/stock/doctype/item_quality_inspection_parameter/item_quality_inspection_parameter.json @@ -8,7 +8,7 @@ "field_order": [ "specification", "value", - "non_numeric", + "numeric", "column_break_3", "min_value", "max_value", @@ -29,7 +29,7 @@ "width": "100px" }, { - "depends_on": "eval:(!doc.formula_based_criteria && doc.non_numeric)", + "depends_on": "eval:(!doc.formula_based_criteria && !doc.numeric)", "fieldname": "value", "fieldtype": "Data", "in_list_view": 1, @@ -55,32 +55,32 @@ "label": "Formula Based Criteria" }, { - "depends_on": "eval:(!doc.formula_based_criteria && !doc.non_numeric)", + "depends_on": "eval:(!doc.formula_based_criteria && doc.numeric)", "fieldname": "min_value", "fieldtype": "Float", "in_list_view": 1, "label": "Minimum Value" }, { - "depends_on": "eval:(!doc.formula_based_criteria && !doc.non_numeric)", + "depends_on": "eval:(!doc.formula_based_criteria && doc.numeric)", "fieldname": "max_value", "fieldtype": "Float", "in_list_view": 1, "label": "Maximum Value" }, { - "default": "0", - "fieldname": "non_numeric", + "default": "1", + "fieldname": "numeric", "fieldtype": "Check", "in_list_view": 1, - "label": "Non-Numeric", + "label": "Numeric", "width": "80px" } ], "idx": 1, "istable": 1, "links": [], - "modified": "2021-01-07 21:32:49.866439", + "modified": "2021-02-01 19:18:46.924399", "modified_by": "Administrator", "module": "Stock", "name": "Item Quality Inspection Parameter", diff --git a/erpnext/stock/doctype/quality_inspection/quality_inspection.py b/erpnext/stock/doctype/quality_inspection/quality_inspection.py index b3acbc5ba01..58b1eca2d33 100644 --- a/erpnext/stock/doctype/quality_inspection/quality_inspection.py +++ b/erpnext/stock/doctype/quality_inspection/quality_inspection.py @@ -97,7 +97,7 @@ class QualityInspection(Document): self.set_status_based_on_acceptance_values(reading) def set_status_based_on_acceptance_values(self, reading): - if cint(reading.non_numeric): + if not cint(reading.numeric): result = reading.get("reading_value") == reading.get("value") else: # numeric readings @@ -136,7 +136,7 @@ class QualityInspection(Document): def get_formula_evaluation_data(self, reading): data = {} - if cint(reading.non_numeric): + if not cint(reading.numeric): data = {"reading_value": reading.get("reading_value")} else: # numeric readings diff --git a/erpnext/stock/doctype/quality_inspection/test_quality_inspection.py b/erpnext/stock/doctype/quality_inspection/test_quality_inspection.py index 8c5a04b3f06..a7dfc9ee288 100644 --- a/erpnext/stock/doctype/quality_inspection/test_quality_inspection.py +++ b/erpnext/stock/doctype/quality_inspection/test_quality_inspection.py @@ -55,7 +55,7 @@ class TestQualityInspection(unittest.TestCase): }, { "specification": "Particle Inspection Needed", # non-numeric reading - "non_numeric": 1, + "numeric": 0, "value": "Yes", "reading_value": "Yes" }] @@ -96,7 +96,7 @@ class TestQualityInspection(unittest.TestCase): { "specification": "Calcium Content", # non-numeric reading "formula_based_criteria": 1, - "non_numeric": 1, + "numeric": 0, "acceptance_formula": "reading_value in ('Grade A', 'Grade B', 'Grade C')", "reading_value": "Grade B" }] diff --git a/erpnext/stock/doctype/quality_inspection_reading/quality_inspection_reading.json b/erpnext/stock/doctype/quality_inspection_reading/quality_inspection_reading.json index 30ff1fea3a4..35d58eff58b 100644 --- a/erpnext/stock/doctype/quality_inspection_reading/quality_inspection_reading.json +++ b/erpnext/stock/doctype/quality_inspection_reading/quality_inspection_reading.json @@ -9,7 +9,7 @@ "specification", "status", "value", - "non_numeric", + "numeric", "manual_inspection", "column_break_4", "min_value", @@ -46,7 +46,7 @@ }, { "columns": 2, - "depends_on": "eval:(!doc.formula_based_criteria && doc.non_numeric)", + "depends_on": "eval:(!doc.formula_based_criteria && !doc.numeric)", "fieldname": "value", "fieldtype": "Data", "label": "Acceptance Criteria Value", @@ -54,7 +54,7 @@ "oldfieldtype": "Data" }, { - "columns": 1, + "columns": 2, "fieldname": "reading_1", "fieldtype": "Data", "in_list_view": 1, @@ -66,7 +66,6 @@ "columns": 1, "fieldname": "reading_2", "fieldtype": "Data", - "in_list_view": 1, "label": "Reading 2", "oldfieldname": "reading_2", "oldfieldtype": "Data" @@ -140,7 +139,7 @@ "options": "\nAccepted\nRejected" }, { - "depends_on": "non_numeric", + "depends_on": "eval:!doc.numeric", "fieldname": "section_break_3", "fieldtype": "Section Break", "label": "Value Based Inspection" @@ -171,51 +170,52 @@ "label": "Formula Based Criteria" }, { - "depends_on": "eval:(!doc.formula_based_criteria && !doc.non_numeric)", + "depends_on": "eval:(!doc.formula_based_criteria && doc.numeric)", "description": "Applied on each reading.", "fieldname": "min_value", "fieldtype": "Float", "label": "Minimum Value" }, { - "depends_on": "eval:(!doc.formula_based_criteria && !doc.non_numeric)", + "depends_on": "eval:(!doc.formula_based_criteria && doc.numeric)", "description": "Applied on each reading.", "fieldname": "max_value", "fieldtype": "Float", "label": "Maximum Value" }, { - "depends_on": "non_numeric", + "columns": 2, + "depends_on": "eval:!doc.numeric", "fieldname": "reading_value", "fieldtype": "Data", "in_list_view": 1, "label": "Reading Value" }, { - "depends_on": "eval:!doc.non_numeric", + "depends_on": "numeric", "fieldname": "section_break_14", "fieldtype": "Section Break", "label": "Numeric Inspection" }, - { - "default": "0", - "fieldname": "non_numeric", - "fieldtype": "Check", - "in_list_view": 1, - "label": "Non-Numeric" - }, { "default": "0", "description": "Set the status manually.", "fieldname": "manual_inspection", "fieldtype": "Check", "label": "Manual Inspection" + }, + { + "default": "1", + "fieldname": "numeric", + "fieldtype": "Check", + "in_list_view": 1, + "label": "Numeric" } ], "idx": 1, "istable": 1, "links": [], - "modified": "2021-01-07 22:16:53.978410", + "modified": "2021-02-01 19:46:22.138018", "modified_by": "Administrator", "module": "Stock", "name": "Quality Inspection Reading", diff --git a/erpnext/stock/doctype/quality_inspection_template/quality_inspection_template.py b/erpnext/stock/doctype/quality_inspection_template/quality_inspection_template.py index c5a7974a732..01d2031b3a4 100644 --- a/erpnext/stock/doctype/quality_inspection_template/quality_inspection_template.py +++ b/erpnext/stock/doctype/quality_inspection_template/quality_inspection_template.py @@ -14,6 +14,6 @@ def get_template_details(template): return frappe.get_all('Item Quality Inspection Parameter', fields=["specification", "value", "acceptance_formula", - "non_numeric", "formula_based_criteria", "min_value", "max_value"], + "numeric", "formula_based_criteria", "min_value", "max_value"], filters={'parenttype': 'Quality Inspection Template', 'parent': template}, order_by="idx") \ No newline at end of file From 6f1664223d965407c7b6717d60628bc62f10473c Mon Sep 17 00:00:00 2001 From: prssanna Date: Mon, 1 Feb 2021 20:43:30 +0530 Subject: [PATCH 453/477] style: missing semicolon --- erpnext/selling/page/point_of_sale/pos_item_cart.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/selling/page/point_of_sale/pos_item_cart.js b/erpnext/selling/page/point_of_sale/pos_item_cart.js index 52d345cbfce..f753b6d5c5e 100644 --- a/erpnext/selling/page/point_of_sale/pos_item_cart.js +++ b/erpnext/selling/page/point_of_sale/pos_item_cart.js @@ -512,7 +512,7 @@ erpnext.PointOfSale.ItemCart = class { return `
    ${description}
    ${format_currency(value, currency)}
    -
    ` +
    `; }).join(''); this.$totals_section.find('.taxes-container').css('display', 'flex').html(taxes_html); } else { From 852e67c5eea95e9344404c7a38a08c915094cbfa Mon Sep 17 00:00:00 2001 From: Suraj Shetty Date: Mon, 1 Feb 2021 22:40:40 +0530 Subject: [PATCH 454/477] fix(patch): Use db_set to ignore validation --- erpnext/patches/v13_0/set_app_name.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/erpnext/patches/v13_0/set_app_name.py b/erpnext/patches/v13_0/set_app_name.py index 0c78b657704..3f886f1d159 100644 --- a/erpnext/patches/v13_0/set_app_name.py +++ b/erpnext/patches/v13_0/set_app_name.py @@ -2,7 +2,6 @@ import frappe from frappe import _ def execute(): - frappe.reload_doctype("System Settings") - settings = frappe.get_doc("System Settings") - settings.app_name = _("ERPNext") - settings.save() \ No newline at end of file + frappe.reload_doctype("System Settings") + settings = frappe.get_doc("System Settings") + settings.db_set("app_name", "ERPNext", commit=True) From d4d639c7edc1dc27625d38af8883b72145e1594b Mon Sep 17 00:00:00 2001 From: Rohit Waghchaure Date: Mon, 1 Feb 2021 22:58:22 +0530 Subject: [PATCH 455/477] fix: test cases for pricing rule --- .../doctype/pricing_rule/test_pricing_rule.py | 3 +++ erpnext/accounts/doctype/pricing_rule/utils.py | 11 +++++------ erpnext/controllers/taxes_and_totals.py | 4 ++-- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/erpnext/accounts/doctype/pricing_rule/test_pricing_rule.py b/erpnext/accounts/doctype/pricing_rule/test_pricing_rule.py index af8d21d9ce4..f28cee7c5af 100644 --- a/erpnext/accounts/doctype/pricing_rule/test_pricing_rule.py +++ b/erpnext/accounts/doctype/pricing_rule/test_pricing_rule.py @@ -56,6 +56,7 @@ class TestPricingRule(unittest.TestCase): self.assertEqual(details.get("discount_percentage"), 10) prule = frappe.get_doc(test_record.copy()) + prule.priority = 1 prule.applicable_for = "Customer" prule.title = "_Test Pricing Rule for Customer" self.assertRaises(MandatoryError, prule.insert) @@ -261,6 +262,7 @@ class TestPricingRule(unittest.TestCase): "rate_or_discount": "Discount Percentage", "rate": 0, "discount_percentage": 17.5, + "priority": 1, "company": "_Test Company" }).insert() @@ -557,6 +559,7 @@ def make_pricing_rule(**args): "rate": args.rate or 0.0, "margin_rate_or_amount": args.margin_rate_or_amount or 0.0, "condition": args.condition or '', + "priority": 1, "apply_multiple_pricing_rules": args.apply_multiple_pricing_rules or 0 }) diff --git a/erpnext/accounts/doctype/pricing_rule/utils.py b/erpnext/accounts/doctype/pricing_rule/utils.py index bd9d0b38159..d1633359963 100644 --- a/erpnext/accounts/doctype/pricing_rule/utils.py +++ b/erpnext/accounts/doctype/pricing_rule/utils.py @@ -59,18 +59,17 @@ def sorted_by_priority(pricing_rules, args, doc=None): pricing_rules_list = [] pricing_rule_dict = {} - priority = [] for pricing_rule in pricing_rules: pricing_rule = filter_pricing_rules(args, pricing_rule, doc) if pricing_rule: if not pricing_rule.get('priority'): - pricing_rules_list.append(pricing_rule) - else: - priority.append(cint(pricing_rule.get('priority'))) + pricing_rule['priority'] = 1 + + if pricing_rule.get('apply_multiple_pricing_rules'): pricing_rule_dict.setdefault(cint(pricing_rule.get("priority")), []).append(pricing_rule) - if priority: - pricing_rules_list.extend(pricing_rule_dict.get(min(priority))) + for key in sorted(pricing_rule_dict): + pricing_rules_list.extend(pricing_rule_dict.get(key)) return pricing_rules_list or pricing_rules diff --git a/erpnext/controllers/taxes_and_totals.py b/erpnext/controllers/taxes_and_totals.py index 9f087e86a45..6c7eb922210 100644 --- a/erpnext/controllers/taxes_and_totals.py +++ b/erpnext/controllers/taxes_and_totals.py @@ -624,8 +624,8 @@ class calculate_taxes_and_totals(object): for d in get_applied_pricing_rules(item.pricing_rules): pricing_rule = frappe.get_cached_doc('Pricing Rule', d) - if (pricing_rule.margin_rate_or_amount and pricing_rule.currency == self.doc.currency and - pricing_rule.margin_type in ['Amount', 'Percentage']): + if pricing_rule.margin_rate_or_amount and ((pricing_rule.currency == self.doc.currency and + pricing_rule.margin_type in ['Amount', 'Percentage']) or pricing_rule.margin_type == 'Percentage'): item.margin_type = pricing_rule.margin_type item.margin_rate_or_amount = pricing_rule.margin_rate_or_amount has_margin = True From 91a02868cb70faa0887445886cfdfa4485e0f127 Mon Sep 17 00:00:00 2001 From: Afshan <33727827+AfshanKhan@users.noreply.github.com> Date: Tue, 2 Feb 2021 11:04:25 +0530 Subject: [PATCH 456/477] fix: emp disappear (#24525) * fix: emp disappear * fix: renamed set_totals_call to set_totals Co-authored-by: Nabin Hait --- .../payroll/doctype/payroll_entry/payroll_entry.js | 1 - erpnext/payroll/doctype/salary_slip/salary_slip.js | 14 +++++++------- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/erpnext/payroll/doctype/payroll_entry/payroll_entry.js b/erpnext/payroll/doctype/payroll_entry/payroll_entry.js index 45f9aa170fc..395e56fa92e 100644 --- a/erpnext/payroll/doctype/payroll_entry/payroll_entry.js +++ b/erpnext/payroll/doctype/payroll_entry/payroll_entry.js @@ -348,7 +348,6 @@ let render_employee_attendance = function (frm, data) { frappe.ui.form.on('Payroll Employee Detail', { employee: function(frm) { - frm.events.clear_employee_table(frm); if (!frm.doc.payroll_frequency) { frappe.throw(__("Please set a Payroll Frequency")); } diff --git a/erpnext/payroll/doctype/salary_slip/salary_slip.js b/erpnext/payroll/doctype/salary_slip/salary_slip.js index b50c774fbe4..7460c752278 100644 --- a/erpnext/payroll/doctype/salary_slip/salary_slip.js +++ b/erpnext/payroll/doctype/salary_slip/salary_slip.js @@ -116,7 +116,7 @@ frappe.ui.form.on("Salary Slip", { }, exchange_rate: function(frm) { - calculate_totals(frm); + set_totals(frm); }, hide_loan_section: function(frm) { @@ -205,14 +205,14 @@ frappe.ui.form.on("Salary Slip", { frappe.ui.form.on('Salary Slip Timesheet', { time_sheet: function(frm) { - calculate_totals(frm); + set_totals(frm); }, timesheets_remove: function(frm) { - calculate_totals(frm); + set_totals(frm); } }); -var calculate_totals = function(frm) { +var set_totals = function(frm) { if (frm.doc.docstatus === 0) { if (frm.doc.earnings || frm.doc.deductions) { frappe.call({ @@ -228,15 +228,15 @@ var calculate_totals = function(frm) { frappe.ui.form.on('Salary Detail', { amount: function(frm) { - calculate_totals(frm); + set_totals(frm); }, earnings_remove: function(frm) { - calculate_totals(frm); + set_totals(frm); }, deductions_remove: function(frm) { - calculate_totals(frm); + set_totals(frm); }, salary_component: function(frm, cdt, cdn) { From 7d64a291b8f99ed0d1cc5da175b53b0df578ccf1 Mon Sep 17 00:00:00 2001 From: Anupam Kumar Date: Tue, 2 Feb 2021 12:43:13 +0530 Subject: [PATCH 457/477] fix: contact permmission issue (#24503) --- erpnext/crm/doctype/lead/lead.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/crm/doctype/lead/lead.py b/erpnext/crm/doctype/lead/lead.py index 1439adb015b..938cbfdc852 100644 --- a/erpnext/crm/doctype/lead/lead.py +++ b/erpnext/crm/doctype/lead/lead.py @@ -176,7 +176,7 @@ class Lead(SellingController): "phone": self.mobile_no }) - contact.insert() + contact.insert(ignore_permissions=True) return contact From 71775790518bad69cb31ae0a4edf4ec482692068 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Tue, 2 Feb 2021 22:03:07 +0530 Subject: [PATCH 458/477] fix: Dependant sle logic fixes (#24489) * fix: Dependant sle logic fixes * fix: negative qty validation * fix: Travis fixes --- .../doctype/work_order/test_work_order.py | 4 +- .../united_states/test_united_states.py | 1 - .../setup/doctype/item_group/item_group.py | 2 - erpnext/shopping_cart/filters.py | 2 - erpnext/stock/doctype/bin/bin.py | 6 +-- .../repost_item_valuation.js | 2 +- erpnext/stock/stock_ledger.py | 48 +++++++------------ .../report/issue_analytics/issue_analytics.py | 3 +- .../issue_analytics/test_issue_analytics.py | 9 ++-- erpnext/www/all-products/index.py | 3 -- 10 files changed, 29 insertions(+), 51 deletions(-) diff --git a/erpnext/manufacturing/doctype/work_order/test_work_order.py b/erpnext/manufacturing/doctype/work_order/test_work_order.py index e562d6c4bdd..06a8e1987d3 100644 --- a/erpnext/manufacturing/doctype/work_order/test_work_order.py +++ b/erpnext/manufacturing/doctype/work_order/test_work_order.py @@ -544,7 +544,7 @@ class TestWorkOrder(unittest.TestCase): expected_qty = {"_Test Item": 2, "_Test Item Home Desktop 100": 4} for row in ste3.items: self.assertEquals(row.qty, expected_qty.get(row.item_code)) - + ste_cancel_list.reverse() for ste_doc in ste_cancel_list: ste_doc.cancel() @@ -586,7 +586,7 @@ class TestWorkOrder(unittest.TestCase): for ste_row in ste2.items: if itemwise_qty.get(ste_row.item_code) and ste_row.s_warehouse: self.assertEquals(ste_row.qty, itemwise_qty.get(ste_row.item_code) / 2) - + ste_cancel_list.reverse() for ste_doc in ste_cancel_list: ste_doc.cancel() diff --git a/erpnext/regional/united_states/test_united_states.py b/erpnext/regional/united_states/test_united_states.py index ad95010a9ac..513570ed6df 100644 --- a/erpnext/regional/united_states/test_united_states.py +++ b/erpnext/regional/united_states/test_united_states.py @@ -26,7 +26,6 @@ class TestUnitedStates(unittest.TestCase): make_payment_entry_to_irs_1099_supplier() filters = frappe._dict({"fiscal_year": "_Test Fiscal Year 2016", "company": "_Test Company 1"}) columns, data = execute_1099_report(filters) - print(columns, data) expected_row = {'supplier': '_US 1099 Test Supplier', 'supplier_group': 'Services', 'payments': 100.0, diff --git a/erpnext/setup/doctype/item_group/item_group.py b/erpnext/setup/doctype/item_group/item_group.py index e4cbf41f83a..bff806d5472 100644 --- a/erpnext/setup/doctype/item_group/item_group.py +++ b/erpnext/setup/doctype/item_group/item_group.py @@ -98,8 +98,6 @@ class ItemGroup(NestedSet, WebsiteGenerator): context.field_filters = filter_engine.get_field_filters() context.attribute_filters = filter_engine.get_attribute_fitlers() - print(context.field_filters, context.attribute_filters) - context.update({ "parents": get_parent_item_groups(self.parent_item_group), "title": self.name diff --git a/erpnext/shopping_cart/filters.py b/erpnext/shopping_cart/filters.py index e60364d92b9..6c63d8759b4 100644 --- a/erpnext/shopping_cart/filters.py +++ b/erpnext/shopping_cart/filters.py @@ -16,7 +16,6 @@ class ProductFiltersBuilder: def get_field_filters(self): filter_fields = [row.fieldname for row in self.doc.filter_fields] - print('FILTERS', self.doc.filter_fields) meta = frappe.get_meta('Item') fields = [df for df in meta.fields if df.fieldname in filter_fields] @@ -53,7 +52,6 @@ class ProductFiltersBuilder: def get_attribute_fitlers(self): attributes = [row.attribute for row in self.doc.filter_attributes] - print('ATTRIBUTES', attributes) attribute_docs = [ frappe.get_doc('Item Attribute', attribute) for attribute in attributes ] diff --git a/erpnext/stock/doctype/bin/bin.py b/erpnext/stock/doctype/bin/bin.py index ab19b77ad8e..1088b4127d3 100644 --- a/erpnext/stock/doctype/bin/bin.py +++ b/erpnext/stock/doctype/bin/bin.py @@ -17,7 +17,7 @@ class Bin(Document): '''Called from erpnext.stock.utils.update_bin''' self.update_qty(args) if args.get("actual_qty") or args.get("voucher_type") == "Stock Reconciliation": - from erpnext.stock.stock_ledger import update_entries_after, update_qty_in_future_sle + from erpnext.stock.stock_ledger import update_entries_after, validate_negative_qty_in_future_sle if not args.get("posting_date"): args["posting_date"] = nowdate() @@ -37,8 +37,8 @@ class Bin(Document): "sle_id": args.name }, allow_negative_stock=allow_negative_stock, via_landed_cost_voucher=via_landed_cost_voucher) - # Update qty_after_transaction in future SLEs of this item and warehouse - update_qty_in_future_sle(args) + # Validate negative qty in future transactions + validate_negative_qty_in_future_sle(args) def update_qty(self, args): # update the stock values (for current quantities) diff --git a/erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.js b/erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.js index e429cd5e304..b3e4286bccb 100644 --- a/erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.js +++ b/erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.js @@ -31,7 +31,7 @@ frappe.ui.form.on('Repost Item Valuation', { } }, refresh: function(frm) { - if (frm.doc.status == "Failed") { + if (frm.doc.status == "Failed" && frm.doc.docstatus==1) { frm.add_custom_button(__('Restart'), function () { frm.trigger("restart_reposting"); }).addClass("btn-primary"); diff --git a/erpnext/stock/stock_ledger.py b/erpnext/stock/stock_ledger.py index 2b2a7a202dd..46919c8c8c3 100644 --- a/erpnext/stock/stock_ledger.py +++ b/erpnext/stock/stock_ledger.py @@ -62,7 +62,7 @@ def make_entry(args, allow_negative_stock=False, via_landed_cost_voucher=False): sle.submit() return sle -def repost_future_sle(args=None, voucher_type=None, voucher_no=None, allow_negative_stock=False, via_landed_cost_voucher=False): +def repost_future_sle(args=None, voucher_type=None, voucher_no=None, allow_negative_stock=None, via_landed_cost_voucher=False): if not args and voucher_type and voucher_no: args = get_args_for_voucher(voucher_type, voucher_no) @@ -181,7 +181,7 @@ class update_entries_after(object): self.process_sle(sle) if sle.dependant_sle_voucher_detail_no: - self.get_dependent_entries_to_fix(entries_to_fix, sle) + entries_to_fix = self.get_dependent_entries_to_fix(entries_to_fix, sle) if self.exceptions: self.raise_exceptions() @@ -221,13 +221,15 @@ class update_entries_after(object): excluded_sle=sle.name) if not dependant_sle: - return + return entries_to_fix elif dependant_sle.item_code == self.item_code and dependant_sle.warehouse == self.args.warehouse: - return - elif dependant_sle.item_code != self.item_code \ - and (dependant_sle.item_code, dependant_sle.warehouse) not in self.new_items: - self.new_items[(dependant_sle.item_code, dependant_sle.warehouse)] = dependant_sle - return + return entries_to_fix + elif dependant_sle.item_code != self.item_code: + if (dependant_sle.item_code, dependant_sle.warehouse) not in self.new_items: + self.new_items[(dependant_sle.item_code, dependant_sle.warehouse)] = dependant_sle + return entries_to_fix + elif dependant_sle.item_code == self.item_code and dependant_sle.warehouse in self.data: + return entries_to_fix self.initialize_previous_data(dependant_sle) @@ -236,7 +238,7 @@ class update_entries_after(object): future_sle_for_dependant = list(self.get_sle_after_datetime(args)) entries_to_fix.extend(future_sle_for_dependant) - entries_to_fix = sorted(entries_to_fix, key=lambda k: k['timestamp']) + return sorted(entries_to_fix, key=lambda k: k['timestamp']) def process_sle(self, sle): # previous sle data for this warehouse @@ -612,11 +614,11 @@ class update_entries_after(object): frappe.local.flags.currently_saving): msg = _("{0} units of {1} needed in {2} to complete this transaction.").format( - abs(deficiency), frappe.get_desk_link('Item', self.item_code), + abs(deficiency), frappe.get_desk_link('Item', exceptions[0]["item_code"]), frappe.get_desk_link('Warehouse', warehouse)) else: msg = _("{0} units of {1} needed in {2} on {3} {4} for {5} to complete this transaction.").format( - abs(deficiency), frappe.get_desk_link('Item', self.item_code), + abs(deficiency), frappe.get_desk_link('Item', exceptions[0]["item_code"]), frappe.get_desk_link('Warehouse', warehouse), exceptions[0]["posting_date"], exceptions[0]["posting_time"], frappe.get_desk_link(exceptions[0]["voucher_type"], exceptions[0]["voucher_no"])) @@ -761,25 +763,6 @@ def get_valuation_rate(item_code, warehouse, voucher_type, voucher_no, return valuation_rate -def update_qty_in_future_sle(args, allow_negative_stock=None): - frappe.db.sql(""" - update `tabStock Ledger Entry` - set qty_after_transaction = qty_after_transaction + {qty} - where - item_code = %(item_code)s - and warehouse = %(warehouse)s - and voucher_no != %(voucher_no)s - and is_cancelled = 0 - and (timestamp(posting_date, posting_time) > timestamp(%(posting_date)s, %(posting_time)s) - or ( - timestamp(posting_date, posting_time) = timestamp(%(posting_date)s, %(posting_time)s) - and creation > %(creation)s - ) - ) - """.format(qty=args.actual_qty), args) - - validate_negative_qty_in_future_sle(args, allow_negative_stock) - def validate_negative_qty_in_future_sle(args, allow_negative_stock=None): allow_negative_stock = allow_negative_stock \ or cint(frappe.db.get_single_value("Stock Settings", "allow_negative_stock")) @@ -808,6 +791,7 @@ def get_future_sle_with_negative_qty(args): and voucher_no != %(voucher_no)s and timestamp(posting_date, posting_time) >= timestamp(%(posting_date)s, %(posting_time)s) and is_cancelled = 0 - and qty_after_transaction < 0 + and qty_after_transaction + {0} < 0 + order by timestamp(posting_date, posting_time) asc limit 1 - """, args, as_dict=1) \ No newline at end of file + """.format(args.actual_qty), args, as_dict=1) \ No newline at end of file diff --git a/erpnext/support/report/issue_analytics/issue_analytics.py b/erpnext/support/report/issue_analytics/issue_analytics.py index 0b629151a6b..3fdb10ddf38 100644 --- a/erpnext/support/report/issue_analytics/issue_analytics.py +++ b/erpnext/support/report/issue_analytics/issue_analytics.py @@ -147,8 +147,7 @@ class IssueAnalytics(object): self.entries = frappe.db.get_all('Issue', fields=[self.field_map.get(self.filters.based_on), 'name', 'opening_date'], - filters=filters, - debug=1 + filters=filters ) def get_common_filters(self): diff --git a/erpnext/support/report/issue_analytics/test_issue_analytics.py b/erpnext/support/report/issue_analytics/test_issue_analytics.py index 432906db9b9..77483198ecc 100644 --- a/erpnext/support/report/issue_analytics/test_issue_analytics.py +++ b/erpnext/support/report/issue_analytics/test_issue_analytics.py @@ -17,9 +17,12 @@ class TestIssueAnalytics(unittest.TestCase): current_month_date = getdate() last_month_date = add_months(current_month_date, -1) - self.current_month = str(months[current_month_date.month - 1]).lower() + '_' + str(current_month_date.year) - self.last_month = str(months[last_month_date.month - 1]).lower() + '_' + str(last_month_date.year) - + self.current_month = str(months[current_month_date.month - 1]).lower() + self.last_month = str(months[last_month_date.month - 1]).lower() + if current_month_date.year != last_month_date.year: + self.current_month += '_' + str(current_month_date.year) + self.last_month += '_' + str(last_month_date.year) + def test_issue_analytics(self): create_service_level_agreements_for_issues() create_issue_types() diff --git a/erpnext/www/all-products/index.py b/erpnext/www/all-products/index.py index 0622270e05f..fd6400f48cf 100644 --- a/erpnext/www/all-products/index.py +++ b/erpnext/www/all-products/index.py @@ -12,7 +12,6 @@ def get_context(context): search = frappe.form_dict.search field_filters = frappe.parse_json(frappe.form_dict.field_filters) attribute_filters = frappe.parse_json(frappe.form_dict.attribute_filters) - print(field_filters, attribute_filters) start = frappe.parse_json(frappe.form_dict.start) else: search = field_filters = attribute_filters = None @@ -30,8 +29,6 @@ def get_context(context): context.field_filters = filter_engine.get_field_filters() context.attribute_filters = filter_engine.get_attribute_fitlers() - print(context.field_filters, context.attribute_filters) - context.product_settings = product_settings context.body_class = "product-page" context.page_length = product_settings.products_per_page or 20 From dce73d1881ec8f79bf3ac0376f8935a0e7122107 Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Wed, 3 Feb 2021 12:06:36 +0530 Subject: [PATCH 459/477] fix: Add accounts user role permission for accounting dimension filter --- .../accounting_dimension_filter.json | 26 ++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/erpnext/accounts/doctype/accounting_dimension_filter/accounting_dimension_filter.json b/erpnext/accounts/doctype/accounting_dimension_filter/accounting_dimension_filter.json index c0327ad0ad8..0f3fbc0b8d3 100644 --- a/erpnext/accounts/doctype/accounting_dimension_filter/accounting_dimension_filter.json +++ b/erpnext/accounts/doctype/accounting_dimension_filter/accounting_dimension_filter.json @@ -108,7 +108,7 @@ ], "index_web_pages_for_search": 1, "links": [], - "modified": "2020-12-16 15:27:23.659285", + "modified": "2021-02-03 12:04:58.678402", "modified_by": "Administrator", "module": "Accounts", "name": "Accounting Dimension Filter", @@ -125,6 +125,30 @@ "role": "System Manager", "share": 1, "write": 1 + }, + { + "create": 1, + "delete": 1, + "email": 1, + "export": 1, + "print": 1, + "read": 1, + "report": 1, + "role": "Accounts User", + "share": 1, + "write": 1 + }, + { + "create": 1, + "delete": 1, + "email": 1, + "export": 1, + "print": 1, + "read": 1, + "report": 1, + "role": "Accounts Manager", + "share": 1, + "write": 1 } ], "quick_entry": 1, From b814b002cecb1fd8f257d16c36f022ecb1cae091 Mon Sep 17 00:00:00 2001 From: Afshan <33727827+AfshanKhan@users.noreply.github.com> Date: Fri, 5 Feb 2021 11:34:55 +0530 Subject: [PATCH 460/477] fix: creating salary slip from timesheet (#24541) --- erpnext/projects/doctype/timesheet/timesheet.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/projects/doctype/timesheet/timesheet.py b/erpnext/projects/doctype/timesheet/timesheet.py index 9e807f728ec..ea81b3eb644 100644 --- a/erpnext/projects/doctype/timesheet/timesheet.py +++ b/erpnext/projects/doctype/timesheet/timesheet.py @@ -288,7 +288,7 @@ def make_sales_invoice(source_name, item_code=None, customer=None): def make_salary_slip(source_name, target_doc=None): target = frappe.new_doc("Salary Slip") set_missing_values(source_name, target) - target.run_method("get_emp_and_leave_details") + target.run_method("get_emp_and_working_day_details") return target From a7820f310ca4efd59a7d585c6fa7567797579ecb Mon Sep 17 00:00:00 2001 From: prssanna Date: Fri, 5 Feb 2021 14:52:31 +0530 Subject: [PATCH 461/477] fix: check if product_info exists --- erpnext/shopping_cart/product_query.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/erpnext/shopping_cart/product_query.py b/erpnext/shopping_cart/product_query.py index da9e798327d..8daf3d7dac9 100644 --- a/erpnext/shopping_cart/product_query.py +++ b/erpnext/shopping_cart/product_query.py @@ -73,7 +73,8 @@ class ProductQuery: for item in result: product_info = get_product_info_for_website(item.item_code, skip_quotation_creation=True).get('product_info') - item.formatted_price = product_info['price'].get('formatted_price') if product_info['price'] else None + if product_info: + item.formatted_price = product_info['price'].get('formatted_price') if product_info['price'] else None return result From 91b41db9e374dc295bb1ae83f653d23ccadea5d4 Mon Sep 17 00:00:00 2001 From: prssanna Date: Fri, 5 Feb 2021 17:34:56 +0530 Subject: [PATCH 462/477] fix: check if product_info exists before setting price --- erpnext/portal/product_configurator/utils.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/erpnext/portal/product_configurator/utils.py b/erpnext/portal/product_configurator/utils.py index 4693d44509a..21fd7c28789 100644 --- a/erpnext/portal/product_configurator/utils.py +++ b/erpnext/portal/product_configurator/utils.py @@ -386,7 +386,8 @@ def get_items(filters=None, search=None): r.description = r.web_long_description or r.description r.image = r.website_image or r.image product_info = get_product_info_for_website(r.item_code, skip_quotation_creation=True).get('product_info') - r.formatted_price = product_info['price'].get('formatted_price') if product_info['price'] else None + if product_info: + r.formatted_price = product_info['price'].get('formatted_price') if product_info['price'] else None return results From c4a1bb0e1c1eddc747fe050ee05e625f8d0d7e8a Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Fri, 5 Feb 2021 10:04:18 -0800 Subject: [PATCH 463/477] fix: couple of travis fixes (#24554) Co-authored-by: Suraj Shetty <13928957+surajshetty3416@users.noreply.github.com> --- .../doctype/inpatient_record/test_inpatient_record.py | 1 + erpnext/hr/doctype/employee/test_employee.py | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/erpnext/healthcare/doctype/inpatient_record/test_inpatient_record.py b/erpnext/healthcare/doctype/inpatient_record/test_inpatient_record.py index 8a918b02751..ea0d1e982d9 100644 --- a/erpnext/healthcare/doctype/inpatient_record/test_inpatient_record.py +++ b/erpnext/healthcare/doctype/inpatient_record/test_inpatient_record.py @@ -139,6 +139,7 @@ def create_inpatient(patient): inpatient_record.phone = patient_obj.phone inpatient_record.inpatient = "Scheduled" inpatient_record.scheduled_date = today() + inpatient_record.company = "_Test Company" return inpatient_record diff --git a/erpnext/hr/doctype/employee/test_employee.py b/erpnext/hr/doctype/employee/test_employee.py index f4b214adc3c..c0e614ac088 100644 --- a/erpnext/hr/doctype/employee/test_employee.py +++ b/erpnext/hr/doctype/employee/test_employee.py @@ -16,11 +16,13 @@ class TestEmployee(unittest.TestCase): employee = frappe.get_doc("Employee", frappe.db.sql_list("select name from tabEmployee limit 1")[0]) employee.date_of_birth = "1992" + frappe.utils.nowdate()[4:] employee.company_email = "test@example.com" + employee.company = "_Test Company" employee.save() from erpnext.hr.doctype.employee.employee import get_employees_who_are_born_today, send_birthday_reminders - self.assertTrue(employee.name in [e.name for e in get_employees_who_are_born_today()]) + employees_born_today = get_employees_who_are_born_today() + self.assertTrue(employees_born_today.get("_Test Company")) frappe.db.sql("delete from `tabEmail Queue`") From ffb36aac8f604e88caa6c77951dea6fe33f30676 Mon Sep 17 00:00:00 2001 From: Anuja Pawar <60467153+Anuja-pawar@users.noreply.github.com> Date: Fri, 5 Feb 2021 23:35:47 +0530 Subject: [PATCH 464/477] fix: fixing item_code not found error in the report (#24483) --- .../item_wise_sales_register/item_wise_sales_register.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py b/erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py index 998003ac698..928b373effe 100644 --- a/erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py +++ b/erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py @@ -52,8 +52,8 @@ def _execute(filters=None, additional_table_columns=None, additional_query_colum row = { 'item_code': d.item_code, - 'item_name': item_record.item_name, - 'item_group': item_record.item_group, + 'item_name': item_record.item_name if item_record else d.item_name, + 'item_group': item_record.item_group if item_record else d.item_group, 'description': d.description, 'invoice': d.parent, 'posting_date': d.posting_date, @@ -383,6 +383,7 @@ def get_items(filters, additional_query_columns): `tabSales Invoice`.project, `tabSales Invoice`.customer, `tabSales Invoice`.remarks, `tabSales Invoice`.territory, `tabSales Invoice`.company, `tabSales Invoice`.base_net_total, `tabSales Invoice Item`.item_code, `tabSales Invoice Item`.description, + `tabSales Invoice Item`.`item_name`, `tabSales Invoice Item`.`item_group`, `tabSales Invoice Item`.sales_order, `tabSales Invoice Item`.delivery_note, `tabSales Invoice Item`.income_account, `tabSales Invoice Item`.cost_center, `tabSales Invoice Item`.stock_qty, `tabSales Invoice Item`.stock_uom, From f29b811a565ea619f12895ef41f187dfc81a6dbc Mon Sep 17 00:00:00 2001 From: Saqib Date: Sat, 6 Feb 2021 17:55:20 +0530 Subject: [PATCH 465/477] fix(e-invoice): do not validate gstin for exports (#24561) --- erpnext/regional/india/e_invoice/utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/regional/india/e_invoice/utils.py b/erpnext/regional/india/e_invoice/utils.py index c8e7e149c43..7d9b2fd624a 100644 --- a/erpnext/regional/india/e_invoice/utils.py +++ b/erpnext/regional/india/e_invoice/utils.py @@ -303,7 +303,7 @@ def validate_mandatory_fields(invoice): _('GSTIN is mandatory to fetch company GSTIN details. Please enter GSTIN in selected company address.'), title=_('Missing Fields') ) - if not frappe.db.get_value('Address', invoice.customer_address, 'gstin'): + if invoice.gst_category != 'Overseas' and not frappe.db.get_value('Address', invoice.customer_address, 'gstin'): frappe.throw( _('GSTIN is mandatory to fetch customer GSTIN details. Please enter GSTIN in selected customer address.'), title=_('Missing Fields') From a97eb6a052b605ef06137e128eed66052bdf4965 Mon Sep 17 00:00:00 2001 From: marination Date: Sun, 7 Feb 2021 22:27:40 +0530 Subject: [PATCH 466/477] fix: Empty State text font weight in Item Dashboard --- erpnext/stock/dashboard/item_dashboard.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/stock/dashboard/item_dashboard.js b/erpnext/stock/dashboard/item_dashboard.js index 9dbb64c343e..95cb92b1b36 100644 --- a/erpnext/stock/dashboard/item_dashboard.js +++ b/erpnext/stock/dashboard/item_dashboard.js @@ -132,7 +132,7 @@ erpnext.stock.ItemDashboard = Class.extend({ var message = __("No Stock Available Currently"); this.content.find('.result').css('text-align', 'center'); - $(`
    + $(`
    ${message}
    `).appendTo(this.result); } }, From 9490122abb40ffff8d987c4bdb85d7aa38e92c1e Mon Sep 17 00:00:00 2001 From: Saqib Date: Mon, 8 Feb 2021 11:40:56 +0530 Subject: [PATCH 467/477] fix(e-invoice): skip e-invoice generation for non-taxable invoices (#24568) --- erpnext/regional/india/e_invoice/utils.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/erpnext/regional/india/e_invoice/utils.py b/erpnext/regional/india/e_invoice/utils.py index 7d9b2fd624a..5b898d52a1b 100644 --- a/erpnext/regional/india/e_invoice/utils.py +++ b/erpnext/regional/india/e_invoice/utils.py @@ -20,11 +20,13 @@ from frappe.utils.data import cstr, cint, format_date, flt, time_diff_in_seconds def validate_einvoice_fields(doc): einvoicing_enabled = cint(frappe.db.get_value('E Invoice Settings', 'E Invoice Settings', 'enable')) - invalid_doctype = doc.doctype not in ['Sales Invoice'] + invalid_doctype = doc.doctype != 'Sales Invoice' invalid_supply_type = doc.get('gst_category') not in ['Registered Regular', 'SEZ', 'Overseas', 'Deemed Export'] company_transaction = doc.get('billing_address_gstin') == doc.get('company_gstin') + no_taxes_applied = len(doc.get('taxes')) == 0 - if not einvoicing_enabled or invalid_doctype or invalid_supply_type or company_transaction: return + if not einvoicing_enabled or invalid_doctype or invalid_supply_type or company_transaction or no_taxes_applied: + return if doc.docstatus == 0 and doc._action == 'save': if doc.irn: From 53dbe39d12c955df7cfd8d967fa0c077a8c49042 Mon Sep 17 00:00:00 2001 From: Afshan <33727827+AfshanKhan@users.noreply.github.com> Date: Mon, 8 Feb 2021 12:32:42 +0530 Subject: [PATCH 468/477] fix: StopIteration error when e-invoice not enabled (#24548) * fix: StopIteration error when e-invoice not enabled * chore: update message Co-authored-by: Saqib --- erpnext/regional/india/e_invoice/utils.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/erpnext/regional/india/e_invoice/utils.py b/erpnext/regional/india/e_invoice/utils.py index 5b898d52a1b..e64be4b6450 100644 --- a/erpnext/regional/india/e_invoice/utils.py +++ b/erpnext/regional/india/e_invoice/utils.py @@ -446,6 +446,8 @@ class GSPConnector(): def get_credentials(self): if self.invoice: gstin = self.get_seller_gstin() + if not self.e_invoice_settings.enable: + frappe.throw(_("E-Invoicing is disabled. Please enable it from {} to generate e-invoices.").format(get_link_to_form("E Invoice Settings", "E Invoice Settings"))) credentials = next(d for d in self.e_invoice_settings.credentials if d.gstin == gstin) else: credentials = self.e_invoice_settings.credentials[0] if self.e_invoice_settings.credentials else None @@ -819,4 +821,4 @@ def generate_eway_bill(doctype, docname, **kwargs): @frappe.whitelist() def cancel_eway_bill(doctype, docname, eway_bill, reason, remark): gsp_connector = GSPConnector(doctype, docname) - gsp_connector.cancel_eway_bill(eway_bill, reason, remark) \ No newline at end of file + gsp_connector.cancel_eway_bill(eway_bill, reason, remark) From 5a7ddba9a319f666a348816beea843a8a99bd3a0 Mon Sep 17 00:00:00 2001 From: marination Date: Mon, 8 Feb 2021 17:06:23 +0530 Subject: [PATCH 469/477] fix: Avoid changing Ref. Doctype in Accounting Dimension after creation --- .../accounting_dimension/accounting_dimension.json | 3 ++- .../accounting_dimension/accounting_dimension.py | 10 ++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/erpnext/accounts/doctype/accounting_dimension/accounting_dimension.json b/erpnext/accounts/doctype/accounting_dimension/accounting_dimension.json index cf55d554fb3..5858f10bb0b 100644 --- a/erpnext/accounts/doctype/accounting_dimension/accounting_dimension.json +++ b/erpnext/accounts/doctype/accounting_dimension/accounting_dimension.json @@ -30,6 +30,7 @@ "fieldtype": "Link", "label": "Reference Document Type", "options": "DocType", + "read_only_depends_on": "eval:!doc.__islocal", "reqd": 1 }, { @@ -48,7 +49,7 @@ } ], "links": [], - "modified": "2020-03-22 20:34:39.805728", + "modified": "2021-02-08 16:37:53.936656", "modified_by": "Administrator", "module": "Accounts", "name": "Accounting Dimension", diff --git a/erpnext/accounts/doctype/accounting_dimension/accounting_dimension.py b/erpnext/accounts/doctype/accounting_dimension/accounting_dimension.py index ef0d3a3cb1f..dd26c4cec24 100644 --- a/erpnext/accounts/doctype/accounting_dimension/accounting_dimension.py +++ b/erpnext/accounts/doctype/accounting_dimension/accounting_dimension.py @@ -29,6 +29,16 @@ class AccountingDimension(Document): if exists and self.is_new(): frappe.throw("Document Type already used as a dimension") + if not self.is_new(): + self.validate_document_type_change() + + def validate_document_type_change(self): + doctype_before_save = frappe.db.get_value("Accounting Dimension", self.name, "document_type") + if doctype_before_save != self.document_type: + message = _("Cannot change Reference Document Type.") + message += _("Please create a new Accounting Dimension if required.") + frappe.throw(message) + def after_insert(self): if frappe.flags.in_test: make_dimension_in_accounting_doctypes(doc=self) From c4d67c2afeae8916de364a68d2a763150c589bea Mon Sep 17 00:00:00 2001 From: Suraj Shetty Date: Mon, 8 Feb 2021 18:42:27 +0530 Subject: [PATCH 470/477] refactor: Move call_popup style from less to scss - Add style for audio --- erpnext/public/build.json | 2 +- erpnext/public/less/call_popup.less | 9 --------- erpnext/public/scss/call_popup.scss | 21 +++++++++++++++++++++ 3 files changed, 22 insertions(+), 10 deletions(-) delete mode 100644 erpnext/public/less/call_popup.less create mode 100644 erpnext/public/scss/call_popup.scss diff --git a/erpnext/public/build.json b/erpnext/public/build.json index 4a40e8e8f94..73262382739 100644 --- a/erpnext/public/build.json +++ b/erpnext/public/build.json @@ -2,7 +2,7 @@ "css/erpnext.css": [ "public/less/erpnext.less", "public/less/hub.less", - "public/less/call_popup.less", + "public/scss/call_popup.scss", "public/scss/point-of-sale.scss" ], "css/marketplace.css": [ diff --git a/erpnext/public/less/call_popup.less b/erpnext/public/less/call_popup.less deleted file mode 100644 index 32e85ce16d9..00000000000 --- a/erpnext/public/less/call_popup.less +++ /dev/null @@ -1,9 +0,0 @@ -.call-popup { - a:hover { - text-decoration: underline; - } - .for-description { - max-height: 250px; - overflow: scroll; - } -} \ No newline at end of file diff --git a/erpnext/public/scss/call_popup.scss b/erpnext/public/scss/call_popup.scss new file mode 100644 index 00000000000..95e31828c18 --- /dev/null +++ b/erpnext/public/scss/call_popup.scss @@ -0,0 +1,21 @@ +.call-popup { + a:hover { + text-decoration: underline; + } + .for-description { + max-height: 250px; + overflow: scroll; + } +} + +audio { + height: 40px; + width: 100%; + max-width: 500px; + background-color: var(--control-bg); + border-radius: var(--border-radius-sm); + &-webkit-media-controls-panel { + background: var(--control-bg); + } + outline: none; +} From 723e6dd73fb76dece4ada93f4b5d4122f8bf28db Mon Sep 17 00:00:00 2001 From: Suraj Shetty Date: Mon, 8 Feb 2021 18:43:26 +0530 Subject: [PATCH 471/477] fix: Update style of call log shown in timeline --- erpnext/public/js/templates/call_link.html | 39 +++++++++---------- .../telephony/doctype/call_log/call_log.py | 2 + 2 files changed, 21 insertions(+), 20 deletions(-) diff --git a/erpnext/public/js/templates/call_link.html b/erpnext/public/js/templates/call_link.html index 08bdf142a70..071078c776e 100644 --- a/erpnext/public/js/templates/call_link.html +++ b/erpnext/public/js/templates/call_link.html @@ -1,32 +1,31 @@
    -
    -
    +
    +
    + {{ type }} Call + {% if (duration) %} + • {{ frappe.format(duration, { fieldtype: "Duration" }) }} + {% endif %} + • {{ comment_when(creation) }} +
    - - - {{ type }} Call - - - {{ frappe.format(duration, { fieldtype: "Duration" }) }} - - - {{ comment_when(creation) }} - - - - Details - {% if (show_call_button) { %} - Callback - {% } %} + + + + + +
    -
    + + +
    {% if (type === "Incoming") { %} Incoming call from {{ from }}, received by {{ to }} {% } else { %} Outgoing Call made by {{ from }} to {{ to }} {% } %} -
    -
    +
    {% if (summary) { %} - {{ summary }} + {{ summary }} {% } else { %} {{ __("No Summary") }} {% } %} diff --git a/erpnext/telephony/doctype/call_log/call_log.py b/erpnext/telephony/doctype/call_log/call_log.py index a277a5f9568..4d553df08b8 100644 --- a/erpnext/telephony/doctype/call_log/call_log.py +++ b/erpnext/telephony/doctype/call_log/call_log.py @@ -165,6 +165,8 @@ def get_linked_call_logs(doctype, docname): for log in logs: log.show_call_button = 0 timeline_contents.append({ + 'icon': 'call', + 'is_card': True, 'creation': log.creation, 'template': 'call_link', 'template_data': log From ba26020a824436545b933d1469f4de07fe72f06a Mon Sep 17 00:00:00 2001 From: Suraj Shetty Date: Mon, 8 Feb 2021 18:45:55 +0530 Subject: [PATCH 472/477] fix: Show audio interface in call log which has recording URL - Also, remove unneccesary column & section break in call log doctype --- .../telephony/doctype/call_log/call_log.js | 25 +++++++++++++++-- .../telephony/doctype/call_log/call_log.json | 28 ++++++++----------- 2 files changed, 34 insertions(+), 19 deletions(-) diff --git a/erpnext/telephony/doctype/call_log/call_log.js b/erpnext/telephony/doctype/call_log/call_log.js index 977f86da0dd..e7afa0b7d09 100644 --- a/erpnext/telephony/doctype/call_log/call_log.js +++ b/erpnext/telephony/doctype/call_log/call_log.js @@ -2,7 +2,26 @@ // For license information, please see license.txt frappe.ui.form.on('Call Log', { - // refresh: function(frm) { - - // } + refresh: function(frm) { + frm.events.setup_recording_audio_control(frm); + const incoming_call = frm.doc.type == 'Incoming'; + frm.add_custom_button(incoming_call ? __('Callback'): __('Call Again'), () => { + const number = incoming_call ? frm.doc.from : frm.doc.to; + frappe.phone_call.handler(number, frm); + }); + }, + setup_recording_audio_control(frm) { + const recording_wrapper = frm.get_field('recording_html').$wrapper; + if (!frm.doc.recording_url || frm.doc.recording_url == 'null') { + recording_wrapper.empty(); + } else { + recording_wrapper.addClass('input-max-width'); + recording_wrapper.html(` + + `); + } + } }); diff --git a/erpnext/telephony/doctype/call_log/call_log.json b/erpnext/telephony/doctype/call_log/call_log.json index 1ecd884bbd4..1d6c39edf6e 100644 --- a/erpnext/telephony/doctype/call_log/call_log.json +++ b/erpnext/telephony/doctype/call_log/call_log.json @@ -5,6 +5,7 @@ "doctype": "DocType", "engine": "InnoDB", "field_order": [ + "call_details_section", "id", "from", "to", @@ -21,20 +22,9 @@ "section_break_11", "summary", "section_break_19", - "links", - "column_break_3", - "section_break_5" + "links" ], "fields": [ - { - "fieldname": "column_break_3", - "fieldtype": "Column Break" - }, - { - "fieldname": "section_break_5", - "fieldtype": "Section Break", - "label": "Call Details" - }, { "fieldname": "id", "fieldtype": "Data", @@ -75,6 +65,7 @@ { "fieldname": "recording_url", "fieldtype": "Data", + "hidden": 1, "label": "Recording URL" }, { @@ -112,13 +103,13 @@ }, { "fieldname": "summary", - "fieldtype": "Small Text", - "label": "Call Summary" + "fieldtype": "Small Text" }, { "fieldname": "section_break_11", "fieldtype": "Section Break", - "hide_border": 1 + "hide_border": 1, + "label": "Call Summary" }, { "fieldname": "start_time", @@ -138,12 +129,17 @@ "label": "Customer", "options": "Customer", "read_only": 1 + }, + { + "fieldname": "call_details_section", + "fieldtype": "Section Break", + "label": "Call Details" } ], "in_create": 1, "index_web_pages_for_search": 1, "links": [], - "modified": "2021-01-13 12:28:20.288985", + "modified": "2021-02-08 14:23:28.744844", "modified_by": "Administrator", "module": "Telephony", "name": "Call Log", From c5248b30ebda26bd89fece350de6a9f11ec95879 Mon Sep 17 00:00:00 2001 From: Suraj Shetty Date: Mon, 8 Feb 2021 18:50:05 +0530 Subject: [PATCH 473/477] fix: Do not re-use call popup if call ID is different --- erpnext/public/js/call_popup/call_popup.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/erpnext/public/js/call_popup/call_popup.js b/erpnext/public/js/call_popup/call_popup.js index be1745e54f1..f3d09ee9986 100644 --- a/erpnext/public/js/call_popup/call_popup.js +++ b/erpnext/public/js/call_popup/call_popup.js @@ -191,11 +191,12 @@ class CallPopup { $(document).on('app_ready', function () { frappe.realtime.on('show_call_popup', call_log => { - if (!erpnext.call_popup) { + let call_popup = erpnext.call_popup; + if (call_popup && call_log.name === call_popup.call_log.name) { erpnext.call_popup = new CallPopup(call_log); } else { - erpnext.call_popup.update_call_log(call_log); - erpnext.call_popup.dialog.show(); + call_popup.update_call_log(call_log); + call_popup.dialog.show(); } }); }); From dcc9947d10d0810b9b61028f98431cf95d5a32cb Mon Sep 17 00:00:00 2001 From: Suraj Shetty Date: Mon, 8 Feb 2021 20:13:23 +0530 Subject: [PATCH 474/477] fix: Update call_popup - Setup missed & call ended listeners - Show contacts based on links --- erpnext/crm/doctype/lead/lead.py | 4 +- erpnext/public/js/call_popup/call_popup.js | 237 +++++++++++---------- 2 files changed, 125 insertions(+), 116 deletions(-) diff --git a/erpnext/crm/doctype/lead/lead.py b/erpnext/crm/doctype/lead/lead.py index 938cbfdc852..d1d096843bf 100644 --- a/erpnext/crm/doctype/lead/lead.py +++ b/erpnext/crm/doctype/lead/lead.py @@ -352,7 +352,7 @@ def get_lead_with_phone_number(number): leads = frappe.get_all('Lead', or_filters={ 'phone': ['like', '%{}'.format(number)], 'mobile_no': ['like', '%{}'.format(number)] - }, limit=1) + }, limit=1, order_by="creation DESC") lead = leads[0].name if leads else None @@ -361,4 +361,4 @@ def get_lead_with_phone_number(number): def daily_open_lead(): leads = frappe.get_all("Lead", filters = [["contact_date", "Between", [nowdate(), nowdate()]]]) for lead in leads: - frappe.db.set_value("Lead", lead.name, "status", "Open") \ No newline at end of file + frappe.db.set_value("Lead", lead.name, "status", "Open") diff --git a/erpnext/public/js/call_popup/call_popup.js b/erpnext/public/js/call_popup/call_popup.js index f3d09ee9986..24297885a2f 100644 --- a/erpnext/public/js/call_popup/call_popup.js +++ b/erpnext/public/js/call_popup/call_popup.js @@ -7,10 +7,103 @@ class CallPopup { } make() { + frappe.utils.play_sound('incoming-call'); this.dialog = new frappe.ui.Dialog({ 'static': true, - 'minimizable': true, - 'fields': [{ + 'minimizable': true + }); + this.dialog.get_close_btn().show(); + this.setup_dialog(); + this.set_call_status(); + frappe.utils.bind_actions_with_object(this.dialog.$body, this); + this.dialog.$wrapper.addClass('call-popup'); + this.dialog.get_close_btn().unbind('click').click(this.close_modal.bind(this)); + this.dialog.show(); + } + + setup_dialog() { + this.setup_call_details(); + this.dialog.$body.empty().append(this.caller_info); + } + + set_indicator(color, blink=false) { + let classes = `indicator ${color} ${blink ? 'blink': ''}`; + this.dialog.header.find('.indicator').attr('class', classes); + } + + set_call_status(call_status) { + let title = ''; + call_status = call_status || this.call_log.status; + if (['Ringing'].includes(call_status) || !call_status) { + title = __('Incoming call from {0}', [this.get_caller_name() || this.caller_number]); + this.set_indicator('blue', true); + } else if (call_status === 'In Progress') { + title = __('Call Connected'); + this.set_indicator('green'); + } else if (['No Answer', 'Missed'].includes(call_status)) { + this.set_indicator('yellow'); + title = __('Call Missed'); + } else if (['Completed', 'Busy', 'Failed'].includes(call_status)) { + this.set_indicator('red'); + title = __('Call Ended'); + } else { + this.set_indicator('blue'); + title = call_status; + } + this.dialog.set_title(title); + } + + update_call_log(call_log, missed) { + this.call_log = call_log; + this.set_call_status(missed ? 'Missed': null); + } + + close_modal() { + this.dialog.hide(); + delete erpnext.call_popup; + } + + call_ended(call_log, missed) { + frappe.utils.play_sound('call-disconnect'); + this.update_call_log(call_log, missed); + setTimeout(() => { + if (!this.dialog.get_value('call_summary')) { + this.close_modal(); + } + }, 60000); + this.clear_listeners(); + } + + get_caller_name() { + const contact_link = this.get_contact_link(); + return contact_link.link_title || contact_link.link_name; + } + + get_contact_link() { + let log = this.call_log; + let contact_link = log.links.find(d => d.link_doctype === 'Contact'); + return contact_link || {}; + } + + setup_listener() { + frappe.realtime.on(`call_${this.call_log.id}_ended`, call_log => { + this.call_ended(call_log); + }); + + frappe.realtime.on(`call_${this.call_log.id}_missed`, call_log => { + this.call_ended(call_log, true); + }); + } + + clear_listeners() { + frappe.realtime.off(`call_${this.call_log.id}_ended`); + frappe.realtime.off(`call_${this.call_log.id}_missed`); + } + + setup_call_details() { + this.caller_info = $(`
    `); + this.call_details = new frappe.ui.FieldGroup({ + fields: [{ 'fieldname': 'name', 'label': 'Name', 'default': this.get_caller_name() || __('Unknown Caller'), @@ -19,17 +112,17 @@ class CallPopup { }, { 'fieldtype': 'Button', 'label': __('Open Contact'), - 'click': () => frappe.set_route('Form', 'Contact', this.call_log.contact), - 'depends_on': () => this.call_log.contact - }, { - 'fieldtype': 'Button', - 'label': __('Open Lead'), - 'click': () => frappe.set_route('Form', 'Lead', this.call_log.lead), - 'depends_on': () => this.call_log.lead + 'click': () => frappe.set_route('Form', 'Contact', this.get_contact_link().link_name), + 'depends_on': () => this.get_caller_name() }, { 'fieldtype': 'Button', 'label': __('Create New Contact'), - 'click': () => frappe.new_doc('Contact', { 'mobile_no': this.caller_number }), + 'click': this.create_new_contact.bind(this), + 'depends_on': () => !this.get_caller_name() + }, { + 'fieldtype': 'Button', + 'label': __('Create New Customer'), + 'click': this.create_new_customer.bind(this), 'depends_on': () => !this.get_caller_name() }, { 'fieldtype': 'Button', @@ -44,26 +137,9 @@ class CallPopup { 'fieldtype': 'Data', 'default': this.caller_number, 'read_only': 1 - }, { - 'fielname': 'last_interaction', - 'fieldtype': 'Section Break', - 'label': __('Activity'), - 'depends_on': () => this.get_caller_name() - }, { - 'fieldtype': 'Small Text', - 'label': __('Last Issue'), - 'fieldname': 'last_issue', - 'read_only': true, - 'depends_on': () => this.call_log.contact, - 'default': `${__('No issue has been raised by the caller.')}` - }, { - 'fieldtype': 'Small Text', - 'label': __('Last Communication'), - 'fieldname': 'last_communication', - 'read_only': true, - 'default': `${__('No communication found.')}` }, { 'fieldtype': 'Section Break', + 'hide_border': 1, }, { 'fieldtype': 'Small Text', 'label': __('Call Summary'), @@ -72,7 +148,7 @@ class CallPopup { 'fieldtype': 'Button', 'label': __('Save'), 'click': () => { - const call_summary = this.dialog.get_value('call_summary'); + const call_summary = this.call_details.get_value('call_summary'); if (!call_summary) return; frappe.xcall('erpnext.telephony.doctype.call_log.call_log.add_call_summary', { 'call_log': this.call_log.name, @@ -94,98 +170,29 @@ class CallPopup { }); } }], + body: this.caller_info }); - this.set_call_status(); - this.dialog.get_close_btn().show(); - this.make_last_interaction_section(); - this.dialog.$body.addClass('call-popup'); - this.dialog.set_secondary_action(this.close_modal.bind(this)); - frappe.utils.play_sound('incoming-call'); - this.dialog.show(); + this.call_details.make(); } - set_indicator(color, blink=false) { - let classes = `indicator ${color} ${blink ? 'blink': ''}`; - this.dialog.header.find('.indicator').attr('class', classes); + is_known_caller() { + return Boolean(this.get_caller_name()); } - set_call_status(call_status) { - let title = ''; - call_status = call_status || this.call_log.status; - if (['Ringing'].includes(call_status) || !call_status) { - title = __('Incoming call from {0}', [this.get_caller_name() || this.caller_number]); - this.set_indicator('blue', true); - } else if (call_status === 'In Progress') { - title = __('Call Connected'); - this.set_indicator('yellow'); - } else if (call_status === 'Missed') { - this.set_indicator('red'); - title = __('Call Missed'); - } else if (['Completed', 'Disconnected'].includes(call_status)) { - this.set_indicator('red'); - title = __('Call Disconnected'); - } else { - this.set_indicator('blue'); - title = call_status; - } - this.dialog.set_title(title); + create_new_customer() { + // to avoid quick entry form + const new_customer = frappe.model.get_new_doc('Customer'); + new_customer.mobile_no = this.caller_number; + frappe.set_route('Form', new_customer.doctype, new_customer.name); } - update_call_log(call_log) { - this.call_log = call_log; - this.set_call_status(); - } - - close_modal() { - this.dialog.hide(); - delete erpnext.call_popup; - } - - call_disconnected(call_log) { - frappe.utils.play_sound('call-disconnect'); - this.update_call_log(call_log); - setTimeout(() => { - if (!this.dialog.get_value('call_summary')) { - this.close_modal(); - } - }, 30000); - } - - make_last_interaction_section() { - frappe.xcall('erpnext.crm.doctype.utils.get_last_interaction', { - 'contact': this.call_log.contact, - 'lead': this.call_log.lead - }).then(data => { - const comm_field = this.dialog.get_field('last_communication'); - if (data.last_communication) { - const comm = data.last_communication; - comm_field.set_value(comm.content); - } - - if (data.last_issue) { - const issue = data.last_issue; - const issue_field = this.dialog.get_field("last_issue"); - issue_field.set_value(issue.subject); - issue_field.$wrapper.append(` - - ${__('View all issues from {0}', [issue.customer])} - - `); - } - }); - } - - get_caller_name() { - let log = this.call_log; - return log.contact_name || log.lead_name; - } - - setup_listener() { - frappe.realtime.on(`call_${this.call_log.id}_disconnected`, call_log => { - this.call_disconnected(call_log); - // Remove call disconnect listener after the call is disconnected - frappe.realtime.off(`call_${this.call_log.id}_disconnected`); - }); + create_new_contact() { + // TODO: fix new_doc, it should accept child table values + const new_contact = frappe.model.get_new_doc('Contact'); + const phone_no = frappe.model.add_child(new_contact, 'Contact Phone', 'phone_nos'); + phone_no.phone = this.caller_number; + phone_no.is_primary_mobile_no = 1; + frappe.set_route('Form', new_contact.doctype, new_contact.name); } } @@ -200,3 +207,5 @@ $(document).on('app_ready', function () { } }); }); + +window.CallPopup = CallPopup; From 8991d4ed0b9a67e282063e2e8ba18de82e8e043d Mon Sep 17 00:00:00 2001 From: Saqib Date: Mon, 8 Feb 2021 20:19:11 +0530 Subject: [PATCH 475/477] fix: fetching of standalone cr/dr notes for reconciliation (#24575) --- .../payment_reconciliation.py | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.py b/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.py index 791b03a0d78..f7a15c04faa 100644 --- a/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.py +++ b/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.py @@ -88,19 +88,19 @@ class PaymentReconciliation(Document): voucher_type = ('Sales Invoice' if self.party_type == 'Customer' else "Purchase Invoice") - return frappe.db.sql(""" SELECT `tab{doc}`.name as reference_name, %(voucher_type)s as reference_type, - (sum(`tabGL Entry`.{dr_or_cr}) - sum(`tabGL Entry`.{reconciled_dr_or_cr})) as amount, + return frappe.db.sql(""" SELECT doc.name as reference_name, %(voucher_type)s as reference_type, + (sum(gl.{dr_or_cr}) - sum(gl.{reconciled_dr_or_cr})) as amount, account_currency as currency - FROM `tab{doc}`, `tabGL Entry` + FROM `tab{doc}` doc, `tabGL Entry` gl WHERE - (`tab{doc}`.name = `tabGL Entry`.against_voucher or `tab{doc}`.name = `tabGL Entry`.voucher_no) - and `tab{doc}`.{party_type_field} = %(party)s - and `tab{doc}`.is_return = 1 and `tab{doc}`.return_against IS NULL - and `tabGL Entry`.against_voucher_type = %(voucher_type)s - and `tab{doc}`.docstatus = 1 and `tabGL Entry`.party = %(party)s - and `tabGL Entry`.party_type = %(party_type)s and `tabGL Entry`.account = %(account)s - and `tabGL Entry`.is_cancelled = 0 - GROUP BY `tab{doc}`.name + (doc.name = gl.against_voucher or doc.name = gl.voucher_no) + and doc.{party_type_field} = %(party)s + and doc.is_return = 1 and ifnull(doc.return_against, "") = "" + and gl.against_voucher_type = %(voucher_type)s + and doc.docstatus = 1 and gl.party = %(party)s + and gl.party_type = %(party_type)s and gl.account = %(account)s + and gl.is_cancelled = 0 + GROUP BY doc.name Having amount > 0 """.format( @@ -113,7 +113,7 @@ class PaymentReconciliation(Document): 'party_type': self.party_type, 'voucher_type': voucher_type, 'account': self.receivable_payable_account - }, as_dict=1) + }, as_dict=1, debug=1) def add_payment_entries(self, entries): self.set('payments', []) From 1016ff48fcd984c7e2e6be0d2d0d377ef021c4c0 Mon Sep 17 00:00:00 2001 From: Suraj Shetty Date: Tue, 9 Feb 2021 12:17:29 +0530 Subject: [PATCH 476/477] fix: Create new call popup if call popup does not exists --- erpnext/public/js/call_popup/call_popup.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/erpnext/public/js/call_popup/call_popup.js b/erpnext/public/js/call_popup/call_popup.js index 24297885a2f..c954f12ac63 100644 --- a/erpnext/public/js/call_popup/call_popup.js +++ b/erpnext/public/js/call_popup/call_popup.js @@ -200,10 +200,10 @@ $(document).on('app_ready', function () { frappe.realtime.on('show_call_popup', call_log => { let call_popup = erpnext.call_popup; if (call_popup && call_log.name === call_popup.call_log.name) { - erpnext.call_popup = new CallPopup(call_log); - } else { call_popup.update_call_log(call_log); call_popup.dialog.show(); + } else { + erpnext.call_popup = new CallPopup(call_log); } }); }); From 5164223b99b2792211a4edc9568cb13f2a0d76c2 Mon Sep 17 00:00:00 2001 From: Anurag Mishra <32095923+Anurag810@users.noreply.github.com> Date: Tue, 9 Feb 2021 16:22:28 +0530 Subject: [PATCH 477/477] fix: error on group by filter (#24587) Co-authored-by: Afshan <33727827+AfshanKhan@users.noreply.github.com> --- .../monthly_attendance_sheet.py | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/erpnext/hr/report/monthly_attendance_sheet/monthly_attendance_sheet.py b/erpnext/hr/report/monthly_attendance_sheet/monthly_attendance_sheet.py index 46082129e24..c5929c6bf99 100644 --- a/erpnext/hr/report/monthly_attendance_sheet/monthly_attendance_sheet.py +++ b/erpnext/hr/report/monthly_attendance_sheet/monthly_attendance_sheet.py @@ -36,6 +36,8 @@ def execute(filters=None): conditions, filters = get_conditions(filters) columns, days = get_columns(filters) att_map = get_attendance_list(conditions, filters) + if not att_map: + return columns, [], None, None if filters.group_by: emp_map, group_by_parameters = get_employee_details(filters.group_by, filters.company) @@ -65,10 +67,14 @@ def execute(filters=None): if filters.group_by: emp_att_map = {} for parameter in group_by_parameters: - data.append([ ""+ parameter + ""]) - record, aaa = add_data(emp_map[parameter], att_map, filters, holiday_map, conditions, default_holiday_list, leave_list=leave_list) - emp_att_map.update(aaa) - data += record + emp_map_set = set([key for key in emp_map[parameter].keys()]) + att_map_set = set([key for key in att_map.keys()]) + if (att_map_set & emp_map_set): + parameter_row = [""+ parameter + ""] + ['' for day in range(filters["total_days_in_month"] + 2)] + data.append(parameter_row) + record, emp_att_data = add_data(emp_map[parameter], att_map, filters, holiday_map, conditions, default_holiday_list, leave_list=leave_list) + emp_att_map.update(emp_att_data) + data += record else: record, emp_att_map = add_data(emp_map, att_map, filters, holiday_map, conditions, default_holiday_list, leave_list=leave_list) data += record @@ -237,6 +243,9 @@ def get_attendance_list(conditions, filters): status from tabAttendance where docstatus = 1 %s order by employee, attendance_date""" % conditions, filters, as_dict=1) + if not attendance_list: + msgprint(_("No attendance record found"), alert=True, indicator="orange") + att_map = {} for d in attendance_list: att_map.setdefault(d.employee, frappe._dict()).setdefault(d.day_of_month, "")