diff --git a/erpnext/controllers/accounts_controller.py b/erpnext/controllers/accounts_controller.py
index 61cf53e6d84..bcdff37ae69 100644
--- a/erpnext/controllers/accounts_controller.py
+++ b/erpnext/controllers/accounts_controller.py
@@ -104,6 +104,8 @@ class AccountsController(TransactionBase):
else:
self.validate_deferred_start_and_end_date()
+ self.set_inter_company_account()
+
validate_regional(self)
validate_einvoice_fields(self)
@@ -877,6 +879,38 @@ class AccountsController(TransactionBase):
else:
return frappe.db.get_single_value("Global Defaults", "disable_rounded_total")
+ def set_inter_company_account(self):
+ """
+ Set intercompany account for inter warehouse transactions
+ This account will be used in case billing company and internal customer's
+ representation company is same
+ """
+
+ if self.is_internal_transfer() and not self.unrealized_profit_loss_account:
+ unrealized_profit_loss_account = frappe.db.get_value('Company', self.company, 'unrealized_profit_loss_account')
+
+ if not unrealized_profit_loss_account:
+ msg = _("Please select Unrealized Profit / Loss account or add default Unrealized Profit / Loss account account for company {0}").format(
+ frappe.bold(self.company))
+ frappe.throw(msg)
+
+ self.unrealized_profit_loss_account = unrealized_profit_loss_account
+
+ def is_internal_transfer(self):
+ """
+ It will an internal transfer if its an internal customer and representation
+ company is same as billing company
+ """
+ if self.doctype == 'Sales Invoice':
+ internal_party_field = 'is_internal_customer'
+ else:
+ internal_party_field = 'is_internal_supplier'
+
+ if self.get(internal_party_field) and (self.represents_company == self.company):
+ return True
+
+ return False
+
@frappe.whitelist()
def get_tax_rate(account_head):
return frappe.db.get_value("Account", account_head, ["tax_rate", "account_name"], as_dict=True)
diff --git a/erpnext/controllers/buying_controller.py b/erpnext/controllers/buying_controller.py
index 89b48f07ee8..1fc88a78153 100644
--- a/erpnext/controllers/buying_controller.py
+++ b/erpnext/controllers/buying_controller.py
@@ -42,6 +42,7 @@ class BuyingController(StockController):
self.validate_items()
self.set_qty_as_per_stock_uom()
self.validate_stock_or_nonstock_items()
+ self.update_tax_category_for_internal_transfer()
self.validate_warehouse()
self.validate_from_warehouse()
self.set_supplier_address()
@@ -94,13 +95,23 @@ class BuyingController(StockController):
def validate_stock_or_nonstock_items(self):
if self.meta.get_field("taxes") and not self.get_stock_items() and not self.get_asset_items():
- tax_for_valuation = [d for d in self.get("taxes")
+ msg = _('Tax Category has been changed to "Total" because all the Items are non-stock items')
+ self.update_tax_category(msg)
+
+ def update_tax_category_for_internal_transfer(self):
+ if self.doctype == 'Purchase Invoice' and self.is_internal_transfer():
+ msg = _('Tax Category has been changed to "Total" as its an internal purchase.')
+ self.update_tax_category(msg)
+
+ def update_tax_category(self, msg):
+ tax_for_valuation = [d for d in self.get("taxes")
if d.category in ["Valuation", "Valuation and Total"]]
- if tax_for_valuation:
- for d in tax_for_valuation:
- d.category = 'Total'
- msgprint(_('Tax Category has been changed to "Total" because all the Items are non-stock items'))
+ if tax_for_valuation:
+ for d in tax_for_valuation:
+ d.category = 'Total'
+
+ msgprint(msg)
def validate_asset_return(self):
if self.doctype not in ['Purchase Receipt', 'Purchase Invoice'] or not self.is_return:
diff --git a/erpnext/controllers/stock_controller.py b/erpnext/controllers/stock_controller.py
index 2017f16d080..deb83fa7371 100644
--- a/erpnext/controllers/stock_controller.py
+++ b/erpnext/controllers/stock_controller.py
@@ -92,9 +92,16 @@ class StockController(AccountsController):
sle = self.update_stock_ledger_entries(sle)
+ # expense account/ target_warehouse / source_warehouse
+ if item_row.get('target_warehouse'):
+ warehouse = item_row.get('target_warehouse')
+ expense_account = warehouse_account[warehouse]["account"]
+ else:
+ expense_account = item_row.expense_account
+
gl_list.append(self.get_gl_dict({
"account": warehouse_account[sle.warehouse]["account"],
- "against": item_row.expense_account,
+ "against": expense_account,
"cost_center": item_row.cost_center,
"project": item_row.project or self.get('project'),
"remarks": self.get("remarks") or "Accounting Entry for Stock",
@@ -102,7 +109,6 @@ class StockController(AccountsController):
"is_opening": item_row.get("is_opening") or self.get("is_opening") or "No",
}, warehouse_account[sle.warehouse]["account_currency"], item=item_row))
- # expense account
gl_list.append(self.get_gl_dict({
"account": item_row.expense_account,
"against": warehouse_account[sle.warehouse]["account"],
diff --git a/erpnext/selling/doctype/customer/customer.py b/erpnext/selling/doctype/customer/customer.py
index ca62488a8c4..c8e3e6764aa 100644
--- a/erpnext/selling/doctype/customer/customer.py
+++ b/erpnext/selling/doctype/customer/customer.py
@@ -388,10 +388,9 @@ def check_credit_limit(customer, company, ignore_outstanding_sales_order=False,
credit_controller_users = get_users_with_role(credit_controller_role or "Sales Master Manager")
# form a list of emails and names to show to the user
- credit_controller_users = [get_formatted_email(user).replace("<", "(").replace(">", ")") for user in credit_controller_users]
-
- if not credit_controller_users:
- frappe.throw(_("Please contact your administrator to extend the credit limits for {0}.".format(customer)))
+ credit_controller_users_formatted = [get_formatted_email(user).replace("<", "(").replace(">", ")") for user in credit_controller_users]
+ if not credit_controller_users_formatted:
+ frappe.throw(_("Please contact your administrator to extend the credit limits for {0}.").format(customer))
message = """Please contact any of the following users to extend the credit limits for {0}: