Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add company validation for all accounting dimension doctypes #44774

Draft
wants to merge 4 commits into
base: develop
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,52 @@ def tearDown(self):
frappe.flags.accounting_dimensions_details = None
frappe.flags.dimension_filter_map = None

def test_company_level_accounting_dimension_validation(self):
company = frappe.new_doc("Company")
company.company_name = "_Test New Company"
company.abbr = "TNC"
company.default_currency = "INR"
company.country = "India"
company.save()

cost_center = frappe.get_doc(
{
"doctype": "Cost Center",
"cost_center_name": "Main - TNC",
"parent_cost_center": "_Test New Company - TNC",
"is_group": 0,
"company": "_Test New Company",
}
)
cost_center.save()

company1 = frappe.new_doc("Company")
company1.company_name = "_Test Demo Company"
company1.abbr = "TDC"
company1.default_currency = "INR"
company1.country = "India"
company1.save()

cost_center1 = frappe.get_doc(
{
"doctype": "Cost Center",
"cost_center_name": "Main - TDC",
"parent_cost_center": "_Test Demo Company - TDC",
"is_group": 0,
"company": "_Test Demo Company",
}
)
cost_center1.save()

si = create_sales_invoice(
company="_Test New Company", customer="_Test Customer", cost_center="Main - TDC", do_not_save=True
)
self.assertRaises(frappe.ValidationError, si.save)

si.update({"cost_center": "Main - TNC"})
si.get("items")[0].update({"cost_center": "Main - TDC"})
self.assertRaises(frappe.ValidationError, si.save)


def create_dimension():
frappe.set_user("Administrator")
Expand Down
19 changes: 16 additions & 3 deletions erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ def make(self):
@classmethod
def setUpClass(cls):
super().setUpClass()
cls.enterClassContext(cls.change_settings("Selling Settings", validate_selling_price=0))
# cls.enterClassContext(cls.change_settings("Selling Settings", validate_selling_price=0))
unlink_payment_on_cancel_of_invoice()

@classmethod
Expand Down Expand Up @@ -3115,6 +3115,15 @@ def test_sales_invoice_against_supplier_usd_with_dimensions(self):
# enable common party accounting
frappe.db.set_single_value("Accounts Settings", "enable_common_party_accounting", 1)

department = frappe.new_doc("Department")
department.department_name = "Test Department"
department.company = "_Test Company"
department.save()

location = frappe.get_doc("Accounting Dimension", "Location")
location.dimension_defaults[0].mandatory_for_bs = 0
location.save()

# create a dimension and make it mandatory
if not frappe.get_all("Accounting Dimension", filters={"document_type": "Department"}):
dim = frappe.get_doc(
Expand All @@ -3139,7 +3148,7 @@ def test_sales_invoice_against_supplier_usd_with_dimensions(self):
si = create_sales_invoice(
customer=customer, parent_cost_center="_Test Cost Center - _TC", do_not_submit=True
)
si.department = "All Departments"
si.department = "Test Department - _TC"
si.save().submit()

# check outstanding of sales invoice
Expand All @@ -3156,7 +3165,7 @@ def test_sales_invoice_against_supplier_usd_with_dimensions(self):
"party": si.customer,
"reference_type": si.doctype,
"reference_name": si.name,
"department": "All Departments",
"department": "Test Department - _TC",
},
pluck="credit_in_account_currency",
)
Expand Down Expand Up @@ -4281,8 +4290,12 @@ def test_total_billed_amount(self):

project = frappe.new_doc("Project")
project.project_name = "Test Total Billed Amount"
project.company = "_Test Company"
project.save()

location = frappe.get_doc("Accounting Dimension", "Location")
location.dimension_defaults[0].mandatory_for_bs = 0
location.save()
si.project = project.name
si.save()
si.submit()
Expand Down
44 changes: 44 additions & 0 deletions erpnext/controllers/accounts_controller.py
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,50 @@ def validate(self):
self.set_total_in_words()
self.set_default_letter_head()

self.validate_accounting_dimensions()

def validate_accounting_dimensions(self):
if not self.company:
return
parent_doctype = frappe.get_meta(self.doctype).__dict__
parent_doctype = frappe._dict(parent_doctype)
accounting_dimensions_doctypes = frappe.get_hooks("accounting_dimension_doctypes")
child_table_list = []
for field in parent_doctype.get("fields"):
field = frappe._dict(field.__dict__)
if field.fieldtype == "Table" and field.options in accounting_dimensions_doctypes:
child_table_list.append(field.fieldname)
accounting_dimensions = ["Cost Center", "Project"]
accounting_dimensions.extend(frappe.get_all("Accounting Dimension", pluck="name"))

for dimension in accounting_dimensions:
if dimension_value := self.get(frappe.scrub(dimension)):
doc = frappe.get_doc(dimension, dimension_value)
if hasattr(doc, "company") and doc.company != self.company:
frappe.throw(
_("{0}: {1} does not belong to the Company: {2}").format(
dimension, frappe.bold(dimension_value), self.company
)
)
if child_table_list:
self.validate_child_accounting_dimensions(accounting_dimensions, child_table_list)

def validate_child_accounting_dimensions(self, accounting_dimensions, child_table_list):
for child_table in child_table_list:
for child in self.get(child_table, []):
for dimension in accounting_dimensions:
dimension_field = frappe.scrub(dimension)
dimension_value = child.get(dimension_field)
if not dimension_value:
continue
doc = frappe.get_doc(dimension, dimension_value)
if hasattr(doc, "company") and doc.company != self.company:
frappe.throw(
_("Row {0}: {1} {2} does not belong to the Company: {3}").format(
child.idx, dimension, frappe.bold(dimension_value), self.company
)
)

def set_default_letter_head(self):
if hasattr(self, "letter_head") and not self.letter_head:
self.letter_head = frappe.db.get_value("Company", self.company, "default_letter_head")
Expand Down
10 changes: 10 additions & 0 deletions erpnext/controllers/tests/test_accounts_controller.py
Original file line number Diff line number Diff line change
Expand Up @@ -1467,6 +1467,13 @@ def test_90_dimensions_filter(self):
"""
self.setup_dimensions()
rate_in_account_currency = 1
department = frappe.get_all(
"Department",
{"name": ["in", ["Management", "Operations", "Legal", "Research & Development"]]},
["name", "company"],
)
for dept in department:
frappe.db.set_value("Department", dept.name, "company", "_Test Company")

# Invoices
si1 = self.create_sales_invoice(qty=1, rate=rate_in_account_currency, do_not_submit=True)
Expand Down Expand Up @@ -1535,6 +1542,7 @@ def test_90_dimensions_filter(self):
def test_91_cr_note_should_inherit_dimension(self):
self.setup_dimensions()
rate_in_account_currency = 1
frappe.db.set_value("Department", "Management", "company", "_Test Company")

# Invoice
si = self.create_sales_invoice(qty=1, rate=rate_in_account_currency, do_not_submit=True)
Expand Down Expand Up @@ -1581,6 +1589,7 @@ def test_92_dimension_inhertiance_exc_gain_loss(self):
self.setup_dimensions()
rate_in_account_currency = 1
dpt = "Research & Development"
frappe.db.set_value("Department", dpt, "company", "_Test Company")

si = self.create_sales_invoice(qty=1, rate=rate_in_account_currency, do_not_save=True)
si.department = dpt
Expand Down Expand Up @@ -1616,6 +1625,7 @@ def test_92_dimension_inhertiance_exc_gain_loss(self):
def test_93_dimension_inheritance_on_advance(self):
self.setup_dimensions()
dpt = "Research & Development"
frappe.db.set_value("Department", dpt, "company", "_Test Company")

adv = self.create_payment_entry(amount=1, source_exc_rate=85)
adv.department = dpt
Expand Down
12 changes: 9 additions & 3 deletions erpnext/projects/doctype/timesheet/test_timesheet.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,13 +55,19 @@ def test_sales_invoice_from_timesheet(self):

def test_timesheet_billing_based_on_project(self):
emp = make_employee("[email protected]")
project = frappe.get_value("Project", {"project_name": "_Test Project"})
project = frappe.get_doc("Project", "_T-Project-00001")
project.company = "_Test Company"
project.save()

location = frappe.get_doc("Accounting Dimension", "Location")
location.dimension_defaults[0].mandatory_for_bs = 0
location.save()

timesheet = make_timesheet(
emp, simulate=True, is_billable=1, project=project, company="_Test Company"
emp, simulate=True, is_billable=1, project=project.name, company="_Test Company"
)
sales_invoice = create_sales_invoice(do_not_save=True)
sales_invoice.project = project
sales_invoice.project = project.name
sales_invoice.submit()

ts = frappe.get_doc("Timesheet", timesheet.name)
Expand Down
Loading