Merge pull request #19084 from rohitwaghchaure/offline_pos_currency_conversion_issue_for_v11

fix: plc conversion issue for offline pos
diff --git a/erpnext/accounts/doctype/account/account.py b/erpnext/accounts/doctype/account/account.py
index 1adc4c4..7cca8d2 100644
--- a/erpnext/accounts/doctype/account/account.py
+++ b/erpnext/accounts/doctype/account/account.py
@@ -100,7 +100,10 @@
 		if ancestors:
 			if frappe.get_value("Company", self.company, "allow_account_creation_against_child_company"):
 				return
-			frappe.throw(_("Please add the account to root level Company - %s" % ancestors[0]))
+
+			if not frappe.db.get_value("Account",
+				{'account_name': self.account_name, 'company': ancestors[0]}, 'name'):
+				frappe.throw(_("Please add the account to root level Company - %s" % ancestors[0]))
 		else:
 			descendants = get_descendants_of('Company', self.company)
 			if not descendants: return
@@ -114,24 +117,7 @@
 
 			if not parent_acc_name_map: return
 
-			for company in descendants:
-				if not parent_acc_name_map.get(company):
-					frappe.throw(_("While creating account for child Company {0}, parent account {1} not found. Please create the parent account in corresponding COA")
-						.format(company, parent_acc_name))
-
-				doc = frappe.copy_doc(self)
-				doc.flags.ignore_root_company_validation = True
-				doc.update({
-					"company": company,
-					# parent account's currency should be passed down to child account's curreny
-					# if it is None, it picks it up from default company currency, which might be unintended
-					"account_currency": self.account_currency,
-					"parent_account": parent_acc_name_map[company]
-				})
-				if not self.check_if_child_acc_exists(doc):
-					doc.save()
-				frappe.msgprint(_("Account {0} is added in the child company {1}")
-					.format(doc.name, company))
+			self.create_account_for_child_company(parent_acc_name_map, descendants)
 
 	def validate_group_or_ledger(self):
 		if self.get("__islocal"):
@@ -173,23 +159,48 @@
 			if frappe.db.get_value("GL Entry", {"account": self.name}):
 				frappe.throw(_("Currency can not be changed after making entries using some other currency"))
 
-	def check_if_child_acc_exists(self, doc):
-		''' Checks if a account in parent company exists in the  '''
-		info = frappe.db.get_value("Account", {
-			"account_name": doc.account_name,
-			"account_number": doc.account_number
-		}, ['company', 'account_currency', 'is_group', 'root_type', 'account_type', 'balance_must_be', 'account_name'], as_dict=1)
+	def create_account_for_child_company(self, parent_acc_name_map, descendants):
+		for company in descendants:
+			if not parent_acc_name_map.get(company):
+				frappe.throw(_("While creating account for child Company {0}, parent account {1} not found. Please create the parent account in corresponding COA")
+					.format(company, parent_acc_name))
 
-		if not info:
-			return
+			filters = {
+				"account_name": self.account_name,
+				"company": company
+			}
 
-		doc = vars(doc)
-		dict_diff = [k for k in info if k in doc and info[k] != doc[k] and k != "company"]
-		if dict_diff:
-			frappe.throw(_("Account {0} already exists in child company {1}. The following fields have different values, they should be same:<ul><li>{2}</li></ul>")
-				.format(info.account_name, info.company, '</li><li>'.join(dict_diff)))
-		else:
-			return True
+			if self.account_number:
+				filters["account_number"] = self.account_number
+
+			child_account = frappe.db.get_value("Account", filters, 'name')
+
+			if not child_account:
+				doc = frappe.copy_doc(self)
+				doc.flags.ignore_root_company_validation = True
+				doc.update({
+					"company": company,
+					# parent account's currency should be passed down to child account's curreny
+					# if it is None, it picks it up from default company currency, which might be unintended
+					"account_currency": self.account_currency,
+					"parent_account": parent_acc_name_map[company]
+				})
+
+				doc.save()
+				frappe.msgprint(_("Account {0} is added in the child company {1}")
+					.format(doc.name, company))
+			elif child_account:
+				# update the parent company's value in child companies
+				doc = frappe.get_doc("Account", child_account)
+				parent_value_changed = False
+				for field in ['account_type', 'account_currency',
+					'freeze_account', 'balance_must_be']:
+					if doc.get(field) != self.get(field):
+						parent_value_changed = True
+						doc.set(field, self.get(field))
+
+				if parent_value_changed:
+					doc.save()
 
 	def convert_group_to_ledger(self):
 		if self.check_if_child_exists():
diff --git a/erpnext/accounts/doctype/accounting_dimension/accounting_dimension.py b/erpnext/accounts/doctype/accounting_dimension/accounting_dimension.py
index 59d7557..af51fc5 100644
--- a/erpnext/accounts/doctype/accounting_dimension/accounting_dimension.py
+++ b/erpnext/accounts/doctype/accounting_dimension/accounting_dimension.py
@@ -174,7 +174,7 @@
 		return accounting_dimensions
 
 def get_checks_for_pl_and_bs_accounts():
-	dimensions = frappe.db.sql("""SELECT p.label, p.disabled, p.fieldname, c.company, c.mandatory_for_pl, c.mandatory_for_bs
+	dimensions = frappe.db.sql("""SELECT p.label, p.disabled, p.fieldname, c.default_dimension, c.company, c.mandatory_for_pl, c.mandatory_for_bs
 		FROM `tabAccounting Dimension`p ,`tabAccounting Dimension Detail` c
 		WHERE p.name = c.parent""", as_dict=1)
 
diff --git a/erpnext/assets/doctype/asset/depreciation.py b/erpnext/assets/doctype/asset/depreciation.py
index 61108ec..e911e80 100644
--- a/erpnext/assets/doctype/asset/depreciation.py
+++ b/erpnext/assets/doctype/asset/depreciation.py
@@ -6,6 +6,7 @@
 import frappe
 from frappe import _
 from frappe.utils import flt, today, getdate, cint
+from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import get_checks_for_pl_and_bs_accounts
 
 def post_depreciation_entries(date=None):
 	# Return if automatic booking of asset depreciation is disabled
@@ -41,6 +42,8 @@
 
 	depreciation_cost_center = asset.cost_center or depreciation_cost_center
 
+	accounting_dimensions = get_checks_for_pl_and_bs_accounts()
+
 	for d in asset.get("schedules"):
 		if not d.journal_entry and getdate(d.schedule_date) <= getdate(date):
 			je = frappe.new_doc("Journal Entry")
@@ -51,23 +54,40 @@
 			je.finance_book = d.finance_book
 			je.remark = "Depreciation Entry against {0} worth {1}".format(asset_name, d.depreciation_amount)
 
-			je.append("accounts", {
+			credit_entry = {
 				"account": accumulated_depreciation_account,
 				"credit_in_account_currency": d.depreciation_amount,
 				"reference_type": "Asset",
 				"reference_name": asset.name
-			})
+			}
 
-			je.append("accounts", {
+			debit_entry = {
 				"account": depreciation_expense_account,
 				"debit_in_account_currency": d.depreciation_amount,
 				"reference_type": "Asset",
 				"reference_name": asset.name,
 				"cost_center": depreciation_cost_center
-			})
+			}
+
+			for dimension in accounting_dimensions:
+				if (asset.get(dimension['fieldname']) or dimension.get('mandatory_for_bs')):
+					credit_entry.update({
+						dimension['fieldname']: asset.get(dimension['fieldname']) or dimension.get('default_dimension')
+					})
+
+				if (asset.get(dimension['fieldname']) or dimension.get('mandatory_for_pl')):
+					debit_entry.update({
+						dimension['fieldname']: asset.get(dimension['fieldname']) or dimension.get('default_dimension')
+					})
+
+			je.append("accounts", credit_entry)
+
+			je.append("accounts", debit_entry)
 
 			je.flags.ignore_permissions = True
-			je.submit()
+			je.save()
+			if not je.meta.get_workflow():
+				je.submit()
 
 			d.db_set("journal_entry", je.name)
 
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 1c39d88..b9be9c0 100644
--- a/erpnext/erpnext_integrations/doctype/amazon_mws_settings/amazon_methods.py
+++ b/erpnext/erpnext_integrations/doctype/amazon_mws_settings/amazon_methods.py
@@ -89,8 +89,6 @@
 			end_date=end_date,
 			marketplaceids=marketplaceids)
 
-	#add time delay to wait for amazon to generate report
-	time.sleep(20)
 	report_request_id = report_response.parsed["ReportRequestInfo"]["ReportRequestId"]["value"]
 	generated_report_id = None
 	#poll to get generated report
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 cc4ccc5..68c2b9c 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
@@ -10,6 +10,7 @@
 import hashlib
 import hmac
 import base64
+import six
 from erpnext.erpnext_integrations.doctype.amazon_mws_settings import xml_utils
 import re
 try:
@@ -77,6 +78,7 @@
 	return d
 
 def remove_namespace(xml):
+	xml = xml.decode('utf-8')
 	regex = re.compile(' xmlns(:ns2)?="[^"]+"|(ns2:)|(xml:)')
 	return regex.sub('', xml)
 
@@ -172,9 +174,10 @@
 			'SignatureMethod': 'HmacSHA256',
 		}
 		params.update(extra_data)
-		request_description = '&'.join(['%s=%s' % (k, urllib.quote(params[k], safe='-_.~').encode('utf-8')) for k in sorted(params)])
+		quote = urllib.quote if six.PY2 else urllib.parse.quote
+		request_description = '&'.join(['%s=%s' % (k, quote(params[k], safe='-_.~')) for k in sorted(params)])
 		signature = self.calc_signature(method, request_description)
-		url = '%s%s?%s&Signature=%s' % (self.domain, self.uri, request_description, urllib.quote(signature))
+		url = '%s%s?%s&Signature=%s' % (self.domain, self.uri, request_description, quote(signature))
 		headers = {'User-Agent': 'python-amazon-mws/0.0.1 (Language=Python)'}
 		headers.update(kwargs.get('extra_headers', {}))
 
@@ -218,7 +221,10 @@
 		"""Calculate MWS signature to interface with Amazon
 		"""
 		sig_data = method + '\n' + self.domain.replace('https://', '').lower() + '\n' + self.uri + '\n' + request_description
-		return base64.b64encode(hmac.new(str(self.secret_key), sig_data, hashlib.sha256).digest())
+		sig_data = sig_data.encode('utf-8')
+		secret_key = self.secret_key.encode('utf-8')
+		digest = hmac.new(secret_key, sig_data, hashlib.sha256).digest()
+		return base64.b64encode(digest).decode('utf-8')
 
 	def get_timestamp(self):
 		"""