Merge pull request #15360 from netchampfaris/marketplaces-fixes

fix(image): New Image component to consistently handle broken images
diff --git a/erpnext/accounts/doctype/payment_entry/payment_entry.json b/erpnext/accounts/doctype/payment_entry/payment_entry.json
index 1d5e130..daf2f2f 100644
--- a/erpnext/accounts/doctype/payment_entry/payment_entry.json
+++ b/erpnext/accounts/doctype/payment_entry/payment_entry.json
@@ -1939,7 +1939,7 @@
  "issingle": 0, 
  "istable": 0, 
  "max_attachments": 0, 
- "modified": "2018-08-21 15:44:28.647566", 
+ "modified": "2018-09-07 15:44:28.647566", 
  "modified_by": "Administrator", 
  "module": "Accounts", 
  "name": "Payment Entry", 
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 cb11ece..3234e7a 100644
--- a/erpnext/erpnext_integrations/doctype/amazon_mws_settings/amazon_methods.py
+++ b/erpnext/erpnext_integrations/doctype/amazon_mws_settings/amazon_methods.py
@@ -3,8 +3,12 @@
 # For license information, please see license.txt
 
 from __future__ import unicode_literals
-import frappe, time, dateutil, math, csv, StringIO
-import amazon_mws_api as mws
+import frappe, time, dateutil, math, csv
+try:
+    from StringIO import StringIO
+except ImportError:
+    from io import StringIO
+import erpnext.erpnext_integrations.doctype.amazon_mws_settings.amazon_mws_api as mws
 from frappe import _
 
 #Get and Create Products
@@ -22,7 +26,7 @@
 			listings_response = reports.get_report(report_id=report_id)
 
 			#Get ASIN Codes
-			string_io = StringIO.StringIO(listings_response.original)
+			string_io = StringIO(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
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 1e131e8..bf6d85b 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
@@ -9,7 +9,7 @@
 import hashlib
 import hmac
 import base64
-import xml_utils
+from erpnext.erpnext_integrations.doctype.amazon_mws_settings import xml_utils
 import re
 try:
 	from xml.etree.ElementTree import ParseError as XMLError
diff --git a/erpnext/erpnext_integrations/doctype/amazon_mws_settings/amazon_mws_settings.json b/erpnext/erpnext_integrations/doctype/amazon_mws_settings/amazon_mws_settings.json
index 771d1f2..607ca4f 100644
--- a/erpnext/erpnext_integrations/doctype/amazon_mws_settings/amazon_mws_settings.json
+++ b/erpnext/erpnext_integrations/doctype/amazon_mws_settings/amazon_mws_settings.json
@@ -864,7 +864,7 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
-   "default": "1", 
+   "default": "", 
    "description": "Check this to enable a scheduled Daily synchronization routine via scheduler", 
    "fieldname": "enable_synch", 
    "fieldtype": "Check", 
@@ -935,7 +935,7 @@
  "issingle": 1, 
  "istable": 0, 
  "max_attachments": 0, 
- "modified": "2018-08-23 20:52:58.471424", 
+ "modified": "2018-09-07 16:45:44.439834", 
  "modified_by": "Administrator", 
  "module": "ERPNext Integrations", 
  "name": "Amazon MWS Settings", 
diff --git a/erpnext/erpnext_integrations/doctype/amazon_mws_settings/amazon_mws_settings.py b/erpnext/erpnext_integrations/doctype/amazon_mws_settings/amazon_mws_settings.py
index 7e64915..249a73f 100644
--- a/erpnext/erpnext_integrations/doctype/amazon_mws_settings/amazon_mws_settings.py
+++ b/erpnext/erpnext_integrations/doctype/amazon_mws_settings/amazon_mws_settings.py
@@ -7,12 +7,15 @@
 from frappe.model.document import Document
 import dateutil
 from frappe.custom.doctype.custom_field.custom_field import create_custom_fields
-from amazon_methods import get_products_details, get_orders
+from erpnext.erpnext_integrations.doctype.amazon_mws_settings.amazon_methods import get_products_details, get_orders
 
 class AmazonMWSSettings(Document):
 	def validate(self):
 		if self.enable_amazon == 1:
+			self.enable_synch = 1
 			setup_custom_fields()
+		else:
+			self.enable_synch = 0
 
 	def get_products_details(self):
 		if self.enable_amazon == 1:
@@ -25,7 +28,7 @@
 
 def schedule_get_order_details():
 	mws_settings = frappe.get_doc("Amazon MWS Settings")
-	if mws_settings.enable_synch:
+	if mws_settings.enable_synch and mws_settings.enable_amazon:
 		after_date = dateutil.parser.parse(mws_settings.after_date).strftime("%Y-%m-%d")
 		get_orders(after_date = after_date)
 
diff --git a/erpnext/healthcare/utils.py b/erpnext/healthcare/utils.py
index 1045d49..1be82e2 100644
--- a/erpnext/healthcare/utils.py
+++ b/erpnext/healthcare/utils.py
@@ -307,8 +307,8 @@
 		fee_validity = create_fee_validity(appointment_doc.practitioner, appointment_doc.patient, appointment_doc.appointment_date, ref_invoice)
 		visited = fee_validity.visited
 
-	print "do_not_update: ", do_not_update
-	print "visited: ", visited
+	print("do_not_update: ", do_not_update)
+	print("visited: ", visited)
 
 	# Mark All Patient Appointment invoiced = True in the validity range do not cross the max visit
 	if (method == "on_cancel"):
@@ -410,7 +410,7 @@
 					lft > %s and rgt < %s""",
 					(each['lft'], each['rgt']))
 				for child in child_list:
-					print child[0], child[1]
+					print(child[0], child[1])
 					if not occupied:
 						occupied = 0
 					if child[1] == "Occupied":
diff --git a/erpnext/hub_node/doctype/hub_tracked_item/hub_tracked_item.json b/erpnext/hub_node/doctype/hub_tracked_item/hub_tracked_item.json
index 9384adb..2e89887 100644
--- a/erpnext/hub_node/doctype/hub_tracked_item/hub_tracked_item.json
+++ b/erpnext/hub_node/doctype/hub_tracked_item/hub_tracked_item.json
@@ -120,7 +120,7 @@
  "issingle": 0, 
  "istable": 0, 
  "max_attachments": 0, 
- "modified": "2018-08-19 22:24:06.207307", 
+ "modified": "2018-09-10 11:37:35.951019", 
  "modified_by": "Administrator", 
  "module": "Hub Node", 
  "name": "Hub Tracked Item", 
@@ -145,6 +145,25 @@
    "share": 1, 
    "submit": 0, 
    "write": 1
+  }, 
+  {
+   "amend": 0, 
+   "cancel": 0, 
+   "create": 1, 
+   "delete": 1, 
+   "email": 1, 
+   "export": 1, 
+   "if_owner": 0, 
+   "import": 0, 
+   "permlevel": 0, 
+   "print": 1, 
+   "read": 1, 
+   "report": 1, 
+   "role": "Item Manager", 
+   "set_user_permissions": 0, 
+   "share": 1, 
+   "submit": 0, 
+   "write": 1
   }
  ], 
  "quick_entry": 1, 
diff --git a/erpnext/patches.txt b/erpnext/patches.txt
index a83dfd6..3b3c25b 100644
--- a/erpnext/patches.txt
+++ b/erpnext/patches.txt
@@ -434,7 +434,7 @@
 erpnext.patches.v8_6.update_timesheet_company_from_PO
 erpnext.patches.v8_6.set_write_permission_for_quotation_for_sales_manager
 erpnext.patches.v8_5.remove_project_type_property_setter
-erpnext.patches.v8_7.add_more_gst_fields #21-09-2017
+erpnext.patches.v8_7.sync_india_custom_fields
 erpnext.patches.v8_7.fix_purchase_receipt_status
 erpnext.patches.v8_6.rename_bom_update_tool
 erpnext.patches.v8_7.set_offline_in_pos_settings #11-09-17
@@ -486,10 +486,8 @@
 erpnext.patches.v10_0.fichier_des_ecritures_comptables_for_france
 erpnext.patches.v10_0.update_assessment_plan
 erpnext.patches.v10_0.update_assessment_result
-erpnext.patches.v10_0.added_extra_gst_custom_field
 erpnext.patches.v10_0.set_default_payment_terms_based_on_company
 erpnext.patches.v10_0.update_sales_order_link_to_purchase_order
-erpnext.patches.v10_0.added_extra_gst_custom_field_in_gstr2 #2018-02-13
 erpnext.patches.v10_0.item_barcode_childtable_migrate
 erpnext.patches.v10_0.rename_price_to_rate_in_pricing_rule
 erpnext.patches.v10_0.set_currency_in_pricing_rule
diff --git a/erpnext/patches/v10_0/added_extra_gst_custom_field.py b/erpnext/patches/v10_0/added_extra_gst_custom_field.py
deleted file mode 100644
index 000e8fd..0000000
--- a/erpnext/patches/v10_0/added_extra_gst_custom_field.py
+++ /dev/null
@@ -1,12 +0,0 @@
-import frappe
-from erpnext.regional.india.setup  import make_custom_fields
-
-def execute():
-	company = frappe.get_all('Company', filters = {'country': 'India'})
-	if not company:
-		return
-
-	frappe.reload_doc("hr", "doctype", "Employee Tax Exemption Declaration")
-	frappe.reload_doc("hr", "doctype", "Employee Tax Exemption Proof Submission")
-
-	make_custom_fields(update=False)
\ No newline at end of file
diff --git a/erpnext/patches/v10_0/remove_and_copy_fields_in_physician.py b/erpnext/patches/v10_0/remove_and_copy_fields_in_physician.py
index f632c94..0739671 100644
--- a/erpnext/patches/v10_0/remove_and_copy_fields_in_physician.py
+++ b/erpnext/patches/v10_0/remove_and_copy_fields_in_physician.py
@@ -5,7 +5,7 @@
 		frappe.reload_doc("healthcare", "doctype", "physician")
 		frappe.reload_doc("healthcare", "doctype", "physician_service_unit_schedule")
 
-		if frappe.db.has_column('Physician', 'physician_schedule'):
+		if frappe.db.has_column('Physician', 'physician_schedules'):
 			for doc in frappe.get_all('Physician'):
 				_doc = frappe.get_doc('Physician', doc.name)
 				if _doc.physician_schedule:
diff --git a/erpnext/patches/v11_0/make_job_card.py b/erpnext/patches/v11_0/make_job_card.py
index be106e6..9c41c0b 100644
--- a/erpnext/patches/v11_0/make_job_card.py
+++ b/erpnext/patches/v11_0/make_job_card.py
@@ -3,6 +3,7 @@
 
 from __future__ import unicode_literals
 import frappe
+from erpnext.manufacturing.doctype.work_order.work_order import create_job_card
 
 def execute():
 	frappe.reload_doc('manufacturing', 'doctype', 'work_order')
@@ -10,9 +11,16 @@
 	frappe.reload_doc('manufacturing', 'doctype', 'job_card')
 	frappe.reload_doc('manufacturing', 'doctype', 'job_card_item')
 
-	for d in frappe.db.sql("""select work_order, name from tabTimesheet
-		where (work_order is not null and work_order != '') and docstatus = 0""", as_dict=1):
-		if d.work_order:
-			doc = frappe.get_doc('Work Order', d.work_order)
-			doc.create_job_card()
-			frappe.delete_doc('Timesheet', d.name)
\ No newline at end of file
+	fieldname = frappe.db.get_value('DocField', {'fieldname': 'work_order', 'parent': 'Timesheet'}, 'fieldname')
+	if not fieldname:
+		fieldname = frappe.db.get_value('DocField', {'fieldname': 'production_order', 'parent': 'Timesheet'}, 'fieldname')
+		if not fieldname: return
+
+	for d in frappe.get_all('Timesheet',
+		filters={fieldname: ['!=', ""], 'docstatus': 0},
+		fields=[fieldname, 'name']):
+		if d[fieldname]:
+			doc = frappe.get_doc('Work Order', d[fieldname])
+			for row in doc.operations:
+				create_job_card(doc, row, auto_create=True)
+			frappe.delete_doc('Timesheet', d.name)
diff --git a/erpnext/patches/v11_0/redesign_healthcare_billing_work_flow.py b/erpnext/patches/v11_0/redesign_healthcare_billing_work_flow.py
index f8ff015..dc7ff13 100644
--- a/erpnext/patches/v11_0/redesign_healthcare_billing_work_flow.py
+++ b/erpnext/patches/v11_0/redesign_healthcare_billing_work_flow.py
@@ -15,6 +15,9 @@
 	frappe.reload_doc('accounts', 'doctype', 'loyalty_program')
 	frappe.reload_doc('accounts', 'doctype', 'sales_invoice_item')
 
+	if "healthcare" not in frappe.get_active_domains():
+		return
+
 	healthcare_custom_field_in_sales_invoice()
 	for si_ref_doc in sales_invoice_referenced_doc:
 		if frappe.db.exists('DocType', si_ref_doc):
diff --git a/erpnext/patches/v8_7/add_more_gst_fields.py b/erpnext/patches/v8_7/add_more_gst_fields.py
deleted file mode 100644
index d2085e0..0000000
--- a/erpnext/patches/v8_7/add_more_gst_fields.py
+++ /dev/null
@@ -1,11 +0,0 @@
-import frappe
-from erpnext.regional.india.setup  import make_custom_fields
-
-def execute():
-	company = frappe.get_all('Company', filters = {'country': 'India'})
-	if not company:
-		return
-
-	frappe.reload_doc('hr', 'doctype', 'employee_tax_exemption_declaration')
-	frappe.reload_doc('hr', 'doctype', 'employee_tax_exemption_proof_submission')
-	make_custom_fields()
\ No newline at end of file
diff --git a/erpnext/patches/v10_0/added_extra_gst_custom_field_in_gstr2.py b/erpnext/patches/v8_7/sync_india_custom_fields.py
similarity index 61%
rename from erpnext/patches/v10_0/added_extra_gst_custom_field_in_gstr2.py
rename to erpnext/patches/v8_7/sync_india_custom_fields.py
index 12aa5fd..323b5bc 100644
--- a/erpnext/patches/v10_0/added_extra_gst_custom_field_in_gstr2.py
+++ b/erpnext/patches/v8_7/sync_india_custom_fields.py
@@ -6,11 +6,14 @@
 	if not company:
 		return
 
+	frappe.reload_doc('hr', 'doctype', 'employee_tax_exemption_declaration')
+	frappe.reload_doc('hr', 'doctype', 'employee_tax_exemption_proof_submission')
+
 	for doctype in ["Sales Invoice", "Delivery Note", "Purchase Invoice"]:
 		frappe.db.sql("""delete from `tabCustom Field` where dt = %s
 			and fieldname in ('port_code', 'shipping_bill_number', 'shipping_bill_date')""", doctype)
 
-	make_custom_fields(update=False)
+	make_custom_fields()
 
 	frappe.db.sql("""
 		update `tabCustom Field`
@@ -18,4 +21,8 @@
 		where fieldname = 'reason_for_issuing_document'
 	""")
 
-
+	frappe.db.sql("""
+		update tabAddress
+		set gst_state_number=concat("0", gst_state_number)
+		where ifnull(gst_state_number, '') != '' and gst_state_number<10
+	""")
\ No newline at end of file
diff --git a/erpnext/regional/india/setup.py b/erpnext/regional/india/setup.py
index da9e469..07a42ff 100644
--- a/erpnext/regional/india/setup.py
+++ b/erpnext/regional/india/setup.py
@@ -171,7 +171,7 @@
 			dict(fieldname='gst_state', label='GST State', fieldtype='Select',
 				options='\n'.join(states), insert_after='gstin'),
 			dict(fieldname='gst_state_number', label='GST State Number',
-				fieldtype='Int', insert_after='gst_state', read_only=1),
+				fieldtype='Data', insert_after='gst_state', read_only=1),
 		],
 		'Purchase Invoice': invoice_gst_fields + purchase_invoice_gst_fields,
 		'Sales Invoice': invoice_gst_fields + sales_invoice_gst_fields,
diff --git a/erpnext/setup/doctype/company/company.json b/erpnext/setup/doctype/company/company.json
index 96d1116..9a245e2 100644
--- a/erpnext/setup/doctype/company/company.json
+++ b/erpnext/setup/doctype/company/company.json
@@ -837,7 +837,7 @@
    "label": "Create Chart Of Accounts Based On", 
    "length": 0, 
    "no_copy": 0, 
-   "options": "\nStandard Template\nExisting Company\n\n\n", 
+   "options": "\nStandard Template\nExisting Company", 
    "permlevel": 0, 
    "precision": "", 
    "print_hide": 0, 
@@ -871,7 +871,7 @@
    "label": "Chart Of Accounts Template", 
    "length": 0, 
    "no_copy": 1, 
-   "options": "\n\n\n", 
+   "options": "", 
    "permlevel": 0, 
    "precision": "", 
    "print_hide": 0, 
@@ -2836,7 +2836,7 @@
  "istable": 0, 
  "max_attachments": 0, 
  "menu_index": 0, 
- "modified": "2018-09-01 16:03:30.716918", 
+ "modified": "2018-09-07 16:03:30.716918", 
  "modified_by": "cave@aperture.com", 
  "module": "Setup", 
  "name": "Company", 
diff --git a/erpnext/stock/report/stock_projected_qty/stock_projected_qty.js b/erpnext/stock/report/stock_projected_qty/stock_projected_qty.js
index 937c0a2..51b9b0c 100644
--- a/erpnext/stock/report/stock_projected_qty/stock_projected_qty.js
+++ b/erpnext/stock/report/stock_projected_qty/stock_projected_qty.js
@@ -27,10 +27,16 @@
 			}
 		},
 		{
+			"fieldname":"item_group",
+			"label": __("Item Group"),
+			"fieldtype": "Link",
+			"options": "Item Group"
+		},
+		{
 			"fieldname":"brand",
 			"label": __("Brand"),
 			"fieldtype": "Link",
 			"options": "Brand"
 		}
 	]
-}
\ No newline at end of file
+}
diff --git a/erpnext/stock/report/stock_projected_qty/stock_projected_qty.py b/erpnext/stock/report/stock_projected_qty/stock_projected_qty.py
index 89a256c..3e6e5a5 100644
--- a/erpnext/stock/report/stock_projected_qty/stock_projected_qty.py
+++ b/erpnext/stock/report/stock_projected_qty/stock_projected_qty.py
@@ -39,6 +39,9 @@
 
 		if filters.brand and filters.brand != item.brand:
 			continue
+			
+		elif filters.item_group and filters.item_group != item.item_group:
+			continue
 
 		elif filters.company and filters.company != company:
 			continue