From 3bd15d3aaa6b4e5020f66d84ecc5eadb8a73e76b Mon Sep 17 00:00:00 2001 From: prssanna Date: Thu, 22 Aug 2019 13:44:48 +0530 Subject: [PATCH 01/32] feat: remove leaderboard from erpnext --- erpnext/utilities/page/__init__.py | 0 .../utilities/page/leaderboard/__init__.py | 0 .../page/leaderboard/leaderboard.css | 54 --- .../utilities/page/leaderboard/leaderboard.js | 307 ------------------ .../page/leaderboard/leaderboard.json | 19 -- .../utilities/page/leaderboard/leaderboard.py | 153 --------- 6 files changed, 533 deletions(-) delete mode 100644 erpnext/utilities/page/__init__.py delete mode 100644 erpnext/utilities/page/leaderboard/__init__.py delete mode 100644 erpnext/utilities/page/leaderboard/leaderboard.css delete mode 100644 erpnext/utilities/page/leaderboard/leaderboard.js delete mode 100644 erpnext/utilities/page/leaderboard/leaderboard.json delete mode 100644 erpnext/utilities/page/leaderboard/leaderboard.py diff --git a/erpnext/utilities/page/__init__.py b/erpnext/utilities/page/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/erpnext/utilities/page/leaderboard/__init__.py b/erpnext/utilities/page/leaderboard/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/erpnext/utilities/page/leaderboard/leaderboard.css b/erpnext/utilities/page/leaderboard/leaderboard.css deleted file mode 100644 index 1f4fc5159a..0000000000 --- a/erpnext/utilities/page/leaderboard/leaderboard.css +++ /dev/null @@ -1,54 +0,0 @@ -.list-filters { - overflow-y: hidden; - padding: 5px -} - -.list-filter-item { - min-width: 150px; - float: left; - margin:5px; -} - -.list-item_content{ - flex: 1; - padding-right: 15px; - align-items: center; -} - -.select-time, .select-doctype, .select-filter, .select-sort { - background: #f0f4f7; -} - -.select-time:focus, .select-doctype:focus, .select-filter:focus, .select-sort:focus { - background: #f0f4f7; -} - -.header-btn-base{ - border:none; - outline:0; - vertical-align:middle; - overflow:hidden; - text-decoration:none; - color:inherit; - background-color:inherit; - cursor:pointer; - white-space:nowrap; -} - -.header-btn-grey,.header-btn-grey:hover{ - color:#000!important; - background-color:#bbb!important -} - -.header-btn-round{ - border-radius:4px -} - -.item-title-bold{ - font-weight: bold; -} - -/* -.header-btn-base:hover { - box-shadow:0 8px 16px 0 rgba(0,0,0,0.2),0 6px 20px 0 rgba(0,0,0,0.19) -}*/ diff --git a/erpnext/utilities/page/leaderboard/leaderboard.js b/erpnext/utilities/page/leaderboard/leaderboard.js deleted file mode 100644 index 43d0e6e948..0000000000 --- a/erpnext/utilities/page/leaderboard/leaderboard.js +++ /dev/null @@ -1,307 +0,0 @@ -frappe.pages["leaderboard"].on_page_load = function (wrapper) { - frappe.leaderboard = new frappe.Leaderboard(wrapper); -} - -frappe.Leaderboard = Class.extend({ - - init: function (parent) { - frappe.ui.make_app_page({ - parent: parent, - title: "Leaderboard", - single_column: false - }); - - this.parent = parent; - this.page = this.parent.page; - this.page.sidebar.html(``); - this.$sidebar_list = this.page.sidebar.find('ul'); - - // const list of doctypes - this.doctypes = ["Customer", "Item", "Supplier", "Sales Partner","Sales Person"]; - this.timespans = ["Week", "Month", "Quarter", "Year"]; - this.filters = { - "Customer": ["total_sales_amount", "total_qty_sold", "outstanding_amount", ], - "Item": ["total_sales_amount", "total_qty_sold", "total_purchase_amount", - "total_qty_purchased", "available_stock_qty", "available_stock_value"], - "Supplier": ["total_purchase_amount", "total_qty_purchased", "outstanding_amount"], - "Sales Partner": ["total_sales_amount", "total_commission"], - "Sales Person": ["total_sales_amount"], - }; - - // for saving current selected filters - // TODO: revert to 0 index for doctype and timespan, and remove preset down - const _initial_doctype = this.doctypes[0]; - const _initial_timespan = this.timespans[0]; - const _initial_filter = this.filters[_initial_doctype]; - - this.options = { - selected_doctype: _initial_doctype, - selected_filter: _initial_filter, - selected_filter_item: _initial_filter[0], - selected_timespan: _initial_timespan, - }; - - this.message = null; - this.make(); - }, - - make: function () { - var me = this; - - var $container = $(`
-
-
-
`).appendTo(this.page.main); - - this.$graph_area = $container.find('.leaderboard-graph'); - - this.doctypes.map(doctype => { - this.get_sidebar_item(doctype).appendTo(this.$sidebar_list); - }); - - this.company_select = this.page.add_field({ - fieldname: 'company', - label: __('Company'), - fieldtype:'Link', - options:'Company', - default:frappe.defaults.get_default('company'), - reqd: 1, - change: function() { - me.options.selected_company = this.value; - me.make_request($container); - } - }); - this.timespan_select = this.page.add_select(__("Timespan"), - this.timespans.map(d => { - return {"label": __(d), value: d } - }) - ); - - this.type_select = this.page.add_select(__("Type"), - me.options.selected_filter.map(d => { - return {"label": __(frappe.model.unscrub(d)), value: d } - }) - ); - - this.$sidebar_list.on('click', 'li', function(e) { - let $li = $(this); - let doctype = $li.find('span').attr("doctype-value"); - - me.options.selected_company = frappe.defaults.get_default('company'); - me.options.selected_doctype = doctype; - me.options.selected_filter = me.filters[doctype]; - me.options.selected_filter_item = me.filters[doctype][0]; - - me.type_select.empty().add_options( - me.options.selected_filter.map(d => { - return {"label": __(frappe.model.unscrub(d)), value: d } - }) - ); - - me.$sidebar_list.find('li').removeClass('active'); - $li.addClass('active'); - - me.make_request($container); - }); - - this.timespan_select.on("change", function() { - me.options.selected_timespan = this.value; - me.make_request($container); - }); - - this.type_select.on("change", function() { - me.options.selected_filter_item = this.value - me.make_request($container); - }); - - // now get leaderboard - this.$sidebar_list.find('li:first').trigger('click'); - }, - - make_request: function ($container) { - var me = this; - - frappe.model.with_doctype(me.options.selected_doctype, function () { - me.get_leaderboard(me.get_leaderboard_data, $container); - }); - }, - - get_leaderboard: function (notify, $container) { - var me = this; - if(!me.options.selected_company) { - frappe.throw(__("Please select Company")); - } - frappe.call({ - method: "erpnext.utilities.page.leaderboard.leaderboard.get_leaderboard", - args: { - doctype: me.options.selected_doctype, - timespan: me.options.selected_timespan, - company: me.options.selected_company, - field: me.options.selected_filter_item, - }, - callback: function (r) { - let results = r.message || []; - - let graph_items = results.slice(0, 10); - - me.$graph_area.show().empty(); - let args = { - data: { - datasets: [ - { - values: graph_items.map(d=>d.value) - } - ], - labels: graph_items.map(d=>d.name) - }, - colors: ['light-green'], - format_tooltip_x: d=>d[me.options.selected_filter_item], - type: 'bar', - height: 140 - }; - new frappe.Chart('.leaderboard-graph', args); - - notify(me, r, $container); - } - }); - }, - - get_leaderboard_data: function (me, res, $container) { - if (res && res.message) { - me.message = null; - $container.find(".leaderboard-list").html(me.render_list_view(res.message)); - } else { - me.$graph_area.hide(); - me.message = __("No items found."); - $container.find(".leaderboard-list").html(me.render_list_view()); - } - }, - - render_list_view: function (items = []) { - var me = this; - - var html = - `${me.render_message()} -
- ${me.render_result(items)} -
`; - - return $(html); - }, - - render_result: function (items) { - var me = this; - - var html = - `${me.render_list_header()} - ${me.render_list_result(items)}`; - - return html; - }, - - render_list_header: function () { - var me = this; - const _selected_filter = me.options.selected_filter - .map(i => frappe.model.unscrub(i)); - const fields = ['name', me.options.selected_filter_item]; - - const html = - `
-
- ${ - fields.map(filter => { - const col = frappe.model.unscrub(filter); - return ( - `
- - ${col} - -
`); - }).join("") - } -
-
`; - return html; - }, - - render_list_result: function (items) { - var me = this; - - let _html = items.map((item, index) => { - const $value = $(me.get_item_html(item)); - - let item_class = ""; - if(index == 0) { - item_class = "first"; - } else if (index == 1) { - item_class = "second"; - } else if(index == 2) { - item_class = "third"; - } - const $item_container = $(`
`).append($value); - return $item_container[0].outerHTML; - }).join(""); - - let html = - `
-
- ${_html} -
-
`; - - return html; - }, - - render_message: function () { - var me = this; - - let html = - `
-
-

No Item found

-
-
`; - - return html; - }, - - get_item_html: function (item) { - var me = this; - const company = me.options.selected_company; - const currency = frappe.get_doc(":Company", company).default_currency; - const fields = ['name','value']; - - const html = - `
- ${ - fields.map(col => { - let val = item[col]; - if(col=="name") { - var formatted_value = ` ${val} ` - } else { - var formatted_value = ` - ${(me.options.selected_filter_item.indexOf('qty') == -1) ? format_currency(val, currency) : val}` - } - - return ( - `
- ${formatted_value} -
`); - }).join("") - } -
`; - - return html; - }, - - get_sidebar_item: function(item) { - return $(`
  • - - ${ __(item) } -
  • `); - } -}); diff --git a/erpnext/utilities/page/leaderboard/leaderboard.json b/erpnext/utilities/page/leaderboard/leaderboard.json deleted file mode 100644 index 8ccef7dcf6..0000000000 --- a/erpnext/utilities/page/leaderboard/leaderboard.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "content": null, - "creation": "2017-06-06 02:54:24.785360", - "docstatus": 0, - "doctype": "Page", - "idx": 0, - "modified": "2017-09-12 14:05:26.422064", - "modified_by": "Administrator", - "module": "Utilities", - "name": "leaderboard", - "owner": "Administrator", - "page_name": "leaderboard", - "roles": [], - "script": null, - "standard": "Yes", - "style": null, - "system_page": 0, - "title": "Leaderboard" -} \ No newline at end of file diff --git a/erpnext/utilities/page/leaderboard/leaderboard.py b/erpnext/utilities/page/leaderboard/leaderboard.py deleted file mode 100644 index 87cf2a43be..0000000000 --- a/erpnext/utilities/page/leaderboard/leaderboard.py +++ /dev/null @@ -1,153 +0,0 @@ -# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and Contributors -# MIT License. See license.txt - -from __future__ import unicode_literals, print_function -import frappe -from frappe.utils import add_to_date - -@frappe.whitelist() -def get_leaderboard(doctype, timespan, company, field): - """return top 10 items for that doctype based on conditions""" - from_date = get_from_date(timespan) - records = [] - if doctype == "Customer": - records = get_all_customers(from_date, company, field) - elif doctype == "Item": - records = get_all_items(from_date, company, field) - elif doctype == "Supplier": - records = get_all_suppliers(from_date, company, field) - elif doctype == "Sales Partner": - records = get_all_sales_partner(from_date, company, field) - elif doctype == "Sales Person": - records = get_all_sales_person(from_date, company) - - return records - -def get_all_customers(from_date, company, field): - if field == "outstanding_amount": - return frappe.db.sql(""" - select customer as name, sum(outstanding_amount) as value - FROM `tabSales Invoice` - where docstatus = 1 and posting_date >= %s and company = %s - group by customer - order by value DESC - limit 20 - """, (from_date, company), as_dict=1) - else: - if field == "total_sales_amount": - select_field = "sum(so_item.base_net_amount)" - elif field == "total_qty_sold": - select_field = "sum(so_item.stock_qty)" - - return frappe.db.sql(""" - select so.customer as name, {0} as value - FROM `tabSales Order` as so JOIN `tabSales Order Item` as so_item - ON so.name = so_item.parent - where so.docstatus = 1 and so.transaction_date >= %s and so.company = %s - group by so.customer - order by value DESC - limit 20 - """.format(select_field), (from_date, company), as_dict=1) - -def get_all_items(from_date, company, field): - if field in ("available_stock_qty", "available_stock_value"): - return frappe.db.sql(""" - select item_code as name, {0} as value - from tabBin - group by item_code - order by value desc - limit 20 - """.format("sum(actual_qty)" if field=="available_stock_qty" else "sum(stock_value)"), as_dict=1) - else: - if field == "total_sales_amount": - select_field = "sum(order_item.base_net_amount)" - select_doctype = "Sales Order" - elif field == "total_purchase_amount": - select_field = "sum(order_item.base_net_amount)" - select_doctype = "Purchase Order" - elif field == "total_qty_sold": - select_field = "sum(order_item.stock_qty)" - select_doctype = "Sales Order" - elif field == "total_qty_purchased": - select_field = "sum(order_item.stock_qty)" - select_doctype = "Purchase Order" - - return frappe.db.sql(""" - select order_item.item_code as name, {0} as value - from `tab{1}` sales_order join `tab{1} Item` as order_item - on sales_order.name = order_item.parent - where sales_order.docstatus = 1 - and sales_order.company = %s and sales_order.transaction_date >= %s - group by order_item.item_code - order by value desc - limit 20 - """.format(select_field, select_doctype), (company, from_date), as_dict=1) - -def get_all_suppliers(from_date, company, field): - if field == "outstanding_amount": - return frappe.db.sql(""" - select supplier as name, sum(outstanding_amount) as value - FROM `tabPurchase Invoice` - where docstatus = 1 and posting_date >= %s and company = %s - group by supplier - order by value DESC - limit 20""", (from_date, company), as_dict=1) - else: - if field == "total_purchase_amount": - select_field = "sum(purchase_order_item.base_net_amount)" - elif field == "total_qty_purchased": - select_field = "sum(purchase_order_item.stock_qty)" - - return frappe.db.sql(""" - select purchase_order.supplier as name, {0} as value - FROM `tabPurchase Order` as purchase_order LEFT JOIN `tabPurchase Order Item` - as purchase_order_item ON purchase_order.name = purchase_order_item.parent - where purchase_order.docstatus = 1 and purchase_order.modified >= %s - and purchase_order.company = %s - group by purchase_order.supplier - order by value DESC - limit 20""".format(select_field), (from_date, company), as_dict=1) - -def get_all_sales_partner(from_date, company, field): - if field == "total_sales_amount": - select_field = "sum(base_net_total)" - elif field == "total_commission": - select_field = "sum(total_commission)" - - return frappe.db.sql(""" - select sales_partner as name, {0} as value - from `tabSales Order` - where ifnull(sales_partner, '') != '' and docstatus = 1 - and transaction_date >= %s and company = %s - group by sales_partner - order by value DESC - limit 20 - """.format(select_field), (from_date, company), as_dict=1) - -def get_all_sales_person(from_date, company): - return frappe.db.sql(""" - select sales_team.sales_person as name, sum(sales_order.base_net_total) as value - from `tabSales Order` as sales_order join `tabSales Team` as sales_team - on sales_order.name = sales_team.parent and sales_team.parenttype = 'Sales Order' - where sales_order.docstatus = 1 - and sales_order.transaction_date >= %s - and sales_order.company = %s - group by sales_team.sales_person - order by value DESC - limit 20 - """, (from_date, company), as_dict=1) - -def get_from_date(seleted_timespan): - """return string for ex:this week as date:string""" - days = months = years = 0 - if "month" == seleted_timespan.lower(): - months = -1 - elif "quarter" == seleted_timespan.lower(): - months = -3 - elif "year" == seleted_timespan.lower(): - years = -1 - else: - days = -7 - - return add_to_date(None, years=years, months=months, days=days, - as_string=True, as_datetime=True) \ No newline at end of file From 3f1444e4107dce4f3d615fc6086261e31f153b6c Mon Sep 17 00:00:00 2001 From: prssanna Date: Tue, 24 Sep 2019 13:04:53 +0530 Subject: [PATCH 02/32] fix: get leaderboards using hooks --- erpnext/hooks.py | 2 + erpnext/startup/leaderboard.py | 128 +++++++++++++++++++++++++++++++++ 2 files changed, 130 insertions(+) create mode 100644 erpnext/startup/leaderboard.py diff --git a/erpnext/hooks.py b/erpnext/hooks.py index 7e33a14d51..b94c29dafc 100644 --- a/erpnext/hooks.py +++ b/erpnext/hooks.py @@ -42,6 +42,8 @@ notification_config = "erpnext.startup.notifications.get_notification_config" get_help_messages = "erpnext.utilities.activation.get_help_messages" get_user_progress_slides = "erpnext.utilities.user_progress.get_user_progress_slides" update_and_get_user_progress = "erpnext.utilities.user_progress_utils.update_default_domain_actions_and_get_state" +leaderboards = "erpnext.startup.leaderboard.get_leaderboards" + on_session_creation = "erpnext.shopping_cart.utils.set_cart_count" on_logout = "erpnext.shopping_cart.utils.clear_cart_count" diff --git a/erpnext/startup/leaderboard.py b/erpnext/startup/leaderboard.py new file mode 100644 index 0000000000..a5549b8748 --- /dev/null +++ b/erpnext/startup/leaderboard.py @@ -0,0 +1,128 @@ + +from __future__ import unicode_literals, print_function +import frappe + +def get_leaderboards(): + leaderboards = { + 'Customer': 'erpnext.startup.leaderboard.get_all_customers', + 'Item': 'erpnext.startup.leaderboard.get_all_items', + 'Supplier': 'erpnext.startup.leaderboard.get_all_suppliers', + 'Sales Partner': 'erpnext.startup.leaderboard.get_all_sales_partner', + 'Sales Person': 'erpnext.startup.leaderboard.get_all_sales_person', + } + + return leaderboards + +def get_all_customers(from_date, company, field): + if field == "outstanding_amount": + return frappe.db.sql(""" + select customer as name, sum(outstanding_amount) as value + FROM `tabSales Invoice` + where docstatus = 1 and posting_date >= %s and company = %s + group by customer + order by value DESC + limit 20 + """, (from_date, company), as_dict=1) + else: + if field == "total_sales_amount": + select_field = "sum(so_item.base_net_amount)" + elif field == "total_qty_sold": + select_field = "sum(so_item.stock_qty)" + + return frappe.db.sql(""" + select so.customer as name, {0} as value + FROM `tabSales Order` as so JOIN `tabSales Order Item` as so_item + ON so.name = so_item.parent + where so.docstatus = 1 and so.transaction_date >= %s and so.company = %s + group by so.customer + order by value DESC + limit 20 + """.format(select_field), (from_date, company), as_dict=1) + +def get_all_items(from_date, company, field): + if field in ("available_stock_qty", "available_stock_value"): + return frappe.db.sql(""" + select item_code as name, {0} as value + from tabBin + group by item_code + order by value desc + limit 20 + """.format("sum(actual_qty)" if field=="available_stock_qty" else "sum(stock_value)"), as_dict=1) + else: + if field == "total_sales_amount": + select_field = "sum(order_item.base_net_amount)" + select_doctype = "Sales Order" + elif field == "total_purchase_amount": + select_field = "sum(order_item.base_net_amount)" + select_doctype = "Purchase Order" + elif field == "total_qty_sold": + select_field = "sum(order_item.stock_qty)" + select_doctype = "Sales Order" + elif field == "total_qty_purchased": + select_field = "sum(order_item.stock_qty)" + select_doctype = "Purchase Order" + + return frappe.db.sql(""" + select order_item.item_code as name, {0} as value + from `tab{1}` sales_order join `tab{1} Item` as order_item + on sales_order.name = order_item.parent + where sales_order.docstatus = 1 + and sales_order.company = %s and sales_order.transaction_date >= %s + group by order_item.item_code + order by value desc + limit 20 + """.format(select_field, select_doctype), (company, from_date), as_dict=1) + +def get_all_suppliers(from_date, company, field): + if field == "outstanding_amount": + return frappe.db.sql(""" + select supplier as name, sum(outstanding_amount) as value + FROM `tabPurchase Invoice` + where docstatus = 1 and posting_date >= %s and company = %s + group by supplier + order by value DESC + limit 20""", (from_date, company), as_dict=1) + else: + if field == "total_purchase_amount": + select_field = "sum(purchase_order_item.base_net_amount)" + elif field == "total_qty_purchased": + select_field = "sum(purchase_order_item.stock_qty)" + + return frappe.db.sql(""" + select purchase_order.supplier as name, {0} as value + FROM `tabPurchase Order` as purchase_order LEFT JOIN `tabPurchase Order Item` + as purchase_order_item ON purchase_order.name = purchase_order_item.parent + where purchase_order.docstatus = 1 and purchase_order.modified >= %s + and purchase_order.company = %s + group by purchase_order.supplier + order by value DESC + limit 20""".format(select_field), (from_date, company), as_dict=1) + +def get_all_sales_partner(from_date, company, field): + if field == "total_sales_amount": + select_field = "sum(base_net_total)" + elif field == "total_commission": + select_field = "sum(total_commission)" + + return frappe.db.sql(""" + select sales_partner as name, {0} as value + from `tabSales Order` + where ifnull(sales_partner, '') != '' and docstatus = 1 + and transaction_date >= %s and company = %s + group by sales_partner + order by value DESC + limit 20 + """.format(select_field), (from_date, company), as_dict=1) + +def get_all_sales_person(from_date, company, field = None): + return frappe.db.sql(""" + select sales_team.sales_person as name, sum(sales_order.base_net_total) as value + from `tabSales Order` as sales_order join `tabSales Team` as sales_team + on sales_order.name = sales_team.parent and sales_team.parenttype = 'Sales Order' + where sales_order.docstatus = 1 + and sales_order.transaction_date >= %s + and sales_order.company = %s + group by sales_team.sales_person + order by value DESC + limit 20 + """, (from_date, company), as_dict=1) From d095acdad5b17923b3bf807327d815e8b7f8ca08 Mon Sep 17 00:00:00 2001 From: prssanna Date: Thu, 26 Sep 2019 13:41:24 +0530 Subject: [PATCH 03/32] fix: use orm for queries --- erpnext/startup/leaderboard.py | 103 ++++++++++++++++++++------------- 1 file changed, 62 insertions(+), 41 deletions(-) diff --git a/erpnext/startup/leaderboard.py b/erpnext/startup/leaderboard.py index a5549b8748..711d0098ed 100644 --- a/erpnext/startup/leaderboard.py +++ b/erpnext/startup/leaderboard.py @@ -4,25 +4,43 @@ import frappe def get_leaderboards(): leaderboards = { - 'Customer': 'erpnext.startup.leaderboard.get_all_customers', - 'Item': 'erpnext.startup.leaderboard.get_all_items', - 'Supplier': 'erpnext.startup.leaderboard.get_all_suppliers', - 'Sales Partner': 'erpnext.startup.leaderboard.get_all_sales_partner', - 'Sales Person': 'erpnext.startup.leaderboard.get_all_sales_person', + "Customer": { + "fields": ['total_sales_amount', 'total_qty_sold', 'outstanding_amount'], + "method": "erpnext.startup.leaderboard.get_all_customers", + }, + "Item": { + "fields": ["total_sales_amount", "total_qty_sold", "total_purchase_amount", + "total_qty_purchased", "available_stock_qty", "available_stock_value"], + "method": "erpnext.startup.leaderboard.get_all_items", + }, + "Supplier": { + "fields": ["total_purchase_amount", "total_qty_purchased", "outstanding_amount"], + "method": "erpnext.startup.leaderboard.get_all_suppliers", + }, + "Sales Partner": { + "fields": ["total_sales_amount", "total_commission"], + "method": "erpnext.startup.leaderboard.get_all_sales_partner", + }, + "Sales Person": { + "fields": ["total_sales_amount"], + "method": "erpnext.startup.leaderboard.get_all_sales_person", + } } return leaderboards -def get_all_customers(from_date, company, field): +def get_all_customers(from_date, company, field, limit = None): if field == "outstanding_amount": - return frappe.db.sql(""" - select customer as name, sum(outstanding_amount) as value - FROM `tabSales Invoice` - where docstatus = 1 and posting_date >= %s and company = %s - group by customer - order by value DESC - limit 20 - """, (from_date, company), as_dict=1) + filters = [['docstatus', '=', '1'], ['company', '=', company]] + if from_date: + filters.append(['posting_date', '>=', from_date]) + return frappe.db.get_all('Sales Invoice', + fields = ['customer as name', 'sum(outstanding_amount) as value'], + filters = filters, + group_by = 'customer', + order_by = 'value desc', + limit = limit + ) else: if field == "total_sales_amount": select_field = "sum(so_item.base_net_amount)" @@ -36,18 +54,18 @@ def get_all_customers(from_date, company, field): where so.docstatus = 1 and so.transaction_date >= %s and so.company = %s group by so.customer order by value DESC - limit 20 - """.format(select_field), (from_date, company), as_dict=1) + limit %s + """.format(select_field), (from_date, company, limit), as_dict=1) -def get_all_items(from_date, company, field): +def get_all_items(from_date, company, field, limit = None): if field in ("available_stock_qty", "available_stock_value"): - return frappe.db.sql(""" - select item_code as name, {0} as value - from tabBin - group by item_code - order by value desc - limit 20 - """.format("sum(actual_qty)" if field=="available_stock_qty" else "sum(stock_value)"), as_dict=1) + select_field = "sum(actual_qty)" if field=="available_stock_qty" else "sum(stock_value)" + return frappe.db.get_all('Bin', + fields = ['item_code as name', '{0} as value'.format(select_field)], + group_by = 'item_code', + order_by = 'value desc', + limit = limit + ) else: if field == "total_sales_amount": select_field = "sum(order_item.base_net_amount)" @@ -70,18 +88,21 @@ def get_all_items(from_date, company, field): and sales_order.company = %s and sales_order.transaction_date >= %s group by order_item.item_code order by value desc - limit 20 - """.format(select_field, select_doctype), (company, from_date), as_dict=1) + limit %s + """.format(select_field, select_doctype), (company, from_date, limit), as_dict=1) -def get_all_suppliers(from_date, company, field): +def get_all_suppliers(from_date, company, field, limit = None): if field == "outstanding_amount": - return frappe.db.sql(""" - select supplier as name, sum(outstanding_amount) as value - FROM `tabPurchase Invoice` - where docstatus = 1 and posting_date >= %s and company = %s - group by supplier - order by value DESC - limit 20""", (from_date, company), as_dict=1) + filters = [['docstatus', '=', '1'], ['company', '=', company]] + if from_date: + filters.append(['posting_date', '>=', from_date]) + return frappe.db.get_all('Purchase Invoice', + fields = ['supplier as name', 'sum(outstanding_amount) as value'], + filters = filters, + group_by = 'supplier', + order_by = 'value desc', + limit = limit + ) else: if field == "total_purchase_amount": select_field = "sum(purchase_order_item.base_net_amount)" @@ -96,9 +117,9 @@ def get_all_suppliers(from_date, company, field): and purchase_order.company = %s group by purchase_order.supplier order by value DESC - limit 20""".format(select_field), (from_date, company), as_dict=1) + limit %s""".format(select_field), (from_date, company, limit), as_dict=1) -def get_all_sales_partner(from_date, company, field): +def get_all_sales_partner(from_date, company, field, limit = None): if field == "total_sales_amount": select_field = "sum(base_net_total)" elif field == "total_commission": @@ -111,10 +132,10 @@ def get_all_sales_partner(from_date, company, field): and transaction_date >= %s and company = %s group by sales_partner order by value DESC - limit 20 - """.format(select_field), (from_date, company), as_dict=1) + limit %s + """.format(select_field), (from_date, company, limit), as_dict=1) -def get_all_sales_person(from_date, company, field = None): +def get_all_sales_person(from_date, company, field = None, limit = None): return frappe.db.sql(""" select sales_team.sales_person as name, sum(sales_order.base_net_total) as value from `tabSales Order` as sales_order join `tabSales Team` as sales_team @@ -124,5 +145,5 @@ def get_all_sales_person(from_date, company, field = None): and sales_order.company = %s group by sales_team.sales_person order by value DESC - limit 20 - """, (from_date, company), as_dict=1) + limit %s + """, (from_date, company, limit), as_dict=1) From 8f7ed71e9eeea046feef714f0c88dab3ba13a431 Mon Sep 17 00:00:00 2001 From: prssanna Date: Fri, 27 Sep 2019 15:09:40 +0530 Subject: [PATCH 04/32] fix: add df to leaderboard config --- erpnext/startup/leaderboard.py | 31 +++++++++++++++++++++++++------ 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/erpnext/startup/leaderboard.py b/erpnext/startup/leaderboard.py index 711d0098ed..b3e4b99cbe 100644 --- a/erpnext/startup/leaderboard.py +++ b/erpnext/startup/leaderboard.py @@ -5,24 +5,43 @@ import frappe def get_leaderboards(): leaderboards = { "Customer": { - "fields": ['total_sales_amount', 'total_qty_sold', 'outstanding_amount'], + "fields": [ + {'fieldname': 'total_sales_amount', 'fieldtype': 'Currency'}, + 'total_qty_sold', + {'fieldname': 'outstanding_amount', 'fieldtype': 'Currency'} + ], "method": "erpnext.startup.leaderboard.get_all_customers", }, "Item": { - "fields": ["total_sales_amount", "total_qty_sold", "total_purchase_amount", - "total_qty_purchased", "available_stock_qty", "available_stock_value"], + "fields": [ + {'fieldname': 'total_sales_amount', 'fieldtype': 'Currency'}, + 'total_qty_sold' + {'fieldname': 'total_purchase_amount', 'fieldtype': 'Currency'}, + 'total_qty_purchased', + 'available_stock_qty', + {'fieldname': 'available_stock_value', 'fieldtype': 'Currency'} + ], "method": "erpnext.startup.leaderboard.get_all_items", }, "Supplier": { - "fields": ["total_purchase_amount", "total_qty_purchased", "outstanding_amount"], + "fields": [ + {'fieldname': 'total_purchase_amount', 'fieldtype': 'Currency'}, + 'total_qty_purchased', + {'fieldname': 'outstanding_amount', 'fieldtype': 'Currency'} + ], "method": "erpnext.startup.leaderboard.get_all_suppliers", }, "Sales Partner": { - "fields": ["total_sales_amount", "total_commission"], + "fields": [ + {'fieldname': 'total_sales_amount', 'fieldtype': 'Currency'}, + {'fieldname': 'total_commission', 'fieldtype': 'Currency'} + ], "method": "erpnext.startup.leaderboard.get_all_sales_partner", }, "Sales Person": { - "fields": ["total_sales_amount"], + "fields": [ + {'fieldname': 'total_sales_amount', 'fieldtype': 'Currency'} + ], "method": "erpnext.startup.leaderboard.get_all_sales_person", } } From 119c976ad143110fd0fa65916de03b14d21481fd Mon Sep 17 00:00:00 2001 From: prssanna Date: Fri, 27 Sep 2019 16:28:08 +0530 Subject: [PATCH 05/32] fix: missing comma --- erpnext/startup/leaderboard.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/startup/leaderboard.py b/erpnext/startup/leaderboard.py index b3e4b99cbe..6d9b77ed24 100644 --- a/erpnext/startup/leaderboard.py +++ b/erpnext/startup/leaderboard.py @@ -15,7 +15,7 @@ def get_leaderboards(): "Item": { "fields": [ {'fieldname': 'total_sales_amount', 'fieldtype': 'Currency'}, - 'total_qty_sold' + 'total_qty_sold', {'fieldname': 'total_purchase_amount', 'fieldtype': 'Currency'}, 'total_qty_purchased', 'available_stock_qty', From b8749224040d96f1f6e8ed0d1a6e10bc2789b81c Mon Sep 17 00:00:00 2001 From: prssanna Date: Mon, 30 Sep 2019 11:12:10 +0530 Subject: [PATCH 06/32] fix: whitelist leaderboard functions --- erpnext/startup/leaderboard.py | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/erpnext/startup/leaderboard.py b/erpnext/startup/leaderboard.py index 6d9b77ed24..00b761bea6 100644 --- a/erpnext/startup/leaderboard.py +++ b/erpnext/startup/leaderboard.py @@ -48,6 +48,7 @@ def get_leaderboards(): return leaderboards +@frappe.whitelist() def get_all_customers(from_date, company, field, limit = None): if field == "outstanding_amount": filters = [['docstatus', '=', '1'], ['company', '=', company]] @@ -73,9 +74,10 @@ def get_all_customers(from_date, company, field, limit = None): where so.docstatus = 1 and so.transaction_date >= %s and so.company = %s group by so.customer order by value DESC - limit %s - """.format(select_field), (from_date, company, limit), as_dict=1) + limit {1} + """.format(select_field, limit), (from_date, company), as_dict=1) +@frappe.whitelist() def get_all_items(from_date, company, field, limit = None): if field in ("available_stock_qty", "available_stock_value"): select_field = "sum(actual_qty)" if field=="available_stock_qty" else "sum(stock_value)" @@ -107,9 +109,10 @@ def get_all_items(from_date, company, field, limit = None): and sales_order.company = %s and sales_order.transaction_date >= %s group by order_item.item_code order by value desc - limit %s - """.format(select_field, select_doctype), (company, from_date, limit), as_dict=1) + limit {2} + """.format(select_field, select_doctype, limit), (company, from_date), as_dict=1) +@frappe.whitelist() def get_all_suppliers(from_date, company, field, limit = None): if field == "outstanding_amount": filters = [['docstatus', '=', '1'], ['company', '=', company]] @@ -136,8 +139,9 @@ def get_all_suppliers(from_date, company, field, limit = None): and purchase_order.company = %s group by purchase_order.supplier order by value DESC - limit %s""".format(select_field), (from_date, company, limit), as_dict=1) + limit {1}""".format(select_field, limit), (from_date, company), as_dict=1) +@frappe.whitelist() def get_all_sales_partner(from_date, company, field, limit = None): if field == "total_sales_amount": select_field = "sum(base_net_total)" @@ -151,9 +155,10 @@ def get_all_sales_partner(from_date, company, field, limit = None): and transaction_date >= %s and company = %s group by sales_partner order by value DESC - limit %s - """.format(select_field), (from_date, company, limit), as_dict=1) + limit {1} + """.format(select_field, limit), (from_date, company), as_dict=1) +@frappe.whitelist() def get_all_sales_person(from_date, company, field = None, limit = None): return frappe.db.sql(""" select sales_team.sales_person as name, sum(sales_order.base_net_total) as value @@ -164,5 +169,5 @@ def get_all_sales_person(from_date, company, field = None, limit = None): and sales_order.company = %s group by sales_team.sales_person order by value DESC - limit %s - """, (from_date, company, limit), as_dict=1) + limit {0} + """.format(limit), (from_date, company), as_dict=1) From d23c9987ed21fbbaea5a533016d8129ac0036ee2 Mon Sep 17 00:00:00 2001 From: Suraj Shetty Date: Mon, 30 Sep 2019 13:09:12 +0530 Subject: [PATCH 07/32] style: Fix Codacy --- erpnext/startup/leaderboard.py | 42 +++++++++++++++++++--------------- 1 file changed, 23 insertions(+), 19 deletions(-) diff --git a/erpnext/startup/leaderboard.py b/erpnext/startup/leaderboard.py index 00b761bea6..90ecd46259 100644 --- a/erpnext/startup/leaderboard.py +++ b/erpnext/startup/leaderboard.py @@ -1,6 +1,7 @@ from __future__ import unicode_literals, print_function import frappe +from frappe.utils import cint def get_leaderboards(): leaderboards = { @@ -74,8 +75,8 @@ def get_all_customers(from_date, company, field, limit = None): where so.docstatus = 1 and so.transaction_date >= %s and so.company = %s group by so.customer order by value DESC - limit {1} - """.format(select_field, limit), (from_date, company), as_dict=1) + limit %s + """.format(select_field), (from_date, company, cint(limit)), as_dict=1) #nosec @frappe.whitelist() def get_all_items(from_date, company, field, limit = None): @@ -109,8 +110,8 @@ def get_all_items(from_date, company, field, limit = None): and sales_order.company = %s and sales_order.transaction_date >= %s group by order_item.item_code order by value desc - limit {2} - """.format(select_field, select_doctype, limit), (company, from_date), as_dict=1) + limit %s + """.format(select_field, select_doctype), (company, from_date, cint(limit)), as_dict=1) #nosec @frappe.whitelist() def get_all_suppliers(from_date, company, field, limit = None): @@ -139,27 +140,30 @@ def get_all_suppliers(from_date, company, field, limit = None): and purchase_order.company = %s group by purchase_order.supplier order by value DESC - limit {1}""".format(select_field, limit), (from_date, company), as_dict=1) + limit %s""".format(select_field), (from_date, company, cint(limit)), as_dict=1) #nosec @frappe.whitelist() def get_all_sales_partner(from_date, company, field, limit = None): if field == "total_sales_amount": - select_field = "sum(base_net_total)" + select_field = "sum(`base_net_total`)" elif field == "total_commission": - select_field = "sum(total_commission)" + select_field = "sum(`total_commission`)" - return frappe.db.sql(""" - select sales_partner as name, {0} as value - from `tabSales Order` - where ifnull(sales_partner, '') != '' and docstatus = 1 - and transaction_date >= %s and company = %s - group by sales_partner - order by value DESC - limit {1} - """.format(select_field, limit), (from_date, company), as_dict=1) + filters = { + 'sales_partner': ['!=', ''], + 'docstatus': 1, + 'company': company + } + if from_date: + filters['transaction_date'] = ['>=', from_date] + + return frappe.get_list('Sales Order', fields=[ + '`sales_partner` as name', + '{} as value'.format(select_field), + ], filters=filters, group_by='sales_partner', order_by='value DESC', limit=limit) @frappe.whitelist() -def get_all_sales_person(from_date, company, field = None, limit = None): +def get_all_sales_person(from_date, company, field = None, limit = 0): return frappe.db.sql(""" select sales_team.sales_person as name, sum(sales_order.base_net_total) as value from `tabSales Order` as sales_order join `tabSales Team` as sales_team @@ -169,5 +173,5 @@ def get_all_sales_person(from_date, company, field = None, limit = None): and sales_order.company = %s group by sales_team.sales_person order by value DESC - limit {0} - """.format(limit), (from_date, company), as_dict=1) + limit %s + """, (from_date, company, cint(limit)), as_dict=1) From 46831c4c20be2cc66fe30943a0055e8657ea3e67 Mon Sep 17 00:00:00 2001 From: Himanshu Warekar Date: Mon, 30 Sep 2019 14:34:56 +0530 Subject: [PATCH 08/32] fix: show mobile no --- erpnext/public/js/templates/contact_list.html | 3 +++ 1 file changed, 3 insertions(+) diff --git a/erpnext/public/js/templates/contact_list.html b/erpnext/public/js/templates/contact_list.html index 50fbfd9f12..7e6969163b 100644 --- a/erpnext/public/js/templates/contact_list.html +++ b/erpnext/public/js/templates/contact_list.html @@ -19,6 +19,9 @@ {% if(contact_list[i].phone) { %} {%= __("Phone") %}: {%= contact_list[i].phone %} ({%= __("Primary") %})
    {% endif %} + {% if(contact_list[i].mobile_no) { %} + {%= __("Mobile No") %}: {%= contact_list[i].mobile_no %} ({%= __("Primary") %})
    + {% endif %} {% if(contact_list[i].phone_nos) { %} {% for(var j=0, k=contact_list[i].phone_nos.length; j From d8763d7d6518ff95b099b950aaaadd1ed1d12759 Mon Sep 17 00:00:00 2001 From: Mangesh-Khairnar Date: Mon, 30 Sep 2019 14:39:46 +0530 Subject: [PATCH 09/32] fix: allow rename/merge in opportunity (#19202) --- erpnext/crm/doctype/opportunity/opportunity.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/erpnext/crm/doctype/opportunity/opportunity.json b/erpnext/crm/doctype/opportunity/opportunity.json index 37f492ede6..66e3ca48dd 100644 --- a/erpnext/crm/doctype/opportunity/opportunity.json +++ b/erpnext/crm/doctype/opportunity/opportunity.json @@ -1,5 +1,6 @@ { "allow_import": 1, + "allow_rename": 1, "autoname": "naming_series:", "creation": "2013-03-07 18:50:30", "description": "Potential Sales Deal", @@ -411,7 +412,7 @@ ], "icon": "fa fa-info-sign", "idx": 195, - "modified": "2019-09-12 09:37:30.127901", + "modified": "2019-09-30 12:58:37.385400", "modified_by": "Administrator", "module": "CRM", "name": "Opportunity", From 7d6f52f4abb3e97f717beb9f4bdeafe27e42bf7a Mon Sep 17 00:00:00 2001 From: Himanshu Date: Mon, 30 Sep 2019 14:40:56 +0530 Subject: [PATCH 10/32] fix: add system user perm in patient (#19133) --- erpnext/healthcare/doctype/patient/patient.json | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/erpnext/healthcare/doctype/patient/patient.json b/erpnext/healthcare/doctype/patient/patient.json index 1de4205ec2..0136f72f5b 100644 --- a/erpnext/healthcare/doctype/patient/patient.json +++ b/erpnext/healthcare/doctype/patient/patient.json @@ -347,13 +347,25 @@ "icon": "fa fa-user", "image_field": "image", "max_attachments": 50, - "modified": "2019-09-23 16:01:39.811633", + "modified": "2019-09-25 23:30:49.905893", "modified_by": "Administrator", "module": "Healthcare", "name": "Patient", "name_case": "Title Case", "owner": "Administrator", "permissions": [ + { + "create": 1, + "delete": 1, + "email": 1, + "export": 1, + "print": 1, + "read": 1, + "report": 1, + "role": "System Manager", + "share": 1, + "write": 1 + }, { "create": 1, "delete": 1, From 201bcaf2ca5106720e556a6a0e949083bd5de2e5 Mon Sep 17 00:00:00 2001 From: Himanshu Date: Mon, 30 Sep 2019 14:56:08 +0530 Subject: [PATCH 11/32] fix(Company): Do not set default account if left blank (#19131) * chore: use dict to set_default_account * fix: dont override expense account if left empty * fix: set accounts only if new company * chore: fix alignment * fix: test cases --- erpnext/setup/doctype/company/company.py | 54 ++++++++++++++---------- 1 file changed, 32 insertions(+), 22 deletions(-) diff --git a/erpnext/setup/doctype/company/company.py b/erpnext/setup/doctype/company/company.py index 584391e1e0..9eb374824a 100644 --- a/erpnext/setup/doctype/company/company.py +++ b/erpnext/setup/doctype/company/company.py @@ -64,16 +64,19 @@ class Company(NestedSet): }) def validate_default_accounts(self): - for field in ["default_bank_account", "default_cash_account", + accounts = [ + "default_bank_account", "default_cash_account", "default_receivable_account", "default_payable_account", "default_expense_account", "default_income_account", "stock_received_but_not_billed", "stock_adjustment_account", - "expenses_included_in_valuation", "default_payroll_payable_account"]: - if self.get(field): - for_company = frappe.db.get_value("Account", self.get(field), "company") - if for_company != self.name: - frappe.throw(_("Account {0} does not belong to company: {1}") - .format(self.get(field), self.name)) + "expenses_included_in_valuation", "default_payroll_payable_account" + ] + + for field in accounts: + if self.get(field): + for_company = frappe.db.get_value("Account", self.get(field), "company") + if for_company != self.name: + frappe.throw(_("Account {0} does not belong to company: {1}").format(self.get(field), self.name)) def validate_currency(self): if self.is_new(): @@ -180,21 +183,29 @@ class Company(NestedSet): self.existing_company = self.parent_company def set_default_accounts(self): - self._set_default_account("default_cash_account", "Cash") - self._set_default_account("default_bank_account", "Bank") - self._set_default_account("round_off_account", "Round Off") - self._set_default_account("accumulated_depreciation_account", "Accumulated Depreciation") - self._set_default_account("depreciation_expense_account", "Depreciation") - self._set_default_account("capital_work_in_progress_account", "Capital Work in Progress") - self._set_default_account("asset_received_but_not_billed", "Asset Received But Not Billed") - self._set_default_account("expenses_included_in_asset_valuation", "Expenses Included In Asset Valuation") + default_accounts = { + "default_cash_account": "Cash", + "default_bank_account": "Bank", + "round_off_account": "Round Off", + "accumulated_depreciation_account": "Accumulated Depreciation", + "depreciation_expense_account": "Depreciation", + "capital_work_in_progress_account": "Capital Work in Progress", + "asset_received_but_not_billed": "Asset Received But Not Billed", + "expenses_included_in_asset_valuation": "Expenses Included In Asset Valuation" + } if self.enable_perpetual_inventory: - self._set_default_account("stock_received_but_not_billed", "Stock Received But Not Billed") - self._set_default_account("default_inventory_account", "Stock") - self._set_default_account("stock_adjustment_account", "Stock Adjustment") - self._set_default_account("expenses_included_in_valuation", "Expenses Included In Valuation") - self._set_default_account("default_expense_account", "Cost of Goods Sold") + default_accounts.update({ + "stock_received_but_not_billed": "Stock Received But Not Billed", + "default_inventory_account": "Stock", + "stock_adjustment_account": "Stock Adjustment", + "expenses_included_in_valuation": "Expenses Included In Valuation", + "default_expense_account": "Cost of Goods Sold" + }) + + for default_account in default_accounts: + if self.is_new() or frappe.flags.in_test: + self._set_default_account(default_account, default_accounts.get(default_account)) if not self.default_income_account: income_account = frappe.db.get_value("Account", @@ -243,8 +254,7 @@ class Company(NestedSet): if self.get(fieldname): return - account = frappe.db.get_value("Account", {"account_type": account_type, - "is_group": 0, "company": self.name}) + account = frappe.db.get_value("Account", {"account_type": account_type, "is_group": 0, "company": self.name}) if account: self.db_set(fieldname, account) From f380b215b242384e32308a22ccabbdc45c22ea48 Mon Sep 17 00:00:00 2001 From: prssanna Date: Fri, 13 Sep 2019 12:26:05 +0530 Subject: [PATCH 12/32] fix: shopify integration --- .../shopify_settings/shopify_settings.json | 1447 +++-------------- .../shopify_settings/shopify_settings.py | 21 +- 2 files changed, 244 insertions(+), 1224 deletions(-) diff --git a/erpnext/erpnext_integrations/doctype/shopify_settings/shopify_settings.json b/erpnext/erpnext_integrations/doctype/shopify_settings/shopify_settings.json index a7040f2f27..de745a56ba 100644 --- a/erpnext/erpnext_integrations/doctype/shopify_settings/shopify_settings.json +++ b/erpnext/erpnext_integrations/doctype/shopify_settings/shopify_settings.json @@ -1,1258 +1,281 @@ { - "allow_copy": 0, - "allow_guest_to_view": 0, - "allow_import": 0, - "allow_rename": 0, - "beta": 0, - "creation": "2015-05-18 05:21:07.270859", - "custom": 0, - "docstatus": 0, - "doctype": "DocType", - "document_type": "System", - "editable_grid": 0, + "creation": "2015-05-18 05:21:07.270859", + "doctype": "DocType", + "document_type": "System", + "field_order": [ + "status_html", + "enable_shopify", + "app_type", + "column_break_4", + "last_sync_datetime", + "section_break_2", + "shopify_url", + "api_key", + "column_break_3", + "password", + "shared_secret", + "access_token", + "section_break_38", + "webhooks", + "section_break_15", + "default_customer", + "column_break_19", + "customer_group", + "company_dependent_settings", + "company", + "cash_bank_account", + "column_break_20", + "cost_center", + "erp_settings", + "price_list", + "update_price_in_erpnext_price_list", + "column_break_26", + "warehouse", + "section_break_25", + "sales_order_series", + "column_break_27", + "sync_delivery_note", + "delivery_note_series", + "sync_sales_invoice", + "sales_invoice_series", + "section_break_22", + "html_16", + "taxes" + ], "fields": [ { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "status_html", - "fieldtype": "HTML", - "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": "status html", - "length": 0, - "no_copy": 0, - "options": "", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 1, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, + "fieldname": "status_html", + "fieldtype": "HTML", + "label": "status html", + "read_only": 1 + }, { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "default": "", - "fieldname": "enable_shopify", - "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": "Enable Shopify", - "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": "enable_shopify", + "fieldtype": "Check", + "label": "Enable Shopify" + }, { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "default": "Public", - "fieldname": "app_type", - "fieldtype": "Select", - "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": "App Type", - "length": 0, - "no_copy": 0, - "options": "Public\nPrivate", - "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 - }, + "default": "Public", + "fieldname": "app_type", + "fieldtype": "Data", + "in_list_view": 1, + "label": "App Type", + "options": "Private", + "read_only": 1, + "reqd": 1 + }, { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "column_break_4", - "fieldtype": "Column Break", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, + "fieldname": "column_break_4", + "fieldtype": "Column Break" + }, { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "last_sync_datetime", - "fieldtype": "Datetime", - "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": "Last Sync Datetime", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 1, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, + "fieldname": "last_sync_datetime", + "fieldtype": "Datetime", + "label": "Last Sync Datetime", + "read_only": 1 + }, { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "section_break_2", - "fieldtype": "Section Break", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, + "fieldname": "section_break_2", + "fieldtype": "Section Break" + }, { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "description": "eg: frappe.myshopify.com", - "fieldname": "shopify_url", - "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": "Shop URL", - "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 - }, + "description": "eg: frappe.myshopify.com", + "fieldname": "shopify_url", + "fieldtype": "Data", + "in_list_view": 1, + "label": "Shop URL", + "reqd": 1 + }, { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "depends_on": "eval:doc.app_type==\"Private\"", - "fieldname": "api_key", - "fieldtype": "Data", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "API Key", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, + "depends_on": "eval:doc.app_type==\"Private\"", + "fieldname": "api_key", + "fieldtype": "Data", + "label": "API Key" + }, { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "column_break_3", - "fieldtype": "Column Break", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, + "fieldname": "column_break_3", + "fieldtype": "Column Break" + }, { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "depends_on": "eval:doc.app_type==\"Private\"", - "fieldname": "password", - "fieldtype": "Password", - "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": "Password", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, + "depends_on": "eval:doc.app_type==\"Private\"", + "fieldname": "password", + "fieldtype": "Password", + "label": "Password" + }, { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "shared_secret", - "fieldtype": "Data", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Shared secret", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, + "fieldname": "shared_secret", + "fieldtype": "Data", + "label": "Shared secret" + }, { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "access_token", - "fieldtype": "Data", - "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": "Access Token", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 1, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, + "fieldname": "access_token", + "fieldtype": "Data", + "hidden": 1, + "label": "Access Token", + "read_only": 1 + }, { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 1, - "columns": 0, - "fieldname": "section_break_38", - "fieldtype": "Section Break", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Webhooks Details", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, + "collapsible": 1, + "fieldname": "section_break_38", + "fieldtype": "Section Break", + "label": "Webhooks Details" + }, { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "webhooks", - "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": "Webhooks", - "length": 0, - "no_copy": 0, - "options": "Shopify Webhook Detail", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 1, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, + "fieldname": "webhooks", + "fieldtype": "Table", + "label": "Webhooks", + "options": "Shopify Webhook Detail", + "read_only": 1 + }, { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "section_break_15", - "fieldtype": "Section Break", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Customer Settings", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, + "fieldname": "section_break_15", + "fieldtype": "Section Break", + "label": "Customer Settings" + }, { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "description": "If Shopify not contains a customer in Order, then while syncing Orders, the system will consider default customer for order", - "fieldname": "default_customer", - "fieldtype": "Link", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Default Customer", - "length": 0, - "no_copy": 0, - "options": "Customer", - "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 - }, + "description": "If Shopify not contains a customer in Order, then while syncing Orders, the system will consider default customer for order", + "fieldname": "default_customer", + "fieldtype": "Link", + "label": "Default Customer", + "options": "Customer" + }, { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "column_break_19", - "fieldtype": "Column Break", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, + "fieldname": "column_break_19", + "fieldtype": "Column Break" + }, { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "default": "", - "description": "Customer Group will set to selected group while syncing customers from Shopify", - "fieldname": "customer_group", - "fieldtype": "Link", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Customer Group", - "length": 0, - "no_copy": 0, - "options": "Customer Group", - "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 - }, + "description": "Customer Group will set to selected group while syncing customers from Shopify", + "fieldname": "customer_group", + "fieldtype": "Link", + "label": "Customer Group", + "options": "Customer Group" + }, { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "company_dependent_settings", - "fieldtype": "Section Break", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, + "fieldname": "company_dependent_settings", + "fieldtype": "Section Break" + }, { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "company", - "fieldtype": "Link", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "For Company", - "length": 0, - "no_copy": 0, - "options": "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": "company", + "fieldtype": "Link", + "label": "For Company", + "options": "Company" + }, { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "description": "Cash Account will used for Sales Invoice creation", - "fieldname": "cash_bank_account", - "fieldtype": "Link", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Cash/Bank Account", - "length": 0, - "no_copy": 0, - "options": "Account", - "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 - }, + "description": "Cash Account will used for Sales Invoice creation", + "fieldname": "cash_bank_account", + "fieldtype": "Link", + "label": "Cash/Bank Account", + "options": "Account" + }, { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "column_break_20", - "fieldtype": "Column Break", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, + "fieldname": "column_break_20", + "fieldtype": "Column Break" + }, { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "cost_center", - "fieldtype": "Link", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Cost Center", - "length": 0, - "no_copy": 0, - "options": "Cost Center", - "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": "cost_center", + "fieldtype": "Link", + "label": "Cost Center", + "options": "Cost Center" + }, { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "erp_settings", - "fieldtype": "Section Break", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, + "fieldname": "erp_settings", + "fieldtype": "Section Break" + }, { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "description": "", - "fieldname": "price_list", - "fieldtype": "Link", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Price List", - "length": 0, - "no_copy": 0, - "options": "Price List", - "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": "price_list", + "fieldtype": "Link", + "label": "Price List", + "options": "Price List" + }, { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "update_price_in_erpnext_price_list", - "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": "Update Price from Shopify To ERPNext Price List", - "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": "update_price_in_erpnext_price_list", + "fieldtype": "Check", + "label": "Update Price from Shopify To ERPNext Price List" + }, { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "column_break_26", - "fieldtype": "Column Break", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, + "fieldname": "column_break_26", + "fieldtype": "Column Break" + }, { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "default": "", - "depends_on": "", - "description": "Default Warehouse to to create Sales Order and Delivery Note", - "fieldname": "warehouse", - "fieldtype": "Link", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Warehouse", - "length": 0, - "no_copy": 0, - "options": "Warehouse", - "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 - }, + "description": "Default Warehouse to to create Sales Order and Delivery Note", + "fieldname": "warehouse", + "fieldtype": "Link", + "label": "Warehouse", + "options": "Warehouse" + }, { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "section_break_25", - "fieldtype": "Section Break", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, + "fieldname": "section_break_25", + "fieldtype": "Section Break" + }, { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "sales_order_series", - "fieldtype": "Select", - "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": "Sales Order Series", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, + "fieldname": "sales_order_series", + "fieldtype": "Select", + "label": "Sales Order Series" + }, { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "column_break_27", - "fieldtype": "Column Break", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, + "fieldname": "column_break_27", + "fieldtype": "Column Break" + }, { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "description": "", - "fieldname": "sync_delivery_note", - "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": "Import Delivery Notes from Shopify on Shipment", - "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": "sync_delivery_note", + "fieldtype": "Check", + "label": "Import Delivery Notes from Shopify on Shipment" + }, { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "depends_on": "eval:doc.sync_delivery_note==1", - "fieldname": "delivery_note_series", - "fieldtype": "Select", - "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": "Delivery Note Series", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, + "depends_on": "eval:doc.sync_delivery_note==1", + "fieldname": "delivery_note_series", + "fieldtype": "Select", + "label": "Delivery Note Series" + }, { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "description": "", - "fieldname": "sync_sales_invoice", - "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": "Import Sales Invoice from Shopify if Payment is marked", - "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": "sync_sales_invoice", + "fieldtype": "Check", + "label": "Import Sales Invoice from Shopify if Payment is marked" + }, { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "depends_on": "eval:doc.sync_sales_invoice==1", - "fieldname": "sales_invoice_series", - "fieldtype": "Select", - "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": "Sales Invoice Series", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, + "depends_on": "eval:doc.sync_sales_invoice==1", + "fieldname": "sales_invoice_series", + "fieldtype": "Select", + "label": "Sales Invoice Series" + }, { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "section_break_22", - "fieldtype": "Section Break", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, + "fieldname": "section_break_22", + "fieldtype": "Section Break" + }, { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "html_16", - "fieldtype": "HTML", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "length": 0, - "no_copy": 0, - "options": "Map Shopify Taxes / Shipping Charges to ERPNext Account", - "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": "html_16", + "fieldtype": "HTML", + "options": "Map Shopify Taxes / Shipping Charges to ERPNext Account" + }, { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "taxes", - "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": "Shopify Tax Account", - "length": 0, - "no_copy": 0, - "options": "Shopify Tax Account", - "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": "taxes", + "fieldtype": "Table", + "label": "Shopify Tax Account", + "options": "Shopify Tax Account" } - ], - "has_web_view": 0, - "hide_heading": 0, - "hide_toolbar": 0, - "idx": 0, - "image_view": 0, - "in_create": 0, - "is_submittable": 0, - "issingle": 1, - "istable": 0, - "max_attachments": 0, - "modified": "2018-09-07 09:11:49.403176", - "modified_by": "Administrator", - "module": "ERPNext Integrations", - "name": "Shopify Settings", - "name_case": "", - "owner": "Administrator", + ], + "issingle": 1, + "modified": "2019-09-13 12:21:43.957327", + "modified_by": "umair@erpnext.com", + "module": "ERPNext Integrations", + "name": "Shopify Settings", + "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": 0, - "role": "System Manager", - "set_user_permissions": 0, - "share": 1, - "submit": 0, + "create": 1, + "delete": 1, + "email": 1, + "print": 1, + "read": 1, + "role": "System Manager", + "share": 1, "write": 1 } - ], - "quick_entry": 0, - "read_only": 0, - "read_only_onload": 0, - "show_name_in_global_search": 0, - "sort_field": "modified", - "sort_order": "DESC", - "track_changes": 0, - "track_seen": 0, - "track_views": 0 + ], + "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 4943053663..f4656221be 100644 --- a/erpnext/erpnext_integrations/doctype/shopify_settings/shopify_settings.py +++ b/erpnext/erpnext_integrations/doctype/shopify_settings/shopify_settings.py @@ -21,32 +21,26 @@ class ShopifySettings(Document): else: self.unregister_webhooks() - self.validate_app_type() - def validate_access_credentials(self): - if self.app_type == "Private": - if not (self.get_password(raise_exception=False) and self.api_key and self.shopify_url): - frappe.msgprint(_("Missing value for Password, API Key or Shopify URL"), raise_exception=frappe.ValidationError) + if not (self.get_password(raise_exception=False) and self.api_key and self.shopify_url): + frappe.msgprint(_("Missing value for Password, API Key or Shopify URL"), raise_exception=frappe.ValidationError) else: if not (self.access_token and self.shopify_url): frappe.msgprint(_("Access token or Shopify URL missing"), raise_exception=frappe.ValidationError) - def validate_app_type(self): - if self.app_type == "Public": - frappe.throw(_("Support for public app is deprecated. Please setup private app, for more details refer user manual")) - def register_webhooks(self): webhooks = ["orders/create", "orders/paid", "orders/fulfilled"] - - url = get_shopify_url('admin/webhooks.json', self) + # url = get_shopify_url('admin/webhooks.json', self) created_webhooks = [d.method for d in self.webhooks] - + url = get_shopify_url('admin/api/2019-04/webhooks.json', self) + print('url', url) for method in webhooks: if method in created_webhooks: continue session = get_request_session() + print('session', session) try: d = session.post(url, data=json.dumps({ "webhook": { @@ -55,6 +49,7 @@ class ShopifySettings(Document): "format": "json" } }), headers=get_header(self)) + print('d', d.json()) d.raise_for_status() self.update_webhook_table(method, d.json()) except Exception as e: @@ -77,6 +72,7 @@ class ShopifySettings(Document): self.remove(d) def update_webhook_table(self, method, res): + print('update') self.append("webhooks", { "webhook_id": res['webhook']['id'], "method": method @@ -84,6 +80,7 @@ class ShopifySettings(Document): def get_shopify_url(path, settings): if settings.app_type == "Private": + print(settings.api_key, settings.get_password('password'), settings.shopify_url, path) return 'https://{}:{}@{}/{}'.format(settings.api_key, settings.get_password('password'), settings.shopify_url, path) else: return 'https://{}/{}'.format(settings.shopify_url, path) From e64bdcd12b6c07f209182308ec92a816556c06ee Mon Sep 17 00:00:00 2001 From: prssanna Date: Fri, 13 Sep 2019 12:32:42 +0530 Subject: [PATCH 13/32] fix: default private app type --- .../doctype/shopify_settings/shopify_settings.json | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/erpnext/erpnext_integrations/doctype/shopify_settings/shopify_settings.json b/erpnext/erpnext_integrations/doctype/shopify_settings/shopify_settings.json index de745a56ba..8f1b746e5b 100644 --- a/erpnext/erpnext_integrations/doctype/shopify_settings/shopify_settings.json +++ b/erpnext/erpnext_integrations/doctype/shopify_settings/shopify_settings.json @@ -56,12 +56,11 @@ "label": "Enable Shopify" }, { - "default": "Public", + "default": "Private", "fieldname": "app_type", "fieldtype": "Data", "in_list_view": 1, "label": "App Type", - "options": "Private", "read_only": 1, "reqd": 1 }, @@ -259,7 +258,7 @@ } ], "issingle": 1, - "modified": "2019-09-13 12:21:43.957327", + "modified": "2019-09-13 12:32:11.384757", "modified_by": "umair@erpnext.com", "module": "ERPNext Integrations", "name": "Shopify Settings", From a9aac02b9006ff7ca5e51b2aad1c4da838d659ef Mon Sep 17 00:00:00 2001 From: prssanna Date: Fri, 13 Sep 2019 12:32:42 +0530 Subject: [PATCH 14/32] fix: default private app type --- .../doctype/shopify_settings/shopify_settings.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/erpnext/erpnext_integrations/doctype/shopify_settings/shopify_settings.py b/erpnext/erpnext_integrations/doctype/shopify_settings/shopify_settings.py index f4656221be..29ee22abc6 100644 --- a/erpnext/erpnext_integrations/doctype/shopify_settings/shopify_settings.py +++ b/erpnext/erpnext_integrations/doctype/shopify_settings/shopify_settings.py @@ -25,10 +25,6 @@ class ShopifySettings(Document): if not (self.get_password(raise_exception=False) and self.api_key and self.shopify_url): frappe.msgprint(_("Missing value for Password, API Key or Shopify URL"), raise_exception=frappe.ValidationError) - else: - if not (self.access_token and self.shopify_url): - frappe.msgprint(_("Access token or Shopify URL missing"), raise_exception=frappe.ValidationError) - def register_webhooks(self): webhooks = ["orders/create", "orders/paid", "orders/fulfilled"] # url = get_shopify_url('admin/webhooks.json', self) From 09f4e0b19c59fcae18948d4b2a19bd5a0ebbcee6 Mon Sep 17 00:00:00 2001 From: prssanna Date: Fri, 13 Sep 2019 12:32:42 +0530 Subject: [PATCH 15/32] fix: default private app type --- .../doctype/shopify_settings/shopify_settings.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/erpnext_integrations/doctype/shopify_settings/shopify_settings.py b/erpnext/erpnext_integrations/doctype/shopify_settings/shopify_settings.py index 29ee22abc6..2b7fa320c0 100644 --- a/erpnext/erpnext_integrations/doctype/shopify_settings/shopify_settings.py +++ b/erpnext/erpnext_integrations/doctype/shopify_settings/shopify_settings.py @@ -56,7 +56,7 @@ class ShopifySettings(Document): deleted_webhooks = [] for d in self.webhooks: - url = get_shopify_url('admin/webhooks/{0}.json'.format(d.webhook_id), self) + url = get_shopify_url('admin/api/2019-04/webhooks.json'.format(d.webhook_id), self) try: res = session.delete(url, headers=get_header(self)) res.raise_for_status() From c8ad8bb7aac3f114489cd1624efc3b4ab964226b Mon Sep 17 00:00:00 2001 From: prssanna Date: Fri, 13 Sep 2019 12:32:42 +0530 Subject: [PATCH 16/32] fix: default private app type --- .../doctype/shopify_settings/shopify_settings.py | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/erpnext/erpnext_integrations/doctype/shopify_settings/shopify_settings.py b/erpnext/erpnext_integrations/doctype/shopify_settings/shopify_settings.py index 2b7fa320c0..e2f6d497d2 100644 --- a/erpnext/erpnext_integrations/doctype/shopify_settings/shopify_settings.py +++ b/erpnext/erpnext_integrations/doctype/shopify_settings/shopify_settings.py @@ -32,12 +32,11 @@ class ShopifySettings(Document): url = get_shopify_url('admin/api/2019-04/webhooks.json', self) print('url', url) for method in webhooks: - if method in created_webhooks: - continue - + print('method', method) session = get_request_session() print('session', session) try: + print(get_header(self)) d = session.post(url, data=json.dumps({ "webhook": { "topic": method, @@ -84,11 +83,7 @@ def get_shopify_url(path, settings): def get_header(settings): header = {'Content-Type': 'application/json'} - if settings.app_type == "Private": - return header - else: - header["X-Shopify-Access-Token"] = settings.access_token - return header + return header; @frappe.whitelist() def get_series(): From c6b7695ab5343ef0309bf19b46de254d59720015 Mon Sep 17 00:00:00 2001 From: prssanna Date: Fri, 13 Sep 2019 12:32:42 +0530 Subject: [PATCH 17/32] fix: default private app type --- erpnext/erpnext_integrations/utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/erpnext_integrations/utils.py b/erpnext/erpnext_integrations/utils.py index 9065779097..6acb241d51 100644 --- a/erpnext/erpnext_integrations/utils.py +++ b/erpnext/erpnext_integrations/utils.py @@ -36,7 +36,7 @@ def get_webhook_address(connector_name, method, exclude_uri=False): try: url = frappe.request.url except RuntimeError: - url = "http://localhost:8000" + url = frappe.utils.get_url() server_url = '{uri.scheme}://{uri.netloc}/api/method/{endpoint}'.format(uri=urlparse(url), endpoint=endpoint) From 5aa87430248b231dd6a6fd554fb0af438f9bfa39 Mon Sep 17 00:00:00 2001 From: hrwx Date: Fri, 13 Sep 2019 17:04:01 +0000 Subject: [PATCH 18/32] changes --- .../connectors/shopify_connection.py | 1 + .../doctype/shopify_settings/sync_product.py | 12 +++++++++--- erpnext/erpnext_integrations/utils.py | 4 ++-- 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/erpnext/erpnext_integrations/connectors/shopify_connection.py b/erpnext/erpnext_integrations/connectors/shopify_connection.py index 1d6e8917f5..ed531666c9 100644 --- a/erpnext/erpnext_integrations/connectors/shopify_connection.py +++ b/erpnext/erpnext_integrations/connectors/shopify_connection.py @@ -246,6 +246,7 @@ def update_taxes_with_shipping_lines(taxes, shipping_lines, shopify_settings): return taxes def get_tax_account_head(tax): + return tax_title = tax.get("title").encode("utf-8") tax_account = frappe.db.get_value("Shopify Tax Account", \ diff --git a/erpnext/erpnext_integrations/doctype/shopify_settings/sync_product.py b/erpnext/erpnext_integrations/doctype/shopify_settings/sync_product.py index 5570e6903a..bde101123d 100644 --- a/erpnext/erpnext_integrations/doctype/shopify_settings/sync_product.py +++ b/erpnext/erpnext_integrations/doctype/shopify_settings/sync_product.py @@ -1,13 +1,14 @@ from __future__ import unicode_literals import frappe from frappe import _ +from erpnext import get_default_company from frappe.utils import cstr, cint, get_request_session from erpnext.erpnext_integrations.doctype.shopify_settings.shopify_settings import get_shopify_url, get_header shopify_variants_attr_list = ["option1", "option2", "option3"] def sync_item_from_shopify(shopify_settings, item): - url = get_shopify_url("/admin/products/{0}.json".format(item.get("product_id")), shopify_settings) + url = get_shopify_url("admin/api/2019-04/products/{0}.json".format(item.get("product_id")), shopify_settings) session = get_request_session() try: @@ -107,7 +108,12 @@ def create_item(shopify_item, warehouse, has_variant=0, attributes=None,variant_ "image": get_item_image(shopify_item), "weight_uom": shopify_item.get("weight_unit"), "weight_per_unit": shopify_item.get("weight"), - "default_supplier": get_supplier(shopify_item) + "default_supplier": get_supplier(shopify_item), + "item_defaults": [ + { + "company": get_default_company() + } + ] } if not is_item_exists(item_dict, attributes, variant_of=variant_of): @@ -116,7 +122,7 @@ def create_item(shopify_item, warehouse, has_variant=0, attributes=None,variant_ if not item_details: new_item = frappe.get_doc(item_dict) - new_item.insert() + new_item.insert(ignore_permissions=True, ignore_mandatory=True) name = new_item.name if not name: diff --git a/erpnext/erpnext_integrations/utils.py b/erpnext/erpnext_integrations/utils.py index 6acb241d51..84f7f5a5d4 100644 --- a/erpnext/erpnext_integrations/utils.py +++ b/erpnext/erpnext_integrations/utils.py @@ -36,8 +36,8 @@ def get_webhook_address(connector_name, method, exclude_uri=False): try: url = frappe.request.url except RuntimeError: - url = frappe.utils.get_url() + url = "http://localhost:8000" server_url = '{uri.scheme}://{uri.netloc}/api/method/{endpoint}'.format(uri=urlparse(url), endpoint=endpoint) - return server_url \ No newline at end of file + return server_url From 5c036d9aaff931fb7071206f676ce7753eccb3f3 Mon Sep 17 00:00:00 2001 From: hrwx Date: Tue, 17 Sep 2019 10:43:31 +0000 Subject: [PATCH 19/32] fix: permissions --- .../erpnext_integrations/connectors/shopify_connection.py | 7 ++++++- .../doctype/shopify_settings/sync_customer.py | 2 +- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/erpnext/erpnext_integrations/connectors/shopify_connection.py b/erpnext/erpnext_integrations/connectors/shopify_connection.py index ed531666c9..b682ba304d 100644 --- a/erpnext/erpnext_integrations/connectors/shopify_connection.py +++ b/erpnext/erpnext_integrations/connectors/shopify_connection.py @@ -19,6 +19,7 @@ def store_request_data(order=None, event=None): dump_request_data(order, event) def sync_sales_order(order, request_id=None): + frappe.set_user('Administrator') shopify_settings = frappe.get_doc("Shopify Settings") frappe.flags.request_id = request_id @@ -33,6 +34,7 @@ def sync_sales_order(order, request_id=None): make_shopify_log(status="Success") def prepare_sales_invoice(order, request_id=None): + frappe.set_user('Administrator') shopify_settings = frappe.get_doc("Shopify Settings") frappe.flags.request_id = request_id @@ -45,6 +47,7 @@ def prepare_sales_invoice(order, request_id=None): make_shopify_log(status="Error", exception=True) def prepare_delivery_note(order, request_id=None): + frappe.set_user('Administrator') shopify_settings = frappe.get_doc("Shopify Settings") frappe.flags.request_id = request_id @@ -151,6 +154,7 @@ def make_payament_entry_against_sales_invoice(doc, shopify_settings): payemnt_entry.flags.ignore_mandatory = True payemnt_entry.reference_no = doc.name payemnt_entry.reference_date = nowdate() + payemnt_entry.insert(ignore_permissions=True) payemnt_entry.submit() def create_delivery_note(shopify_order, shopify_settings, so): @@ -168,6 +172,7 @@ def create_delivery_note(shopify_order, shopify_settings, so): dn.items = get_fulfillment_items(dn.items, fulfillment.get("line_items"), shopify_settings) dn.flags.ignore_mandatory = True dn.save() + dn.submit() frappe.db.commit() def get_fulfillment_items(dn_items, fulfillment_items, shopify_settings): @@ -200,7 +205,7 @@ def get_order_items(order_items, shopify_settings): "rate": shopify_item.get("price"), "delivery_date": nowdate(), "qty": shopify_item.get("quantity"), - "stock_uom": shopify_item.get("sku"), + "stock_uom": shopify_item.get("uom") or _("Nos"), "warehouse": shopify_settings.warehouse }) else: diff --git a/erpnext/erpnext_integrations/doctype/shopify_settings/sync_customer.py b/erpnext/erpnext_integrations/doctype/shopify_settings/sync_customer.py index 4b284b2e9d..7866fdea31 100644 --- a/erpnext/erpnext_integrations/doctype/shopify_settings/sync_customer.py +++ b/erpnext/erpnext_integrations/doctype/shopify_settings/sync_customer.py @@ -21,7 +21,7 @@ def create_customer(shopify_customer, shopify_settings): "customer_type": _("Individual") }) customer.flags.ignore_mandatory = True - customer.insert() + customer.insert(ignore_permissions=True) if customer: create_customer_address(customer, shopify_customer) From bf09fbe6b9b90626f78b1bcb744aab78f13aa56b Mon Sep 17 00:00:00 2001 From: hrwx Date: Wed, 18 Sep 2019 08:03:28 +0000 Subject: [PATCH 20/32] fix: sku --- erpnext/erpnext_integrations/connectors/shopify_connection.py | 1 + .../doctype/shopify_settings/test_shopify_settings.py | 1 + 2 files changed, 2 insertions(+) diff --git a/erpnext/erpnext_integrations/connectors/shopify_connection.py b/erpnext/erpnext_integrations/connectors/shopify_connection.py index b682ba304d..0bf6bdec02 100644 --- a/erpnext/erpnext_integrations/connectors/shopify_connection.py +++ b/erpnext/erpnext_integrations/connectors/shopify_connection.py @@ -140,6 +140,7 @@ def create_sales_invoice(shopify_order, shopify_settings, so): 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) + si.insert(ignore_mandatory=True) si.submit() make_payament_entry_against_sales_invoice(si, shopify_settings) frappe.db.commit() 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 b983407f7b..64ef3dc085 100644 --- a/erpnext/erpnext_integrations/doctype/shopify_settings/test_shopify_settings.py +++ b/erpnext/erpnext_integrations/doctype/shopify_settings/test_shopify_settings.py @@ -40,6 +40,7 @@ class ShopifySettings(unittest.TestCase): "price_list": "_Test Price List", "warehouse": "_Test Warehouse - _TC", "cash_bank_account": "Cash - _TC", + "account": "Cash - _TC", "customer_group": "_Test Customer Group", "cost_center": "Main - _TC", "taxes": [ From ebc0e1ca8ac343db044aad0d9617b6948d855c5c Mon Sep 17 00:00:00 2001 From: hrwx Date: Thu, 19 Sep 2019 06:13:47 +0000 Subject: [PATCH 21/32] fix: remove return statement --- erpnext/erpnext_integrations/connectors/shopify_connection.py | 1 - 1 file changed, 1 deletion(-) diff --git a/erpnext/erpnext_integrations/connectors/shopify_connection.py b/erpnext/erpnext_integrations/connectors/shopify_connection.py index 0bf6bdec02..bd980374b6 100644 --- a/erpnext/erpnext_integrations/connectors/shopify_connection.py +++ b/erpnext/erpnext_integrations/connectors/shopify_connection.py @@ -252,7 +252,6 @@ def update_taxes_with_shipping_lines(taxes, shipping_lines, shopify_settings): return taxes def get_tax_account_head(tax): - return tax_title = tax.get("title").encode("utf-8") tax_account = frappe.db.get_value("Shopify Tax Account", \ From 1f512b36c5c4d76d277cfb2881c57ef199b28836 Mon Sep 17 00:00:00 2001 From: prssanna Date: Fri, 27 Sep 2019 12:03:35 +0530 Subject: [PATCH 22/32] fix(patch): set app_type as private --- erpnext/patches.txt | 2 ++ erpnext/patches/v12_0/set_default_shopify_app_type.py | 6 ++++++ 2 files changed, 8 insertions(+) create mode 100644 erpnext/patches/v12_0/set_default_shopify_app_type.py diff --git a/erpnext/patches.txt b/erpnext/patches.txt index 722baaf622..9f98099257 100644 --- a/erpnext/patches.txt +++ b/erpnext/patches.txt @@ -638,3 +638,5 @@ erpnext.patches.v12_0.add_variant_of_in_item_attribute_table erpnext.patches.v12_0.rename_bank_account_field_in_journal_entry_account erpnext.patches.v12_0.create_default_energy_point_rules erpnext.patches.v12_0.set_produced_qty_field_in_sales_order_for_work_order +erpnext.patches.v12_0.generate_leave_ledger_entries +erpnext.patches.v12_0.set_default_shopify_app_type diff --git a/erpnext/patches/v12_0/set_default_shopify_app_type.py b/erpnext/patches/v12_0/set_default_shopify_app_type.py new file mode 100644 index 0000000000..d040ea7f71 --- /dev/null +++ b/erpnext/patches/v12_0/set_default_shopify_app_type.py @@ -0,0 +1,6 @@ +from __future__ import unicode_literals +import frappe + +def execute(): + frappe.reload_doc('erpnext_integrations', 'doctype', 'shopify_settings') + frappe.db.set_value('Shopify Settings', None, 'app_type', 'Private') \ No newline at end of file From 147af15268d514ef23a2a1e4811e99ad29a902c4 Mon Sep 17 00:00:00 2001 From: Marica Date: Mon, 30 Sep 2019 15:11:15 +0530 Subject: [PATCH 23/32] fix: Added 'Manual' % Complete Method in Project (#19175) Added additional '% Complete Method' in Project so that Project can be set to 'Completed' irrespective of presence of Tasks --- erpnext/projects/doctype/project/project.json | 2 +- erpnext/projects/doctype/project/project.py | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/erpnext/projects/doctype/project/project.json b/erpnext/projects/doctype/project/project.json index 205f895849..7d47db371d 100644 --- a/erpnext/projects/doctype/project/project.json +++ b/erpnext/projects/doctype/project/project.json @@ -108,7 +108,7 @@ "fieldname": "percent_complete_method", "fieldtype": "Select", "label": "% Complete Method", - "options": "Task Completion\nTask Progress\nTask Weight" + "options": "Manual\nTask Completion\nTask Progress\nTask Weight" }, { "bold": 1, diff --git a/erpnext/projects/doctype/project/project.py b/erpnext/projects/doctype/project/project.py index 6176cf89b4..783bcf3c38 100644 --- a/erpnext/projects/doctype/project/project.py +++ b/erpnext/projects/doctype/project/project.py @@ -87,6 +87,11 @@ class Project(Document): frappe.db.set_value("Sales Order", self.sales_order, "project", self.name) def update_percent_complete(self): + if self.percent_complete_method == "Manual": + if self.status == "Completed": + self.percent_complete = 100 + return + total = frappe.db.count('Task', dict(project=self.name)) if not total: From ed1cc18ab529c218429e88daef94aaa8df4595af Mon Sep 17 00:00:00 2001 From: rohitwaghchaure Date: Mon, 30 Sep 2019 15:15:52 +0530 Subject: [PATCH 24/32] fix: stock ledger report not showing data if the UOM filter has selected (#19179) --- .../stock/report/stock_ledger/stock_ledger.py | 2 +- erpnext/stock/utils.py | 53 +++++++++++-------- 2 files changed, 32 insertions(+), 23 deletions(-) diff --git a/erpnext/stock/report/stock_ledger/stock_ledger.py b/erpnext/stock/report/stock_ledger/stock_ledger.py index d386230687..5bdbca23d9 100644 --- a/erpnext/stock/report/stock_ledger/stock_ledger.py +++ b/erpnext/stock/report/stock_ledger/stock_ledger.py @@ -107,7 +107,7 @@ def get_item_details(items, sl_entries, include_uom): if include_uom: cf_field = ", ucd.conversion_factor" cf_join = "left join `tabUOM Conversion Detail` ucd on ucd.parent=item.name and ucd.uom='%s'" \ - % frappe.db.escape(include_uom) + % (include_uom) res = frappe.db.sql(""" select diff --git a/erpnext/stock/utils.py b/erpnext/stock/utils.py index 4c663e393f..2ac0bae6da 100644 --- a/erpnext/stock/utils.py +++ b/erpnext/stock/utils.py @@ -253,31 +253,40 @@ def update_included_uom_in_report(columns, result, include_uom, conversion_facto return convertible_cols = {} - for col_idx in reversed(range(0, len(columns))): - col = columns[col_idx] - if isinstance(col, dict) and col.get("convertible") in ['rate', 'qty']: - convertible_cols[col_idx] = col['convertible'] - columns.insert(col_idx+1, col.copy()) - columns[col_idx+1]['fieldname'] += "_alt" - if convertible_cols[col_idx] == 'rate': - columns[col_idx+1]['label'] += " (per {})".format(include_uom) - else: - columns[col_idx+1]['label'] += " ({})".format(include_uom) + + is_dict_obj = False + if isinstance(result[0], dict): + is_dict_obj = True + + convertible_columns = {} + for idx, d in enumerate(columns): + key = d.get("fieldname") if is_dict_obj else idx + if d.get("convertible"): + convertible_columns.setdefault(key, d.get("convertible")) + + # Add new column to show qty/rate as per the selected UOM + columns.insert(idx+1, { + 'label': "{0} (per {1})".format(d.get("label"), include_uom), + 'fieldname': "{0}_{1}".format(d.get("fieldname"), frappe.scrub(include_uom)), + 'fieldtype': 'Currency' if d.get("convertible") == 'rate' else 'Float' + }) for row_idx, row in enumerate(result): - new_row = [] - for col_idx, d in enumerate(row): - new_row.append(d) - if col_idx in convertible_cols: - if conversion_factors[row_idx]: - if convertible_cols[col_idx] == 'rate': - new_row.append(flt(d) * conversion_factors[row_idx]) - else: - new_row.append(flt(d) / conversion_factors[row_idx]) - else: - new_row.append(None) + data = row.items() if is_dict_obj else enumerate(row) + for key, value in data: + if not key in convertible_columns or not conversion_factors[row_idx]: + continue - result[row_idx] = new_row + if convertible_columns.get(key) == 'rate': + new_value = flt(value) * conversion_factors[row_idx] + else: + new_value = flt(value) / conversion_factors[row_idx] + + if not is_dict_obj: + row.insert(key+1, new_value) + else: + new_key = "{0}_{1}".format(key, frappe.scrub(include_uom)) + row[new_key] = new_value def get_available_serial_nos(item_code, warehouse): return frappe.get_all("Serial No", filters = {'item_code': item_code, From b54f0fb388dfbb71fe845c91fb9ee7c7363faeda Mon Sep 17 00:00:00 2001 From: Deepesh Garg <42651287+deepeshgarg007@users.noreply.github.com> Date: Mon, 30 Sep 2019 15:19:56 +0530 Subject: [PATCH 25/32] fix: Party column empty in accounts receivable/ payable summary (#19205) --- .../accounts_receivable_summary.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/erpnext/accounts/report/accounts_receivable_summary/accounts_receivable_summary.py b/erpnext/accounts/report/accounts_receivable_summary/accounts_receivable_summary.py index 350e081957..b90a7a9501 100644 --- a/erpnext/accounts/report/accounts_receivable_summary/accounts_receivable_summary.py +++ b/erpnext/accounts/report/accounts_receivable_summary/accounts_receivable_summary.py @@ -3,7 +3,7 @@ from __future__ import unicode_literals import frappe -from frappe import _ +from frappe import _, scrub from frappe.utils import flt, cint from erpnext.accounts.party import get_partywise_advanced_payment_amount from erpnext.accounts.report.accounts_receivable.accounts_receivable import ReceivablePayableReport @@ -40,7 +40,7 @@ class AccountsReceivableSummary(ReceivablePayableReport): row.party = party if self.party_naming_by == "Naming Series": - row.party_name = frappe.get_cached_value(self.party_type, party, [self.party_type + "_name"]) + row.party_name = frappe.get_cached_value(self.party_type, party, scrub(self.party_type) + "_name") row.update(party_dict) From 8d889ef80e18ae6533d2686bae61d6226aaab2ca Mon Sep 17 00:00:00 2001 From: rohitwaghchaure Date: Mon, 30 Sep 2019 15:22:12 +0530 Subject: [PATCH 26/32] fix: update the pending qty in production plan on completion of work order (#19180) --- erpnext/manufacturing/doctype/production_plan/production_plan.py | 1 + 1 file changed, 1 insertion(+) diff --git a/erpnext/manufacturing/doctype/production_plan/production_plan.py b/erpnext/manufacturing/doctype/production_plan/production_plan.py index b51420ffdb..04359e3f5d 100644 --- a/erpnext/manufacturing/doctype/production_plan/production_plan.py +++ b/erpnext/manufacturing/doctype/production_plan/production_plan.py @@ -195,6 +195,7 @@ class ProductionPlan(Document): for data in self.po_items: if data.name == production_plan_item: data.produced_qty = produced_qty + data.pending_qty = data.planned_qty - data.produced_qty data.db_update() self.calculate_total_produced_qty() From de15cc1387d167e41db5258364144c81a255a1c1 Mon Sep 17 00:00:00 2001 From: Marica Date: Mon, 30 Sep 2019 15:36:33 +0530 Subject: [PATCH 27/32] fix: Work order dialog box 'Select Quantity' on clicking 'Finish' (#19136) The dialog box fetched 0 as Quantity to Manufacture and Max Quantity on finishing a Work Order --- .../manufacturing/doctype/work_order/work_order.js | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/erpnext/manufacturing/doctype/work_order/work_order.js b/erpnext/manufacturing/doctype/work_order/work_order.js index ce7b4f9425..96e44c881b 100644 --- a/erpnext/manufacturing/doctype/work_order/work_order.js +++ b/erpnext/manufacturing/doctype/work_order/work_order.js @@ -545,11 +545,14 @@ erpnext.work_order = { get_max_transferable_qty: (frm, purpose) => { let max = 0; - if (frm.doc.skip_transfer) return max; - if (purpose === 'Manufacture') { - max = flt(frm.doc.material_transferred_for_manufacturing) - flt(frm.doc.produced_qty); + if (frm.doc.skip_transfer) { + max = flt(frm.doc.qty) - flt(frm.doc.produced_qty); } else { - max = flt(frm.doc.qty) - flt(frm.doc.material_transferred_for_manufacturing); + if (purpose === 'Manufacture') { + max = flt(frm.doc.material_transferred_for_manufacturing) - flt(frm.doc.produced_qty); + } else { + max = flt(frm.doc.qty) - flt(frm.doc.material_transferred_for_manufacturing); + } } return flt(max, precision('qty')); }, From 905573700be41b5fa8b08c5a7939f969db29e9f8 Mon Sep 17 00:00:00 2001 From: Mangesh-Khairnar Date: Mon, 30 Sep 2019 16:10:47 +0530 Subject: [PATCH 28/32] feat(report): fixed asset register (#19164) * feat(report): fixed asset register * fix: fetch supplier and check for asset status * fix: fetch vendor name from purchase invoice * style(fixed-asset-register): use conventional column name * Update fixed_asset_register.py --- .../report/fixed_asset_register/__init__.py | 0 .../fixed_asset_register.js | 30 +++ .../fixed_asset_register.json | 27 +++ .../fixed_asset_register.py | 172 ++++++++++++++++++ 4 files changed, 229 insertions(+) create mode 100644 erpnext/assets/report/fixed_asset_register/__init__.py create mode 100644 erpnext/assets/report/fixed_asset_register/fixed_asset_register.js create mode 100644 erpnext/assets/report/fixed_asset_register/fixed_asset_register.json create mode 100644 erpnext/assets/report/fixed_asset_register/fixed_asset_register.py diff --git a/erpnext/assets/report/fixed_asset_register/__init__.py b/erpnext/assets/report/fixed_asset_register/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/erpnext/assets/report/fixed_asset_register/fixed_asset_register.js b/erpnext/assets/report/fixed_asset_register/fixed_asset_register.js new file mode 100644 index 0000000000..5e994b5c9c --- /dev/null +++ b/erpnext/assets/report/fixed_asset_register/fixed_asset_register.js @@ -0,0 +1,30 @@ +// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors +// For license information, please see license.txt +/* eslint-disable */ + +frappe.query_reports["Fixed Asset Register"] = { + "filters": [ + { + fieldname:"company", + label: __("Company"), + fieldtype: "Link", + options: "Company", + default: frappe.defaults.get_user_default("Company"), + reqd: 1 + }, + { + fieldname:"status", + label: __("Status"), + fieldtype: "Select", + options: "In Store\nDisposed", + default: 'In Store', + reqd: 1 + }, + { + fieldname:"finance_book", + label: __("Finance Book"), + fieldtype: "Link", + options: "Finance Book" + }, + ] +}; diff --git a/erpnext/assets/report/fixed_asset_register/fixed_asset_register.json b/erpnext/assets/report/fixed_asset_register/fixed_asset_register.json new file mode 100644 index 0000000000..ae2aa542f5 --- /dev/null +++ b/erpnext/assets/report/fixed_asset_register/fixed_asset_register.json @@ -0,0 +1,27 @@ +{ + "add_total_row": 0, + "creation": "2019-09-23 16:35:02.836134", + "disable_prepared_report": 0, + "disabled": 0, + "docstatus": 0, + "doctype": "Report", + "idx": 0, + "is_standard": "Yes", + "modified": "2019-09-23 16:35:02.836134", + "modified_by": "Administrator", + "module": "Assets", + "name": "Fixed Asset Register", + "owner": "Administrator", + "prepared_report": 0, + "ref_doctype": "Asset", + "report_name": "Fixed Asset Register", + "report_type": "Script Report", + "roles": [ + { + "role": "Accounts User" + }, + { + "role": "Quality Manager" + } + ] +} \ No newline at end of file diff --git a/erpnext/assets/report/fixed_asset_register/fixed_asset_register.py b/erpnext/assets/report/fixed_asset_register/fixed_asset_register.py new file mode 100644 index 0000000000..eac0e2a0bf --- /dev/null +++ b/erpnext/assets/report/fixed_asset_register/fixed_asset_register.py @@ -0,0 +1,172 @@ +# Copyright (c) 2013, Frappe Technologies Pvt. Ltd. and contributors +# For license information, please see license.txt + +from __future__ import unicode_literals +import frappe +from frappe import _ + +def execute(filters=None): + filters = frappe._dict(filters or {}) + columns = get_columns(filters) + data = get_data(filters) + return columns, data + +def get_columns(filters): + return [ + { + "label": _("Asset Id"), + "fieldtype": "Link", + "fieldname": "asset_id", + "options": "Asset", + "width": 100 + }, + { + "label": _("Asset Name"), + "fieldtype": "Data", + "fieldname": "asset_name", + "width": 140 + }, + { + "label": _("Asset Category"), + "fieldtype": "Link", + "fieldname": "asset_category", + "options": "Asset Category", + "width": 100 + }, + { + "label": _("Status"), + "fieldtype": "Data", + "fieldname": "status", + "width": 90 + }, + { + "label": _("Cost Center"), + "fieldtype": "Link", + "fieldname": "cost_center", + "options": "Cost Center", + "width": 100 + }, + { + "label": _("Department"), + "fieldtype": "Link", + "fieldname": "department", + "options": "Department", + "width": 100 + }, + { + "label": _("Location"), + "fieldtype": "Link", + "fieldname": "location", + "options": "Location", + "width": 100 + }, + { + "label": _("Purchase Date"), + "fieldtype": "Date", + "fieldname": "purchase_date", + "width": 90 + }, + { + "label": _("Gross Purchase Amount"), + "fieldname": "gross_purchase_amount", + "options": "Currency", + "width": 90 + }, + { + "label": _("Vendor Name"), + "fieldtype": "Data", + "fieldname": "vendor_name", + "width": 100 + }, + { + "label": _("Available For Use Date"), + "fieldtype": "Date", + "fieldname": "available_for_use_date", + "width": 90 + }, + { + "label": _("Current Value"), + "fieldname": "current_value", + "options": "Currency", + "width": 90 + }, + ] + +def get_conditions(filters): + conditions = {'docstatus': 1} + status = filters.status + + if filters.company: + conditions["company"] = filters.company + + # In Store assets are those that are not sold or scrapped + operand = 'not in' + if status not in 'In Store': + operand = 'in' + + conditions['status'] = (operand, ['Sold', 'Scrapped']) + + return conditions + +def get_data(filters): + + data = [] + + conditions = get_conditions(filters) + current_value_map = get_finance_book_value_map(filters.finance_book) + pr_supplier_map = get_purchase_receipt_supplier_map() + pi_supplier_map = get_purchase_invoice_supplier_map() + + assets_record = frappe.db.get_all("Asset", + filters=conditions, + fields=["name", "asset_name", "department", "cost_center", "purchase_receipt", + "asset_category", "purchase_date", "gross_purchase_amount", "location", + "available_for_use_date", "status", "purchase_invoice"]) + + for asset in assets_record: + if current_value_map.get(asset.name) is not None: + row = { + "asset_id": asset.name, + "asset_name": asset.asset_name, + "status": asset.status, + "department": asset.department, + "cost_center": asset.cost_center, + "vendor_name": pr_supplier_map.get(asset.purchase_receipt) or pi_supplier_map.get(asset.purchase_invoice), + "gross_purchase_amount": asset.gross_purchase_amount, + "available_for_use_date": asset.available_for_use_date, + "location": asset.location, + "asset_category": asset.asset_category, + "purchase_date": asset.purchase_date, + "current_value": current_value_map.get(asset.name) + } + data.append(row) + + return data + +def get_finance_book_value_map(finance_book=''): + return frappe._dict(frappe.db.sql(''' Select + parent, value_after_depreciation + FROM `tabAsset Finance Book` + WHERE + parentfield='finance_books' + AND finance_book=%s''', (finance_book))) + +def get_purchase_receipt_supplier_map(): + return frappe._dict(frappe.db.sql(''' Select + pr.name, pr.supplier + FROM `tabPurchase Receipt` pr, `tabPurchase Receipt Item` pri + WHERE + pri.parent = pr.name + AND pri.is_fixed_asset=1 + AND pr.docstatus=1 + AND pr.is_return=0''')) + +def get_purchase_invoice_supplier_map(): + return frappe._dict(frappe.db.sql(''' Select + pi.name, pi.supplier + FROM `tabPurchase Invoice` pi, `tabPurchase Invoice Item` pii + WHERE + pii.parent = pi.name + AND pii.is_fixed_asset=1 + AND pi.docstatus=1 + AND pi.is_return=0''')) From 25e043766a3d30c94f2e7a82e1ba437bc6971d9d Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Mon, 30 Sep 2019 16:36:23 +0530 Subject: [PATCH 29/32] fix: Get leave approvers in Employee leave balance report (#19211) --- .../report/employee_leave_balance/employee_leave_balance.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/erpnext/hr/report/employee_leave_balance/employee_leave_balance.py b/erpnext/hr/report/employee_leave_balance/employee_leave_balance.py index 7717ba0e40..e967db87c4 100644 --- a/erpnext/hr/report/employee_leave_balance/employee_leave_balance.py +++ b/erpnext/hr/report/employee_leave_balance/employee_leave_balance.py @@ -60,7 +60,10 @@ def get_data(filters, leave_types): data = [] for employee in active_employees: - leave_approvers = department_approver_map.get(employee.department_name, []).append(employee.leave_approver) + leave_approvers = department_approver_map.get(employee.department_name, []) + if employee.leave_approver: + leave_approvers.append(employee.leave_approver) + if (len(leave_approvers) and user in leave_approvers) or (user in ["Administrator", employee.user_id]) or ("HR Manager" in frappe.get_roles(user)): row = [employee.name, employee.employee_name, employee.department] From d463c346feb2ee373e14d184843b331225a53563 Mon Sep 17 00:00:00 2001 From: Rohan Date: Mon, 30 Sep 2019 16:37:29 +0530 Subject: [PATCH 30/32] fix: set no-copy on some contract fields (#19208) --- erpnext/crm/doctype/contract/contract.json | 1249 ++++---------------- 1 file changed, 258 insertions(+), 991 deletions(-) diff --git a/erpnext/crm/doctype/contract/contract.json b/erpnext/crm/doctype/contract/contract.json index d48cc3762c..e04ad30ea7 100755 --- a/erpnext/crm/doctype/contract/contract.json +++ b/erpnext/crm/doctype/contract/contract.json @@ -1,1034 +1,301 @@ { - "allow_copy": 0, - "allow_guest_to_view": 0, - "allow_import": 1, - "allow_rename": 1, - "autoname": "", - "beta": 0, - "creation": "2018-04-12 06:32:04.582486", - "custom": 0, - "docstatus": 0, - "doctype": "DocType", - "document_type": "", - "editable_grid": 1, - "engine": "InnoDB", + "allow_import": 1, + "allow_rename": 1, + "creation": "2018-04-12 06:32:04.582486", + "doctype": "DocType", + "editable_grid": 1, + "engine": "InnoDB", + "field_order": [ + "party_type", + "is_signed", + "cb_party", + "party_name", + "party_user", + "status", + "fulfilment_status", + "sb_terms", + "start_date", + "cb_date", + "end_date", + "sb_signee", + "signee", + "signed_on", + "cb_user", + "ip_address", + "sb_contract", + "contract_template", + "contract_terms", + "sb_fulfilment", + "requires_fulfilment", + "fulfilment_deadline", + "fulfilment_terms", + "sb_references", + "document_type", + "cb_links", + "document_name", + "amended_from" + ], "fields": [ { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "default": "Customer", - "fieldname": "party_type", - "fieldtype": "Select", - "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": "Party Type", - "length": 0, - "no_copy": 0, - "options": "Customer\nSupplier\nEmployee", - "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 - }, + "default": "Customer", + "fieldname": "party_type", + "fieldtype": "Select", + "label": "Party Type", + "options": "Customer\nSupplier\nEmployee", + "reqd": 1 + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 1, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "is_signed", - "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": "Signed", - "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_on_submit": 1, + "default": "0", + "fieldname": "is_signed", + "fieldtype": "Check", + "label": "Signed", + "no_copy": 1 + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "cb_party", - "fieldtype": "Column Break", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, + "fieldname": "cb_party", + "fieldtype": "Column Break" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "party_name", - "fieldtype": "Dynamic Link", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 1, - "label": "Party Name", - "length": 0, - "no_copy": 0, - "options": "party_type", - "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 - }, + "fieldname": "party_name", + "fieldtype": "Dynamic Link", + "in_standard_filter": 1, + "label": "Party Name", + "options": "party_type", + "reqd": 1 + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "depends_on": "", - "fieldname": "party_user", - "fieldtype": "Link", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Party User", - "length": 0, - "no_copy": 0, - "options": "User", - "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": "party_user", + "fieldtype": "Link", + "label": "Party User", + "options": "User" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 1, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "status", - "fieldtype": "Select", - "hidden": 1, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 1, - "label": "Status", - "length": 0, - "no_copy": 0, - "options": "Unsigned\nActive\nInactive", - "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_on_submit": 1, + "fieldname": "status", + "fieldtype": "Select", + "hidden": 1, + "in_list_view": 1, + "in_standard_filter": 1, + "label": "Status", + "no_copy": 1, + "options": "Unsigned\nActive\nInactive" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 1, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "fulfilment_status", - "fieldtype": "Select", - "hidden": 1, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 1, - "label": "Fulfilment Status", - "length": 0, - "no_copy": 0, - "options": "N/A\nUnfulfilled\nPartially Fulfilled\nFulfilled\nLapsed", - "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_on_submit": 1, + "fieldname": "fulfilment_status", + "fieldtype": "Select", + "hidden": 1, + "in_list_view": 1, + "in_standard_filter": 1, + "label": "Fulfilment Status", + "no_copy": 1, + "options": "N/A\nUnfulfilled\nPartially Fulfilled\nFulfilled\nLapsed" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "sb_terms", - "fieldtype": "Section Break", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Contract Period", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, + "fieldname": "sb_terms", + "fieldtype": "Section Break", + "label": "Contract Period" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "start_date", - "fieldtype": "Date", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Start Date", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, + "fieldname": "start_date", + "fieldtype": "Date", + "label": "Start Date" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "cb_date", - "fieldtype": "Column Break", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, + "fieldname": "cb_date", + "fieldtype": "Column Break" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "end_date", - "fieldtype": "Date", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "End Date", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, + "fieldname": "end_date", + "fieldtype": "Date", + "label": "End Date" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "collapsible_depends_on": "", - "columns": 0, - "depends_on": "eval:doc.is_signed==1", - "fieldname": "sb_signee", - "fieldtype": "Section Break", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Signee Details", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, + "depends_on": "eval:doc.is_signed==1", + "fieldname": "sb_signee", + "fieldtype": "Section Break", + "label": "Signee Details" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 1, - "bold": 0, - "collapsible": 0, - "columns": 0, - "depends_on": "", - "fieldname": "signee", - "fieldtype": "Data", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 1, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Signee", - "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_on_submit": 1, + "fieldname": "signee", + "fieldtype": "Data", + "in_global_search": 1, + "label": "Signee", + "no_copy": 1 + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 1, - "bold": 0, - "collapsible": 0, - "columns": 0, - "depends_on": "", - "fieldname": "signed_on", - "fieldtype": "Datetime", - "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": "Signed On", - "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_on_submit": 1, + "fieldname": "signed_on", + "fieldtype": "Datetime", + "in_list_view": 1, + "label": "Signed On", + "no_copy": 1 + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "cb_user", - "fieldtype": "Column Break", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, + "fieldname": "cb_user", + "fieldtype": "Column Break" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 1, - "bold": 0, - "collapsible": 0, - "columns": 0, - "depends_on": "", - "fieldname": "ip_address", - "fieldtype": "Data", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "IP Address", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 1, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, + "allow_on_submit": 1, + "fieldname": "ip_address", + "fieldtype": "Data", + "label": "IP Address", + "no_copy": 1, + "read_only": 1 + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 1, - "collapsible_depends_on": "eval:doc.docstatus==0", - "columns": 0, - "fieldname": "sb_contract", - "fieldtype": "Section Break", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Contract Details", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, + "collapsible": 1, + "collapsible_depends_on": "eval:doc.docstatus==0", + "fieldname": "sb_contract", + "fieldtype": "Section Break", + "label": "Contract Details" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "contract_template", - "fieldtype": "Link", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Contract Template", - "length": 0, - "no_copy": 0, - "options": "Contract Template", - "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": "contract_template", + "fieldtype": "Link", + "label": "Contract Template", + "options": "Contract Template" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "contract_terms", - "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": "Contract Terms", - "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 - }, + "fieldname": "contract_terms", + "fieldtype": "Text Editor", + "in_list_view": 1, + "label": "Contract Terms", + "reqd": 1 + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "sb_fulfilment", - "fieldtype": "Section Break", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Fulfilment Details", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, + "fieldname": "sb_fulfilment", + "fieldtype": "Section Break", + "label": "Fulfilment Details" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "requires_fulfilment", - "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": "Requires Fulfilment", - "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": "requires_fulfilment", + "fieldtype": "Check", + "label": "Requires Fulfilment" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "depends_on": "eval:doc.requires_fulfilment==1", - "fieldname": "fulfilment_deadline", - "fieldtype": "Date", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Fulfilment Deadline", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, + "depends_on": "eval:doc.requires_fulfilment==1", + "fieldname": "fulfilment_deadline", + "fieldtype": "Date", + "label": "Fulfilment Deadline" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 1, - "bold": 0, - "collapsible": 0, - "columns": 0, - "depends_on": "eval:doc.requires_fulfilment==1", - "fieldname": "fulfilment_terms", - "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": "Fulfilment Terms", - "length": 0, - "no_copy": 0, - "options": "Contract Fulfilment Checklist", - "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_on_submit": 1, + "depends_on": "eval:doc.requires_fulfilment==1", + "fieldname": "fulfilment_terms", + "fieldtype": "Table", + "label": "Fulfilment Terms", + "options": "Contract Fulfilment Checklist" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 1, - "columns": 0, - "fieldname": "sb_references", - "fieldtype": "Section Break", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "References", - "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 - }, + "collapsible": 1, + "fieldname": "sb_references", + "fieldtype": "Section Break", + "label": "References" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "default": "", - "depends_on": "", - "fieldname": "document_type", - "fieldtype": "Select", - "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": "Document Type", - "length": 0, - "no_copy": 0, - "options": "\nQuotation\nProject\nSales Order\nPurchase Order\nSales Invoice\nPurchase Invoice", - "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": "document_type", + "fieldtype": "Select", + "label": "Document Type", + "options": "\nQuotation\nProject\nSales Order\nPurchase Order\nSales Invoice\nPurchase Invoice" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "cb_links", - "fieldtype": "Column Break", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, + "fieldname": "cb_links", + "fieldtype": "Column Break" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "depends_on": "", - "fieldname": "document_name", - "fieldtype": "Dynamic Link", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 1, - "in_list_view": 1, - "in_standard_filter": 1, - "label": "Document Name", - "length": 0, - "no_copy": 0, - "options": "document_type", - "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": "document_name", + "fieldtype": "Dynamic Link", + "in_global_search": 1, + "in_list_view": 1, + "in_standard_filter": 1, + "label": "Document Name", + "options": "document_type" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "amended_from", - "fieldtype": "Link", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Amended From", - "length": 0, - "no_copy": 1, - "options": "Contract", - "permlevel": 0, - "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 + "fieldname": "amended_from", + "fieldtype": "Link", + "label": "Amended From", + "no_copy": 1, + "options": "Contract", + "print_hide": 1, + "read_only": 1 } - ], - "has_web_view": 0, - "hide_heading": 0, - "hide_toolbar": 0, - "idx": 0, - "image_view": 0, - "in_create": 0, - "is_submittable": 1, - "issingle": 0, - "istable": 0, - "max_attachments": 0, - "modified": "2018-06-14 12:47:10.142988", - "modified_by": "Administrator", - "module": "CRM", - "name": "Contract", - "name_case": "", - "owner": "Administrator", + ], + "is_submittable": 1, + "modified": "2019-09-30 00:56:41.559681", + "modified_by": "Administrator", + "module": "CRM", + "name": "Contract", + "owner": "Administrator", "permissions": [ { - "amend": 1, - "cancel": 1, - "create": 1, - "delete": 1, - "email": 1, - "export": 1, - "if_owner": 0, - "import": 0, - "permlevel": 0, - "print": 1, - "read": 1, - "report": 1, - "role": "Sales Manager", - "set_user_permissions": 0, - "share": 1, - "submit": 1, + "amend": 1, + "cancel": 1, + "create": 1, + "delete": 1, + "email": 1, + "export": 1, + "print": 1, + "read": 1, + "report": 1, + "role": "Sales Manager", + "share": 1, + "submit": 1, "write": 1 - }, + }, { - "amend": 1, - "cancel": 1, - "create": 1, - "delete": 1, - "email": 1, - "export": 1, - "if_owner": 0, - "import": 0, - "permlevel": 0, - "print": 1, - "read": 1, - "report": 1, - "role": "Purchase Manager", - "set_user_permissions": 0, - "share": 1, - "submit": 1, + "amend": 1, + "cancel": 1, + "create": 1, + "delete": 1, + "email": 1, + "export": 1, + "print": 1, + "read": 1, + "report": 1, + "role": "Purchase Manager", + "share": 1, + "submit": 1, "write": 1 - }, + }, { - "amend": 1, - "cancel": 1, - "create": 1, - "delete": 1, - "email": 1, - "export": 1, - "if_owner": 0, - "import": 0, - "permlevel": 0, - "print": 1, - "read": 1, - "report": 1, - "role": "HR Manager", - "set_user_permissions": 0, - "share": 1, - "submit": 1, + "amend": 1, + "cancel": 1, + "create": 1, + "delete": 1, + "email": 1, + "export": 1, + "print": 1, + "read": 1, + "report": 1, + "role": "HR Manager", + "share": 1, + "submit": 1, "write": 1 - }, + }, { - "amend": 1, - "cancel": 1, - "create": 1, - "delete": 1, - "email": 1, - "export": 1, - "if_owner": 0, - "import": 0, - "permlevel": 0, - "print": 1, - "read": 1, - "report": 1, - "role": "System Manager", - "set_user_permissions": 0, - "share": 1, - "submit": 1, + "amend": 1, + "cancel": 1, + "create": 1, + "delete": 1, + "email": 1, + "export": 1, + "print": 1, + "read": 1, + "report": 1, + "role": "System Manager", + "share": 1, + "submit": 1, "write": 1 } - ], - "quick_entry": 0, - "read_only": 0, - "read_only_onload": 0, - "show_name_in_global_search": 1, - "sort_field": "modified", - "sort_order": "DESC", - "title_field": "", - "track_changes": 1, + ], + "show_name_in_global_search": 1, + "sort_field": "modified", + "sort_order": "DESC", + "track_changes": 1, "track_seen": 1 } \ No newline at end of file From 20194c4cc577f34e01a0f959568f1f45b89eac91 Mon Sep 17 00:00:00 2001 From: DeeMysterio Date: Mon, 30 Sep 2019 16:59:15 +0530 Subject: [PATCH 31/32] rename return/invoice to Purchase return/invoice (#19212) --- erpnext/stock/doctype/purchase_receipt/purchase_receipt.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.js b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.js index 2e8bc64038..aef53ed74b 100644 --- a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.js +++ b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.js @@ -115,12 +115,12 @@ erpnext.stock.PurchaseReceiptController = erpnext.buying.BuyingController.extend cur_frm.add_custom_button(__("Close"), this.close_purchase_receipt, __("Status")) } - cur_frm.add_custom_button(__('Return'), this.make_purchase_return, __('Create')); + cur_frm.add_custom_button(__('Purchase Return'), this.make_purchase_return, __('Create')); cur_frm.add_custom_button(__('Make Stock Entry'), cur_frm.cscript['Make Stock Entry'], __('Create')); if(flt(this.frm.doc.per_billed) < 100) { - cur_frm.add_custom_button(__('Invoice'), this.make_purchase_invoice, __('Create')); + cur_frm.add_custom_button(__('Purchase Invoice'), this.make_purchase_invoice, __('Create')); } cur_frm.add_custom_button(__('Retention Stock Entry'), this.make_retention_stock_entry, __('Create')); From 9d26c69c4a86c527b10a8333f75dc17628d85ce6 Mon Sep 17 00:00:00 2001 From: Chinmay Pai Date: Mon, 30 Sep 2019 16:59:42 +0530 Subject: [PATCH 32/32] fix(amazon-mws): python3 compatibility changes (#19209) Signed-off-by: Chinmay D. Pai --- .../doctype/amazon_mws_settings/amazon_methods.py | 12 +++++------- .../doctype/amazon_mws_settings/amazon_mws_api.py | 6 +++--- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/erpnext/erpnext_integrations/doctype/amazon_mws_settings/amazon_methods.py b/erpnext/erpnext_integrations/doctype/amazon_mws_settings/amazon_methods.py index b9be9c0b9c..2f39dc596b 100644 --- a/erpnext/erpnext_integrations/doctype/amazon_mws_settings/amazon_methods.py +++ b/erpnext/erpnext_integrations/doctype/amazon_mws_settings/amazon_methods.py @@ -4,10 +4,7 @@ from __future__ import unicode_literals import frappe, time, dateutil, math, csv -try: - from StringIO import StringIO -except ImportError: - from io import StringIO +from six import StringIO import erpnext.erpnext_integrations.doctype.amazon_mws_settings.amazon_mws_api as mws from frappe import _ @@ -26,7 +23,7 @@ def get_products_details(): listings_response = reports.get_report(report_id=report_id) #Get ASIN Codes - string_io = StringIO(listings_response.original) + string_io = StringIO(frappe.safe_decode(listings_response.original)) csv_rows = list(csv.reader(string_io, delimiter=str('\t'))) asin_list = list(set([row[1] for row in csv_rows[1:]])) #break into chunks of 10 @@ -294,7 +291,8 @@ def create_sales_order(order_json,after_date): so.submit() except Exception as e: - frappe.log_error(message=e, title="Create Sales Order") + import traceback + frappe.log_error(message=traceback.format_exc(), title="Create Sales Order") def create_customer(order_json): order_customer_name = "" @@ -451,7 +449,7 @@ def get_charges_and_fees(market_place_order_id): shipment_item_list = return_as_list(shipment_event.ShipmentEvent.ShipmentItemList.ShipmentItem) for shipment_item in shipment_item_list: - charges, fees = [] + charges, fees = [], [] if 'ItemChargeList' in shipment_item.keys(): charges = return_as_list(shipment_item.ItemChargeList.ChargeComponent) diff --git a/erpnext/erpnext_integrations/doctype/amazon_mws_settings/amazon_mws_api.py b/erpnext/erpnext_integrations/doctype/amazon_mws_settings/amazon_mws_api.py index 68c2b9c324..9925dc4a08 100755 --- a/erpnext/erpnext_integrations/doctype/amazon_mws_settings/amazon_mws_api.py +++ b/erpnext/erpnext_integrations/doctype/amazon_mws_settings/amazon_mws_api.py @@ -65,7 +65,8 @@ def calc_md5(string): """ md = hashlib.md5() md.update(string) - return base64.encodestring(md.digest()).strip('\n') + return base64.encodestring(md.digest()).strip('\n') if six.PY2 \ + else base64.encodebytes(md.digest()).decode().strip() def remove_empty(d): """ @@ -87,8 +88,7 @@ class DictWrapper(object): self.original = xml self._rootkey = rootkey self._mydict = xml_utils.xml2dict().fromstring(remove_namespace(xml)) - self._response_dict = self._mydict.get(self._mydict.keys()[0], - self._mydict) + self._response_dict = self._mydict.get(list(self._mydict)[0], self._mydict) @property def parsed(self):