Merge pull request #16523 from Zlash65/comp-sync
feat: Sync Chart of Accounts in Company hierarchy
This commit is contained in:
commit
4c8627e88d
@ -5,7 +5,7 @@ from __future__ import unicode_literals
|
|||||||
import frappe
|
import frappe
|
||||||
from frappe.utils import cint, cstr
|
from frappe.utils import cint, cstr
|
||||||
from frappe import throw, _
|
from frappe import throw, _
|
||||||
from frappe.utils.nestedset import NestedSet
|
from frappe.utils.nestedset import NestedSet, get_ancestors_of, get_descendants_of
|
||||||
|
|
||||||
class RootNotEditable(frappe.ValidationError): pass
|
class RootNotEditable(frappe.ValidationError): pass
|
||||||
class BalanceMismatchError(frappe.ValidationError): pass
|
class BalanceMismatchError(frappe.ValidationError): pass
|
||||||
@ -41,6 +41,7 @@ class Account(NestedSet):
|
|||||||
self.validate_frozen_accounts_modifier()
|
self.validate_frozen_accounts_modifier()
|
||||||
self.validate_balance_must_be_debit_or_credit()
|
self.validate_balance_must_be_debit_or_credit()
|
||||||
self.validate_account_currency()
|
self.validate_account_currency()
|
||||||
|
self.validate_root_company_and_sync_account_to_children()
|
||||||
|
|
||||||
def validate_parent(self):
|
def validate_parent(self):
|
||||||
"""Fetch Parent Details and validate parent account"""
|
"""Fetch Parent Details and validate parent account"""
|
||||||
@ -90,6 +91,34 @@ class Account(NestedSet):
|
|||||||
if not self.parent_account and not self.is_group:
|
if not self.parent_account and not self.is_group:
|
||||||
frappe.throw(_("Root Account must be a group"))
|
frappe.throw(_("Root Account must be a group"))
|
||||||
|
|
||||||
|
def validate_root_company_and_sync_account_to_children(self):
|
||||||
|
# ignore validation while creating new compnay or while syncing to child companies
|
||||||
|
if frappe.local.flags.ignore_root_company_validation or self.flags.ignore_root_company_validation:
|
||||||
|
return
|
||||||
|
|
||||||
|
ancestors = get_root_company(self.company)
|
||||||
|
if ancestors:
|
||||||
|
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
|
||||||
|
|
||||||
|
acc_name_map = {}
|
||||||
|
acc_name = frappe.db.get_value('Account', self.parent_account, "account_name")
|
||||||
|
for d in frappe.db.get_values('Account',
|
||||||
|
{"company": ["in", descendants], "account_name": acc_name},
|
||||||
|
["company", "name"], as_dict=True):
|
||||||
|
acc_name_map[d["company"]] = d["name"]
|
||||||
|
|
||||||
|
for company in descendants:
|
||||||
|
doc = frappe.copy_doc(self)
|
||||||
|
doc.flags.ignore_root_company_validation = True
|
||||||
|
doc.update({"company": company, "account_currency": None,
|
||||||
|
"parent": acc_name_map[company], "parent_account": acc_name_map[company]})
|
||||||
|
doc.save()
|
||||||
|
frappe.msgprint(_("Account {0} is added in the child company {1}")
|
||||||
|
.format(doc.name, company))
|
||||||
|
|
||||||
def validate_group_or_ledger(self):
|
def validate_group_or_ledger(self):
|
||||||
if self.get("__islocal"):
|
if self.get("__islocal"):
|
||||||
return
|
return
|
||||||
@ -250,3 +279,9 @@ def merge_account(old, new, is_group, root_type, company):
|
|||||||
frappe.rename_doc("Account", old, new, merge=1, ignore_permissions=1)
|
frappe.rename_doc("Account", old, new, merge=1, ignore_permissions=1)
|
||||||
|
|
||||||
return new
|
return new
|
||||||
|
|
||||||
|
@frappe.whitelist()
|
||||||
|
def get_root_company(company):
|
||||||
|
# return the topmost company in the hierarchy
|
||||||
|
ancestors = get_ancestors_of('Company', company, "lft asc")
|
||||||
|
return [ancestors[0]] if ancestors else []
|
||||||
|
@ -4,13 +4,38 @@ frappe.treeview_settings["Account"] = {
|
|||||||
breadcrumbs: "Accounts",
|
breadcrumbs: "Accounts",
|
||||||
title: __("Chart Of Accounts"),
|
title: __("Chart Of Accounts"),
|
||||||
get_tree_root: false,
|
get_tree_root: false,
|
||||||
filters: [{
|
filters: [
|
||||||
fieldname: "company",
|
{
|
||||||
fieldtype:"Select",
|
fieldname: "company",
|
||||||
options: erpnext.utils.get_tree_options("company"),
|
fieldtype:"Select",
|
||||||
label: __("Company"),
|
options: erpnext.utils.get_tree_options("company"),
|
||||||
default: erpnext.utils.get_tree_default("company")
|
label: __("Company"),
|
||||||
}],
|
default: erpnext.utils.get_tree_default("company"),
|
||||||
|
on_change: function() {
|
||||||
|
var me = frappe.treeview_settings['Account'].treeview;
|
||||||
|
var company = me.page.fields_dict.company.get_value();
|
||||||
|
frappe.call({
|
||||||
|
method: "erpnext.accounts.doctype.account.account.get_root_company",
|
||||||
|
args: {
|
||||||
|
company: company,
|
||||||
|
},
|
||||||
|
callback: function(r) {
|
||||||
|
if(r.message) {
|
||||||
|
let root_company = r.message.length ? r.message[0] : "";
|
||||||
|
me.page.fields_dict.root_company.set_value(root_company);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
fieldname: "root_company",
|
||||||
|
fieldtype:"Data",
|
||||||
|
label: __("Root Company"),
|
||||||
|
hidden: true,
|
||||||
|
disable_onchange: true
|
||||||
|
}
|
||||||
|
],
|
||||||
root_label: "Accounts",
|
root_label: "Accounts",
|
||||||
get_tree_nodes: 'erpnext.accounts.utils.get_children',
|
get_tree_nodes: 'erpnext.accounts.utils.get_children',
|
||||||
add_tree_node: 'erpnext.accounts.utils.add_ac',
|
add_tree_node: 'erpnext.accounts.utils.add_ac',
|
||||||
@ -42,8 +67,8 @@ frappe.treeview_settings["Account"] = {
|
|||||||
],
|
],
|
||||||
ignore_fields:["parent_account"],
|
ignore_fields:["parent_account"],
|
||||||
onload: function(treeview) {
|
onload: function(treeview) {
|
||||||
frappe.treeview_settings['Account'].page = {};
|
frappe.treeview_settings['Account'].treeview = {};
|
||||||
$.extend(frappe.treeview_settings['Account'].page, treeview.page);
|
$.extend(frappe.treeview_settings['Account'].treeview, treeview);
|
||||||
function get_company() {
|
function get_company() {
|
||||||
return treeview.page.fields_dict.company.get_value();
|
return treeview.page.fields_dict.company.get_value();
|
||||||
}
|
}
|
||||||
@ -78,6 +103,18 @@ frappe.treeview_settings["Account"] = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
},
|
},
|
||||||
|
post_render: function(treeview) {
|
||||||
|
frappe.treeview_settings['Account'].treeview["tree"] = treeview.tree;
|
||||||
|
treeview.page.set_primary_action(__("New"), function() {
|
||||||
|
let root_company = treeview.page.fields_dict.root_company.get_value();
|
||||||
|
|
||||||
|
if(root_company) {
|
||||||
|
frappe.throw(__("Please add the account to root level Company - ") + root_company);
|
||||||
|
} else {
|
||||||
|
treeview.new_node();
|
||||||
|
}
|
||||||
|
}, "octicon octicon-plus");
|
||||||
|
},
|
||||||
onrender: function(node) {
|
onrender: function(node) {
|
||||||
if(frappe.boot.user.can_read.indexOf("GL Entry") !== -1){
|
if(frappe.boot.user.can_read.indexOf("GL Entry") !== -1){
|
||||||
var dr_or_cr = node.data.balance < 0 ? "Cr" : "Dr";
|
var dr_or_cr = node.data.balance < 0 ? "Cr" : "Dr";
|
||||||
@ -93,6 +130,19 @@ frappe.treeview_settings["Account"] = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
toolbar: [
|
toolbar: [
|
||||||
|
{
|
||||||
|
label:__("Add Child"),
|
||||||
|
condition: function(node) {
|
||||||
|
return frappe.boot.user.can_create.indexOf("Account") !== -1 &&
|
||||||
|
!frappe.treeview_settings['Account'].treeview.page.fields_dict.root_company.get_value() &&
|
||||||
|
node.expandable && !node.hide_add;
|
||||||
|
},
|
||||||
|
click: function() {
|
||||||
|
var me = frappe.treeview_settings['Account'].treeview;
|
||||||
|
me.new_node();
|
||||||
|
},
|
||||||
|
btnClass: "hidden-xs"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
condition: function(node) {
|
condition: function(node) {
|
||||||
return !node.root && frappe.boot.user.can_read.indexOf("GL Entry") !== -1
|
return !node.root && frappe.boot.user.can_read.indexOf("GL Entry") !== -1
|
||||||
@ -103,7 +153,7 @@ frappe.treeview_settings["Account"] = {
|
|||||||
"account": node.label,
|
"account": node.label,
|
||||||
"from_date": frappe.sys_defaults.year_start_date,
|
"from_date": frappe.sys_defaults.year_start_date,
|
||||||
"to_date": frappe.sys_defaults.year_end_date,
|
"to_date": frappe.sys_defaults.year_end_date,
|
||||||
"company": frappe.treeview_settings['Account'].page.fields_dict.company.get_value()
|
"company": frappe.treeview_settings['Account'].treeview.page.fields_dict.company.get_value()
|
||||||
};
|
};
|
||||||
frappe.set_route("query-report", "General Ledger");
|
frappe.set_route("query-report", "General Ledger");
|
||||||
},
|
},
|
||||||
|
@ -97,6 +97,19 @@ class TestAccount(unittest.TestCase):
|
|||||||
self.assertRaises(frappe.ValidationError, merge_account, "Capital Stock - _TC",\
|
self.assertRaises(frappe.ValidationError, merge_account, "Capital Stock - _TC",\
|
||||||
"Softwares - _TC", doc.is_group, doc.root_type, doc.company)
|
"Softwares - _TC", doc.is_group, doc.root_type, doc.company)
|
||||||
|
|
||||||
|
def test_account_sync(self):
|
||||||
|
del frappe.local.flags["ignore_root_company_validation"]
|
||||||
|
acc = frappe.new_doc("Account")
|
||||||
|
acc.account_name = "Test Sync Account"
|
||||||
|
acc.parent_account = "Temporary Accounts - _TC3"
|
||||||
|
acc.company = "_Test Company 3"
|
||||||
|
acc.insert()
|
||||||
|
|
||||||
|
acc_tc_4 = frappe.db.get_value('Account', {'account_name': "Test Sync Account", "company": "_Test Company 4"})
|
||||||
|
acc_tc_5 = frappe.db.get_value('Account', {'account_name': "Test Sync Account", "company": "_Test Company 5"})
|
||||||
|
self.assertEqual(acc_tc_4, "Test Sync Account - _TC4")
|
||||||
|
self.assertEqual(acc_tc_5, "Test Sync Account - _TC5")
|
||||||
|
|
||||||
def _make_test_records(verbose):
|
def _make_test_records(verbose):
|
||||||
from frappe.test_runner import make_test_objects
|
from frappe.test_runner import make_test_objects
|
||||||
|
|
||||||
|
@ -20,6 +20,7 @@ class StaffingPlan(Document):
|
|||||||
self.total_estimated_budget = 0
|
self.total_estimated_budget = 0
|
||||||
|
|
||||||
for detail in self.get("staffing_details"):
|
for detail in self.get("staffing_details"):
|
||||||
|
self.set_vacancies(detail)
|
||||||
self.validate_overlap(detail)
|
self.validate_overlap(detail)
|
||||||
self.validate_with_subsidiary_plans(detail)
|
self.validate_with_subsidiary_plans(detail)
|
||||||
self.validate_with_parent_plan(detail)
|
self.validate_with_parent_plan(detail)
|
||||||
@ -39,6 +40,15 @@ class StaffingPlan(Document):
|
|||||||
else: detail.vacancies = detail.number_of_positions = detail.total_estimated_cost = 0
|
else: detail.vacancies = detail.number_of_positions = detail.total_estimated_cost = 0
|
||||||
self.total_estimated_budget += detail.total_estimated_cost
|
self.total_estimated_budget += detail.total_estimated_cost
|
||||||
|
|
||||||
|
def set_vacancies(self, row):
|
||||||
|
if not row.vacancies:
|
||||||
|
current_openings = 0
|
||||||
|
for field in ['current_count', 'current_openings']:
|
||||||
|
if row.get(field):
|
||||||
|
current_openings += row.get(field)
|
||||||
|
|
||||||
|
row.vacancies = row.number_of_positions - current_openings
|
||||||
|
|
||||||
def validate_overlap(self, staffing_plan_detail):
|
def validate_overlap(self, staffing_plan_detail):
|
||||||
# Validate if any submitted Staffing Plan exist for any Designations in this plan
|
# Validate if any submitted Staffing Plan exist for any Designations in this plan
|
||||||
# and spd.vacancies>0 ?
|
# and spd.vacancies>0 ?
|
||||||
|
@ -18,7 +18,7 @@ class TestStaffingPlan(unittest.TestCase):
|
|||||||
if frappe.db.exists("Staffing Plan", "Test"):
|
if frappe.db.exists("Staffing Plan", "Test"):
|
||||||
return
|
return
|
||||||
staffing_plan = frappe.new_doc("Staffing Plan")
|
staffing_plan = frappe.new_doc("Staffing Plan")
|
||||||
staffing_plan.company = "_Test Company 3"
|
staffing_plan.company = "_Test Company 10"
|
||||||
staffing_plan.name = "Test"
|
staffing_plan.name = "Test"
|
||||||
staffing_plan.from_date = nowdate()
|
staffing_plan.from_date = nowdate()
|
||||||
staffing_plan.to_date = add_days(nowdate(), 10)
|
staffing_plan.to_date = add_days(nowdate(), 10)
|
||||||
@ -67,7 +67,7 @@ class TestStaffingPlan(unittest.TestCase):
|
|||||||
if frappe.db.exists("Staffing Plan", "Test 1"):
|
if frappe.db.exists("Staffing Plan", "Test 1"):
|
||||||
return
|
return
|
||||||
staffing_plan = frappe.new_doc("Staffing Plan")
|
staffing_plan = frappe.new_doc("Staffing Plan")
|
||||||
staffing_plan.company = "_Test Company 3"
|
staffing_plan.company = "_Test Company 10"
|
||||||
staffing_plan.name = "Test 1"
|
staffing_plan.name = "Test 1"
|
||||||
staffing_plan.from_date = nowdate()
|
staffing_plan.from_date = nowdate()
|
||||||
staffing_plan.to_date = add_days(nowdate(), 10)
|
staffing_plan.to_date = add_days(nowdate(), 10)
|
||||||
@ -85,11 +85,11 @@ def _set_up():
|
|||||||
make_company()
|
make_company()
|
||||||
|
|
||||||
def make_company():
|
def make_company():
|
||||||
if frappe.db.exists("Company", "_Test Company 3"):
|
if frappe.db.exists("Company", "_Test Company 10"):
|
||||||
return
|
return
|
||||||
company = frappe.new_doc("Company")
|
company = frappe.new_doc("Company")
|
||||||
company.company_name = "_Test Company 3"
|
company.company_name = "_Test Company 10"
|
||||||
company.abbr = "_TC3"
|
company.abbr = "_TC10"
|
||||||
company.parent_company = "_Test Company"
|
company.parent_company = "_Test Company"
|
||||||
company.default_currency = "INR"
|
company.default_currency = "INR"
|
||||||
company.country = "India"
|
company.country = "India"
|
||||||
|
@ -16,6 +16,12 @@ frappe.ui.form.on("Company", {
|
|||||||
filters: {"is_additional_component": 1}
|
filters: {"is_additional_component": 1}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
frm.set_query("parent_company", function() {
|
||||||
|
return {
|
||||||
|
filters: {"is_group": 1}
|
||||||
|
}
|
||||||
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
company_name: function(frm) {
|
company_name: function(frm) {
|
||||||
@ -28,6 +34,13 @@ frappe.ui.form.on("Company", {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
parent_company: function(frm) {
|
||||||
|
var bool = frm.doc.parent_company ? true : false;
|
||||||
|
frm.set_value('create_chart_of_accounts_based_on', bool ? "Existing Company" : "");
|
||||||
|
frm.set_value('existing_company', bool ? frm.doc.parent_company : "");
|
||||||
|
disbale_coa_fields(frm, bool);
|
||||||
|
},
|
||||||
|
|
||||||
date_of_commencement: function(frm) {
|
date_of_commencement: function(frm) {
|
||||||
if(frm.doc.date_of_commencement<frm.doc.date_of_incorporation)
|
if(frm.doc.date_of_commencement<frm.doc.date_of_incorporation)
|
||||||
{
|
{
|
||||||
@ -39,8 +52,10 @@ frappe.ui.form.on("Company", {
|
|||||||
},
|
},
|
||||||
|
|
||||||
refresh: function(frm) {
|
refresh: function(frm) {
|
||||||
if(frm.doc.abbr && !frm.doc.__islocal) {
|
if(!frm.doc.__islocal) {
|
||||||
frm.set_df_property("abbr", "read_only", 1);
|
frm.doc.abbr && frm.set_df_property("abbr", "read_only", 1);
|
||||||
|
frm.set_df_property("parent_company", "read_only", 1);
|
||||||
|
disbale_coa_fields(frm);
|
||||||
}
|
}
|
||||||
|
|
||||||
frm.toggle_display('address_html', !frm.doc.__islocal);
|
frm.toggle_display('address_html', !frm.doc.__islocal);
|
||||||
@ -256,3 +271,9 @@ erpnext.company.set_custom_query = function(frm, v) {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var disbale_coa_fields = function(frm, bool=true) {
|
||||||
|
frm.set_df_property("create_chart_of_accounts_based_on", "read_only", bool);
|
||||||
|
frm.set_df_property("chart_of_accounts", "read_only", bool);
|
||||||
|
frm.set_df_property("existing_company", "read_only", bool);
|
||||||
|
};
|
@ -39,6 +39,7 @@ class Company(NestedSet):
|
|||||||
self.validate_coa_input()
|
self.validate_coa_input()
|
||||||
self.validate_perpetual_inventory()
|
self.validate_perpetual_inventory()
|
||||||
self.check_country_change()
|
self.check_country_change()
|
||||||
|
self.set_chart_of_accounts()
|
||||||
|
|
||||||
def validate_abbr(self):
|
def validate_abbr(self):
|
||||||
if not self.abbr:
|
if not self.abbr:
|
||||||
@ -141,6 +142,7 @@ class Company(NestedSet):
|
|||||||
|
|
||||||
def create_default_accounts(self):
|
def create_default_accounts(self):
|
||||||
from erpnext.accounts.doctype.account.chart_of_accounts.chart_of_accounts import create_charts
|
from erpnext.accounts.doctype.account.chart_of_accounts.chart_of_accounts import create_charts
|
||||||
|
frappe.local.flags.ignore_root_company_validation = True
|
||||||
create_charts(self.name, self.chart_of_accounts, self.existing_company)
|
create_charts(self.name, self.chart_of_accounts, self.existing_company)
|
||||||
|
|
||||||
frappe.db.set(self, "default_receivable_account", frappe.db.get_value("Account",
|
frappe.db.set(self, "default_receivable_account", frappe.db.get_value("Account",
|
||||||
@ -173,6 +175,12 @@ class Company(NestedSet):
|
|||||||
self.country != frappe.get_cached_value('Company', self.name, 'country'):
|
self.country != frappe.get_cached_value('Company', self.name, 'country'):
|
||||||
frappe.flags.country_change = True
|
frappe.flags.country_change = True
|
||||||
|
|
||||||
|
def set_chart_of_accounts(self):
|
||||||
|
''' If parent company is set, chart of accounts will be based on that company '''
|
||||||
|
if self.parent_company:
|
||||||
|
self.create_chart_of_accounts_based_on = "Existing Company"
|
||||||
|
self.existing_company = self.parent_company
|
||||||
|
|
||||||
def set_default_accounts(self):
|
def set_default_accounts(self):
|
||||||
self._set_default_account("default_cash_account", "Cash")
|
self._set_default_account("default_cash_account", "Cash")
|
||||||
self._set_default_account("default_bank_account", "Bank")
|
self._set_default_account("default_bank_account", "Bank")
|
||||||
|
@ -1,32 +1,66 @@
|
|||||||
[
|
[
|
||||||
{
|
{
|
||||||
"abbr": "_TC",
|
"abbr": "_TC",
|
||||||
"company_name": "_Test Company",
|
"company_name": "_Test Company",
|
||||||
"country": "India",
|
"country": "India",
|
||||||
"default_currency": "INR",
|
"default_currency": "INR",
|
||||||
"doctype": "Company",
|
"doctype": "Company",
|
||||||
"domain": "Manufacturing",
|
"domain": "Manufacturing",
|
||||||
"chart_of_accounts": "Standard",
|
"chart_of_accounts": "Standard",
|
||||||
"default_holiday_list": "_Test Holiday List"
|
"default_holiday_list": "_Test Holiday List"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"abbr": "_TC1",
|
"abbr": "_TC1",
|
||||||
"company_name": "_Test Company 1",
|
"company_name": "_Test Company 1",
|
||||||
"country": "United States",
|
"country": "United States",
|
||||||
"default_currency": "USD",
|
"default_currency": "USD",
|
||||||
"doctype": "Company",
|
"doctype": "Company",
|
||||||
"domain": "Retail",
|
"domain": "Retail",
|
||||||
"chart_of_accounts": "Standard",
|
"chart_of_accounts": "Standard",
|
||||||
"default_holiday_list": "_Test Holiday List"
|
"default_holiday_list": "_Test Holiday List"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"abbr": "_TC2",
|
"abbr": "_TC2",
|
||||||
"company_name": "_Test Company 2",
|
"company_name": "_Test Company 2",
|
||||||
"default_currency": "EUR",
|
"default_currency": "EUR",
|
||||||
"country": "Germany",
|
"country": "Germany",
|
||||||
"doctype": "Company",
|
"doctype": "Company",
|
||||||
"domain": "Retail",
|
"domain": "Retail",
|
||||||
"chart_of_accounts": "Standard",
|
"chart_of_accounts": "Standard",
|
||||||
"default_holiday_list": "_Test Holiday List"
|
"default_holiday_list": "_Test Holiday List"
|
||||||
}
|
},
|
||||||
|
{
|
||||||
|
"abbr": "_TC3",
|
||||||
|
"company_name": "_Test Company 3",
|
||||||
|
"is_group": 1,
|
||||||
|
"country": "India",
|
||||||
|
"default_currency": "INR",
|
||||||
|
"doctype": "Company",
|
||||||
|
"domain": "Manufacturing",
|
||||||
|
"chart_of_accounts": "Standard",
|
||||||
|
"default_holiday_list": "_Test Holiday List"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"abbr": "_TC4",
|
||||||
|
"company_name": "_Test Company 4",
|
||||||
|
"parent_company": "_Test Company 3",
|
||||||
|
"is_group": 1,
|
||||||
|
"country": "India",
|
||||||
|
"default_currency": "INR",
|
||||||
|
"doctype": "Company",
|
||||||
|
"domain": "Manufacturing",
|
||||||
|
"chart_of_accounts": "Standard",
|
||||||
|
"default_holiday_list": "_Test Holiday List"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"abbr": "_TC5",
|
||||||
|
"company_name": "_Test Company 5",
|
||||||
|
"parent_company": "_Test Company 4",
|
||||||
|
"country": "India",
|
||||||
|
"default_currency": "INR",
|
||||||
|
"doctype": "Company",
|
||||||
|
"domain": "Manufacturing",
|
||||||
|
"chart_of_accounts": "Standard",
|
||||||
|
"default_holiday_list": "_Test Holiday List"
|
||||||
|
}
|
||||||
]
|
]
|
||||||
|
Loading…
x
Reference in New Issue
Block a user