From ad31e02616786480cfbadeb39fcaf357e68b4133 Mon Sep 17 00:00:00 2001 From: marination Date: Thu, 30 Mar 2023 21:03:03 +0530 Subject: [PATCH 01/89] feat: Store Party bank details in party records (Customer/Supplier/Employee/Shareholder) --- .../bank_transaction/bank_transaction.json | 29 +++++++++++++++-- .../bank_transaction/bank_transaction.py | 11 +++++++ .../doctype/shareholder/shareholder.json | 32 +++++++++++++++++-- erpnext/buying/doctype/supplier/supplier.json | 30 ++++++++++++++++- .../selling/doctype/customer/customer.json | 25 ++++++++++++++- erpnext/setup/doctype/employee/employee.json | 15 +++++++-- 6 files changed, 132 insertions(+), 10 deletions(-) diff --git a/erpnext/accounts/doctype/bank_transaction/bank_transaction.json b/erpnext/accounts/doctype/bank_transaction/bank_transaction.json index 768d2f0fa4..1543fdb894 100644 --- a/erpnext/accounts/doctype/bank_transaction/bank_transaction.json +++ b/erpnext/accounts/doctype/bank_transaction/bank_transaction.json @@ -33,7 +33,11 @@ "unallocated_amount", "party_section", "party_type", - "party" + "party", + "column_break_3czf", + "bank_party_name", + "bank_party_no", + "bank_party_iban" ], "fields": [ { @@ -202,11 +206,30 @@ "fieldtype": "Data", "label": "Transaction Type", "length": 50 + }, + { + "fieldname": "column_break_3czf", + "fieldtype": "Column Break" + }, + { + "fieldname": "bank_party_name", + "fieldtype": "Data", + "label": "Party Name (Bank Statement)" + }, + { + "fieldname": "bank_party_no", + "fieldtype": "Data", + "label": "Party Account No. (Bank Statement)" + }, + { + "fieldname": "bank_party_iban", + "fieldtype": "Data", + "label": "Party IBAN (Bank Statement)" } ], "is_submittable": 1, "links": [], - "modified": "2022-05-29 18:36:50.475964", + "modified": "2023-03-30 15:30:46.485683", "modified_by": "Administrator", "module": "Accounts", "name": "Bank Transaction", @@ -260,4 +283,4 @@ "states": [], "title_field": "bank_account", "track_changes": 1 -} +} \ No newline at end of file diff --git a/erpnext/accounts/doctype/bank_transaction/bank_transaction.py b/erpnext/accounts/doctype/bank_transaction/bank_transaction.py index fcbaf329f5..676c71910b 100644 --- a/erpnext/accounts/doctype/bank_transaction/bank_transaction.py +++ b/erpnext/accounts/doctype/bank_transaction/bank_transaction.py @@ -8,6 +8,17 @@ from erpnext.controllers.status_updater import StatusUpdater class BankTransaction(StatusUpdater): + # TODO + # On BT save: + # - Match by account no/iban in Customer/Supplier/Employee + # - Match by Party Name + # - If match found, set party type and party name. + + # On submit/update after submit + # - Create/Update a Bank Party Map record + # - User can edit after submit. + # - If changes in party/party name after submit, edit bank party map (which should edit all transactions with same account no/iban/bank party name) + def after_insert(self): self.unallocated_amount = abs(flt(self.withdrawal) - flt(self.deposit)) diff --git a/erpnext/accounts/doctype/shareholder/shareholder.json b/erpnext/accounts/doctype/shareholder/shareholder.json index e94aea94b7..2be2a2fc42 100644 --- a/erpnext/accounts/doctype/shareholder/shareholder.json +++ b/erpnext/accounts/doctype/shareholder/shareholder.json @@ -1,4 +1,5 @@ { + "actions": [], "autoname": "naming_series:", "creation": "2017-12-25 16:50:53.878430", "doctype": "DocType", @@ -19,7 +20,11 @@ "contact_html", "section_break_3", "share_balance", - "contact_list" + "contact_list", + "bank_details_section", + "bank_account_no", + "column_break_tyo0", + "iban" ], "fields": [ { @@ -109,13 +114,33 @@ "hidden": 1, "label": "Contact List", "read_only": 1 + }, + { + "fieldname": "bank_details_section", + "fieldtype": "Section Break", + "label": "Bank Details" + }, + { + "fieldname": "bank_account_no", + "fieldtype": "Data", + "label": "Bank Account No" + }, + { + "fieldname": "column_break_tyo0", + "fieldtype": "Column Break" + }, + { + "fieldname": "iban", + "fieldtype": "Data", + "label": "IBAN" } ], - "modified": "2019-11-17 23:24:11.395882", + "links": [], + "modified": "2023-03-30 16:00:55.087823", "modified_by": "Administrator", "module": "Accounts", "name": "Shareholder", - "name_case": "Title Case", + "naming_rule": "By \"Naming Series\" field", "owner": "Administrator", "permissions": [ { @@ -158,6 +183,7 @@ "search_fields": "folio_no", "sort_field": "modified", "sort_order": "DESC", + "states": [], "title_field": "title", "track_changes": 1 } \ No newline at end of file diff --git a/erpnext/buying/doctype/supplier/supplier.json b/erpnext/buying/doctype/supplier/supplier.json index 1bf7f589e2..a80dcfe538 100644 --- a/erpnext/buying/doctype/supplier/supplier.json +++ b/erpnext/buying/doctype/supplier/supplier.json @@ -52,6 +52,11 @@ "supplier_primary_address", "primary_address", "accounting_tab", + "bank_details_section", + "bank_account_no", + "column_break_n8mz", + "iban", + "section_break_ow3k", "payment_terms", "accounts", "settings_tab", @@ -445,6 +450,29 @@ { "fieldname": "column_break_59", "fieldtype": "Column Break" + }, + { + "fieldname": "bank_details_section", + "fieldtype": "Section Break", + "label": "Bank Details" + }, + { + "fieldname": "bank_account_no", + "fieldtype": "Data", + "label": "Bank Account No" + }, + { + "fieldname": "column_break_n8mz", + "fieldtype": "Column Break" + }, + { + "fieldname": "iban", + "fieldtype": "Data", + "label": "IBAN" + }, + { + "fieldname": "section_break_ow3k", + "fieldtype": "Section Break" } ], "icon": "fa fa-user", @@ -457,7 +485,7 @@ "link_fieldname": "party" } ], - "modified": "2023-02-18 11:05:50.592270", + "modified": "2023-03-30 15:50:40.241257", "modified_by": "Administrator", "module": "Buying", "name": "Supplier", diff --git a/erpnext/selling/doctype/customer/customer.json b/erpnext/selling/doctype/customer/customer.json index c133cd3152..5dc6a72da8 100644 --- a/erpnext/selling/doctype/customer/customer.json +++ b/erpnext/selling/doctype/customer/customer.json @@ -61,6 +61,10 @@ "tax_category", "tax_withholding_category", "accounting_tab", + "bank_details_section", + "bank_account_no", + "column_break_xtwg", + "iban", "credit_limit_section", "payment_terms", "credit_limits", @@ -555,6 +559,25 @@ { "fieldname": "column_break_54", "fieldtype": "Column Break" + }, + { + "fieldname": "bank_details_section", + "fieldtype": "Section Break", + "label": "Bank Details" + }, + { + "fieldname": "bank_account_no", + "fieldtype": "Data", + "label": "Bank Account No" + }, + { + "fieldname": "column_break_xtwg", + "fieldtype": "Column Break" + }, + { + "fieldname": "iban", + "fieldtype": "Data", + "label": "IBAN" } ], "icon": "fa fa-user", @@ -568,7 +591,7 @@ "link_fieldname": "party" } ], - "modified": "2023-02-18 11:04:46.343527", + "modified": "2023-03-30 15:45:44.387975", "modified_by": "Administrator", "module": "Selling", "name": "Customer", diff --git a/erpnext/setup/doctype/employee/employee.json b/erpnext/setup/doctype/employee/employee.json index 99693d9091..6cb4292226 100644 --- a/erpnext/setup/doctype/employee/employee.json +++ b/erpnext/setup/doctype/employee/employee.json @@ -78,7 +78,9 @@ "salary_mode", "bank_details_section", "bank_name", + "column_break_heye", "bank_ac_no", + "iban", "personal_details", "marital_status", "family_background", @@ -804,17 +806,26 @@ { "fieldname": "column_break_104", "fieldtype": "Column Break" + }, + { + "fieldname": "column_break_heye", + "fieldtype": "Column Break" + }, + { + "depends_on": "eval:doc.salary_mode == 'Bank'", + "fieldname": "iban", + "fieldtype": "Data", + "label": "IBAN" } ], "icon": "fa fa-user", "idx": 24, "image_field": "image", "links": [], - "modified": "2022-09-13 10:27:14.579197", + "modified": "2023-03-30 15:57:05.174592", "modified_by": "Administrator", "module": "Setup", "name": "Employee", - "name_case": "Title Case", "naming_rule": "By \"Naming Series\" field", "owner": "Administrator", "permissions": [ From e7745033dfc819bae534cc78a2987210c1fbcdf9 Mon Sep 17 00:00:00 2001 From: marination Date: Fri, 31 Mar 2023 16:11:00 +0530 Subject: [PATCH 02/89] feat: Party auto-matcher from Bank Transaction data - Created Bank Party Mapper - Created class to auto match by account/iban or party name/description(fuzzy) - Automatch and set in transaction or create mapper - `rapidfuzz` introduced --- .../doctype/bank_party_mapper/__init__.py | 0 .../bank_party_mapper/bank_party_mapper.js | 8 + .../bank_party_mapper/bank_party_mapper.json | 80 +++++++++ .../bank_party_mapper/bank_party_mapper.py | 9 + .../test_bank_party_mapper.py | 9 + .../bank_transaction/auto_match_party.py | 157 ++++++++++++++++++ .../bank_transaction/bank_transaction.json | 14 +- .../bank_transaction/bank_transaction.py | 35 +++- pyproject.toml | 1 + 9 files changed, 301 insertions(+), 12 deletions(-) create mode 100644 erpnext/accounts/doctype/bank_party_mapper/__init__.py create mode 100644 erpnext/accounts/doctype/bank_party_mapper/bank_party_mapper.js create mode 100644 erpnext/accounts/doctype/bank_party_mapper/bank_party_mapper.json create mode 100644 erpnext/accounts/doctype/bank_party_mapper/bank_party_mapper.py create mode 100644 erpnext/accounts/doctype/bank_party_mapper/test_bank_party_mapper.py create mode 100644 erpnext/accounts/doctype/bank_transaction/auto_match_party.py diff --git a/erpnext/accounts/doctype/bank_party_mapper/__init__.py b/erpnext/accounts/doctype/bank_party_mapper/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/erpnext/accounts/doctype/bank_party_mapper/bank_party_mapper.js b/erpnext/accounts/doctype/bank_party_mapper/bank_party_mapper.js new file mode 100644 index 0000000000..d11d8040b2 --- /dev/null +++ b/erpnext/accounts/doctype/bank_party_mapper/bank_party_mapper.js @@ -0,0 +1,8 @@ +// Copyright (c) 2023, Frappe Technologies Pvt. Ltd. and contributors +// For license information, please see license.txt + +// frappe.ui.form.on("Bank Party Mapper", { +// refresh(frm) { + +// }, +// }); diff --git a/erpnext/accounts/doctype/bank_party_mapper/bank_party_mapper.json b/erpnext/accounts/doctype/bank_party_mapper/bank_party_mapper.json new file mode 100644 index 0000000000..4f5f6bfa88 --- /dev/null +++ b/erpnext/accounts/doctype/bank_party_mapper/bank_party_mapper.json @@ -0,0 +1,80 @@ +{ + "actions": [], + "creation": "2023-03-31 10:48:20.249481", + "default_view": "List", + "doctype": "DocType", + "editable_grid": 1, + "engine": "InnoDB", + "field_order": [ + "party_type", + "party", + "column_break_wbna", + "bank_party_name_desc", + "bank_party_account_number", + "bank_party_iban" + ], + "fields": [ + { + "fieldname": "bank_party_account_number", + "fieldtype": "Data", + "in_list_view": 1, + "label": "Party Account No. (Bank Statement)" + }, + { + "fieldname": "bank_party_iban", + "fieldtype": "Data", + "in_list_view": 1, + "label": "Party IBAN (Bank Statement)" + }, + { + "fieldname": "column_break_wbna", + "fieldtype": "Column Break" + }, + { + "fieldname": "party_type", + "fieldtype": "Link", + "in_list_view": 1, + "in_standard_filter": 1, + "label": "Party Type", + "options": "DocType" + }, + { + "fieldname": "party", + "fieldtype": "Dynamic Link", + "in_list_view": 1, + "in_standard_filter": 1, + "label": "Party", + "options": "party_type" + }, + { + "fieldname": "bank_party_name_desc", + "fieldtype": "Small Text", + "label": "Party Name/Desc (Bank Statement)" + } + ], + "index_web_pages_for_search": 1, + "links": [], + "modified": "2023-04-03 10:11:31.384383", + "modified_by": "Administrator", + "module": "Accounts", + "name": "Bank Party Mapper", + "owner": "Administrator", + "permissions": [ + { + "create": 1, + "delete": 1, + "email": 1, + "export": 1, + "print": 1, + "read": 1, + "report": 1, + "role": "System Manager", + "share": 1, + "write": 1 + } + ], + "sort_field": "modified", + "sort_order": "DESC", + "states": [], + "track_changes": 1 +} \ No newline at end of file diff --git a/erpnext/accounts/doctype/bank_party_mapper/bank_party_mapper.py b/erpnext/accounts/doctype/bank_party_mapper/bank_party_mapper.py new file mode 100644 index 0000000000..d3a9a5e586 --- /dev/null +++ b/erpnext/accounts/doctype/bank_party_mapper/bank_party_mapper.py @@ -0,0 +1,9 @@ +# Copyright (c) 2023, Frappe Technologies Pvt. Ltd. and contributors +# For license information, please see license.txt + +# import frappe +from frappe.model.document import Document + + +class BankPartyMapper(Document): + pass diff --git a/erpnext/accounts/doctype/bank_party_mapper/test_bank_party_mapper.py b/erpnext/accounts/doctype/bank_party_mapper/test_bank_party_mapper.py new file mode 100644 index 0000000000..c05b23f1a5 --- /dev/null +++ b/erpnext/accounts/doctype/bank_party_mapper/test_bank_party_mapper.py @@ -0,0 +1,9 @@ +# Copyright (c) 2023, Frappe Technologies Pvt. Ltd. and Contributors +# See license.txt + +# import frappe +from frappe.tests.utils import FrappeTestCase + + +class TestBankPartyMapper(FrappeTestCase): + pass diff --git a/erpnext/accounts/doctype/bank_transaction/auto_match_party.py b/erpnext/accounts/doctype/bank_transaction/auto_match_party.py new file mode 100644 index 0000000000..7354fa0928 --- /dev/null +++ b/erpnext/accounts/doctype/bank_transaction/auto_match_party.py @@ -0,0 +1,157 @@ +import frappe +from rapidfuzz import fuzz, process + + +class AutoMatchParty: + def __init__(self, **kwargs) -> None: + self.__dict__.update(kwargs) + + def get(self, key): + return self.__dict__.get(key, None) + + def match(self): + result = AutoMatchbyAccountIBAN( + bank_party_account_number=self.bank_party_account_number, + bank_party_iban=self.bank_party_iban, + deposit=self.deposit, + ).match() + + if not result: + result = AutoMatchbyPartyDescription( + bank_party_name=self.bank_party_name, description=self.description, deposit=self.deposit + ).match() + + return result + + +class AutoMatchbyAccountIBAN: + def __init__(self, **kwargs) -> None: + self.__dict__.update(kwargs) + + def get(self, key): + return self.__dict__.get(key, None) + + def match(self): + if not (self.bank_party_account_number or self.bank_party_iban): + return None + + result = self.match_account_in_bank_party_mapper() + if not result: + result = self.match_account_in_party() + + return result + + def match_account_in_bank_party_mapper(self): + filter_field = ( + "bank_party_account_number" if self.bank_party_account_number else "bank_party_iban" + ) + result = frappe.db.get_value( + "Bank Party Mapper", + filters={filter_field: self.get(filter_field)}, + fieldname=["party_type", "party"], + ) + if result: + party_type, party = result + return (party_type, party, None) + + return result + + def match_account_in_party(self): + # If not check if there is a match in Customer/Supplier/Employee + filter_field = "bank_account_no" if self.bank_party_account_number else "iban" + transaction_field = ( + "bank_party_account_number" if self.bank_party_account_number else "bank_party_iban" + ) + result = None + + parties = ["Supplier", "Employee", "Customer"] # most -> least likely to receive + if self.deposit > 0: + parties = ["Customer", "Supplier", "Employee"] # most -> least likely to pay + + for party in parties: + party_name = frappe.db.get_value( + party, filters={filter_field: self.get(transaction_field)}, fieldname=["name"] + ) + if party_name: + result = (party, party_name, {transaction_field: self.get(transaction_field)}) + break + + return result + + +class AutoMatchbyPartyDescription: + def __init__(self, **kwargs) -> None: + self.__dict__.update(kwargs) + + def get(self, key): + return self.__dict__.get(key, None) + + def match(self): + # Match by Customer, Supplier or Employee Name + # search bank party mapper by party and then description + # fuzzy search by customer/supplier & employee + if not (self.bank_party_name or self.description): + return None + + result = self.match_party_name_desc_in_bank_party_mapper() + + if not result: + result = self.match_party_name_desc_in_party() + + return result + + def match_party_name_desc_in_bank_party_mapper(self): + """Check if match exists for party name or description in Bank Party Mapper""" + result = None + # TODO: or filters + if self.bank_party_name: + result = frappe.db.get_value( + "Bank Party Mapper", + filters={"bank_party_name_desc": self.bank_party_name}, + fieldname=["party_type", "party"], + ) + + if not result and self.description: + result = frappe.db.get_value( + "Bank Party Mapper", + filters={"bank_party_name_desc": self.description}, + fieldname=["party_type", "party"], + ) + + result = result + (None,) if result else result + + return result + + def match_party_name_desc_in_party(self): + """Fuzzy search party name and/or description against parties in the system""" + result = None + + parties = ["Supplier", "Employee", "Customer"] # most-least likely to receive + if frappe.utils.flt(self.deposit) > 0.0: + parties = ["Customer", "Supplier", "Employee"] # most-least likely to pay + + for party in parties: + name_field = party.lower() + "_name" + filters = {"status": "Active"} if party == "Employee" else {"disabled": 0} + + names = frappe.get_all(party, filters=filters, pluck=name_field) + + for field in ["bank_party_name", "description"]: + if not result and self.get(field): + result = self.fuzzy_search_and_return_result(party, names, field) + if result: + break + + return result + + def fuzzy_search_and_return_result(self, party, names, field): + result = process.extractOne(query=self.get(field), choices=names, scorer=fuzz.token_set_ratio) + + if result: + party_name, score, index = result + if score > 75: + return (party, party_name, {"bank_party_name_desc": self.get(field)}) + else: + return None + + return result diff --git a/erpnext/accounts/doctype/bank_transaction/bank_transaction.json b/erpnext/accounts/doctype/bank_transaction/bank_transaction.json index 1543fdb894..4139a9f6d5 100644 --- a/erpnext/accounts/doctype/bank_transaction/bank_transaction.json +++ b/erpnext/accounts/doctype/bank_transaction/bank_transaction.json @@ -36,7 +36,7 @@ "party", "column_break_3czf", "bank_party_name", - "bank_party_no", + "bank_party_account_number", "bank_party_iban" ], "fields": [ @@ -216,20 +216,20 @@ "fieldtype": "Data", "label": "Party Name (Bank Statement)" }, - { - "fieldname": "bank_party_no", - "fieldtype": "Data", - "label": "Party Account No. (Bank Statement)" - }, { "fieldname": "bank_party_iban", "fieldtype": "Data", "label": "Party IBAN (Bank Statement)" + }, + { + "fieldname": "bank_party_account_number", + "fieldtype": "Data", + "label": "Party Account No. (Bank Statement)" } ], "is_submittable": 1, "links": [], - "modified": "2023-03-30 15:30:46.485683", + "modified": "2023-03-31 10:45:30.671309", "modified_by": "Administrator", "module": "Accounts", "name": "Bank Transaction", diff --git a/erpnext/accounts/doctype/bank_transaction/bank_transaction.py b/erpnext/accounts/doctype/bank_transaction/bank_transaction.py index 676c71910b..745450423b 100644 --- a/erpnext/accounts/doctype/bank_transaction/bank_transaction.py +++ b/erpnext/accounts/doctype/bank_transaction/bank_transaction.py @@ -9,11 +9,6 @@ from erpnext.controllers.status_updater import StatusUpdater class BankTransaction(StatusUpdater): # TODO - # On BT save: - # - Match by account no/iban in Customer/Supplier/Employee - # - Match by Party Name - # - If match found, set party type and party name. - # On submit/update after submit # - Create/Update a Bank Party Map record # - User can edit after submit. @@ -22,6 +17,12 @@ class BankTransaction(StatusUpdater): def after_insert(self): self.unallocated_amount = abs(flt(self.withdrawal) - flt(self.deposit)) + def on_update(self): + if self.party_type and self.party: + return + + self.auto_set_party() + def on_submit(self): self.clear_linked_payment_entries() self.set_status() @@ -157,6 +158,30 @@ class BankTransaction(StatusUpdater): payment_entry.payment_document, payment_entry.payment_entry, clearance_date, self ) + def auto_set_party(self): + # TODO: check if enabled + from erpnext.accounts.doctype.bank_transaction.auto_match_party import AutoMatchParty + + result = AutoMatchParty( + bank_party_account_number=self.bank_party_account_number, + bank_party_iban=self.bank_party_iban, + bank_party_name=self.bank_party_name, + description=self.description, + deposit=self.deposit, + ).match() + + if result: + self.party_type, self.party, mapper = result + + if not mapper: + return + + mapper_doc = frappe.get_doc( + {"doctype": "Bank Party Mapper", "party_type": self.party_type, "party": self.party} + ) + mapper_doc.update(mapper) + mapper_doc.insert() + @frappe.whitelist() def get_doctypes_for_bank_reconciliation(): diff --git a/pyproject.toml b/pyproject.toml index 0718e5b4a1..e5bc884729 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -12,6 +12,7 @@ dependencies = [ "pycountry~=20.7.3", "Unidecode~=1.2.0", "barcodenumber~=0.5.0", + "rapidfuzz~=2.15.0", # integration dependencies "gocardless-pro~=1.22.0", From 3a898289b0bcf867263e1b94a90846a1bcaa756a Mon Sep 17 00:00:00 2001 From: marination Date: Mon, 3 Apr 2023 16:11:00 +0530 Subject: [PATCH 03/89] chore: Single query with or filter to search Party Mapper by name/desc --- .../bank_transaction/auto_match_party.py | 36 +++++++++++-------- 1 file changed, 21 insertions(+), 15 deletions(-) diff --git a/erpnext/accounts/doctype/bank_transaction/auto_match_party.py b/erpnext/accounts/doctype/bank_transaction/auto_match_party.py index 7354fa0928..01b674340a 100644 --- a/erpnext/accounts/doctype/bank_transaction/auto_match_party.py +++ b/erpnext/accounts/doctype/bank_transaction/auto_match_party.py @@ -1,4 +1,5 @@ import frappe +from frappe.utils import flt from rapidfuzz import fuzz, process @@ -65,7 +66,7 @@ class AutoMatchbyAccountIBAN: result = None parties = ["Supplier", "Employee", "Customer"] # most -> least likely to receive - if self.deposit > 0: + if flt(self.deposit) > 0: parties = ["Customer", "Supplier", "Employee"] # most -> least likely to pay for party in parties: @@ -103,22 +104,27 @@ class AutoMatchbyPartyDescription: def match_party_name_desc_in_bank_party_mapper(self): """Check if match exists for party name or description in Bank Party Mapper""" result = None - # TODO: or filters + or_filters = [] + if self.bank_party_name: - result = frappe.db.get_value( - "Bank Party Mapper", - filters={"bank_party_name_desc": self.bank_party_name}, - fieldname=["party_type", "party"], - ) + or_filters.append(["bank_party_name_desc", self.bank_party_name]) - if not result and self.description: - result = frappe.db.get_value( - "Bank Party Mapper", - filters={"bank_party_name_desc": self.description}, - fieldname=["party_type", "party"], - ) + if self.description: + or_filters.append(["bank_party_name_desc", self.description]) - result = result + (None,) if result else result + mapper_res = frappe.get_all( + "Bank Party Mapper", + or_filters=or_filters, + fields=["party_type", "party"], + limit_page_length=1, + ) + if mapper_res: + mapper_res = mapper_res[0] + result = ( + mapper_res["party_type"], + mapper_res["party"], + None, + ) return result @@ -127,7 +133,7 @@ class AutoMatchbyPartyDescription: result = None parties = ["Supplier", "Employee", "Customer"] # most-least likely to receive - if frappe.utils.flt(self.deposit) > 0.0: + if flt(self.deposit) > 0.0: parties = ["Customer", "Supplier", "Employee"] # most-least likely to pay for party in parties: From 37c1331aba62ee85a79286d58a71461bb483be54 Mon Sep 17 00:00:00 2001 From: marination Date: Tue, 4 Apr 2023 14:03:35 +0530 Subject: [PATCH 04/89] fix: Don't set description as key in Mapper doc if matched by description - Description is volatile and will keep changing - It will lead to multiple Bank Party Mapper docs for the same party that will never be referenced again - Parts of the descripton keep changing which is why it will never match a mapper record - If matched by desc, dont create mapper record. --- .../doctype/bank_transaction/auto_match_party.py | 12 +++++++++--- .../doctype/bank_transaction/bank_transaction.py | 6 +++--- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/erpnext/accounts/doctype/bank_transaction/auto_match_party.py b/erpnext/accounts/doctype/bank_transaction/auto_match_party.py index 01b674340a..3fbdc5f36b 100644 --- a/erpnext/accounts/doctype/bank_transaction/auto_match_party.py +++ b/erpnext/accounts/doctype/bank_transaction/auto_match_party.py @@ -107,10 +107,10 @@ class AutoMatchbyPartyDescription: or_filters = [] if self.bank_party_name: - or_filters.append(["bank_party_name_desc", self.bank_party_name]) + or_filters.append({"bank_party_name_desc": self.bank_party_name}) if self.description: - or_filters.append(["bank_party_name_desc", self.description]) + or_filters.append({"bank_party_name_desc": self.description}) mapper_res = frappe.get_all( "Bank Party Mapper", @@ -156,7 +156,13 @@ class AutoMatchbyPartyDescription: if result: party_name, score, index = result if score > 75: - return (party, party_name, {"bank_party_name_desc": self.get(field)}) + # Dont set description as a key in Bank Party Mapper due to its volatility + mapper = {"bank_party_name_desc": self.get(field)} if field == "bank_party_name" else None + return ( + party, + party_name, + mapper, + ) else: return None diff --git a/erpnext/accounts/doctype/bank_transaction/bank_transaction.py b/erpnext/accounts/doctype/bank_transaction/bank_transaction.py index 745450423b..118705d0d3 100644 --- a/erpnext/accounts/doctype/bank_transaction/bank_transaction.py +++ b/erpnext/accounts/doctype/bank_transaction/bank_transaction.py @@ -18,9 +18,6 @@ class BankTransaction(StatusUpdater): self.unallocated_amount = abs(flt(self.withdrawal) - flt(self.deposit)) def on_update(self): - if self.party_type and self.party: - return - self.auto_set_party() def on_submit(self): @@ -162,6 +159,9 @@ class BankTransaction(StatusUpdater): # TODO: check if enabled from erpnext.accounts.doctype.bank_transaction.auto_match_party import AutoMatchParty + if self.party_type and self.party: + return + result = AutoMatchParty( bank_party_account_number=self.bank_party_account_number, bank_party_iban=self.bank_party_iban, From 27ce789023c98f4cd99086db9f5fd8d1f3ee3a30 Mon Sep 17 00:00:00 2001 From: marination Date: Tue, 4 Apr 2023 19:27:01 +0530 Subject: [PATCH 05/89] feat: Manually Update/Correct Party in Bank Transaction - On updating bank trans.n party after submit, the corresponding mapper doc will be updated too - The mapper doc in turn will update all linked bank transactions that do not have this updated value - Added Bank Party Mapper hidden link in Bank Transaction - Rename field in BPM to `Party Name` as it does not hold description data - If a BT matches with a BPM record, link that record in the BT --- .../bank_party_mapper/bank_party_mapper.js | 12 ++++---- .../bank_party_mapper/bank_party_mapper.json | 10 +++---- .../bank_party_mapper/bank_party_mapper.py | 19 ++++++++++-- .../bank_transaction/auto_match_party.py | 30 ++++++++----------- .../bank_transaction/bank_transaction.json | 15 ++++++++-- .../bank_transaction/bank_transaction.py | 19 ++++++++++++ 6 files changed, 73 insertions(+), 32 deletions(-) diff --git a/erpnext/accounts/doctype/bank_party_mapper/bank_party_mapper.js b/erpnext/accounts/doctype/bank_party_mapper/bank_party_mapper.js index d11d8040b2..b13e46a0e7 100644 --- a/erpnext/accounts/doctype/bank_party_mapper/bank_party_mapper.js +++ b/erpnext/accounts/doctype/bank_party_mapper/bank_party_mapper.js @@ -1,8 +1,10 @@ // Copyright (c) 2023, Frappe Technologies Pvt. Ltd. and contributors // For license information, please see license.txt -// frappe.ui.form.on("Bank Party Mapper", { -// refresh(frm) { - -// }, -// }); +frappe.ui.form.on("Bank Party Mapper", { + refresh(frm) { + if (!frm.is_new()) { + frm.set_intro(__("Please avoid editing unless you are absolutely certain.")); + } + }, +}); diff --git a/erpnext/accounts/doctype/bank_party_mapper/bank_party_mapper.json b/erpnext/accounts/doctype/bank_party_mapper/bank_party_mapper.json index 4f5f6bfa88..ddc79f24a0 100644 --- a/erpnext/accounts/doctype/bank_party_mapper/bank_party_mapper.json +++ b/erpnext/accounts/doctype/bank_party_mapper/bank_party_mapper.json @@ -9,7 +9,7 @@ "party_type", "party", "column_break_wbna", - "bank_party_name_desc", + "bank_party_name", "bank_party_account_number", "bank_party_iban" ], @@ -47,14 +47,14 @@ "options": "party_type" }, { - "fieldname": "bank_party_name_desc", - "fieldtype": "Small Text", - "label": "Party Name/Desc (Bank Statement)" + "fieldname": "bank_party_name", + "fieldtype": "Data", + "label": "Party Name (Bank Statement)" } ], "index_web_pages_for_search": 1, "links": [], - "modified": "2023-04-03 10:11:31.384383", + "modified": "2023-04-04 14:27:23.450456", "modified_by": "Administrator", "module": "Accounts", "name": "Bank Party Mapper", diff --git a/erpnext/accounts/doctype/bank_party_mapper/bank_party_mapper.py b/erpnext/accounts/doctype/bank_party_mapper/bank_party_mapper.py index d3a9a5e586..02e36b08fe 100644 --- a/erpnext/accounts/doctype/bank_party_mapper/bank_party_mapper.py +++ b/erpnext/accounts/doctype/bank_party_mapper/bank_party_mapper.py @@ -1,9 +1,24 @@ # Copyright (c) 2023, Frappe Technologies Pvt. Ltd. and contributors # For license information, please see license.txt -# import frappe +import frappe from frappe.model.document import Document class BankPartyMapper(Document): - pass + def on_update(self): + self.update_party_in_linked_transactions() + + def update_party_in_linked_transactions(self): + if self.is_new(): + return + + # Set updated party values in other linked bank transactions + bank_transaction = frappe.qb.DocType("Bank Transaction") + + frappe.qb.update(bank_transaction).set("party_type", self.party_type).set( + "party", self.party + ).where( + (bank_transaction.bank_party_mapper == self.name) + & ((bank_transaction.party_type != self.party_type) | (bank_transaction.party != self.party)) + ).run() diff --git a/erpnext/accounts/doctype/bank_transaction/auto_match_party.py b/erpnext/accounts/doctype/bank_transaction/auto_match_party.py index 3fbdc5f36b..9707f79a2a 100644 --- a/erpnext/accounts/doctype/bank_transaction/auto_match_party.py +++ b/erpnext/accounts/doctype/bank_transaction/auto_match_party.py @@ -49,11 +49,11 @@ class AutoMatchbyAccountIBAN: result = frappe.db.get_value( "Bank Party Mapper", filters={filter_field: self.get(filter_field)}, - fieldname=["party_type", "party"], + fieldname=["party_type", "party", "name"], ) if result: - party_type, party = result - return (party_type, party, None) + party_type, party, mapper_name = result + return (party_type, party, {"mapper_name": mapper_name}) return result @@ -89,33 +89,29 @@ class AutoMatchbyPartyDescription: def match(self): # Match by Customer, Supplier or Employee Name - # search bank party mapper by party and then description + # search bank party mapper by party # fuzzy search by customer/supplier & employee if not (self.bank_party_name or self.description): return None - result = self.match_party_name_desc_in_bank_party_mapper() + result = self.match_party_name_in_bank_party_mapper() if not result: result = self.match_party_name_desc_in_party() return result - def match_party_name_desc_in_bank_party_mapper(self): - """Check if match exists for party name or description in Bank Party Mapper""" + def match_party_name_in_bank_party_mapper(self): + """Check if match exists for party name in Bank Party Mapper""" result = None - or_filters = [] - if self.bank_party_name: - or_filters.append({"bank_party_name_desc": self.bank_party_name}) - - if self.description: - or_filters.append({"bank_party_name_desc": self.description}) + if not self.bank_party_name: + return mapper_res = frappe.get_all( "Bank Party Mapper", - or_filters=or_filters, - fields=["party_type", "party"], + filters={"bank_party_name": self.bank_party_name}, + fields=["party_type", "party", "name"], limit_page_length=1, ) if mapper_res: @@ -123,7 +119,7 @@ class AutoMatchbyPartyDescription: result = ( mapper_res["party_type"], mapper_res["party"], - None, + {"mapper_name": mapper_res["name"]}, ) return result @@ -157,7 +153,7 @@ class AutoMatchbyPartyDescription: party_name, score, index = result if score > 75: # Dont set description as a key in Bank Party Mapper due to its volatility - mapper = {"bank_party_name_desc": self.get(field)} if field == "bank_party_name" else None + mapper = {"bank_party_name": self.get(field)} if field == "bank_party_name" else None return ( party, party_name, diff --git a/erpnext/accounts/doctype/bank_transaction/bank_transaction.json b/erpnext/accounts/doctype/bank_transaction/bank_transaction.json index 4139a9f6d5..d3dc5b5845 100644 --- a/erpnext/accounts/doctype/bank_transaction/bank_transaction.json +++ b/erpnext/accounts/doctype/bank_transaction/bank_transaction.json @@ -37,7 +37,8 @@ "column_break_3czf", "bank_party_name", "bank_party_account_number", - "bank_party_iban" + "bank_party_iban", + "bank_party_mapper" ], "fields": [ { @@ -214,7 +215,7 @@ { "fieldname": "bank_party_name", "fieldtype": "Data", - "label": "Party Name (Bank Statement)" + "label": "Party Name/Account Holder (Bank Statement)" }, { "fieldname": "bank_party_iban", @@ -225,11 +226,19 @@ "fieldname": "bank_party_account_number", "fieldtype": "Data", "label": "Party Account No. (Bank Statement)" + }, + { + "fieldname": "bank_party_mapper", + "fieldtype": "Link", + "hidden": 1, + "label": "Bank Party Mapper", + "options": "Bank Party Mapper", + "read_only": 1 } ], "is_submittable": 1, "links": [], - "modified": "2023-03-31 10:45:30.671309", + "modified": "2023-04-04 15:47:20.620006", "modified_by": "Administrator", "module": "Accounts", "name": "Bank Transaction", diff --git a/erpnext/accounts/doctype/bank_transaction/bank_transaction.py b/erpnext/accounts/doctype/bank_transaction/bank_transaction.py index 118705d0d3..a93882a5b3 100644 --- a/erpnext/accounts/doctype/bank_transaction/bank_transaction.py +++ b/erpnext/accounts/doctype/bank_transaction/bank_transaction.py @@ -35,6 +35,8 @@ class BankTransaction(StatusUpdater): self.update_allocations() self._saving_flag = False + self.set_in_bank_party_mapper() + def on_cancel(self): self.clear_linked_payment_entries(for_cancel=True) self.set_status(update=True) @@ -176,11 +178,28 @@ class BankTransaction(StatusUpdater): if not mapper: return + if mapper.get("mapper_name"): + # Transaction matched with a Bank party Mapper record + self.bank_party_mapper = mapper.get("mapper_name") # Link mapper to Bank Transaction + return + mapper_doc = frappe.get_doc( {"doctype": "Bank Party Mapper", "party_type": self.party_type, "party": self.party} ) mapper_doc.update(mapper) mapper_doc.insert() + self.bank_party_mapper = mapper_doc.name # Link mapper to Bank Transaction + + def set_in_bank_party_mapper(self): + """Set in Bank Party Mapper if Party Type & Party are manually changed after submit.""" + doc_before_update = self.get_doc_before_save() + party_type_changed = self.party_type and (doc_before_update.party_type != self.party_type) + party_changed = self.party and (doc_before_update.party != self.party) + + if (party_type_changed or party_changed) and self.bank_party_mapper: + mapper_doc = frappe.get_doc("Bank Party Mapper", self.bank_party_mapper) + mapper_doc.update({"party_type": self.party_type, "party": self.party}) + mapper_doc.save() @frappe.whitelist() From 33604550ce237c23d2d17345e2c041fc183a9b54 Mon Sep 17 00:00:00 2001 From: marination Date: Tue, 4 Apr 2023 19:42:25 +0530 Subject: [PATCH 06/89] chore: Perform automatch on submit - misc: Clearer naming --- .../doctype/bank_transaction/bank_transaction.py | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/erpnext/accounts/doctype/bank_transaction/bank_transaction.py b/erpnext/accounts/doctype/bank_transaction/bank_transaction.py index a93882a5b3..6a094915b7 100644 --- a/erpnext/accounts/doctype/bank_transaction/bank_transaction.py +++ b/erpnext/accounts/doctype/bank_transaction/bank_transaction.py @@ -17,13 +17,12 @@ class BankTransaction(StatusUpdater): def after_insert(self): self.unallocated_amount = abs(flt(self.withdrawal) - flt(self.deposit)) - def on_update(self): - self.auto_set_party() - def on_submit(self): self.clear_linked_payment_entries() self.set_status() + self.auto_set_party() + _saving_flag = False # nosemgrep: frappe-semgrep-rules.rules.frappe-modifying-but-not-comitting @@ -35,7 +34,7 @@ class BankTransaction(StatusUpdater): self.update_allocations() self._saving_flag = False - self.set_in_bank_party_mapper() + self.update_automatch_bank_party_mapper() def on_cancel(self): self.clear_linked_payment_entries(for_cancel=True) @@ -190,8 +189,8 @@ class BankTransaction(StatusUpdater): mapper_doc.insert() self.bank_party_mapper = mapper_doc.name # Link mapper to Bank Transaction - def set_in_bank_party_mapper(self): - """Set in Bank Party Mapper if Party Type & Party are manually changed after submit.""" + def update_automatch_bank_party_mapper(self): + """Update Bank Party Mapper if Party Type & Party are manually changed after submit.""" doc_before_update = self.get_doc_before_save() party_type_changed = self.party_type and (doc_before_update.party_type != self.party_type) party_changed = self.party and (doc_before_update.party != self.party) From aea4315435cecd8c531eda5c4bf305b4792ca692 Mon Sep 17 00:00:00 2001 From: marination Date: Tue, 4 Apr 2023 19:56:21 +0530 Subject: [PATCH 07/89] chore: Make auto matching party configurable - Checkbox in Accounts settings "Enable Automatic Party Matching" - Check before invoking automatching methods - misc: Remove TODO comments --- .../accounts_settings/accounts_settings.json | 18 ++++++++++++++++-- .../bank_transaction/bank_transaction.py | 13 ++++--------- 2 files changed, 20 insertions(+), 11 deletions(-) diff --git a/erpnext/accounts/doctype/accounts_settings/accounts_settings.json b/erpnext/accounts/doctype/accounts_settings/accounts_settings.json index c0eed18ad1..259612e0e4 100644 --- a/erpnext/accounts/doctype/accounts_settings/accounts_settings.json +++ b/erpnext/accounts/doctype/accounts_settings/accounts_settings.json @@ -59,7 +59,9 @@ "frozen_accounts_modifier", "report_settings_sb", "tab_break_dpet", - "show_balance_in_coa" + "show_balance_in_coa", + "banking_tab", + "enable_party_matching" ], "fields": [ { @@ -368,6 +370,18 @@ "fieldname": "book_tax_discount_loss", "fieldtype": "Check", "label": "Book Tax Loss on Early Payment Discount" + }, + { + "fieldname": "banking_tab", + "fieldtype": "Tab Break", + "label": "Banking" + }, + { + "default": "0", + "description": "Auto match and set the Party in Bank Transactions", + "fieldname": "enable_party_matching", + "fieldtype": "Check", + "label": "Enable Automatic Party Matching" } ], "icon": "icon-cog", @@ -375,7 +389,7 @@ "index_web_pages_for_search": 1, "issingle": 1, "links": [], - "modified": "2023-03-28 09:50:20.375233", + "modified": "2023-04-04 16:20:41.330039", "modified_by": "Administrator", "module": "Accounts", "name": "Accounts Settings", diff --git a/erpnext/accounts/doctype/bank_transaction/bank_transaction.py b/erpnext/accounts/doctype/bank_transaction/bank_transaction.py index 6a094915b7..25385a03ca 100644 --- a/erpnext/accounts/doctype/bank_transaction/bank_transaction.py +++ b/erpnext/accounts/doctype/bank_transaction/bank_transaction.py @@ -8,12 +8,6 @@ from erpnext.controllers.status_updater import StatusUpdater class BankTransaction(StatusUpdater): - # TODO - # On submit/update after submit - # - Create/Update a Bank Party Map record - # - User can edit after submit. - # - If changes in party/party name after submit, edit bank party map (which should edit all transactions with same account no/iban/bank party name) - def after_insert(self): self.unallocated_amount = abs(flt(self.withdrawal) - flt(self.deposit)) @@ -21,7 +15,8 @@ class BankTransaction(StatusUpdater): self.clear_linked_payment_entries() self.set_status() - self.auto_set_party() + if frappe.db.get_single_value("Accounts Settings", "enable_party_matching"): + self.auto_set_party() _saving_flag = False @@ -34,7 +29,8 @@ class BankTransaction(StatusUpdater): self.update_allocations() self._saving_flag = False - self.update_automatch_bank_party_mapper() + if frappe.db.get_single_value("Accounts Settings", "enable_party_matching"): + self.update_automatch_bank_party_mapper() def on_cancel(self): self.clear_linked_payment_entries(for_cancel=True) @@ -157,7 +153,6 @@ class BankTransaction(StatusUpdater): ) def auto_set_party(self): - # TODO: check if enabled from erpnext.accounts.doctype.bank_transaction.auto_match_party import AutoMatchParty if self.party_type and self.party: From d7bc1928045d4e89e9acc61b6a71da25537b19a5 Mon Sep 17 00:00:00 2001 From: marination Date: Wed, 5 Apr 2023 15:28:47 +0530 Subject: [PATCH 08/89] fix: Match by both Account No and IBAN & other cleanups - A BT could have both account and iban, and a Supplier could have only IBAN set - In this case, matching by either (only account) gives no match - Match by Account OR IBAN, use `or_filters` - If matched, set both account no. and IBAN in Bank Party Mapper - Explain AutoMatchParty - Add type hints to return values - Use `set_value` to set values in BT after matching since its an after submit event --- .../bank_transaction/auto_match_party.py | 96 +++++++++++++------ .../bank_transaction/bank_transaction.py | 28 +++--- 2 files changed, 82 insertions(+), 42 deletions(-) diff --git a/erpnext/accounts/doctype/bank_transaction/auto_match_party.py b/erpnext/accounts/doctype/bank_transaction/auto_match_party.py index 9707f79a2a..2a2aff1eef 100644 --- a/erpnext/accounts/doctype/bank_transaction/auto_match_party.py +++ b/erpnext/accounts/doctype/bank_transaction/auto_match_party.py @@ -1,16 +1,40 @@ +from typing import Tuple, Union + import frappe from frappe.utils import flt from rapidfuzz import fuzz, process class AutoMatchParty: + """ + Matches by Account/IBAN and then by Party Name/Description sequentially. + Returns when a result is obtained. + + Result (if present) is of the form: (Party Type, Party, Mapper,) + + Mapper(if present) is one of the forms: + 1. {"mapper_name": }: Indicates that an existing Bank Party Mapper matched against + the transaction and the same must be linked in the Bank Transaction. + + 2. {"bank_party_account_number": , "bank_party_iban": } : Indicates that a match was + found in Customer/Supplier/Employee by account details. A Bank Party Mapper is now created + mapping the Party to the Account No./IBAN + + 3. {"bank_party_name": }: Indicates that a match was found in + Customer/Supplier/Employee by party name. A Bank Party Mapper is now created mapping the Party + to the Party Name (Bank Statement). If matched by Description, no mapper is created as + description is not a static key. + + Mapper data is used either to create a new Bank Party Mapper or link an existing mapper to a transaction. + """ + def __init__(self, **kwargs) -> None: self.__dict__.update(kwargs) def get(self, key): return self.__dict__.get(key, None) - def match(self): + def match(self) -> Union[Tuple, None]: result = AutoMatchbyAccountIBAN( bank_party_account_number=self.bank_party_account_number, bank_party_iban=self.bank_party_iban, @@ -42,27 +66,30 @@ class AutoMatchbyAccountIBAN: return result - def match_account_in_bank_party_mapper(self): - filter_field = ( - "bank_party_account_number" if self.bank_party_account_number else "bank_party_iban" - ) - result = frappe.db.get_value( + def match_account_in_bank_party_mapper(self) -> Union[Tuple, None]: + """Check for a IBAN/Account No. match in Bank Party Mapper""" + result = None + or_filters = {} + if self.bank_party_account_number: + or_filters["bank_party_account_number"] = self.bank_party_account_number + + if self.bank_party_iban: + or_filters["bank_party_iban"] = self.bank_party_iban + + mapper = frappe.db.get_all( "Bank Party Mapper", - filters={filter_field: self.get(filter_field)}, - fieldname=["party_type", "party", "name"], + or_filters=or_filters, + fields=["party_type", "party", "name"], + limit_page_length=1, ) - if result: - party_type, party, mapper_name = result - return (party_type, party, {"mapper_name": mapper_name}) + if mapper: + data = mapper[0] + return (data["party_type"], data["party"], {"mapper_name": data["name"]}) return result - def match_account_in_party(self): - # If not check if there is a match in Customer/Supplier/Employee - filter_field = "bank_account_no" if self.bank_party_account_number else "iban" - transaction_field = ( - "bank_party_account_number" if self.bank_party_account_number else "bank_party_iban" - ) + def match_account_in_party(self) -> Union[Tuple, None]: + """Check if there is a IBAN/Account No. match in Customer/Supplier/Employee""" result = None parties = ["Supplier", "Employee", "Customer"] # most -> least likely to receive @@ -70,11 +97,26 @@ class AutoMatchbyAccountIBAN: parties = ["Customer", "Supplier", "Employee"] # most -> least likely to pay for party in parties: - party_name = frappe.db.get_value( - party, filters={filter_field: self.get(transaction_field)}, fieldname=["name"] + or_filters = {} + if self.bank_party_account_number: + acc_no_field = "bank_ac_no" if party == "Employee" else "bank_account_no" + or_filters[acc_no_field] = self.bank_party_account_number + + if self.bank_party_iban: + or_filters["iban"] = self.bank_party_iban + + party_result = frappe.db.get_all( + party, or_filters=or_filters, pluck="name", limit_page_length=1 ) - if party_name: - result = (party, party_name, {transaction_field: self.get(transaction_field)}) + if party_result: + result = ( + party, + party_result[0], + { + "bank_party_account_number": self.get("bank_party_account_number"), + "bank_party_iban": self.get("bank_party_iban"), + }, + ) break return result @@ -87,7 +129,7 @@ class AutoMatchbyPartyDescription: def get(self, key): return self.__dict__.get(key, None) - def match(self): + def match(self) -> Union[Tuple, None]: # Match by Customer, Supplier or Employee Name # search bank party mapper by party # fuzzy search by customer/supplier & employee @@ -101,10 +143,9 @@ class AutoMatchbyPartyDescription: return result - def match_party_name_in_bank_party_mapper(self): + def match_party_name_in_bank_party_mapper(self) -> Union[Tuple, None]: """Check if match exists for party name in Bank Party Mapper""" result = None - if not self.bank_party_name: return @@ -116,7 +157,7 @@ class AutoMatchbyPartyDescription: ) if mapper_res: mapper_res = mapper_res[0] - result = ( + return ( mapper_res["party_type"], mapper_res["party"], {"mapper_name": mapper_res["name"]}, @@ -124,10 +165,9 @@ class AutoMatchbyPartyDescription: return result - def match_party_name_desc_in_party(self): + def match_party_name_desc_in_party(self) -> Union[Tuple, None]: """Fuzzy search party name and/or description against parties in the system""" result = None - parties = ["Supplier", "Employee", "Customer"] # most-least likely to receive if flt(self.deposit) > 0.0: parties = ["Customer", "Supplier", "Employee"] # most-least likely to pay @@ -146,7 +186,7 @@ class AutoMatchbyPartyDescription: return result - def fuzzy_search_and_return_result(self, party, names, field): + def fuzzy_search_and_return_result(self, party, names, field) -> Union[Tuple, None]: result = process.extractOne(query=self.get(field), choices=names, scorer=fuzz.token_set_ratio) if result: diff --git a/erpnext/accounts/doctype/bank_transaction/bank_transaction.py b/erpnext/accounts/doctype/bank_transaction/bank_transaction.py index 25385a03ca..cf3a6e648a 100644 --- a/erpnext/accounts/doctype/bank_transaction/bank_transaction.py +++ b/erpnext/accounts/doctype/bank_transaction/bank_transaction.py @@ -167,22 +167,22 @@ class BankTransaction(StatusUpdater): ).match() if result: - self.party_type, self.party, mapper = result + party_type, party, mapper = result + to_update = {"party_type": party_type, "party": party} - if not mapper: - return + if mapper and mapper.get("mapper_name"): + # Transaction matched with an existing Bank party Mapper record + to_update["bank_party_mapper"] = mapper.get("mapper_name") + elif mapper: + # Make new Mapper record to remember match + mapper_doc = frappe.get_doc( + {"doctype": "Bank Party Mapper", "party_type": party_type, "party": party} + ) + mapper_doc.update(mapper) + mapper_doc.insert() + to_update["bank_party_mapper"] = mapper_doc.name - if mapper.get("mapper_name"): - # Transaction matched with a Bank party Mapper record - self.bank_party_mapper = mapper.get("mapper_name") # Link mapper to Bank Transaction - return - - mapper_doc = frappe.get_doc( - {"doctype": "Bank Party Mapper", "party_type": self.party_type, "party": self.party} - ) - mapper_doc.update(mapper) - mapper_doc.insert() - self.bank_party_mapper = mapper_doc.name # Link mapper to Bank Transaction + frappe.db.set_value("Bank Transaction", self.name, field=to_update) def update_automatch_bank_party_mapper(self): """Update Bank Party Mapper if Party Type & Party are manually changed after submit.""" From 7ed8f59dc89f02562a56d1281219506214a440b3 Mon Sep 17 00:00:00 2001 From: marination Date: Mon, 10 Apr 2023 22:11:00 +0530 Subject: [PATCH 09/89] test: Match by Account No, IBAN, Party Name, Desc and match correction --- .../bank_transaction/test_auto_match_party.py | 193 ++++++++++++++++++ 1 file changed, 193 insertions(+) create mode 100644 erpnext/accounts/doctype/bank_transaction/test_auto_match_party.py diff --git a/erpnext/accounts/doctype/bank_transaction/test_auto_match_party.py b/erpnext/accounts/doctype/bank_transaction/test_auto_match_party.py new file mode 100644 index 0000000000..86181c865d --- /dev/null +++ b/erpnext/accounts/doctype/bank_transaction/test_auto_match_party.py @@ -0,0 +1,193 @@ +# Copyright (c) 2023, Frappe Technologies Pvt. Ltd. and Contributors +# License: GNU General Public License v3. See license.txt + +import frappe +from frappe.tests.utils import FrappeTestCase +from frappe.utils import nowdate + +from erpnext.accounts.doctype.bank_transaction.test_bank_transaction import create_bank_account + + +class TestAutoMatchParty(FrappeTestCase): + @classmethod + def setUpClass(cls): + create_bank_account() + frappe.db.set_single_value("Accounts Settings", "enable_party_matching", 1) + return super().setUpClass() + + @classmethod + def tearDownClass(cls): + frappe.db.set_single_value("Accounts Settings", "enable_party_matching", 0) + + def test_match_by_account_number(self): + """Test if transaction matches with existing (Bank Party Mapper) or new match.""" + create_supplier_for_match(account_no="000000003716541159") + doc = create_bank_transaction( + withdrawal=1200, + transaction_id="562213b0ca1bf838dab8f2c6a39bbc3b", + account_no="000000003716541159", + iban="DE02000000003716541159", + ) + + self.assertEqual(doc.party_type, "Supplier") + self.assertEqual(doc.party, "John Doe & Co.") + self.assertTrue(doc.bank_party_mapper) + + # Check if Bank Party Mapper is created to remember mapping + bank_party_mapper = frappe.get_doc("Bank Party Mapper", doc.bank_party_mapper) + self.assertEqual(bank_party_mapper.party, "John Doe & Co.") + self.assertEqual(bank_party_mapper.bank_party_account_number, "000000003716541159") + self.assertEqual(bank_party_mapper.bank_party_iban, "DE02000000003716541159") + + # Check if created mapping is used for quick match + doc_2 = create_bank_transaction( + withdrawal=500, + transaction_id="602413b8ji8bf838fub8f2c6a39bah7y", + account_no="000000003716541159", + ) + self.assertEqual(doc_2.party, "John Doe & Co.") + self.assertEqual(doc_2.bank_party_mapper, bank_party_mapper.name) + + def test_match_by_iban(self): + create_supplier_for_match(iban="DE02000000003716541159") + doc = create_bank_transaction( + withdrawal=1200, + transaction_id="c5455a224602afaa51592a9d9250600d", + account_no="000000003716541159", + iban="DE02000000003716541159", + ) + + self.assertEqual(doc.party_type, "Supplier") + self.assertEqual(doc.party, "John Doe & Co.") + self.assertTrue(doc.bank_party_mapper) + + bank_party_mapper = frappe.get_doc("Bank Party Mapper", doc.bank_party_mapper) + self.assertEqual(bank_party_mapper.party, "John Doe & Co.") + self.assertEqual(bank_party_mapper.bank_party_account_number, "000000003716541159") + self.assertEqual(bank_party_mapper.bank_party_iban, "DE02000000003716541159") + + def test_match_by_party_name(self): + create_supplier_for_match(supplier_name="Jackson Ella W.") + doc = create_bank_transaction( + withdrawal=1200, + transaction_id="1f6f661f347ff7b1ea588665f473adb1", + party_name="Ella Jackson", + iban="DE04000000003716545346", + ) + self.assertEqual(doc.party_type, "Supplier") + self.assertEqual(doc.party, "Jackson Ella W.") + self.assertTrue(doc.bank_party_mapper) + + bank_party_mapper = frappe.get_doc("Bank Party Mapper", doc.bank_party_mapper) + self.assertEqual(bank_party_mapper.party, "Jackson Ella W.") + self.assertEqual(bank_party_mapper.bank_party_name, "Ella Jackson") + self.assertEqual(bank_party_mapper.bank_party_iban, None) + + # Check if created mapping is used for quick match + doc_2 = create_bank_transaction( + withdrawal=500, + transaction_id="578313b8ji8bf838fub8f2c6a39bah7y", + party_name="Ella Jackson", + account_no="000000004316531152", + ) + self.assertEqual(doc_2.party, "Jackson Ella W.") + self.assertEqual(doc_2.bank_party_mapper, bank_party_mapper.name) + + def test_match_by_description(self): + create_supplier_for_match(supplier_name="Microsoft") + doc = create_bank_transaction( + description="Auftraggeber: microsoft payments Buchungstext: msft ..e3006b5hdy. ref. j375979555927627/5536", + withdrawal=1200, + transaction_id="8df880a2d09c3bed3fea358ca5168c5a", + party_name="", + ) + self.assertEqual(doc.party_type, "Supplier") + self.assertEqual(doc.party, "Microsoft") + self.assertFalse(doc.bank_party_mapper) + + def test_correct_match_after_submit(self): + """Correct wrong mapping after submit. Test impact.""" + # Similar named suppliers + create_supplier_for_match(supplier_name="Amazon") + create_supplier_for_match(supplier_name="Amazing Co.") + + # Bank Transactions actually from "Amazon" that match better with "Amazing Co." + doc = create_bank_transaction( + description="visa06323202 amzn.com/bill 7,88eur1,5324711959 90.22. 1,62 87861003", + withdrawal=24.85, + transaction_id="3a1da4ee2dc5a980138d36ef5297cbd9", + party_name="Amazn Co.", + ) + doc_2 = create_bank_transaction( + description="visa61268005 amzn.com/bill 22,345eur1,7654711959 89.23. 1,64 61268005", + withdrawal=80, + transaction_id="584314e459b00f792bfd569267efba6e", + party_name="Amazn Co.", + ) + + self.assertEqual(doc.party_type, "Supplier") + self.assertEqual(doc.party, "Amazing Co.") + self.assertTrue(doc.bank_party_mapper) + self.assertTrue(doc_2.bank_party_mapper, doc.bank_party_mapper) + + bank_party_mapper = frappe.get_doc("Bank Party Mapper", doc.bank_party_mapper) + self.assertEqual(bank_party_mapper.party, "Amazing Co.") + self.assertEqual(bank_party_mapper.bank_party_name, "Amazn Co.") + + # User corrects the value after submit to "Amazon" + doc.party = "Amazon" + doc.save() + bank_party_mapper.reload() + doc_2.reload() + + # Mapping is edited and all transactions with this mapping are updated + self.assertEqual(bank_party_mapper.party, "Amazon") + self.assertEqual(bank_party_mapper.bank_party_name, "Amazn Co.") + self.assertEqual(doc_2.party, "Amazon") + + +def create_supplier_for_match(supplier_name="John Doe & Co.", account_no=None, iban=None): + if frappe.db.exists("Supplier", supplier_name): + frappe.db.set_value("Supplier", supplier_name, {"bank_account_no": account_no, "iban": iban}) + return + + frappe.get_doc( + { + "doctype": "Supplier", + "supplier_name": supplier_name, + "supplier_group": "Services", + "supplier_type": "Company", + "bank_account_no": account_no, + "iban": iban, + } + ).insert() + + +def create_bank_transaction( + description=None, + withdrawal=0, + deposit=0, + transaction_id=None, + party_name=None, + account_no=None, + iban=None, +): + doc = frappe.get_doc( + { + "doctype": "Bank Transaction", + "description": description or "1512567 BG/000002918 OPSKATTUZWXXX AT776000000098709837 Herr G", + "date": nowdate(), + "withdrawal": withdrawal, + "deposit": deposit, + "currency": "INR", + "bank_account": "Checking Account - Citi Bank", + "transaction_id": transaction_id, + "bank_party_name": party_name, + "bank_party_account_number": account_no, + "bank_party_iban": iban, + } + ).insert() + doc.submit() + doc.reload() + + return doc From 430b247dfc0e4f681fe47d540fd24cd0b40f76d1 Mon Sep 17 00:00:00 2001 From: marination Date: Tue, 11 Apr 2023 01:33:08 +0530 Subject: [PATCH 10/89] fix: Remove bank details fields from Shareholder --- .../doctype/shareholder/shareholder.json | 27 ++----------------- 1 file changed, 2 insertions(+), 25 deletions(-) diff --git a/erpnext/accounts/doctype/shareholder/shareholder.json b/erpnext/accounts/doctype/shareholder/shareholder.json index 2be2a2fc42..e80b05720e 100644 --- a/erpnext/accounts/doctype/shareholder/shareholder.json +++ b/erpnext/accounts/doctype/shareholder/shareholder.json @@ -20,11 +20,7 @@ "contact_html", "section_break_3", "share_balance", - "contact_list", - "bank_details_section", - "bank_account_no", - "column_break_tyo0", - "iban" + "contact_list" ], "fields": [ { @@ -114,29 +110,10 @@ "hidden": 1, "label": "Contact List", "read_only": 1 - }, - { - "fieldname": "bank_details_section", - "fieldtype": "Section Break", - "label": "Bank Details" - }, - { - "fieldname": "bank_account_no", - "fieldtype": "Data", - "label": "Bank Account No" - }, - { - "fieldname": "column_break_tyo0", - "fieldtype": "Column Break" - }, - { - "fieldname": "iban", - "fieldtype": "Data", - "label": "IBAN" } ], "links": [], - "modified": "2023-03-30 16:00:55.087823", + "modified": "2023-04-10 22:02:20.406087", "modified_by": "Administrator", "module": "Accounts", "name": "Shareholder", From dbf7a479b66bc31890b4a957564c7dfdfad49517 Mon Sep 17 00:00:00 2001 From: marination Date: Tue, 9 May 2023 20:36:07 +0530 Subject: [PATCH 11/89] fix: Use existing bank fields to match by bank account no/IBAN - Remove newly added fields in Party doctypes to store bank details - Use Bank Account's fields to match against account no/iban - For employee, if Bank Account does not exist, find in Employee doctype against account no/iban --- .../bank_transaction/auto_match_party.py | 15 ++++++++-- erpnext/buying/doctype/supplier/supplier.json | 30 +------------------ .../selling/doctype/customer/customer.json | 25 +--------------- 3 files changed, 14 insertions(+), 56 deletions(-) diff --git a/erpnext/accounts/doctype/bank_transaction/auto_match_party.py b/erpnext/accounts/doctype/bank_transaction/auto_match_party.py index 2a2aff1eef..e43d9beb05 100644 --- a/erpnext/accounts/doctype/bank_transaction/auto_match_party.py +++ b/erpnext/accounts/doctype/bank_transaction/auto_match_party.py @@ -99,15 +99,24 @@ class AutoMatchbyAccountIBAN: for party in parties: or_filters = {} if self.bank_party_account_number: - acc_no_field = "bank_ac_no" if party == "Employee" else "bank_account_no" - or_filters[acc_no_field] = self.bank_party_account_number + or_filters["bank_account_no"] = self.bank_party_account_number if self.bank_party_iban: or_filters["iban"] = self.bank_party_iban party_result = frappe.db.get_all( - party, or_filters=or_filters, pluck="name", limit_page_length=1 + "Bank Account", or_filters=or_filters, pluck="name", limit_page_length=1 ) + + if party == "Employee" and not party_result: + # Search in Bank Accounts first for Employee, and then Employee record + if "bank_account_no" in or_filters: + or_filters["bank_ac_no"] = or_filters.pop("bank_account_no") + + party_result = frappe.db.get_all( + party, or_filters=or_filters, pluck="name", limit_page_length=1 + ) + if party_result: result = ( party, diff --git a/erpnext/buying/doctype/supplier/supplier.json b/erpnext/buying/doctype/supplier/supplier.json index a80dcfe538..f0097898f6 100644 --- a/erpnext/buying/doctype/supplier/supplier.json +++ b/erpnext/buying/doctype/supplier/supplier.json @@ -52,11 +52,6 @@ "supplier_primary_address", "primary_address", "accounting_tab", - "bank_details_section", - "bank_account_no", - "column_break_n8mz", - "iban", - "section_break_ow3k", "payment_terms", "accounts", "settings_tab", @@ -450,29 +445,6 @@ { "fieldname": "column_break_59", "fieldtype": "Column Break" - }, - { - "fieldname": "bank_details_section", - "fieldtype": "Section Break", - "label": "Bank Details" - }, - { - "fieldname": "bank_account_no", - "fieldtype": "Data", - "label": "Bank Account No" - }, - { - "fieldname": "column_break_n8mz", - "fieldtype": "Column Break" - }, - { - "fieldname": "iban", - "fieldtype": "Data", - "label": "IBAN" - }, - { - "fieldname": "section_break_ow3k", - "fieldtype": "Section Break" } ], "icon": "fa fa-user", @@ -485,7 +457,7 @@ "link_fieldname": "party" } ], - "modified": "2023-03-30 15:50:40.241257", + "modified": "2023-05-09 15:34:13.408932", "modified_by": "Administrator", "module": "Buying", "name": "Supplier", diff --git a/erpnext/selling/doctype/customer/customer.json b/erpnext/selling/doctype/customer/customer.json index 5dc6a72da8..72a1594b2d 100644 --- a/erpnext/selling/doctype/customer/customer.json +++ b/erpnext/selling/doctype/customer/customer.json @@ -61,10 +61,6 @@ "tax_category", "tax_withholding_category", "accounting_tab", - "bank_details_section", - "bank_account_no", - "column_break_xtwg", - "iban", "credit_limit_section", "payment_terms", "credit_limits", @@ -559,25 +555,6 @@ { "fieldname": "column_break_54", "fieldtype": "Column Break" - }, - { - "fieldname": "bank_details_section", - "fieldtype": "Section Break", - "label": "Bank Details" - }, - { - "fieldname": "bank_account_no", - "fieldtype": "Data", - "label": "Bank Account No" - }, - { - "fieldname": "column_break_xtwg", - "fieldtype": "Column Break" - }, - { - "fieldname": "iban", - "fieldtype": "Data", - "label": "IBAN" } ], "icon": "fa fa-user", @@ -591,7 +568,7 @@ "link_fieldname": "party" } ], - "modified": "2023-03-30 15:45:44.387975", + "modified": "2023-05-09 15:38:40.255193", "modified_by": "Administrator", "module": "Selling", "name": "Customer", From 4a14e9ea4e8f131913f7a0ede725db9a7603e85a Mon Sep 17 00:00:00 2001 From: marination Date: Wed, 17 May 2023 14:23:44 +0530 Subject: [PATCH 12/89] fix: Tests --- .../bank_transaction/auto_match_party.py | 2 +- .../bank_transaction/test_auto_match_party.py | 40 ++++++++++++++++--- 2 files changed, 35 insertions(+), 7 deletions(-) diff --git a/erpnext/accounts/doctype/bank_transaction/auto_match_party.py b/erpnext/accounts/doctype/bank_transaction/auto_match_party.py index e43d9beb05..79d52c6565 100644 --- a/erpnext/accounts/doctype/bank_transaction/auto_match_party.py +++ b/erpnext/accounts/doctype/bank_transaction/auto_match_party.py @@ -105,7 +105,7 @@ class AutoMatchbyAccountIBAN: or_filters["iban"] = self.bank_party_iban party_result = frappe.db.get_all( - "Bank Account", or_filters=or_filters, pluck="name", limit_page_length=1 + "Bank Account", or_filters=or_filters, pluck="party", limit_page_length=1 ) if party == "Employee" and not party_result: diff --git a/erpnext/accounts/doctype/bank_transaction/test_auto_match_party.py b/erpnext/accounts/doctype/bank_transaction/test_auto_match_party.py index 86181c865d..2f94516ac2 100644 --- a/erpnext/accounts/doctype/bank_transaction/test_auto_match_party.py +++ b/erpnext/accounts/doctype/bank_transaction/test_auto_match_party.py @@ -146,22 +146,50 @@ class TestAutoMatchParty(FrappeTestCase): self.assertEqual(doc_2.party, "Amazon") -def create_supplier_for_match(supplier_name="John Doe & Co.", account_no=None, iban=None): - if frappe.db.exists("Supplier", supplier_name): - frappe.db.set_value("Supplier", supplier_name, {"bank_account_no": account_no, "iban": iban}) +def create_supplier_for_match(supplier_name="John Doe & Co.", iban=None, account_no=None): + if frappe.db.exists("Supplier", {"supplier_name": supplier_name}): + # Update related Bank Account details + if not (iban or account_no): + return + + frappe.db.set_value( + dt="Bank Account", + dn={"party": supplier_name}, + field={"iban": iban, "bank_account_no": account_no}, + ) return - frappe.get_doc( + # Create Supplier and Bank Account for the same + supplier = frappe.get_doc( { "doctype": "Supplier", "supplier_name": supplier_name, "supplier_group": "Services", "supplier_type": "Company", - "bank_account_no": account_no, - "iban": iban, } ).insert() + if not frappe.db.exists("Bank", "TestBank"): + frappe.get_doc( + { + "doctype": "Bank", + "bank_name": "TestBank", + } + ).insert(ignore_if_duplicate=True) + + if not frappe.db.exists("Bank Account", supplier.name + " - " + "TestBank"): + frappe.get_doc( + { + "doctype": "Bank Account", + "account_name": supplier.name, + "bank": "TestBank", + "iban": iban, + "bank_account_no": account_no, + "party_type": "Supplier", + "party": supplier.name, + } + ).insert() + def create_bank_transaction( description=None, From 4364fb9628854a27942304e55c26f62d916cd46c Mon Sep 17 00:00:00 2001 From: marination Date: Wed, 17 May 2023 19:45:03 +0530 Subject: [PATCH 13/89] feat: Optional Fuzzy Matching & Skip Matches for multiple similar matches - Fuzzy matching can be enabled optionally in the settings - If a query gets multiple matches with the same score, do not set a party as it is an extremely close call - misc: Add 'cancelled' status to Bank transaction - Test for skipping matching with extremely close matches --- .../accounts_settings/accounts_settings.json | 13 +++- .../bank_transaction/auto_match_party.py | 77 ++++++++++++++----- .../bank_transaction/bank_transaction.json | 4 +- .../bank_transaction/test_auto_match_party.py | 18 +++++ 4 files changed, 88 insertions(+), 24 deletions(-) diff --git a/erpnext/accounts/doctype/accounts_settings/accounts_settings.json b/erpnext/accounts/doctype/accounts_settings/accounts_settings.json index ff07de3467..05f1169d96 100644 --- a/erpnext/accounts/doctype/accounts_settings/accounts_settings.json +++ b/erpnext/accounts/doctype/accounts_settings/accounts_settings.json @@ -64,7 +64,8 @@ "tab_break_dpet", "show_balance_in_coa", "banking_tab", - "enable_party_matching" + "enable_party_matching", + "enable_fuzzy_matching" ], "fields": [ { @@ -404,6 +405,14 @@ "fieldname": "enable_party_matching", "fieldtype": "Check", "label": "Enable Automatic Party Matching" + }, + { + "default": "0", + "depends_on": "enable_party_matching", + "description": "Approximately match the description/party name against parties", + "fieldname": "enable_fuzzy_matching", + "fieldtype": "Check", + "label": "Enable Fuzzy Matching" } ], "icon": "icon-cog", @@ -411,7 +420,7 @@ "index_web_pages_for_search": 1, "issingle": 1, "links": [], - "modified": "2023-04-21 13:11:37.130743", + "modified": "2023-05-17 12:20:04.107641", "modified_by": "Administrator", "module": "Accounts", "name": "Accounts Settings", diff --git a/erpnext/accounts/doctype/bank_transaction/auto_match_party.py b/erpnext/accounts/doctype/bank_transaction/auto_match_party.py index 79d52c6565..753f0c1171 100644 --- a/erpnext/accounts/doctype/bank_transaction/auto_match_party.py +++ b/erpnext/accounts/doctype/bank_transaction/auto_match_party.py @@ -35,13 +35,15 @@ class AutoMatchParty: return self.__dict__.get(key, None) def match(self) -> Union[Tuple, None]: + result = None result = AutoMatchbyAccountIBAN( bank_party_account_number=self.bank_party_account_number, bank_party_iban=self.bank_party_iban, deposit=self.deposit, ).match() - if not result: + fuzzy_matching_enabled = frappe.db.get_single_value("Accounts Settings", "enable_fuzzy_matching") + if not result and fuzzy_matching_enabled: result = AutoMatchbyPartyDescription( bank_party_name=self.bank_party_name, description=self.description, deposit=self.deposit ).match() @@ -184,31 +186,66 @@ class AutoMatchbyPartyDescription: for party in parties: name_field = party.lower() + "_name" filters = {"status": "Active"} if party == "Employee" else {"disabled": 0} - names = frappe.get_all(party, filters=filters, pluck=name_field) for field in ["bank_party_name", "description"]: - if not result and self.get(field): - result = self.fuzzy_search_and_return_result(party, names, field) - if result: - break + if not self.get(field): + continue + + result, skip = self.fuzzy_search_and_return_result(party, names, field) + if result or skip: + break + + if result or skip: + # We skip if: + # If it was hard to distinguish between close matches and so match is None + # OR if the right match was found + break return result def fuzzy_search_and_return_result(self, party, names, field) -> Union[Tuple, None]: - result = process.extractOne(query=self.get(field), choices=names, scorer=fuzz.token_set_ratio) + skip = False - if result: - party_name, score, index = result - if score > 75: - # Dont set description as a key in Bank Party Mapper due to its volatility - mapper = {"bank_party_name": self.get(field)} if field == "bank_party_name" else None - return ( - party, - party_name, - mapper, - ) - else: - return None + result = process.extract(query=self.get(field), choices=names, scorer=fuzz.token_set_ratio) + party_name, skip = self.process_fuzzy_result(result) - return result + if not party_name: + return None, skip + + # Dont set description as a key in Bank Party Mapper due to its volatility + mapper = {"bank_party_name": self.get(field)} if field == "bank_party_name" else None + return ( + party, + party_name, + mapper, + ), skip + + def process_fuzzy_result(self, result: Union[list, None]): + """ + If there are multiple valid close matches return None as result may be faulty. + Return the result only if one accurate match stands out. + + Returns: Result, Skip (whether or not to continue matching) + """ + PARTY, SCORE, CUTOFF = 0, 1, 80 + + if not result or not len(result): + return None, False + + first_result = result[0] + + if len(result) == 1: + return (result[0][PARTY] if first_result[SCORE] > CUTOFF else None), True + + second_result = result[1] + + if first_result[SCORE] > CUTOFF: + # If multiple matches with the same score, return None but discontinue matching + # Matches were found but were too closes to distinguish between + if first_result[SCORE] == second_result[SCORE]: + return None, True + + return first_result[PARTY], True + else: + return None, False diff --git a/erpnext/accounts/doctype/bank_transaction/bank_transaction.json b/erpnext/accounts/doctype/bank_transaction/bank_transaction.json index d3dc5b5845..e7de71aef4 100644 --- a/erpnext/accounts/doctype/bank_transaction/bank_transaction.json +++ b/erpnext/accounts/doctype/bank_transaction/bank_transaction.json @@ -68,7 +68,7 @@ "fieldtype": "Select", "in_standard_filter": 1, "label": "Status", - "options": "\nPending\nSettled\nUnreconciled\nReconciled" + "options": "\nPending\nSettled\nUnreconciled\nReconciled\nCancelled" }, { "fieldname": "bank_account", @@ -238,7 +238,7 @@ ], "is_submittable": 1, "links": [], - "modified": "2023-04-04 15:47:20.620006", + "modified": "2023-05-17 14:56:10.547480", "modified_by": "Administrator", "module": "Accounts", "name": "Bank Transaction", diff --git a/erpnext/accounts/doctype/bank_transaction/test_auto_match_party.py b/erpnext/accounts/doctype/bank_transaction/test_auto_match_party.py index 2f94516ac2..8c6dc9d766 100644 --- a/erpnext/accounts/doctype/bank_transaction/test_auto_match_party.py +++ b/erpnext/accounts/doctype/bank_transaction/test_auto_match_party.py @@ -13,11 +13,13 @@ class TestAutoMatchParty(FrappeTestCase): def setUpClass(cls): create_bank_account() frappe.db.set_single_value("Accounts Settings", "enable_party_matching", 1) + frappe.db.set_single_value("Accounts Settings", "enable_fuzzy_matching", 1) return super().setUpClass() @classmethod def tearDownClass(cls): frappe.db.set_single_value("Accounts Settings", "enable_party_matching", 0) + frappe.db.set_single_value("Accounts Settings", "enable_fuzzy_matching", 0) def test_match_by_account_number(self): """Test if transaction matches with existing (Bank Party Mapper) or new match.""" @@ -145,6 +147,22 @@ class TestAutoMatchParty(FrappeTestCase): self.assertEqual(bank_party_mapper.bank_party_name, "Amazn Co.") self.assertEqual(doc_2.party, "Amazon") + def test_skip_match_if_multiple_close_results(self): + create_supplier_for_match(supplier_name="Adithya Medical & General Stores") + create_supplier_for_match(supplier_name="Adithya Medical And General Stores") + + doc = create_bank_transaction( + description="Paracetamol Consignment, SINV-0009", + withdrawal=24.85, + transaction_id="3a1da4ee2dc5a980138d56ef3460cbd9", + party_name="Adithya Medical & General", + ) + + # Mapping is skipped as both Supplier names have the same match score + self.assertEqual(doc.party_type, None) + self.assertEqual(doc.party, None) + self.assertFalse(doc.bank_party_mapper) + def create_supplier_for_match(supplier_name="John Doe & Co.", iban=None, account_no=None): if frappe.db.exists("Supplier", {"supplier_name": supplier_name}): From 2e52a63b0df0f20ff774131623580377ce57d451 Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Sun, 4 Jun 2023 19:20:28 +0530 Subject: [PATCH 14/89] feat: Accounting Ledger Preview --- .../doctype/sales_invoice/sales_invoice.js | 1 + erpnext/controllers/stock_controller.py | 13 +++++++ .../public/js/controllers/stock_controller.js | 36 ++++++++++++++++++- 3 files changed, 49 insertions(+), 1 deletion(-) diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.js b/erpnext/accounts/doctype/sales_invoice/sales_invoice.js index 8cb29505eb..1ef0c51cba 100644 --- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.js +++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.js @@ -88,6 +88,7 @@ erpnext.accounts.SalesInvoiceController = class SalesInvoiceController extends e } this.show_general_ledger(); + this.show_ledger_preview(); if(doc.update_stock) this.show_stock_ledger(); diff --git a/erpnext/controllers/stock_controller.py b/erpnext/controllers/stock_controller.py index befde71775..30dcc7ffa7 100644 --- a/erpnext/controllers/stock_controller.py +++ b/erpnext/controllers/stock_controller.py @@ -15,6 +15,7 @@ from erpnext.accounts.general_ledger import ( make_reverse_gl_entries, process_gl_map, ) +from erpnext.accounts.report.general_ledger.general_ledger import get_columns from erpnext.accounts.utils import get_fiscal_year from erpnext.controllers.accounts_controller import AccountsController from erpnext.stock import get_warehouse_account_map @@ -824,6 +825,18 @@ class StockController(AccountsController): gl_entries.append(self.get_gl_dict(gl_entry, item=item)) +@frappe.whitelist() +def show_ledger_preview(company, doctype, docname): + filters = {"company": company} + doc = frappe.get_doc(doctype, docname) + columns = get_columns(filters) + data = doc.get_gl_entries() + return { + "columns": columns, + "data": data, + } + + def repost_required_for_queue(doc: StockController) -> bool: """check if stock document contains repeated item-warehouse with queue based valuation. diff --git a/erpnext/public/js/controllers/stock_controller.js b/erpnext/public/js/controllers/stock_controller.js index d346357a8f..919ffda52f 100644 --- a/erpnext/public/js/controllers/stock_controller.js +++ b/erpnext/public/js/controllers/stock_controller.js @@ -66,7 +66,7 @@ erpnext.stock.StockController = class StockController extends frappe.ui.form.Con } show_general_ledger() { - var me = this; + let me = this; if(this.frm.doc.docstatus > 0) { cur_frm.add_custom_button(__('Accounting Ledger'), function() { frappe.route_options = { @@ -81,4 +81,38 @@ erpnext.stock.StockController = class StockController extends frappe.ui.form.Con }, __("View")); } } + + show_ledger_preview() { + let me = this + if(this.frm.doc.docstatus == 0) { + cur_frm.add_custom_button(__('Accounting Ledger Preview'), function() { + frappe.call({ + "method": "erpnext.controllers.stock_controller.show_ledger_preview", + "args": { + "company": me.frm.doc.company, + "doctype": me.frm.doc.doctype, + "docname": me.frm.doc.name + }, + "callback": function(response) { + me.get_datatable(response); + } + }) + }, __("View")); + } + } + + get_datatable(response) { + const datatable_options = { + columns: response.columns, + data: response.data, + dynamicRowHeight: true, + checkboxColumn: false, + inlineFilters: true, + }; + + this.datatable = new frappe.DataTable( + this.frm.page.main.parent, + datatable_options + ); + } }; From 752a92bd8be6d25325b01e4780f1b37b2195da87 Mon Sep 17 00:00:00 2001 From: marination Date: Tue, 6 Jun 2023 18:59:07 +0530 Subject: [PATCH 15/89] chore: Remove Bank Party Mapper implementation - Matching by Acc No/IBAN can easily happen with Bank Accounts. It's not a tedious query - Historical lookups for Party Name/Desc match are very tricky. The user could have manually set a match and we would not know. Also this leaves the Bank Party Mapper only useful for Party Name/Desc lookups, which feels excessive. - We want to reduce the number of places the same data is stored and reduce confusion - The Party Name/Desc will optionally happen fuzzily, or not at all - There will be no Mapper lookups --- .../doctype/bank_party_mapper/__init__.py | 0 .../bank_party_mapper/bank_party_mapper.js | 10 -- .../bank_party_mapper/bank_party_mapper.json | 80 ----------- .../bank_party_mapper/bank_party_mapper.py | 24 ---- .../test_bank_party_mapper.py | 9 -- .../bank_transaction/auto_match_party.py | 135 ++++-------------- .../bank_transaction/bank_transaction.json | 13 +- .../bank_transaction/bank_transaction.py | 34 +---- .../bank_transaction/test_auto_match_party.py | 79 ---------- 9 files changed, 37 insertions(+), 347 deletions(-) delete mode 100644 erpnext/accounts/doctype/bank_party_mapper/__init__.py delete mode 100644 erpnext/accounts/doctype/bank_party_mapper/bank_party_mapper.js delete mode 100644 erpnext/accounts/doctype/bank_party_mapper/bank_party_mapper.json delete mode 100644 erpnext/accounts/doctype/bank_party_mapper/bank_party_mapper.py delete mode 100644 erpnext/accounts/doctype/bank_party_mapper/test_bank_party_mapper.py diff --git a/erpnext/accounts/doctype/bank_party_mapper/__init__.py b/erpnext/accounts/doctype/bank_party_mapper/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/erpnext/accounts/doctype/bank_party_mapper/bank_party_mapper.js b/erpnext/accounts/doctype/bank_party_mapper/bank_party_mapper.js deleted file mode 100644 index b13e46a0e7..0000000000 --- a/erpnext/accounts/doctype/bank_party_mapper/bank_party_mapper.js +++ /dev/null @@ -1,10 +0,0 @@ -// Copyright (c) 2023, Frappe Technologies Pvt. Ltd. and contributors -// For license information, please see license.txt - -frappe.ui.form.on("Bank Party Mapper", { - refresh(frm) { - if (!frm.is_new()) { - frm.set_intro(__("Please avoid editing unless you are absolutely certain.")); - } - }, -}); diff --git a/erpnext/accounts/doctype/bank_party_mapper/bank_party_mapper.json b/erpnext/accounts/doctype/bank_party_mapper/bank_party_mapper.json deleted file mode 100644 index ddc79f24a0..0000000000 --- a/erpnext/accounts/doctype/bank_party_mapper/bank_party_mapper.json +++ /dev/null @@ -1,80 +0,0 @@ -{ - "actions": [], - "creation": "2023-03-31 10:48:20.249481", - "default_view": "List", - "doctype": "DocType", - "editable_grid": 1, - "engine": "InnoDB", - "field_order": [ - "party_type", - "party", - "column_break_wbna", - "bank_party_name", - "bank_party_account_number", - "bank_party_iban" - ], - "fields": [ - { - "fieldname": "bank_party_account_number", - "fieldtype": "Data", - "in_list_view": 1, - "label": "Party Account No. (Bank Statement)" - }, - { - "fieldname": "bank_party_iban", - "fieldtype": "Data", - "in_list_view": 1, - "label": "Party IBAN (Bank Statement)" - }, - { - "fieldname": "column_break_wbna", - "fieldtype": "Column Break" - }, - { - "fieldname": "party_type", - "fieldtype": "Link", - "in_list_view": 1, - "in_standard_filter": 1, - "label": "Party Type", - "options": "DocType" - }, - { - "fieldname": "party", - "fieldtype": "Dynamic Link", - "in_list_view": 1, - "in_standard_filter": 1, - "label": "Party", - "options": "party_type" - }, - { - "fieldname": "bank_party_name", - "fieldtype": "Data", - "label": "Party Name (Bank Statement)" - } - ], - "index_web_pages_for_search": 1, - "links": [], - "modified": "2023-04-04 14:27:23.450456", - "modified_by": "Administrator", - "module": "Accounts", - "name": "Bank Party Mapper", - "owner": "Administrator", - "permissions": [ - { - "create": 1, - "delete": 1, - "email": 1, - "export": 1, - "print": 1, - "read": 1, - "report": 1, - "role": "System Manager", - "share": 1, - "write": 1 - } - ], - "sort_field": "modified", - "sort_order": "DESC", - "states": [], - "track_changes": 1 -} \ No newline at end of file diff --git a/erpnext/accounts/doctype/bank_party_mapper/bank_party_mapper.py b/erpnext/accounts/doctype/bank_party_mapper/bank_party_mapper.py deleted file mode 100644 index 02e36b08fe..0000000000 --- a/erpnext/accounts/doctype/bank_party_mapper/bank_party_mapper.py +++ /dev/null @@ -1,24 +0,0 @@ -# Copyright (c) 2023, Frappe Technologies Pvt. Ltd. and contributors -# For license information, please see license.txt - -import frappe -from frappe.model.document import Document - - -class BankPartyMapper(Document): - def on_update(self): - self.update_party_in_linked_transactions() - - def update_party_in_linked_transactions(self): - if self.is_new(): - return - - # Set updated party values in other linked bank transactions - bank_transaction = frappe.qb.DocType("Bank Transaction") - - frappe.qb.update(bank_transaction).set("party_type", self.party_type).set( - "party", self.party - ).where( - (bank_transaction.bank_party_mapper == self.name) - & ((bank_transaction.party_type != self.party_type) | (bank_transaction.party != self.party)) - ).run() diff --git a/erpnext/accounts/doctype/bank_party_mapper/test_bank_party_mapper.py b/erpnext/accounts/doctype/bank_party_mapper/test_bank_party_mapper.py deleted file mode 100644 index c05b23f1a5..0000000000 --- a/erpnext/accounts/doctype/bank_party_mapper/test_bank_party_mapper.py +++ /dev/null @@ -1,9 +0,0 @@ -# Copyright (c) 2023, Frappe Technologies Pvt. Ltd. and Contributors -# See license.txt - -# import frappe -from frappe.tests.utils import FrappeTestCase - - -class TestBankPartyMapper(FrappeTestCase): - pass diff --git a/erpnext/accounts/doctype/bank_transaction/auto_match_party.py b/erpnext/accounts/doctype/bank_transaction/auto_match_party.py index 753f0c1171..5d94a08f2f 100644 --- a/erpnext/accounts/doctype/bank_transaction/auto_match_party.py +++ b/erpnext/accounts/doctype/bank_transaction/auto_match_party.py @@ -10,22 +10,7 @@ class AutoMatchParty: Matches by Account/IBAN and then by Party Name/Description sequentially. Returns when a result is obtained. - Result (if present) is of the form: (Party Type, Party, Mapper,) - - Mapper(if present) is one of the forms: - 1. {"mapper_name": }: Indicates that an existing Bank Party Mapper matched against - the transaction and the same must be linked in the Bank Transaction. - - 2. {"bank_party_account_number": , "bank_party_iban": } : Indicates that a match was - found in Customer/Supplier/Employee by account details. A Bank Party Mapper is now created - mapping the Party to the Account No./IBAN - - 3. {"bank_party_name": }: Indicates that a match was found in - Customer/Supplier/Employee by party name. A Bank Party Mapper is now created mapping the Party - to the Party Name (Bank Statement). If matched by Description, no mapper is created as - description is not a static key. - - Mapper data is used either to create a new Bank Party Mapper or link an existing mapper to a transaction. + Result (if present) is of the form: (Party Type, Party,) """ def __init__(self, **kwargs) -> None: @@ -44,7 +29,7 @@ class AutoMatchParty: fuzzy_matching_enabled = frappe.db.get_single_value("Accounts Settings", "enable_fuzzy_matching") if not result and fuzzy_matching_enabled: - result = AutoMatchbyPartyDescription( + result = AutoMatchbyPartyNameDescription( bank_party_name=self.bank_party_name, description=self.description, deposit=self.deposit ).match() @@ -62,50 +47,16 @@ class AutoMatchbyAccountIBAN: if not (self.bank_party_account_number or self.bank_party_iban): return None - result = self.match_account_in_bank_party_mapper() - if not result: - result = self.match_account_in_party() - - return result - - def match_account_in_bank_party_mapper(self) -> Union[Tuple, None]: - """Check for a IBAN/Account No. match in Bank Party Mapper""" - result = None - or_filters = {} - if self.bank_party_account_number: - or_filters["bank_party_account_number"] = self.bank_party_account_number - - if self.bank_party_iban: - or_filters["bank_party_iban"] = self.bank_party_iban - - mapper = frappe.db.get_all( - "Bank Party Mapper", - or_filters=or_filters, - fields=["party_type", "party", "name"], - limit_page_length=1, - ) - if mapper: - data = mapper[0] - return (data["party_type"], data["party"], {"mapper_name": data["name"]}) - + result = self.match_account_in_party() return result def match_account_in_party(self) -> Union[Tuple, None]: """Check if there is a IBAN/Account No. match in Customer/Supplier/Employee""" result = None - - parties = ["Supplier", "Employee", "Customer"] # most -> least likely to receive - if flt(self.deposit) > 0: - parties = ["Customer", "Supplier", "Employee"] # most -> least likely to pay + parties = get_parties_in_order(self.deposit) + or_filters = self.get_or_filters() for party in parties: - or_filters = {} - if self.bank_party_account_number: - or_filters["bank_account_no"] = self.bank_party_account_number - - if self.bank_party_iban: - or_filters["iban"] = self.bank_party_iban - party_result = frappe.db.get_all( "Bank Account", or_filters=or_filters, pluck="party", limit_page_length=1 ) @@ -123,17 +74,23 @@ class AutoMatchbyAccountIBAN: result = ( party, party_result[0], - { - "bank_party_account_number": self.get("bank_party_account_number"), - "bank_party_iban": self.get("bank_party_iban"), - }, ) break return result + def get_or_filters(self) -> dict: + or_filters = {} + if self.bank_party_account_number: + or_filters["bank_account_no"] = self.bank_party_account_number -class AutoMatchbyPartyDescription: + if self.bank_party_iban: + or_filters["iban"] = self.bank_party_iban + + return or_filters + + +class AutoMatchbyPartyNameDescription: def __init__(self, **kwargs) -> None: self.__dict__.update(kwargs) @@ -141,52 +98,21 @@ class AutoMatchbyPartyDescription: return self.__dict__.get(key, None) def match(self) -> Union[Tuple, None]: - # Match by Customer, Supplier or Employee Name - # search bank party mapper by party # fuzzy search by customer/supplier & employee if not (self.bank_party_name or self.description): return None - result = self.match_party_name_in_bank_party_mapper() - - if not result: - result = self.match_party_name_desc_in_party() - - return result - - def match_party_name_in_bank_party_mapper(self) -> Union[Tuple, None]: - """Check if match exists for party name in Bank Party Mapper""" - result = None - if not self.bank_party_name: - return - - mapper_res = frappe.get_all( - "Bank Party Mapper", - filters={"bank_party_name": self.bank_party_name}, - fields=["party_type", "party", "name"], - limit_page_length=1, - ) - if mapper_res: - mapper_res = mapper_res[0] - return ( - mapper_res["party_type"], - mapper_res["party"], - {"mapper_name": mapper_res["name"]}, - ) - + result = self.match_party_name_desc_in_party() return result def match_party_name_desc_in_party(self) -> Union[Tuple, None]: """Fuzzy search party name and/or description against parties in the system""" result = None - parties = ["Supplier", "Employee", "Customer"] # most-least likely to receive - if flt(self.deposit) > 0.0: - parties = ["Customer", "Supplier", "Employee"] # most-least likely to pay + parties = get_parties_in_order(self.deposit) for party in parties: - name_field = party.lower() + "_name" filters = {"status": "Active"} if party == "Employee" else {"disabled": 0} - names = frappe.get_all(party, filters=filters, pluck=name_field) + names = frappe.get_all(party, filters=filters, pluck=party.lower() + "_name") for field in ["bank_party_name", "description"]: if not self.get(field): @@ -197,8 +123,7 @@ class AutoMatchbyPartyDescription: break if result or skip: - # We skip if: - # If it was hard to distinguish between close matches and so match is None + # Skip If: It was hard to distinguish between close matches and so match is None # OR if the right match was found break @@ -206,19 +131,15 @@ class AutoMatchbyPartyDescription: def fuzzy_search_and_return_result(self, party, names, field) -> Union[Tuple, None]: skip = False - result = process.extract(query=self.get(field), choices=names, scorer=fuzz.token_set_ratio) party_name, skip = self.process_fuzzy_result(result) if not party_name: return None, skip - # Dont set description as a key in Bank Party Mapper due to its volatility - mapper = {"bank_party_name": self.get(field)} if field == "bank_party_name" else None return ( party, party_name, - mapper, ), skip def process_fuzzy_result(self, result: Union[list, None]): @@ -226,7 +147,7 @@ class AutoMatchbyPartyDescription: If there are multiple valid close matches return None as result may be faulty. Return the result only if one accurate match stands out. - Returns: Result, Skip (whether or not to continue matching) + Returns: Result, Skip (whether or not to discontinue matching) """ PARTY, SCORE, CUTOFF = 0, 1, 80 @@ -234,18 +155,24 @@ class AutoMatchbyPartyDescription: return None, False first_result = result[0] - if len(result) == 1: - return (result[0][PARTY] if first_result[SCORE] > CUTOFF else None), True + return (first_result[PARTY] if first_result[SCORE] > CUTOFF else None), True second_result = result[1] - if first_result[SCORE] > CUTOFF: # If multiple matches with the same score, return None but discontinue matching - # Matches were found but were too closes to distinguish between + # Matches were found but were too close to distinguish between if first_result[SCORE] == second_result[SCORE]: return None, True return first_result[PARTY], True else: return None, False + + +def get_parties_in_order(deposit: float) -> list: + parties = ["Supplier", "Employee", "Customer"] # most -> least likely to receive + if flt(deposit) > 0: + parties = ["Customer", "Supplier", "Employee"] # most -> least likely to pay + + return parties diff --git a/erpnext/accounts/doctype/bank_transaction/bank_transaction.json b/erpnext/accounts/doctype/bank_transaction/bank_transaction.json index e7de71aef4..b32022e6fd 100644 --- a/erpnext/accounts/doctype/bank_transaction/bank_transaction.json +++ b/erpnext/accounts/doctype/bank_transaction/bank_transaction.json @@ -37,8 +37,7 @@ "column_break_3czf", "bank_party_name", "bank_party_account_number", - "bank_party_iban", - "bank_party_mapper" + "bank_party_iban" ], "fields": [ { @@ -226,19 +225,11 @@ "fieldname": "bank_party_account_number", "fieldtype": "Data", "label": "Party Account No. (Bank Statement)" - }, - { - "fieldname": "bank_party_mapper", - "fieldtype": "Link", - "hidden": 1, - "label": "Bank Party Mapper", - "options": "Bank Party Mapper", - "read_only": 1 } ], "is_submittable": 1, "links": [], - "modified": "2023-05-17 14:56:10.547480", + "modified": "2023-06-06 13:58:12.821411", "modified_by": "Administrator", "module": "Accounts", "name": "Bank Transaction", diff --git a/erpnext/accounts/doctype/bank_transaction/bank_transaction.py b/erpnext/accounts/doctype/bank_transaction/bank_transaction.py index 04c3013a00..f82337fbd7 100644 --- a/erpnext/accounts/doctype/bank_transaction/bank_transaction.py +++ b/erpnext/accounts/doctype/bank_transaction/bank_transaction.py @@ -29,9 +29,6 @@ class BankTransaction(StatusUpdater): self.update_allocations() self._saving_flag = False - if frappe.db.get_single_value("Accounts Settings", "enable_party_matching"): - self.update_automatch_bank_party_mapper() - def on_cancel(self): self.clear_linked_payment_entries(for_cancel=True) self.set_status(update=True) @@ -167,33 +164,10 @@ class BankTransaction(StatusUpdater): ).match() if result: - party_type, party, mapper = result - to_update = {"party_type": party_type, "party": party} - - if mapper and mapper.get("mapper_name"): - # Transaction matched with an existing Bank party Mapper record - to_update["bank_party_mapper"] = mapper.get("mapper_name") - elif mapper: - # Make new Mapper record to remember match - mapper_doc = frappe.get_doc( - {"doctype": "Bank Party Mapper", "party_type": party_type, "party": party} - ) - mapper_doc.update(mapper) - mapper_doc.insert() - to_update["bank_party_mapper"] = mapper_doc.name - - frappe.db.set_value("Bank Transaction", self.name, field=to_update) - - def update_automatch_bank_party_mapper(self): - """Update Bank Party Mapper if Party Type & Party are manually changed after submit.""" - doc_before_update = self.get_doc_before_save() - party_type_changed = self.party_type and (doc_before_update.party_type != self.party_type) - party_changed = self.party and (doc_before_update.party != self.party) - - if (party_type_changed or party_changed) and self.bank_party_mapper: - mapper_doc = frappe.get_doc("Bank Party Mapper", self.bank_party_mapper) - mapper_doc.update({"party_type": self.party_type, "party": self.party}) - mapper_doc.save() + party_type, party = result + frappe.db.set_value( + "Bank Transaction", self.name, field={"party_type": party_type, "party": party} + ) @frappe.whitelist() diff --git a/erpnext/accounts/doctype/bank_transaction/test_auto_match_party.py b/erpnext/accounts/doctype/bank_transaction/test_auto_match_party.py index 8c6dc9d766..a498545f2a 100644 --- a/erpnext/accounts/doctype/bank_transaction/test_auto_match_party.py +++ b/erpnext/accounts/doctype/bank_transaction/test_auto_match_party.py @@ -22,7 +22,6 @@ class TestAutoMatchParty(FrappeTestCase): frappe.db.set_single_value("Accounts Settings", "enable_fuzzy_matching", 0) def test_match_by_account_number(self): - """Test if transaction matches with existing (Bank Party Mapper) or new match.""" create_supplier_for_match(account_no="000000003716541159") doc = create_bank_transaction( withdrawal=1200, @@ -33,22 +32,6 @@ class TestAutoMatchParty(FrappeTestCase): self.assertEqual(doc.party_type, "Supplier") self.assertEqual(doc.party, "John Doe & Co.") - self.assertTrue(doc.bank_party_mapper) - - # Check if Bank Party Mapper is created to remember mapping - bank_party_mapper = frappe.get_doc("Bank Party Mapper", doc.bank_party_mapper) - self.assertEqual(bank_party_mapper.party, "John Doe & Co.") - self.assertEqual(bank_party_mapper.bank_party_account_number, "000000003716541159") - self.assertEqual(bank_party_mapper.bank_party_iban, "DE02000000003716541159") - - # Check if created mapping is used for quick match - doc_2 = create_bank_transaction( - withdrawal=500, - transaction_id="602413b8ji8bf838fub8f2c6a39bah7y", - account_no="000000003716541159", - ) - self.assertEqual(doc_2.party, "John Doe & Co.") - self.assertEqual(doc_2.bank_party_mapper, bank_party_mapper.name) def test_match_by_iban(self): create_supplier_for_match(iban="DE02000000003716541159") @@ -61,12 +44,6 @@ class TestAutoMatchParty(FrappeTestCase): self.assertEqual(doc.party_type, "Supplier") self.assertEqual(doc.party, "John Doe & Co.") - self.assertTrue(doc.bank_party_mapper) - - bank_party_mapper = frappe.get_doc("Bank Party Mapper", doc.bank_party_mapper) - self.assertEqual(bank_party_mapper.party, "John Doe & Co.") - self.assertEqual(bank_party_mapper.bank_party_account_number, "000000003716541159") - self.assertEqual(bank_party_mapper.bank_party_iban, "DE02000000003716541159") def test_match_by_party_name(self): create_supplier_for_match(supplier_name="Jackson Ella W.") @@ -78,22 +55,6 @@ class TestAutoMatchParty(FrappeTestCase): ) self.assertEqual(doc.party_type, "Supplier") self.assertEqual(doc.party, "Jackson Ella W.") - self.assertTrue(doc.bank_party_mapper) - - bank_party_mapper = frappe.get_doc("Bank Party Mapper", doc.bank_party_mapper) - self.assertEqual(bank_party_mapper.party, "Jackson Ella W.") - self.assertEqual(bank_party_mapper.bank_party_name, "Ella Jackson") - self.assertEqual(bank_party_mapper.bank_party_iban, None) - - # Check if created mapping is used for quick match - doc_2 = create_bank_transaction( - withdrawal=500, - transaction_id="578313b8ji8bf838fub8f2c6a39bah7y", - party_name="Ella Jackson", - account_no="000000004316531152", - ) - self.assertEqual(doc_2.party, "Jackson Ella W.") - self.assertEqual(doc_2.bank_party_mapper, bank_party_mapper.name) def test_match_by_description(self): create_supplier_for_match(supplier_name="Microsoft") @@ -107,46 +68,6 @@ class TestAutoMatchParty(FrappeTestCase): self.assertEqual(doc.party, "Microsoft") self.assertFalse(doc.bank_party_mapper) - def test_correct_match_after_submit(self): - """Correct wrong mapping after submit. Test impact.""" - # Similar named suppliers - create_supplier_for_match(supplier_name="Amazon") - create_supplier_for_match(supplier_name="Amazing Co.") - - # Bank Transactions actually from "Amazon" that match better with "Amazing Co." - doc = create_bank_transaction( - description="visa06323202 amzn.com/bill 7,88eur1,5324711959 90.22. 1,62 87861003", - withdrawal=24.85, - transaction_id="3a1da4ee2dc5a980138d36ef5297cbd9", - party_name="Amazn Co.", - ) - doc_2 = create_bank_transaction( - description="visa61268005 amzn.com/bill 22,345eur1,7654711959 89.23. 1,64 61268005", - withdrawal=80, - transaction_id="584314e459b00f792bfd569267efba6e", - party_name="Amazn Co.", - ) - - self.assertEqual(doc.party_type, "Supplier") - self.assertEqual(doc.party, "Amazing Co.") - self.assertTrue(doc.bank_party_mapper) - self.assertTrue(doc_2.bank_party_mapper, doc.bank_party_mapper) - - bank_party_mapper = frappe.get_doc("Bank Party Mapper", doc.bank_party_mapper) - self.assertEqual(bank_party_mapper.party, "Amazing Co.") - self.assertEqual(bank_party_mapper.bank_party_name, "Amazn Co.") - - # User corrects the value after submit to "Amazon" - doc.party = "Amazon" - doc.save() - bank_party_mapper.reload() - doc_2.reload() - - # Mapping is edited and all transactions with this mapping are updated - self.assertEqual(bank_party_mapper.party, "Amazon") - self.assertEqual(bank_party_mapper.bank_party_name, "Amazn Co.") - self.assertEqual(doc_2.party, "Amazon") - def test_skip_match_if_multiple_close_results(self): create_supplier_for_match(supplier_name="Adithya Medical & General Stores") create_supplier_for_match(supplier_name="Adithya Medical And General Stores") From eb1db5eaa3e3d28351b4f906b7e91b03da7ae83c Mon Sep 17 00:00:00 2001 From: marination Date: Wed, 7 Jun 2023 11:54:16 +0530 Subject: [PATCH 16/89] chore: Remove instances of `bank_party_mapper` and use `new_doc` --- .../bank_transaction/test_auto_match_party.py | 49 ++++++++----------- 1 file changed, 20 insertions(+), 29 deletions(-) diff --git a/erpnext/accounts/doctype/bank_transaction/test_auto_match_party.py b/erpnext/accounts/doctype/bank_transaction/test_auto_match_party.py index a498545f2a..36ef1fca07 100644 --- a/erpnext/accounts/doctype/bank_transaction/test_auto_match_party.py +++ b/erpnext/accounts/doctype/bank_transaction/test_auto_match_party.py @@ -66,7 +66,6 @@ class TestAutoMatchParty(FrappeTestCase): ) self.assertEqual(doc.party_type, "Supplier") self.assertEqual(doc.party, "Microsoft") - self.assertFalse(doc.bank_party_mapper) def test_skip_match_if_multiple_close_results(self): create_supplier_for_match(supplier_name="Adithya Medical & General Stores") @@ -82,7 +81,6 @@ class TestAutoMatchParty(FrappeTestCase): # Mapping is skipped as both Supplier names have the same match score self.assertEqual(doc.party_type, None) self.assertEqual(doc.party, None) - self.assertFalse(doc.bank_party_mapper) def create_supplier_for_match(supplier_name="John Doe & Co.", iban=None, account_no=None): @@ -99,35 +97,26 @@ def create_supplier_for_match(supplier_name="John Doe & Co.", iban=None, account return # Create Supplier and Bank Account for the same - supplier = frappe.get_doc( - { - "doctype": "Supplier", - "supplier_name": supplier_name, - "supplier_group": "Services", - "supplier_type": "Company", - } - ).insert() + supplier = frappe.new_doc("Supplier") + supplier.supplier_name = supplier_name + supplier.supplier_group = "Services" + supplier.supplier_type = "Company" + supplier.insert() if not frappe.db.exists("Bank", "TestBank"): - frappe.get_doc( - { - "doctype": "Bank", - "bank_name": "TestBank", - } - ).insert(ignore_if_duplicate=True) + bank = frappe.new_doc("Bank") + bank.bank_name = "TestBank" + bank.insert(ignore_if_duplicate=True) if not frappe.db.exists("Bank Account", supplier.name + " - " + "TestBank"): - frappe.get_doc( - { - "doctype": "Bank Account", - "account_name": supplier.name, - "bank": "TestBank", - "iban": iban, - "bank_account_no": account_no, - "party_type": "Supplier", - "party": supplier.name, - } - ).insert() + bank_account = frappe.new_doc("Bank Account") + bank_account.account_name = supplier.name + bank_account.bank = "TestBank" + bank_account.iban = iban + bank_account.bank_account_no = account_no + bank_account.party_type = "Supplier" + bank_account.party = supplier.name + bank_account.insert() def create_bank_transaction( @@ -139,7 +128,8 @@ def create_bank_transaction( account_no=None, iban=None, ): - doc = frappe.get_doc( + doc = frappe.new_doc("Bank Transaction") + doc.update( { "doctype": "Bank Transaction", "description": description or "1512567 BG/000002918 OPSKATTUZWXXX AT776000000098709837 Herr G", @@ -153,7 +143,8 @@ def create_bank_transaction( "bank_party_account_number": account_no, "bank_party_iban": iban, } - ).insert() + ) + doc.insert() doc.submit() doc.reload() From 5155d5bfb2d8909d76f6515fdae1cb0230d27a67 Mon Sep 17 00:00:00 2001 From: DaizyModi Date: Wed, 7 Jun 2023 12:05:17 +0530 Subject: [PATCH 17/89] chore: remove whitelisting for methods not accessed from UI --- erpnext/accounts/doctype/bank_account/bank_account.py | 1 - erpnext/assets/doctype/asset_maintenance/asset_maintenance.py | 1 - .../supplier_scorecard_period/supplier_scorecard_period.py | 1 - .../doctype/plaid_settings/plaid_settings.py | 1 - erpnext/stock/get_item_details.py | 1 - 5 files changed, 5 deletions(-) diff --git a/erpnext/accounts/doctype/bank_account/bank_account.py b/erpnext/accounts/doctype/bank_account/bank_account.py index b91f0f9137..363a2776aa 100644 --- a/erpnext/accounts/doctype/bank_account/bank_account.py +++ b/erpnext/accounts/doctype/bank_account/bank_account.py @@ -70,7 +70,6 @@ def make_bank_account(doctype, docname): return doc -@frappe.whitelist() def get_party_bank_account(party_type, party): return frappe.db.get_value(party_type, party, "default_bank_account") diff --git a/erpnext/assets/doctype/asset_maintenance/asset_maintenance.py b/erpnext/assets/doctype/asset_maintenance/asset_maintenance.py index 83031415ec..641d35fa04 100644 --- a/erpnext/assets/doctype/asset_maintenance/asset_maintenance.py +++ b/erpnext/assets/doctype/asset_maintenance/asset_maintenance.py @@ -42,7 +42,6 @@ class AssetMaintenance(Document): maintenance_log.db_set("maintenance_status", "Cancelled") -@frappe.whitelist() def assign_tasks(asset_maintenance_name, assign_to_member, maintenance_task, next_due_date): team_member = frappe.db.get_value("User", assign_to_member, "email") args = { diff --git a/erpnext/buying/doctype/supplier_scorecard_period/supplier_scorecard_period.py b/erpnext/buying/doctype/supplier_scorecard_period/supplier_scorecard_period.py index a8b76db093..1967df2a26 100644 --- a/erpnext/buying/doctype/supplier_scorecard_period/supplier_scorecard_period.py +++ b/erpnext/buying/doctype/supplier_scorecard_period/supplier_scorecard_period.py @@ -99,7 +99,6 @@ def import_string_path(path): return mod -@frappe.whitelist() def make_supplier_scorecard(source_name, target_doc=None): def update_criteria_fields(obj, target, source_parent): target.max_score, target.formula = frappe.db.get_value( diff --git a/erpnext/erpnext_integrations/doctype/plaid_settings/plaid_settings.py b/erpnext/erpnext_integrations/doctype/plaid_settings/plaid_settings.py index e57a30a88e..61d2acefae 100644 --- a/erpnext/erpnext_integrations/doctype/plaid_settings/plaid_settings.py +++ b/erpnext/erpnext_integrations/doctype/plaid_settings/plaid_settings.py @@ -161,7 +161,6 @@ def add_account_subtype(account_subtype): frappe.throw(frappe.get_traceback()) -@frappe.whitelist() def sync_transactions(bank, bank_account): """Sync transactions based on the last integration date as the start date, after sync is completed add the transaction date of the oldest transaction as the last integration date.""" diff --git a/erpnext/stock/get_item_details.py b/erpnext/stock/get_item_details.py index 64650bc201..4f85ac054d 100644 --- a/erpnext/stock/get_item_details.py +++ b/erpnext/stock/get_item_details.py @@ -191,7 +191,6 @@ def process_string_args(args): return args -@frappe.whitelist() def get_item_code(barcode=None, serial_no=None): if barcode: item_code = frappe.db.get_value("Item Barcode", {"barcode": barcode}, fieldname=["parent"]) From 83c46085fbb56e1cfb2981a7d57b8ed313b4979a Mon Sep 17 00:00:00 2001 From: Nikhil Kothari Date: Wed, 7 Jun 2023 14:14:57 +0530 Subject: [PATCH 18/89] feat: added support for mandatory dimensions per account --- .../accounting_dimension_filter.js | 10 ++++ .../accounting_dimension_filter.json | 60 ++++++++----------- .../accounting_dimension_filter.py | 7 ++- 3 files changed, 38 insertions(+), 39 deletions(-) diff --git a/erpnext/accounts/doctype/accounting_dimension_filter/accounting_dimension_filter.js b/erpnext/accounts/doctype/accounting_dimension_filter/accounting_dimension_filter.js index 8a6b021b8a..6f0b6fcd91 100644 --- a/erpnext/accounts/doctype/accounting_dimension_filter/accounting_dimension_filter.js +++ b/erpnext/accounts/doctype/accounting_dimension_filter/accounting_dimension_filter.js @@ -68,6 +68,16 @@ frappe.ui.form.on('Accounting Dimension Filter', { frm.refresh_field("dimensions"); frm.trigger('setup_filters'); }, + apply_restriction_on_values: function(frm) { + /** If restriction on values is not applied, we should set "allow_or_restrict" to "Restrict" with an empty allowed dimension table. + * Hence it's not "restricted" on any value. + */ + if (!frm.doc.apply_restriction_on_values) { + frm.set_value("allow_or_restrict", "Restrict"); + frm.clear_table("dimensions"); + frm.refresh_field("dimensions"); + } + } }); frappe.ui.form.on('Allowed Dimension', { diff --git a/erpnext/accounts/doctype/accounting_dimension_filter/accounting_dimension_filter.json b/erpnext/accounts/doctype/accounting_dimension_filter/accounting_dimension_filter.json index 0f3fbc0b8d..1f320b0a1a 100644 --- a/erpnext/accounts/doctype/accounting_dimension_filter/accounting_dimension_filter.json +++ b/erpnext/accounts/doctype/accounting_dimension_filter/accounting_dimension_filter.json @@ -10,6 +10,7 @@ "disabled", "column_break_2", "company", + "apply_restriction_on_values", "allow_or_restrict", "section_break_4", "accounts", @@ -24,94 +25,80 @@ "fieldtype": "Select", "in_list_view": 1, "label": "Accounting Dimension", - "reqd": 1, - "show_days": 1, - "show_seconds": 1 + "reqd": 1 }, { "fieldname": "column_break_2", - "fieldtype": "Column Break", - "show_days": 1, - "show_seconds": 1 + "fieldtype": "Column Break" }, { "fieldname": "section_break_4", "fieldtype": "Section Break", - "hide_border": 1, - "show_days": 1, - "show_seconds": 1 + "hide_border": 1 }, { "fieldname": "column_break_6", - "fieldtype": "Column Break", - "show_days": 1, - "show_seconds": 1 + "fieldtype": "Column Break" }, { + "depends_on": "eval:doc.apply_restriction_on_values == 1;", "fieldname": "allow_or_restrict", "fieldtype": "Select", "label": "Allow Or Restrict Dimension", "options": "Allow\nRestrict", - "reqd": 1, - "show_days": 1, - "show_seconds": 1 + "reqd": 1 }, { "fieldname": "accounts", "fieldtype": "Table", "label": "Applicable On Account", "options": "Applicable On Account", - "reqd": 1, - "show_days": 1, - "show_seconds": 1 + "reqd": 1 }, { - "depends_on": "eval:doc.accounting_dimension", + "depends_on": "eval:doc.accounting_dimension && doc.apply_restriction_on_values", "fieldname": "dimensions", "fieldtype": "Table", "label": "Applicable Dimension", - "options": "Allowed Dimension", - "reqd": 1, - "show_days": 1, - "show_seconds": 1 + "mandatory_depends_on": "eval:doc.apply_restriction_on_values == 1;", + "options": "Allowed Dimension" }, { "default": "0", "fieldname": "disabled", "fieldtype": "Check", - "label": "Disabled", - "show_days": 1, - "show_seconds": 1 + "label": "Disabled" }, { "fieldname": "company", "fieldtype": "Link", "label": "Company", "options": "Company", - "reqd": 1, - "show_days": 1, - "show_seconds": 1 + "reqd": 1 }, { "fieldname": "dimension_filter_help", "fieldtype": "HTML", - "label": "Dimension Filter Help", - "show_days": 1, - "show_seconds": 1 + "label": "Dimension Filter Help" }, { "fieldname": "section_break_10", - "fieldtype": "Section Break", - "show_days": 1, - "show_seconds": 1 + "fieldtype": "Section Break" + }, + { + "default": "0", + "fieldname": "apply_restriction_on_values", + "fieldtype": "Check", + "label": "Apply restriction on dimension values" } ], "index_web_pages_for_search": 1, "links": [], - "modified": "2021-02-03 12:04:58.678402", + "modified": "2023-06-07 13:41:36.736175", "modified_by": "Administrator", "module": "Accounts", "name": "Accounting Dimension Filter", + "naming_rule": "Expression", "owner": "Administrator", "permissions": [ { @@ -154,5 +141,6 @@ "quick_entry": 1, "sort_field": "modified", "sort_order": "DESC", + "states": [], "track_changes": 1 } \ No newline at end of file diff --git a/erpnext/accounts/doctype/accounting_dimension_filter/accounting_dimension_filter.py b/erpnext/accounts/doctype/accounting_dimension_filter/accounting_dimension_filter.py index 80f736fa5b..c0573a703c 100644 --- a/erpnext/accounts/doctype/accounting_dimension_filter/accounting_dimension_filter.py +++ b/erpnext/accounts/doctype/accounting_dimension_filter/accounting_dimension_filter.py @@ -44,12 +44,12 @@ def get_dimension_filter_map(): a.applicable_on_account, d.dimension_value, p.accounting_dimension, p.allow_or_restrict, a.is_mandatory FROM - `tabApplicable On Account` a, `tabAllowed Dimension` d, + `tabApplicable On Account` a, `tabAccounting Dimension Filter` p + LEFT JOIN `tabAllowed Dimension` d ON d.parent = p.name WHERE p.name = a.parent AND p.disabled = 0 - AND p.name = d.parent """, as_dict=1, ) @@ -76,4 +76,5 @@ def build_map(map_object, dimension, account, filter_value, allow_or_restrict, i (dimension, account), {"allowed_dimensions": [], "is_mandatory": is_mandatory, "allow_or_restrict": allow_or_restrict}, ) - map_object[(dimension, account)]["allowed_dimensions"].append(filter_value) + if filter_value: + map_object[(dimension, account)]["allowed_dimensions"].append(filter_value) From e1116bbbbb6987e37d940f1f00e3e334ed0101d0 Mon Sep 17 00:00:00 2001 From: Nikhil Kothari Date: Wed, 7 Jun 2023 14:20:42 +0530 Subject: [PATCH 19/89] fix: added server side check for allow/restrict --- .../accounting_dimension_filter.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/erpnext/accounts/doctype/accounting_dimension_filter/accounting_dimension_filter.py b/erpnext/accounts/doctype/accounting_dimension_filter/accounting_dimension_filter.py index c0573a703c..2a6c76dd4a 100644 --- a/erpnext/accounts/doctype/accounting_dimension_filter/accounting_dimension_filter.py +++ b/erpnext/accounts/doctype/accounting_dimension_filter/accounting_dimension_filter.py @@ -8,6 +8,13 @@ from frappe.model.document import Document class AccountingDimensionFilter(Document): + + def before_save(self): + # If restriction is not applied on values, then remove all the dimensions and set allow_or_restrict to Restrict + if not self.apply_restriction_on_values: + self.allow_or_restrict = "Restrict" + self.set('dimensions', []) + def validate(self): self.validate_applicable_accounts() From 83a75844755c141fca8e3885c904581d07196057 Mon Sep 17 00:00:00 2001 From: Nikhil Kothari Date: Wed, 7 Jun 2023 15:00:05 +0530 Subject: [PATCH 20/89] fix: tests now create filters with checkbox enabled --- .../accounting_dimension_filter.json | 4 ++-- .../test_accounting_dimension_filter.py | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/erpnext/accounts/doctype/accounting_dimension_filter/accounting_dimension_filter.json b/erpnext/accounts/doctype/accounting_dimension_filter/accounting_dimension_filter.json index 1f320b0a1a..2bd6c12a0a 100644 --- a/erpnext/accounts/doctype/accounting_dimension_filter/accounting_dimension_filter.json +++ b/erpnext/accounts/doctype/accounting_dimension_filter/accounting_dimension_filter.json @@ -86,7 +86,7 @@ "fieldtype": "Section Break" }, { - "default": "0", + "default": "1", "fieldname": "apply_restriction_on_values", "fieldtype": "Check", "label": "Apply restriction on dimension values" @@ -94,7 +94,7 @@ ], "index_web_pages_for_search": 1, "links": [], - "modified": "2023-06-07 13:41:36.736175", + "modified": "2023-06-07 14:59:41.869117", "modified_by": "Administrator", "module": "Accounts", "name": "Accounting Dimension Filter", diff --git a/erpnext/accounts/doctype/accounting_dimension_filter/test_accounting_dimension_filter.py b/erpnext/accounts/doctype/accounting_dimension_filter/test_accounting_dimension_filter.py index f13f2f9f27..6aba2ab253 100644 --- a/erpnext/accounts/doctype/accounting_dimension_filter/test_accounting_dimension_filter.py +++ b/erpnext/accounts/doctype/accounting_dimension_filter/test_accounting_dimension_filter.py @@ -64,6 +64,7 @@ def create_accounting_dimension_filter(): "accounting_dimension": "Cost Center", "allow_or_restrict": "Allow", "company": "_Test Company", + "apply_restriction_on_values": 1, "accounts": [ { "applicable_on_account": "Sales - _TC", @@ -85,6 +86,7 @@ def create_accounting_dimension_filter(): "doctype": "Accounting Dimension Filter", "accounting_dimension": "Department", "allow_or_restrict": "Allow", + "apply_restriction_on_values": 1, "company": "_Test Company", "accounts": [{"applicable_on_account": "Sales - _TC", "is_mandatory": 1}], "dimensions": [{"accounting_dimension": "Department", "dimension_value": "Accounts - _TC"}], From 0bd4de450431b2992b08389570a1526f187f0672 Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Wed, 7 Jun 2023 22:33:35 +0530 Subject: [PATCH 21/89] fix: Remove special treatment for P&L Accounts --- erpnext/accounts/utils.py | 5 ----- 1 file changed, 5 deletions(-) diff --git a/erpnext/accounts/utils.py b/erpnext/accounts/utils.py index 0ee06e8239..a5cb324762 100644 --- a/erpnext/accounts/utils.py +++ b/erpnext/accounts/utils.py @@ -237,11 +237,6 @@ def get_balance_on( if not (frappe.flags.ignore_account_permission or ignore_account_permission): acc.check_permission("read") - if report_type == "Profit and Loss": - # for pl accounts, get balance within a fiscal year - cond.append( - "posting_date >= '%s' and voucher_type != 'Period Closing Voucher'" % year_start_date - ) # different filter for group and ledger - improved performance if acc.is_group: cond.append( From f68ab3dfff50a2161858f072b33f75c306a731f4 Mon Sep 17 00:00:00 2001 From: Devin Slauenwhite Date: Wed, 7 Jun 2023 15:14:24 -0400 Subject: [PATCH 22/89] test: reconcile credit against invoice --- .../test_payment_reconciliation.py | 41 ++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) diff --git a/erpnext/accounts/doctype/payment_reconciliation/test_payment_reconciliation.py b/erpnext/accounts/doctype/payment_reconciliation/test_payment_reconciliation.py index 3be11ae31a..e4efc6894f 100644 --- a/erpnext/accounts/doctype/payment_reconciliation/test_payment_reconciliation.py +++ b/erpnext/accounts/doctype/payment_reconciliation/test_payment_reconciliation.py @@ -11,10 +11,13 @@ from frappe.utils import add_days, flt, nowdate from erpnext import get_default_cost_center from erpnext.accounts.doctype.payment_entry.payment_entry import get_payment_entry from erpnext.accounts.doctype.payment_entry.test_payment_entry import create_payment_entry +from erpnext.accounts.doctype.purchase_invoice.test_purchase_invoice import make_purchase_invoice from erpnext.accounts.doctype.sales_invoice.test_sales_invoice import create_sales_invoice from erpnext.accounts.party import get_party_account from erpnext.stock.doctype.item.test_item import create_item +test_dependencies = ["Item"] + class TestPaymentReconciliation(FrappeTestCase): def setUp(self): @@ -163,7 +166,7 @@ class TestPaymentReconciliation(FrappeTestCase): def create_payment_reconciliation(self): pr = frappe.new_doc("Payment Reconciliation") pr.company = self.company - pr.party_type = "Customer" + pr.party_type = self.party_type or "Customer" pr.party = self.customer pr.receivable_payable_account = get_party_account(pr.party_type, pr.party, pr.company) pr.from_invoice_date = pr.to_invoice_date = pr.from_payment_date = pr.to_payment_date = nowdate() @@ -890,6 +893,42 @@ class TestPaymentReconciliation(FrappeTestCase): self.assertEqual(pr.allocation[0].allocated_amount, 85) self.assertEqual(pr.allocation[0].difference_amount, 0) + def test_reconciliation_purchase_invoice_against_return(self): + pi = make_purchase_invoice( + supplier="_Test Supplier USD", currency="USD", conversion_rate=50 + ).submit() + + pi_return = frappe.get_doc(pi.as_dict()) + pi_return.name = None + pi_return.docstatus = 0 + pi_return.is_return = 1 + pi_return.conversion_rate = 80 + pi_return.items[0].qty = -pi_return.items[0].qty + pi_return.submit() + + self.company = "_Test Company" + self.party_type = "Supplier" + self.customer = "_Test Supplier USD" + + pr = self.create_payment_reconciliation() + pr.get_unreconciled_entries() + + invoices = [] + payments = [] + for invoice in pr.invoices: + if invoice.invoice_number == pi.name: + invoices.append(invoice.as_dict()) + break + for payment in pr.payments: + if payment.reference_name == pi_return.name: + payments.append(payment.as_dict()) + break + + pr.allocate_entries(frappe._dict({"invoices": invoices, "payments": payments})) + + # Should not raise frappe.exceptions.ValidationError: Total Debit must be equal to Total Credit. + pr.reconcile() + def make_customer(customer_name, currency=None): if not frappe.db.exists("Customer", customer_name): From 7973951c370de0bc95c82ed132b109cdade9f2b9 Mon Sep 17 00:00:00 2001 From: Devin Slauenwhite Date: Wed, 7 Jun 2023 15:55:16 -0400 Subject: [PATCH 23/89] fix: missing attribute error --- .../payment_reconciliation/test_payment_reconciliation.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/erpnext/accounts/doctype/payment_reconciliation/test_payment_reconciliation.py b/erpnext/accounts/doctype/payment_reconciliation/test_payment_reconciliation.py index e4efc6894f..2ac7df0e39 100644 --- a/erpnext/accounts/doctype/payment_reconciliation/test_payment_reconciliation.py +++ b/erpnext/accounts/doctype/payment_reconciliation/test_payment_reconciliation.py @@ -166,7 +166,9 @@ class TestPaymentReconciliation(FrappeTestCase): def create_payment_reconciliation(self): pr = frappe.new_doc("Payment Reconciliation") pr.company = self.company - pr.party_type = self.party_type or "Customer" + pr.party_type = ( + self.party_type if hasattr(self, "party_type") and self.party_type else "Customer" + ) pr.party = self.customer pr.receivable_payable_account = get_party_account(pr.party_type, pr.party, pr.company) pr.from_invoice_date = pr.to_invoice_date = pr.from_payment_date = pr.to_payment_date = nowdate() From 54935438e127d984ca28ddac4cda84e090e7f72a Mon Sep 17 00:00:00 2001 From: Devin Slauenwhite Date: Wed, 7 Jun 2023 15:55:37 -0400 Subject: [PATCH 24/89] fix: reconcile invoice against credit note --- .../payment_reconciliation.py | 29 +++++++++++++++---- 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.py b/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.py index cc2b9420cc..77adf45911 100644 --- a/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.py +++ b/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.py @@ -316,6 +316,7 @@ class PaymentReconciliation(Document): entry_list = [] dr_or_cr_notes = [] + difference_entries = [] for row in self.get("allocation"): reconciled_entry = [] if row.invoice_number and row.allocated_amount: @@ -328,13 +329,15 @@ class PaymentReconciliation(Document): reconciled_entry.append(payment_details) if payment_details.difference_amount: - self.make_difference_entry(payment_details) + difference_entries.append( + self.make_difference_entry(payment_details, do_not_save_and_submit=bool(dr_or_cr_notes)) + ) if entry_list: reconcile_against_document(entry_list, skip_ref_details_update_for_pe) if dr_or_cr_notes: - reconcile_dr_cr_note(dr_or_cr_notes, self.company) + reconcile_dr_cr_note(dr_or_cr_notes, difference_entries, self.company) @frappe.whitelist() def reconcile(self): @@ -362,7 +365,7 @@ class PaymentReconciliation(Document): self.get_unreconciled_entries() - def make_difference_entry(self, row): + def make_difference_entry(self, row, do_not_save_and_submit=False): journal_entry = frappe.new_doc("Journal Entry") journal_entry.voucher_type = "Exchange Gain Or Loss" journal_entry.company = self.company @@ -410,8 +413,11 @@ class PaymentReconciliation(Document): journal_entry.append("accounts", journal_account) - journal_entry.save() - journal_entry.submit() + if not do_not_save_and_submit: + journal_entry.save() + journal_entry.submit() + + return journal_entry def get_payment_details(self, row, dr_or_cr): return frappe._dict( @@ -577,7 +583,14 @@ class PaymentReconciliation(Document): return condition -def reconcile_dr_cr_note(dr_cr_notes, company): +def reconcile_dr_cr_note(dr_cr_notes, difference_entries, company): + def find_difference_entry(voucher_type, voucher_no): + for jv in difference_entries: + accounts = iter(jv.accounts) + for account in accounts: + if account.reference_type == voucher_type and account.reference_name == voucher_no: + return next(accounts) + for inv in dr_cr_notes: voucher_type = "Credit Note" if inv.voucher_type == "Sales Invoice" else "Debit Note" @@ -622,5 +635,9 @@ def reconcile_dr_cr_note(dr_cr_notes, company): ], } ) + + if difference_entry := find_difference_entry(inv.against_voucher_type, inv.against_voucher): + jv.append("accounts", difference_entry) + jv.flags.ignore_mandatory = True jv.submit() From e30c3eafefca33afd91e2e473750a1582a3b88ad Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Mon, 12 Jun 2023 11:46:51 +0530 Subject: [PATCH 25/89] fix: Stock ledger preview --- .../doctype/sales_invoice/sales_invoice.json | 32 ++++++++- erpnext/controllers/buying_controller.py | 1 + erpnext/controllers/stock_controller.py | 69 +++++++++++++++++-- .../public/js/controllers/stock_controller.js | 15 ++-- 4 files changed, 104 insertions(+), 13 deletions(-) diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.json b/erpnext/accounts/doctype/sales_invoice/sales_invoice.json index 6a65b30ceb..15be2e71ba 100644 --- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.json +++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.json @@ -211,7 +211,12 @@ "is_discounted", "remarks", "repost_required", - "connections_tab" + "connections_tab", + "ledger_preview", + "accounting_ledger_section", + "accounting_ledger_preview_html", + "stock_ledger_section", + "stock_ledger_preview_html" ], "fields": [ { @@ -2142,6 +2147,29 @@ "fieldname": "use_company_roundoff_cost_center", "fieldtype": "Check", "label": "Use Company default Cost Center for Round off" + }, + { + "fieldname": "ledger_preview", + "fieldtype": "Tab Break", + "label": "Ledger Preview" + }, + { + "fieldname": "accounting_ledger_section", + "fieldtype": "Section Break", + "label": "Accounting Ledger" + }, + { + "fieldname": "accounting_ledger_preview_html", + "fieldtype": "HTML" + }, + { + "fieldname": "stock_ledger_section", + "fieldtype": "Section Break", + "label": "Stock Ledger" + }, + { + "fieldname": "stock_ledger_preview_html", + "fieldtype": "HTML" } ], "icon": "fa fa-file-text", @@ -2154,7 +2182,7 @@ "link_fieldname": "consolidated_invoice" } ], - "modified": "2023-04-28 14:15:59.901154", + "modified": "2023-06-11 11:18:14.024258", "modified_by": "Administrator", "module": "Accounts", "name": "Sales Invoice", diff --git a/erpnext/controllers/buying_controller.py b/erpnext/controllers/buying_controller.py index e15b61287e..efddae7e70 100644 --- a/erpnext/controllers/buying_controller.py +++ b/erpnext/controllers/buying_controller.py @@ -511,6 +511,7 @@ class BuyingController(SubcontractingController): if self.get("is_old_subcontracting_flow"): self.make_sl_entries_for_supplier_warehouse(sl_entries) + self.make_sl_entries( sl_entries, allow_negative_stock=allow_negative_stock, diff --git a/erpnext/controllers/stock_controller.py b/erpnext/controllers/stock_controller.py index 30dcc7ffa7..a81c03615e 100644 --- a/erpnext/controllers/stock_controller.py +++ b/erpnext/controllers/stock_controller.py @@ -15,7 +15,6 @@ from erpnext.accounts.general_ledger import ( make_reverse_gl_entries, process_gl_map, ) -from erpnext.accounts.report.general_ledger.general_ledger import get_columns from erpnext.accounts.utils import get_fiscal_year from erpnext.controllers.accounts_controller import AccountsController from erpnext.stock import get_warehouse_account_map @@ -827,16 +826,76 @@ class StockController(AccountsController): @frappe.whitelist() def show_ledger_preview(company, doctype, docname): + from erpnext.accounts.report.general_ledger.general_ledger import get_columns as get_gl_columns + from erpnext.stock.report.stock_ledger.stock_ledger import get_columns as get_sl_columns + + frappe.db.savepoint("show_ledger_preview") + filters = {"company": company} doc = frappe.get_doc(doctype, docname) - columns = get_columns(filters) - data = doc.get_gl_entries() + + datatable_sl_columns = [] + datatable_sl_data = [] + + if doc.update_stock or doc.doctype in ("Purchase Receipt", "Delivery Note"): + sl_columns = get_sl_columns(filters) + doc.docstatus = 1 + doc.update_stock_ledger() + sl_entries = get_sl_entries_for_preview(doc.doctype, doc.name) + datatable_sl_columns = get_columns(sl_columns) + datatable_sl_data = get_data(sl_columns, sl_entries) + + doc.docstatus = 1 + gl_columns = get_gl_columns(filters) + doc.make_gl_entries() + gl_data = get_gl_entries_for_preview(doc.doctype, doc.name) + + datatable_gl_columns = get_columns(gl_columns) + datatable_gl_data = get_data(gl_columns, gl_data) + + frappe.db.rollback(save_point="show_ledger_preview") + return { - "columns": columns, - "data": data, + "gl_columns": datatable_gl_columns, + "gl_data": datatable_gl_data, + "sl_columns": datatable_sl_columns, + "sl_data": datatable_sl_data, } +def get_sl_entries_for_preview(doctype, docname): + return frappe.get_all( + "Stock Ledger Entry", filters={"voucher_type": doctype, "voucher_no": docname}, fields=["*"] + ) + + +def get_gl_entries_for_preview(doctype, docname): + return frappe.get_all( + "GL Entry", filters={"voucher_type": doctype, "voucher_no": docname}, fields=["*"] + ) + + +def get_columns(raw_columns): + return [ + {"name": d.get("label"), "editable": False, "width": 100} + for d in raw_columns + if not d.get("hidden") + ] + + +def get_data(raw_columns, raw_data): + datatable_data = [] + for row in raw_data: + data_row = [] + for column in raw_columns: + if not column.get("hidden"): + data_row.append(row.get(column.get("fieldname"))) + + datatable_data.append(data_row) + + return datatable_data + + def repost_required_for_queue(doc: StockController) -> bool: """check if stock document contains repeated item-warehouse with queue based valuation. diff --git a/erpnext/public/js/controllers/stock_controller.js b/erpnext/public/js/controllers/stock_controller.js index 919ffda52f..0ef2e6eb69 100644 --- a/erpnext/public/js/controllers/stock_controller.js +++ b/erpnext/public/js/controllers/stock_controller.js @@ -94,24 +94,27 @@ erpnext.stock.StockController = class StockController extends frappe.ui.form.Con "docname": me.frm.doc.name }, "callback": function(response) { - me.get_datatable(response); + console.log(response.message); + me.get_datatable(response.message.gl_columns, response.message.gl_data, me.frm.get_field("accounting_ledger_preview_html").wrapper); + me.get_datatable(response.message.sl_columns, response.message.sl_data, me.frm.get_field("stock_ledger_preview_html").wrapper); + me.frm.scroll_to_field("accounting_ledger_preview_html"); } }) }, __("View")); } } - get_datatable(response) { + get_datatable(columns, data, wrapper) { const datatable_options = { - columns: response.columns, - data: response.data, + columns: columns, + data: data, dynamicRowHeight: true, checkboxColumn: false, inlineFilters: true, }; - this.datatable = new frappe.DataTable( - this.frm.page.main.parent, + new frappe.DataTable( + wrapper, datatable_options ); } From 011ac131cfdbb7ae75dcebc92412c43a3de8cd92 Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Mon, 12 Jun 2023 18:42:49 +0530 Subject: [PATCH 26/89] fix: Add column values --- erpnext/controllers/stock_controller.py | 133 +++++++++++++----- .../public/js/controllers/stock_controller.js | 1 - 2 files changed, 95 insertions(+), 39 deletions(-) diff --git a/erpnext/controllers/stock_controller.py b/erpnext/controllers/stock_controller.py index a81c03615e..3277721126 100644 --- a/erpnext/controllers/stock_controller.py +++ b/erpnext/controllers/stock_controller.py @@ -826,60 +826,118 @@ class StockController(AccountsController): @frappe.whitelist() def show_ledger_preview(company, doctype, docname): - from erpnext.accounts.report.general_ledger.general_ledger import get_columns as get_gl_columns - from erpnext.stock.report.stock_ledger.stock_ledger import get_columns as get_sl_columns - frappe.db.savepoint("show_ledger_preview") filters = {"company": company} doc = frappe.get_doc(doctype, docname) - datatable_sl_columns = [] - datatable_sl_data = [] - - if doc.update_stock or doc.doctype in ("Purchase Receipt", "Delivery Note"): - sl_columns = get_sl_columns(filters) - doc.docstatus = 1 - doc.update_stock_ledger() - sl_entries = get_sl_entries_for_preview(doc.doctype, doc.name) - datatable_sl_columns = get_columns(sl_columns) - datatable_sl_data = get_data(sl_columns, sl_entries) - - doc.docstatus = 1 - gl_columns = get_gl_columns(filters) - doc.make_gl_entries() - gl_data = get_gl_entries_for_preview(doc.doctype, doc.name) - - datatable_gl_columns = get_columns(gl_columns) - datatable_gl_data = get_data(gl_columns, gl_data) + sl_columns, sl_data = get_stock_ledger_preview(doc, filters) + gl_columns, gl_data = get_accounting_ledger_preview(doc, filters) frappe.db.rollback(save_point="show_ledger_preview") return { - "gl_columns": datatable_gl_columns, - "gl_data": datatable_gl_data, - "sl_columns": datatable_sl_columns, - "sl_data": datatable_sl_data, + "gl_columns": gl_columns, + "gl_data": gl_data, + "sl_columns": sl_columns, + "sl_data": sl_data, } -def get_sl_entries_for_preview(doctype, docname): +def get_accounting_ledger_preview(doc, filters): + from erpnext.accounts.report.general_ledger.general_ledger import get_columns as get_gl_columns + + gl_columns, gl_data = [], [] + fields = [ + "posting_date", + "account", + "debit", + "credit", + "against", + "party", + "party_type", + "against_voucher_type", + "against_voucher", + ] + + doc.docstatus = 1 + doc.make_gl_entries() + columns = get_gl_columns(filters) + gl_entries = get_gl_entries_for_preview(doc.doctype, doc.name, fields) + + gl_columns = get_columns(columns, fields) + gl_data = get_data(fields, gl_entries) + + return gl_columns, gl_data + + +def get_stock_ledger_preview(doc, filters): + from erpnext.stock.report.stock_ledger.stock_ledger import get_columns as get_sl_columns + + sl_columns, sl_data = [], [] + fields = [ + "item_code", + "stock_uom", + "actual_qty", + "qty_after_transaction", + "warehouse", + "incoming_rate", + "valuation_rate", + "stock_value", + "stock_value_difference", + ] + columns_fields = [ + "item_code", + "stock_uom", + "in_qty", + "out_qty", + "qty_after_transaction", + "warehouse", + "incoming_rate", + "valuation_rate", + "stock_value", + "stock_value_difference", + ] + + if doc.update_stock or doc.doctype in ("Purchase Receipt", "Delivery Note"): + doc.docstatus = 1 + doc.update_stock_ledger() + columns = get_sl_columns(filters) + sl_entries = get_sl_entries_for_preview(doc.doctype, doc.name, fields) + + sl_columns = get_columns(columns, columns_fields) + sl_data = get_data(columns_fields, sl_entries) + + return sl_columns, sl_data + + +def get_sl_entries_for_preview(doctype, docname, fields): + sl_entries = frappe.get_all( + "Stock Ledger Entry", filters={"voucher_type": doctype, "voucher_no": docname}, fields=fields + ) + + for entry in sl_entries: + if entry.actual_qty > 0: + entry["in_qty"] = entry.actual_qty + entry["out_qty"] = 0 + else: + entry["out_qty"] = abs(entry.actual_qty) + entry["in_qty"] = 0 + + return sl_entries + + +def get_gl_entries_for_preview(doctype, docname, fields): return frappe.get_all( - "Stock Ledger Entry", filters={"voucher_type": doctype, "voucher_no": docname}, fields=["*"] + "GL Entry", filters={"voucher_type": doctype, "voucher_no": docname}, fields=fields ) -def get_gl_entries_for_preview(doctype, docname): - return frappe.get_all( - "GL Entry", filters={"voucher_type": doctype, "voucher_no": docname}, fields=["*"] - ) - - -def get_columns(raw_columns): +def get_columns(raw_columns, fields): return [ - {"name": d.get("label"), "editable": False, "width": 100} + {"name": d.get("label"), "editable": False, "width": 110} for d in raw_columns - if not d.get("hidden") + if not d.get("hidden") and d.get("fieldname") in fields ] @@ -888,8 +946,7 @@ def get_data(raw_columns, raw_data): for row in raw_data: data_row = [] for column in raw_columns: - if not column.get("hidden"): - data_row.append(row.get(column.get("fieldname"))) + data_row.append(row.get(column) or "") datatable_data.append(data_row) diff --git a/erpnext/public/js/controllers/stock_controller.js b/erpnext/public/js/controllers/stock_controller.js index 0ef2e6eb69..0a14ed7935 100644 --- a/erpnext/public/js/controllers/stock_controller.js +++ b/erpnext/public/js/controllers/stock_controller.js @@ -94,7 +94,6 @@ erpnext.stock.StockController = class StockController extends frappe.ui.form.Con "docname": me.frm.doc.name }, "callback": function(response) { - console.log(response.message); me.get_datatable(response.message.gl_columns, response.message.gl_data, me.frm.get_field("accounting_ledger_preview_html").wrapper); me.get_datatable(response.message.sl_columns, response.message.sl_data, me.frm.get_field("stock_ledger_preview_html").wrapper); me.frm.scroll_to_field("accounting_ledger_preview_html"); From 2c1ab569a784d482779f29dc2f7085d78e2a5403 Mon Sep 17 00:00:00 2001 From: s-aga-r Date: Wed, 14 Jun 2023 15:29:35 +0530 Subject: [PATCH 27/89] fix: add validation for QI in PR --- .../purchase_receipt/purchase_receipt.py | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py index 1ac2f35019..387f031380 100644 --- a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py +++ b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py @@ -122,6 +122,7 @@ class PurchaseReceipt(BuyingController): self.set_status() self.po_required() + self.validate_items_quality_inspection() self.validate_with_previous_doc() self.validate_uom_is_integer("uom", ["qty", "received_qty"]) self.validate_uom_is_integer("stock_uom", "stock_qty") @@ -195,6 +196,26 @@ class PurchaseReceipt(BuyingController): if not d.purchase_order: frappe.throw(_("Purchase Order number required for Item {0}").format(d.item_code)) + def validate_items_quality_inspection(self): + for item in self.get("items"): + if item.quality_inspection: + qi = frappe.db.get_value( + "Quality Inspection", + item.quality_inspection, + ["reference_type", "reference_name", "item_code"], + as_dict=True, + ) + + if qi.reference_type != self.doctype or qi.reference_name != self.name: + msg = f"""Row #{item.idx}: Please select a valid Quality Inspection with Reference Type + {frappe.bold(self.doctype)} and Reference Name {frappe.bold(self.name)}.""" + frappe.throw(_(msg)) + + if qi.item_code != item.item_code: + msg = f"""Row #{item.idx}: Please select a valid Quality Inspection with Item Code + {frappe.bold(item.item_code)}.""" + frappe.throw(_(msg)) + def get_already_received_qty(self, po, po_detail): qty = frappe.db.sql( """select sum(qty) from `tabPurchase Receipt Item` From 4b5454c752dc88576b584429f1c33ba0d279bc59 Mon Sep 17 00:00:00 2001 From: s-aga-r Date: Fri, 16 Jun 2023 15:04:37 +0530 Subject: [PATCH 28/89] fix(ux): set route options for new `SBB` --- .../asset_capitalization/asset_capitalization.js | 11 +++++++++++ erpnext/assets/doctype/asset_repair/asset_repair.js | 10 ++++++++++ erpnext/manufacturing/doctype/job_card/job_card.js | 11 +++++++++++ erpnext/public/js/controllers/transaction.js | 9 +++++++++ .../doctype/installation_note/installation_note.js | 10 ++++++++++ erpnext/selling/doctype/quotation/quotation.js | 11 +++++++++++ erpnext/stock/doctype/pick_list/pick_list.js | 11 +++++++++++ erpnext/stock/doctype/stock_entry/stock_entry.js | 9 +++++++++ .../stock_reconciliation/stock_reconciliation.js | 11 +++++++++++ .../subcontracting_receipt/subcontracting_receipt.js | 10 ++++++++++ 10 files changed, 103 insertions(+) diff --git a/erpnext/assets/doctype/asset_capitalization/asset_capitalization.js b/erpnext/assets/doctype/asset_capitalization/asset_capitalization.js index 96f4438ef7..01fcb11d81 100644 --- a/erpnext/assets/doctype/asset_capitalization/asset_capitalization.js +++ b/erpnext/assets/doctype/asset_capitalization/asset_capitalization.js @@ -112,6 +112,17 @@ erpnext.assets.AssetCapitalization = class AssetCapitalization extends erpnext.s } }; }); + + let sbb_field = me.frm.get_docfield('stock_items', 'serial_and_batch_bundle'); + if (sbb_field) { + sbb_field.get_route_options_for_new_doc = (row) => { + return { + 'item_code': row.doc.item_code, + 'warehouse': row.doc.warehouse, + 'voucher_type': me.frm.doc.doctype, + } + }; + } } target_item_code() { diff --git a/erpnext/assets/doctype/asset_repair/asset_repair.js b/erpnext/assets/doctype/asset_repair/asset_repair.js index b2ab82cbfb..dae993a283 100644 --- a/erpnext/assets/doctype/asset_repair/asset_repair.js +++ b/erpnext/assets/doctype/asset_repair/asset_repair.js @@ -40,6 +40,16 @@ frappe.ui.form.on('Asset Repair', { } } }); + + let sbb_field = frm.get_docfield('stock_items', 'serial_and_batch_bundle'); + if (sbb_field) { + sbb_field.get_route_options_for_new_doc = (row) => { + return { + 'item_code': row.doc.item_code, + 'voucher_type': frm.doc.doctype, + } + }; + } }, refresh: function(frm) { diff --git a/erpnext/manufacturing/doctype/job_card/job_card.js b/erpnext/manufacturing/doctype/job_card/job_card.js index 7d08aca24b..8e9f542362 100644 --- a/erpnext/manufacturing/doctype/job_card/job_card.js +++ b/erpnext/manufacturing/doctype/job_card/job_card.js @@ -23,6 +23,17 @@ frappe.ui.form.on('Job Card', { } }); + let sbb_field = frm.get_docfield('serial_and_batch_bundle'); + if (sbb_field) { + sbb_field.get_route_options_for_new_doc = () => { + return { + 'item_code': frm.doc.production_item, + 'warehouse': frm.doc.wip_warehouse, + 'voucher_type': frm.doc.doctype, + } + }; + } + frm.set_indicator_formatter('sub_operation', function(doc) { if (doc.status == "Pending") { diff --git a/erpnext/public/js/controllers/transaction.js b/erpnext/public/js/controllers/transaction.js index 933556774b..0d92683f21 100644 --- a/erpnext/public/js/controllers/transaction.js +++ b/erpnext/public/js/controllers/transaction.js @@ -134,6 +134,15 @@ erpnext.TransactionController = class TransactionController extends erpnext.taxe } } }); + + let sbb_field = this.frm.get_docfield('items', 'serial_and_batch_bundle'); + if (sbb_field) { + sbb_field.get_route_options_for_new_doc = (row) => { + return { + 'item_code': row.doc.item_code, + } + }; + } } if( diff --git a/erpnext/selling/doctype/installation_note/installation_note.js b/erpnext/selling/doctype/installation_note/installation_note.js index d63060e6e4..dd6f8a8104 100644 --- a/erpnext/selling/doctype/installation_note/installation_note.js +++ b/erpnext/selling/doctype/installation_note/installation_note.js @@ -18,6 +18,16 @@ frappe.ui.form.on('Installation Note', { } } }); + + let sbb_field = frm.get_docfield('items', 'serial_and_batch_bundle'); + if (sbb_field) { + sbb_field.get_route_options_for_new_doc = (row) => { + return { + 'item_code': row.doc.item_code, + 'voucher_type': frm.doc.doctype, + } + }; + } }, onload: function(frm) { if(!frm.doc.status) { diff --git a/erpnext/selling/doctype/quotation/quotation.js b/erpnext/selling/doctype/quotation/quotation.js index 280485a833..67c392cc3f 100644 --- a/erpnext/selling/doctype/quotation/quotation.js +++ b/erpnext/selling/doctype/quotation/quotation.js @@ -46,6 +46,17 @@ frappe.ui.form.on('Quotation', { } } }); + + let sbb_field = frm.get_docfield('packed_items', 'serial_and_batch_bundle'); + if (sbb_field) { + sbb_field.get_route_options_for_new_doc = (row) => { + return { + 'item_code': row.doc.item_code, + 'warehouse': row.doc.warehouse, + 'voucher_type': frm.doc.doctype, + } + }; + } }, refresh: function(frm) { diff --git a/erpnext/stock/doctype/pick_list/pick_list.js b/erpnext/stock/doctype/pick_list/pick_list.js index acbb62d0a0..35c35a6f07 100644 --- a/erpnext/stock/doctype/pick_list/pick_list.js +++ b/erpnext/stock/doctype/pick_list/pick_list.js @@ -65,6 +65,17 @@ frappe.ui.form.on('Pick List', { } } }); + + let sbb_field = frm.get_docfield('locations', 'serial_and_batch_bundle'); + if (sbb_field) { + sbb_field.get_route_options_for_new_doc = (row) => { + return { + 'item_code': row.doc.item_code, + 'warehouse': row.doc.warehouse, + 'voucher_type': frm.doc.doctype, + } + }; + } }, set_item_locations:(frm, save) => { if (!(frm.doc.locations && frm.doc.locations.length)) { diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.js b/erpnext/stock/doctype/stock_entry/stock_entry.js index 3d497ac2eb..403e04ae60 100644 --- a/erpnext/stock/doctype/stock_entry/stock_entry.js +++ b/erpnext/stock/doctype/stock_entry/stock_entry.js @@ -115,6 +115,15 @@ frappe.ui.form.on('Stock Entry', { } }); + let sbb_field = frm.get_docfield('items', 'serial_and_batch_bundle'); + if (sbb_field) { + sbb_field.get_route_options_for_new_doc = (row) => { + return { + 'item_code': row.doc.item_code, + 'voucher_type': frm.doc.doctype, + } + }; + } frm.add_fetch("bom_no", "inspection_required", "inspection_required"); erpnext.accounts.dimensions.setup_dimension_filters(frm, frm.doctype); diff --git a/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.js b/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.js index 6afbf01e1e..0664c2929c 100644 --- a/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.js +++ b/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.js @@ -42,6 +42,17 @@ frappe.ui.form.on("Stock Reconciliation", { } }); + let sbb_field = frm.get_docfield('items', 'serial_and_batch_bundle'); + if (sbb_field) { + sbb_field.get_route_options_for_new_doc = (row) => { + return { + 'item_code': row.doc.item_code, + 'warehouse': row.doc.warehouse, + 'voucher_type': frm.doc.doctype, + } + }; + } + if (frm.doc.company) { erpnext.queries.setup_queries(frm, "Warehouse", function() { return erpnext.queries.warehouse(frm.doc); diff --git a/erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.js b/erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.js index bd1512b1e3..5ee1f7b716 100644 --- a/erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.js +++ b/erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.js @@ -89,6 +89,16 @@ frappe.ui.form.on('Subcontracting Receipt', { } }); + let sbb_field = frm.get_docfield('supplied_items', 'serial_and_batch_bundle'); + if (sbb_field) { + sbb_field.get_route_options_for_new_doc = (row) => { + return { + 'item_code': row.doc.rm_item_code, + 'voucher_type': frm.doc.doctype, + } + }; + } + let batch_no_field = frm.get_docfield('items', 'batch_no'); if (batch_no_field) { batch_no_field.get_route_options_for_new_doc = function(row) { From 28dd758aa3e7f2cd68f4658d1c4ca6f591c6df07 Mon Sep 17 00:00:00 2001 From: Rohit Waghchaure Date: Fri, 16 Jun 2023 16:44:56 +0530 Subject: [PATCH 29/89] fix: incorrect stock value for purchase returned with rejected qty --- .../controllers/sales_and_purchase_return.py | 3 ++ .../purchase_receipt/test_purchase_receipt.py | 46 +++++++++++++++++++ 2 files changed, 49 insertions(+) diff --git a/erpnext/controllers/sales_and_purchase_return.py b/erpnext/controllers/sales_and_purchase_return.py index 11cee28a57..818c7894b7 100644 --- a/erpnext/controllers/sales_and_purchase_return.py +++ b/erpnext/controllers/sales_and_purchase_return.py @@ -660,6 +660,9 @@ def get_filters( if reference_voucher_detail_no: filters["voucher_detail_no"] = reference_voucher_detail_no + if item_row and item_row.get("warehouse"): + filters["warehouse"] = item_row.get("warehouse") + return filters diff --git a/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py b/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py index 92235b0845..ddc055656f 100644 --- a/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py +++ b/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py @@ -1781,6 +1781,52 @@ class TestPurchaseReceipt(FrappeTestCase): pr.items[0].delivery_note_item = delivery_note_item pr.save() + def test_purchase_return_valuation_with_rejected_qty(self): + item_code = "_Test Item Return Valuation" + create_item(item_code) + + warehouse = create_warehouse("_Test Warehouse Return Valuation") + rejected_warehouse = create_warehouse("_Test Rejected Warehouse Return Valuation") + + # Step 1: Create Purchase Receipt with valuation rate 100 + make_purchase_receipt( + item_code=item_code, + warehouse=warehouse, + qty=10, + rate=100, + rejected_qty=2, + rejected_warehouse=rejected_warehouse, + ) + + # Step 2: Create One more Purchase Receipt with valuation rate 200 + pr = make_purchase_receipt( + item_code=item_code, + warehouse=warehouse, + qty=10, + rate=200, + rejected_qty=2, + rejected_warehouse=rejected_warehouse, + ) + + # Step 3: Create Purchase Return for 2 qty + from erpnext.stock.doctype.purchase_receipt.purchase_receipt import make_purchase_return + + pr_return = make_purchase_return(pr.name) + pr_return.items[0].qty = 2 * -1 + pr_return.items[0].received_qty = 2 * -1 + pr_return.items[0].rejected_qty = 0 + pr_return.items[0].rejected_warehouse = "" + pr_return.save() + pr_return.submit() + + data = frappe.get_all( + "Stock Ledger Entry", + filters={"voucher_no": pr_return.name, "docstatus": 1}, + fields=["SUM(stock_value_difference) as stock_value_difference"], + )[0] + + self.assertEqual(abs(data["stock_value_difference"]), 400.00) + def prepare_data_for_internal_transfer(): from erpnext.accounts.doctype.sales_invoice.test_sales_invoice import create_internal_supplier From e3afcc694599ee0624da42c4271f21f611b2f570 Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Sat, 17 Jun 2023 12:15:47 +0530 Subject: [PATCH 30/89] fix: cannot start / stop Job Card (backport #35753) (#35755) fix: cannot start / stop jobs (cherry picked from commit 53ec2a9268ca41fd44f58859df02c1f0876ed757) Co-authored-by: Anoop Kurungadam --- erpnext/manufacturing/doctype/job_card/job_card.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/manufacturing/doctype/job_card/job_card.py b/erpnext/manufacturing/doctype/job_card/job_card.py index 496cbfd0a6..2c17568d1b 100644 --- a/erpnext/manufacturing/doctype/job_card/job_card.py +++ b/erpnext/manufacturing/doctype/job_card/job_card.py @@ -161,7 +161,7 @@ class JobCard(Document): self.total_completed_qty = flt(self.total_completed_qty, self.precision("total_completed_qty")) for row in self.sub_operations: - self.c += row.completed_qty + self.total_completed_qty += row.completed_qty def get_overlap_for(self, args, check_next_available_slot=False): production_capacity = 1 From df8c3f0888e06c28da0937190e97c3589d67c44d Mon Sep 17 00:00:00 2001 From: Rohit Waghchaure Date: Sat, 17 Jun 2023 12:14:32 +0530 Subject: [PATCH 31/89] fix: validation of job card in stock entry --- erpnext/stock/doctype/stock_entry/stock_entry.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.py b/erpnext/stock/doctype/stock_entry/stock_entry.py index 517fea5bd1..d9b5503b50 100644 --- a/erpnext/stock/doctype/stock_entry/stock_entry.py +++ b/erpnext/stock/doctype/stock_entry/stock_entry.py @@ -266,10 +266,10 @@ class StockEntry(StockController): return for row in self.items: - if row.job_card_item: + if row.job_card_item or not row.s_warehouse: continue - msg = f"""Row #{0}: The job card item reference + msg = f"""Row #{row.idx}: The job card item reference is missing. Kindly create the stock entry from the job card. If you have added the row manually then you won't be able to add job card item reference.""" From 0444b9880213c5f67ba79df95a48e46b44a4bc5a Mon Sep 17 00:00:00 2001 From: David Arnold Date: Sun, 18 Jun 2023 11:47:31 -0500 Subject: [PATCH 32/89] feat: add verified chart of accounts for colombia in two variants (#34508) This information is scraped from the in Colombia widely trusted site dedicated to the plan unico de cuentas (PUC): puc.com.co feat(accounts): add account_type overlay to colombian CoA Add account_type overlay with a most significant number matching strategy and a hand-crafted dictionary based on the erpnext documentation and the corresponding account description from puc.com.co Script used for scraping: https://gist.github.com/blaggacao/d45a454d27556f41fef88833937088f1 --- .../co_vauxoo_mx_chart_template.json | 3008 ------ .../verified/co_plan_unico_de_cuentas.json | 9400 +++++++++++++++++ .../co_plan_unico_de_cuentas_simple.json | 1746 +++ 3 files changed, 11146 insertions(+), 3008 deletions(-) delete mode 100644 erpnext/accounts/doctype/account/chart_of_accounts/unverified/co_vauxoo_mx_chart_template.json create mode 100644 erpnext/accounts/doctype/account/chart_of_accounts/verified/co_plan_unico_de_cuentas.json create mode 100644 erpnext/accounts/doctype/account/chart_of_accounts/verified/co_plan_unico_de_cuentas_simple.json diff --git a/erpnext/accounts/doctype/account/chart_of_accounts/unverified/co_vauxoo_mx_chart_template.json b/erpnext/accounts/doctype/account/chart_of_accounts/unverified/co_vauxoo_mx_chart_template.json deleted file mode 100644 index aa7d5519fd..0000000000 --- a/erpnext/accounts/doctype/account/chart_of_accounts/unverified/co_vauxoo_mx_chart_template.json +++ /dev/null @@ -1,3008 +0,0 @@ -{ - "country_code": "co", - "name": "Colombia - Unique Account Chart - PUC", - "tree": { - "ACTIVO": { - "DEUDORES": { - "ANTICIPO DE IMPUESTOS Y CONTRIBUCIONES O SALDOS A FAVOR": { - "ANTICIPO DE IMPUESTOS DE INDUSTRIA Y COMERCIO": {}, - "ANTICIPO DE IMPUESTOS DE RENTA Y COMPLEMENTARIOS": {}, - "CONTRIBUCIONES": {}, - "IMPUESTO A LAS VENTAS RETENIDO": { - " IMPUESTO A LAS VENTAS RETENIDO": {} - }, - "IMPUESTO DE INDUSTRIA Y COMERCIO RETENIDO": {}, - "IMPUESTOS DESCONTABLES": {}, - "OTROS": {}, - "RETENCION EN LA FUENTE": {}, - "SOBRANTES EN LIQUIDACION PRIVADA DE IMPUESTOS": {} - }, - "ANTICIPOS Y AVANCES": { - "A AGENTES": { - "A AGENTES": {} - }, - "A CONCESIONARIOS": {}, - "A CONTRATISTAS": {}, - "A PROVEEDORES": {}, - "A TRABAJADORES": {}, - "AJUSTES POR INFLACION": {}, - "DE ADJUDICACIONES": {}, - "OTROS": {} - }, - "APORTES POR COBRAR": {}, - "CLIENTES": { - "DEL EXTERIOR": {}, - "DEUDORES DEL SISTEMA": {}, - "NACIONALES": { - "DEUDORES CLIENTES NACIONALES": {} - } - }, - "CUENTAS CORRIENTES COMERCIALES": { - "ACCIONISTAS O SOCIOS": {}, - "CASA MATRIZ": {}, - "COMPANIAS VINCULADAS": {}, - "OTRAS": {}, - "PARTICULARES": {} - }, - "CUENTAS DE OPERACION CONJUNTA": {}, - "CUENTAS POR COBRAR A CASA MATRIZ": { - "PAGOS A NOMBRE DE CASA MATRIZ": {}, - "PRESTAMOS": {}, - "VALORES RECIBIDOS POR CASA MATRIZ": {}, - "VENTAS": {} - }, - "CUENTAS POR COBRAR A DIRECTORES": {}, - "CUENTAS POR COBRAR A SOCIOS Y ACCIONISTAS": { - "A ACCIONISTAS": { - "ALFONSO SOTO": {}, - "DOUGLAS CANELON": {}, - "LIGIA MARINA CANELON CASTELLANOS": {} - }, - "A SOCIOS": { - "A SOCIOS": {} - } - }, - "CUENTAS POR COBRAR A TRABAJADORES": { - "CALAMIDAD DOMESTICA": {}, - "EDUCACION": {}, - "MEDICOS, ODONTOLOGICOS Y SIMILARES": {}, - "OTROS": {}, - "RESPONSABILIDADES": {}, - "VEHICULOS": {}, - "VIVIENDA": {} - }, - "CUENTAS POR COBRAR A VINCULADOS ECONOMICOS": { - "FILIALES": {}, - "SUBSIDIARIAS": {}, - "SUCURSALES": {} - }, - "DEPOSITOS": { - "EN GARANTIA": {}, - "OTROS": {}, - "PARA ADQUISICION DE ACCIONES, CUOTAS O DERECHOS SOCIALES": {}, - "PARA CONTRATOS": {}, - "PARA IMPORTACIONES": {}, - "PARA JUICIOS EJECUTIVOS": {}, - "PARA RESPONSABILIDADES": {}, - "PARA SERVICIOS": {} - }, - "DERECHOS DE RECOMPRA DE CARTERA NEGOCIADA": {}, - "DEUDAS DE DIFICIL COBRO": {}, - "DEUDORES VARIOS": { - "COMISIONISTAS DE BOLSAS": {}, - "CUENTAS POR COBRAR DE TERCEROS": {}, - "DEPOSITARIOS": {}, - "FONDO DE INVERSION": {}, - "FONDOS DE INVERSION SOCIAL": {}, - "OTROS": {}, - "PAGOS POR CUENTA DE TERCEROS": {} - }, - "INGRESOS POR COBRAR": { - "ARRENDAMIENTOS": {}, - "CERT POR COBRAR": {}, - "COMISIONES": {}, - "DIVIDENDOS Y/O PARTICIPACIONES": {}, - "HONORARIOS": {}, - "INTERESES": {}, - "OTROS": { - "Generica a Cobrar": {} - }, - "SERVICIOS": {} - }, - "PRESTAMOS A PARTICULARES": { - "CON GARANTIA PERSONAL": {}, - "CON GARANTIA REAL": {} - }, - "PROMESAS DE COMPRA VENTA": { - "DE BIENES RAICES": {}, - "DE FLOTA Y EQUIPO AEREO": {}, - "DE FLOTA Y EQUIPO DE TRANSPORTE": {}, - "DE FLOTA Y EQUIPO FERREO": {}, - "DE FLOTA Y EQUIPO FLUVIAL Y/O MARITIMO": {}, - "DE MAQUINARIA Y EQUIPO": {}, - "DE OTROS BIENES": {}, - "DE SEMOVIENTES": {} - }, - "PROVISIONES": { - "ANTICIPOS Y AVANCES": {}, - "CLIENTES": {}, - "CUENTAS CORRIENTES COMERCIALES": {}, - "CUENTAS DE OPERACION CONJUNTA": {}, - "CUENTAS POR COBRAR A CASA MATRIZ": {}, - "CUENTAS POR COBRAR A SOCIOS Y ACCIONISTAS": {}, - "CUENTAS POR COBRAR A TRABAJADORES": {}, - "CUENTAS POR COBRAR A VINCULADOS ECONOMICOS": {}, - "DEPOSITOS": {}, - "DERECHOS DE RECOMPRA DE CARTERA NEGOCIADA": {}, - "DEUDORES VARIOS": {}, - "INGRESOS POR COBRAR": {}, - "PRESTAMOS A PARTICULARES": {}, - "PROMESAS DE COMPRAVENTA": {}, - "RECLAMACIONES": {}, - "RETENCION SOBRE CONTRATOS": {} - }, - "RECLAMACIONES": { - "A COMPANIAS ASEGURADORAS": {}, - "A TRANSPORTADORES": {}, - "OTRAS": {}, - "POR TIQUETES AEREOS": {} - }, - "RETENCION SOBRE CONTRATOS": { - "DE CONSTRUCCION": {}, - "DE PRESTACION DE SERVICIOS": {}, - "IMPUESTO A LAS VENTAS RETENIDO": { - "IMPUESTO A LAS VENTAS RETENIDO": {} - }, - "IMPUESTO DE INDUSTRIA Y COMERCIO RETENIDO": { - "IMPUESTO DE INDUSTRIA Y COMERCIO RETENIDO": {} - }, - "OTROS": { - "OTROS": {} - }, - "RETEFTE SOBRE COMPRA DE LUBRICANTES": { - "RETEFTE SOBRE COMPRA DE LUBRICANTES": {} - } - } - }, - "DIFERIDOS": { - "AMORTIZACION ACUMULADA": { - "AJUSTES POR INFLACION": {}, - "COSTOS DE EXPLORACION POR AMORTIZAR": {}, - "COSTOS DE EXPLOTACION Y DESARROLLO": {} - }, - "CARGOS DIFERIDOS": { - "AJUSTES POR INFLACION": {}, - "CONCURSOS Y LICITACIONES": {}, - "CONTRIBUCIONES Y AFILIACIONES": {}, - "CUBIERTERIA": {}, - "DOTACION Y SUMINISTRO A TRABAJADORES": {}, - "ELEMENTOS DE ASEO Y CAFETERIA": {}, - "ELEMENTOS DE ROPERIA Y LENCERIA": {}, - "ENTRENAMIENTO DE PERSONAL": {}, - "ESTUDIOS, INVESTIGACIONES Y PROYECTOS": {}, - "FERIAS Y EXPOSICIONES": {}, - "IMPUESTO DE RENTA DIFERIDO ?DEBITOS? POR DIFERENCIAS TEMPORALES": {}, - "INSTRUMENTAL QUIRURGICO": {}, - "LICENCIAS": { - "LICENCIAS": {} - }, - "LOZA Y CRISTALERIA": {}, - "MEJORAS A PROPIEDADES AJENAS": {}, - "MOLDES Y TROQUELES": {}, - "ORGANIZACION Y PREOPERATIVOS": {}, - "OTROS": {}, - "PLATERIA": {}, - "PROGRAMAS PARA COMPUTADOR (SOFTWARE)": {}, - "PUBLICIDAD, PROPAGANDA Y PROMOCION": {}, - "REMODELACIONES": {}, - "UTILES Y PAPELERIA": { - "UTILES Y PAPELERIA": {} - } - }, - "CARGOS POR CORRECCION MONETARIA DIFERIDA": {}, - "COSTOS DE EXPLORACION POR AMORTIZAR": { - "AJUSTES POR INFLACION": {}, - "OTROS COSTOS DE EXPLORACION": {}, - "POZOS NO COMERCIALES": {}, - "POZOS SECOS": {} - }, - "COSTOS DE EXPLOTACION Y DESARROLLO": { - "AJUSTES POR INFLACION": {}, - "FACILIDADES DE PRODUCCION": {}, - "PERFORACION Y EXPLOTACION": {}, - "PERFORACIONES CAMPOS EN DESARROLLO": {}, - "SERVICIO A POZOS": {} - }, - "GASTOS PAGADOS POR ANTICIPADO": { - "ARRENDAMIENTOS": {}, - "BODEGAJES": {}, - "COMISIONES": {}, - "HONORARIOS": {}, - "INTERESES": {}, - "MANTENIMIENTO EQUIPOS": {}, - "OTROS": {}, - "SEGUROS Y FIANZAS": {}, - "SERVICIOS": {}, - "SUSCRIPCIONES": {} - } - }, - "DISPONIBLE": { - "BANCOS": { - "MONEDA EXTRANJERA": {}, - "MONEDA NACIONAL": {} - }, - "CAJA": { - "CAJA GENERAL": { - "CAJA GENERAL": {} - }, - "CAJAS MENORES": { - "CAJAS MENORES": {} - }, - "MONEDA EXTRANJERA": {} - }, - "CUENTAS DE AHORRO": { - "BANCOS": {}, - "CORPORACIONES DE AHORRO Y VIVIENDA": {}, - "ORGANISMOS COOPERATIVOS FINANCIEROS": {} - }, - "FONDOS": { - "DE AMORTIZACION MONEDA EXTRANJERA": {}, - "DE AMORTIZACION MONEDA NACIONAL": {}, - "ESPECIALES MONEDA EXTRANJERA": {}, - "ESPECIALES MONEDA NACIONAL": {}, - "ROTATORIOS MONEDA EXTRANJERA": {}, - "ROTATORIOS MONEDA NACIONAL": {} - }, - "REMESAS EN TRANSITO": { - "MONEDA EXTRANJERA": {}, - "MONEDA NACIONAL": {} - } - }, - "INTANGIBLES": { - "CONCESIONES Y FRANQUICIAS": { - "AJUSTES POR INFLACION": {}, - "CONCESIONES": {}, - "FRANQUICIAS": {} - }, - "CREDITO MERCANTIL": { - "ADQUIRIDO O COMPRADO": {}, - "AJUSTES POR INFLACION": {}, - "FORMADO O ESTIMADO": {} - }, - "DEPRECIACION Y/O AMORTIZACION ACUMULADA": { - "AJUSTES POR INFLACION": {}, - "CONCESIONES Y FRANQUICIAS": {}, - "CREDITO MERCANTIL": {}, - "DERECHOS": {}, - "KNOW HOW": {}, - "LICENCIAS": {}, - "MARCAS": {}, - "PATENTES": {} - }, - "DERECHOS": { - "AJUSTES POR INFLACION": {}, - "DE EXHIBICION - PELICULAS": {}, - "DERECHOS DE AUTOR": {}, - "EN BIENES RECIBIDOS EN ARRENDAMIENTO FINANCIERO (LEASING)": {}, - "EN FIDEICOMISOS DE ADMINISTRACION": {}, - "EN FIDEICOMISOS DE GARANTIA": {}, - "EN FIDEICOMISOS INMOBILIARIOS": {}, - "OTROS": {}, - "PUESTO DE BOLSA": {} - }, - "KNOW HOW": { - "AJUSTES POR INFLACION": {} - }, - "LICENCIAS": { - "AJUSTES POR INFLACION": {} - }, - "MARCAS": { - "ADQUIRIDAS": {}, - "AJUSTES POR INFLACION": {}, - "FORMADAS": {} - }, - "PATENTES": { - "ADQUIRIDAS": {}, - "AJUSTES POR INFLACION": {}, - "FORMADAS": {} - }, - "PROVISIONES": {} - }, - "INVENTARIOS": { - "BIENES RAICES PARA LA VENTA": { - "AJUSTES POR INFLACION": {} - }, - "CONTRATOS EN EJECUCION": { - "AJUSTES POR INFLACION": {} - }, - "CULTIVOS EN DESARROLLO": { - "AJUSTES POR INFLACION": {} - }, - "ENVASES Y EMPAQUES": { - "AJUSTES POR INFLACION": {} - }, - "INVENTARIOS EN TRANSITO": { - "AJUSTES POR INFLACION": {} - }, - "MATERIALES, REPUESTOS Y ACCESORIOS": { - "AJUSTES POR INFLACION": {} - }, - "MATERIAS PRIMAS": { - "AJUSTES POR INFLACION": {} - }, - "MERCANCIAS NO FABRICADAS POR LA EMPRESA": { - "AJUSTES POR INFLACION": {} - }, - "OBRAS DE CONSTRUCCION EN CURSO": { - "AJUSTES POR INFLACION": {} - }, - "OBRAS DE URBANISMO": { - "AJUSTES POR INFLACION": {} - }, - "PLANTACIONES AGRICOLAS": { - "AJUSTES POR INFLACION": {} - }, - "PRODUCTOS EN PROCESO": { - "AJUSTES POR INFLACION": {} - }, - "PRODUCTOS TERMINADOS": { - "AJUSTES POR INFLACION": {}, - "PRODUCTOS AGRICOLAS Y FORESTALES": {}, - "PRODUCTOS DE PESCA": {}, - "PRODUCTOS EXTRAIDOS Y/O PROCESADOS": {}, - "PRODUCTOS MANUFACTURADOS": {}, - "SUBPRODUCTOS": {} - }, - "PROVISIONES": { - "LIFO": {}, - "PARA DIFERENCIA DE INVENTARIO FISICO": {}, - "PARA OBSOLESCENCIA": {}, - "PARA PERDIDAS DE INVENTARIOS": {} - }, - "SEMOVIENTES": { - "AJUSTES POR INFLACION": {} - }, - "TERRENOS": { - "AJUSTES POR INFLACION": {}, - "POR URBANIZAR": {}, - "URBANIZADOS POR CONSTRUIR": {} - } - }, - "INVERSIONES": { - "ACCIONES": { - "ACTIVIDAD FINANCIERA": {}, - "ACTIVIDADES INMOBILIARIAS, EMPRESARIALES Y DE ALQUILER": {}, - "AGRICULTURA, GANADERIA, CAZA Y SILVICULTURA": {}, - "AJUSTES POR INFLACION": {}, - "COMERCIO AL POR MAYOR Y AL POR MENOR": {}, - "CONSTRUCCION": {}, - "ENSENANZA": {}, - "EXPLOTACION DE MINAS Y CANTERAS": {}, - "HOTELES Y RESTAURANTES": {}, - "INDUSTRIA MANUFACTURERA": {}, - "OTRAS ACTIVIDADES DE SERVICIOS COMUNITARIOS, SOCIALES Y PERSONALES": {}, - "PESCA": {}, - "SERVICIOS SOCIALES Y DE SALUD": {}, - "SUMINISTRO DE ELECTRICIDAD, GAS Y AGUA": {}, - "TRANSPORTE, ALMACENAMIENTO Y COMUNICACIONES": {} - }, - "ACEPTACIONES BANCARIAS O FINANCIERAS": { - "BANCOS COMERCIALES": {}, - "COMPANIAS DE FINANCIAMIENTO COMERCIAL": {}, - "CORPORACIONES FINANCIERAS": {}, - "OTRAS": {} - }, - "BONOS": { - "BONOS CONVERTIBLES EN ACCIONES": {}, - "BONOS ORDINARIOS": {}, - "BONOS PUBLICOS MONEDA EXTRANJERA": {}, - "BONOS PUBLICOS MONEDA NACIONAL": {}, - "OTROS": {} - }, - "CEDULAS": { - "CEDULAS DE CAPITALIZACION": {}, - "CEDULAS DE INVERSION": {}, - "CEDULAS HIPOTECARIAS": {}, - "OTRAS": {} - }, - "CERTIFICADOS": { - "CERTIFICADOS CAFETEROS VALORIZABLES": {}, - "CERTIFICADOS DE AHORRO DE VALOR CONSTANTE (CAVC)": {}, - "CERTIFICADOS DE CAMBIO": {}, - "CERTIFICADOS DE DEPOSITO A TERMINO (CDT)": {}, - "CERTIFICADOS DE DEPOSITO DE AHORRO": {}, - "CERTIFICADOS DE DESARROLLO TURISTICO": {}, - "CERTIFICADOS DE INVERSION FORESTAL (CIF)": {}, - "CERTIFICADOS DE REEMBOLSO TRIBUTARIO (CERT)": {}, - "CERTIFICADOS ELECTRICOS VALORIZABLES (CEV)": {}, - "OTROS": {} - }, - "CUENTAS EN PARTICIPACION": { - "AJUSTES POR INFLACION": {} - }, - "CUOTAS O PARTES DE INTERES SOCIAL": { - "ACTIVIDAD FINANCIERA": {}, - "ACTIVIDADES INMOBILIARIAS, EMPRESARIALES Y DE ALQUILER": {}, - "AGRICULTURA, GANADERIA, CAZA Y SILVICULTURA": {}, - "AJUSTES POR INFLACION": {}, - "COMERCIO AL POR MAYOR Y AL POR MENOR": {}, - "CONSTRUCCION": {}, - "ENSENANZA": {}, - "EXPLOTACION DE MINAS Y CANTERAS": {}, - "HOTELES Y RESTAURANTES": {}, - "INDUSTRIA MANUFACTURERA": {}, - "OTRAS ACTIVIDADES DE SERVICIOS COMUNITARIOS, SOCIALES Y PERSONALES": {}, - "PESCA": {}, - "SERVICIOS SOCIALES Y DE SALUD": {}, - "SUMINISTRO DE ELECTRICIDAD, GAS Y AGUA": {}, - "TRANSPORTE, ALMACENAMIENTO Y COMUNICACIONES": {} - }, - "DERECHOS DE RECOMPRA DE INVERSIONES NEGOCIADAS (REPOS)": { - "ACCIONES": {}, - "ACEPTACIONES BANCARIAS O FINANCIERAS": {}, - "AJUSTES POR INFLACION": {}, - "BONOS": {}, - "CEDULAS": {}, - "CERTIFICADOS": {}, - "CUOTAS O PARTES DE INTERES SOCIAL": {}, - "OTROS": {}, - "PAPELES COMERCIALES": {}, - "TITULOS": {} - }, - "DERECHOS FIDUCIARIOS": { - "FIDEICOMISOS DE INVERSION MONEDA EXTRANJERA": {}, - "FIDEICOMISOS DE INVERSION MONEDA NACIONAL": {} - }, - "OBLIGATORIAS": { - "BONOS DE FINANCIAMIENTO ESPECIAL": {}, - "BONOS DE FINANCIAMIENTO PRESUPUESTAL": {}, - "BONOS PARA DESARROLLO SOCIAL Y SEGURIDAD INTERNA (BDSI)": {}, - "OTRAS": {} - }, - "OTRAS INVERSIONES": { - "ACCIONES O DERECHOS EN CLUBES DEPORTIVOS": {}, - "AJUSTES POR INFLACION": {}, - "APORTES EN COOPERATIVAS": {}, - "BONOS EN COLEGIOS": {}, - "DERECHOS EN CLUBES SOCIALES": {}, - "DIVERSAS": {} - }, - "PAPELES COMERCIALES": { - "EMPRESAS COMERCIALES": {}, - "EMPRESAS DE SERVICIOS": {}, - "EMPRESAS INDUSTRIALES": {} - }, - "PROVISIONES": { - "ACCIONES": {}, - "ACEPTACIONES BANCARIAS O FINANCIERAS": {}, - "BONOS": {}, - "CEDULAS": {}, - "CERTIFICADOS": {}, - "CUENTAS EN PARTICIPACION": {}, - "CUOTAS O PARTES DE INTERES SOCIAL": {}, - "DERECHOS DE RECOMPRA DE INVERSIONES NEGOCIADAS": {}, - "DERECHOS FIDUCIARIOS": {}, - "OBLIGATORIAS": {}, - "OTRAS INVERSIONES": {}, - "PAPELES COMERCIALES": {}, - "TITULOS": {} - }, - "TITULOS": { - "OTROS": {}, - "TESOROS": {}, - "TITULOS CANJEABLES POR CERTIFICADOS DE CAMBIO": {}, - "TITULOS DE AHORRO CAFETERO (TAC)": {}, - "TITULOS DE AHORRO EDUCATIVO (TAE)": {}, - "TITULOS DE AHORRO NACIONAL (TAN)": {}, - "TITULOS DE CREDITO DE FOMENTO": {}, - "TITULOS DE DESARROLLO AGROPECUARIO": {}, - "TITULOS DE DEVOLUCION DE IMPUESTOS NACIONALES (TIDIS)": {}, - "TITULOS DE PARTICIPACION": {}, - "TITULOS DE TESORERIA (TES)": {}, - "TITULOS ENERGETICOS DE RENTABILIDAD CRECIENTE (TER)": {}, - "TITULOS FINANCIEROS AGROINDUSTRIALES (TFA)": {}, - "TITULOS FINANCIEROS INDUSTRIALES Y COMERCIALES": {}, - "TITULOS INMOBILIARIOS": {} - } - }, - "OTROS ACTIVOS": { - "BIENES DE ARTE Y CULTURA": { - "AJUSTES POR INFLACION": {}, - "BIBLIOTECAS": {}, - "OBRAS DE ARTE": {}, - "OTROS": {} - }, - "DIVERSOS": { - "AJUSTES POR INFLACION": {}, - "AMORTIZACION ACUMULADA DE BIENES ENTREGADOS EN COMODATO (CR)": {}, - "BIENES ENTREGADOS EN COMODATO": {}, - "BIENES RECIBIDOS EN PAGO": {}, - "DERECHOS SUCESORALES": {}, - "ESTAMPILLAS": {}, - "MAQUINAS PORTEADORAS": {}, - "OTROS": { - "OTROS": {} - } - }, - "PROVISIONES": { - "BIENES DE ARTE Y CULTURA": {}, - "DIVERSOS": {} - } - }, - "PROPIEDADES, PLANTA Y EQUIPO": { - "ACUEDUCTOS, PLANTAS Y REDES": { - "ACUEDUCTO, ACEQUIAS Y CANALIZACIONES": {}, - "AJUSTES POR INFLACION": {}, - "GASODUCTOS": {}, - "INSTALACIONES PARA AGUA Y ENERGIA": {}, - "INSTALACIONES Y EQUIPO DE BOMBEO": {}, - "OLEODUCTOS": {}, - "OTROS": {}, - "PLANTAS DE DISTRIBUCION": {}, - "PLANTAS DE GENERACION A GAS": {}, - "PLANTAS DE GENERACION DIESEL, GASOLINA Y PETROLEO": {}, - "PLANTAS DE GENERACION HIDRAULICA": {}, - "PLANTAS DE GENERACION TERMICA": {}, - "PLANTAS DE TRANSMISION Y SUBESTACIONES": {}, - "PLANTAS DE TRATAMIENTO": {}, - "PLANTAS DESHIDRATADORAS": {}, - "POLIDUCTOS": {}, - "REDES ALIMENTACION DE GAS": {}, - "REDES DE AIRE": {}, - "REDES DE DISTRIBUCION": {}, - "REDES DE DISTRIBUCION DE VAPOR": {}, - "REDES DE RECOLECCION DE AGUAS NEGRAS": {}, - "REDES EXTERNAS DE TELEFONIA": {} - }, - "AGOTAMIENTO ACUMULADO": { - "AJUSTES POR INFLACION": {}, - "MINAS Y CANTERAS": {}, - "POZOS ARTESIANOS": {}, - "YACIMIENTOS": {} - }, - "AMORTIZACION ACUMULADA": { - "AJUSTES POR INFLACION": {}, - "PLANTACIONES AGRICOLAS Y FORESTALES": {}, - "SEMOVIENTES": {}, - "VIAS DE COMUNICACION": {} - }, - "ARMAMENTO DE VIGILANCIA": { - "AJUSTES POR INFLACION": {} - }, - "CONSTRUCCIONES EN CURSO": { - "ACUEDUCTOS, PLANTAS Y REDES": {}, - "AJUSTES POR INFLACION": {}, - "CONSTRUCCIONES Y EDIFICACIONES": {}, - "POZOS ARTESIANOS": {}, - "PROYECTOS DE DESARROLLO": {}, - "PROYECTOS DE EXPLORACION": {}, - "VIAS DE COMUNICACION": {} - }, - "CONSTRUCCIONES Y EDIFICACIONES": { - "AJUSTES POR INFLACION": {}, - "ALMACENES": {}, - "BODEGAS": {}, - "CAFETERIA Y CASINOS": {}, - "CASETAS Y CAMPAMENTOS": {}, - "EDIFICIOS": {}, - "FABRICAS Y PLANTAS INDUSTRIALES": {}, - "HANGARES": {}, - "INSTALACIONES AGROPECUARIAS": {}, - "INVERNADEROS": {}, - "OFICINAS": {}, - "OTROS": {}, - "PARQUEADEROS, GARAJES Y DEPOSITOS": {}, - "SALAS DE EXHIBICION Y VENTAS": {}, - "SILOS": {}, - "TERMINAL DE BUSES Y TAXIS": {}, - "TERMINAL FERREO": {}, - "TERMINAL MARITIMO": {}, - "VIVIENDAS PARA EMPLEADOS Y OBREROS": {} - }, - "DEPRECIACION ACUMULADA": { - "ACUEDUCTOS, PLANTAS Y REDES": {}, - "AJUSTES POR INFLACION": {}, - "ARMAMENTO DE VIGILANCIA": {}, - "CONSTRUCCIONES Y EDIFICACIONES": {}, - "ENVASES Y EMPAQUES": {}, - "EQUIPO DE COMPUTACION Y COMUNICACION": {}, - "EQUIPO DE HOTELES Y RESTAURANTES": {}, - "EQUIPO DE OFICINA": {}, - "EQUIPO MEDICO-CIENTIFICO": {}, - "FLOTA Y EQUIPO AEREO": {}, - "FLOTA Y EQUIPO DE TRANSPORTE": {}, - "FLOTA Y EQUIPO FERREO": {}, - "FLOTA Y EQUIPO FLUVIAL Y/O MARITIMO": {}, - "MAQUINARIA Y EQUIPO": {} - }, - "DEPRECIACION DIFERIDA": { - "AJUSTES POR INFLACION": {}, - "DEFECTO FISCAL SOBRE LA CONTABLE (CR)": {}, - "EXCESO FISCAL SOBRE LA CONTABLE": {} - }, - "ENVASES Y EMPAQUES": { - "AJUSTES POR INFLACION": {} - }, - "EQUIPO DE COMPUTACION Y COMUNICACION": { - "AJUSTES POR INFLACION": {}, - "EQUIPOS DE PROCESAMIENTO DE DATOS": { - "EQUIPOS DE PROCESAMIENTO DE DATOS": {} - }, - "EQUIPOS DE RADIO": {}, - "EQUIPOS DE TELECOMUNICACIONES": { - "EQUIPOS DE TELECOMUNICACIONES": {} - }, - "LINEAS TELEFONICAS": {}, - "OTROS": {}, - "SATELITES Y ANTENAS": {} - }, - "EQUIPO DE HOTELES Y RESTAURANTES": { - "AJUSTES POR INFLACION": {}, - "DE COMESTIBLES Y BEBIDAS": {}, - "DE HABITACIONES": {}, - "OTROS": {} - }, - "EQUIPO DE OFICINA": { - "AJUSTES POR INFLACION": {}, - "EQUIPOS": { - "EQUIPOS": {} - }, - "MUEBLES Y ENSERES": { - "MUEBLES Y ENSERES": {} - }, - "OTROS": {} - }, - "EQUIPO MEDICO-CIENTIFICO": { - "AJUSTES POR INFLACION": {}, - "INSTRUMENTAL": {}, - "LABORATORIO": {}, - "MEDICO": {}, - "ODONTOLOGICO": {}, - "OTROS": {} - }, - "FLOTA Y EQUIPO AEREO": { - "AJUSTES POR INFLACION": {}, - "AVIONES": {}, - "AVIONETAS": {}, - "EQUIPOS DE VUELO": {}, - "HELICOPTEROS": {}, - "MANUALES DE ENTRENAMIENTO PERSONAL TECNICO": {}, - "OTROS": {}, - "TURBINAS Y MOTORES": {} - }, - "FLOTA Y EQUIPO DE TRANSPORTE": { - "AJUSTES POR INFLACION": {}, - "AUTOS, CAMIONETAS Y CAMPEROS": {}, - "BANDAS TRANSPORTADORAS": {}, - "BICICLETAS": {}, - "BUSES Y BUSETAS": {}, - "CAMIONES, VOLQUETAS Y FURGONES": {}, - "ESTIBAS Y CARRETAS": {}, - "MONTACARGAS": {}, - "MOTOCICLETAS": {}, - "OTROS": {}, - "PALAS Y GRUAS": {}, - "RECOLECTORES Y CONTENEDORES": {}, - "TRACTOMULAS Y REMOLQUES": {} - }, - "FLOTA Y EQUIPO FERREO": { - "AJUSTES POR INFLACION": {}, - "LOCOMOTORAS": {}, - "OTROS": {}, - "REDES FERREAS": {}, - "VAGONES": {} - }, - "FLOTA Y EQUIPO FLUVIAL Y/O MARITIMO": { - "AJUSTES POR INFLACION": {}, - "AMARRES": {}, - "BOTES": {}, - "BOYAS": {}, - "BUQUES": {}, - "CONTENEDORES Y CHASISES": {}, - "GABARRAS": {}, - "LANCHAS": {}, - "OTROS": {}, - "REMOLCADORAS": {} - }, - "MAQUINARIA Y EQUIPO": { - "AJUSTES POR INFLACION": {} - }, - "MAQUINARIA Y EQUIPOS EN MONTAJE": { - "AJUSTES POR INFLACION": {}, - "EQUIPO DE COMPUTACION Y COMUNICACION": {}, - "EQUIPO DE HOTELES Y RESTAURANTES": {}, - "EQUIPO DE OFICINA": {}, - "EQUIPO MEDICO-CIENTIFICO": {}, - "FLOTA Y EQUIPO AEREO": {}, - "FLOTA Y EQUIPO DE TRANSPORTE": {}, - "FLOTA Y EQUIPO FERREO": {}, - "FLOTA Y EQUIPO FLUVIAL Y/O MARITIMO": {}, - "MAQUINARIA Y EQUIPO": {}, - "PLANTAS Y REDES": {} - }, - "MATERIALES PROYECTOS PETROLEROS": { - "AJUSTES POR INFLACION": {}, - "COSTOS DE IMPORTACION MATERIALES": {}, - "PROYECTOS DE CONSTRUCCION": {}, - "TUBERIAS Y EQUIPO": {} - }, - "MINAS Y CANTERAS": { - "AJUSTES POR INFLACION": {}, - "CANTERAS": {}, - "MINAS": {} - }, - "PLANTACIONES AGRICOLAS Y FORESTALES": { - "AJUSTES POR INFLACION": {}, - "CULTIVOS AMORTIZABLES": {}, - "CULTIVOS EN DESARROLLO": {} - }, - "POZOS ARTESIANOS": { - "AJUSTES POR INFLACION": {} - }, - "PROPIEDADES, PLANTA Y EQUIPO EN TRANSITO": { - "AJUSTES POR INFLACION": {}, - "ARMAMENTO DE VIGILANCIA": {}, - "ENVASES Y EMPAQUES": {}, - "EQUIPO DE COMPUTACION Y COMUNICACION": {}, - "EQUIPO DE HOTELES Y RESTAURANTES": {}, - "EQUIPO DE OFICINA": {}, - "EQUIPO MEDICO-CIENTIFICO": {}, - "FLOTA Y EQUIPO AEREO": {}, - "FLOTA Y EQUIPO DE TRANSPORTE": {}, - "FLOTA Y EQUIPO FERREO": {}, - "FLOTA Y EQUIPO FLUVIAL Y/O MARITIMO": {}, - "MAQUINARIA Y EQUIPO": {}, - "PLANTAS Y REDES": {}, - "SEMOVIENTES": {} - }, - "PROVISIONES": { - "ACUEDUCTOS, PLANTAS Y REDES": {}, - "ARMAMENTO DE VIGILANCIA": {}, - "CONSTRUCCIONES EN CURSO": {}, - "CONSTRUCCIONES Y EDIFICACIONES": {}, - "ENVASES Y EMPAQUES": {}, - "EQUIPO DE COMPUTACION Y COMUNICACION": {}, - "EQUIPO DE HOTELES Y RESTAURANTES": {}, - "EQUIPO DE OFICINA": {}, - "EQUIPO MEDICO-CIENTIFICO": {}, - "FLOTA Y EQUIPO AEREO": {}, - "FLOTA Y EQUIPO DE TRANSPORTE": {}, - "FLOTA Y EQUIPO FERREO": {}, - "FLOTA Y EQUIPO FLUVIAL Y/O MARITIMO": {}, - "MAQUINARIA EN MONTAJE": {}, - "MAQUINARIA Y EQUIPO": {}, - "MATERIALES PROYECTOS PETROLEROS": {}, - "MINAS Y CANTERAS": {}, - "PLANTACIONES AGRICOLAS Y FORESTALES": {}, - "POZOS ARTESIANOS": {}, - "PROPIEDADES, PLANTA Y EQUIPO EN TRANSITO": {}, - "SEMOVIENTES": {}, - "TERRENOS": {}, - "VIAS DE COMUNICACION": {}, - "YACIMIENTOS": {} - }, - "SEMOVIENTES": { - "AJUSTES POR INFLACION": {} - }, - "TERRENOS": { - "AJUSTES POR INFLACION": {}, - "RURALES": {}, - "URBANOS": {} - }, - "VIAS DE COMUNICACION": { - "AERODROMOS": {}, - "AJUSTES POR INFLACION": {}, - "CALLES": {}, - "OTROS": {}, - "PAVIMENTACION Y PATIOS": {}, - "PUENTES": {}, - "VIAS": {} - }, - "YACIMIENTOS": { - "AJUSTES POR INFLACION": {} - } - }, - "VALORIZACIONES": { - "DE INVERSIONES": { - "ACCIONES": {}, - "CUOTAS O PARTES DE INTERES SOCIAL": {}, - "DERECHOS FIDUCIARIOS": {} - }, - "DE OTROS ACTIVOS": { - "BIENES DE ARTE Y CULTURA": {}, - "BIENES ENTREGADOS EN COMODATO": {}, - "BIENES RECIBIDOS EN PAGO": {}, - "INVENTARIO DE SEMOVIENTES": {} - }, - "DE PROPIEDADES, PLANTA Y EQUIPO": { - "ACUEDUCTOS, PLANTAS Y REDES": {}, - "ARMAMENTO DE VIGILANCIA": {}, - "CONSTRUCCIONES Y EDIFICACIONES": {}, - "ENVASES Y EMPAQUES": {}, - "EQUIPO DE COMPUTACION Y COMUNICACION": {}, - "EQUIPO DE HOTELES Y RESTAURANTES": {}, - "EQUIPO DE OFICINA": {}, - "EQUIPO MEDICO-CIENTIFICO": {}, - "FLOTA Y EQUIPO AEREO": {}, - "FLOTA Y EQUIPO DE TRANSPORTE": {}, - "FLOTA Y EQUIPO FERREO": {}, - "FLOTA Y EQUIPO FLUVIAL Y/O MARITIMO": {}, - "MAQUINARIA Y EQUIPO": {}, - "MATERIALES PROYECTOS PETROLEROS": {}, - "MINAS Y CANTERAS": {}, - "PLANTACIONES AGRICOLAS Y FORESTALES": {}, - "POZOS ARTESIANOS": {}, - "SEMOVIENTES": {}, - "TERRENOS": {}, - "VIAS DE COMUNICACION": {}, - "YACIMIENTOS": {} - } - }, - "root_type": "Asset" - }, - "COSTOS DE PRODUCCION O DE OPERACION": { - "CONTRATOS DE SERVICIOS": {}, - "COSTOS INDIRECTOS": {}, - "MANO DE OBRA DIRECTA": {}, - "MATERIA PRIMA": {}, - "root_type": "Expense" - }, - "COSTOS DE VENTAS": { - "COMPRAS": { - "COMPRA DE ENERGIA": { - "AJUSTES POR INFLACION": {} - }, - "DE MATERIALES INDIRECTOS": { - "AJUSTES POR INFLACION": {} - }, - "DE MATERIAS PRIMAS": { - "AJUSTES POR INFLACION": {} - }, - "DE MERCANCIAS": { - "AJUSTES POR INFLACION": {} - }, - "DEVOLUCIONES EN COMPRAS (CR)": { - "AJUSTES POR INFLACION": {} - } - }, - "COSTO DE VENTAS Y DE PRESTACION DE SERVICIOS": { - "ACTIVIDAD FINANCIERA": { - "AJUSTES POR INFLACION": {}, - "DE INVERSIONES": {}, - "DE SERVICIO DE BOLSA": {} - }, - "ACTIVIDADES INMOBILIARIAS, EMPRESARIALES Y DE ALQUILER": { - "ACTIVIDADES CONEXAS": {}, - "ACTIVIDADES EMPRESARIALES DE CONSULTORIA": {}, - "AJUSTES POR INFLACION": {}, - "ALQUILER DE EFECTOS PERSONALES Y ENSERES DOMESTICOS": {}, - "ALQUILER EQUIPO DE TRANSPORTE": {}, - "ALQUILER MAQUINARIA Y EQUIPO": {}, - "ARRENDAMIENTOS DE BIENES INMUEBLES": {}, - "CONSULTORIA EN EQUIPO Y PROGRAMAS DE INFORMATICA": {}, - "DOTACION DE PERSONAL": {}, - "ENVASE Y EMPAQUE": {}, - "FOTOCOPIADO": {}, - "FOTOGRAFIA": {}, - "INMOBILIARIAS POR RETRIBUCION O CONTRATA": {}, - "INVESTIGACION Y SEGURIDAD": {}, - "INVESTIGACIONES CIENTIFICAS Y DE DESARROLLO": {}, - "LIMPIEZA DE INMUEBLES": {}, - "MANTENIMIENTO Y REPARACION DE MAQUINARIA DE OFICINA": {}, - "MANTENIMIENTO Y REPARACION DE MAQUINARIA Y EQUIPO": {}, - "PROCESAMIENTO DE DATOS": {}, - "PUBLICIDAD": {} - }, - "AGRICULTURA, GANADERIA, CAZA Y SILVICULTURA": { - "ACTIVIDAD DE CAZA": {}, - "ACTIVIDAD DE SILVICULTURA": {}, - "ACTIVIDADES CONEXAS": {}, - "AJUSTES POR INFLACION": {}, - "CRIA DE GANADO CABALLAR Y VACUNO": {}, - "CRIA DE OTROS ANIMALES": {}, - "CRIA DE OVEJAS, CABRAS, ASNOS, MULAS Y BURDEGANOS": {}, - "CULTIVO DE ALGODON Y PLANTAS PARA MATERIAL TEXTIL": {}, - "CULTIVO DE BANANO": {}, - "CULTIVO DE CAFE": {}, - "CULTIVO DE CANA DE AZUCAR": {}, - "CULTIVO DE CEREALES": {}, - "CULTIVO DE FLORES": {}, - "CULTIVOS DE FRUTAS, NUECES Y PLANTAS AROMATICAS": {}, - "CULTIVOS DE HORTALIZAS, LEGUMBRES Y PLANTAS ORNAMENTALES": {}, - "OTROS CULTIVOS AGRICOLAS": {}, - "PRODUCCION AVICOLA": {}, - "SERVICIOS AGRICOLAS Y GANADEROS": {} - }, - "COMERCIO AL POR MAYOR Y AL POR MENOR": { - "AJUSTES POR INFLACION": {}, - "MANTENIMIENTO, REPARACION Y LAVADO DE VEHICULOS AUTOMOTORES": {}, - "REPARACION DE EFECTOS PERSONALES Y ELECTRODOMESTICOS": {}, - "VENTA A CAMBIO DE RETRIBUCION O POR CONTRATA": {}, - "VENTA DE ANIMALES VIVOS Y CUEROS": {}, - "VENTA DE ARTICULOS EN CACHARRERIAS Y MISCELANEAS": {}, - "VENTA DE ARTICULOS EN CASAS DE EMPENO Y PRENDERIAS": {}, - "VENTA DE ARTICULOS EN RELOJERIAS Y JOYERIAS": {}, - "VENTA DE COMBUSTIBLES SOLIDOS, LIQUIDOS, GASEOSOS": {}, - "VENTA DE CUBIERTOS, VAJILLAS, CRISTALERIA, PORCELANAS, CERAMICAS Y OTROS ARTICULOS DE USO DOMESTICO": {}, - "VENTA DE ELECTRODOMESTICOS Y MUEBLES": {}, - "VENTA DE EMPAQUES": {}, - "VENTA DE EQUIPO FOTOGRAFICO": {}, - "VENTA DE EQUIPO OPTICO Y DE PRECISION": {}, - "VENTA DE EQUIPO PROFESIONAL Y CIENTIFICO": {}, - "VENTA DE HERRAMIENTAS Y ARTICULOS DE FERRETERIA": {}, - "VENTA DE INSTRUMENTOS MUSICALES": {}, - "VENTA DE INSTRUMENTOS QUIRURGICOS Y ORTOPEDICOS": {}, - "VENTA DE INSUMOS, MATERIAS PRIMAS AGROPECUARIAS Y FLORES": {}, - "VENTA DE JUEGOS, JUGUETES Y ARTICULOS DEPORTIVOS": {}, - "VENTA DE LIBROS, REVISTAS, ELEMENTOS DE PAPELERIA, UTILES Y TEXTOS ESCOLARES": {}, - "VENTA DE LOTERIAS, RIFAS, CHANCE, APUESTAS Y SIMILARES": {}, - "VENTA DE LUBRICANTES, ADITIVOS, LLANTAS Y LUJOS PARA AUTOMOTORES": {}, - "VENTA DE MAQUINARIA, EQUIPO DE OFICINA Y PROGRAMAS DE COMPUTADOR": {}, - "VENTA DE MATERIALES DE CONSTRUCCION, FONTANERIA Y CALEFACCION": {}, - "VENTA DE OTROS INSUMOS Y MATERIAS PRIMAS NO AGROPECUARIAS": {}, - "VENTA DE OTROS PRODUCTOS": {}, - "VENTA DE PAPEL Y CARTON": {}, - "VENTA DE PARTES, PIEZAS Y ACCESORIOS DE VEHICULOS AUTOMOTORES": {}, - "VENTA DE PINTURAS Y LACAS": {}, - "VENTA DE PRODUCTOS AGROPECUARIOS": {}, - "VENTA DE PRODUCTOS DE ASEO, FARMACEUTICOS, MEDICINALES Y ARTICULOS DE TOCADOR": {}, - "VENTA DE PRODUCTOS DE VIDRIOS Y MARQUETERIA": {}, - "VENTA DE PRODUCTOS EN ALMACENES NO ESPECIALIZADOS": {}, - "VENTA DE PRODUCTOS INTERMEDIOS, DESPERDICIOS Y DESECHOS": {}, - "VENTA DE PRODUCTOS TEXTILES, DE VESTIR, DE CUERO Y CALZADO": {}, - "VENTA DE QUIMICOS": {}, - "VENTA DE VEHICULOS AUTOMOTORES": {} - }, - "CONSTRUCCION": { - "ACONDICIONAMIENTO DE EDIFICIOS": {}, - "ACTIVIDADES CONEXAS": {}, - "AJUSTES POR INFLACION": {}, - "ALQUILER DE EQUIPO CON OPERARIO": {}, - "CONSTRUCCION DE EDIFICIOS Y OBRAS DE INGENIERIA CIVIL": {}, - "PREPARACION DE TERRENOS": {}, - "TERMINACION DE EDIFICACIONES": {} - }, - "ENSENANZA": { - "ACTIVIDADES CONEXAS": {}, - "ACTIVIDADES RELACIONADAS CON LA EDUCACION": {}, - "AJUSTES POR INFLACION": {} - }, - "EXPLOTACION DE MINAS Y CANTERAS": { - "ACTIVIDADES CONEXAS": {}, - "AJUSTES POR INFLACION": {}, - "CARBON": {}, - "GAS NATURAL": {}, - "MINERALES DE HIERRO": {}, - "MINERALES METALIFEROS NO FERROSOS": {}, - "ORO": {}, - "OTRAS MINAS Y CANTERAS": {}, - "PETROLEO CRUDO": {}, - "PIEDRA, ARENA Y ARCILLA": {}, - "PIEDRAS PRECIOSAS": {}, - "PRESTACION DE SERVICIOS SECTOR MINERO": {}, - "SERVICIOS RELACIONADOS CON EXTRACCION DE PETROLEO Y GAS": {} - }, - "HOTELES Y RESTAURANTES": { - "ACTIVIDADES CONEXAS": {}, - "AJUSTES POR INFLACION": {}, - "BARES Y CANTINAS": {}, - "CAMPAMENTO Y OTROS TIPOS DE HOSPEDAJE": {}, - "HOTELERIA": {}, - "RESTAURANTES": {} - }, - "INDUSTRIAS MANUFACTURERAS": { - "ACABADO DE PRODUCTOS TEXTILES": {}, - "AJUSTES POR INFLACION": {}, - "CORTE, TALLADO Y ACABADO DE LA PIEDRA": {}, - "CURTIDO, ADOBO O PREPARACION DE CUERO": {}, - "EDICIONES Y PUBLICACIONES": {}, - "ELABORACION DE ABONOS Y COMPUESTOS DE NITROGENO": {}, - "ELABORACION DE ACEITES Y GRASAS": {}, - "ELABORACION DE ALIMENTOS PARA ANIMALES": {}, - "ELABORACION DE ALMIDONES Y DERIVADOS": {}, - "ELABORACION DE APARATOS DE USO DOMESTICO": {}, - "ELABORACION DE ARTICULOS DE HORMIGON, CEMENTO Y YESO": {}, - "ELABORACION DE ARTICULOS DE MATERIALES TEXTILES": {}, - "ELABORACION DE AZUCAR Y MELAZAS": {}, - "ELABORACION DE BEBIDAS ALCOHOLICAS Y ALCOHOL ETILICO": {}, - "ELABORACION DE BEBIDAS MALTEADAS Y DE MALTA": {}, - "ELABORACION DE BEBIDAS NO ALCOHOLICAS": {}, - "ELABORACION DE CACAO, CHOCOLATE Y CONFITERIA": {}, - "ELABORACION DE CALZADO": {}, - "ELABORACION DE CEMENTO, CAL Y YESO": {}, - "ELABORACION DE CUERDAS, CORDELES, BRAMANTES Y REDES": {}, - "ELABORACION DE EQUIPO DE ILUMINACION": {}, - "ELABORACION DE EQUIPO DE OFICINA": {}, - "ELABORACION DE FIBRAS": {}, - "ELABORACION DE JABONES, DETERGENTES Y PREPARADOS DE TOCADOR": {}, - "ELABORACION DE MALETAS, BOLSOS Y SIMILARES": {}, - "ELABORACION DE OTROS PRODUCTOS ALIMENTICIOS": {}, - "ELABORACION DE OTROS PRODUCTOS DE CAUCHO": {}, - "ELABORACION DE OTROS PRODUCTOS DE METAL": {}, - "ELABORACION DE OTROS PRODUCTOS MINERALES NO METALICOS": {}, - "ELABORACION DE OTROS PRODUCTOS QUIMICOS": {}, - "ELABORACION DE OTROS PRODUCTOS TEXTILES": {}, - "ELABORACION DE OTROS TIPOS DE EQUIPO ELECTRICO": {}, - "ELABORACION DE PASTA Y PRODUCTOS DE MADERA, PAPEL Y CARTON": {}, - "ELABORACION DE PASTAS Y PRODUCTOS FARINACEOS": {}, - "ELABORACION DE PILAS Y BATERIAS PRIMARIAS": {}, - "ELABORACION DE PINTURAS, TINTAS Y MASILLAS": {}, - "ELABORACION DE PLASTICO Y CAUCHO SINTETICO": {}, - "ELABORACION DE PRENDAS DE VESTIR": {}, - "ELABORACION DE PRODUCTOS DE CAFE": {}, - "ELABORACION DE PRODUCTOS DE CERAMICA, LOZA, PIEDRA, ARCILLA Y PORCELANA": {}, - "ELABORACION DE PRODUCTOS DE HORNO DE COQUE": {}, - "ELABORACION DE PRODUCTOS DE LA REFINACION DE PETROLEO": {}, - "ELABORACION DE PRODUCTOS DE MOLINERIA": {}, - "ELABORACION DE PRODUCTOS DE PLASTICO": {}, - "ELABORACION DE PRODUCTOS DE TABACO": {}, - "ELABORACION DE PRODUCTOS FARMACEUTICOS Y BOTANICOS": {}, - "ELABORACION DE PRODUCTOS LACTEOS": {}, - "ELABORACION DE PRODUCTOS PARA PANADERIA": {}, - "ELABORACION DE PRODUCTOS QUIMICOS DE USO AGROPECUARIO": {}, - "ELABORACION DE SUSTANCIAS QUIMICAS BASICAS": {}, - "ELABORACION DE TAPICES Y ALFOMBRAS": {}, - "ELABORACION DE TEJIDOS": {}, - "ELABORACION DE VIDRIO Y PRODUCTOS DE VIDRIO": {}, - "ELABORACION DE VINOS": {}, - "FABRICACION DE AERONAVES": {}, - "FABRICACION DE APARATOS E INSTRUMENTOS MEDICOS": {}, - "FABRICACION DE ARTICULOS DE FERRETERIA": {}, - "FABRICACION DE ARTICULOS Y EQUIPO PARA DEPORTE": {}, - "FABRICACION DE BICICLETAS Y SILLAS DE RUEDAS": {}, - "FABRICACION DE CARROCERIAS PARA AUTOMOTORES": {}, - "FABRICACION DE EQUIPOS DE ELEVACION Y MANIPULACION": {}, - "FABRICACION DE EQUIPOS DE RADIO, TELEVISION Y COMUNICACIONES": {}, - "FABRICACION DE INSTRUMENTOS DE MEDICION Y CONTROL": {}, - "FABRICACION DE INSTRUMENTOS DE MUSICA": {}, - "FABRICACION DE INSTRUMENTOS DE OPTICA Y EQUIPO FOTOGRAFICO": {}, - "FABRICACION DE JOYAS Y ARTICULOS CONEXOS": {}, - "FABRICACION DE JUEGOS Y JUGUETES": {}, - "FABRICACION DE LOCOMOTORAS Y MATERIAL RODANTE PARA FERROCARRILES": {}, - "FABRICACION DE MAQUINARIA Y EQUIPO": {}, - "FABRICACION DE MOTOCICLETAS": {}, - "FABRICACION DE MUEBLES": {}, - "FABRICACION DE OTROS TIPOS DE TRANSPORTE": {}, - "FABRICACION DE PARTES, PIEZAS Y ACCESORIOS PARA AUTOMOTORES": {}, - "FABRICACION DE PRODUCTOS METALICOS PARA USO ESTRUCTURAL": {}, - "FABRICACION DE RELOJES": {}, - "FABRICACION DE VEHICULOS AUTOMOTORES": {}, - "FABRICACION Y REPARACION DE BUQUES Y OTRAS EMBARCACIONES": {}, - "FORJA, PRENSADO, ESTAMPADO, LAMINADO DE METAL Y PULVIMETALURGIA": {}, - "FUNDICION DE METALES NO FERROSOS": {}, - "IMPRESION": {}, - "INDUSTRIAS BASICAS Y FUNDICION DE HIERRO Y ACERO": {}, - "PREPARACION E HILATURA DE FIBRAS TEXTILES Y TEJEDURIA": {}, - "PREPARACION, ADOBO Y TENIDO DE PIELES": {}, - "PRODUCCION DE MADERA, ARTICULOS DE MADERA Y CORCHO": {}, - "PRODUCCION Y PROCESAMIENTO DE CARNES Y PRODUCTOS CARNICOS": {}, - "PRODUCTOS DE FRUTAS, LEGUMBRES Y HORTALIZAS": {}, - "PRODUCTOS DE OTRAS INDUSTRIAS MANUFACTURERAS": {}, - "PRODUCTOS DE PESCADO": {}, - "PRODUCTOS PRIMARIOS DE METALES PRECIOSOS Y DE METALES NO FERROSOS": {}, - "RECICLAMIENTO DE DESPERDICIOS": {}, - "REPRODUCCION DE GRABACIONES": {}, - "REVESTIMIENTO DE METALES Y OBRAS DE INGENIERIA MECANICA": {}, - "SERVICIOS RELACIONADOS CON LA EDICION Y LA IMPRESION": {} - }, - "OTRAS ACTIVIDADES DE SERVICIOS COMUNITARIOS, SOCIALES Y PERSONALES": { - "ACTIVIDAD DE RADIO Y TELEVISION": {}, - "ACTIVIDAD TEATRAL, MUSICAL Y ARTISTICA": {}, - "ACTIVIDADES CONEXAS": {}, - "ACTIVIDADES DE ASOCIACION": {}, - "AGENCIAS DE NOTICIAS": {}, - "AJUSTES POR INFLACION": {}, - "ELIMINACION DE DESPERDICIOS Y AGUAS RESIDUALES": {}, - "ENTRETENIMIENTO Y ESPARCIMIENTO": {}, - "EXHIBICION DE FILMES Y VIDEOCINTAS": {}, - "GRABACION Y PRODUCCION DE DISCOS": {}, - "LAVANDERIAS Y SIMILARES": {}, - "PELUQUERIAS Y SIMILARES": {}, - "PRODUCCION Y DISTRIBUCION DE FILMES Y VIDEOCINTAS": {}, - "SERVICIOS FUNERARIOS": {}, - "ZONAS FRANCAS": {} - }, - "PESCA": { - "ACTIVIDAD DE PESCA": {}, - "ACTIVIDADES CONEXAS": {}, - "AJUSTES POR INFLACION": {}, - "EXPLOTACION DE CRIADEROS DE PECES": {} - }, - "SERVICIOS SOCIALES Y DE SALUD": { - "ACTIVIDADES CONEXAS": {}, - "ACTIVIDADES DE SERVICIOS SOCIALES": {}, - "ACTIVIDADES VETERINARIAS": {}, - "AJUSTES POR INFLACION": {}, - "SERVICIO DE LABORATORIO": {}, - "SERVICIO HOSPITALARIO": {}, - "SERVICIO MEDICO": {}, - "SERVICIO ODONTOLOGICO": {} - }, - "SUMINISTRO DE ELECTRICIDAD, GAS Y AGUA": { - "ACTIVIDADES CONEXAS": {}, - "AJUSTES POR INFLACION": {}, - "CAPTACION, DEPURACION Y DISTRIBUCION DE AGUA": {}, - "FABRICACION DE GAS Y DISTRIBUCION DE COMBUSTIBLES GASEOSOS": {}, - "GENERACION, CAPTACION Y DISTRIBUCION DE ENERGIA ELECTRICA": {} - }, - "TRANSPORTE, ALMACENAMIENTO Y COMUNICACIONES": { - "ACTIVIDADES CONEXAS": {}, - "AGENCIAS DE VIAJE": {}, - "AJUSTES POR INFLACION": {}, - "ALMACENAMIENTO Y DEPOSITO": {}, - "MANIPULACION DE CARGA": {}, - "OTRAS AGENCIAS DE TRANSPORTE": {}, - "SERVICIO DE RADIO Y TELEVISION POR CABLE": {}, - "SERVICIO DE TELEGRAFO": {}, - "SERVICIO DE TRANSMISION DE DATOS": {}, - "SERVICIO DE TRANSPORTE POR CARRETERA": {}, - "SERVICIO DE TRANSPORTE POR TUBERIAS": {}, - "SERVICIO DE TRANSPORTE POR VIA ACUATICA": { - "SERVICIO DE TRANSPORTE POR VIA ACUATICA": {} - }, - "SERVICIO DE TRANSPORTE POR VIA AEREA": {}, - "SERVICIO DE TRANSPORTE POR VIA FERREA": {}, - "SERVICIO POSTAL Y DE CORREO": {}, - "SERVICIO TELEFONICO": {}, - "SERVICIOS COMPLEMENTARIOS PARA EL TRANSPORTE": {}, - "TRANSMISION DE SONIDO E IMAGENES POR CONTRATO": {} - } - }, - "root_type": "Expense" - }, - "CUENTAS DE ORDEN ACREEDORAS": { - "ACREEDORAS DE CONTROL": { - "AJUSTES POR INFLACION PATRIMONIO": { - "CAPITAL SOCIAL": {}, - "DIVIDENDOS O PARTICIPACIONES DECRETADAS EN ACCIONES, CUOTAS O PARTES DE INTERES SOCIAL": {}, - "RESERVAS": {}, - "RESULTADOS DE EJERCICIOS ANTERIORES": {}, - "SUPERAVIT DE CAPITAL": {} - }, - "CONTRATOS DE ARRENDAMIENTO FINANCIERO": { - "BIENES INMUEBLES": {}, - "BIENES MUEBLES": {} - }, - "OTRAS CUENTAS DE ORDEN ACREEDORAS DE CONTROL": { - "ADJUDICACIONES PENDIENTES DE LEGALIZAR": {}, - "AJUSTES POR INFLACION": {}, - "CONTRATOS DE CONSTRUCCIONES E INSTALACIONES POR EJECUTAR": {}, - "CONVENIOS DE PAGO": {}, - "DIVERSAS": {}, - "DOCUMENTOS POR COBRAR DESCONTADOS": {}, - "RESERVA ARTICULO 3\u00ba LEY 4\u00aa DE 1980": {}, - "RESERVA COSTO REPOSICION SEMOVIENTES": {} - } - }, - "ACREEDORAS DE CONTROL POR CONTRA (DB)": {}, - "ACREEDORAS FISCALES": {}, - "ACREEDORAS FISCALES POR CONTRA (DB)": {}, - "RESPONSABILIDADES CONTINGENTES": { - "BIENES Y VALORES RECIBIDOS DE TERCEROS": { - "AJUSTES POR INFLACION": {}, - "EN ARRENDAMIENTO": {}, - "EN COMODATO": {}, - "EN CONSIGNACION": {}, - "EN DEPOSITO": {}, - "EN PRESTAMO": {} - }, - "BIENES Y VALORES RECIBIDOS EN CUSTODIA": { - "AJUSTES POR INFLACION": {}, - "BIENES MUEBLES": {}, - "VALORES MOBILIARIOS": {} - }, - "BIENES Y VALORES RECIBIDOS EN GARANTIA": { - "AJUSTES POR INFLACION": {}, - "BIENES INMUEBLES": {}, - "BIENES MUEBLES": {}, - "CONTRATOS DE GANADO EN PARTICIPACION": {}, - "VALORES MOBILIARIOS": {} - }, - "CONTRATOS DE ADMINISTRACION DELEGADA": {}, - "CUENTAS EN PARTICIPACION": {}, - "LITIGIOS Y/O DEMANDAS": { - "ADMINISTRATIVOS O ARBITRALES": {}, - "CIVILES": {}, - "LABORALES": {}, - "TRIBUTARIOS": {} - }, - "OTRAS RESPONSABILIDADES CONTINGENTES": {}, - "PROMESAS DE COMPRAVENTA": {} - }, - "RESPONSABILIDADES CONTINGENTES POR CONTRA (DB)": {}, - "root_type": "Liability" - }, - "CUENTAS DE ORDEN DEUDORAS": { - "DERECHOS CONTINGENTES": { - "BIENES Y VALORES EN PODER DE TERCEROS": { - "AJUSTES POR INFLACION": {}, - "EN ARRENDAMIENTO": {}, - "EN CONSIGNACION": {}, - "EN DEPOSITO": {}, - "EN PRESTAMO": {} - }, - "BIENES Y VALORES ENTREGADOS EN CUSTODIA": { - "AJUSTES POR INFLACION": {}, - "BIENES MUEBLES": {}, - "VALORES MOBILIARIOS": {} - }, - "BIENES Y VALORES ENTREGADOS EN GARANTIA": { - "AJUSTES POR INFLACION": {}, - "BIENES INMUEBLES": {}, - "BIENES MUEBLES": {}, - "CONTRATOS DE GANADO EN PARTICIPACION": {}, - "VALORES MOBILIARIOS": {} - }, - "DIVERSAS": { - "AJUSTES POR INFLACION": {}, - "OTRAS": {}, - "VALORES ADQUIRIDOS POR RECIBIR": {} - }, - "LITIGIOS Y/O DEMANDAS": { - "EJECUTIVOS": {}, - "INCUMPLIMIENTO DE CONTRATOS": {} - }, - "PROMESAS DE COMPRAVENTA": {} - }, - "DERECHOS CONTINGENTES POR CONTRA (CR)": {}, - "DEUDORAS DE CONTROL": { - "ACTIVOS CASTIGADOS": { - "DEUDORES": {}, - "INVERSIONES": {}, - "OTROS ACTIVOS": {} - }, - "AJUSTES POR INFLACION ACTIVOS": { - "CARGOS DIFERIDOS": {}, - "INTANGIBLES": {}, - "INVENTARIOS": {}, - "INVERSIONES": {}, - "OTROS ACTIVOS": {}, - "PROPIEDADES, PLANTA Y EQUIPO": {} - }, - "BIENES RECIBIDOS EN ARRENDAMIENTO FINANCIERO": { - "AJUSTES POR INFLACION": {}, - "BIENES INMUEBLES": {}, - "BIENES MUEBLES": {} - }, - "CAPITALIZACION POR REVALORIZACION DE PATRIMONIO": {}, - "CREDITOS A FAVOR NO UTILIZADOS": { - "EXTERIOR": {}, - "PAIS": {} - }, - "OTRAS CUENTAS DEUDORAS DE CONTROL": { - "AJUSTES POR INFLACION": {}, - "BIENES Y VALORES EN FIDEICOMISO": {}, - "CERTIFICADOS DE DEPOSITO A TERMINO": {}, - "CHEQUES DEVUELTOS": {}, - "CHEQUES POSFECHADOS": {}, - "DIVERSAS": {}, - "INTERESES SOBRE DEUDAS VENCIDAS": {} - }, - "PROPIEDADES, PLANTA Y EQUIPO TOTALMENTE DEPRECIADOS, AGOTADOS Y/O AMORTIZADOS": { - "ACUEDUCTOS, PLANTAS Y REDES": {}, - "AJUSTES POR INFLACION": {}, - "ARMAMENTO DE VIGILANCIA": {}, - "CONSTRUCCIONES Y EDIFICACIONES": {}, - "ENVASES Y EMPAQUES": {}, - "EQUIPO DE COMPUTACION Y COMUNICACION": {}, - "EQUIPO DE HOTELES Y RESTAURANTES": {}, - "EQUIPO DE OFICINA": {}, - "EQUIPO MEDICO-CIENTIFICO": {}, - "FLOTA Y EQUIPO AEREO": {}, - "FLOTA Y EQUIPO DE TRANSPORTE": {}, - "FLOTA Y EQUIPO FERREO": {}, - "FLOTA Y EQUIPO FLUVIAL Y/O MARITIMO": {}, - "MAQUINARIA Y EQUIPO": {}, - "MATERIALES PROYECTOS PETROLEROS": {}, - "MINAS Y CANTERAS": {}, - "PLANTACIONES AGRICOLAS Y FORESTALES": {}, - "POZOS ARTESIANOS": {}, - "SEMOVIENTES": {}, - "VIAS DE COMUNICACION": {}, - "YACIMIENTOS": {} - }, - "TITULOS DE INVERSION AMORTIZADOS": { - "BONOS": {}, - "OTROS": {} - }, - "TITULOS DE INVERSION NO COLOCADOS": { - "ACCIONES": {}, - "BONOS": {}, - "OTROS": {} - } - }, - "DEUDORAS DE CONTROL POR CONTRA (CR)": {}, - "DEUDORAS FISCALES": {}, - "DEUDORAS FISCALES POR CONTRA (CR)": {}, - "root_type": "Asset" - }, - "GASTOS": { - "GANANCIAS Y PERDIDAS": { - "GANANCIAS Y PERDIDAS": { - "GANANCIAS Y PERDIDAS": {} - } - }, - "IMPUESTO DE RENTA Y COMPLEMENTARIOS": { - "IMPUESTO DE RENTA Y COMPLEMENTARIOS": { - "IMPUESTO DE RENTA Y COMPLEMENTARIOS": {} - } - }, - "NO OPERACIONALES": { - "FINANCIEROS": { - "AJUSTES POR INFLACION": {}, - "COMISIONES": {}, - "DESCUENTOS COMERCIALES CONDICIONADOS": {}, - "DIFERENCIA EN CAMBIO": {}, - "GASTOS BANCARIOS": {}, - "GASTOS EN NEGOCIACION CERTIFICADOS DE CAMBIO": {}, - "GASTOS MANEJO Y EMISION DE BONOS": {}, - "INTERESES": {}, - "OTROS": {}, - "PRIMA AMORTIZADA": {}, - "REAJUSTE MONETARIO-UPAC (HOY UVR)": {} - }, - "GASTOS DIVERSOS": { - "AJUSTES POR INFLACION": {}, - "AMORTIZACION DE BIENES ENTREGADOS EN COMODATO": {}, - "CONSTITUCION DE GARANTIAS": {}, - "DEMANDAS LABORALES": {}, - "DEMANDAS POR INCUMPLIMIENTO DE CONTRATOS": {}, - "DONACIONES": {}, - "INDEMNIZACIONES": {}, - "MULTAS, SANCIONES Y LITIGIOS": {}, - "OTROS": { - "OTROS": {} - } - }, - "GASTOS EXTRAORDINARIOS": { - "ACTIVIDADES CULTURALES Y CIVICAS": {}, - "AJUSTES POR INFLACION": {}, - "COSTAS Y PROCESOS JUDICIALES": {}, - "COSTOS Y GASTOS DE EJERCICIOS ANTERIORES": {}, - "IMPUESTOS ASUMIDOS": {}, - "OTROS": {} - }, - "PERDIDA EN VENTA Y RETIRO DE BIENES": { - "AJUSTES POR INFLACION": {}, - "OTROS": {}, - "PERDIDAS POR SINIESTROS": {}, - "RETIRO DE OTROS ACTIVOS": {}, - "RETIRO DE PROPIEDADES, PLANTA Y EQUIPO": {}, - "VENTA DE CARTERA": {}, - "VENTA DE INTANGIBLES": {}, - "VENTA DE INVERSIONES": {}, - "VENTA DE OTROS ACTIVOS": {}, - "VENTA DE PROPIEDADES, PLANTA Y EQUIPO": {} - }, - "PERDIDAS METODO DE PARTICIPACION": { - "DE SOCIEDADES ANONIMAS Y/O ASIMILADAS": {}, - "DE SOCIEDADES LIMITADAS Y/O ASIMILADAS": {} - } - }, - "OPERACIONALES DE ADMINISTRACION": { - "ADECUACION E INSTALACION": { - "AJUSTES POR INFLACION": {}, - "ARREGLOS ORNAMENTALES": {}, - "INSTALACIONES ELECTRICAS": {}, - "OTROS": { - "OTROS": {} - }, - "REPARACIONES LOCATIVAS": { - "REPARACIONES LOCATIVAS": {} - } - }, - "AMORTIZACIONES": { - "AJUSTES POR INFLACION": {}, - "CARGOS DIFERIDOS": {}, - "INTANGIBLES": {}, - "OTRAS": {}, - "VIAS DE COMUNICACION": {} - }, - "ARRENDAMIENTOS": { - "ACUEDUCTOS, PLANTAS Y REDES": {}, - "AERODROMOS": {}, - "AJUSTES POR INFLACION": {}, - "CONSTRUCCIONES Y EDIFICACIONES": { - "CONSTRUCCIONES Y EDIFICACIONES": {} - }, - "EQUIPO DE COMPUTACION Y COMUNICACION": {}, - "EQUIPO DE HOTELES Y RESTAURANTES": {}, - "EQUIPO DE OFICINA": {}, - "EQUIPO MEDICO-CIENTIFICO": {}, - "FLOTA Y EQUIPO AEREO": {}, - "FLOTA Y EQUIPO DE TRANSPORTE": {}, - "FLOTA Y EQUIPO FERREO": {}, - "FLOTA Y EQUIPO FLUVIAL Y/O MARITIMO": {}, - "MAQUINARIA Y EQUIPO": {}, - "OTROS": {}, - "SEMOVIENTES": {}, - "TERRENOS": {} - }, - "CONTRIBUCIONES Y AFILIACIONES": { - "AFILIACIONES Y SOSTENIMIENTO": {}, - "AJUSTES POR INFLACION": {}, - "CONTRIBUCIONES": {} - }, - "DEPRECIACIONES": { - "ACUEDUCTOS, PLANTAS Y REDES": {}, - "AJUSTES POR INFLACION": {}, - "ARMAMENTO DE VIGILANCIA": {}, - "CONSTRUCCIONES Y EDIFICACIONES": {}, - "EQUIPO DE COMPUTACION Y COMUNICACION": {}, - "EQUIPO DE HOTELES Y RESTAURANTES": {}, - "EQUIPO DE OFICINA": {}, - "EQUIPO MEDICO-CIENTIFICO": {}, - "FLOTA Y EQUIPO AEREO": {}, - "FLOTA Y EQUIPO DE TRANSPORTE": {}, - "FLOTA Y EQUIPO FERREO": {}, - "FLOTA Y EQUIPO FLUVIAL Y/O MARITIMO": {}, - "MAQUINARIA Y EQUIPO": {} - }, - "DIVERSOS": { - "AJUSTES POR INFLACION": {}, - "CASINO Y RESTAURANTE": {}, - "COMBUSTIBLES Y LUBRICANTES": {}, - "COMISIONES": { - "COMISIONES": {} - }, - "ELEMENTOS DE ASEO Y CAFETERIA": { - "ELEMENTOS DE ASEO Y CAFETERIA": {} - }, - "ENVASES Y EMPAQUES": {}, - "ESTAMPILLAS": {}, - "GASTOS DE REPRESENTACION Y RELACIONES PUBLICAS": {}, - "INDEMNIZACION POR DANOS A TERCEROS": {}, - "LIBROS, SUSCRIPCIONES, PERIODICOS Y REVISTAS": { - "LIBROS, SUSCRIPCIONES, PERIODICOS Y REVISTAS": {} - }, - "MICROFILMACION": {}, - "MUSICA AMBIENTAL": {}, - "OTROS": { - "OTROS": {} - }, - "PARQUEADEROS": {}, - "POLVORA Y SIMILARES": {}, - "TAXIS Y BUSES": {}, - "UTILES, PAPELERIA Y FOTOCOPIAS": { - "UTILES, PAPELERIA Y FOTOCOPIAS": {} - } - }, - "GASTOS DE PERSONAL": { - "AJUSTES POR INFLACION": {}, - "AMORTIZACION BONOS PENSIONALES": {}, - "AMORTIZACION CALCULO ACTUARIAL PENSIONES DE JUBILACION": {}, - "AMORTIZACION TITULOS PENSIONALES": {}, - "APORTES A ADMINISTRADORAS DE RIESGOS PROFESIONALES, ARP": {}, - "APORTES A ENTIDADES PROMOTORAS DE SALUD, EPS": {}, - "APORTES A FONDOS DE PENSIONES Y/O CESANTIAS": {}, - "APORTES CAJAS DE COMPENSACION FAMILIAR": {}, - "APORTES ICBF": {}, - "APORTES SINDICALES": {}, - "AUXILIO DE TRANSPORTE": { - "EMPLEADOS": {} - }, - "AUXILIOS": {}, - "BONIFICACIONES": {}, - "CAPACITACION AL PERSONAL": {}, - "CESANTIAS": { - "EMPLEADOS": {} - }, - "COMISIONES": {}, - "CUOTAS PARTES PENSIONES DE JUBILACION": {}, - "DOTACION Y SUMINISTRO A TRABAJADORES": {}, - "GASTOS DEPORTIVOS Y DE RECREACION": {}, - "GASTOS MEDICOS Y DROGAS": {}, - "HORAS EXTRAS Y RECARGOS": {}, - "INCAPACIDADES": {}, - "INDEMNIZACIONES LABORALES": {}, - "INTERESES SOBRE CESANTIAS": { - "EMPLEADOS": {} - }, - "JORNALES": {}, - "OTROS": {}, - "PENSIONES DE JUBILACION": {}, - "PRIMA DE SERVICIOS": { - "EMPLEADOS": {} - }, - "PRIMAS EXTRALEGALES": {}, - "SALARIO INTEGRAL": {}, - "SEGUROS": {}, - "SENA": {}, - "SUELDOS": { - "EMPLEADOS": {} - }, - "VACACIONES": { - "EMPLEADOS": {} - }, - "VIATICOS": {} - }, - "GASTOS DE VIAJE": { - "AJUSTES POR INFLACION": {}, - "ALOJAMIENTO Y MANUTENCION": {}, - "OTROS": {}, - "PASAJES AEREOS": {}, - "PASAJES FERREOS": {}, - "PASAJES FLUVIALES Y/O MARITIMOS": {}, - "PASAJES TERRESTRES": {} - }, - "GASTOS LEGALES": { - "ADUANEROS": {}, - "AJUSTES POR INFLACION": {}, - "CONSULARES": {}, - "NOTARIALES": { - "NOTARIALES": {} - }, - "OTROS": {}, - "REGISTRO MERCANTIL": { - "REGISTRO MERCANTIL": {} - }, - "TRAMITES Y LICENCIAS": {} - }, - "HONORARIOS": { - "AJUSTES POR INFLACION": {}, - "ASESORIA FINANCIERA": {}, - "ASESORIA JURIDICA": { - "ASESORIA JURIDICA": {} - }, - "ASESORIA TECNICA": {}, - "AUDITORIA EXTERNA": {}, - "AVALUOS": {}, - "JUNTA DIRECTIVA": {}, - "OTROS": {}, - "REVISORIA FISCAL": {} - }, - "IMPUESTOS": { - "A LA PROPIEDAD RAIZ": {}, - "AJUSTES POR INFLACION": {}, - "CUOTAS DE FOMENTO": { - "GRAVAMEN MOVIMIENTOS FINANCIEROS": {} - }, - "DE ESPECTACULOS PUBLICOS": {}, - "DE TIMBRES": {}, - "DE TURISMO": {}, - "DE VALORIZACION": {}, - "DE VEHICULOS": {}, - "DERECHOS SOBRE INSTRUMENTOS PUBLICOS": {}, - "INDUSTRIA Y COMERCIO": {}, - "IVA DESCONTABLE": {}, - "OTROS": {}, - "TASA POR UTILIZACION DE PUERTOS": {} - }, - "MANTENIMIENTO Y REPARACIONES": { - "ACUEDUCTOS, PLANTAS Y REDES": {}, - "AJUSTES POR INFLACION": {}, - "ARMAMENTO DE VIGILANCIA": {}, - "CONSTRUCCIONES Y EDIFICACIONES": { - "CONSTRUCCIONES Y EDIFICACIONES": {} - }, - "EQUIPO DE COMPUTACION Y COMUNICACION": {}, - "EQUIPO DE HOTELES Y RESTAURANTES": {}, - "EQUIPO DE OFICINA": {}, - "EQUIPO MEDICO-CIENTIFICO": {}, - "FLOTA Y EQUIPO AEREO": {}, - "FLOTA Y EQUIPO DE TRANSPORTE": {}, - "FLOTA Y EQUIPO FERREO": {}, - "FLOTA Y EQUIPO FLUVIAL Y/O MARITIMO": {}, - "MAQUINARIA Y EQUIPO": {}, - "TERRENOS": {}, - "VIAS DE COMUNICACION": {} - }, - "PROVISIONES": { - "AJUSTES POR INFLACION": {}, - "DEUDORES": {}, - "INVERSIONES": {}, - "OTROS ACTIVOS": {}, - "PROPIEDADES, PLANTA Y EQUIPO": {} - }, - "SEGUROS": { - "AJUSTES POR INFLACION": {}, - "CORRIENTE DEBIL": {}, - "CUMPLIMIENTO": {}, - "FLOTA Y EQUIPO AEREO": {}, - "FLOTA Y EQUIPO DE TRANSPORTE": {}, - "FLOTA Y EQUIPO FERREO": {}, - "FLOTA Y EQUIPO FLUVIAL Y/O MARITIMO": {}, - "INCENDIO": {}, - "LUCRO CESANTE": {}, - "MANEJO": {}, - "OBLIGATORIO ACCIDENTE DE TRANSITO": {}, - "OTROS": {}, - "RESPONSABILIDAD CIVIL Y EXTRACONTRACTUAL": {}, - "ROTURA DE MAQUINARIA": {}, - "SUSTRACCION Y HURTO": {}, - "TERREMOTO": {}, - "TRANSPORTE DE MERCANCIA": {}, - "VIDA COLECTIVA": {}, - "VUELO": {} - }, - "SERVICIOS": { - "ACUEDUCTO Y ALCANTARILLADO": { - "ACUEDUCTO Y ALCANTARILLADO": {} - }, - "AJUSTES POR INFLACION": {}, - "ASEO Y VIGILANCIA": { - "ASEO Y VIGILANCIA": {} - }, - "ASISTENCIA TECNICA": {}, - "CORREO, PORTES Y TELEGRAMAS": {}, - "ENERGIA ELECTRICA": {}, - "FAX Y TELEX": {}, - "GAS": {}, - "OTROS": { - "OTROS": {} - }, - "PROCESAMIENTO ELECTRONICO DE DATOS": { - "PROCESAMIENTO ELECTRONICO DE DATOS": {} - }, - "TELEFONO": { - "TELEFONO": {} - }, - "TEMPORALES": { - "TEMPORALES": {} - }, - "TRANSPORTE, FLETES Y ACARREOS": {} - } - }, - "OPERACIONALES DE VENTAS": { - "ADECUACION E INSTALACION": { - "AJUSTES POR INFLACION": {}, - "ARREGLOS ORNAMENTALES": {}, - "INSTALACIONES ELECTRICAS": {}, - "OTROS": {}, - "REPARACIONES LOCATIVAS": {} - }, - "AMORTIZACIONES": { - "AJUSTES POR INFLACION": {}, - "CARGOS DIFERIDOS": {}, - "INTANGIBLES": {}, - "OTRAS": {}, - "VIAS DE COMUNICACION": {} - }, - "ARRENDAMIENTOS": { - "ACUEDUCTOS, PLANTAS Y REDES": {}, - "AERODROMOS": {}, - "AJUSTES POR INFLACION": {}, - "CONSTRUCCIONES Y EDIFICACIONES": {}, - "EQUIPO DE COMPUTACION Y COMUNICACION": {}, - "EQUIPO DE HOTELES Y RESTAURANTES": {}, - "EQUIPO DE OFICINA": {}, - "EQUIPO MEDICO-CIENTIFICO": {}, - "FLOTA Y EQUIPO AEREO": {}, - "FLOTA Y EQUIPO DE TRANSPORTE": {}, - "FLOTA Y EQUIPO FERREO": {}, - "FLOTA Y EQUIPO FLUVIAL Y/O MARITIMO": {}, - "MAQUINARIA Y EQUIPO": {}, - "OTROS": {}, - "SEMOVIENTES": {}, - "TERRENOS": {} - }, - "CONTRIBUCIONES Y AFILIACIONES": { - "AFILIACIONES Y SOSTENIMIENTO": {}, - "AJUSTES POR INFLACION": {}, - "CONTRIBUCIONES": {} - }, - "DEPRECIACIONES": { - "ACUEDUCTOS, PLANTAS Y REDES": {}, - "AJUSTES POR INFLACION": {}, - "ARMAMENTO DE VIGILANCIA": {}, - "CONSTRUCCIONES Y EDIFICACIONES": {}, - "ENVASES Y EMPAQUES": {}, - "EQUIPO DE COMPUTACION Y COMUNICACION": {}, - "EQUIPO DE HOTELES Y RESTAURANTES": {}, - "EQUIPO DE OFICINA": {}, - "EQUIPO MEDICO-CIENTIFICO": {}, - "FLOTA Y EQUIPO AEREO": {}, - "FLOTA Y EQUIPO DE TRANSPORTE": {}, - "FLOTA Y EQUIPO FERREO": {}, - "FLOTA Y EQUIPO FLUVIAL Y/O MARITIMO": {}, - "MAQUINARIA Y EQUIPO": {} - }, - "DIVERSOS": { - "AJUSTES POR INFLACION": {}, - "CASINO Y RESTAURANTE": {}, - "COMBUSTIBLES Y LUBRICANTES": {}, - "COMISIONES": {}, - "ELEMENTOS DE ASEO Y CAFETERIA": {}, - "ENVASES Y EMPAQUES": {}, - "ESTAMPILLAS": {}, - "GASTOS DE REPRESENTACION Y RELACIONES PUBLICAS": {}, - "INDEMNIZACION POR DANOS A TERCEROS": {}, - "LIBROS, SUSCRIPCIONES, PERIODICOS Y REVISTAS": {}, - "MICROFILMACION": {}, - "MUSICA AMBIENTAL": {}, - "OTROS": { - "Otros Gastos": {} - }, - "PARQUEADEROS": {}, - "POLVORA Y SIMILARES": {}, - "TAXIS Y BUSES": {}, - "UTILES, PAPELERIA Y FOTOCOPIAS": {} - }, - "FINANCIEROS-REAJUSTE DEL SISTEMA": { - "AJUSTES POR INFLACION": {} - }, - "GASTOS DE PERSONAL": { - "AJUSTES POR INFLACION": {}, - "AMORTIZACION BONOS PENSIONALES": {}, - "AMORTIZACION CALCULO ACTUARIAL PENSIONES DE JUBILACION": {}, - "AMORTIZACION TITULOS PENSIONALES": {}, - "APORTES A ADMINISTRADORAS DE RIESGOS PROFESIONALES, ARP": {}, - "APORTES A ENTIDADES PROMOTORAS DE SALUD, EPS": {}, - "APORTES A FONDOS DE PENSIONES Y/O CESANTIAS": {}, - "APORTES CAJAS DE COMPENSACION FAMILIAR": {}, - "APORTES ICBF": {}, - "APORTES SINDICALES": {}, - "AUXILIO DE TRANSPORTE": {}, - "AUXILIOS": {}, - "BONIFICACIONES": {}, - "CAPACITACION AL PERSONAL": {}, - "CESANTIAS": {}, - "COMISIONES": {}, - "CUOTAS PARTES PENSIONES DE JUBILACION": {}, - "DOTACION Y SUMINISTRO A TRABAJADORES": {}, - "GASTOS DEPORTIVOS Y DE RECREACION": {}, - "GASTOS MEDICOS Y DROGAS": {}, - "HORAS EXTRAS Y RECARGOS": {}, - "INCAPACIDADES": {}, - "INDEMNIZACIONES LABORALES": {}, - "INTERESES SOBRE CESANTIAS": {}, - "JORNALES": {}, - "OTROS": {}, - "PENSIONES DE JUBILACION": {}, - "PRIMA DE SERVICIOS": {}, - "PRIMAS EXTRALEGALES": {}, - "SALARIO INTEGRAL": {}, - "SEGUROS": {}, - "SENA": {}, - "SUELDOS": {}, - "VACACIONES": {}, - "VIATICOS": {} - }, - "GASTOS DE VIAJE": { - "AJUSTES POR INFLACION": {}, - "ALOJAMIENTO Y MANUTENCION": {}, - "OTROS": {}, - "PASAJES AEREOS": {}, - "PASAJES FERREOS": {}, - "PASAJES FLUVIALES Y/O MARITIMOS": {}, - "PASAJES TERRESTRES": {} - }, - "GASTOS LEGALES": { - "ADUANEROS": {}, - "AJUSTES POR INFLACION": {}, - "CONSULARES": {}, - "NOTARIALES": {}, - "OTROS": {}, - "REGISTRO MERCANTIL": {}, - "TRAMITES Y LICENCIAS": {} - }, - "HONORARIOS": { - "AJUSTES POR INFLACION": {}, - "ASESORIA FINANCIERA": {}, - "ASESORIA JURIDICA": {}, - "ASESORIA TECNICA": {}, - "AUDITORIA EXTERNA": {}, - "AVALUOS": {}, - "JUNTA DIRECTIVA": {}, - "OTROS": {}, - "REVISORIA FISCAL": {} - }, - "IMPUESTOS": { - "A LA PROPIEDAD RAIZ": {}, - "AJUSTES POR INFLACION": {}, - "CERVEZAS": {}, - "CIGARRILLOS": {}, - "CUOTAS DE FOMENTO": {}, - "DE ESPECTACULOS PUBLICOS": {}, - "DE TIMBRES": {}, - "DE TURISMO": {}, - "DE VALORIZACION": {}, - "DE VEHICULOS": {}, - "DERECHOS SOBRE INSTRUMENTOS PUBLICOS": {}, - "INDUSTRIA Y COMERCIO": {}, - "IVA DESCONTABLE": {}, - "LICORES": {}, - "OTROS": {}, - "TASA POR UTILIZACION DE PUERTOS": {} - }, - "MANTENIMIENTO Y REPARACIONES": { - "ACUEDUCTOS, PLANTAS Y REDES": {}, - "AJUSTES POR INFLACION": {}, - "ARMAMENTO DE VIGILANCIA": {}, - "CONSTRUCCIONES Y EDIFICACIONES": {}, - "EQUIPO DE COMPUTACION Y COMUNICACION": {}, - "EQUIPO DE HOTELES Y RESTAURANTES": {}, - "EQUIPO DE OFICINA": {}, - "EQUIPO MEDICO-CIENTIFICO": {}, - "FLOTA Y EQUIPO AEREO": {}, - "FLOTA Y EQUIPO DE TRANSPORTE": {}, - "FLOTA Y EQUIPO FERREO": {}, - "FLOTA Y EQUIPO FLUVIAL Y/O MARITIMO": {}, - "MAQUINARIA Y EQUIPO": {}, - "TERRENOS": {}, - "VIAS DE COMUNICACION": {} - }, - "PERDIDAS METODO DE PARTICIPACION": { - "DE SOCIEDADES ANONIMAS Y/O ASIMILADAS": {}, - "DE SOCIEDADES LIMITADAS Y/O ASIMILADAS": {} - }, - "PROVISIONES": { - "AJUSTES POR INFLACION": {}, - "DEUDORES": {}, - "INVENTARIOS": {}, - "INVERSIONES": {}, - "OTROS ACTIVOS": {}, - "PROPIEDADES, PLANTA Y EQUIPO": {} - }, - "SEGUROS": { - "AJUSTES POR INFLACION": {}, - "CORRIENTE DEBIL": {}, - "CUMPLIMIENTO": {}, - "FLOTA Y EQUIPO AEREO": {}, - "FLOTA Y EQUIPO DE TRANSPORTE": {}, - "FLOTA Y EQUIPO FERREO": {}, - "FLOTA Y EQUIPO FLUVIAL Y/O MARITIMO": {}, - "INCENDIO": {}, - "LUCRO CESANTE": {}, - "MANEJO": {}, - "OBLIGATORIO ACCIDENTE DE TRANSITO": {}, - "OTROS": {}, - "RESPONSABILIDAD CIVIL Y EXTRACONTRACTUAL": {}, - "ROTURA DE MAQUINARIA": {}, - "SUSTRACCION Y HURTO": {}, - "TERREMOTO": {}, - "VIDA COLECTIVA": {}, - "VUELO": {} - }, - "SERVICIOS": { - "ACUEDUCTO Y ALCANTARILLADO": {}, - "AJUSTES POR INFLACION": {}, - "ASEO Y VIGILANCIA": {}, - "ASISTENCIA TECNICA": {}, - "CORREO, PORTES Y TELEGRAMAS": {}, - "ENERGIA ELECTRICA": {}, - "FAX Y TELEX": {}, - "GAS": {}, - "OTROS": {}, - "PROCESAMIENTO ELECTRONICO DE DATOS": {}, - "PUBLICIDAD, PROPAGANDA Y PROMOCION": {}, - "TELEFONO": {}, - "TEMPORALES": {}, - "TRANSPORTE, FLETES Y ACARREOS": {} - } - }, - "root_type": "Expense" - }, - "INGRESOS": { - "AJUSTES POR INFLACION": { - "CORRECCION MONETARIA": { - "ACTIVOS DIFERIDOS": {}, - "AGOTAMIENTO ACUMULADO (DB)": {}, - "AMORTIZACION ACUMULADA (DB)": {}, - "COMPRAS (CR)": {}, - "COSTO DE VENTAS (CR)": {}, - "COSTOS DE PRODUCCION O DE OPERACION (CR)": {}, - "DEPRECIACION ACUMULADA (DB)": {}, - "DEPRECIACION DIFERIDA (CR)": {}, - "DEVOLUCIONES EN COMPRAS (DB)": {}, - "DEVOLUCIONES EN VENTAS (CR)": {}, - "GASTOS NO OPERACIONALES (CR)": {}, - "GASTOS OPERACIONALES DE ADMINISTRACION (CR)": {}, - "GASTOS OPERACIONALES DE VENTAS (CR)": {}, - "INGRESOS NO OPERACIONALES (DB)": {}, - "INGRESOS OPERACIONALES (DB)": {}, - "INTANGIBLES (CR)": {}, - "INVENTARIOS (CR)": {}, - "INVERSIONES (CR)": {}, - "OTROS ACTIVOS (CR)": {}, - "PASIVOS SUJETOS DE AJUSTE": {}, - "PATRIMONIO": {}, - "PROPIEDADES, PLANTA Y EQUIPO (CR)": {} - } - }, - "NO OPERACIONALES": { - "ARRENDAMIENTOS": { - "ACUEDUCTOS, PLANTAS Y REDES": {}, - "AERODROMOS": {}, - "AJUSTES POR INFLACION": {}, - "CONSTRUCCIONES Y EDIFICIOS": {}, - "ENVASES Y EMPAQUES": {}, - "EQUIPO DE COMPUTACION Y COMUNICACION": {}, - "EQUIPO DE HOTELES Y RESTAURANTES": {}, - "EQUIPO DE OFICINA": {}, - "EQUIPO MEDICO-CIENTIFICO": {}, - "FLOTA Y EQUIPO AEREO": {}, - "FLOTA Y EQUIPO DE TRANSPORTE": {}, - "FLOTA Y EQUIPO FERREO": {}, - "FLOTA Y EQUIPO FLUVIAL Y/O MARITIMO": {}, - "MAQUINARIA Y EQUIPO": {}, - "PLANTACIONES AGRICOLAS Y FORESTALES": {}, - "SEMOVIENTES": {}, - "TERRENOS": {} - }, - "COMISIONES": { - "AJUSTES POR INFLACION": {}, - "DE ACTIVIDADES FINANCIERAS": {}, - "DE CONCESIONARIOS": {}, - "DERECHOS DE AUTOR": {}, - "DERECHOS DE PROGRAMACION": {}, - "POR DISTRIBUCION DE PELICULAS": {}, - "POR INGRESOS PARA TERCEROS": {}, - "POR VENTA DE SEGUROS": {}, - "POR VENTA DE SERVICIOS DE TALLER": {}, - "SOBRE INVERSIONES": {} - }, - "DEVOLUCIONES EN OTRAS VENTAS (DB)": { - "AJUSTES POR INFLACION": {} - }, - "DIVERSOS": { - "AJUSTE AL PESO": {}, - "AJUSTES POR INFLACION": {}, - "APROVECHAMIENTOS": { - "APROVECHAMIENTOS": {} - }, - "AUXILIOS": {}, - "BONIFICACIONES": {}, - "CAPACITACION DISTRIBUIDORES": {}, - "CERT": {}, - "DE ESCRITURACION": {}, - "DE LA ACTIVIDAD GANADERA": {}, - "DECORACIONES": {}, - "DERECHOS Y LICITACIONES": {}, - "DERIVADOS DE LAS EXPORTACIONES": {}, - "EXCEDENTES": {}, - "HISTORIA CLINICA": {}, - "INGRESOS POR ELEMENTOS PERDIDOS": {}, - "INGRESOS POR INVESTIGACION Y DESARROLLO": {}, - "LLAMADAS TELEFONICAS": {}, - "MANEJO DE CARGA": {}, - "MULTAS Y RECARGOS": {}, - "OTROS": {}, - "OTROS INGRESOS DE EXPLOTACION": {}, - "POR TRABAJOS EJECUTADOS": {}, - "PREAVISOS DESCONTADOS": {}, - "PREMIOS": {}, - "PRODUCTOS DESCONTADOS": {}, - "RECLAMOS": {}, - "RECOBRO DE DANOS": {}, - "RECONOCIMIENTOS ISS": {}, - "REGALIAS": {}, - "REGISTRO PROMESAS DE VENTA": {}, - "RESULTADOS, MATRICULAS Y TRASPASOS": {}, - "SOBRANTES DE CAJA": {}, - "SOBRANTES EN LIQUIDACION FLETES": {}, - "SUBSIDIOS ESTATALES": {}, - "SUBVENCIONES": {}, - "UTILES, PAPELERIA Y FOTOCOPIAS": { - "UTILES, PAPELERIA Y FOTOCOPIAS": {} - } - }, - "DIVIDENDOS Y PARTICIPACIONES": { - "AJUSTES POR INFLACION": {}, - "DE SOCIEDADES ANONIMAS Y/O ASIMILADAS": {}, - "DE SOCIEDADES LIMITADAS Y/O ASIMILADAS": {} - }, - "FINANCIEROS": { - "ACEPTACIONES BANCARIAS": {}, - "AJUSTES POR INFLACION": {}, - "COMISIONES CHEQUES DE OTRAS PLAZAS": {}, - "DESCUENTOS AMORTIZADOS": {}, - "DESCUENTOS BANCARIOS": {}, - "DESCUENTOS COMERCIALES CONDICIONADOS": {}, - "DIFERENCIA EN CAMBIO": {}, - "FINANCIACION SISTEMAS DE VIAJES": {}, - "FINANCIACION VEHICULOS": {}, - "INTERESES": {}, - "MULTAS Y RECARGOS": {}, - "OTROS": {}, - "REAJUSTE MONETARIO-UPAC (HOY UVR)": {}, - "SANCIONES CHEQUES DEVUELTOS": {} - }, - "HONORARIOS": { - "ADMINISTRACION DE VINCULADAS": {}, - "AJUSTES POR INFLACION": {}, - "ASESORIAS": {}, - "ASISTENCIA TECNICA": {} - }, - "INDEMNIZACIONES": { - "AJUSTES POR INFLACION": {}, - "DANO EMERGENTE COMPANIAS DE SEGUROS": {}, - "DE TERCEROS": {}, - "LUCRO CESANTE COMPANIAS DE SEGUROS": {}, - "OTRAS": {}, - "POR INCAPACIDADES ISS": {}, - "POR INCUMPLIMIENTO DE CONTRATOS": {}, - "POR PERDIDA DE MERCANCIA": {}, - "POR SINIESTRO": {}, - "POR SUMINISTROS": {} - }, - "INGRESOS DE EJERCICIOS ANTERIORES": { - "AJUSTES POR INFLACION": {} - }, - "INGRESOS METODO DE PARTICIPACION": { - "DE SOCIEDADES ANONIMAS Y/O ASIMILADAS": {}, - "DE SOCIEDADES LIMITADAS Y/O ASIMILADAS": {} - }, - "OTRAS VENTAS": { - "AJUSTES POR INFLACION": {}, - "COMBUSTIBLES Y LUBRICANTES": {}, - "DE PROPAGANDA": {}, - "ENVASES Y EMPAQUES": {}, - "EXCEDENTES DE EXPORTACION": {}, - "MATERIA PRIMA": {}, - "MATERIAL DE DESECHO": {}, - "MATERIALES VARIOS": {}, - "PRODUCTOS AGRICOLAS": {}, - "PRODUCTOS DE DIVERSIFICACION": {}, - "PRODUCTOS EN REMATE": {} - }, - "PARTICIPACIONES EN CONCESIONES": { - "AJUSTES POR INFLACION": {} - }, - "RECUPERACIONES": { - "AJUSTES POR INFLACION": {}, - "DE DEPRECIACION": {}, - "DE PROVISIONES": {}, - "DESCUENTOS CONCEDIDOS": {}, - "DEUDAS MALAS": {}, - "GASTOS BANCARIOS": {}, - "RECLAMOS": {}, - "REINTEGRO DE OTROS COSTOS Y GASTOS": {}, - "REINTEGRO GARANTIAS": {}, - "REINTEGRO POR PERSONAL EN COMISION": {}, - "SEGUROS": {} - }, - "SERVICIOS": { - "ADMINISTRATIVOS": {}, - "AJUSTES POR INFLACION": {}, - "AL PERSONAL": {}, - "DE BASCULA": {}, - "DE CASINO": {}, - "DE COMPUTACION": {}, - "DE MANTENIMIENTO": {}, - "DE PRENSA": {}, - "DE RECEPCION DE AERONAVES": {}, - "DE TELEFAX": {}, - "DE TRANSPORTE": {}, - "DE TRANSPORTE PROGRAMA GAS NATURAL": {}, - "DE TRILLA": {}, - "ENTRE COMPANIAS": {}, - "FLETES": {}, - "OTROS": {}, - "POR CONTRATOS": {}, - "TALLER DE VEHICULOS": {}, - "TECNICOS": {} - }, - "UTILIDAD EN VENTA DE INVERSIONES": { - "ACCIONES": {}, - "AJUSTES POR INFLACION": {}, - "BONOS": {}, - "CEDULAS": {}, - "CERTIFICADOS": {}, - "CUOTAS O PARTES DE INTERES SOCIAL": {}, - "DERECHOS FIDUCIARIOS": {}, - "OBLIGATORIAS": {}, - "OTRAS": {}, - "PAPELES COMERCIALES": {}, - "TITULOS": {} - }, - "UTILIDAD EN VENTA DE OTROS BIENES": { - "AJUSTES POR INFLACION": {}, - "INTANGIBLES": {}, - "OTROS ACTIVOS": {} - }, - "UTILIDAD EN VENTA DE PROPIEDADES, PLANTA Y EQUIPO": { - "ACUEDUCTOS, PLANTAS Y REDES": {}, - "AJUSTES POR INFLACION": {}, - "ARMAMENTO DE VIGILANCIA": {}, - "CONSTRUCCIONES EN CURSO": {}, - "CONSTRUCCIONES Y EDIFICACIONES": {}, - "ENVASES Y EMPAQUES": {}, - "EQUIPO DE COMPUTACION Y COMUNICACION": {}, - "EQUIPO DE HOTELES Y RESTAURANTES": {}, - "EQUIPO DE OFICINA": {}, - "EQUIPO MEDICO-CIENTIFICO": {}, - "FLOTA Y EQUIPO AEREO": {}, - "FLOTA Y EQUIPO DE TRANSPORTE": {}, - "FLOTA Y EQUIPO FERREO": {}, - "FLOTA Y EQUIPO FLUVIAL Y/O MARITIMO": {}, - "MAQUINARIA EN MONTAJE": {}, - "MAQUINARIA Y EQUIPO": {}, - "MATERIALES INDUSTRIA PETROLERA": {}, - "MINAS Y CANTERAS": {}, - "PLANTACIONES AGRICOLAS Y FORESTALES": {}, - "POZOS ARTESIANOS": {}, - "SEMOVIENTES": {}, - "TERRENOS": {}, - "VIAS DE COMUNICACION": {}, - "YACIMIENTOS": {} - } - }, - "OPERACIONALES": { - "ACTIVIDAD FINANCIERA": { - "ACTIVIDADES CONEXAS": {}, - "AJUSTES POR INFLACION": {}, - "COMISIONES": {}, - "CUOTAS DE ADMINISTRACION-CONSORCIOS": {}, - "CUOTAS DE INGRESO O RETIRO-SOCIEDAD ADMINISTRADORA": {}, - "CUOTAS DE INSCRIPCION-CONSORCIOS": {}, - "DIVIDENDOS DE SOCIEDADES ANONIMAS Y/O ASIMILADAS": {}, - "ELIMINACION DE SUSCRIPTORES-CONSORCIOS": {}, - "INGRESOS METODO DE PARTICIPACION": {}, - "INSCRIPCIONES Y CUOTAS": {}, - "INTERESES": {}, - "OPERACIONES DE DESCUENTO": {}, - "PARTICIPACIONES DE SOCIEDADES LIMITADAS Y/O ASIMILADAS": {}, - "REAJUSTE DEL SISTEMA-CONSORCIOS": {}, - "REAJUSTE MONETARIO-UPAC (HOY UVR)": {}, - "RECUPERACION DE GARANTIAS": {}, - "SERVICIOS A COMISIONISTAS": {}, - "VENTA DE INVERSIONES": {} - }, - "ACTIVIDADES INMOBILIARIAS, EMPRESARIALES Y DE ALQUILER": { - "ACTIVIDADES CONEXAS": {}, - "ACTIVIDADES EMPRESARIALES DE CONSULTORIA": {}, - "AJUSTES POR INFLACION": {}, - "ALQUILER DE EFECTOS PERSONALES Y ENSERES DOMESTICOS": {}, - "ALQUILER EQUIPO DE TRANSPORTE": {}, - "ALQUILER MAQUINARIA Y EQUIPO": {}, - "ARRENDAMIENTOS DE BIENES INMUEBLES": {}, - "CONSULTORIA EN EQUIPO Y PROGRAMAS DE INFORMATICA": {}, - "DOTACION DE PERSONAL": {}, - "ENVASE Y EMPAQUE": {}, - "FOTOCOPIADO": {}, - "FOTOGRAFIA": {}, - "INMOBILIARIAS POR RETRIBUCION O CONTRATA": {}, - "INVESTIGACION Y SEGURIDAD": {}, - "INVESTIGACIONES CIENTIFICAS Y DE DESARROLLO": {}, - "LIMPIEZA DE INMUEBLES": {}, - "MANTENIMIENTO Y REPARACION DE MAQUINARIA DE OFICINA": {}, - "MANTENIMIENTO Y REPARACION DE MAQUINARIA Y EQUIPO": {}, - "PROCESAMIENTO DE DATOS": {}, - "PUBLICIDAD": {} - }, - "AGRICULTURA, GANADERIA, CAZA Y SILVICULTURA": { - "ACTIVIDAD DE CAZA": {}, - "ACTIVIDAD DE SILVICULTURA": {}, - "ACTIVIDADES CONEXAS": {}, - "AJUSTES POR INFLACION": {}, - "CRIA DE GANADO CABALLAR Y VACUNO": {}, - "CRIA DE OTROS ANIMALES": {}, - "CRIA DE OVEJAS, CABRAS, ASNOS, MULAS Y BURDEGANOS": {}, - "CULTIVO DE ALGODON Y PLANTAS PARA MATERIAL TEXTIL": {}, - "CULTIVO DE BANANO": {}, - "CULTIVO DE CAFE": {}, - "CULTIVO DE CANA DE AZUCAR": {}, - "CULTIVO DE CEREALES": {}, - "CULTIVO DE FLORES": {}, - "CULTIVOS DE FRUTAS, NUECES Y PLANTAS AROMATICAS": {}, - "CULTIVOS DE HORTALIZAS, LEGUMBRES Y PLANTAS ORNAMENTALES": {}, - "OTROS CULTIVOS AGRICOLAS": {}, - "PRODUCCION AVICOLA": {}, - "SERVICIOS AGRICOLAS Y GANADEROS": {} - }, - "COMERCIO AL POR MAYOR Y AL POR MENOR": { - "AJUSTES POR INFLACION": {}, - "MANTENIMIENTO, REPARACION Y LAVADO DE VEHICULOS AUTOMOTORES": {}, - "REPARACION DE EFECTOS PERSONALES Y ELECTRODOMESTICOS": {}, - "VENTA A CAMBIO DE RETRIBUCION O POR CONTRATA": {}, - "VENTA DE ANIMALES VIVOS Y CUEROS": {}, - "VENTA DE ARTICULOS EN CACHARRERIAS Y MISCELANEAS": {}, - "VENTA DE ARTICULOS EN CASAS DE EMPENO Y PRENDERIAS": {}, - "VENTA DE ARTICULOS EN RELOJERIAS Y JOYERIAS": {}, - "VENTA DE COMBUSTIBLES SOLIDOS, LIQUIDOS, GASEOSOS": {}, - "VENTA DE CUBIERTOS, VAJILLAS, CRISTALERIA, PORCELANAS, CERAMICAS Y OTROS ARTICULOS DE USO DOMESTICO": {}, - "VENTA DE ELECTRODOMESTICOS Y MUEBLES": {}, - "VENTA DE EMPAQUES": {}, - "VENTA DE EQUIPO FOTOGRAFICO": {}, - "VENTA DE EQUIPO OPTICO Y DE PRECISION": {}, - "VENTA DE EQUIPO PROFESIONAL Y CIENTIFICO": {}, - "VENTA DE HERRAMIENTAS Y ARTICULOS DE FERRETERIA": {}, - "VENTA DE INSTRUMENTOS MUSICALES": {}, - "VENTA DE INSTRUMENTOS QUIRURGICOS Y ORTOPEDICOS": {}, - "VENTA DE INSUMOS, MATERIAS PRIMAS AGROPECUARIAS Y FLORES": {}, - "VENTA DE JUEGOS, JUGUETES Y ARTICULOS DEPORTIVOS": {}, - "VENTA DE LIBROS, REVISTAS, ELEMENTOS DE PAPELERIA, UTILES Y TEXTOS ESCOLARES": {}, - "VENTA DE LOTERIAS, RIFAS, CHANCE, APUESTAS Y SIMILARES": {}, - "VENTA DE LUBRICANTES, ADITIVOS, LLANTAS Y LUJOS PARA AUTOMOTORES": {}, - "VENTA DE MAQUINARIA, EQUIPO DE OFICINA Y PROGRAMAS DE COMPUTADOR": {}, - "VENTA DE MATERIALES DE CONSTRUCCION, FONTANERIA Y CALEFACCION": {}, - "VENTA DE OTROS INSUMOS Y MATERIAS PRIMAS NO AGROPECUARIAS": {}, - "VENTA DE OTROS PRODUCTOS": { - "Ingresos Generales": {} - }, - "VENTA DE PAPEL Y CARTON": {}, - "VENTA DE PARTES, PIEZAS Y ACCESORIOS DE VEHICULOS AUTOMOTORES": {}, - "VENTA DE PINTURAS Y LACAS": {}, - "VENTA DE PRODUCTOS AGROPECUARIOS": {}, - "VENTA DE PRODUCTOS DE ASEO, FARMACEUTICOS, MEDICINALES, Y ARTICULOS DE TOCADOR": {}, - "VENTA DE PRODUCTOS DE VIDRIOS Y MARQUETERIA": {}, - "VENTA DE PRODUCTOS EN ALMACENES NO ESPECIALIZADOS": {}, - "VENTA DE PRODUCTOS INTERMEDIOS, DESPERDICIOS Y DESECHOS": {}, - "VENTA DE PRODUCTOS TEXTILES, DE VESTIR, DE CUERO Y CALZADO": {}, - "VENTA DE QUIMICOS": {}, - "VENTA DE VEHICULOS AUTOMOTORES": {} - }, - "CONSTRUCCION": { - "ACONDICIONAMIENTO DE EDIFICIOS": {}, - "ACTIVIDADES CONEXAS": {}, - "AJUSTES POR INFLACION": {}, - "ALQUILER DE EQUIPO CON OPERARIOS": {}, - "CONSTRUCCION DE EDIFICIOS Y OBRAS DE INGENIERIA CIVIL": {}, - "PREPARACION DE TERRENOS": {}, - "TERMINACION DE EDIFICACIONES": {} - }, - "DEVOLUCIONES EN VENTAS (DB)": { - "AJUSTES POR INFLACION": {} - }, - "ENSENANZA": { - "ACTIVIDADES CONEXAS": {}, - "ACTIVIDADES RELACIONADAS CON LA EDUCACION": {}, - "AJUSTES POR INFLACION": {} - }, - "EXPLOTACION DE MINAS Y CANTERAS": { - "ACTIVIDADES CONEXAS": {}, - "AJUSTES POR INFLACION": {}, - "CARBON": {}, - "GAS NATURAL": {}, - "MINERALES DE HIERRO": {}, - "MINERALES METALIFEROS NO FERROSOS": {}, - "ORO": {}, - "OTRAS MINAS Y CANTERAS": {}, - "PETROLEO CRUDO": {}, - "PIEDRA, ARENA Y ARCILLA": {}, - "PIEDRAS PRECIOSAS": {}, - "PRESTACION DE SERVICIOS SECTOR MINERO": {}, - "SERVICIOS RELACIONADOS CON EXTRACCION DE PETROLEO Y GAS": {} - }, - "HOTELES Y RESTAURANTES": { - "ACTIVIDADES CONEXAS": {}, - "AJUSTES POR INFLACION": {}, - "BARES Y CANTINAS": {}, - "CAMPAMENTO Y OTROS TIPOS DE HOSPEDAJE": {}, - "HOTELERIA": {}, - "RESTAURANTES": {} - }, - "INDUSTRIAS MANUFACTURERAS": { - "ACABADO DE PRODUCTOS TEXTILES": {}, - "AJUSTES POR INFLACION": {}, - "CORTE, TALLADO Y ACABADO DE LA PIEDRA": {}, - "CURTIDO, ADOBO O PREPARACION DE CUERO": {}, - "EDICIONES Y PUBLICACIONES": {}, - "ELABORACION DE ABONOS Y COMPUESTOS DE NITROGENO": {}, - "ELABORACION DE ACEITES Y GRASAS": {}, - "ELABORACION DE ALIMENTOS PARA ANIMALES": {}, - "ELABORACION DE ALMIDONES Y DERIVADOS": {}, - "ELABORACION DE APARATOS DE USO DOMESTICO": {}, - "ELABORACION DE ARTICULOS DE HORMIGON, CEMENTO Y YESO": {}, - "ELABORACION DE ARTICULOS DE MATERIALES TEXTILES": {}, - "ELABORACION DE AZUCAR Y MELAZAS": {}, - "ELABORACION DE BEBIDAS ALCOHOLICAS Y ALCOHOL ETILICO": {}, - "ELABORACION DE BEBIDAS MALTEADAS Y DE MALTA": {}, - "ELABORACION DE BEBIDAS NO ALCOHOLICAS": {}, - "ELABORACION DE CACAO, CHOCOLATE Y CONFITERIA": {}, - "ELABORACION DE CALZADO": {}, - "ELABORACION DE CEMENTO, CAL Y YESO": {}, - "ELABORACION DE CUERDAS, CORDELES, BRAMANTES Y REDES": {}, - "ELABORACION DE EQUIPO DE ILUMINACION": {}, - "ELABORACION DE EQUIPO DE OFICINA": {}, - "ELABORACION DE FIBRAS": {}, - "ELABORACION DE JABONES, DETERGENTES Y PREPARADOS DE TOCADOR": {}, - "ELABORACION DE MALETAS, BOLSOS Y SIMILARES": {}, - "ELABORACION DE OTROS PRODUCTOS ALIMENTICIOS": {}, - "ELABORACION DE OTROS PRODUCTOS DE CAUCHO": {}, - "ELABORACION DE OTROS PRODUCTOS DE METAL": {}, - "ELABORACION DE OTROS PRODUCTOS MINERALES NO METALICOS": {}, - "ELABORACION DE OTROS PRODUCTOS QUIMICOS": {}, - "ELABORACION DE OTROS PRODUCTOS TEXTILES": {}, - "ELABORACION DE OTROS TIPOS DE EQUIPO ELECTRICO": {}, - "ELABORACION DE PASTA Y PRODUCTOS DE MADERA, PAPEL Y CARTON": {}, - "ELABORACION DE PASTAS Y PRODUCTOS FARINACEOS": {}, - "ELABORACION DE PILAS Y BATERIAS PRIMARIAS": {}, - "ELABORACION DE PINTURAS, TINTAS Y MASILLAS": {}, - "ELABORACION DE PLASTICO Y CAUCHO SINTETICO": {}, - "ELABORACION DE PRENDAS DE VESTIR": {}, - "ELABORACION DE PRODUCTOS DE CAFE": {}, - "ELABORACION DE PRODUCTOS DE CERAMICA, LOZA, PIEDRA, ARCILLA Y PORCELANA": {}, - "ELABORACION DE PRODUCTOS DE HORNO DE COQUE": {}, - "ELABORACION DE PRODUCTOS DE LA REFINACION DE PETROLEO": {}, - "ELABORACION DE PRODUCTOS DE MOLINERIA": {}, - "ELABORACION DE PRODUCTOS DE PLASTICO": {}, - "ELABORACION DE PRODUCTOS DE TABACO": {}, - "ELABORACION DE PRODUCTOS FARMACEUTICOS Y BOTANICOS": {}, - "ELABORACION DE PRODUCTOS LACTEOS": {}, - "ELABORACION DE PRODUCTOS PARA PANADERIA": {}, - "ELABORACION DE PRODUCTOS QUIMICOS DE USO AGROPECUARIO": {}, - "ELABORACION DE SUSTANCIAS QUIMICAS BASICAS": {}, - "ELABORACION DE TAPICES Y ALFOMBRAS": {}, - "ELABORACION DE TEJIDOS": {}, - "ELABORACION DE VIDRIO Y PRODUCTOS DE VIDRIO": {}, - "ELABORACION DE VINOS": {}, - "FABRICACION DE AERONAVES": {}, - "FABRICACION DE APARATOS E INSTRUMENTOS MEDICOS": {}, - "FABRICACION DE ARTICULOS DE FERRETERIA": {}, - "FABRICACION DE ARTICULOS Y EQUIPO PARA DEPORTE": {}, - "FABRICACION DE BICICLETAS Y SILLAS DE RUEDAS": {}, - "FABRICACION DE CARROCERIAS PARA AUTOMOTORES": {}, - "FABRICACION DE EQUIPOS DE ELEVACION Y MANIPULACION": {}, - "FABRICACION DE EQUIPOS DE RADIO, TELEVISION Y COMUNICACIONES": {}, - "FABRICACION DE INSTRUMENTOS DE MEDICION Y CONTROL": {}, - "FABRICACION DE INSTRUMENTOS DE MUSICA": {}, - "FABRICACION DE INSTRUMENTOS DE OPTICA Y EQUIPO FOTOGRAFICO": {}, - "FABRICACION DE JOYAS Y ARTICULOS CONEXOS": {}, - "FABRICACION DE JUEGOS Y JUGUETES": {}, - "FABRICACION DE LOCOMOTORAS Y MATERIAL RODANTE PARA FERROCARRILES": {}, - "FABRICACION DE MAQUINARIA Y EQUIPO": {}, - "FABRICACION DE MOTOCICLETAS": {}, - "FABRICACION DE MUEBLES": {}, - "FABRICACION DE OTROS TIPOS DE TRANSPORTE": {}, - "FABRICACION DE PARTES PIEZAS Y ACCESORIOS PARA AUTOMOTORES": {}, - "FABRICACION DE PRODUCTOS METALICOS PARA USO ESTRUCTURAL": {}, - "FABRICACION DE RELOJES": {}, - "FABRICACION DE VEHICULOS AUTOMOTORES": {}, - "FABRICACION Y REPARACION DE BUQUES Y OTRAS EMBARCACIONES": {}, - "FORJA, PRENSADO, ESTAMPADO, LAMINADO DE METAL Y PULVIMETALURGIA": {}, - "FUNDICION DE METALES NO FERROSOS": {}, - "IMPRESION": {}, - "INDUSTRIAS BASICAS Y FUNDICION DE HIERRO Y ACERO": {}, - "PREPARACION E HILATURA DE FIBRAS TEXTILES Y TEJEDURIA": {}, - "PREPARACION, ADOBO Y TENIDO DE PIELES": {}, - "PRODUCCION DE MADERA, ARTICULOS DE MADERA Y CORCHO": {}, - "PRODUCCION Y PROCESAMIENTO DE CARNES Y PRODUCTOS CARNICOS": {}, - "PRODUCTOS DE FRUTAS, LEGUMBRES Y HORTALIZAS": {}, - "PRODUCTOS DE OTRAS INDUSTRIAS MANUFACTURERAS": {}, - "PRODUCTOS DE PESCADO": {}, - "PRODUCTOS PRIMARIOS DE METALES PRECIOSOS Y DE METALES NO FERROSOS": {}, - "RECICLAMIENTO DE DESPERDICIOS": {}, - "REPRODUCCION DE GRABACIONES": {}, - "REVESTIMIENTO DE METALES Y OBRAS DE INGENIERIA MECANICA": {}, - "SERVICIOS RELACIONADOS CON LA EDICION Y LA IMPRESION": {} - }, - "OTRAS ACTIVIDADES DE SERVICIOS COMUNITARIOS, SOCIALES Y PERSONALES": { - "ACTIVIDAD DE RADIO Y TELEVISION": {}, - "ACTIVIDAD TEATRAL, MUSICAL Y ARTISTICA": {}, - "ACTIVIDADES CONEXAS": {}, - "ACTIVIDADES DE ASOCIACION": {}, - "AGENCIAS DE NOTICIAS": {}, - "AJUSTES POR INFLACION": {}, - "ELIMINACION DE DESPERDICIOS Y AGUAS RESIDUALES": {}, - "ENTRETENIMIENTO Y ESPARCIMIENTO": {}, - "EXHIBICION DE FILMES Y VIDEOCINTAS": {}, - "GRABACION Y PRODUCCION DE DISCOS": {}, - "LAVANDERIAS Y SIMILARES": {}, - "PELUQUERIAS Y SIMILARES": {}, - "PRODUCCION Y DISTRIBUCION DE FILMES Y VIDEOCINTAS": {}, - "SERVICIOS FUNERARIOS": {}, - "ZONAS FRANCAS": {} - }, - "PESCA": { - "ACTIVIDAD DE PESCA": {}, - "ACTIVIDADES CONEXAS": {}, - "AJUSTES POR INFLACION": {}, - "EXPLOTACION DE CRIADEROS DE PECES": {} - }, - "SERVICIOS SOCIALES Y DE SALUD": { - "ACTIVIDADES CONEXAS": {}, - "ACTIVIDADES DE SERVICIOS SOCIALES": {}, - "ACTIVIDADES VETERINARIAS": {}, - "AJUSTES POR INFLACION": {}, - "SERVICIO DE LABORATORIO": {}, - "SERVICIO HOSPITALARIO": {}, - "SERVICIO MEDICO": {}, - "SERVICIO ODONTOLOGICO": {} - }, - "SUMINISTRO DE ELECTRICIDAD, GAS Y AGUA": { - "ACTIVIDADES CONEXAS": {}, - "AJUSTES POR INFLACION": {}, - "CAPTACION, DEPURACION Y DISTRIBUCION DE AGUA": {}, - "FABRICACION DE GAS Y DISTRIBUCION DE COMBUSTIBLES GASEOSOS": {}, - "GENERACION, CAPTACION Y DISTRIBUCION DE ENERGIA ELECTRICA": {} - }, - "TRANSPORTE, ALMACENAMIENTO Y COMUNICACIONES": { - "ACTIVIDADES CONEXAS": {}, - "AGENCIAS DE VIAJE": {}, - "AJUSTES POR INFLACION": {}, - "ALMACENAMIENTO Y DEPOSITO": {}, - "MANIPULACION DE CARGA": {}, - "OTRAS AGENCIAS DE TRANSPORTE": {}, - "SERVICIO DE RADIO Y TELEVISION POR CABLE": {}, - "SERVICIO DE TELEGRAFO": {}, - "SERVICIO DE TRANSMISION DE DATOS": {}, - "SERVICIO DE TRANSPORTE POR CARRETERA": {}, - "SERVICIO DE TRANSPORTE POR TUBERIAS": {}, - "SERVICIO DE TRANSPORTE POR VIA ACUATICA": {}, - "SERVICIO DE TRANSPORTE POR VIA AEREA": {}, - "SERVICIO DE TRANSPORTE POR VIA FERREA": {}, - "SERVICIO POSTAL Y DE CORREO": {}, - "SERVICIO TELEFONICO": {}, - "SERVICIOS COMPLEMENTARIOS PARA EL TRANSPORTE": {}, - "TRANSMISION DE SONIDO E IMAGENES POR CONTRATO": {} - } - }, - "root_type": "Income" - }, - "PASIVO": { - "BONOS Y PAPELES COMERCIALES": { - "BONOS EN CIRCULACION": {}, - "BONOS OBLIGATORIAMENTE CONVERTIBLES EN ACCIONES": {}, - "BONOS PENSIONALES": { - "BONOS PENSIONALES POR AMORTIZAR (DB)": {}, - "INTERESES CAUSADOS SOBRE BONOS PENSIONALES": {}, - "VALOR BONOS PENSIONALES": {} - }, - "PAPELES COMERCIALES": {}, - "TITULOS PENSIONALES": { - "INTERESES CAUSADOS SOBRE TITULOS PENSIONALES": {}, - "TITULOS PENSIONALES POR AMORTIZAR (DB)": {}, - "VALOR TITULOS PENSIONALES": {} - } - }, - "CUENTAS POR PAGAR": { - "A CASA MATRIZ": {}, - "A COMPANIAS VINCULADAS": {}, - "A CONTRATISTAS": {}, - "ACREEDORES OFICIALES": {}, - "ACREEDORES VARIOS": { - "COMISIONISTAS DE BOLSAS": {}, - "DEPOSITARIOS": {}, - "DONACIONES ASIGNADAS POR PAGAR": {}, - "FONDO DE PERSEVERANCIA": {}, - "FONDOS DE CESANTIAS Y/O PENSIONES": {}, - "OTROS": { - "Generica a Pagarr": {} - }, - "REINTEGROS POR PAGAR": {}, - "SOCIEDAD ADMINISTRADORA-FONDOS DE INVERSION": {} - }, - "COSTOS Y GASTOS POR PAGAR": { - "ARRENDAMIENTOS": {}, - "COMISIONES": {}, - "GASTOS DE REPRESENTACION Y RELACIONES PUBLICAS": {}, - "GASTOS DE VIAJE": {}, - "GASTOS FINANCIEROS": {}, - "GASTOS LEGALES": {}, - "HONORARIOS": {}, - "LIBROS, SUSCRIPCIONES, PERIODICOS Y REVISTAS": {}, - "OTROS": {}, - "SEGUROS": {}, - "SERVICIOS ADUANEROS": {}, - "SERVICIOS DE MANTENIMIENTO": {}, - "SERVICIOS PUBLICOS": {}, - "SERVICIOS TECNICOS": {}, - "TRANSPORTES, FLETES Y ACARREOS": {} - }, - "CUENTAS CORRIENTES COMERCIALES": {}, - "CUOTAS POR DEVOLVER": {}, - "DEUDAS CON ACCIONISTAS O SOCIOS": { - "ACCIONISTAS": {}, - "SOCIOS": {} - }, - "DEUDAS CON DIRECTORES": {}, - "DIVIDENDOS O PARTICIPACIONES POR PAGAR": { - "DIVIDENDOS": { - "LIGINA MARINA CANELON CASTELLANOS": {} - }, - "PARTICIPACIONES": {} - }, - "IMPUESTO A LAS VENTAS RETENIDO": { - "IMPUESTO A LAS VENTAS RETENIDO": { - "IMPUESTO A LAS VENTAS RETENIDO": {} - } - }, - "IMPUESTO DE INDUSTRIA Y COMERCIO RETENIDO": { - "IMPUESTO DE INDUSTRIA Y COMERCIO RETENIDO": { - "IMPUESTO DE INDUSTRIA Y COMERCIO RETENIDO": {} - } - }, - "INSTALAMENTOS POR PAGAR": {}, - "ORDENES DE COMPRA POR UTILIZAR": {}, - "REGALIAS POR PAGAR": {}, - "RETENCION EN LA FUENTE": { - "ARRENDAMIENTOS": { - "ARRENDAMIENTOS BIENES INMUEBLES": {} - }, - "AUTORRETENCIONES": {}, - "COMISIONES": { - "COMISIONES": {} - }, - "COMPRAS": { - "COMPRAS GRAL": {} - }, - "DIVIDENDOS Y/O PARTICIPACIONES": {}, - "ENAJENACION PROPIEDADES PLANTA Y EQUIPO, PERSONAS NATURALES": {}, - "HONORARIOS": { - "RETEFTE HONORARIOS 10%": {}, - "RETEFTE HONORARIOS 11%": {} - }, - "LOTERIAS, RIFAS, APUESTAS Y SIMILARES": {}, - "OTRAS RETENCIONES Y PATRIMONIO": { - "OTRAS RETENCIONES Y PATRIMONIO": {} - }, - "PAGO DIAN RETENCIONES": { - "PAGO DIAN RETENCIONES": {} - }, - "POR IMPUESTO DE TIMBRE": {}, - "POR INGRESOS OBTENIDOS EN EL EXTERIOR": {}, - "POR PAGOS AL EXTERIOR": {}, - "RENDIMIENTOS FINANCIEROS": {}, - "SALARIOS Y PAGOS LABORALES": { - "SALARIOS Y PAGOS LABORALES": {} - }, - "SERVICIOS": { - "ASEO Y/O VIGILANCIA": {}, - "DE HOTEL, RESTAURANTE Y HOSPEDAJE": {}, - "SERVICIOS GRAL DECLARANTES": {}, - "SERVICIOS GRAL NO DECLARANTES": {}, - "SERVICIOS TEMPORALES": {}, - "TRANSPORTE DE CARGA": {}, - "TRANSPORTE DE PASAJEROS TERRESTRE": {} - } - }, - "RETENCIONES Y APORTES DE NOMINA": { - "APORTES A ADMINISTRADORAS DE RIESGOS PROFESIONALES, ARP": {}, - "APORTES A ENTIDADES PROMOTORAS DE SALUD, EPS": {}, - "APORTES AL FIC": {}, - "APORTES AL ICBF, SENA Y CAJAS DE COMPENSACION": {}, - "COOPERATIVAS": {}, - "EMBARGOS JUDICIALES": {}, - "FONDOS": {}, - "LIBRANZAS": {}, - "OTROS": {}, - "SINDICATOS": {} - } - }, - "DIFERIDOS": { - "ABONOS DIFERIDOS": { - "REAJUSTE DEL SISTEMA": {} - }, - "CREDITO POR CORRECCION MONETARIA DIFERIDA": {}, - "IMPUESTOS DIFERIDOS": { - "AJUSTES POR INFLACION": {}, - "DIVERSOS": {}, - "POR DEPRECIACION FLEXIBLE": {} - }, - "INGRESOS RECIBIDOS POR ANTICIPADO": { - "ARRENDAMIENTOS": {}, - "COMISIONES": {}, - "CUOTAS DE ADMINISTRACION": {}, - "DE SUSCRIPTORES": {}, - "HONORARIOS": {}, - "INTERESES": {}, - "MATRICULAS Y PENSIONES": {}, - "MERCANCIA EN TRANSITO YA VENDIDA": {}, - "OTROS": {}, - "SERVICIOS TECNICOS": {}, - "TRANSPORTES, FLETES Y ACARREOS": {} - }, - "UTILIDAD DIFERIDA EN VENTAS A PLAZOS": {} - }, - "IMPUESTOS, GRAVAMENES Y TASAS": { - "A LA PROPIEDAD RAIZ": {}, - "A LAS EXPORTACIONES CAFETERAS": {}, - "A LAS IMPORTACIONES": {}, - "AL AZAR Y JUEGOS": {}, - "AL SACRIFICIO DE GANADO": {}, - "CUOTAS DE FOMENTO": {}, - "DE ESPECTACULOS PUBLICOS": {}, - "DE HIDROCARBUROS Y MINAS": { - "DE HIDROCARBUROS": {}, - "DE MINAS": {} - }, - "DE INDUSTRIA Y COMERCIO": { - "VIGENCIA FISCAL CORRIENTE": { - "IMPUESTO GENERADO": {}, - "IMPUESTOS DESCOTABLES": {}, - "IMPUESTOS RETENIDOS": {}, - "PAGOS SECRETARIA DE HACIENDA DISTRITAL": {} - }, - "VIGENCIAS FISCALES ANTERIORES": {} - }, - "DE LICORES, CERVEZAS Y CIGARRILLOS": { - "DE CERVEZAS": {}, - "DE CIGARRILLOS": {}, - "DE LICORES": {} - }, - "DE RENTA Y COMPLEMENTARIOS": { - "VIGENCIA FISCAL CORRIENTE": {}, - "VIGENCIAS FISCALES ANTERIORES": {} - }, - "DE TURISMO": {}, - "DE VALORIZACION": { - "VIGENCIA FISCAL CORRIENTE": {}, - "VIGENCIAS FISCALES ANTERIORES": {} - }, - "DE VEHICULOS": { - "VIGENCIA FISCAL CORRIENTE": {}, - "VIGENCIAS FISCALES ANTERIORES": {} - }, - "DERECHOS SOBRE INSTRUMENTOS PUBLICOS": {}, - "GRAVAMENES Y REGALIAS POR UTILIZACION DEL SUELO": {}, - "IMPUESTO SOBRE LAS VENTAS POR PAGAR": { - "IVA DESCONTABLE": { - "IVA DESCONTABLE": {} - }, - "IVA GENERADO": { - "IVA GENERADO": {} - }, - "IVA RETENIDO": { - "IVA RETENIDO": {} - }, - "PAGOS DIAN": { - "PAGOS DIAN": {} - } - }, - "OTROS": {}, - "REGALIAS E IMPUESTOS A LA PEQUENA Y MEDIANA MINERIA": {}, - "TASA POR UTILIZACION DE PUERTOS": {} - }, - "OBLIGACIONES FINANCIERAS": { - "BANCOS DEL EXTERIOR": { - "ACEPTACIONES BANCARIAS": {}, - "CARTAS DE CREDITO": {}, - "PAGARES": {}, - "SOBREGIROS": {} - }, - "BANCOS NACIONALES": { - "ACEPTACIONES BANCARIAS": {}, - "CARTAS DE CREDITO": {}, - "PAGARES": { - "BANCOLOMBIA MORATO": {} - }, - "SOBREGIROS": {} - }, - "COMPANIAS DE FINANCIAMIENTO COMERCIAL": { - "ACEPTACIONES FINANCIERAS": {}, - "CONTRATOS DE ARRENDAMIENTO FINANCIERO (LEASING)": {}, - "PAGARES": {} - }, - "COMPROMISOS DE RECOMPRA DE CARTERA NEGOCIADA": {}, - "COMPROMISOS DE RECOMPRA DE INVERSIONES NEGOCIADAS": { - "ACCIONES": {}, - "ACEPTACIONES BANCARIAS O FINANCIERAS": {}, - "BONOS": {}, - "CEDULAS": {}, - "CERTIFICADOS": {}, - "CUOTAS O PARTES DE INTERES SOCIAL": {}, - "OTROS": {}, - "PAPELES COMERCIALES": {}, - "TITULOS": {} - }, - "CORPORACIONES DE AHORRO Y VIVIENDA": { - "HIPOTECARIAS": {}, - "PAGARES": {}, - "SOBREGIROS": {} - }, - "CORPORACIONES FINANCIERAS": { - "ACEPTACIONES FINANCIERAS": {}, - "CARTAS DE CREDITO": {}, - "CONTRATOS DE ARRENDAMIENTO FINANCIERO (LEASING)": {}, - "PAGARES": {} - }, - "ENTIDADES FINANCIERAS DEL EXTERIOR": {}, - "OBLIGACIONES GUBERNAMENTALES": { - "ENTIDADES OFICIALES": {}, - "GOBIERNO NACIONAL": {} - }, - "OTRAS OBLIGACIONES": { - "CASA MATRIZ": {}, - "COMPANIAS VINCULADAS": {}, - "DIRECTORES": {}, - "FONDOS Y COOPERATIVAS": {}, - "OTRAS": {}, - "PARTICULARES": { - "PARTICULARES": {} - }, - "SOCIOS O ACCIONISTAS": {} - } - }, - "OBLIGACIONES LABORALES": { - "CESANTIAS CONSOLIDADAS": { - "LEY 50 DE 1990 Y NORMAS POSTERIORES": {}, - "LEY LABORAL ANTERIOR": {} - }, - "CUOTAS PARTES PENSIONES DE JUBILACION": {}, - "INDEMNIZACIONES LABORALES": {}, - "INTERESES SOBRE CESANTIAS": {}, - "PENSIONES POR PAGAR": {}, - "PRESTACIONES EXTRALEGALES": { - "AUXILIOS": {}, - "BONIFICACIONES": {}, - "DOTACION Y SUMINISTRO A TRABAJADORES": {}, - "OTRAS": {}, - "PRIMAS": {}, - "SEGUROS": {} - }, - "PRIMA DE SERVICIOS": {}, - "SALARIOS POR PAGAR": {}, - "VACACIONES CONSOLIDADAS": {} - }, - "OTROS PASIVOS": { - "ACREEDORES DEL SISTEMA": { - "CUOTAS NETAS": {}, - "GRUPOS EN FORMACION": {} - }, - "ANTICIPOS Y AVANCES RECIBIDOS": { - "DE CLIENTES": {}, - "OTROS": {}, - "PARA OBRAS EN PROCESO": {}, - "SOBRE CONTRATOS": {} - }, - "CUENTAS DE OPERACION CONJUNTA": {}, - "CUENTAS EN PARTICIPACION": {}, - "DEPOSITOS RECIBIDOS": { - "DE LICITACIONES": {}, - "DE MANEJO DE BIENES": {}, - "FONDO DE RESERVA": {}, - "OTROS": {}, - "PARA FUTURA SUSCRIPCION DE ACCIONES": {}, - "PARA FUTURO PAGO DE CUOTAS O DERECHOS SOCIALES": {}, - "PARA GARANTIA DE CONTRATOS": {}, - "PARA GARANTIA EN LA PRESTACION DE SERVICIOS": {} - }, - "DIVERSOS": { - "PRESTAMOS DE PRODUCTOS": {}, - "PROGRAMA DE EXTENSION AGROPECUARIA": {}, - "REEMBOLSO DE COSTOS EXPLORATORIOS": {} - }, - "EMBARGOS JUDICIALES": { - "DEPOSITOS JUDICIALES": {}, - "INDEMNIZACIONES": {} - }, - "INGRESOS RECIBIDOS PARA TERCEROS": { - "VALORES RECIBIDOS PARA TERCEROS": {}, - "VENTA POR CUENTA DE TERCEROS": {} - }, - "RETENCIONES A TERCEROS SOBRE CONTRATOS": { - "CUMPLIMIENTO OBLIGACIONES LABORALES": {}, - "GARANTIA CUMPLIMIENTO DE CONTRATOS": {}, - "PARA ESTABILIDAD DE OBRA": {} - } - }, - "PASIVOS ESTIMADOS Y PROVISIONES": { - "PARA CONTINGENCIAS": { - "ADMINISTRATIVOS": {}, - "CIVILES": {}, - "COMERCIALES": {}, - "INTERESES POR MULTAS Y SANCIONES": {}, - "LABORALES": {}, - "MULTAS Y SANCIONES AUTORIDADES ADMINISTRATIVAS": {}, - "OTRAS": {}, - "PENALES": {}, - "RECLAMOS": {} - }, - "PARA COSTOS Y GASTOS": { - "COMISIONES": {}, - "GARANTIAS": {}, - "GASTOS DE VIAJE": {}, - "HONORARIOS": {}, - "INTERESES": {}, - "MATERIALES Y REPUESTOS": {}, - "OTROS": {}, - "REGALIAS": {}, - "SERVICIOS PUBLICOS": {}, - "SERVICIOS TECNICOS": {}, - "TRANSPORTES, FLETES Y ACARREOS": {} - }, - "PARA MANTENIMIENTO Y REPARACIONES": { - "ACUEDUCTOS, PLANTAS Y REDES": {}, - "ARMAMENTO DE VIGILANCIA": {}, - "CONSTRUCCIONES Y EDIFICACIONES": {}, - "ENVASES Y EMPAQUES": {}, - "EQUIPO DE COMPUTACION Y COMUNICACION": {}, - "EQUIPO DE HOTELES Y RESTAURANTES": {}, - "EQUIPO DE OFICINA": {}, - "EQUIPO MEDICO-CIENTIFICO": {}, - "FLOTA Y EQUIPO AEREO": {}, - "FLOTA Y EQUIPO DE TRANSPORTE": {}, - "FLOTA Y EQUIPO FERREO": {}, - "FLOTA Y EQUIPO FLUVIAL Y/O MARITIMO": {}, - "MAQUINARIA Y EQUIPO": {}, - "OTROS": {}, - "PLANTACIONES AGRICOLAS Y FORESTALES": {}, - "POZOS ARTESIANOS": {}, - "TERRENOS": {}, - "VIAS DE COMUNICACION": {} - }, - "PARA OBLIGACIONES DE GARANTIAS": {}, - "PARA OBLIGACIONES FISCALES": { - "DE HIDROCARBUROS Y MINAS": {}, - "DE INDUSTRIA Y COMERCIO": {}, - "DE RENTA Y COMPLEMENTARIOS": {}, - "DE VEHICULOS": {}, - "OTROS": {}, - "TASA POR UTILIZACION DE PUERTOS": {} - }, - "PARA OBLIGACIONES LABORALES": { - "CESANTIAS": {}, - "INTERESES SOBRE CESANTIAS": {}, - "OTRAS": {}, - "PRESTACIONES EXTRALEGALES": {}, - "PRIMA DE SERVICIOS": {}, - "VACACIONES": {}, - "VIATICOS": {} - }, - "PARA OBRAS DE URBANISMO": { - "ACUEDUCTO Y ALCANTARILLADO": {}, - "ENERGIA ELECTRICA": {}, - "OTROS": {}, - "TELEFONOS": {} - }, - "PENSIONES DE JUBILACION": { - "CALCULO ACTUARIAL PENSIONES DE JUBILACION": {}, - "PENSIONES DE JUBILACION POR AMORTIZAR (DB)": {} - }, - "PROVISIONES DIVERSAS": { - "AUTOSEGURO": {}, - "OTRAS": {}, - "PARA AJUSTES EN REDENCION DE UNIDADES": {}, - "PARA BENEFICENCIA": {}, - "PARA COMUNICACIONES": {}, - "PARA OPERACION": {}, - "PARA PERDIDA EN TRANSPORTE": {}, - "PARA PROTECCION DE BIENES AGOTABLES": {}, - "PLANES Y PROGRAMAS DE REFORESTACION Y ELECTRIFICACION": {} - } - }, - "PROVEEDORES": { - "CASA MATRIZ": {}, - "COMPANIAS VINCULADAS": {}, - "CUENTAS CORRIENTES COMERCIALES": {}, - "DEL EXTERIOR": { - "PROVEEDORES EXTRANJEROS CXP": { - "PROVEEDORES EXTRANJEROS CXP": {} - } - }, - "NACIONALES": { - "PROVEEDORES NACIONALES CXP": { - "PROVEEDORES NACIONALES CXP": {} - } - } - }, - "root_type": "Liability" - }, - "PATRIMONIO": { - "CAPITAL SOCIAL": { - "APORTES DEL ESTADO": {}, - "APORTES SOCIALES": { - "APORTES DE SOCIOS-FONDO MUTUO DE INVERSION": {}, - "CONTRIBUCION DE LA EMPRESA-FONDO MUTUO DE INVERSION": {}, - "CUOTAS O PARTES DE INTERES SOCIAL": {}, - "SUSCRIPCIONES DEL PUBLICO": {} - }, - "CAPITAL ASIGNADO": {}, - "CAPITAL DE PERSONAS NATURALES": {}, - "CAPITAL SUSCRITO Y PAGADO": { - "CAPITAL AUTORIZADO": {}, - "CAPITAL POR SUSCRIBIR (DB)": {}, - "CAPITAL SUSCRITO POR COBRAR (DB)": {}, - "CAPITAL SUSCRITO Y PAGADO": { - "CAPITAL SUSCRITO Y PAGADO": {} - } - }, - "FONDO SOCIAL": {}, - "INVERSION SUPLEMENTARIA AL CAPITAL ASIGNADO": {} - }, - "DIVIDENDOS O PARTICIPACIONES DECRETADOS EN ACCIONES, CUOTAS O PARTES DE INTERES SOCIAL": { - "DIVIDENDOS DECRETADOS EN ACCIONES": {}, - "PARTICIPACIONES DECRETADAS EN CUOTAS O PARTES DE INTERES SOCIAL": {} - }, - "RESERVAS": { - "RESERVAS ESTATUTARIAS": { - "OTRAS": {}, - "PARA FUTURAS CAPITALIZACIONES": {}, - "PARA FUTUROS ENSANCHES": {}, - "PARA REPOSICION DE ACTIVOS": {} - }, - "RESERVAS OBLIGATORIAS": { - "ACCIONES PROPIAS READQUIRIDAS (DB)": {}, - "CUOTAS O PARTES DE INTERES SOCIAL PROPIAS READQUIRIDAS (DB)": {}, - "OTRAS": {}, - "RESERVA LEGAL": {}, - "RESERVA LEY 4\u00aa DE 1980": {}, - "RESERVA LEY 7\u00aa DE 1990": {}, - "RESERVA PARA EXTENSION AGROPECUARIA": {}, - "RESERVA PARA READQUISICION DE ACCIONES": {}, - "RESERVA PARA READQUISICION DE CUOTAS O PARTES DE INTERES SOCIAL": {}, - "RESERVA PARA REPOSICION DE SEMOVIENTES": {}, - "RESERVAS POR DISPOSICIONES FISCALES": {} - }, - "RESERVAS OCASIONALES": { - "A DISPOSICION DEL MAXIMO ORGANO SOCIAL": {}, - "OTRAS": {}, - "PARA ADQUISICION O REPOSICION DE PROPIEDADES, PLANTA Y EQUIPO": {}, - "PARA BENEFICENCIA Y CIVISMO": {}, - "PARA CAPITAL DE TRABAJO": {}, - "PARA ESTABILIZACION DE RENDIMIENTOS": {}, - "PARA FOMENTO ECONOMICO": {}, - "PARA FUTURAS CAPITALIZACIONES": {}, - "PARA FUTUROS ENSANCHES": {}, - "PARA INVESTIGACIONES Y DESARROLLO": {} - } - }, - "RESULTADOS DE EJERCICIOS ANTERIORES": { - "PERDIDAS ACUMULADAS": {}, - "UTILIDADES ACUMULADAS": {} - }, - "RESULTADOS DEL EJERCICIO": { - "PERDIDA DEL EJERCICIO": {}, - "UTILIDAD DEL EJERCICIO": { - "UTILIDAD DEL EJERCICIO": { - "UTILIDAD DEL EJERCICIO": {} - } - } - }, - "REVALORIZACION DEL PATRIMONIO": { - "AJUSTES POR INFLACION": { - "DE ACTIVOS EN PERIODO IMPRODUCTIVO": {}, - "DE AJUSTES DECRETO 3019 DE 1989": {}, - "DE CAPITAL SOCIAL": {}, - "DE DIVIDENDOS Y PARTICIPACIONES DECRETADAS EN ACCIONES, CUOTAS O PARTES DE INTERES SOCIAL": {}, - "DE RESERVAS": {}, - "DE RESULTADOS DE EJERCICIOS ANTERIORES": {}, - "DE SANEAMIENTO FISCAL": {}, - "DE SUPERAVIT DE CAPITAL": {}, - "SUPERAVIT METODO DE PARTICIPACION": {} - }, - "AJUSTES POR INFLACION DECRETO 3019 DE 1989": {}, - "SANEAMIENTO FISCAL": {} - }, - "SUPERAVIT DE CAPITAL": { - "CREDITO MERCANTIL": {}, - "DONACIONES": { - "EN BIENES INMUEBLES": {}, - "EN BIENES MUEBLES": {}, - "EN DINERO": {}, - "EN INTANGIBLES": {}, - "EN VALORES MOBILIARIOS": {} - }, - "KNOW HOW": {}, - "PRIMA EN COLOCACION DE ACCIONES, CUOTAS O PARTES DE INTERES SOCIAL": { - "PRIMA EN COLOCACION DE ACCIONES": {}, - "PRIMA EN COLOCACION DE ACCIONES POR COBRAR (DB)": {}, - "PRIMA EN COLOCACION DE CUOTAS O PARTES DE INTERES SOCIAL": {} - }, - "SUPERAVIT METODO DE PARTICIPACION": { - "DE ACCIONES": {}, - "DE CUOTAS O PARTES DE INTERES SOCIAL": {} - } - }, - "SUPERAVIT POR VALORIZACIONES": { - "DE INVERSIONES": { - "ACCIONES": {}, - "CUOTAS O PARTES DE INTERES SOCIAL": {}, - "DERECHOS FIDUCIARIOS": {} - }, - "DE OTROS ACTIVOS": { - "BIENES DE ARTE Y CULTURA": {}, - "BIENES ENTREGADOS EN COMODATO": {}, - "BIENES RECIBIDOS EN PAGO": {}, - "INVENTARIO DE SEMOVIENTES": {} - }, - "DE PROPIEDADES, PLANTA Y EQUIPO": { - "ACUEDUCTOS, PLANTAS Y REDES": {}, - "ARMAMENTO DE VIGILANCIA": {}, - "CONSTRUCCIONES Y EDIFICACIONES": {}, - "ENVASES Y EMPAQUES": {}, - "EQUIPO DE COMPUTACION Y COMUNICACION": {}, - "EQUIPO DE HOTELES Y RESTAURANTES": {}, - "EQUIPO DE OFICINA": {}, - "EQUIPO MEDICO-CIENTIFICO": {}, - "FLOTA Y EQUIPO AEREO": {}, - "FLOTA Y EQUIPO DE TRANSPORTE": {}, - "FLOTA Y EQUIPO FERREO": {}, - "FLOTA Y EQUIPO FLUVIAL Y/O MARITIMO": {}, - "MAQUINARIA Y EQUIPO": {}, - "MATERIALES PROYECTOS PETROLEROS": {}, - "MINAS Y CANTERAS": {}, - "PLANTACIONES AGRICOLAS Y FORESTALES": {}, - "POZOS ARTESIANOS": {}, - "SEMOVIENTES": {}, - "TERRENOS": {}, - "VIAS DE COMUNICACION": {}, - "YACIMIENTOS": {} - } - }, - "root_type": "Asset" - } - } -} diff --git a/erpnext/accounts/doctype/account/chart_of_accounts/verified/co_plan_unico_de_cuentas.json b/erpnext/accounts/doctype/account/chart_of_accounts/verified/co_plan_unico_de_cuentas.json new file mode 100644 index 0000000000..622f4b661b --- /dev/null +++ b/erpnext/accounts/doctype/account/chart_of_accounts/verified/co_plan_unico_de_cuentas.json @@ -0,0 +1,9400 @@ +{ + "country_code": "co", + "name": "Colombia PUC", + "tree": { + "Activo": { + "account_number": "1", + "root_type": "Asset", + "Disponible": { + "account_number": "11", + "Caja": { + "account_number": "1105", + "account_type": "Cash", + "Caja general": { + "account_number": "110505", + "account_type": "Cash" + }, + "Cajas menores": { + "account_number": "110510", + "account_type": "Cash" + }, + "Moneda extranjera": { + "account_number": "110515", + "account_type": "Cash" + } + }, + "Bancos": { + "account_number": "1110", + "account_type": "Bank", + "Moneda nacional": { + "account_number": "111005", + "account_type": "Bank" + }, + "Moneda extranjera": { + "account_number": "111010", + "account_type": "Bank" + } + }, + "Remesas en tr\u00e1nsito": { + "account_number": "1115", + "Moneda nacional": { + "account_number": "111505" + }, + "Moneda extranjera": { + "account_number": "111510" + } + }, + "Cuentas de ahorro": { + "account_number": "1120", + "Bancos": { + "account_number": "112005" + }, + "Corporaciones de ahorro y vivienda": { + "account_number": "112010" + }, + "Organismos cooperativos financieros": { + "account_number": "112015" + } + }, + "Fondos": { + "account_number": "1125", + "Rotatorios moneda nacional": { + "account_number": "112505" + }, + "Rotatorios moneda extranjera": { + "account_number": "112510" + }, + "Especiales moneda nacional": { + "account_number": "112515" + }, + "Especiales moneda extranjera": { + "account_number": "112520" + }, + "De amortizaci\u00f3n moneda nacional": { + "account_number": "112525" + }, + "De amortizaci\u00f3n moneda extranjera": { + "account_number": "112530" + } + } + }, + "Inversiones": { + "account_number": "12", + "Acciones": { + "account_number": "1205", + "Agricultura, ganader\u00eda, caza y silvicultura": { + "account_number": "120505" + }, + "Pesca": { + "account_number": "120510" + }, + "Explotaci\u00f3n de minas y canteras": { + "account_number": "120515" + }, + "Industria manufacturera": { + "account_number": "120520" + }, + "Suministro de electricidad, gas y agua": { + "account_number": "120525" + }, + "Construcci\u00f3n": { + "account_number": "120530" + }, + "Comercio al por mayor y al por menor": { + "account_number": "120535" + }, + "Hoteles y restaurantes": { + "account_number": "120540" + }, + "Transporte, almacenamiento y comunicaciones": { + "account_number": "120545" + }, + "Actividad financiera": { + "account_number": "120550" + }, + "Actividades inmobiliarias, empresariales y de alquiler": { + "account_number": "120555" + }, + "Ense\u00f1anza": { + "account_number": "120560" + }, + "Servicios sociales y de salud": { + "account_number": "120565" + }, + "Otras actividades de servicios comunitarios, sociales y personales": { + "account_number": "120570" + }, + "Ajustes por inflaci\u00f3n": { + "account_number": "120599" + } + }, + "Cuotas o partes de inter\u00e9s social": { + "account_number": "1210", + "Agricultura, ganader\u00eda, caza y silvicultura": { + "account_number": "121005" + }, + "Pesca": { + "account_number": "121010" + }, + "Explotaci\u00f3n de minas y canteras": { + "account_number": "121015" + }, + "Industria manufacturera": { + "account_number": "121020" + }, + "Suministro de electricidad, gas y agua": { + "account_number": "121025" + }, + "Construcci\u00f3n": { + "account_number": "121030" + }, + "Comercio al por mayor y al por menor": { + "account_number": "121035" + }, + "Hoteles y restaurantes": { + "account_number": "121040" + }, + "Transporte, almacenamiento y comunicaciones": { + "account_number": "121045" + }, + "Actividad financiera": { + "account_number": "121050" + }, + "Actividades inmobiliarias, empresariales y de alquiler": { + "account_number": "121055" + }, + "Ense\u00f1anza": { + "account_number": "121060" + }, + "Servicios sociales y de salud": { + "account_number": "121065" + }, + "Otras actividades de servicios comunitarios, sociales y personales": { + "account_number": "121070" + }, + "Ajustes por inflaci\u00f3n": { + "account_number": "121099" + } + }, + "Bonos": { + "account_number": "1215", + "Bonos p\u00fablicos moneda nacional": { + "account_number": "121505" + }, + "Bonos p\u00fablicos moneda extranjera": { + "account_number": "121510" + }, + "Bonos ordinarios": { + "account_number": "121515" + }, + "Bonos convertibles en acciones": { + "account_number": "121520" + }, + "Otros": { + "account_number": "121595" + } + }, + "C\u00e9dulas": { + "account_number": "1220", + "C\u00e9dulas de capitalizaci\u00f3n": { + "account_number": "122005" + }, + "C\u00e9dulas hipotecarias": { + "account_number": "122010" + }, + "C\u00e9dulas de inversi\u00f3n": { + "account_number": "122015" + }, + "Otras": { + "account_number": "122095" + } + }, + "Certificados": { + "account_number": "1225", + "Certificados de dep\u00f3sito a t\u00e9rmino (CDT)": { + "account_number": "122505" + }, + "Certificados de dep\u00f3sito de ahorro": { + "account_number": "122510" + }, + "Certificados de ahorro de valor constante (CAVC)": { + "account_number": "122515" + }, + "Certificados de cambio": { + "account_number": "122520" + }, + "Certificados cafeteros valorizables": { + "account_number": "122525" + }, + "Certificados el\u00e9ctricos valorizables (CEV)": { + "account_number": "122530" + }, + "Certificados de reembolso tributario (CERT)": { + "account_number": "122535" + }, + "Certificados de desarrollo tur\u00edstico": { + "account_number": "122540" + }, + "Certificados de inversi\u00f3n forestal (CIF)": { + "account_number": "122545" + }, + "Otros": { + "account_number": "122595" + } + }, + "Papeles comerciales": { + "account_number": "1230", + "Empresas comerciales": { + "account_number": "123005" + }, + "Empresas industriales": { + "account_number": "123010" + }, + "Empresas de servicios": { + "account_number": "123015" + } + }, + "T\u00edtulos": { + "account_number": "1235", + "T\u00edtulos de desarrollo agropecuario": { + "account_number": "123505" + }, + "T\u00edtulos canjeables por certificados de cambio": { + "account_number": "123510" + }, + "T\u00edtulos de tesorer\u00eda (TES)": { + "account_number": "123515" + }, + "T\u00edtulos de participaci\u00f3n": { + "account_number": "123520" + }, + "T\u00edtulos de cr\u00e9dito de fomento": { + "account_number": "123525" + }, + "T\u00edtulos financieros agroindustriales (TFA)": { + "account_number": "123530" + }, + "T\u00edtulos de ahorro cafetero (TAC)": { + "account_number": "123535" + }, + "T\u00edtulos de ahorro nacional (TAN)": { + "account_number": "123540" + }, + "T\u00edtulos energ\u00e9ticos de rentabilidad creciente (TER)": { + "account_number": "123545" + }, + "T\u00edtulos de ahorro educativo (TAE)": { + "account_number": "123550" + }, + "T\u00edtulos financieros industriales y comerciales": { + "account_number": "123555" + }, + "Tesoros": { + "account_number": "123560" + }, + "T\u00edtulos de devoluci\u00f3n de impuestos nacionales (TIDIS)": { + "account_number": "123565" + }, + "T\u00edtulos inmobiliarios": { + "account_number": "123570" + }, + "Otros": { + "account_number": "123595" + } + }, + "Aceptaciones bancarias o financieras": { + "account_number": "1240", + "Bancos comerciales": { + "account_number": "124005" + }, + "Compa\u00f1\u00edas de financiamiento comercial": { + "account_number": "124010" + }, + "Corporaciones financieras": { + "account_number": "124015" + }, + "Otras": { + "account_number": "124095" + } + }, + "Derechos fiduciarios": { + "account_number": "1245", + "Fideicomisos de inversi\u00f3n moneda nacional": { + "account_number": "124505" + }, + "Fideicomisos de inversi\u00f3n moneda extranjera": { + "account_number": "124510" + } + }, + "Derechos de recompra de inversiones negociadas (repos)": { + "account_number": "1250", + "Acciones": { + "account_number": "125005" + }, + "Cuotas o partes de inter\u00e9s social": { + "account_number": "125010" + }, + "Bonos": { + "account_number": "125015" + }, + "C\u00e9dulas": { + "account_number": "125020" + }, + "Certificados": { + "account_number": "125025" + }, + "Papeles comerciales": { + "account_number": "125030" + }, + "T\u00edtulos": { + "account_number": "125035" + }, + "Aceptaciones bancarias o financieras": { + "account_number": "125040" + }, + "Otros": { + "account_number": "125095" + }, + "Ajustes por inflaci\u00f3n": { + "account_number": "125099" + } + }, + "Obligatorias": { + "account_number": "1255", + "Bonos de financiamiento especial": { + "account_number": "125505" + }, + "Bonos de financiamiento presupuestal": { + "account_number": "125510" + }, + "Bonos para desarrollo social y seguridad interna (BDSI)": { + "account_number": "125515" + }, + "Otras": { + "account_number": "125595" + } + }, + "Cuentas en participaci\u00f3n": { + "account_number": "1260", + "Ajustes por inflaci\u00f3n": { + "account_number": "126099" + } + }, + "Otras inversiones": { + "account_number": "1295", + "Aportes en cooperativas": { + "account_number": "129505" + }, + "Derechos en clubes sociales": { + "account_number": "129510" + }, + "Acciones o derechos en clubes deportivos": { + "account_number": "129515" + }, + "Bonos en colegios": { + "account_number": "129520" + }, + "Diversas": { + "account_number": "129595" + }, + "Ajustes por inflaci\u00f3n": { + "account_number": "129599" + } + }, + "Provisiones": { + "account_number": "1299", + "Acciones": { + "account_number": "129905" + }, + "Cuotas o partes de inter\u00e9s social": { + "account_number": "129910" + }, + "Bonos": { + "account_number": "129915" + }, + "C\u00e9dulas": { + "account_number": "129920" + }, + "Certificados": { + "account_number": "129925" + }, + "Papeles comerciales": { + "account_number": "129930" + }, + "T\u00edtulos": { + "account_number": "129935" + }, + "Aceptaciones bancarias o financieras": { + "account_number": "129940" + }, + "Derechos fiduciarios": { + "account_number": "129945" + }, + "Derechos de recompra de inversiones negociadas": { + "account_number": "129950" + }, + "Obligatorias": { + "account_number": "129955" + }, + "Cuentas en participaci\u00f3n": { + "account_number": "129960" + }, + "Otras inversiones": { + "account_number": "129995" + } + } + }, + "Deudores": { + "account_number": "13", + "account_type": "Receivable", + "Clientes": { + "account_number": "1305", + "account_type": "Receivable", + "Nacionales": { + "account_number": "130505", + "account_type": "Receivable" + }, + "Del exterior": { + "account_number": "130510", + "account_type": "Receivable" + }, + "Deudores del sistema": { + "account_number": "130515", + "account_type": "Receivable" + } + }, + "Cuentas corrientes comerciales": { + "account_number": "1310", + "account_type": "Receivable", + "Casa matriz": { + "account_number": "131005", + "account_type": "Receivable" + }, + "Compa\u00f1\u00edas vinculadas": { + "account_number": "131010", + "account_type": "Receivable" + }, + "Accionistas o socios": { + "account_number": "131015", + "account_type": "Receivable" + }, + "Particulares": { + "account_number": "131020", + "account_type": "Receivable" + }, + "Otras": { + "account_number": "131095", + "account_type": "Receivable" + } + }, + "Cuentas por cobrar a casa matriz": { + "account_number": "1315", + "account_type": "Receivable", + "Ventas": { + "account_number": "131505", + "account_type": "Receivable" + }, + "Pagos a nombre de casa matriz": { + "account_number": "131510", + "account_type": "Receivable" + }, + "Valores recibidos por casa matriz": { + "account_number": "131515", + "account_type": "Receivable" + }, + "Pr\u00e9stamos": { + "account_number": "131520", + "account_type": "Receivable" + } + }, + "Cuentas por cobrar a vinculados econ\u00f3micos": { + "account_number": "1320", + "account_type": "Receivable", + "Filiales": { + "account_number": "132005", + "account_type": "Receivable" + }, + "Subsidiarias": { + "account_number": "132010", + "account_type": "Receivable" + }, + "Sucursales": { + "account_number": "132015", + "account_type": "Receivable" + } + }, + "Cuentas por cobrar a directores": { + "account_number": "1323", + "account_type": "Receivable" + }, + "Cuentas por cobrar a socios y accionistas": { + "account_number": "1325", + "account_type": "Receivable", + "A socios": { + "account_number": "132505", + "account_type": "Receivable" + }, + "A accionistas": { + "account_number": "132510", + "account_type": "Receivable" + } + }, + "Aportes por cobrar": { + "account_number": "1328", + "account_type": "Receivable" + }, + "Anticipos y avances": { + "account_number": "1330", + "account_type": "Receivable", + "A proveedores": { + "account_number": "133005", + "account_type": "Receivable" + }, + "A contratistas": { + "account_number": "133010", + "account_type": "Receivable" + }, + "A trabajadores": { + "account_number": "133015", + "account_type": "Receivable" + }, + "A agentes": { + "account_number": "133020", + "account_type": "Receivable" + }, + "A concesionarios": { + "account_number": "133025", + "account_type": "Receivable" + }, + "De adjudicaciones": { + "account_number": "133030", + "account_type": "Receivable" + }, + "Otros": { + "account_number": "133095", + "account_type": "Receivable" + }, + "Ajustes por inflaci\u00f3n": { + "account_number": "133099", + "account_type": "Receivable" + } + }, + "Cuentas de operaci\u00f3n conjunta": { + "account_number": "1332", + "account_type": "Receivable" + }, + "Dep\u00f3sitos": { + "account_number": "1335", + "account_type": "Receivable", + "Para importaciones": { + "account_number": "133505", + "account_type": "Receivable" + }, + "Para servicios": { + "account_number": "133510", + "account_type": "Receivable" + }, + "Para contratos": { + "account_number": "133515", + "account_type": "Receivable" + }, + "Para responsabilidades": { + "account_number": "133520", + "account_type": "Receivable" + }, + "Para juicios ejecutivos": { + "account_number": "133525", + "account_type": "Receivable" + }, + "Para adquisici\u00f3n de acciones, cuotas o derechos sociales": { + "account_number": "133530", + "account_type": "Receivable" + }, + "En garant\u00eda": { + "account_number": "133535", + "account_type": "Receivable" + }, + "Otros": { + "account_number": "133595", + "account_type": "Receivable" + } + }, + "Promesas de compra venta": { + "account_number": "1340", + "account_type": "Receivable", + "De bienes ra\u00edces": { + "account_number": "134005", + "account_type": "Receivable" + }, + "De maquinaria y equipo": { + "account_number": "134010", + "account_type": "Receivable" + }, + "De flota y equipo de transporte": { + "account_number": "134015", + "account_type": "Receivable" + }, + "De flota y equipo a\u00e9reo": { + "account_number": "134020", + "account_type": "Receivable" + }, + "De flota y equipo f\u00e9rreo": { + "account_number": "134025", + "account_type": "Receivable" + }, + "De flota y equipo fluvial y/o mar\u00edtimo": { + "account_number": "134030", + "account_type": "Receivable" + }, + "De semovientes": { + "account_number": "134035", + "account_type": "Receivable" + }, + "De otros bienes": { + "account_number": "134095", + "account_type": "Receivable" + } + }, + "Ingresos por cobrar": { + "account_number": "1345", + "account_type": "Receivable", + "Dividendos y/o participaciones": { + "account_number": "134505", + "account_type": "Receivable" + }, + "Intereses": { + "account_number": "134510", + "account_type": "Receivable" + }, + "Comisiones": { + "account_number": "134515", + "account_type": "Receivable" + }, + "Honorarios": { + "account_number": "134520", + "account_type": "Receivable" + }, + "Servicios": { + "account_number": "134525", + "account_type": "Receivable" + }, + "Arrendamientos": { + "account_number": "134530", + "account_type": "Receivable" + }, + "CERT por cobrar": { + "account_number": "134535", + "account_type": "Receivable" + }, + "Otros": { + "account_number": "134595", + "account_type": "Receivable" + } + }, + "Retenci\u00f3n sobre contratos": { + "account_number": "1350", + "account_type": "Receivable", + "De construcci\u00f3n": { + "account_number": "135005", + "account_type": "Receivable" + }, + "De prestaci\u00f3n de servicios": { + "account_number": "135010", + "account_type": "Receivable" + }, + "Otros": { + "account_number": "135095", + "account_type": "Receivable" + } + }, + "Anticipo de impuestos y contribuciones o saldos a favor": { + "account_number": "1355", + "account_type": "Receivable", + "Anticipo de impuestos de renta y complementarios": { + "account_number": "135505", + "account_type": "Receivable" + }, + "Anticipo de impuestos de industria y comercio": { + "account_number": "135510", + "account_type": "Receivable" + }, + "Retenci\u00f3n en la fuente": { + "account_number": "135515", + "account_type": "Receivable" + }, + "Impuesto a las ventas retenido": { + "account_number": "135517", + "account_type": "Receivable" + }, + "Impuesto de industria y comercio retenido": { + "account_number": "135518", + "account_type": "Receivable" + }, + "Sobrantes en liquidaci\u00f3n privada de impuestos": { + "account_number": "135520", + "account_type": "Receivable" + }, + "Contribuciones": { + "account_number": "135525", + "account_type": "Receivable" + }, + "Impuestos descontables": { + "account_number": "135530", + "account_type": "Receivable" + }, + "Otros": { + "account_number": "135595", + "account_type": "Receivable" + } + }, + "Reclamaciones": { + "account_number": "1360", + "account_type": "Receivable", + "A compa\u00f1\u00edas aseguradoras": { + "account_number": "136005", + "account_type": "Receivable" + }, + "A transportadores": { + "account_number": "136010", + "account_type": "Receivable" + }, + "Por tiquetes a\u00e9reos": { + "account_number": "136015", + "account_type": "Receivable" + }, + "Otras": { + "account_number": "136095", + "account_type": "Receivable" + } + }, + "Cuentas por cobrar a trabajadores": { + "account_number": "1365", + "account_type": "Receivable", + "Vivienda": { + "account_number": "136505", + "account_type": "Receivable" + }, + "Veh\u00edculos": { + "account_number": "136510", + "account_type": "Receivable" + }, + "Educaci\u00f3n": { + "account_number": "136515", + "account_type": "Receivable" + }, + "M\u00e9dicos, odontol\u00f3gicos y similares": { + "account_number": "136520", + "account_type": "Receivable" + }, + "Calamidad dom\u00e9stica": { + "account_number": "136525", + "account_type": "Receivable" + }, + "Responsabilidades": { + "account_number": "136530", + "account_type": "Receivable" + }, + "Otros": { + "account_number": "136595", + "account_type": "Receivable" + } + }, + "Pr\u00e9stamos a particulares": { + "account_number": "1370", + "account_type": "Receivable", + "Con garant\u00eda real": { + "account_number": "137005", + "account_type": "Receivable" + }, + "Con garant\u00eda personal": { + "account_number": "137010", + "account_type": "Receivable" + } + }, + "Deudores varios": { + "account_number": "1380", + "account_type": "Receivable", + "Depositarios": { + "account_number": "138005", + "account_type": "Receivable" + }, + "Comisionistas de bolsas": { + "account_number": "138010", + "account_type": "Receivable" + }, + "Fondo de inversi\u00f3n": { + "account_number": "138015", + "account_type": "Receivable" + }, + "Cuentas por cobrar de terceros": { + "account_number": "138020", + "account_type": "Receivable" + }, + "Pagos por cuenta de terceros": { + "account_number": "138025", + "account_type": "Receivable" + }, + "Fondos de inversi\u00f3n social": { + "account_number": "138030", + "account_type": "Receivable" + }, + "Otros": { + "account_number": "138095", + "account_type": "Receivable" + } + }, + "Derechos de recompra de cartera negociada": { + "account_number": "1385", + "account_type": "Receivable" + }, + "Deudas de dif\u00edcil cobro": { + "account_number": "1390", + "account_type": "Receivable" + }, + "Provisiones": { + "account_number": "1399", + "account_type": "Receivable", + "Clientes": { + "account_number": "139905", + "account_type": "Receivable" + }, + "Cuentas corrientes comerciales": { + "account_number": "139910", + "account_type": "Receivable" + }, + "Cuentas por cobrar a casa matriz": { + "account_number": "139915", + "account_type": "Receivable" + }, + "Cuentas por cobrar a vinculados econ\u00f3micos": { + "account_number": "139920", + "account_type": "Receivable" + }, + "Cuentas por cobrar a socios y accionistas": { + "account_number": "139925", + "account_type": "Receivable" + }, + "Anticipos y avances": { + "account_number": "139930", + "account_type": "Receivable" + }, + "Cuentas de operaci\u00f3n conjunta": { + "account_number": "139932", + "account_type": "Receivable" + }, + "Dep\u00f3sitos": { + "account_number": "139935", + "account_type": "Receivable" + }, + "Promesas de compraventa": { + "account_number": "139940", + "account_type": "Receivable" + }, + "Ingresos por cobrar": { + "account_number": "139945", + "account_type": "Receivable" + }, + "Retenci\u00f3n sobre contratos": { + "account_number": "139950", + "account_type": "Receivable" + }, + "Reclamaciones": { + "account_number": "139955", + "account_type": "Receivable" + }, + "Cuentas por cobrar a trabajadores": { + "account_number": "139960", + "account_type": "Receivable" + }, + "Pr\u00e9stamos a particulares": { + "account_number": "139965", + "account_type": "Receivable" + }, + "Deudores varios": { + "account_number": "139975", + "account_type": "Receivable" + }, + "Derechos de recompra de cartera negociada": { + "account_number": "139980", + "account_type": "Receivable" + } + } + }, + "Inventarios": { + "account_number": "14", + "account_type": "Stock", + "Materias primas": { + "account_number": "1405", + "account_type": "Stock", + "Ajustes por inflaci\u00f3n": { + "account_number": "140599", + "account_type": "Stock" + } + }, + "Productos en proceso": { + "account_number": "1410", + "account_type": "Stock", + "Ajustes por inflaci\u00f3n": { + "account_number": "141099", + "account_type": "Stock" + } + }, + "Obras de construcci\u00f3n en curso": { + "account_number": "1415", + "account_type": "Stock", + "Ajustes por inflaci\u00f3n": { + "account_number": "141599", + "account_type": "Stock" + } + }, + "Obras de urbanismo": { + "account_number": "1417", + "account_type": "Stock", + "Ajustes por inflaci\u00f3n": { + "account_number": "141799", + "account_type": "Stock" + } + }, + "Contratos en ejecuci\u00f3n": { + "account_number": "1420", + "account_type": "Stock", + "Ajustes por inflaci\u00f3n": { + "account_number": "142099", + "account_type": "Stock" + } + }, + "Cultivos en desarrollo": { + "account_number": "1425", + "account_type": "Stock", + "Ajustes por inflaci\u00f3n": { + "account_number": "142599", + "account_type": "Stock" + } + }, + "Plantaciones agr\u00edcolas": { + "account_number": "1428", + "account_type": "Stock", + "Ajustes por inflaci\u00f3n": { + "account_number": "142899", + "account_type": "Stock" + } + }, + "Productos terminados": { + "account_number": "1430", + "account_type": "Stock", + "Productos manufacturados": { + "account_number": "143005", + "account_type": "Stock" + }, + "Productos extra\u00eddos y/o procesados": { + "account_number": "143010", + "account_type": "Stock" + }, + "Productos agr\u00edcolas y forestales": { + "account_number": "143015", + "account_type": "Stock" + }, + "Subproductos": { + "account_number": "143020", + "account_type": "Stock" + }, + "Productos de pesca": { + "account_number": "143025", + "account_type": "Stock" + }, + "Ajustes por inflaci\u00f3n": { + "account_number": "143099", + "account_type": "Stock" + } + }, + "Mercanc\u00edas no fabricadas por la empresa": { + "account_number": "1435", + "account_type": "Stock", + "Ajustes por inflaci\u00f3n": { + "account_number": "143599", + "account_type": "Stock" + } + }, + "Bienes ra\u00edces para la venta": { + "account_number": "1440", + "account_type": "Stock", + "Ajustes por inflaci\u00f3n": { + "account_number": "144099", + "account_type": "Stock" + } + }, + "Semovientes": { + "account_number": "1445", + "account_type": "Stock", + "Ajustes por inflaci\u00f3n": { + "account_number": "144599", + "account_type": "Stock" + } + }, + "Terrenos": { + "account_number": "1450", + "account_type": "Stock", + "Por urbanizar": { + "account_number": "145005", + "account_type": "Stock" + }, + "Urbanizados por construir": { + "account_number": "145010", + "account_type": "Stock" + }, + "Ajustes por inflaci\u00f3n": { + "account_number": "145099", + "account_type": "Stock" + } + }, + "Materiales, repuestos y accesorios": { + "account_number": "1455", + "account_type": "Stock", + "Ajustes por inflaci\u00f3n": { + "account_number": "145599", + "account_type": "Stock" + } + }, + "Envases y empaques": { + "account_number": "1460", + "account_type": "Stock", + "Ajustes por inflaci\u00f3n": { + "account_number": "146099", + "account_type": "Stock" + } + }, + "Inventarios en tr\u00e1nsito": { + "account_number": "1465", + "account_type": "Stock", + "Ajustes por inflaci\u00f3n": { + "account_number": "146599", + "account_type": "Stock" + } + }, + "Provisiones": { + "account_number": "1499", + "account_type": "Stock", + "Para obsolescencia": { + "account_number": "149905", + "account_type": "Stock" + }, + "Para diferencia de inventario f\u00edsico": { + "account_number": "149910", + "account_type": "Stock" + }, + "Para p\u00e9rdidas de inventarios": { + "account_number": "149915", + "account_type": "Stock" + }, + "Lifo": { + "account_number": "149920", + "account_type": "Stock" + } + } + }, + "Propiedades, planta y equipo": { + "account_number": "15", + "account_type": "Fixed Asset", + "Terrenos": { + "account_number": "1504", + "account_type": "Fixed Asset", + "Urbanos": { + "account_number": "150405", + "account_type": "Fixed Asset" + }, + "Rurales": { + "account_number": "150410", + "account_type": "Fixed Asset" + }, + "Ajustes por inflaci\u00f3n": { + "account_number": "150499", + "account_type": "Fixed Asset" + } + }, + "Materiales proyectos petroleros": { + "account_number": "1506", + "account_type": "Fixed Asset", + "Tuber\u00edas y equipo": { + "account_number": "150605", + "account_type": "Fixed Asset" + }, + "Costos de importaci\u00f3n materiales": { + "account_number": "150610", + "account_type": "Fixed Asset" + }, + "Proyectos de construcci\u00f3n": { + "account_number": "150615", + "account_type": "Fixed Asset" + }, + "Ajustes por inflaci\u00f3n": { + "account_number": "150699", + "account_type": "Fixed Asset" + } + }, + "Construcciones en curso": { + "account_number": "1508", + "account_type": "Fixed Asset", + "Construcciones y edificaciones": { + "account_number": "150805", + "account_type": "Fixed Asset" + }, + "Acueductos, plantas y redes": { + "account_number": "150810", + "account_type": "Fixed Asset" + }, + "V\u00edas de comunicaci\u00f3n": { + "account_number": "150815", + "account_type": "Fixed Asset" + }, + "Pozos artesianos": { + "account_number": "150820", + "account_type": "Fixed Asset" + }, + "Proyectos de exploraci\u00f3n": { + "account_number": "150825", + "account_type": "Fixed Asset" + }, + "Proyectos de desarrollo": { + "account_number": "150830", + "account_type": "Fixed Asset" + }, + "Ajustes por inflaci\u00f3n": { + "account_number": "150899", + "account_type": "Fixed Asset" + } + }, + "Maquinaria y equipos en montaje": { + "account_number": "1512", + "account_type": "Fixed Asset", + "Maquinaria y equipo": { + "account_number": "151205", + "account_type": "Fixed Asset" + }, + "Equipo de oficina": { + "account_number": "151210", + "account_type": "Fixed Asset" + }, + "Equipo de computaci\u00f3n y comunicaci\u00f3n": { + "account_number": "151215", + "account_type": "Fixed Asset" + }, + "Equipo m\u00e9dico-cient\u00edfico": { + "account_number": "151220", + "account_type": "Fixed Asset" + }, + "Equipo de hoteles y restaurantes": { + "account_number": "151225", + "account_type": "Fixed Asset" + }, + "Flota y equipo de transporte": { + "account_number": "151230", + "account_type": "Fixed Asset" + }, + "Flota y equipo fluvial y/o mar\u00edtimo": { + "account_number": "151235", + "account_type": "Fixed Asset" + }, + "Flota y equipo a\u00e9reo": { + "account_number": "151240", + "account_type": "Fixed Asset" + }, + "Flota y equipo f\u00e9rreo": { + "account_number": "151245", + "account_type": "Fixed Asset" + }, + "Plantas y redes": { + "account_number": "151250", + "account_type": "Fixed Asset" + }, + "Ajustes por inflaci\u00f3n": { + "account_number": "151299", + "account_type": "Fixed Asset" + } + }, + "Construcciones y edificaciones": { + "account_number": "1516", + "account_type": "Fixed Asset", + "Edificios": { + "account_number": "151605", + "account_type": "Fixed Asset" + }, + "Oficinas": { + "account_number": "151610", + "account_type": "Fixed Asset" + }, + "Almacenes": { + "account_number": "151615", + "account_type": "Fixed Asset" + }, + "F\u00e1bricas y plantas industriales": { + "account_number": "151620", + "account_type": "Fixed Asset" + }, + "Salas de exhibici\u00f3n y ventas": { + "account_number": "151625", + "account_type": "Fixed Asset" + }, + "Cafeter\u00eda y casinos": { + "account_number": "151630", + "account_type": "Fixed Asset" + }, + "Silos": { + "account_number": "151635", + "account_type": "Fixed Asset" + }, + "Invernaderos": { + "account_number": "151640", + "account_type": "Fixed Asset" + }, + "Casetas y campamentos": { + "account_number": "151645", + "account_type": "Fixed Asset" + }, + "Instalaciones agropecuarias": { + "account_number": "151650", + "account_type": "Fixed Asset" + }, + "Viviendas para empleados y obreros": { + "account_number": "151655", + "account_type": "Fixed Asset" + }, + "Terminal de buses y taxis": { + "account_number": "151660", + "account_type": "Fixed Asset" + }, + "Terminal mar\u00edtimo": { + "account_number": "151663", + "account_type": "Fixed Asset" + }, + "Terminal f\u00e9rreo": { + "account_number": "151665", + "account_type": "Fixed Asset" + }, + "Parqueaderos, garajes y dep\u00f3sitos": { + "account_number": "151670", + "account_type": "Fixed Asset" + }, + "Hangares": { + "account_number": "151675", + "account_type": "Fixed Asset" + }, + "Bodegas": { + "account_number": "151680", + "account_type": "Fixed Asset" + }, + "Otros": { + "account_number": "151695", + "account_type": "Fixed Asset" + }, + "Ajustes por inflaci\u00f3n": { + "account_number": "151699", + "account_type": "Fixed Asset" + } + }, + "Maquinaria y equipo": { + "account_number": "1520", + "account_type": "Fixed Asset", + "Ajustes por inflaci\u00f3n": { + "account_number": "152099", + "account_type": "Fixed Asset" + } + }, + "Equipo de oficina": { + "account_number": "1524", + "account_type": "Fixed Asset", + "Muebles y enseres": { + "account_number": "152405", + "account_type": "Fixed Asset" + }, + "Equipos": { + "account_number": "152410", + "account_type": "Fixed Asset" + }, + "Otros": { + "account_number": "152495", + "account_type": "Fixed Asset" + }, + "Ajustes por inflaci\u00f3n": { + "account_number": "152499", + "account_type": "Fixed Asset" + } + }, + "Equipo de computaci\u00f3n y comunicaci\u00f3n": { + "account_number": "1528", + "account_type": "Fixed Asset", + "Equipos de procesamiento de datos": { + "account_number": "152805", + "account_type": "Fixed Asset" + }, + "Equipos de telecomunicaciones": { + "account_number": "152810", + "account_type": "Fixed Asset" + }, + "Equipos de radio": { + "account_number": "152815", + "account_type": "Fixed Asset" + }, + "Sat\u00e9lites y antenas": { + "account_number": "152820", + "account_type": "Fixed Asset" + }, + "L\u00edneas telef\u00f3nicas": { + "account_number": "152825", + "account_type": "Fixed Asset" + }, + "Otros": { + "account_number": "152895", + "account_type": "Fixed Asset" + }, + "Ajustes por inflaci\u00f3n": { + "account_number": "152899", + "account_type": "Fixed Asset" + } + }, + "Equipo m\u00e9dico-cient\u00edfico": { + "account_number": "1532", + "account_type": "Fixed Asset", + "M\u00e9dico": { + "account_number": "153205", + "account_type": "Fixed Asset" + }, + "Odontol\u00f3gico": { + "account_number": "153210", + "account_type": "Fixed Asset" + }, + "Laboratorio": { + "account_number": "153215", + "account_type": "Fixed Asset" + }, + "Instrumental": { + "account_number": "153220", + "account_type": "Fixed Asset" + }, + "Otros": { + "account_number": "153295", + "account_type": "Fixed Asset" + }, + "Ajustes por inflaci\u00f3n": { + "account_number": "153299", + "account_type": "Fixed Asset" + } + }, + "Equipo de hoteles y restaurantes": { + "account_number": "1536", + "account_type": "Fixed Asset", + "De habitaciones": { + "account_number": "153605", + "account_type": "Fixed Asset" + }, + "De comestibles y bebidas": { + "account_number": "153610", + "account_type": "Fixed Asset" + }, + "Otros": { + "account_number": "153695", + "account_type": "Fixed Asset" + }, + "Ajustes por inflaci\u00f3n": { + "account_number": "153699", + "account_type": "Fixed Asset" + } + }, + "Flota y equipo de transporte": { + "account_number": "1540", + "account_type": "Fixed Asset", + "Autos, camionetas y camperos": { + "account_number": "154005", + "account_type": "Fixed Asset" + }, + "Camiones, volquetas y furgones": { + "account_number": "154008", + "account_type": "Fixed Asset" + }, + "Tractomulas y remolques": { + "account_number": "154010", + "account_type": "Fixed Asset" + }, + "Buses y busetas": { + "account_number": "154015", + "account_type": "Fixed Asset" + }, + "Recolectores y contenedores": { + "account_number": "154017", + "account_type": "Fixed Asset" + }, + "Montacargas": { + "account_number": "154020", + "account_type": "Fixed Asset" + }, + "Palas y gr\u00faas": { + "account_number": "154025", + "account_type": "Fixed Asset" + }, + "Motocicletas": { + "account_number": "154030", + "account_type": "Fixed Asset" + }, + "Bicicletas": { + "account_number": "154035", + "account_type": "Fixed Asset" + }, + "Estibas y carretas": { + "account_number": "154040", + "account_type": "Fixed Asset" + }, + "Bandas transportadoras": { + "account_number": "154045", + "account_type": "Fixed Asset" + }, + "Otros": { + "account_number": "154095", + "account_type": "Fixed Asset" + }, + "Ajustes por inflaci\u00f3n": { + "account_number": "154099", + "account_type": "Fixed Asset" + } + }, + "Flota y equipo fluvial y/o mar\u00edtimo": { + "account_number": "1544", + "account_type": "Fixed Asset", + "Buques": { + "account_number": "154405", + "account_type": "Fixed Asset" + }, + "Lanchas": { + "account_number": "154410", + "account_type": "Fixed Asset" + }, + "Remolcadoras": { + "account_number": "154415", + "account_type": "Fixed Asset" + }, + "Botes": { + "account_number": "154420", + "account_type": "Fixed Asset" + }, + "Boyas": { + "account_number": "154425", + "account_type": "Fixed Asset" + }, + "Amarres": { + "account_number": "154430", + "account_type": "Fixed Asset" + }, + "Contenedores y chasises": { + "account_number": "154435", + "account_type": "Fixed Asset" + }, + "Gabarras": { + "account_number": "154440", + "account_type": "Fixed Asset" + }, + "Otros": { + "account_number": "154495", + "account_type": "Fixed Asset" + }, + "Ajustes por inflaci\u00f3n": { + "account_number": "154499", + "account_type": "Fixed Asset" + } + }, + "Flota y equipo a\u00e9reo": { + "account_number": "1548", + "account_type": "Fixed Asset", + "Aviones": { + "account_number": "154805", + "account_type": "Fixed Asset" + }, + "Avionetas": { + "account_number": "154810", + "account_type": "Fixed Asset" + }, + "Helic\u00f3pteros": { + "account_number": "154815", + "account_type": "Fixed Asset" + }, + "Turbinas y motores": { + "account_number": "154820", + "account_type": "Fixed Asset" + }, + "Manuales de entrenamiento personal t\u00e9cnico": { + "account_number": "154825", + "account_type": "Fixed Asset" + }, + "Equipos de vuelo": { + "account_number": "154830", + "account_type": "Fixed Asset" + }, + "Otros": { + "account_number": "154895", + "account_type": "Fixed Asset" + }, + "Ajustes por inflaci\u00f3n": { + "account_number": "154899", + "account_type": "Fixed Asset" + } + }, + "Flota y equipo f\u00e9rreo": { + "account_number": "1552", + "account_type": "Fixed Asset", + "Locomotoras": { + "account_number": "155205", + "account_type": "Fixed Asset" + }, + "Vagones": { + "account_number": "155210", + "account_type": "Fixed Asset" + }, + "Redes f\u00e9rreas": { + "account_number": "155215", + "account_type": "Fixed Asset" + }, + "Otros": { + "account_number": "155295", + "account_type": "Fixed Asset" + }, + "Ajustes por inflaci\u00f3n": { + "account_number": "155299", + "account_type": "Fixed Asset" + } + }, + "Acueductos, plantas y redes": { + "account_number": "1556", + "account_type": "Fixed Asset", + "Instalaciones para agua y energ\u00eda": { + "account_number": "155605", + "account_type": "Fixed Asset" + }, + "Acueducto, acequias y canalizaciones": { + "account_number": "155610", + "account_type": "Fixed Asset" + }, + "Plantas de generaci\u00f3n hidr\u00e1ulica": { + "account_number": "155615", + "account_type": "Fixed Asset" + }, + "Plantas de generaci\u00f3n t\u00e9rmica": { + "account_number": "155620", + "account_type": "Fixed Asset" + }, + "Plantas de generaci\u00f3n a gas": { + "account_number": "155625", + "account_type": "Fixed Asset" + }, + "Plantas de generaci\u00f3n diesel, gasolina y petr\u00f3leo": { + "account_number": "155628", + "account_type": "Fixed Asset" + }, + "Plantas de distribuci\u00f3n": { + "account_number": "155630", + "account_type": "Fixed Asset" + }, + "Plantas de transmisi\u00f3n y subestaciones": { + "account_number": "155635", + "account_type": "Fixed Asset" + }, + "Oleoductos": { + "account_number": "155640", + "account_type": "Fixed Asset" + }, + "Gasoductos": { + "account_number": "155645", + "account_type": "Fixed Asset" + }, + "Poliductos": { + "account_number": "155647", + "account_type": "Fixed Asset" + }, + "Redes de distribuci\u00f3n": { + "account_number": "155650", + "account_type": "Fixed Asset" + }, + "Plantas de tratamiento": { + "account_number": "155655", + "account_type": "Fixed Asset" + }, + "Redes de recolecci\u00f3n de aguas negras": { + "account_number": "155660", + "account_type": "Fixed Asset" + }, + "Instalaciones y equipo de bombeo": { + "account_number": "155665", + "account_type": "Fixed Asset" + }, + "Redes de distribuci\u00f3n de vapor": { + "account_number": "155670", + "account_type": "Fixed Asset" + }, + "Redes de aire": { + "account_number": "155675", + "account_type": "Fixed Asset" + }, + "Redes alimentaci\u00f3n de gas": { + "account_number": "155680", + "account_type": "Fixed Asset" + }, + "Redes externas de telefon\u00eda": { + "account_number": "155682", + "account_type": "Fixed Asset" + }, + "Plantas deshidratadoras": { + "account_number": "155685", + "account_type": "Fixed Asset" + }, + "Otros": { + "account_number": "155695", + "account_type": "Fixed Asset" + }, + "Ajustes por inflaci\u00f3n": { + "account_number": "155699", + "account_type": "Fixed Asset" + } + }, + "Armamento de vigilancia": { + "account_number": "1560", + "account_type": "Fixed Asset", + "Ajustes por inflaci\u00f3n": { + "account_number": "156099", + "account_type": "Fixed Asset" + } + }, + "Envases y empaques": { + "account_number": "1562", + "account_type": "Fixed Asset", + "Ajustes por inflaci\u00f3n": { + "account_number": "156299", + "account_type": "Fixed Asset" + } + }, + "Plantaciones agr\u00edcolas y forestales": { + "account_number": "1564", + "account_type": "Fixed Asset", + "Cultivos en desarrollo": { + "account_number": "156405", + "account_type": "Fixed Asset" + }, + "Cultivos amortizables": { + "account_number": "156410", + "account_type": "Fixed Asset" + }, + "Ajustes por inflaci\u00f3n": { + "account_number": "156499", + "account_type": "Fixed Asset" + } + }, + "V\u00edas de comunicaci\u00f3n": { + "account_number": "1568", + "account_type": "Fixed Asset", + "Pavimentaci\u00f3n y patios": { + "account_number": "156805", + "account_type": "Fixed Asset" + }, + "V\u00edas": { + "account_number": "156810", + "account_type": "Fixed Asset" + }, + "Puentes": { + "account_number": "156815", + "account_type": "Fixed Asset" + }, + "Calles": { + "account_number": "156820", + "account_type": "Fixed Asset" + }, + "Aer\u00f3dromos": { + "account_number": "156825", + "account_type": "Fixed Asset" + }, + "Otros": { + "account_number": "156895", + "account_type": "Fixed Asset" + }, + "Ajustes por inflaci\u00f3n": { + "account_number": "156899", + "account_type": "Fixed Asset" + } + }, + "Minas y canteras": { + "account_number": "1572", + "account_type": "Fixed Asset", + "Minas": { + "account_number": "157205", + "account_type": "Fixed Asset" + }, + "Canteras": { + "account_number": "157210", + "account_type": "Fixed Asset" + }, + "Ajustes por inflaci\u00f3n": { + "account_number": "157299", + "account_type": "Fixed Asset" + } + }, + "Pozos artesianos": { + "account_number": "1576", + "account_type": "Fixed Asset", + "Ajustes por inflaci\u00f3n": { + "account_number": "157699", + "account_type": "Fixed Asset" + } + }, + "Yacimientos": { + "account_number": "1580", + "account_type": "Fixed Asset", + "Ajustes por inflaci\u00f3n": { + "account_number": "158099", + "account_type": "Fixed Asset" + } + }, + "Semovientes": { + "account_number": "1584", + "account_type": "Fixed Asset", + "Ajustes por inflaci\u00f3n": { + "account_number": "158499", + "account_type": "Fixed Asset" + } + }, + "Propiedades, planta y equipo en tr\u00e1nsito": { + "account_number": "1588", + "account_type": "Fixed Asset", + "Maquinaria y equipo": { + "account_number": "158805", + "account_type": "Fixed Asset" + }, + "Equipo de oficina": { + "account_number": "158810", + "account_type": "Fixed Asset" + }, + "Equipo de computaci\u00f3n y comunicaci\u00f3n": { + "account_number": "158815", + "account_type": "Fixed Asset" + }, + "Equipo m\u00e9dico-cient\u00edfico": { + "account_number": "158820", + "account_type": "Fixed Asset" + }, + "Equipo de hoteles y restaurantes": { + "account_number": "158825", + "account_type": "Fixed Asset" + }, + "Flota y equipo de transporte": { + "account_number": "158830", + "account_type": "Fixed Asset" + }, + "Flota y equipo fluvial y/o mar\u00edtimo": { + "account_number": "158835", + "account_type": "Fixed Asset" + }, + "Flota y equipo a\u00e9reo": { + "account_number": "158840", + "account_type": "Fixed Asset" + }, + "Flota y equipo f\u00e9rreo": { + "account_number": "158845", + "account_type": "Fixed Asset" + }, + "Plantas y redes": { + "account_number": "158850", + "account_type": "Fixed Asset" + }, + "Armamento de vigilancia": { + "account_number": "158855", + "account_type": "Fixed Asset" + }, + "Semovientes": { + "account_number": "158860", + "account_type": "Fixed Asset" + }, + "Envases y empaques": { + "account_number": "158865", + "account_type": "Fixed Asset" + }, + "Ajustes por inflaci\u00f3n": { + "account_number": "158899", + "account_type": "Fixed Asset" + } + }, + "Depreciaci\u00f3n acumulada": { + "account_number": "1592", + "account_type": "Fixed Asset", + "Construcciones y edificaciones": { + "account_number": "159205", + "account_type": "Fixed Asset" + }, + "Maquinaria y equipo": { + "account_number": "159210", + "account_type": "Fixed Asset" + }, + "Equipo de oficina": { + "account_number": "159215", + "account_type": "Fixed Asset" + }, + "Equipo de computaci\u00f3n y comunicaci\u00f3n": { + "account_number": "159220", + "account_type": "Fixed Asset" + }, + "Equipo m\u00e9dico-cient\u00edfico": { + "account_number": "159225", + "account_type": "Fixed Asset" + }, + "Equipo de hoteles y restaurantes": { + "account_number": "159230", + "account_type": "Fixed Asset" + }, + "Flota y equipo de transporte": { + "account_number": "159235", + "account_type": "Fixed Asset" + }, + "Flota y equipo fluvial y/o mar\u00edtimo": { + "account_number": "159240", + "account_type": "Fixed Asset" + }, + "Flota y equipo a\u00e9reo": { + "account_number": "159245", + "account_type": "Fixed Asset" + }, + "Flota y equipo f\u00e9rreo": { + "account_number": "159250", + "account_type": "Fixed Asset" + }, + "Acueductos, plantas y redes": { + "account_number": "159255", + "account_type": "Fixed Asset" + }, + "Armamento de vigilancia": { + "account_number": "159260", + "account_type": "Fixed Asset" + }, + "Envases y empaques": { + "account_number": "159265", + "account_type": "Fixed Asset" + }, + "Ajustes por inflaci\u00f3n": { + "account_number": "159299", + "account_type": "Fixed Asset" + } + }, + "Depreciaci\u00f3n diferida": { + "account_number": "1596", + "account_type": "Fixed Asset", + "Exceso fiscal sobre la contable": { + "account_number": "159605", + "account_type": "Fixed Asset" + }, + "Defecto fiscal sobre la contable (CR)": { + "account_number": "159610", + "account_type": "Fixed Asset" + }, + "Ajustes por inflaci\u00f3n": { + "account_number": "159699", + "account_type": "Fixed Asset" + } + }, + "Amortizaci\u00f3n acumulada": { + "account_number": "1597", + "account_type": "Fixed Asset", + "Plantaciones agr\u00edcolas y forestales": { + "account_number": "159705", + "account_type": "Fixed Asset" + }, + "V\u00edas de comunicaci\u00f3n": { + "account_number": "159710", + "account_type": "Fixed Asset" + }, + "Semovientes": { + "account_number": "159715", + "account_type": "Fixed Asset" + }, + "Ajustes por inflaci\u00f3n": { + "account_number": "159799", + "account_type": "Fixed Asset" + } + }, + "Agotamiento acumulado": { + "account_number": "1598", + "account_type": "Fixed Asset", + "Minas y canteras": { + "account_number": "159805", + "account_type": "Fixed Asset" + }, + "Pozos artesianos": { + "account_number": "159815", + "account_type": "Fixed Asset" + }, + "Yacimientos": { + "account_number": "159820", + "account_type": "Fixed Asset" + }, + "Ajustes por inflaci\u00f3n": { + "account_number": "159899", + "account_type": "Fixed Asset" + } + }, + "Provisiones": { + "account_number": "1599", + "account_type": "Fixed Asset", + "Terrenos": { + "account_number": "159904", + "account_type": "Fixed Asset" + }, + "Materiales proyectos petroleros": { + "account_number": "159906", + "account_type": "Fixed Asset" + }, + "Construcciones en curso": { + "account_number": "159908", + "account_type": "Fixed Asset" + }, + "Maquinaria en montaje": { + "account_number": "159912", + "account_type": "Fixed Asset" + }, + "Construcciones y edificaciones": { + "account_number": "159916", + "account_type": "Fixed Asset" + }, + "Maquinaria y equipo": { + "account_number": "159920", + "account_type": "Fixed Asset" + }, + "Equipo de oficina": { + "account_number": "159924", + "account_type": "Fixed Asset" + }, + "Equipo de computaci\u00f3n y comunicaci\u00f3n": { + "account_number": "159928", + "account_type": "Fixed Asset" + }, + "Equipo m\u00e9dico-cient\u00edfico": { + "account_number": "159932", + "account_type": "Fixed Asset" + }, + "Equipo de hoteles y restaurantes": { + "account_number": "159936", + "account_type": "Fixed Asset" + }, + "Flota y equipo de transporte": { + "account_number": "159940", + "account_type": "Fixed Asset" + }, + "Flota y equipo fluvial y/o mar\u00edtimo": { + "account_number": "159944", + "account_type": "Fixed Asset" + }, + "Flota y equipo a\u00e9reo": { + "account_number": "159948", + "account_type": "Fixed Asset" + }, + "Flota y equipo f\u00e9rreo": { + "account_number": "159952", + "account_type": "Fixed Asset" + }, + "Acueductos, plantas y redes": { + "account_number": "159956", + "account_type": "Fixed Asset" + }, + "Armamento de vigilancia": { + "account_number": "159960", + "account_type": "Fixed Asset" + }, + "Envases y empaques": { + "account_number": "159962", + "account_type": "Fixed Asset" + }, + "Plantaciones agr\u00edcolas y forestales": { + "account_number": "159964", + "account_type": "Fixed Asset" + }, + "V\u00edas de comunicaci\u00f3n": { + "account_number": "159968", + "account_type": "Fixed Asset" + }, + "Minas y canteras": { + "account_number": "159972", + "account_type": "Fixed Asset" + }, + "Pozos artesianos": { + "account_number": "159980", + "account_type": "Fixed Asset" + }, + "Yacimientos": { + "account_number": "159984", + "account_type": "Fixed Asset" + }, + "Semovientes": { + "account_number": "159988", + "account_type": "Fixed Asset" + }, + "Propiedades, planta y equipo en tr\u00e1nsito": { + "account_number": "159992", + "account_type": "Fixed Asset" + } + } + }, + "Intangibles": { + "account_number": "16", + "Cr\u00e9dito mercantil": { + "account_number": "1605", + "Formado o estimado": { + "account_number": "160505" + }, + "Adquirido o comprado": { + "account_number": "160510" + }, + "Ajustes por inflaci\u00f3n": { + "account_number": "160599" + } + }, + "Marcas": { + "account_number": "1610", + "Adquiridas": { + "account_number": "161005" + }, + "Formadas": { + "account_number": "161010" + }, + "Ajustes por inflaci\u00f3n": { + "account_number": "161099" + } + }, + "Patentes": { + "account_number": "1615", + "Adquiridas": { + "account_number": "161505" + }, + "Formadas": { + "account_number": "161510" + }, + "Ajustes por inflaci\u00f3n": { + "account_number": "161599" + } + }, + "Concesiones y franquicias": { + "account_number": "1620", + "Concesiones": { + "account_number": "162005" + }, + "Franquicias": { + "account_number": "162010" + }, + "Ajustes por inflaci\u00f3n": { + "account_number": "162099" + } + }, + "Derechos": { + "account_number": "1625", + "Derechos de autor": { + "account_number": "162505" + }, + "Puesto de bolsa": { + "account_number": "162510" + }, + "En fideicomisos inmobiliarios": { + "account_number": "162515" + }, + "En fideicomisos de garant\u00eda": { + "account_number": "162520" + }, + "En fideicomisos de administraci\u00f3n": { + "account_number": "162525" + }, + "De exhibici\u00f3n - pel\u00edculas": { + "account_number": "162530" + }, + "En bienes recibidos en arrendamiento financiero (leasing)": { + "account_number": "162535" + }, + "Otros": { + "account_number": "162595" + }, + "Ajustes por inflaci\u00f3n": { + "account_number": "162599" + } + }, + "Know how": { + "account_number": "1630", + "Ajustes por inflaci\u00f3n": { + "account_number": "163099" + } + }, + "Licencias": { + "account_number": "1635", + "Ajustes por inflaci\u00f3n": { + "account_number": "163599" + } + }, + "Depreciaci\u00f3n y/o amortizaci\u00f3n acumulada": { + "account_number": "1698", + "Cr\u00e9dito mercantil": { + "account_number": "169805" + }, + "Marcas": { + "account_number": "169810" + }, + "Patentes": { + "account_number": "169815" + }, + "Concesiones y franquicias": { + "account_number": "169820" + }, + "Derechos": { + "account_number": "169830" + }, + "Know how": { + "account_number": "169835" + }, + "Licencias": { + "account_number": "169840" + }, + "Ajustes por inflaci\u00f3n": { + "account_number": "169899" + } + }, + "Provisiones": { + "account_number": "1699", + "account_type": "Accumulated Depreciation" + } + }, + "Diferidos": { + "account_number": "17", + "Gastos pagados por anticipado": { + "account_number": "1705", + "Intereses": { + "account_number": "170505" + }, + "Honorarios": { + "account_number": "170510" + }, + "Comisiones": { + "account_number": "170515" + }, + "Seguros y fianzas": { + "account_number": "170520" + }, + "Arrendamientos": { + "account_number": "170525" + }, + "Bodegajes": { + "account_number": "170530" + }, + "Mantenimiento equipos": { + "account_number": "170535" + }, + "Servicios": { + "account_number": "170540" + }, + "Suscripciones": { + "account_number": "170545" + }, + "Otros": { + "account_number": "170595" + } + }, + "Cargos diferidos": { + "account_number": "1710", + "Organizaci\u00f3n y preoperativos": { + "account_number": "171004" + }, + "Remodelaciones": { + "account_number": "171008" + }, + "Estudios, investigaciones y proyectos": { + "account_number": "171012" + }, + "Programas para computador (software)": { + "account_number": "171016" + }, + "\u00datiles y papeler\u00eda": { + "account_number": "171020" + }, + "Mejoras a propiedades ajenas": { + "account_number": "171024" + }, + "Contribuciones y afiliaciones": { + "account_number": "171028" + }, + "Entrenamiento de personal": { + "account_number": "171032" + }, + "Ferias y exposiciones": { + "account_number": "171036" + }, + "Licencias": { + "account_number": "171040" + }, + "Publicidad, propaganda y promoci\u00f3n": { + "account_number": "171044" + }, + "Elementos de aseo y cafeter\u00eda": { + "account_number": "171048" + }, + "Moldes y troqueles": { + "account_number": "171052" + }, + "Instrumental quir\u00fargico": { + "account_number": "171056" + }, + "Dotaci\u00f3n y suministro a trabajadores": { + "account_number": "171060" + }, + "Elementos de roper\u00eda y lencer\u00eda": { + "account_number": "171064" + }, + "Loza y cristaler\u00eda": { + "account_number": "171068" + }, + "Plater\u00eda": { + "account_number": "171069" + }, + "Cubierter\u00eda": { + "account_number": "171070" + }, + "Impuesto de renta diferido ?d\u00e9bitos? por diferencias temporales": { + "account_number": "171076" + }, + "Concursos y licitaciones": { + "account_number": "171080" + }, + "Otros": { + "account_number": "171095" + }, + "Ajustes por inflaci\u00f3n": { + "account_number": "171099" + } + }, + "Costos de exploraci\u00f3n por amortizar": { + "account_number": "1715", + "Pozos secos": { + "account_number": "171505" + }, + "Pozos no comerciales": { + "account_number": "171510" + }, + "Otros costos de exploraci\u00f3n": { + "account_number": "171515" + }, + "Ajustes por inflaci\u00f3n": { + "account_number": "171599" + } + }, + "Costos de explotaci\u00f3n y desarrollo": { + "account_number": "1720", + "Perforaci\u00f3n y explotaci\u00f3n": { + "account_number": "172005" + }, + "Perforaciones campos en desarrollo": { + "account_number": "172010" + }, + "Facilidades de producci\u00f3n": { + "account_number": "172015" + }, + "Servicio a pozos": { + "account_number": "172020" + }, + "Ajustes por inflaci\u00f3n": { + "account_number": "172099" + } + }, + "Cargos por correcci\u00f3n monetaria diferida": { + "account_number": "1730" + }, + "Amortizaci\u00f3n acumulada": { + "account_number": "1798", + "account_type": "Accumulated Depreciation", + "Costos de exploraci\u00f3n por amortizar": { + "account_number": "179805", + "account_type": "Accumulated Depreciation" + }, + "Costos de explotaci\u00f3n y desarrollo": { + "account_number": "179810", + "account_type": "Accumulated Depreciation" + }, + "Ajustes por inflaci\u00f3n": { + "account_number": "179899", + "account_type": "Accumulated Depreciation" + } + } + }, + "Otros activos": { + "account_number": "18", + "Bienes de arte y cultura": { + "account_number": "1805", + "Obras de arte": { + "account_number": "180505" + }, + "Bibliotecas": { + "account_number": "180510" + }, + "Otros": { + "account_number": "180595" + }, + "Ajustes por inflaci\u00f3n": { + "account_number": "180599" + } + }, + "Diversos": { + "account_number": "1895", + "M\u00e1quinas porteadoras": { + "account_number": "189505" + }, + "Bienes entregados en comodato": { + "account_number": "189510" + }, + "Amortizaci\u00f3n acumulada de bienes entregados en comodato (CR)": { + "account_number": "189515" + }, + "Bienes recibidos en pago": { + "account_number": "189520" + }, + "Derechos sucesorales": { + "account_number": "189525" + }, + "Estampillas": { + "account_number": "189530" + }, + "Otros": { + "account_number": "189595" + }, + "Ajustes por inflaci\u00f3n": { + "account_number": "189599" + } + }, + "Provisiones": { + "account_number": "1899", + "Bienes de arte y cultura": { + "account_number": "189905" + }, + "Diversos": { + "account_number": "189995" + } + } + }, + "Valorizaciones": { + "account_number": "19", + "De inversiones": { + "account_number": "1905", + "Acciones": { + "account_number": "190505" + }, + "Cuotas o partes de inter\u00e9s social": { + "account_number": "190510" + }, + "Derechos fiduciarios": { + "account_number": "190515" + } + }, + "De propiedades, planta y equipo": { + "account_number": "1910", + "Terrenos": { + "account_number": "191004" + }, + "Materiales proyectos petroleros": { + "account_number": "191006" + }, + "Construcciones y edificaciones": { + "account_number": "191008" + }, + "Maquinaria y equipo": { + "account_number": "191012" + }, + "Equipo de oficina": { + "account_number": "191016" + }, + "Equipo de computaci\u00f3n y comunicaci\u00f3n": { + "account_number": "191020" + }, + "Equipo m\u00e9dico-cient\u00edfico": { + "account_number": "191024" + }, + "Equipo de hoteles y restaurantes": { + "account_number": "191028" + }, + "Flota y equipo de transporte": { + "account_number": "191032" + }, + "Flota y equipo fluvial y/o mar\u00edtimo": { + "account_number": "191036" + }, + "Flota y equipo a\u00e9reo": { + "account_number": "191040" + }, + "Flota y equipo f\u00e9rreo": { + "account_number": "191044" + }, + "Acueductos, plantas y redes": { + "account_number": "191048" + }, + "Armamento de vigilancia": { + "account_number": "191052" + }, + "Envases y empaques": { + "account_number": "191056" + }, + "Plantaciones agr\u00edcolas y forestales": { + "account_number": "191060" + }, + "V\u00edas de comunicaci\u00f3n": { + "account_number": "191064" + }, + "Minas y canteras": { + "account_number": "191068" + }, + "Pozos artesianos": { + "account_number": "191072" + }, + "Yacimientos": { + "account_number": "191076" + }, + "Semovientes": { + "account_number": "191080" + } + }, + "De otros activos": { + "account_number": "1995", + "Bienes de arte y cultura": { + "account_number": "199505" + }, + "Bienes entregados en comodato": { + "account_number": "199510" + }, + "Bienes recibidos en pago": { + "account_number": "199515" + }, + "Inventario de semovientes": { + "account_number": "199520" + } + } + } + }, + "Pasivo": { + "account_number": "2", + "root_type": "Liability", + "Obligaciones financieras": { + "account_number": "21", + "Bancos nacionales": { + "account_number": "2105", + "Sobregiros": { + "account_number": "210505" + }, + "Pagar\u00e9s": { + "account_number": "210510" + }, + "Cartas de cr\u00e9dito": { + "account_number": "210515" + }, + "Aceptaciones bancarias": { + "account_number": "210520" + } + }, + "Bancos del exterior": { + "account_number": "2110", + "Sobregiros": { + "account_number": "211005" + }, + "Pagar\u00e9s": { + "account_number": "211010" + }, + "Cartas de cr\u00e9dito": { + "account_number": "211015" + }, + "Aceptaciones bancarias": { + "account_number": "211020" + } + }, + "Corporaciones financieras": { + "account_number": "2115", + "Pagar\u00e9s": { + "account_number": "211505" + }, + "Aceptaciones financieras": { + "account_number": "211510" + }, + "Cartas de cr\u00e9dito": { + "account_number": "211515" + }, + "Contratos de arrendamiento financiero (leasing)": { + "account_number": "211520" + } + }, + "Compa\u00f1\u00edas de financiamiento comercial": { + "account_number": "2120", + "Pagar\u00e9s": { + "account_number": "212005" + }, + "Aceptaciones financieras": { + "account_number": "212010" + }, + "Contratos de arrendamiento financiero (leasing)": { + "account_number": "212020" + } + }, + "Corporaciones de ahorro y vivienda": { + "account_number": "2125", + "Sobregiros": { + "account_number": "212505" + }, + "Pagar\u00e9s": { + "account_number": "212510" + }, + "Hipotecarias": { + "account_number": "212515" + } + }, + "Entidades financieras del exterior": { + "account_number": "2130" + }, + "Compromisos de recompra de inversiones negociadas": { + "account_number": "2135", + "Acciones": { + "account_number": "213505" + }, + "Cuotas o partes de inter\u00e9s social": { + "account_number": "213510" + }, + "Bonos": { + "account_number": "213515" + }, + "C\u00e9dulas": { + "account_number": "213520" + }, + "Certificados": { + "account_number": "213525" + }, + "Papeles comerciales": { + "account_number": "213530" + }, + "T\u00edtulos": { + "account_number": "213535" + }, + "Aceptaciones bancarias o financieras": { + "account_number": "213540" + }, + "Otros": { + "account_number": "213595" + } + }, + "Compromisos de recompra de cartera negociada": { + "account_number": "2140" + }, + "Obligaciones gubernamentales": { + "account_number": "2145", + "Gobierno Nacional": { + "account_number": "214505" + }, + "Entidades oficiales": { + "account_number": "214510" + } + }, + "Otras obligaciones": { + "account_number": "2195", + "Particulares": { + "account_number": "219505" + }, + "Compa\u00f1\u00edas vinculadas": { + "account_number": "219510" + }, + "Casa matriz": { + "account_number": "219515" + }, + "Socios o accionistas": { + "account_number": "219520" + }, + "Fondos y cooperativas": { + "account_number": "219525" + }, + "Directores": { + "account_number": "219530" + }, + "Otras": { + "account_number": "219595" + } + } + }, + "Proveedores": { + "account_number": "22", + "account_type": "Payable", + "Nacionales": { + "account_number": "2205", + "account_type": "Payable" + }, + "Del exterior": { + "account_number": "2210", + "account_type": "Payable" + }, + "Cuentas corrientes comerciales": { + "account_number": "2215", + "account_type": "Payable" + }, + "Casa matriz": { + "account_number": "2220", + "account_type": "Payable" + }, + "Compa\u00f1\u00edas vinculadas": { + "account_number": "2225", + "account_type": "Payable" + } + }, + "Cuentas por pagar": { + "account_number": "23", + "account_type": "Payable", + "Cuentas corrientes comerciales": { + "account_number": "2305", + "account_type": "Payable" + }, + "A casa matriz": { + "account_number": "2310", + "account_type": "Payable" + }, + "A compa\u00f1\u00edas vinculadas": { + "account_number": "2315", + "account_type": "Payable" + }, + "A contratistas": { + "account_number": "2320", + "account_type": "Payable" + }, + "\u00d3rdenes de compra por utilizar": { + "account_number": "2330", + "account_type": "Payable" + }, + "Costos y gastos por pagar": { + "account_number": "2335", + "account_type": "Payable", + "Gastos financieros": { + "account_number": "233505", + "account_type": "Payable" + }, + "Gastos legales": { + "account_number": "233510", + "account_type": "Payable" + }, + "Libros, suscripciones, peri\u00f3dicos y revistas": { + "account_number": "233515", + "account_type": "Payable" + }, + "Comisiones": { + "account_number": "233520", + "account_type": "Payable" + }, + "Honorarios": { + "account_number": "233525", + "account_type": "Payable" + }, + "Servicios t\u00e9cnicos": { + "account_number": "233530", + "account_type": "Payable" + }, + "Servicios de mantenimiento": { + "account_number": "233535", + "account_type": "Payable" + }, + "Arrendamientos": { + "account_number": "233540", + "account_type": "Payable" + }, + "Transportes, fletes y acarreos": { + "account_number": "233545", + "account_type": "Payable" + }, + "Servicios p\u00fablicos": { + "account_number": "233550", + "account_type": "Payable" + }, + "Seguros": { + "account_number": "233555", + "account_type": "Payable" + }, + "Gastos de viaje": { + "account_number": "233560", + "account_type": "Payable" + }, + "Gastos de representaci\u00f3n y relaciones p\u00fablicas": { + "account_number": "233565", + "account_type": "Payable" + }, + "Servicios aduaneros": { + "account_number": "233570", + "account_type": "Payable" + }, + "Otros": { + "account_number": "233595", + "account_type": "Payable" + } + }, + "Instalamentos por pagar": { + "account_number": "2340", + "account_type": "Payable" + }, + "Acreedores oficiales": { + "account_number": "2345", + "account_type": "Payable" + }, + "Regal\u00edas por pagar": { + "account_number": "2350", + "account_type": "Payable" + }, + "Deudas con accionistas o socios": { + "account_number": "2355", + "account_type": "Payable", + "Accionistas": { + "account_number": "235505", + "account_type": "Payable" + }, + "Socios": { + "account_number": "235510", + "account_type": "Payable" + } + }, + "Deudas con directores": { + "account_number": "2357", + "account_type": "Payable" + }, + "Dividendos o participaciones por pagar": { + "account_number": "2360", + "account_type": "Payable", + "Dividendos": { + "account_number": "236005", + "account_type": "Payable" + }, + "Participaciones": { + "account_number": "236010", + "account_type": "Payable" + } + }, + "Retenci\u00f3n en la fuente": { + "account_number": "2365", + "account_type": "Payable", + "Salarios y pagos laborales": { + "account_number": "236505", + "account_type": "Payable" + }, + "Dividendos y/o participaciones": { + "account_number": "236510", + "account_type": "Payable" + }, + "Honorarios": { + "account_number": "236515", + "account_type": "Payable" + }, + "Comisiones": { + "account_number": "236520", + "account_type": "Payable" + }, + "Servicios": { + "account_number": "236525", + "account_type": "Payable" + }, + "Arrendamientos": { + "account_number": "236530", + "account_type": "Payable" + }, + "Rendimientos financieros": { + "account_number": "236535", + "account_type": "Payable" + }, + "Compras": { + "account_number": "236540", + "account_type": "Payable" + }, + "Loter\u00edas, rifas, apuestas y similares": { + "account_number": "236545", + "account_type": "Payable" + }, + "Por pagos al exterior": { + "account_number": "236550", + "account_type": "Payable" + }, + "Por ingresos obtenidos en el exterior": { + "account_number": "236555", + "account_type": "Payable" + }, + "Enajenaci\u00f3n propiedades planta y equipo, personas naturales": { + "account_number": "236560", + "account_type": "Payable" + }, + "Por impuesto de timbre": { + "account_number": "236565", + "account_type": "Payable" + }, + "Otras retenciones y patrimonio": { + "account_number": "236570", + "account_type": "Payable" + }, + "Autorretenciones": { + "account_number": "236575", + "account_type": "Payable" + } + }, + "Impuesto a las ventas retenido": { + "account_number": "2367", + "account_type": "Payable" + }, + "Impuesto de industria y comercio retenido": { + "account_number": "2368", + "account_type": "Payable" + }, + "Retenciones y aportes de n\u00f3mina": { + "account_number": "2370", + "account_type": "Payable", + "Aportes a entidades promotoras de salud, EPS": { + "account_number": "237005", + "account_type": "Payable" + }, + "Aportes a administradoras de riesgos profesionales, ARP": { + "account_number": "237006", + "account_type": "Payable" + }, + "Aportes al ICBF, SENA y cajas de compensaci\u00f3n": { + "account_number": "237010", + "account_type": "Payable" + }, + "Aportes al FIC": { + "account_number": "237015", + "account_type": "Payable" + }, + "Embargos judiciales": { + "account_number": "237025", + "account_type": "Payable" + }, + "Libranzas": { + "account_number": "237030", + "account_type": "Payable" + }, + "Sindicatos": { + "account_number": "237035", + "account_type": "Payable" + }, + "Cooperativas": { + "account_number": "237040", + "account_type": "Payable" + }, + "Fondos": { + "account_number": "237045", + "account_type": "Payable" + }, + "Otros": { + "account_number": "237095", + "account_type": "Payable" + } + }, + "Cuotas por devolver": { + "account_number": "2375", + "account_type": "Payable" + }, + "Acreedores varios": { + "account_number": "2380", + "account_type": "Payable", + "Depositarios": { + "account_number": "238005", + "account_type": "Payable" + }, + "Comisionistas de bolsas": { + "account_number": "238010", + "account_type": "Payable" + }, + "Sociedad administradora-Fondos de inversi\u00f3n": { + "account_number": "238015", + "account_type": "Payable" + }, + "Reintegros por pagar": { + "account_number": "238020", + "account_type": "Payable" + }, + "Fondo de perseverancia": { + "account_number": "238025", + "account_type": "Payable" + }, + "Fondos de cesant\u00edas y/o pensiones": { + "account_number": "238030", + "account_type": "Payable" + }, + "Donaciones asignadas por pagar": { + "account_number": "238035", + "account_type": "Payable" + }, + "Otros": { + "account_number": "238095", + "account_type": "Payable" + } + } + }, + "Impuestos, grav\u00e1menes y tasas": { + "account_number": "24", + "account_type": "Tax", + "De renta y complementarios": { + "account_number": "2404", + "account_type": "Tax", + "Vigencia fiscal corriente": { + "account_number": "240405", + "account_type": "Tax" + }, + "Vigencias fiscales anteriores": { + "account_number": "240410", + "account_type": "Tax" + } + }, + "Impuesto sobre las ventas por pagar": { + "account_number": "2408", + "account_type": "Tax" + }, + "De industria y comercio": { + "account_number": "2412", + "account_type": "Tax", + "Vigencia fiscal corriente": { + "account_number": "241205", + "account_type": "Tax" + }, + "Vigencias fiscales anteriores": { + "account_number": "241210", + "account_type": "Tax" + } + }, + "A la propiedad ra\u00edz": { + "account_number": "2416", + "account_type": "Tax" + }, + "Derechos sobre instrumentos p\u00fablicos": { + "account_number": "2420", + "account_type": "Tax" + }, + "De valorizaci\u00f3n": { + "account_number": "2424", + "account_type": "Tax", + "Vigencia fiscal corriente": { + "account_number": "242405", + "account_type": "Tax" + }, + "Vigencias fiscales anteriores": { + "account_number": "242410", + "account_type": "Tax" + } + }, + "De turismo": { + "account_number": "2428", + "account_type": "Tax" + }, + "Tasa por utilizaci\u00f3n de puertos": { + "account_number": "2432", + "account_type": "Tax" + }, + "De veh\u00edculos": { + "account_number": "2436", + "account_type": "Tax", + "Vigencia fiscal corriente": { + "account_number": "243605", + "account_type": "Tax" + }, + "Vigencias fiscales anteriores": { + "account_number": "243610", + "account_type": "Tax" + } + }, + "De espect\u00e1culos p\u00fablicos": { + "account_number": "2440", + "account_type": "Tax" + }, + "De hidrocarburos y minas": { + "account_number": "2444", + "account_type": "Tax", + "De hidrocarburos": { + "account_number": "244405", + "account_type": "Tax" + }, + "De minas": { + "account_number": "244410", + "account_type": "Tax" + } + }, + "Regal\u00edas e impuestos a la peque\u00f1a y mediana miner\u00eda": { + "account_number": "2448", + "account_type": "Tax" + }, + "A las exportaciones cafeteras": { + "account_number": "2452", + "account_type": "Tax" + }, + "A las importaciones": { + "account_number": "2456", + "account_type": "Tax" + }, + "Cuotas de fomento": { + "account_number": "2460", + "account_type": "Tax" + }, + "De licores, cervezas y cigarrillos": { + "account_number": "2464", + "account_type": "Tax", + "De licores": { + "account_number": "246405", + "account_type": "Tax" + }, + "De cervezas": { + "account_number": "246410", + "account_type": "Tax" + }, + "De cigarrillos": { + "account_number": "246415", + "account_type": "Tax" + } + }, + "Al sacrificio de ganado": { + "account_number": "2468", + "account_type": "Tax" + }, + "Al azar y juegos": { + "account_number": "2472", + "account_type": "Tax" + }, + "Grav\u00e1menes y regal\u00edas por utilizaci\u00f3n del suelo": { + "account_number": "2476", + "account_type": "Tax" + }, + "Otros": { + "account_number": "2495", + "account_type": "Tax" + } + }, + "Obligaciones laborales": { + "account_number": "25", + "Salarios por pagar": { + "account_number": "2505" + }, + "Cesant\u00edas consolidadas": { + "account_number": "2510", + "Ley laboral anterior": { + "account_number": "251005" + }, + "Ley 50 de 1990 y normas posteriores": { + "account_number": "251010" + } + }, + "Intereses sobre cesant\u00edas": { + "account_number": "2515" + }, + "Prima de servicios": { + "account_number": "2520" + }, + "Vacaciones consolidadas": { + "account_number": "2525" + }, + "Prestaciones extralegales": { + "account_number": "2530", + "Primas": { + "account_number": "253005" + }, + "Auxilios": { + "account_number": "253010" + }, + "Dotaci\u00f3n y suministro a trabajadores": { + "account_number": "253015" + }, + "Bonificaciones": { + "account_number": "253020" + }, + "Seguros": { + "account_number": "253025" + }, + "Otras": { + "account_number": "253095" + } + }, + "Pensiones por pagar": { + "account_number": "2532" + }, + "Cuotas partes pensiones de jubilaci\u00f3n": { + "account_number": "2535" + }, + "Indemnizaciones laborales": { + "account_number": "2540" + } + }, + "Pasivos estimados y provisiones": { + "account_number": "26", + "Para costos y gastos": { + "account_number": "2605", + "Intereses": { + "account_number": "260505" + }, + "Comisiones": { + "account_number": "260510" + }, + "Honorarios": { + "account_number": "260515" + }, + "Servicios t\u00e9cnicos": { + "account_number": "260520" + }, + "Transportes, fletes y acarreos": { + "account_number": "260525" + }, + "Gastos de viaje": { + "account_number": "260530" + }, + "Servicios p\u00fablicos": { + "account_number": "260535" + }, + "Regal\u00edas": { + "account_number": "260540" + }, + "Garant\u00edas": { + "account_number": "260545" + }, + "Materiales y repuestos": { + "account_number": "260550" + }, + "Otros": { + "account_number": "260595" + } + }, + "Para obligaciones laborales": { + "account_number": "2610", + "Cesant\u00edas": { + "account_number": "261005" + }, + "Intereses sobre cesant\u00edas": { + "account_number": "261010" + }, + "Vacaciones": { + "account_number": "261015" + }, + "Prima de servicios": { + "account_number": "261020" + }, + "Prestaciones extralegales": { + "account_number": "261025" + }, + "Vi\u00e1ticos": { + "account_number": "261030" + }, + "Otras": { + "account_number": "261095" + } + }, + "Para obligaciones fiscales": { + "account_number": "2615", + "De renta y complementarios": { + "account_number": "261505" + }, + "De industria y comercio": { + "account_number": "261510" + }, + "Tasa por utilizaci\u00f3n de puertos": { + "account_number": "261515" + }, + "De veh\u00edculos": { + "account_number": "261520" + }, + "De hidrocarburos y minas": { + "account_number": "261525" + }, + "Otros": { + "account_number": "261595" + } + }, + "Pensiones de jubilaci\u00f3n": { + "account_number": "2620", + "C\u00e1lculo actuarial pensiones de jubilaci\u00f3n": { + "account_number": "262005" + }, + "Pensiones de jubilaci\u00f3n por amortizar (DB)": { + "account_number": "262010" + } + }, + "Para obras de urbanismo": { + "account_number": "2625", + "Acueducto y alcantarillado": { + "account_number": "262505" + }, + "Energ\u00eda el\u00e9ctrica": { + "account_number": "262510" + }, + "Tel\u00e9fonos": { + "account_number": "262515" + }, + "Otros": { + "account_number": "262595" + } + }, + "Para mantenimiento y reparaciones": { + "account_number": "2630", + "Terrenos": { + "account_number": "263005" + }, + "Construcciones y edificaciones": { + "account_number": "263010" + }, + "Maquinaria y equipo": { + "account_number": "263015" + }, + "Equipo de oficina": { + "account_number": "263020" + }, + "Equipo de computaci\u00f3n y comunicaci\u00f3n": { + "account_number": "263025" + }, + "Equipo m\u00e9dico-cient\u00edfico": { + "account_number": "263030" + }, + "Equipo de hoteles y restaurantes": { + "account_number": "263035" + }, + "Flota y equipo de transporte": { + "account_number": "263040" + }, + "Flota y equipo fluvial y/o mar\u00edtimo": { + "account_number": "263045" + }, + "Flota y equipo a\u00e9reo": { + "account_number": "263050" + }, + "Flota y equipo f\u00e9rreo": { + "account_number": "263055" + }, + "Acueductos, plantas y redes": { + "account_number": "263060" + }, + "Armamento de vigilancia": { + "account_number": "263065" + }, + "Envases y empaques": { + "account_number": "263070" + }, + "Plantaciones agr\u00edcolas y forestales": { + "account_number": "263075" + }, + "V\u00edas de comunicaci\u00f3n": { + "account_number": "263080" + }, + "Pozos artesianos": { + "account_number": "263085" + }, + "Otros": { + "account_number": "263095" + } + }, + "Para contingencias": { + "account_number": "2635", + "Multas y sanciones autoridades administrativas": { + "account_number": "263505" + }, + "Intereses por multas y sanciones": { + "account_number": "263510" + }, + "Reclamos": { + "account_number": "263515" + }, + "Laborales": { + "account_number": "263520" + }, + "Civiles": { + "account_number": "263525" + }, + "Penales": { + "account_number": "263530" + }, + "Administrativos": { + "account_number": "263535" + }, + "Comerciales": { + "account_number": "263540" + }, + "Otras": { + "account_number": "263595" + } + }, + "Para obligaciones de garant\u00edas": { + "account_number": "2640" + }, + "Provisiones diversas": { + "account_number": "2695", + "Para beneficencia": { + "account_number": "269505" + }, + "Para comunicaciones": { + "account_number": "269510" + }, + "Para p\u00e9rdida en transporte": { + "account_number": "269515" + }, + "Para operaci\u00f3n": { + "account_number": "269520" + }, + "Para protecci\u00f3n de bienes agotables": { + "account_number": "269525" + }, + "Para ajustes en redenci\u00f3n de unidades": { + "account_number": "269530" + }, + "Autoseguro": { + "account_number": "269535" + }, + "Planes y programas de reforestaci\u00f3n y electrificaci\u00f3n": { + "account_number": "269540" + }, + "Otras": { + "account_number": "269595" + } + } + }, + "Diferidos": { + "account_number": "27", + "Ingresos recibidos por anticipado": { + "account_number": "2705", + "Intereses": { + "account_number": "270505" + }, + "Comisiones": { + "account_number": "270510" + }, + "Arrendamientos": { + "account_number": "270515" + }, + "Honorarios": { + "account_number": "270520" + }, + "Servicios t\u00e9cnicos": { + "account_number": "270525" + }, + "De suscriptores": { + "account_number": "270530" + }, + "Transportes, fletes y acarreos": { + "account_number": "270535" + }, + "Mercanc\u00eda en tr\u00e1nsito ya vendida": { + "account_number": "270540" + }, + "Matr\u00edculas y pensiones": { + "account_number": "270545" + }, + "Cuotas de administraci\u00f3n": { + "account_number": "270550" + }, + "Otros": { + "account_number": "270595" + } + }, + "Abonos diferidos": { + "account_number": "2710", + "Reajuste del sistema": { + "account_number": "271005" + } + }, + "Utilidad diferida en ventas a plazos": { + "account_number": "2715" + }, + "Cr\u00e9dito por correcci\u00f3n monetaria diferida": { + "account_number": "2720" + }, + "Impuestos diferidos": { + "account_number": "2725", + "Por depreciaci\u00f3n flexible": { + "account_number": "272505" + }, + "Diversos": { + "account_number": "272595" + }, + "Ajustes por inflaci\u00f3n": { + "account_number": "272599" + } + } + }, + "Otros pasivos": { + "account_number": "28", + "Anticipos y avances recibidos": { + "account_number": "2805", + "De clientes": { + "account_number": "280505" + }, + "Sobre contratos": { + "account_number": "280510" + }, + "Para obras en proceso": { + "account_number": "280515" + }, + "Otros": { + "account_number": "280595" + } + }, + "Dep\u00f3sitos recibidos": { + "account_number": "2810", + "Para futura suscripci\u00f3n de acciones": { + "account_number": "281005" + }, + "Para futuro pago de cuotas o derechos sociales": { + "account_number": "281010" + }, + "Para garant\u00eda en la prestaci\u00f3n de servicios": { + "account_number": "281015" + }, + "Para garant\u00eda de contratos": { + "account_number": "281020" + }, + "De licitaciones": { + "account_number": "281025" + }, + "De manejo de bienes": { + "account_number": "281030" + }, + "Fondo de reserva": { + "account_number": "281035" + }, + "Otros": { + "account_number": "281095" + } + }, + "Ingresos recibidos para terceros": { + "account_number": "2815", + "Valores recibidos para terceros": { + "account_number": "281505" + }, + "Venta por cuenta de terceros": { + "account_number": "281510" + } + }, + "Cuentas de operaci\u00f3n conjunta": { + "account_number": "2820" + }, + "Retenciones a terceros sobre contratos": { + "account_number": "2825", + "Cumplimiento obligaciones laborales": { + "account_number": "282505" + }, + "Para estabilidad de obra": { + "account_number": "282510" + }, + "Garant\u00eda cumplimiento de contratos": { + "account_number": "282515" + } + }, + "Embargos judiciales": { + "account_number": "2830", + "Indemnizaciones": { + "account_number": "283005" + }, + "Dep\u00f3sitos judiciales": { + "account_number": "283010" + } + }, + "Acreedores del sistema": { + "account_number": "2835", + "Cuotas netas": { + "account_number": "283505" + }, + "Grupos en formaci\u00f3n": { + "account_number": "283510" + } + }, + "Cuentas en participaci\u00f3n": { + "account_number": "2840" + }, + "Diversos": { + "account_number": "2895", + "Pr\u00e9stamos de productos": { + "account_number": "289505" + }, + "Reembolso de costos exploratorios": { + "account_number": "289510" + }, + "Programa de extensi\u00f3n agropecuaria": { + "account_number": "289515" + } + } + }, + "Bonos y papeles comerciales": { + "account_number": "29", + "Bonos en circulaci\u00f3n": { + "account_number": "2905" + }, + "Bonos obligatoriamente convertibles en acciones": { + "account_number": "2910" + }, + "Papeles comerciales": { + "account_number": "2915" + }, + "Bonos pensionales": { + "account_number": "2920", + "Valor bonos pensionales": { + "account_number": "292005" + }, + "Bonos pensionales por amortizar (DB)": { + "account_number": "292010" + }, + "Intereses causados sobre bonos pensionales": { + "account_number": "292015" + } + }, + "T\u00edtulos pensionales": { + "account_number": "2925", + "Valor t\u00edtulos pensionales": { + "account_number": "292505" + }, + "T\u00edtulos pensionales por amortizar (DB)": { + "account_number": "292510" + }, + "Intereses causados sobre t\u00edtulos pensionales": { + "account_number": "292515" + } + } + } + }, + "Patrimonio": { + "account_number": "3", + "account_type": "Equity", + "root_type": "Equity", + "Capital social": { + "account_number": "31", + "account_type": "Equity", + "Capital suscrito y pagado": { + "account_number": "3105", + "account_type": "Equity", + "Capital autorizado": { + "account_number": "310505", + "account_type": "Equity" + }, + "Capital por suscribir (DB)": { + "account_number": "310510", + "account_type": "Equity" + }, + "Capital suscrito por cobrar (DB)": { + "account_number": "310515", + "account_type": "Equity" + } + }, + "Aportes sociales": { + "account_number": "3115", + "account_type": "Equity", + "Cuotas o partes de inter\u00e9s social": { + "account_number": "311505", + "account_type": "Equity" + }, + "Aportes de socios-fondo mutuo de inversi\u00f3n": { + "account_number": "311510", + "account_type": "Equity" + }, + "Contribuci\u00f3n de la empresa-fondo mutuo de inversi\u00f3n": { + "account_number": "311515", + "account_type": "Equity" + }, + "Suscripciones del p\u00fablico": { + "account_number": "311520", + "account_type": "Equity" + } + }, + "Capital asignado": { + "account_number": "3120", + "account_type": "Equity" + }, + "Inversi\u00f3n suplementaria al capital asignado": { + "account_number": "3125", + "account_type": "Equity" + }, + "Capital de personas naturales": { + "account_number": "3130", + "account_type": "Equity" + }, + "Aportes del Estado": { + "account_number": "3135", + "account_type": "Equity" + }, + "Fondo social": { + "account_number": "3140", + "account_type": "Equity" + } + }, + "Super\u00e1vit de capital": { + "account_number": "32", + "account_type": "Equity", + "Prima en colocaci\u00f3n de acciones, cuotas o partes de inter\u00e9s social": { + "account_number": "3205", + "account_type": "Equity", + "Prima en colocaci\u00f3n de acciones": { + "account_number": "320505", + "account_type": "Equity" + }, + "Prima en colocaci\u00f3n de acciones por cobrar (DB)": { + "account_number": "320510", + "account_type": "Equity" + }, + "Prima en colocaci\u00f3n de cuotas o partes de inter\u00e9s social": { + "account_number": "320515", + "account_type": "Equity" + } + }, + "Donaciones": { + "account_number": "3210", + "account_type": "Equity", + "En dinero": { + "account_number": "321005", + "account_type": "Equity" + }, + "En valores mobiliarios": { + "account_number": "321010", + "account_type": "Equity" + }, + "En bienes muebles": { + "account_number": "321015", + "account_type": "Equity" + }, + "En bienes inmuebles": { + "account_number": "321020", + "account_type": "Equity" + }, + "En intangibles": { + "account_number": "321025", + "account_type": "Equity" + } + }, + "Cr\u00e9dito mercantil": { + "account_number": "3215", + "account_type": "Equity" + }, + "Know how": { + "account_number": "3220", + "account_type": "Equity" + }, + "Super\u00e1vit m\u00e9todo de participaci\u00f3n": { + "account_number": "3225", + "account_type": "Equity", + "De acciones": { + "account_number": "322505", + "account_type": "Equity" + }, + "De cuotas o partes de inter\u00e9s social": { + "account_number": "322510", + "account_type": "Equity" + } + } + }, + "Reservas": { + "account_number": "33", + "account_type": "Equity", + "Reservas obligatorias": { + "account_number": "3305", + "account_type": "Equity", + "Reserva legal": { + "account_number": "330505", + "account_type": "Equity" + }, + "Reservas por disposiciones fiscales": { + "account_number": "330510", + "account_type": "Equity" + }, + "Reserva para readquisici\u00f3n de acciones": { + "account_number": "330515", + "account_type": "Equity" + }, + "Acciones propias readquiridas (DB)": { + "account_number": "330516", + "account_type": "Equity" + }, + "Reserva para readquisici\u00f3n de cuotas o partes de inter\u00e9s social": { + "account_number": "330517", + "account_type": "Equity" + }, + "Cuotas o partes de inter\u00e9s social propias readquiridas (DB)": { + "account_number": "330518", + "account_type": "Equity" + }, + "Reserva para extensi\u00f3n agropecuaria": { + "account_number": "330520", + "account_type": "Equity" + }, + "Reserva Ley 7\u00aa de 1990": { + "account_number": "330525", + "account_type": "Equity" + }, + "Reserva para reposici\u00f3n de semovientes": { + "account_number": "330530", + "account_type": "Equity" + }, + "Reserva Ley 4\u00aa de 1980": { + "account_number": "330535", + "account_type": "Equity" + }, + "Otras": { + "account_number": "330595", + "account_type": "Equity" + } + }, + "Reservas estatutarias": { + "account_number": "3310", + "account_type": "Equity", + "Para futuras capitalizaciones": { + "account_number": "331005", + "account_type": "Equity" + }, + "Para reposici\u00f3n de activos": { + "account_number": "331010", + "account_type": "Equity" + }, + "Para futuros ensanches": { + "account_number": "331015", + "account_type": "Equity" + }, + "Otras": { + "account_number": "331095", + "account_type": "Equity" + } + }, + "Reservas ocasionales": { + "account_number": "3315", + "account_type": "Equity", + "Para beneficencia y civismo": { + "account_number": "331505", + "account_type": "Equity" + }, + "Para futuras capitalizaciones": { + "account_number": "331510", + "account_type": "Equity" + }, + "Para futuros ensanches": { + "account_number": "331515", + "account_type": "Equity" + }, + "Para adquisici\u00f3n o reposici\u00f3n de propiedades, planta y equipo": { + "account_number": "331520", + "account_type": "Equity" + }, + "Para investigaciones y desarrollo": { + "account_number": "331525", + "account_type": "Equity" + }, + "Para fomento econ\u00f3mico": { + "account_number": "331530", + "account_type": "Equity" + }, + "Para capital de trabajo": { + "account_number": "331535", + "account_type": "Equity" + }, + "Para estabilizaci\u00f3n de rendimientos": { + "account_number": "331540", + "account_type": "Equity" + }, + "A disposici\u00f3n del m\u00e1ximo \u00f3rgano social": { + "account_number": "331545", + "account_type": "Equity" + }, + "Otras": { + "account_number": "331595", + "account_type": "Equity" + } + } + }, + "Revalorizaci\u00f3n del patrimonio": { + "account_number": "34", + "account_type": "Equity", + "Ajustes por inflaci\u00f3n": { + "account_number": "3405", + "account_type": "Equity", + "De capital social": { + "account_number": "340505", + "account_type": "Equity" + }, + "De super\u00e1vit de capital": { + "account_number": "340510", + "account_type": "Equity" + }, + "De reservas": { + "account_number": "340515", + "account_type": "Equity" + }, + "De resultados de ejercicios anteriores": { + "account_number": "340520", + "account_type": "Equity" + }, + "De activos en per\u00edodo improductivo": { + "account_number": "340525", + "account_type": "Equity" + }, + "De saneamiento fiscal": { + "account_number": "340530", + "account_type": "Equity" + }, + "De ajustes Decreto 3019 de 1989": { + "account_number": "340535", + "account_type": "Equity" + }, + "De dividendos y participaciones decretadas en acciones, cuotas o partes de inter\u00e9s social": { + "account_number": "340540", + "account_type": "Equity" + }, + "Super\u00e1vit m\u00e9todo de participaci\u00f3n": { + "account_number": "340545", + "account_type": "Equity" + } + }, + "Saneamiento fiscal": { + "account_number": "3410", + "account_type": "Equity" + }, + "Ajustes por inflaci\u00f3n Decreto 3019 de 1989": { + "account_number": "3415", + "account_type": "Equity" + } + }, + "Dividendos o participaciones decretados en acciones, cuotas o partes de inter\u00e9s social": { + "account_number": "35", + "account_type": "Equity", + "Dividendos decretados en acciones": { + "account_number": "3505", + "account_type": "Equity" + }, + "Participaciones decretadas en cuotas o partes de inter\u00e9s social": { + "account_number": "3510", + "account_type": "Equity" + } + }, + "Resultados del ejercicio": { + "account_number": "36", + "account_type": "Equity", + "Utilidad del ejercicio": { + "account_number": "3605", + "account_type": "Equity" + }, + "P\u00e9rdida del ejercicio": { + "account_number": "3610", + "account_type": "Equity" + } + }, + "Resultados de ejercicios anteriores": { + "account_number": "37", + "account_type": "Equity", + "Utilidades acumuladas": { + "account_number": "3705", + "account_type": "Equity" + }, + "P\u00e9rdidas acumuladas": { + "account_number": "3710", + "account_type": "Equity" + } + }, + "Super\u00e1vit por valorizaciones": { + "account_number": "38", + "account_type": "Equity", + "De inversiones": { + "account_number": "3805", + "account_type": "Equity", + "Acciones": { + "account_number": "380505", + "account_type": "Equity" + }, + "Cuotas o partes de inter\u00e9s social": { + "account_number": "380510", + "account_type": "Equity" + }, + "Derechos fiduciarios": { + "account_number": "380515", + "account_type": "Equity" + } + }, + "De propiedades, planta y equipo": { + "account_number": "3810", + "account_type": "Equity", + "Terrenos": { + "account_number": "381004", + "account_type": "Equity" + }, + "Materiales proyectos petroleros": { + "account_number": "381006", + "account_type": "Equity" + }, + "Construcciones y edificaciones": { + "account_number": "381008", + "account_type": "Equity" + }, + "Maquinaria y equipo": { + "account_number": "381012", + "account_type": "Equity" + }, + "Equipo de oficina": { + "account_number": "381016", + "account_type": "Equity" + }, + "Equipo de computaci\u00f3n y comunicaci\u00f3n": { + "account_number": "381020", + "account_type": "Equity" + }, + "Equipo m\u00e9dico-cient\u00edfico": { + "account_number": "381024", + "account_type": "Equity" + }, + "Equipo de hoteles y restaurantes": { + "account_number": "381028", + "account_type": "Equity" + }, + "Flota y equipo de transporte": { + "account_number": "381032", + "account_type": "Equity" + }, + "Flota y equipo fluvial y/o mar\u00edtimo": { + "account_number": "381036", + "account_type": "Equity" + }, + "Flota y equipo a\u00e9reo": { + "account_number": "381040", + "account_type": "Equity" + }, + "Flota y equipo f\u00e9rreo": { + "account_number": "381044", + "account_type": "Equity" + }, + "Acueductos, plantas y redes": { + "account_number": "381048", + "account_type": "Equity" + }, + "Armamento de vigilancia": { + "account_number": "381052", + "account_type": "Equity" + }, + "Envases y empaques": { + "account_number": "381056", + "account_type": "Equity" + }, + "Plantaciones agr\u00edcolas y forestales": { + "account_number": "381060", + "account_type": "Equity" + }, + "V\u00edas de comunicaci\u00f3n": { + "account_number": "381064", + "account_type": "Equity" + }, + "Minas y canteras": { + "account_number": "381068", + "account_type": "Equity" + }, + "Pozos artesianos": { + "account_number": "381072", + "account_type": "Equity" + }, + "Yacimientos": { + "account_number": "381076", + "account_type": "Equity" + }, + "Semovientes": { + "account_number": "381080", + "account_type": "Equity" + } + }, + "De otros activos": { + "account_number": "3895", + "account_type": "Equity", + "Bienes de arte y cultura": { + "account_number": "389505", + "account_type": "Equity" + }, + "Bienes entregados en comodato": { + "account_number": "389510", + "account_type": "Equity" + }, + "Bienes recibidos en pago": { + "account_number": "389515", + "account_type": "Equity" + }, + "Inventario de semovientes": { + "account_number": "389520", + "account_type": "Equity" + } + } + } + }, + "Ingresos": { + "account_number": "4", + "account_type": "Income Account", + "root_type": "Income", + "Operacionales": { + "account_number": "41", + "account_type": "Income Account", + "Agricultura, ganader\u00eda, caza y silvicultura": { + "account_number": "4105", + "account_type": "Income Account", + "Cultivo de cereales": { + "account_number": "410505", + "account_type": "Income Account" + }, + "Cultivos de hortalizas, legumbres y plantas ornamentales": { + "account_number": "410510", + "account_type": "Income Account" + }, + "Cultivos de frutas, nueces y plantas arom\u00e1ticas": { + "account_number": "410515", + "account_type": "Income Account" + }, + "Cultivo de caf\u00e9": { + "account_number": "410520", + "account_type": "Income Account" + }, + "Cultivo de flores": { + "account_number": "410525", + "account_type": "Income Account" + }, + "Cultivo de ca\u00f1a de az\u00facar": { + "account_number": "410530", + "account_type": "Income Account" + }, + "Cultivo de algod\u00f3n y plantas para material textil": { + "account_number": "410535", + "account_type": "Income Account" + }, + "Cultivo de banano": { + "account_number": "410540", + "account_type": "Income Account" + }, + "Otros cultivos agr\u00edcolas": { + "account_number": "410545", + "account_type": "Income Account" + }, + "Cr\u00eda de ovejas, cabras, asnos, mulas y burd\u00e9ganos": { + "account_number": "410550", + "account_type": "Income Account" + }, + "Cr\u00eda de ganado caballar y vacuno": { + "account_number": "410555", + "account_type": "Income Account" + }, + "Producci\u00f3n av\u00edcola": { + "account_number": "410560", + "account_type": "Income Account" + }, + "Cr\u00eda de otros animales": { + "account_number": "410565", + "account_type": "Income Account" + }, + "Servicios agr\u00edcolas y ganaderos": { + "account_number": "410570", + "account_type": "Income Account" + }, + "Actividad de caza": { + "account_number": "410575", + "account_type": "Income Account" + }, + "Actividad de silvicultura": { + "account_number": "410580", + "account_type": "Income Account" + }, + "Actividades conexas": { + "account_number": "410595", + "account_type": "Income Account" + }, + "Ajustes por inflaci\u00f3n": { + "account_number": "410599", + "account_type": "Income Account" + } + }, + "Pesca": { + "account_number": "4110", + "account_type": "Income Account", + "Actividad de pesca": { + "account_number": "411005", + "account_type": "Income Account" + }, + "Explotaci\u00f3n de criaderos de peces": { + "account_number": "411010", + "account_type": "Income Account" + }, + "Actividades conexas": { + "account_number": "411095", + "account_type": "Income Account" + }, + "Ajustes por inflaci\u00f3n": { + "account_number": "411099", + "account_type": "Income Account" + } + }, + "Explotaci\u00f3n de minas y canteras": { + "account_number": "4115", + "account_type": "Income Account", + "Carb\u00f3n": { + "account_number": "411505", + "account_type": "Income Account" + }, + "Petr\u00f3leo crudo": { + "account_number": "411510", + "account_type": "Income Account" + }, + "Gas natural": { + "account_number": "411512", + "account_type": "Income Account" + }, + "Servicios relacionados con extracci\u00f3n de petr\u00f3leo y gas": { + "account_number": "411514", + "account_type": "Income Account" + }, + "Minerales de hierro": { + "account_number": "411515", + "account_type": "Income Account" + }, + "Minerales metal\u00edferos no ferrosos": { + "account_number": "411520", + "account_type": "Income Account" + }, + "Piedra, arena y arcilla": { + "account_number": "411525", + "account_type": "Income Account" + }, + "Piedras preciosas": { + "account_number": "411527", + "account_type": "Income Account" + }, + "Oro": { + "account_number": "411528", + "account_type": "Income Account" + }, + "Otras minas y canteras": { + "account_number": "411530", + "account_type": "Income Account" + }, + "Prestaci\u00f3n de servicios sector minero": { + "account_number": "411532", + "account_type": "Income Account" + }, + "Actividades conexas": { + "account_number": "411595", + "account_type": "Income Account" + }, + "Ajustes por inflaci\u00f3n": { + "account_number": "411599", + "account_type": "Income Account" + } + }, + "Industrias manufactureras": { + "account_number": "4120", + "account_type": "Income Account", + "Producci\u00f3n y procesamiento de carnes y productos c\u00e1rnicos": { + "account_number": "412001", + "account_type": "Income Account" + }, + "Productos de pescado": { + "account_number": "412002", + "account_type": "Income Account" + }, + "Productos de frutas, legumbres y hortalizas": { + "account_number": "412003", + "account_type": "Income Account" + }, + "Elaboraci\u00f3n de aceites y grasas": { + "account_number": "412004", + "account_type": "Income Account" + }, + "Elaboraci\u00f3n de productos l\u00e1cteos": { + "account_number": "412005", + "account_type": "Income Account" + }, + "Elaboraci\u00f3n de productos de moliner\u00eda": { + "account_number": "412006", + "account_type": "Income Account" + }, + "Elaboraci\u00f3n de almidones y derivados": { + "account_number": "412007", + "account_type": "Income Account" + }, + "Elaboraci\u00f3n de alimentos para animales": { + "account_number": "412008", + "account_type": "Income Account" + }, + "Elaboraci\u00f3n de productos para panader\u00eda": { + "account_number": "412009", + "account_type": "Income Account" + }, + "Elaboraci\u00f3n de az\u00facar y melazas": { + "account_number": "412010", + "account_type": "Income Account" + }, + "Elaboraci\u00f3n de cacao, chocolate y confiter\u00eda": { + "account_number": "412011", + "account_type": "Income Account" + }, + "Elaboraci\u00f3n de pastas y productos farin\u00e1ceos": { + "account_number": "412012", + "account_type": "Income Account" + }, + "Elaboraci\u00f3n de productos de caf\u00e9": { + "account_number": "412013", + "account_type": "Income Account" + }, + "Elaboraci\u00f3n de otros productos alimenticios": { + "account_number": "412014", + "account_type": "Income Account" + }, + "Elaboraci\u00f3n de bebidas alcoh\u00f3licas y alcohol et\u00edlico": { + "account_number": "412015", + "account_type": "Income Account" + }, + "Elaboraci\u00f3n de vinos": { + "account_number": "412016", + "account_type": "Income Account" + }, + "Elaboraci\u00f3n de bebidas malteadas y de malta": { + "account_number": "412017", + "account_type": "Income Account" + }, + "Elaboraci\u00f3n de bebidas no alcoh\u00f3licas": { + "account_number": "412018", + "account_type": "Income Account" + }, + "Elaboraci\u00f3n de productos de tabaco": { + "account_number": "412019", + "account_type": "Income Account" + }, + "Preparaci\u00f3n e hilatura de fibras textiles y tejedur\u00eda": { + "account_number": "412020", + "account_type": "Income Account" + }, + "Acabado de productos textiles": { + "account_number": "412021", + "account_type": "Income Account" + }, + "Elaboraci\u00f3n de art\u00edculos de materiales textiles": { + "account_number": "412022", + "account_type": "Income Account" + }, + "Elaboraci\u00f3n de tapices y alfombras": { + "account_number": "412023", + "account_type": "Income Account" + }, + "Elaboraci\u00f3n de cuerdas, cordeles, bramantes y redes": { + "account_number": "412024", + "account_type": "Income Account" + }, + "Elaboraci\u00f3n de otros productos textiles": { + "account_number": "412025", + "account_type": "Income Account" + }, + "Elaboraci\u00f3n de tejidos": { + "account_number": "412026", + "account_type": "Income Account" + }, + "Elaboraci\u00f3n de prendas de vestir": { + "account_number": "412027", + "account_type": "Income Account" + }, + "Preparaci\u00f3n, adobo y te\u00f1ido de pieles": { + "account_number": "412028", + "account_type": "Income Account" + }, + "Curtido, adobo o preparaci\u00f3n de cuero": { + "account_number": "412029", + "account_type": "Income Account" + }, + "Elaboraci\u00f3n de maletas, bolsos y similares": { + "account_number": "412030", + "account_type": "Income Account" + }, + "Elaboraci\u00f3n de calzado": { + "account_number": "412031", + "account_type": "Income Account" + }, + "Producci\u00f3n de madera, art\u00edculos de madera y corcho": { + "account_number": "412032", + "account_type": "Income Account" + }, + "Elaboraci\u00f3n de pasta y productos de madera, papel y cart\u00f3n": { + "account_number": "412033", + "account_type": "Income Account" + }, + "Ediciones y publicaciones": { + "account_number": "412034", + "account_type": "Income Account" + }, + "Impresi\u00f3n": { + "account_number": "412035", + "account_type": "Income Account" + }, + "Servicios relacionados con la edici\u00f3n y la impresi\u00f3n": { + "account_number": "412036", + "account_type": "Income Account" + }, + "Reproducci\u00f3n de grabaciones": { + "account_number": "412037", + "account_type": "Income Account" + }, + "Elaboraci\u00f3n de productos de horno de coque": { + "account_number": "412038", + "account_type": "Income Account" + }, + "Elaboraci\u00f3n de productos de la refinaci\u00f3n de petr\u00f3leo": { + "account_number": "412039", + "account_type": "Income Account" + }, + "Elaboraci\u00f3n de sustancias qu\u00edmicas b\u00e1sicas": { + "account_number": "412040", + "account_type": "Income Account" + }, + "Elaboraci\u00f3n de abonos y compuestos de nitr\u00f3geno": { + "account_number": "412041", + "account_type": "Income Account" + }, + "Elaboraci\u00f3n de pl\u00e1stico y caucho sint\u00e9tico": { + "account_number": "412042", + "account_type": "Income Account" + }, + "Elaboraci\u00f3n de productos qu\u00edmicos de uso agropecuario": { + "account_number": "412043", + "account_type": "Income Account" + }, + "Elaboraci\u00f3n de pinturas, tintas y masillas": { + "account_number": "412044", + "account_type": "Income Account" + }, + "Elaboraci\u00f3n de productos farmac\u00e9uticos y bot\u00e1nicos": { + "account_number": "412045", + "account_type": "Income Account" + }, + "Elaboraci\u00f3n de jabones, detergentes y preparados de tocador": { + "account_number": "412046", + "account_type": "Income Account" + }, + "Elaboraci\u00f3n de otros productos qu\u00edmicos": { + "account_number": "412047", + "account_type": "Income Account" + }, + "Elaboraci\u00f3n de fibras": { + "account_number": "412048", + "account_type": "Income Account" + }, + "Elaboraci\u00f3n de otros productos de caucho": { + "account_number": "412049", + "account_type": "Income Account" + }, + "Elaboraci\u00f3n de productos de pl\u00e1stico": { + "account_number": "412050", + "account_type": "Income Account" + }, + "Elaboraci\u00f3n de vidrio y productos de vidrio": { + "account_number": "412051", + "account_type": "Income Account" + }, + "Elaboraci\u00f3n de productos de cer\u00e1mica, loza, piedra, arcilla y porcelana": { + "account_number": "412052", + "account_type": "Income Account" + }, + "Elaboraci\u00f3n de cemento, cal y yeso": { + "account_number": "412053", + "account_type": "Income Account" + }, + "Elaboraci\u00f3n de art\u00edculos de hormig\u00f3n, cemento y yeso": { + "account_number": "412054", + "account_type": "Income Account" + }, + "Corte, tallado y acabado de la piedra": { + "account_number": "412055", + "account_type": "Income Account" + }, + "Elaboraci\u00f3n de otros productos minerales no met\u00e1licos": { + "account_number": "412056", + "account_type": "Income Account" + }, + "Industrias b\u00e1sicas y fundici\u00f3n de hierro y acero": { + "account_number": "412057", + "account_type": "Income Account" + }, + "Productos primarios de metales preciosos y de metales no ferrosos": { + "account_number": "412058", + "account_type": "Income Account" + }, + "Fundici\u00f3n de metales no ferrosos": { + "account_number": "412059", + "account_type": "Income Account" + }, + "Fabricaci\u00f3n de productos met\u00e1licos para uso estructural": { + "account_number": "412060", + "account_type": "Income Account" + }, + "Forja, prensado, estampado, laminado de metal y pulvimetalurgia": { + "account_number": "412061", + "account_type": "Income Account" + }, + "Revestimiento de metales y obras de ingenier\u00eda mec\u00e1nica": { + "account_number": "412062", + "account_type": "Income Account" + }, + "Fabricaci\u00f3n de art\u00edculos de ferreter\u00eda": { + "account_number": "412063", + "account_type": "Income Account" + }, + "Elaboraci\u00f3n de otros productos de metal": { + "account_number": "412064", + "account_type": "Income Account" + }, + "Fabricaci\u00f3n de maquinaria y equipo": { + "account_number": "412065", + "account_type": "Income Account" + }, + "Fabricaci\u00f3n de equipos de elevaci\u00f3n y manipulaci\u00f3n": { + "account_number": "412066", + "account_type": "Income Account" + }, + "Elaboraci\u00f3n de aparatos de uso dom\u00e9stico": { + "account_number": "412067", + "account_type": "Income Account" + }, + "Elaboraci\u00f3n de equipo de oficina": { + "account_number": "412068", + "account_type": "Income Account" + }, + "Elaboraci\u00f3n de pilas y bater\u00edas primarias": { + "account_number": "412069", + "account_type": "Income Account" + }, + "Elaboraci\u00f3n de equipo de iluminaci\u00f3n": { + "account_number": "412070", + "account_type": "Income Account" + }, + "Elaboraci\u00f3n de otros tipos de equipo el\u00e9ctrico": { + "account_number": "412071", + "account_type": "Income Account" + }, + "Fabricaci\u00f3n de equipos de radio, televisi\u00f3n y comunicaciones": { + "account_number": "412072", + "account_type": "Income Account" + }, + "Fabricaci\u00f3n de aparatos e instrumentos m\u00e9dicos": { + "account_number": "412073", + "account_type": "Income Account" + }, + "Fabricaci\u00f3n de instrumentos de medici\u00f3n y control": { + "account_number": "412074", + "account_type": "Income Account" + }, + "Fabricaci\u00f3n de instrumentos de \u00f3ptica y equipo fotogr\u00e1fico": { + "account_number": "412075", + "account_type": "Income Account" + }, + "Fabricaci\u00f3n de relojes": { + "account_number": "412076", + "account_type": "Income Account" + }, + "Fabricaci\u00f3n de veh\u00edculos automotores": { + "account_number": "412077", + "account_type": "Income Account" + }, + "Fabricaci\u00f3n de carrocer\u00edas para automotores": { + "account_number": "412078", + "account_type": "Income Account" + }, + "Fabricaci\u00f3n de partes piezas y accesorios para automotores": { + "account_number": "412079", + "account_type": "Income Account" + }, + "Fabricaci\u00f3n y reparaci\u00f3n de buques y otras embarcaciones": { + "account_number": "412080", + "account_type": "Income Account" + }, + "Fabricaci\u00f3n de locomotoras y material rodante para ferrocarriles": { + "account_number": "412081", + "account_type": "Income Account" + }, + "Fabricaci\u00f3n de aeronaves": { + "account_number": "412082", + "account_type": "Income Account" + }, + "Fabricaci\u00f3n de motocicletas": { + "account_number": "412083", + "account_type": "Income Account" + }, + "Fabricaci\u00f3n de bicicletas y sillas de ruedas": { + "account_number": "412084", + "account_type": "Income Account" + }, + "Fabricaci\u00f3n de otros tipos de transporte": { + "account_number": "412085", + "account_type": "Income Account" + }, + "Fabricaci\u00f3n de muebles": { + "account_number": "412086", + "account_type": "Income Account" + }, + "Fabricaci\u00f3n de joyas y art\u00edculos conexos": { + "account_number": "412087", + "account_type": "Income Account" + }, + "Fabricaci\u00f3n de instrumentos de m\u00fasica": { + "account_number": "412088", + "account_type": "Income Account" + }, + "Fabricaci\u00f3n de art\u00edculos y equipo para deporte": { + "account_number": "412089", + "account_type": "Income Account" + }, + "Fabricaci\u00f3n de juegos y juguetes": { + "account_number": "412090", + "account_type": "Income Account" + }, + "Reciclamiento de desperdicios": { + "account_number": "412091", + "account_type": "Income Account" + }, + "Productos de otras industrias manufactureras": { + "account_number": "412095", + "account_type": "Income Account" + }, + "Ajustes por inflaci\u00f3n": { + "account_number": "412099", + "account_type": "Income Account" + } + }, + "Suministro de electricidad, gas y agua": { + "account_number": "4125", + "account_type": "Income Account", + "Generaci\u00f3n, captaci\u00f3n y distribuci\u00f3n de energ\u00eda el\u00e9ctrica": { + "account_number": "412505", + "account_type": "Income Account" + }, + "Fabricaci\u00f3n de gas y distribuci\u00f3n de combustibles gaseosos": { + "account_number": "412510", + "account_type": "Income Account" + }, + "Captaci\u00f3n, depuraci\u00f3n y distribuci\u00f3n de agua": { + "account_number": "412515", + "account_type": "Income Account" + }, + "Actividades conexas": { + "account_number": "412595", + "account_type": "Income Account" + }, + "Ajustes por inflaci\u00f3n": { + "account_number": "412599", + "account_type": "Income Account" + } + }, + "Construcci\u00f3n": { + "account_number": "4130", + "account_type": "Income Account", + "Preparaci\u00f3n de terrenos": { + "account_number": "413005", + "account_type": "Income Account" + }, + "Construcci\u00f3n de edificios y obras de ingenier\u00eda civil": { + "account_number": "413010", + "account_type": "Income Account" + }, + "Acondicionamiento de edificios": { + "account_number": "413015", + "account_type": "Income Account" + }, + "Terminaci\u00f3n de edificaciones": { + "account_number": "413020", + "account_type": "Income Account" + }, + "Alquiler de equipo con operarios": { + "account_number": "413025", + "account_type": "Income Account" + }, + "Actividades conexas": { + "account_number": "413095", + "account_type": "Income Account" + }, + "Ajustes por inflaci\u00f3n": { + "account_number": "413099", + "account_type": "Income Account" + } + }, + "Comercio al por mayor y al por menor": { + "account_number": "4135", + "account_type": "Income Account", + "Venta de veh\u00edculos automotores": { + "account_number": "413502", + "account_type": "Income Account" + }, + "Mantenimiento, reparaci\u00f3n y lavado de veh\u00edculos automotores": { + "account_number": "413504", + "account_type": "Income Account" + }, + "Venta de partes, piezas y accesorios de veh\u00edculos automotores": { + "account_number": "413506", + "account_type": "Income Account" + }, + "Venta de combustibles s\u00f3lidos, l\u00edquidos, gaseosos": { + "account_number": "413508", + "account_type": "Income Account" + }, + "Venta de lubricantes, aditivos, llantas y lujos para automotores": { + "account_number": "413510", + "account_type": "Income Account" + }, + "Venta a cambio de retribuci\u00f3n o por contrata": { + "account_number": "413512", + "account_type": "Income Account" + }, + "Venta de insumos, materias primas agropecuarias y flores": { + "account_number": "413514", + "account_type": "Income Account" + }, + "Venta de otros insumos y materias primas no agropecuarias": { + "account_number": "413516", + "account_type": "Income Account" + }, + "Venta de animales vivos y cueros": { + "account_number": "413518", + "account_type": "Income Account" + }, + "Venta de productos en almacenes no especializados": { + "account_number": "413520", + "account_type": "Income Account" + }, + "Venta de productos agropecuarios": { + "account_number": "413522", + "account_type": "Income Account" + }, + "Venta de productos textiles, de vestir, de cuero y calzado": { + "account_number": "413524", + "account_type": "Income Account" + }, + "Venta de papel y cart\u00f3n": { + "account_number": "413526", + "account_type": "Income Account" + }, + "Venta de libros, revistas, elementos de papeler\u00eda, \u00fatiles y textos escolares": { + "account_number": "413528", + "account_type": "Income Account" + }, + "Venta de juegos, juguetes y art\u00edculos deportivos": { + "account_number": "413530", + "account_type": "Income Account" + }, + "Venta de instrumentos quir\u00fargicos y ortop\u00e9dicos": { + "account_number": "413532", + "account_type": "Income Account" + }, + "Venta de art\u00edculos en relojer\u00edas y joyer\u00edas": { + "account_number": "413534", + "account_type": "Income Account" + }, + "Venta de electrodom\u00e9sticos y muebles": { + "account_number": "413536", + "account_type": "Income Account" + }, + "Venta de productos de aseo, farmac\u00e9uticos, medicinales, y art\u00edculos de tocador": { + "account_number": "413538", + "account_type": "Income Account" + }, + "Venta de cubiertos, vajillas, cristaler\u00eda, porcelanas, cer\u00e1micas y otros art\u00edculos de uso dom\u00e9stico": { + "account_number": "413540", + "account_type": "Income Account" + }, + "Venta de materiales de construcci\u00f3n, fontaner\u00eda y calefacci\u00f3n": { + "account_number": "413542", + "account_type": "Income Account" + }, + "Venta de pinturas y lacas": { + "account_number": "413544", + "account_type": "Income Account" + }, + "Venta de productos de vidrios y marqueter\u00eda": { + "account_number": "413546", + "account_type": "Income Account" + }, + "Venta de herramientas y art\u00edculos de ferreter\u00eda": { + "account_number": "413548", + "account_type": "Income Account" + }, + "Venta de qu\u00edmicos": { + "account_number": "413550", + "account_type": "Income Account" + }, + "Venta de productos intermedios, desperdicios y desechos": { + "account_number": "413552", + "account_type": "Income Account" + }, + "Venta de maquinaria, equipo de oficina y programas de computador": { + "account_number": "413554", + "account_type": "Income Account" + }, + "Venta de art\u00edculos en cacharrer\u00edas y miscel\u00e1neas": { + "account_number": "413556", + "account_type": "Income Account" + }, + "Venta de instrumentos musicales": { + "account_number": "413558", + "account_type": "Income Account" + }, + "Venta de art\u00edculos en casas de empe\u00f1o y prender\u00edas": { + "account_number": "413560", + "account_type": "Income Account" + }, + "Venta de equipo fotogr\u00e1fico": { + "account_number": "413562", + "account_type": "Income Account" + }, + "Venta de equipo \u00f3ptico y de precisi\u00f3n": { + "account_number": "413564", + "account_type": "Income Account" + }, + "Venta de empaques": { + "account_number": "413566", + "account_type": "Income Account" + }, + "Venta de equipo profesional y cient\u00edfico": { + "account_number": "413568", + "account_type": "Income Account" + }, + "Venta de loter\u00edas, rifas, chance, apuestas y similares": { + "account_number": "413570", + "account_type": "Income Account" + }, + "Reparaci\u00f3n de efectos personales y electrodom\u00e9sticos": { + "account_number": "413572", + "account_type": "Income Account" + }, + "Venta de otros productos": { + "account_number": "413595", + "account_type": "Income Account" + }, + "Ajustes por inflaci\u00f3n": { + "account_number": "413599", + "account_type": "Income Account" + } + }, + "Hoteles y restaurantes": { + "account_number": "4140", + "account_type": "Income Account", + "Hoteler\u00eda": { + "account_number": "414005", + "account_type": "Income Account" + }, + "Campamento y otros tipos de hospedaje": { + "account_number": "414010", + "account_type": "Income Account" + }, + "Restaurantes": { + "account_number": "414015", + "account_type": "Income Account" + }, + "Bares y cantinas": { + "account_number": "414020", + "account_type": "Income Account" + }, + "Actividades conexas": { + "account_number": "414095", + "account_type": "Income Account" + }, + "Ajustes por inflaci\u00f3n": { + "account_number": "414099", + "account_type": "Income Account" + } + }, + "Transporte, almacenamiento y comunicaciones": { + "account_number": "4145", + "account_type": "Income Account", + "Servicio de transporte por carretera": { + "account_number": "414505", + "account_type": "Income Account" + }, + "Servicio de transporte por v\u00eda f\u00e9rrea": { + "account_number": "414510", + "account_type": "Income Account" + }, + "Servicio de transporte por v\u00eda acu\u00e1tica": { + "account_number": "414515", + "account_type": "Income Account" + }, + "Servicio de transporte por v\u00eda a\u00e9rea": { + "account_number": "414520", + "account_type": "Income Account" + }, + "Servicio de transporte por tuber\u00edas": { + "account_number": "414525", + "account_type": "Income Account" + }, + "Manipulaci\u00f3n de carga": { + "account_number": "414530", + "account_type": "Income Account" + }, + "Almacenamiento y dep\u00f3sito": { + "account_number": "414535", + "account_type": "Income Account" + }, + "Servicios complementarios para el transporte": { + "account_number": "414540", + "account_type": "Income Account" + }, + "Agencias de viaje": { + "account_number": "414545", + "account_type": "Income Account" + }, + "Otras agencias de transporte": { + "account_number": "414550", + "account_type": "Income Account" + }, + "Servicio postal y de correo": { + "account_number": "414555", + "account_type": "Income Account" + }, + "Servicio telef\u00f3nico": { + "account_number": "414560", + "account_type": "Income Account" + }, + "Servicio de tel\u00e9grafo": { + "account_number": "414565", + "account_type": "Income Account" + }, + "Servicio de transmisi\u00f3n de datos": { + "account_number": "414570", + "account_type": "Income Account" + }, + "Servicio de radio y televisi\u00f3n por cable": { + "account_number": "414575", + "account_type": "Income Account" + }, + "Transmisi\u00f3n de sonido e im\u00e1genes por contrato": { + "account_number": "414580", + "account_type": "Income Account" + }, + "Actividades conexas": { + "account_number": "414595", + "account_type": "Income Account" + }, + "Ajustes por inflaci\u00f3n": { + "account_number": "414599", + "account_type": "Income Account" + } + }, + "Actividad financiera": { + "account_number": "4150", + "account_type": "Income Account", + "Venta de inversiones": { + "account_number": "415005", + "account_type": "Income Account" + }, + "Dividendos de sociedades an\u00f3nimas y/o asimiladas": { + "account_number": "415010", + "account_type": "Income Account" + }, + "Participaciones de sociedades limitadas y/o asimiladas": { + "account_number": "415015", + "account_type": "Income Account" + }, + "Intereses": { + "account_number": "415020", + "account_type": "Income Account" + }, + "Reajuste monetario-UPAC (hoy UVR)": { + "account_number": "415025", + "account_type": "Income Account" + }, + "Comisiones": { + "account_number": "415030", + "account_type": "Income Account" + }, + "Operaciones de descuento": { + "account_number": "415035", + "account_type": "Income Account" + }, + "Cuotas de inscripci\u00f3n-consorcios": { + "account_number": "415040", + "account_type": "Income Account" + }, + "Cuotas de administraci\u00f3n-consorcios": { + "account_number": "415045", + "account_type": "Income Account" + }, + "Reajuste del sistema-consorcios": { + "account_number": "415050", + "account_type": "Income Account" + }, + "Eliminaci\u00f3n de suscriptores-consorcios": { + "account_number": "415055", + "account_type": "Income Account" + }, + "Cuotas de ingreso o retiro-sociedad administradora": { + "account_number": "415060", + "account_type": "Income Account" + }, + "Servicios a comisionistas": { + "account_number": "415065", + "account_type": "Income Account" + }, + "Inscripciones y cuotas": { + "account_number": "415070", + "account_type": "Income Account" + }, + "Recuperaci\u00f3n de garant\u00edas": { + "account_number": "415075", + "account_type": "Income Account" + }, + "Ingresos m\u00e9todo de participaci\u00f3n": { + "account_number": "415080", + "account_type": "Income Account" + }, + "Actividades conexas": { + "account_number": "415095", + "account_type": "Income Account" + }, + "Ajustes por inflaci\u00f3n": { + "account_number": "415099", + "account_type": "Income Account" + } + }, + "Actividades inmobiliarias, empresariales y de alquiler": { + "account_number": "4155", + "account_type": "Income Account", + "Arrendamientos de bienes inmuebles": { + "account_number": "415505", + "account_type": "Income Account" + }, + "Inmobiliarias por retribuci\u00f3n o contrata": { + "account_number": "415510", + "account_type": "Income Account" + }, + "Alquiler equipo de transporte": { + "account_number": "415515", + "account_type": "Income Account" + }, + "Alquiler maquinaria y equipo": { + "account_number": "415520", + "account_type": "Income Account" + }, + "Alquiler de efectos personales y enseres dom\u00e9sticos": { + "account_number": "415525", + "account_type": "Income Account" + }, + "Consultor\u00eda en equipo y programas de inform\u00e1tica": { + "account_number": "415530", + "account_type": "Income Account" + }, + "Procesamiento de datos": { + "account_number": "415535", + "account_type": "Income Account" + }, + "Mantenimiento y reparaci\u00f3n de maquinaria de oficina": { + "account_number": "415540", + "account_type": "Income Account" + }, + "Investigaciones cient\u00edficas y de desarrollo": { + "account_number": "415545", + "account_type": "Income Account" + }, + "Actividades empresariales de consultor\u00eda": { + "account_number": "415550", + "account_type": "Income Account" + }, + "Publicidad": { + "account_number": "415555", + "account_type": "Income Account" + }, + "Dotaci\u00f3n de personal": { + "account_number": "415560", + "account_type": "Income Account" + }, + "Investigaci\u00f3n y seguridad": { + "account_number": "415565", + "account_type": "Income Account" + }, + "Limpieza de inmuebles": { + "account_number": "415570", + "account_type": "Income Account" + }, + "Fotograf\u00eda": { + "account_number": "415575", + "account_type": "Income Account" + }, + "Envase y empaque": { + "account_number": "415580", + "account_type": "Income Account" + }, + "Fotocopiado": { + "account_number": "415585", + "account_type": "Income Account" + }, + "Mantenimiento y reparaci\u00f3n de maquinaria y equipo": { + "account_number": "415590", + "account_type": "Income Account" + }, + "Actividades conexas": { + "account_number": "415595", + "account_type": "Income Account" + }, + "Ajustes por inflaci\u00f3n": { + "account_number": "415599", + "account_type": "Income Account" + } + }, + "Ense\u00f1anza": { + "account_number": "4160", + "account_type": "Income Account", + "Actividades relacionadas con la educaci\u00f3n": { + "account_number": "416005", + "account_type": "Income Account" + }, + "Actividades conexas": { + "account_number": "416095", + "account_type": "Income Account" + }, + "Ajustes por inflaci\u00f3n": { + "account_number": "416099", + "account_type": "Income Account" + } + }, + "Servicios sociales y de salud": { + "account_number": "4165", + "account_type": "Income Account", + "Servicio hospitalario": { + "account_number": "416505", + "account_type": "Income Account" + }, + "Servicio m\u00e9dico": { + "account_number": "416510", + "account_type": "Income Account" + }, + "Servicio odontol\u00f3gico": { + "account_number": "416515", + "account_type": "Income Account" + }, + "Servicio de laboratorio": { + "account_number": "416520", + "account_type": "Income Account" + }, + "Actividades veterinarias": { + "account_number": "416525", + "account_type": "Income Account" + }, + "Actividades de servicios sociales": { + "account_number": "416530", + "account_type": "Income Account" + }, + "Actividades conexas": { + "account_number": "416595", + "account_type": "Income Account" + }, + "Ajustes por inflaci\u00f3n": { + "account_number": "416599", + "account_type": "Income Account" + } + }, + "Otras actividades de servicios comunitarios, sociales y personales": { + "account_number": "4170", + "account_type": "Income Account", + "Eliminaci\u00f3n de desperdicios y aguas residuales": { + "account_number": "417005", + "account_type": "Income Account" + }, + "Actividades de asociaci\u00f3n": { + "account_number": "417010", + "account_type": "Income Account" + }, + "Producci\u00f3n y distribuci\u00f3n de filmes y videocintas": { + "account_number": "417015", + "account_type": "Income Account" + }, + "Exhibici\u00f3n de filmes y videocintas": { + "account_number": "417020", + "account_type": "Income Account" + }, + "Actividad de radio y televisi\u00f3n": { + "account_number": "417025", + "account_type": "Income Account" + }, + "Actividad teatral, musical y art\u00edstica": { + "account_number": "417030", + "account_type": "Income Account" + }, + "Grabaci\u00f3n y producci\u00f3n de discos": { + "account_number": "417035", + "account_type": "Income Account" + }, + "Entretenimiento y esparcimiento": { + "account_number": "417040", + "account_type": "Income Account" + }, + "Agencias de noticias": { + "account_number": "417045", + "account_type": "Income Account" + }, + "Lavander\u00edas y similares": { + "account_number": "417050", + "account_type": "Income Account" + }, + "Peluquer\u00edas y similares": { + "account_number": "417055", + "account_type": "Income Account" + }, + "Servicios funerarios": { + "account_number": "417060", + "account_type": "Income Account" + }, + "Zonas francas": { + "account_number": "417065", + "account_type": "Income Account" + }, + "Actividades conexas": { + "account_number": "417095", + "account_type": "Income Account" + }, + "Ajustes por inflaci\u00f3n": { + "account_number": "417099", + "account_type": "Income Account" + } + }, + "Devoluciones en ventas (DB)": { + "account_number": "4175", + "account_type": "Income Account", + "Ajustes por inflaci\u00f3n": { + "account_number": "417599", + "account_type": "Income Account" + } + } + }, + "No operacionales": { + "account_number": "42", + "account_type": "Income Account", + "Otras ventas": { + "account_number": "4205", + "account_type": "Income Account", + "Materia prima": { + "account_number": "420505", + "account_type": "Income Account" + }, + "Material de desecho": { + "account_number": "420510", + "account_type": "Income Account" + }, + "Materiales varios": { + "account_number": "420515", + "account_type": "Income Account" + }, + "Productos de diversificaci\u00f3n": { + "account_number": "420520", + "account_type": "Income Account" + }, + "Excedentes de exportaci\u00f3n": { + "account_number": "420525", + "account_type": "Income Account" + }, + "Envases y empaques": { + "account_number": "420530", + "account_type": "Income Account" + }, + "Productos agr\u00edcolas": { + "account_number": "420535", + "account_type": "Income Account" + }, + "De propaganda": { + "account_number": "420540", + "account_type": "Income Account" + }, + "Productos en remate": { + "account_number": "420545", + "account_type": "Income Account" + }, + "Combustibles y lubricantes": { + "account_number": "420550", + "account_type": "Income Account" + }, + "Ajustes por inflaci\u00f3n": { + "account_number": "420599", + "account_type": "Income Account" + } + }, + "Financieros": { + "account_number": "4210", + "account_type": "Income Account", + "Intereses": { + "account_number": "421005", + "account_type": "Income Account" + }, + "Reajuste monetario-UPAC (hoy UVR)": { + "account_number": "421010", + "account_type": "Income Account" + }, + "Descuentos amortizados": { + "account_number": "421015", + "account_type": "Income Account" + }, + "Diferencia en cambio": { + "account_number": "421020", + "account_type": "Income Account" + }, + "Financiaci\u00f3n veh\u00edculos": { + "account_number": "421025", + "account_type": "Income Account" + }, + "Financiaci\u00f3n sistemas de viajes": { + "account_number": "421030", + "account_type": "Income Account" + }, + "Aceptaciones bancarias": { + "account_number": "421035", + "account_type": "Income Account" + }, + "Descuentos comerciales condicionados": { + "account_number": "421040", + "account_type": "Income Account" + }, + "Descuentos bancarios": { + "account_number": "421045", + "account_type": "Income Account" + }, + "Comisiones cheques de otras plazas": { + "account_number": "421050", + "account_type": "Income Account" + }, + "Multas y recargos": { + "account_number": "421055", + "account_type": "Income Account" + }, + "Sanciones cheques devueltos": { + "account_number": "421060", + "account_type": "Income Account" + }, + "Otros": { + "account_number": "421095", + "account_type": "Income Account" + }, + "Ajustes por inflaci\u00f3n": { + "account_number": "421099", + "account_type": "Income Account" + } + }, + "Dividendos y participaciones": { + "account_number": "4215", + "account_type": "Income Account", + "De sociedades an\u00f3nimas y/o asimiladas": { + "account_number": "421505", + "account_type": "Income Account" + }, + "De sociedades limitadas y/o asimiladas": { + "account_number": "421510", + "account_type": "Income Account" + }, + "Ajustes por inflaci\u00f3n": { + "account_number": "421599", + "account_type": "Income Account" + } + }, + "Ingresos m\u00e9todo de participaci\u00f3n": { + "account_number": "4218", + "account_type": "Income Account", + "De sociedades an\u00f3nimas y/o asimiladas": { + "account_number": "421805", + "account_type": "Income Account" + }, + "De sociedades limitadas y/o asimiladas": { + "account_number": "421810", + "account_type": "Income Account" + } + }, + "Arrendamientos": { + "account_number": "4220", + "account_type": "Income Account", + "Terrenos": { + "account_number": "422005", + "account_type": "Income Account" + }, + "Construcciones y edificios": { + "account_number": "422010", + "account_type": "Income Account" + }, + "Maquinaria y equipo": { + "account_number": "422015", + "account_type": "Income Account" + }, + "Equipo de oficina": { + "account_number": "422020", + "account_type": "Income Account" + }, + "Equipo de computaci\u00f3n y comunicaci\u00f3n": { + "account_number": "422025", + "account_type": "Income Account" + }, + "Equipo m\u00e9dico-cient\u00edfico": { + "account_number": "422030", + "account_type": "Income Account" + }, + "Equipo de hoteles y restaurantes": { + "account_number": "422035", + "account_type": "Income Account" + }, + "Flota y equipo de transporte": { + "account_number": "422040", + "account_type": "Income Account" + }, + "Flota y equipo fluvial y/o mar\u00edtimo": { + "account_number": "422045", + "account_type": "Income Account" + }, + "Flota y equipo a\u00e9reo": { + "account_number": "422050", + "account_type": "Income Account" + }, + "Flota y equipo f\u00e9rreo": { + "account_number": "422055", + "account_type": "Income Account" + }, + "Acueductos, plantas y redes": { + "account_number": "422060", + "account_type": "Income Account" + }, + "Envases y empaques": { + "account_number": "422062", + "account_type": "Income Account" + }, + "Plantaciones agr\u00edcolas y forestales": { + "account_number": "422065", + "account_type": "Income Account" + }, + "Aer\u00f3dromos": { + "account_number": "422070", + "account_type": "Income Account" + }, + "Semovientes": { + "account_number": "422075", + "account_type": "Income Account" + }, + "Ajustes por inflaci\u00f3n": { + "account_number": "422099", + "account_type": "Income Account" + } + }, + "Comisiones": { + "account_number": "4225", + "account_type": "Income Account", + "Sobre inversiones": { + "account_number": "422505", + "account_type": "Income Account" + }, + "De concesionarios": { + "account_number": "422510", + "account_type": "Income Account" + }, + "De actividades financieras": { + "account_number": "422515", + "account_type": "Income Account" + }, + "Por venta de servicios de taller": { + "account_number": "422520", + "account_type": "Income Account" + }, + "Por venta de seguros": { + "account_number": "422525", + "account_type": "Income Account" + }, + "Por ingresos para terceros": { + "account_number": "422530", + "account_type": "Income Account" + }, + "Por distribuci\u00f3n de pel\u00edculas": { + "account_number": "422535", + "account_type": "Income Account" + }, + "Derechos de autor": { + "account_number": "422540", + "account_type": "Income Account" + }, + "Derechos de programaci\u00f3n": { + "account_number": "422545", + "account_type": "Income Account" + }, + "Ajustes por inflaci\u00f3n": { + "account_number": "422599", + "account_type": "Income Account" + } + }, + "Honorarios": { + "account_number": "4230", + "account_type": "Income Account", + "Asesor\u00edas": { + "account_number": "423005", + "account_type": "Income Account" + }, + "Asistencia t\u00e9cnica": { + "account_number": "423010", + "account_type": "Income Account" + }, + "Administraci\u00f3n de vinculadas": { + "account_number": "423015", + "account_type": "Income Account" + }, + "Ajustes por inflaci\u00f3n": { + "account_number": "423099", + "account_type": "Income Account" + } + }, + "Servicios": { + "account_number": "4235", + "account_type": "Income Account", + "De b\u00e1scula": { + "account_number": "423505", + "account_type": "Income Account" + }, + "De transporte": { + "account_number": "423510", + "account_type": "Income Account" + }, + "De prensa": { + "account_number": "423515", + "account_type": "Income Account" + }, + "Administrativos": { + "account_number": "423520", + "account_type": "Income Account" + }, + "T\u00e9cnicos": { + "account_number": "423525", + "account_type": "Income Account" + }, + "De computaci\u00f3n": { + "account_number": "423530", + "account_type": "Income Account" + }, + "De telefax": { + "account_number": "423535", + "account_type": "Income Account" + }, + "Taller de veh\u00edculos": { + "account_number": "423540", + "account_type": "Income Account" + }, + "De recepci\u00f3n de aeronaves": { + "account_number": "423545", + "account_type": "Income Account" + }, + "De transporte programa gas natural": { + "account_number": "423550", + "account_type": "Income Account" + }, + "Por contratos": { + "account_number": "423555", + "account_type": "Income Account" + }, + "De trilla": { + "account_number": "423560", + "account_type": "Income Account" + }, + "De mantenimiento": { + "account_number": "423565", + "account_type": "Income Account" + }, + "Al personal": { + "account_number": "423570", + "account_type": "Income Account" + }, + "De casino": { + "account_number": "423575", + "account_type": "Income Account" + }, + "Fletes": { + "account_number": "423580", + "account_type": "Income Account" + }, + "Entre compa\u00f1\u00edas": { + "account_number": "423585", + "account_type": "Income Account" + }, + "Otros": { + "account_number": "423595", + "account_type": "Income Account" + }, + "Ajustes por inflaci\u00f3n": { + "account_number": "423599", + "account_type": "Income Account" + } + }, + "Utilidad en venta de inversiones": { + "account_number": "4240", + "account_type": "Income Account", + "Acciones": { + "account_number": "424005", + "account_type": "Income Account" + }, + "Cuotas o partes de inter\u00e9s social": { + "account_number": "424010", + "account_type": "Income Account" + }, + "Bonos": { + "account_number": "424015", + "account_type": "Income Account" + }, + "C\u00e9dulas": { + "account_number": "424020", + "account_type": "Income Account" + }, + "Certificados": { + "account_number": "424025", + "account_type": "Income Account" + }, + "Papeles comerciales": { + "account_number": "424030", + "account_type": "Income Account" + }, + "T\u00edtulos": { + "account_number": "424035", + "account_type": "Income Account" + }, + "Derechos fiduciarios": { + "account_number": "424045", + "account_type": "Income Account" + }, + "Obligatorias": { + "account_number": "424050", + "account_type": "Income Account" + }, + "Otras": { + "account_number": "424095", + "account_type": "Income Account" + }, + "Ajustes por inflaci\u00f3n": { + "account_number": "424099", + "account_type": "Income Account" + } + }, + "Utilidad en venta de propiedades, planta y equipo": { + "account_number": "4245", + "account_type": "Income Account", + "Terrenos": { + "account_number": "424504", + "account_type": "Income Account" + }, + "Materiales industria petrolera": { + "account_number": "424506", + "account_type": "Income Account" + }, + "Construcciones en curso": { + "account_number": "424508", + "account_type": "Income Account" + }, + "Maquinaria en montaje": { + "account_number": "424512", + "account_type": "Income Account" + }, + "Construcciones y edificaciones": { + "account_number": "424516", + "account_type": "Income Account" + }, + "Maquinaria y equipo": { + "account_number": "424520", + "account_type": "Income Account" + }, + "Equipo de oficina": { + "account_number": "424524", + "account_type": "Income Account" + }, + "Equipo de computaci\u00f3n y comunicaci\u00f3n": { + "account_number": "424528", + "account_type": "Income Account" + }, + "Equipo m\u00e9dico-cient\u00edfico": { + "account_number": "424532", + "account_type": "Income Account" + }, + "Equipo de hoteles y restaurantes": { + "account_number": "424536", + "account_type": "Income Account" + }, + "Flota y equipo de transporte": { + "account_number": "424540", + "account_type": "Income Account" + }, + "Flota y equipo fluvial y/o mar\u00edtimo": { + "account_number": "424544", + "account_type": "Income Account" + }, + "Flota y equipo a\u00e9reo": { + "account_number": "424548", + "account_type": "Income Account" + }, + "Flota y equipo f\u00e9rreo": { + "account_number": "424552", + "account_type": "Income Account" + }, + "Acueductos, plantas y redes": { + "account_number": "424556", + "account_type": "Income Account" + }, + "Armamento de vigilancia": { + "account_number": "424560", + "account_type": "Income Account" + }, + "Envases y empaques": { + "account_number": "424562", + "account_type": "Income Account" + }, + "Plantaciones agr\u00edcolas y forestales": { + "account_number": "424564", + "account_type": "Income Account" + }, + "V\u00edas de comunicaci\u00f3n": { + "account_number": "424568", + "account_type": "Income Account" + }, + "Minas y Canteras": { + "account_number": "424572", + "account_type": "Income Account" + }, + "Pozos artesianos": { + "account_number": "424580", + "account_type": "Income Account" + }, + "Yacimientos": { + "account_number": "424584", + "account_type": "Income Account" + }, + "Semovientes": { + "account_number": "424588", + "account_type": "Income Account" + }, + "Ajustes por inflaci\u00f3n": { + "account_number": "424599", + "account_type": "Income Account" + } + }, + "Utilidad en venta de otros bienes": { + "account_number": "4248", + "account_type": "Income Account", + "Intangibles": { + "account_number": "424805", + "account_type": "Income Account" + }, + "Otros activos": { + "account_number": "424810", + "account_type": "Income Account" + }, + "Ajustes por inflaci\u00f3n": { + "account_number": "424899", + "account_type": "Income Account" + } + }, + "Recuperaciones": { + "account_number": "4250", + "account_type": "Income Account", + "Deudas malas": { + "account_number": "425005", + "account_type": "Income Account" + }, + "Seguros": { + "account_number": "425010", + "account_type": "Income Account" + }, + "Reclamos": { + "account_number": "425015", + "account_type": "Income Account" + }, + "Reintegro por personal en comisi\u00f3n": { + "account_number": "425020", + "account_type": "Income Account" + }, + "Reintegro garant\u00edas": { + "account_number": "425025", + "account_type": "Income Account" + }, + "Descuentos concedidos": { + "account_number": "425030", + "account_type": "Income Account" + }, + "De provisiones": { + "account_number": "425035", + "account_type": "Income Account" + }, + "Gastos bancarios": { + "account_number": "425040", + "account_type": "Income Account" + }, + "De depreciaci\u00f3n": { + "account_number": "425045", + "account_type": "Income Account" + }, + "Reintegro de otros costos y gastos": { + "account_number": "425050", + "account_type": "Income Account" + }, + "Ajustes por inflaci\u00f3n": { + "account_number": "425099", + "account_type": "Income Account" + } + }, + "Indemnizaciones": { + "account_number": "4255", + "account_type": "Income Account", + "Por siniestro": { + "account_number": "425505", + "account_type": "Income Account" + }, + "Por suministros": { + "account_number": "425510", + "account_type": "Income Account" + }, + "Lucro cesante compa\u00f1\u00edas de seguros": { + "account_number": "425515", + "account_type": "Income Account" + }, + "Da\u00f1o emergente compa\u00f1\u00edas de seguros": { + "account_number": "425520", + "account_type": "Income Account" + }, + "Por p\u00e9rdida de mercanc\u00eda": { + "account_number": "425525", + "account_type": "Income Account" + }, + "Por incumplimiento de contratos": { + "account_number": "425530", + "account_type": "Income Account" + }, + "De terceros": { + "account_number": "425535", + "account_type": "Income Account" + }, + "Por incapacidades ISS": { + "account_number": "425540", + "account_type": "Income Account" + }, + "Otras": { + "account_number": "425595", + "account_type": "Income Account" + }, + "Ajustes por inflaci\u00f3n": { + "account_number": "425599", + "account_type": "Income Account" + } + }, + "Participaciones en concesiones": { + "account_number": "4260", + "account_type": "Income Account", + "Ajustes por inflaci\u00f3n": { + "account_number": "426099", + "account_type": "Income Account" + } + }, + "Ingresos de ejercicios anteriores": { + "account_number": "4265", + "account_type": "Income Account", + "Ajustes por inflaci\u00f3n": { + "account_number": "426599", + "account_type": "Income Account" + } + }, + "Devoluciones en otras ventas (DB)": { + "account_number": "4275", + "account_type": "Income Account", + "Ajustes por inflaci\u00f3n": { + "account_number": "427599", + "account_type": "Income Account" + } + }, + "Diversos": { + "account_number": "4295", + "account_type": "Income Account", + "CERT": { + "account_number": "429503", + "account_type": "Income Account" + }, + "Aprovechamientos": { + "account_number": "429505", + "account_type": "Income Account" + }, + "Auxilios": { + "account_number": "429507", + "account_type": "Income Account" + }, + "Subvenciones": { + "account_number": "429509", + "account_type": "Income Account" + }, + "Ingresos por investigaci\u00f3n y desarrollo": { + "account_number": "429511", + "account_type": "Income Account" + }, + "Por trabajos ejecutados": { + "account_number": "429513", + "account_type": "Income Account" + }, + "Regal\u00edas": { + "account_number": "429515", + "account_type": "Income Account" + }, + "Derivados de las exportaciones": { + "account_number": "429517", + "account_type": "Income Account" + }, + "Otros ingresos de explotaci\u00f3n": { + "account_number": "429519", + "account_type": "Income Account" + }, + "De la actividad ganadera": { + "account_number": "429521", + "account_type": "Income Account" + }, + "Derechos y licitaciones": { + "account_number": "429525", + "account_type": "Income Account" + }, + "Ingresos por elementos perdidos": { + "account_number": "429530", + "account_type": "Income Account" + }, + "Multas y recargos": { + "account_number": "429533", + "account_type": "Income Account" + }, + "Preavisos descontados": { + "account_number": "429535", + "account_type": "Income Account" + }, + "Reclamos": { + "account_number": "429537", + "account_type": "Income Account" + }, + "Recobro de da\u00f1os": { + "account_number": "429540", + "account_type": "Income Account" + }, + "Premios": { + "account_number": "429543", + "account_type": "Income Account" + }, + "Bonificaciones": { + "account_number": "429545", + "account_type": "Income Account" + }, + "Productos descontados": { + "account_number": "429547", + "account_type": "Income Account" + }, + "Reconocimientos ISS": { + "account_number": "429549", + "account_type": "Income Account" + }, + "Excedentes": { + "account_number": "429551", + "account_type": "Income Account" + }, + "Sobrantes de caja": { + "account_number": "429553", + "account_type": "Income Account" + }, + "Sobrantes en liquidaci\u00f3n fletes": { + "account_number": "429555", + "account_type": "Income Account" + }, + "Subsidios estatales": { + "account_number": "429557", + "account_type": "Income Account" + }, + "Capacitaci\u00f3n distribuidores": { + "account_number": "429559", + "account_type": "Income Account" + }, + "De escrituraci\u00f3n": { + "account_number": "429561", + "account_type": "Income Account" + }, + "Registro promesas de venta": { + "account_number": "429563", + "account_type": "Income Account" + }, + "\u00datiles, papeler\u00eda y fotocopias": { + "account_number": "429567", + "account_type": "Income Account" + }, + "Resultados, matr\u00edculas y traspasos": { + "account_number": "429571", + "account_type": "Income Account" + }, + "Decoraciones": { + "account_number": "429573", + "account_type": "Income Account" + }, + "Manejo de carga": { + "account_number": "429575", + "account_type": "Income Account" + }, + "Historia cl\u00ednica": { + "account_number": "429579", + "account_type": "Income Account" + }, + "Ajuste al peso": { + "account_number": "429581", + "account_type": "Income Account" + }, + "Llamadas telef\u00f3nicas": { + "account_number": "429583", + "account_type": "Income Account" + }, + "Otros": { + "account_number": "429595", + "account_type": "Income Account" + }, + "Ajustes por inflaci\u00f3n": { + "account_number": "429599", + "account_type": "Income Account" + } + } + }, + "Ajustes por inflaci\u00f3n": { + "account_number": "47", + "account_type": "Income Account", + "Correcci\u00f3n monetaria": { + "account_number": "4705", + "account_type": "Income Account", + "Inversiones (CR)": { + "account_number": "470505", + "account_type": "Income Account" + }, + "Inventarios (CR)": { + "account_number": "470510", + "account_type": "Income Account" + }, + "Propiedades, planta y equipo (CR)": { + "account_number": "470515", + "account_type": "Income Account" + }, + "Intangibles (CR)": { + "account_number": "470520", + "account_type": "Income Account" + }, + "Activos diferidos": { + "account_number": "470525", + "account_type": "Income Account" + }, + "Otros activos (CR)": { + "account_number": "470530", + "account_type": "Income Account" + }, + "Pasivos sujetos de ajuste": { + "account_number": "470535", + "account_type": "Income Account" + }, + "Patrimonio": { + "account_number": "470540", + "account_type": "Income Account" + }, + "Depreciaci\u00f3n acumulada (DB)": { + "account_number": "470545", + "account_type": "Income Account" + }, + "Depreciaci\u00f3n diferida (CR)": { + "account_number": "470550", + "account_type": "Income Account" + }, + "Agotamiento acumulado (DB)": { + "account_number": "470555", + "account_type": "Income Account" + }, + "Amortizaci\u00f3n acumulada (DB)": { + "account_number": "470560", + "account_type": "Income Account" + }, + "Ingresos operacionales (DB)": { + "account_number": "470565", + "account_type": "Income Account" + }, + "Devoluciones en ventas (CR)": { + "account_number": "470568", + "account_type": "Income Account" + }, + "Ingresos no operacionales (DB)": { + "account_number": "470570", + "account_type": "Income Account" + }, + "Gastos operacionales de administraci\u00f3n (CR)": { + "account_number": "470575", + "account_type": "Income Account" + }, + "Gastos operacionales de ventas (CR)": { + "account_number": "470580", + "account_type": "Income Account" + }, + "Gastos no operacionales (CR)": { + "account_number": "470585", + "account_type": "Income Account" + }, + "Compras (CR)": { + "account_number": "470590", + "account_type": "Income Account" + }, + "Devoluciones en compras (DB)": { + "account_number": "470591", + "account_type": "Income Account" + }, + "Costo de ventas (CR)": { + "account_number": "470592", + "account_type": "Income Account" + }, + "Costos de producci\u00f3n o de operaci\u00f3n (CR)": { + "account_number": "470594", + "account_type": "Income Account" + } + } + } + }, + "Gastos": { + "account_number": "5", + "account_type": "Expense Account", + "root_type": "Expense", + "Operacionales de administraci\u00f3n": { + "account_number": "51", + "account_type": "Expense Account", + "Gastos de personal": { + "account_number": "5105", + "account_type": "Expense Account", + "Salario integral": { + "account_number": "510503", + "account_type": "Expense Account" + }, + "Sueldos": { + "account_number": "510506", + "account_type": "Expense Account" + }, + "Jornales": { + "account_number": "510512", + "account_type": "Expense Account" + }, + "Horas extras y recargos": { + "account_number": "510515", + "account_type": "Expense Account" + }, + "Comisiones": { + "account_number": "510518", + "account_type": "Expense Account" + }, + "Vi\u00e1ticos": { + "account_number": "510521", + "account_type": "Expense Account" + }, + "Incapacidades": { + "account_number": "510524", + "account_type": "Expense Account" + }, + "Auxilio de transporte": { + "account_number": "510527", + "account_type": "Expense Account" + }, + "Cesant\u00edas": { + "account_number": "510530", + "account_type": "Expense Account" + }, + "Intereses sobre cesant\u00edas": { + "account_number": "510533", + "account_type": "Expense Account" + }, + "Prima de servicios": { + "account_number": "510536", + "account_type": "Expense Account" + }, + "Vacaciones": { + "account_number": "510539", + "account_type": "Expense Account" + }, + "Primas extralegales": { + "account_number": "510542", + "account_type": "Expense Account" + }, + "Auxilios": { + "account_number": "510545", + "account_type": "Expense Account" + }, + "Bonificaciones": { + "account_number": "510548", + "account_type": "Expense Account" + }, + "Dotaci\u00f3n y suministro a trabajadores": { + "account_number": "510551", + "account_type": "Expense Account" + }, + "Seguros": { + "account_number": "510554", + "account_type": "Expense Account" + }, + "Cuotas partes pensiones de jubilaci\u00f3n": { + "account_number": "510557", + "account_type": "Expense Account" + }, + "Amortizaci\u00f3n c\u00e1lculo actuarial pensiones de jubilaci\u00f3n": { + "account_number": "510558", + "account_type": "Expense Account" + }, + "Pensiones de jubilaci\u00f3n": { + "account_number": "510559", + "account_type": "Expense Account" + }, + "Indemnizaciones laborales": { + "account_number": "510560", + "account_type": "Expense Account" + }, + "Amortizaci\u00f3n bonos pensionales": { + "account_number": "510561", + "account_type": "Expense Account" + }, + "Amortizaci\u00f3n t\u00edtulos pensionales": { + "account_number": "510562", + "account_type": "Expense Account" + }, + "Capacitaci\u00f3n al personal": { + "account_number": "510563", + "account_type": "Expense Account" + }, + "Gastos deportivos y de recreaci\u00f3n": { + "account_number": "510566", + "account_type": "Expense Account" + }, + "Aportes a administradoras de riesgos profesionales, ARP": { + "account_number": "510568", + "account_type": "Expense Account" + }, + "Aportes a entidades promotoras de salud, EPS": { + "account_number": "510569", + "account_type": "Expense Account" + }, + "Aportes a fondos de pensiones y/o cesant\u00edas": { + "account_number": "510570", + "account_type": "Expense Account" + }, + "Aportes cajas de compensaci\u00f3n familiar": { + "account_number": "510572", + "account_type": "Expense Account" + }, + "Aportes ICBF": { + "account_number": "510575", + "account_type": "Expense Account" + }, + "SENA": { + "account_number": "510578", + "account_type": "Expense Account" + }, + "Aportes sindicales": { + "account_number": "510581", + "account_type": "Expense Account" + }, + "Gastos m\u00e9dicos y drogas": { + "account_number": "510584", + "account_type": "Expense Account" + }, + "Otros": { + "account_number": "510595", + "account_type": "Expense Account" + }, + "Ajustes por inflaci\u00f3n": { + "account_number": "510599", + "account_type": "Expense Account" + } + }, + "Honorarios": { + "account_number": "5110", + "account_type": "Expense Account", + "Junta directiva": { + "account_number": "511005", + "account_type": "Expense Account" + }, + "Revisor\u00eda fiscal": { + "account_number": "511010", + "account_type": "Expense Account" + }, + "Auditor\u00eda externa": { + "account_number": "511015", + "account_type": "Expense Account" + }, + "Aval\u00faos": { + "account_number": "511020", + "account_type": "Expense Account" + }, + "Asesor\u00eda jur\u00eddica": { + "account_number": "511025", + "account_type": "Expense Account" + }, + "Asesor\u00eda financiera": { + "account_number": "511030", + "account_type": "Expense Account" + }, + "Asesor\u00eda t\u00e9cnica": { + "account_number": "511035", + "account_type": "Expense Account" + }, + "Otros": { + "account_number": "511095", + "account_type": "Expense Account" + }, + "Ajustes por inflaci\u00f3n": { + "account_number": "511099", + "account_type": "Expense Account" + } + }, + "Impuestos": { + "account_number": "5115", + "account_type": "Expense Account", + "Industria y comercio": { + "account_number": "511505", + "account_type": "Expense Account" + }, + "De timbres": { + "account_number": "511510", + "account_type": "Expense Account" + }, + "A la propiedad ra\u00edz": { + "account_number": "511515", + "account_type": "Expense Account" + }, + "Derechos sobre instrumentos p\u00fablicos": { + "account_number": "511520", + "account_type": "Expense Account" + }, + "De valorizaci\u00f3n": { + "account_number": "511525", + "account_type": "Expense Account" + }, + "De turismo": { + "account_number": "511530", + "account_type": "Expense Account" + }, + "Tasa por utilizaci\u00f3n de puertos": { + "account_number": "511535", + "account_type": "Expense Account" + }, + "De veh\u00edculos": { + "account_number": "511540", + "account_type": "Expense Account" + }, + "De espect\u00e1culos p\u00fablicos": { + "account_number": "511545", + "account_type": "Expense Account" + }, + "Cuotas de fomento": { + "account_number": "511550", + "account_type": "Expense Account" + }, + "IVA descontable": { + "account_number": "511570", + "account_type": "Expense Account" + }, + "Otros": { + "account_number": "511595", + "account_type": "Expense Account" + }, + "Ajustes por inflaci\u00f3n": { + "account_number": "511599", + "account_type": "Expense Account" + } + }, + "Arrendamientos": { + "account_number": "5120", + "account_type": "Expense Account", + "Terrenos": { + "account_number": "512005", + "account_type": "Expense Account" + }, + "Construcciones y edificaciones": { + "account_number": "512010", + "account_type": "Expense Account" + }, + "Maquinaria y equipo": { + "account_number": "512015", + "account_type": "Expense Account" + }, + "Equipo de oficina": { + "account_number": "512020", + "account_type": "Expense Account" + }, + "Equipo de computaci\u00f3n y comunicaci\u00f3n": { + "account_number": "512025", + "account_type": "Expense Account" + }, + "Equipo m\u00e9dico-cient\u00edfico": { + "account_number": "512030", + "account_type": "Expense Account" + }, + "Equipo de hoteles y restaurantes": { + "account_number": "512035", + "account_type": "Expense Account" + }, + "Flota y equipo de transporte": { + "account_number": "512040", + "account_type": "Expense Account" + }, + "Flota y equipo fluvial y/o mar\u00edtimo": { + "account_number": "512045", + "account_type": "Expense Account" + }, + "Flota y equipo a\u00e9reo": { + "account_number": "512050", + "account_type": "Expense Account" + }, + "Flota y equipo f\u00e9rreo": { + "account_number": "512055", + "account_type": "Expense Account" + }, + "Acueductos, plantas y redes": { + "account_number": "512060", + "account_type": "Expense Account" + }, + "Aer\u00f3dromos": { + "account_number": "512065", + "account_type": "Expense Account" + }, + "Semovientes": { + "account_number": "512070", + "account_type": "Expense Account" + }, + "Otros": { + "account_number": "512095", + "account_type": "Expense Account" + }, + "Ajustes por inflaci\u00f3n": { + "account_number": "512099", + "account_type": "Expense Account" + } + }, + "Contribuciones y afiliaciones": { + "account_number": "5125", + "account_type": "Expense Account", + "Contribuciones": { + "account_number": "512505", + "account_type": "Expense Account" + }, + "Afiliaciones y sostenimiento": { + "account_number": "512510", + "account_type": "Expense Account" + }, + "Ajustes por inflaci\u00f3n": { + "account_number": "512599", + "account_type": "Expense Account" + } + }, + "Seguros": { + "account_number": "5130", + "account_type": "Expense Account", + "Manejo": { + "account_number": "513005", + "account_type": "Expense Account" + }, + "Cumplimiento": { + "account_number": "513010", + "account_type": "Expense Account" + }, + "Corriente d\u00e9bil": { + "account_number": "513015", + "account_type": "Expense Account" + }, + "Vida colectiva": { + "account_number": "513020", + "account_type": "Expense Account" + }, + "Incendio": { + "account_number": "513025", + "account_type": "Expense Account" + }, + "Terremoto": { + "account_number": "513030", + "account_type": "Expense Account" + }, + "Sustracci\u00f3n y hurto": { + "account_number": "513035", + "account_type": "Expense Account" + }, + "Flota y equipo de transporte": { + "account_number": "513040", + "account_type": "Expense Account" + }, + "Flota y equipo fluvial y/o mar\u00edtimo": { + "account_number": "513045", + "account_type": "Expense Account" + }, + "Flota y equipo a\u00e9reo": { + "account_number": "513050", + "account_type": "Expense Account" + }, + "Flota y equipo f\u00e9rreo": { + "account_number": "513055", + "account_type": "Expense Account" + }, + "Responsabilidad civil y extracontractual": { + "account_number": "513060", + "account_type": "Expense Account" + }, + "Vuelo": { + "account_number": "513065", + "account_type": "Expense Account" + }, + "Rotura de maquinaria": { + "account_number": "513070", + "account_type": "Expense Account" + }, + "Obligatorio accidente de tr\u00e1nsito": { + "account_number": "513075", + "account_type": "Expense Account" + }, + "Lucro cesante": { + "account_number": "513080", + "account_type": "Expense Account" + }, + "Transporte de mercanc\u00eda": { + "account_number": "513085", + "account_type": "Expense Account" + }, + "Otros": { + "account_number": "513095", + "account_type": "Expense Account" + }, + "Ajustes por inflaci\u00f3n": { + "account_number": "513099", + "account_type": "Expense Account" + } + }, + "Servicios": { + "account_number": "5135", + "account_type": "Expense Account", + "Aseo y vigilancia": { + "account_number": "513505", + "account_type": "Expense Account" + }, + "Temporales": { + "account_number": "513510", + "account_type": "Expense Account" + }, + "Asistencia t\u00e9cnica": { + "account_number": "513515", + "account_type": "Expense Account" + }, + "Procesamiento electr\u00f3nico de datos": { + "account_number": "513520", + "account_type": "Expense Account" + }, + "Acueducto y alcantarillado": { + "account_number": "513525", + "account_type": "Expense Account" + }, + "Energ\u00eda el\u00e9ctrica": { + "account_number": "513530", + "account_type": "Expense Account" + }, + "Tel\u00e9fono": { + "account_number": "513535", + "account_type": "Expense Account" + }, + "Correo, portes y telegramas": { + "account_number": "513540", + "account_type": "Expense Account" + }, + "Fax y t\u00e9lex": { + "account_number": "513545", + "account_type": "Expense Account" + }, + "Transporte, fletes y acarreos": { + "account_number": "513550", + "account_type": "Expense Account" + }, + "Gas": { + "account_number": "513555", + "account_type": "Expense Account" + }, + "Otros": { + "account_number": "513595", + "account_type": "Expense Account" + }, + "Ajustes por inflaci\u00f3n": { + "account_number": "513599", + "account_type": "Expense Account" + } + }, + "Gastos legales": { + "account_number": "5140", + "account_type": "Expense Account", + "Notariales": { + "account_number": "514005", + "account_type": "Expense Account" + }, + "Registro mercantil": { + "account_number": "514010", + "account_type": "Expense Account" + }, + "Tr\u00e1mites y licencias": { + "account_number": "514015", + "account_type": "Expense Account" + }, + "Aduaneros": { + "account_number": "514020", + "account_type": "Expense Account" + }, + "Consulares": { + "account_number": "514025", + "account_type": "Expense Account" + }, + "Otros": { + "account_number": "514095", + "account_type": "Expense Account" + }, + "Ajustes por inflaci\u00f3n": { + "account_number": "514099", + "account_type": "Expense Account" + } + }, + "Mantenimiento y reparaciones": { + "account_number": "5145", + "account_type": "Expense Account", + "Terrenos": { + "account_number": "514505", + "account_type": "Expense Account" + }, + "Construcciones y edificaciones": { + "account_number": "514510", + "account_type": "Expense Account" + }, + "Maquinaria y equipo": { + "account_number": "514515", + "account_type": "Expense Account" + }, + "Equipo de oficina": { + "account_number": "514520", + "account_type": "Expense Account" + }, + "Equipo de computaci\u00f3n y comunicaci\u00f3n": { + "account_number": "514525", + "account_type": "Expense Account" + }, + "Equipo m\u00e9dico-cient\u00edfico": { + "account_number": "514530", + "account_type": "Expense Account" + }, + "Equipo de hoteles y restaurantes": { + "account_number": "514535", + "account_type": "Expense Account" + }, + "Flota y equipo de transporte": { + "account_number": "514540", + "account_type": "Expense Account" + }, + "Flota y equipo fluvial y/o mar\u00edtimo": { + "account_number": "514545", + "account_type": "Expense Account" + }, + "Flota y equipo a\u00e9reo": { + "account_number": "514550", + "account_type": "Expense Account" + }, + "Flota y equipo f\u00e9rreo": { + "account_number": "514555", + "account_type": "Expense Account" + }, + "Acueductos, plantas y redes": { + "account_number": "514560", + "account_type": "Expense Account" + }, + "Armamento de vigilancia": { + "account_number": "514565", + "account_type": "Expense Account" + }, + "V\u00edas de comunicaci\u00f3n": { + "account_number": "514570", + "account_type": "Expense Account" + }, + "Ajustes por inflaci\u00f3n": { + "account_number": "514599", + "account_type": "Expense Account" + } + }, + "Adecuaci\u00f3n e instalaci\u00f3n": { + "account_number": "5150", + "account_type": "Expense Account", + "Instalaciones el\u00e9ctricas": { + "account_number": "515005", + "account_type": "Expense Account" + }, + "Arreglos ornamentales": { + "account_number": "515010", + "account_type": "Expense Account" + }, + "Reparaciones locativas": { + "account_number": "515015", + "account_type": "Expense Account" + }, + "Otros": { + "account_number": "515095", + "account_type": "Expense Account" + }, + "Ajustes por inflaci\u00f3n": { + "account_number": "515099", + "account_type": "Expense Account" + } + }, + "Gastos de viaje": { + "account_number": "5155", + "account_type": "Expense Account", + "Alojamiento y manutenci\u00f3n": { + "account_number": "515505", + "account_type": "Expense Account" + }, + "Pasajes fluviales y/o mar\u00edtimos": { + "account_number": "515510", + "account_type": "Expense Account" + }, + "Pasajes a\u00e9reos": { + "account_number": "515515", + "account_type": "Expense Account" + }, + "Pasajes terrestres": { + "account_number": "515520", + "account_type": "Expense Account" + }, + "Pasajes f\u00e9rreos": { + "account_number": "515525", + "account_type": "Expense Account" + }, + "Otros": { + "account_number": "515595", + "account_type": "Expense Account" + }, + "Ajustes por inflaci\u00f3n": { + "account_number": "515599", + "account_type": "Expense Account" + } + }, + "Depreciaciones": { + "account_number": "5160", + "account_type": "Expense Account", + "Construcciones y edificaciones": { + "account_number": "516005", + "account_type": "Expense Account" + }, + "Maquinaria y equipo": { + "account_number": "516010", + "account_type": "Expense Account" + }, + "Equipo de oficina": { + "account_number": "516015", + "account_type": "Expense Account" + }, + "Equipo de computaci\u00f3n y comunicaci\u00f3n": { + "account_number": "516020", + "account_type": "Expense Account" + }, + "Equipo m\u00e9dico-cient\u00edfico": { + "account_number": "516025", + "account_type": "Expense Account" + }, + "Equipo de hoteles y restaurantes": { + "account_number": "516030", + "account_type": "Expense Account" + }, + "Flota y equipo de transporte": { + "account_number": "516035", + "account_type": "Expense Account" + }, + "Flota y equipo fluvial y/o mar\u00edtimo": { + "account_number": "516040", + "account_type": "Expense Account" + }, + "Flota y equipo a\u00e9reo": { + "account_number": "516045", + "account_type": "Expense Account" + }, + "Flota y equipo f\u00e9rreo": { + "account_number": "516050", + "account_type": "Expense Account" + }, + "Acueductos, plantas y redes": { + "account_number": "516055", + "account_type": "Expense Account" + }, + "Armamento de vigilancia": { + "account_number": "516060", + "account_type": "Expense Account" + }, + "Ajustes por inflaci\u00f3n": { + "account_number": "516099", + "account_type": "Expense Account" + } + }, + "Amortizaciones": { + "account_number": "5165", + "account_type": "Expense Account", + "V\u00edas de comunicaci\u00f3n": { + "account_number": "516505", + "account_type": "Expense Account" + }, + "Intangibles": { + "account_number": "516510", + "account_type": "Expense Account" + }, + "Cargos diferidos": { + "account_number": "516515", + "account_type": "Expense Account" + }, + "Otras": { + "account_number": "516595", + "account_type": "Expense Account" + }, + "Ajustes por inflaci\u00f3n": { + "account_number": "516599", + "account_type": "Expense Account" + } + }, + "Diversos": { + "account_number": "5195", + "account_type": "Expense Account", + "Comisiones": { + "account_number": "519505", + "account_type": "Expense Account" + }, + "Libros, suscripciones, peri\u00f3dicos y revistas": { + "account_number": "519510", + "account_type": "Expense Account" + }, + "M\u00fasica ambiental": { + "account_number": "519515", + "account_type": "Expense Account" + }, + "Gastos de representaci\u00f3n y relaciones p\u00fablicas": { + "account_number": "519520", + "account_type": "Expense Account" + }, + "Elementos de aseo y cafeter\u00eda": { + "account_number": "519525", + "account_type": "Expense Account" + }, + "\u00datiles, papeler\u00eda y fotocopias": { + "account_number": "519530", + "account_type": "Expense Account" + }, + "Combustibles y lubricantes": { + "account_number": "519535", + "account_type": "Expense Account" + }, + "Envases y empaques": { + "account_number": "519540", + "account_type": "Expense Account" + }, + "Taxis y buses": { + "account_number": "519545", + "account_type": "Expense Account" + }, + "Estampillas": { + "account_number": "519550", + "account_type": "Expense Account" + }, + "Microfilmaci\u00f3n": { + "account_number": "519555", + "account_type": "Expense Account" + }, + "Casino y restaurante": { + "account_number": "519560", + "account_type": "Expense Account" + }, + "Parqueaderos": { + "account_number": "519565", + "account_type": "Expense Account" + }, + "Indemnizaci\u00f3n por da\u00f1os a terceros": { + "account_number": "519570", + "account_type": "Expense Account" + }, + "P\u00f3lvora y similares": { + "account_number": "519575", + "account_type": "Expense Account" + }, + "Otros": { + "account_number": "519595", + "account_type": "Expense Account" + }, + "Ajustes por inflaci\u00f3n": { + "account_number": "519599", + "account_type": "Expense Account" + } + }, + "Provisiones": { + "account_number": "5199", + "account_type": "Expense Account", + "Inversiones": { + "account_number": "519905", + "account_type": "Expense Account" + }, + "Deudores": { + "account_number": "519910", + "account_type": "Expense Account" + }, + "Propiedades, planta y equipo": { + "account_number": "519915", + "account_type": "Expense Account" + }, + "Otros activos": { + "account_number": "519995", + "account_type": "Expense Account" + }, + "Ajustes por inflaci\u00f3n": { + "account_number": "519999", + "account_type": "Expense Account" + } + } + }, + "Operacionales de ventas": { + "account_number": "52", + "account_type": "Expense Account", + "Gastos de personal": { + "account_number": "5205", + "account_type": "Expense Account", + "Salario integral": { + "account_number": "520503", + "account_type": "Expense Account" + }, + "Sueldos": { + "account_number": "520506", + "account_type": "Expense Account" + }, + "Jornales": { + "account_number": "520512", + "account_type": "Expense Account" + }, + "Horas extras y recargos": { + "account_number": "520515", + "account_type": "Expense Account" + }, + "Comisiones": { + "account_number": "520518", + "account_type": "Expense Account" + }, + "Vi\u00e1ticos": { + "account_number": "520521", + "account_type": "Expense Account" + }, + "Incapacidades": { + "account_number": "520524", + "account_type": "Expense Account" + }, + "Auxilio de transporte": { + "account_number": "520527", + "account_type": "Expense Account" + }, + "Cesant\u00edas": { + "account_number": "520530", + "account_type": "Expense Account" + }, + "Intereses sobre cesant\u00edas": { + "account_number": "520533", + "account_type": "Expense Account" + }, + "Prima de servicios": { + "account_number": "520536", + "account_type": "Expense Account" + }, + "Vacaciones": { + "account_number": "520539", + "account_type": "Expense Account" + }, + "Primas extralegales": { + "account_number": "520542", + "account_type": "Expense Account" + }, + "Auxilios": { + "account_number": "520545", + "account_type": "Expense Account" + }, + "Bonificaciones": { + "account_number": "520548", + "account_type": "Expense Account" + }, + "Dotaci\u00f3n y suministro a trabajadores": { + "account_number": "520551", + "account_type": "Expense Account" + }, + "Seguros": { + "account_number": "520554", + "account_type": "Expense Account" + }, + "Cuotas partes pensiones de jubilaci\u00f3n": { + "account_number": "520557", + "account_type": "Expense Account" + }, + "Amortizaci\u00f3n c\u00e1lculo actuarial pensiones de jubilaci\u00f3n": { + "account_number": "520558", + "account_type": "Expense Account" + }, + "Pensiones de jubilaci\u00f3n": { + "account_number": "520559", + "account_type": "Expense Account" + }, + "Indemnizaciones laborales": { + "account_number": "520560", + "account_type": "Expense Account" + }, + "Amortizaci\u00f3n bonos pensionales": { + "account_number": "520561", + "account_type": "Expense Account" + }, + "Amortizaci\u00f3n t\u00edtulos pensionales": { + "account_number": "520562", + "account_type": "Expense Account" + }, + "Capacitaci\u00f3n al personal": { + "account_number": "520563", + "account_type": "Expense Account" + }, + "Gastos deportivos y de recreaci\u00f3n": { + "account_number": "520566", + "account_type": "Expense Account" + }, + "Aportes a administradoras de riesgos profesionales, ARP": { + "account_number": "520568", + "account_type": "Expense Account" + }, + "Aportes a entidades promotoras de salud, EPS": { + "account_number": "520569", + "account_type": "Expense Account" + }, + "Aportes a fondos de pensiones y/o cesant\u00edas": { + "account_number": "520570", + "account_type": "Expense Account" + }, + "Aportes cajas de compensaci\u00f3n familiar": { + "account_number": "520572", + "account_type": "Expense Account" + }, + "Aportes ICBF": { + "account_number": "520575", + "account_type": "Expense Account" + }, + "SENA": { + "account_number": "520578", + "account_type": "Expense Account" + }, + "Aportes sindicales": { + "account_number": "520581", + "account_type": "Expense Account" + }, + "Gastos m\u00e9dicos y drogas": { + "account_number": "520584", + "account_type": "Expense Account" + }, + "Otros": { + "account_number": "520595", + "account_type": "Expense Account" + }, + "Ajustes por inflaci\u00f3n": { + "account_number": "520599", + "account_type": "Expense Account" + } + }, + "Honorarios": { + "account_number": "5210", + "account_type": "Expense Account", + "Junta directiva": { + "account_number": "521005", + "account_type": "Expense Account" + }, + "Revisor\u00eda fiscal": { + "account_number": "521010", + "account_type": "Expense Account" + }, + "Auditor\u00eda externa": { + "account_number": "521015", + "account_type": "Expense Account" + }, + "Aval\u00faos": { + "account_number": "521020", + "account_type": "Expense Account" + }, + "Asesor\u00eda jur\u00eddica": { + "account_number": "521025", + "account_type": "Expense Account" + }, + "Asesor\u00eda financiera": { + "account_number": "521030", + "account_type": "Expense Account" + }, + "Asesor\u00eda t\u00e9cnica": { + "account_number": "521035", + "account_type": "Expense Account" + }, + "Otros": { + "account_number": "521095", + "account_type": "Expense Account" + }, + "Ajustes por inflaci\u00f3n": { + "account_number": "521099", + "account_type": "Expense Account" + } + }, + "Impuestos": { + "account_number": "5215", + "account_type": "Expense Account", + "Industria y comercio": { + "account_number": "521505", + "account_type": "Expense Account" + }, + "De timbres": { + "account_number": "521510", + "account_type": "Expense Account" + }, + "A la propiedad ra\u00edz": { + "account_number": "521515", + "account_type": "Expense Account" + }, + "Derechos sobre instrumentos p\u00fablicos": { + "account_number": "521520", + "account_type": "Expense Account" + }, + "De valorizaci\u00f3n": { + "account_number": "521525", + "account_type": "Expense Account" + }, + "De turismo": { + "account_number": "521530", + "account_type": "Expense Account" + }, + "Tasa por utilizaci\u00f3n de puertos": { + "account_number": "521535", + "account_type": "Expense Account" + }, + "De veh\u00edculos": { + "account_number": "521540", + "account_type": "Expense Account" + }, + "De espect\u00e1culos p\u00fablicos": { + "account_number": "521545", + "account_type": "Expense Account" + }, + "Cuotas de fomento": { + "account_number": "521550", + "account_type": "Expense Account" + }, + "Licores": { + "account_number": "521555", + "account_type": "Expense Account" + }, + "Cervezas": { + "account_number": "521560", + "account_type": "Expense Account" + }, + "Cigarrillos": { + "account_number": "521565", + "account_type": "Expense Account" + }, + "IVA descontable": { + "account_number": "521570", + "account_type": "Expense Account" + }, + "Otros": { + "account_number": "521595", + "account_type": "Expense Account" + }, + "Ajustes por inflaci\u00f3n": { + "account_number": "521599", + "account_type": "Expense Account" + } + }, + "Arrendamientos": { + "account_number": "5220", + "account_type": "Expense Account", + "Terrenos": { + "account_number": "522005", + "account_type": "Expense Account" + }, + "Construcciones y edificaciones": { + "account_number": "522010", + "account_type": "Expense Account" + }, + "Maquinaria y equipo": { + "account_number": "522015", + "account_type": "Expense Account" + }, + "Equipo de oficina": { + "account_number": "522020", + "account_type": "Expense Account" + }, + "Equipo de computaci\u00f3n y comunicaci\u00f3n": { + "account_number": "522025", + "account_type": "Expense Account" + }, + "Equipo m\u00e9dico-cient\u00edfico": { + "account_number": "522030", + "account_type": "Expense Account" + }, + "Equipo de hoteles y restaurantes": { + "account_number": "522035", + "account_type": "Expense Account" + }, + "Flota y equipo de transporte": { + "account_number": "522040", + "account_type": "Expense Account" + }, + "Flota y equipo fluvial y/o mar\u00edtimo": { + "account_number": "522045", + "account_type": "Expense Account" + }, + "Flota y equipo a\u00e9reo": { + "account_number": "522050", + "account_type": "Expense Account" + }, + "Flota y equipo f\u00e9rreo": { + "account_number": "522055", + "account_type": "Expense Account" + }, + "Acueductos, plantas y redes": { + "account_number": "522060", + "account_type": "Expense Account" + }, + "Aer\u00f3dromos": { + "account_number": "522065", + "account_type": "Expense Account" + }, + "Semovientes": { + "account_number": "522070", + "account_type": "Expense Account" + }, + "Otros": { + "account_number": "522095", + "account_type": "Expense Account" + }, + "Ajustes por inflaci\u00f3n": { + "account_number": "522099", + "account_type": "Expense Account" + } + }, + "Contribuciones y afiliaciones": { + "account_number": "5225", + "account_type": "Expense Account", + "Contribuciones": { + "account_number": "522505", + "account_type": "Expense Account" + }, + "Afiliaciones y sostenimiento": { + "account_number": "522510", + "account_type": "Expense Account" + }, + "Ajustes por inflaci\u00f3n": { + "account_number": "522599", + "account_type": "Expense Account" + } + }, + "Seguros": { + "account_number": "5230", + "account_type": "Expense Account", + "Manejo": { + "account_number": "523005", + "account_type": "Expense Account" + }, + "Cumplimiento": { + "account_number": "523010", + "account_type": "Expense Account" + }, + "Corriente d\u00e9bil": { + "account_number": "523015", + "account_type": "Expense Account" + }, + "Vida colectiva": { + "account_number": "523020", + "account_type": "Expense Account" + }, + "Incendio": { + "account_number": "523025", + "account_type": "Expense Account" + }, + "Terremoto": { + "account_number": "523030", + "account_type": "Expense Account" + }, + "Sustracci\u00f3n y hurto": { + "account_number": "523035", + "account_type": "Expense Account" + }, + "Flota y equipo de transporte": { + "account_number": "523040", + "account_type": "Expense Account" + }, + "Flota y equipo fluvial y/o mar\u00edtimo": { + "account_number": "523045", + "account_type": "Expense Account" + }, + "Flota y equipo a\u00e9reo": { + "account_number": "523050", + "account_type": "Expense Account" + }, + "Flota y equipo f\u00e9rreo": { + "account_number": "523055", + "account_type": "Expense Account" + }, + "Responsabilidad civil y extracontractual": { + "account_number": "523060", + "account_type": "Expense Account" + }, + "Vuelo": { + "account_number": "523065", + "account_type": "Expense Account" + }, + "Rotura de maquinaria": { + "account_number": "523070", + "account_type": "Expense Account" + }, + "Obligatorio accidente de tr\u00e1nsito": { + "account_number": "523075", + "account_type": "Expense Account" + }, + "Lucro cesante": { + "account_number": "523080", + "account_type": "Expense Account" + }, + "Otros": { + "account_number": "523095", + "account_type": "Expense Account" + }, + "Ajustes por inflaci\u00f3n": { + "account_number": "523099", + "account_type": "Expense Account" + } + }, + "Servicios": { + "account_number": "5235", + "account_type": "Expense Account", + "Aseo y vigilancia": { + "account_number": "523505", + "account_type": "Expense Account" + }, + "Temporales": { + "account_number": "523510", + "account_type": "Expense Account" + }, + "Asistencia t\u00e9cnica": { + "account_number": "523515", + "account_type": "Expense Account" + }, + "Procesamiento electr\u00f3nico de datos": { + "account_number": "523520", + "account_type": "Expense Account" + }, + "Acueducto y alcantarillado": { + "account_number": "523525", + "account_type": "Expense Account" + }, + "Energ\u00eda el\u00e9ctrica": { + "account_number": "523530", + "account_type": "Expense Account" + }, + "Tel\u00e9fono": { + "account_number": "523535", + "account_type": "Expense Account" + }, + "Correo, portes y telegramas": { + "account_number": "523540", + "account_type": "Expense Account" + }, + "Fax y t\u00e9lex": { + "account_number": "523545", + "account_type": "Expense Account" + }, + "Transporte, fletes y acarreos": { + "account_number": "523550", + "account_type": "Expense Account" + }, + "Gas": { + "account_number": "523555", + "account_type": "Expense Account" + }, + "Publicidad, propaganda y promoci\u00f3n": { + "account_number": "523560", + "account_type": "Expense Account" + }, + "Otros": { + "account_number": "523595", + "account_type": "Expense Account" + }, + "Ajustes por inflaci\u00f3n": { + "account_number": "523599", + "account_type": "Expense Account" + } + }, + "Gastos legales": { + "account_number": "5240", + "account_type": "Expense Account", + "Notariales": { + "account_number": "524005", + "account_type": "Expense Account" + }, + "Registro mercantil": { + "account_number": "524010", + "account_type": "Expense Account" + }, + "Tr\u00e1mites y licencias": { + "account_number": "524015", + "account_type": "Expense Account" + }, + "Aduaneros": { + "account_number": "524020", + "account_type": "Expense Account" + }, + "Consulares": { + "account_number": "524025", + "account_type": "Expense Account" + }, + "Otros": { + "account_number": "524095", + "account_type": "Expense Account" + }, + "Ajustes por inflaci\u00f3n": { + "account_number": "524099", + "account_type": "Expense Account" + } + }, + "Mantenimiento y reparaciones": { + "account_number": "5245", + "account_type": "Expense Account", + "Terrenos": { + "account_number": "524505", + "account_type": "Expense Account" + }, + "Construcciones y edificaciones": { + "account_number": "524510", + "account_type": "Expense Account" + }, + "Maquinaria y equipo": { + "account_number": "524515", + "account_type": "Expense Account" + }, + "Equipo de oficina": { + "account_number": "524520", + "account_type": "Expense Account" + }, + "Equipo de computaci\u00f3n y comunicaci\u00f3n": { + "account_number": "524525", + "account_type": "Expense Account" + }, + "Equipo m\u00e9dico-cient\u00edfico": { + "account_number": "524530", + "account_type": "Expense Account" + }, + "Equipo de hoteles y restaurantes": { + "account_number": "524535", + "account_type": "Expense Account" + }, + "Flota y equipo de transporte": { + "account_number": "524540", + "account_type": "Expense Account" + }, + "Flota y equipo fluvial y/o mar\u00edtimo": { + "account_number": "524545", + "account_type": "Expense Account" + }, + "Flota y equipo a\u00e9reo": { + "account_number": "524550", + "account_type": "Expense Account" + }, + "Flota y equipo f\u00e9rreo": { + "account_number": "524555", + "account_type": "Expense Account" + }, + "Acueductos, plantas y redes": { + "account_number": "524560", + "account_type": "Expense Account" + }, + "Armamento de vigilancia": { + "account_number": "524565", + "account_type": "Expense Account" + }, + "V\u00edas de comunicaci\u00f3n": { + "account_number": "524570", + "account_type": "Expense Account" + }, + "Ajustes por inflaci\u00f3n": { + "account_number": "524599", + "account_type": "Expense Account" + } + }, + "Adecuaci\u00f3n e instalaci\u00f3n": { + "account_number": "5250", + "account_type": "Expense Account", + "Instalaciones el\u00e9ctricas": { + "account_number": "525005", + "account_type": "Expense Account" + }, + "Arreglos ornamentales": { + "account_number": "525010", + "account_type": "Expense Account" + }, + "Reparaciones locativas": { + "account_number": "525015", + "account_type": "Expense Account" + }, + "Otros": { + "account_number": "525095", + "account_type": "Expense Account" + }, + "Ajustes por inflaci\u00f3n": { + "account_number": "525099", + "account_type": "Expense Account" + } + }, + "Gastos de viaje": { + "account_number": "5255", + "account_type": "Expense Account", + "Alojamiento y manutenci\u00f3n": { + "account_number": "525505", + "account_type": "Expense Account" + }, + "Pasajes fluviales y/o mar\u00edtimos": { + "account_number": "525510", + "account_type": "Expense Account" + }, + "Pasajes a\u00e9reos": { + "account_number": "525515", + "account_type": "Expense Account" + }, + "Pasajes terrestres": { + "account_number": "525520", + "account_type": "Expense Account" + }, + "Pasajes f\u00e9rreos": { + "account_number": "525525", + "account_type": "Expense Account" + }, + "Otros": { + "account_number": "525595", + "account_type": "Expense Account" + }, + "Ajustes por inflaci\u00f3n": { + "account_number": "525599", + "account_type": "Expense Account" + } + }, + "Depreciaciones": { + "account_number": "5260", + "account_type": "Expense Account", + "Construcciones y edificaciones": { + "account_number": "526005", + "account_type": "Expense Account" + }, + "Maquinaria y equipo": { + "account_number": "526010", + "account_type": "Expense Account" + }, + "Equipo de oficina": { + "account_number": "526015", + "account_type": "Expense Account" + }, + "Equipo de computaci\u00f3n y comunicaci\u00f3n": { + "account_number": "526020", + "account_type": "Expense Account" + }, + "Equipo m\u00e9dico-cient\u00edfico": { + "account_number": "526025", + "account_type": "Expense Account" + }, + "Equipo de hoteles y restaurantes": { + "account_number": "526030", + "account_type": "Expense Account" + }, + "Flota y equipo de transporte": { + "account_number": "526035", + "account_type": "Expense Account" + }, + "Flota y equipo fluvial y/o mar\u00edtimo": { + "account_number": "526040", + "account_type": "Expense Account" + }, + "Flota y equipo a\u00e9reo": { + "account_number": "526045", + "account_type": "Expense Account" + }, + "Flota y equipo f\u00e9rreo": { + "account_number": "526050", + "account_type": "Expense Account" + }, + "Acueductos, plantas y redes": { + "account_number": "526055", + "account_type": "Expense Account" + }, + "Armamento de vigilancia": { + "account_number": "526060", + "account_type": "Expense Account" + }, + "Envases y empaques": { + "account_number": "526065", + "account_type": "Expense Account" + }, + "Ajustes por inflaci\u00f3n": { + "account_number": "526099", + "account_type": "Expense Account" + } + }, + "Amortizaciones": { + "account_number": "5265", + "account_type": "Expense Account", + "V\u00edas de comunicaci\u00f3n": { + "account_number": "526505", + "account_type": "Expense Account" + }, + "Intangibles": { + "account_number": "526510", + "account_type": "Expense Account" + }, + "Cargos diferidos": { + "account_number": "526515", + "account_type": "Expense Account" + }, + "Otras": { + "account_number": "526595", + "account_type": "Expense Account" + }, + "Ajustes por inflaci\u00f3n": { + "account_number": "526599", + "account_type": "Expense Account" + } + }, + "Financieros-reajuste del sistema": { + "account_number": "5270", + "account_type": "Expense Account", + "Ajustes por inflaci\u00f3n": { + "account_number": "527099", + "account_type": "Expense Account" + } + }, + "P\u00e9rdidas m\u00e9todo de participaci\u00f3n": { + "account_number": "5275", + "account_type": "Expense Account", + "De sociedades an\u00f3nimas y/o asimiladas": { + "account_number": "527505", + "account_type": "Expense Account" + }, + "De sociedades limitadas y/o asimiladas": { + "account_number": "527510", + "account_type": "Expense Account" + } + }, + "Diversos": { + "account_number": "5295", + "account_type": "Expense Account", + "Comisiones": { + "account_number": "529505", + "account_type": "Expense Account" + }, + "Libros, suscripciones, peri\u00f3dicos y revistas": { + "account_number": "529510", + "account_type": "Expense Account" + }, + "M\u00fasica ambiental": { + "account_number": "529515", + "account_type": "Expense Account" + }, + "Gastos de representaci\u00f3n y relaciones p\u00fablicas": { + "account_number": "529520", + "account_type": "Expense Account" + }, + "Elementos de aseo y cafeter\u00eda": { + "account_number": "529525", + "account_type": "Expense Account" + }, + "\u00datiles, papeler\u00eda y fotocopias": { + "account_number": "529530", + "account_type": "Expense Account" + }, + "Combustibles y lubricantes": { + "account_number": "529535", + "account_type": "Expense Account" + }, + "Envases y empaques": { + "account_number": "529540", + "account_type": "Expense Account" + }, + "Taxis y buses": { + "account_number": "529545", + "account_type": "Expense Account" + }, + "Estampillas": { + "account_number": "529550", + "account_type": "Expense Account" + }, + "Microfilmaci\u00f3n": { + "account_number": "529555", + "account_type": "Expense Account" + }, + "Casino y restaurante": { + "account_number": "529560", + "account_type": "Expense Account" + }, + "Parqueaderos": { + "account_number": "529565", + "account_type": "Expense Account" + }, + "Indemnizaci\u00f3n por da\u00f1os a terceros": { + "account_number": "529570", + "account_type": "Expense Account" + }, + "P\u00f3lvora y similares": { + "account_number": "529575", + "account_type": "Expense Account" + }, + "Otros": { + "account_number": "529595", + "account_type": "Expense Account" + }, + "Ajustes por inflaci\u00f3n": { + "account_number": "529599", + "account_type": "Expense Account" + } + }, + "Provisiones": { + "account_number": "5299", + "account_type": "Expense Account", + "Inversiones": { + "account_number": "529905", + "account_type": "Expense Account" + }, + "Deudores": { + "account_number": "529910", + "account_type": "Expense Account" + }, + "Inventarios": { + "account_number": "529915", + "account_type": "Expense Account" + }, + "Propiedades, planta y equipo": { + "account_number": "529920", + "account_type": "Expense Account" + }, + "Otros activos": { + "account_number": "529995", + "account_type": "Expense Account" + }, + "Ajustes por inflaci\u00f3n": { + "account_number": "529999", + "account_type": "Expense Account" + } + } + }, + "No operacionales": { + "account_number": "53", + "account_type": "Expense Account", + "Financieros": { + "account_number": "5305", + "account_type": "Expense Account", + "Gastos bancarios": { + "account_number": "530505", + "account_type": "Expense Account" + }, + "Reajuste monetario-UPAC (hoy UVR)": { + "account_number": "530510", + "account_type": "Expense Account" + }, + "Comisiones": { + "account_number": "530515", + "account_type": "Expense Account" + }, + "Intereses": { + "account_number": "530520", + "account_type": "Expense Account" + }, + "Diferencia en cambio": { + "account_number": "530525", + "account_type": "Expense Account" + }, + "Gastos en negociaci\u00f3n certificados de cambio": { + "account_number": "530530", + "account_type": "Expense Account" + }, + "Descuentos comerciales condicionados": { + "account_number": "530535", + "account_type": "Expense Account" + }, + "Gastos manejo y emisi\u00f3n de bonos": { + "account_number": "530540", + "account_type": "Expense Account" + }, + "Prima amortizada": { + "account_number": "530545", + "account_type": "Expense Account" + }, + "Otros": { + "account_number": "530595", + "account_type": "Expense Account" + }, + "Ajustes por inflaci\u00f3n": { + "account_number": "530599", + "account_type": "Expense Account" + } + }, + "P\u00e9rdida en venta y retiro de bienes": { + "account_number": "5310", + "account_type": "Expense Account", + "Venta de inversiones": { + "account_number": "531005", + "account_type": "Expense Account" + }, + "Venta de cartera": { + "account_number": "531010", + "account_type": "Expense Account" + }, + "Venta de propiedades, planta y equipo": { + "account_number": "531015", + "account_type": "Expense Account" + }, + "Venta de intangibles": { + "account_number": "531020", + "account_type": "Expense Account" + }, + "Venta de otros activos": { + "account_number": "531025", + "account_type": "Expense Account" + }, + "Retiro de propiedades, planta y equipo": { + "account_number": "531030", + "account_type": "Expense Account" + }, + "Retiro de otros activos": { + "account_number": "531035", + "account_type": "Expense Account" + }, + "P\u00e9rdidas por siniestros": { + "account_number": "531040", + "account_type": "Expense Account" + }, + "Otros": { + "account_number": "531095", + "account_type": "Expense Account" + }, + "Ajustes por inflaci\u00f3n": { + "account_number": "531099", + "account_type": "Expense Account" + } + }, + "P\u00e9rdidas m\u00e9todo de participaci\u00f3n": { + "account_number": "5313", + "account_type": "Expense Account", + "De sociedades an\u00f3nimas y/o asimiladas": { + "account_number": "531305", + "account_type": "Expense Account" + }, + "De sociedades limitadas y/o asimiladas": { + "account_number": "531310", + "account_type": "Expense Account" + } + }, + "Gastos extraordinarios": { + "account_number": "5315", + "account_type": "Expense Account", + "Costas y procesos judiciales": { + "account_number": "531505", + "account_type": "Expense Account" + }, + "Actividades culturales y c\u00edvicas": { + "account_number": "531510", + "account_type": "Expense Account" + }, + "Costos y gastos de ejercicios anteriores": { + "account_number": "531515", + "account_type": "Expense Account" + }, + "Impuestos asumidos": { + "account_number": "531520", + "account_type": "Expense Account" + }, + "Otros": { + "account_number": "531595", + "account_type": "Expense Account" + }, + "Ajustes por inflaci\u00f3n": { + "account_number": "531599", + "account_type": "Expense Account" + } + }, + "Gastos diversos": { + "account_number": "5395", + "account_type": "Expense Account", + "Demandas laborales": { + "account_number": "539505", + "account_type": "Expense Account" + }, + "Demandas por incumplimiento de contratos": { + "account_number": "539510", + "account_type": "Expense Account" + }, + "Indemnizaciones": { + "account_number": "539515", + "account_type": "Expense Account" + }, + "Multas, sanciones y litigios": { + "account_number": "539520", + "account_type": "Expense Account" + }, + "Donaciones": { + "account_number": "539525", + "account_type": "Expense Account" + }, + "Constituci\u00f3n de garant\u00edas": { + "account_number": "539530", + "account_type": "Expense Account" + }, + "Amortizaci\u00f3n de bienes entregados en comodato": { + "account_number": "539535", + "account_type": "Expense Account" + }, + "Otros": { + "account_number": "539595", + "account_type": "Expense Account" + }, + "Ajustes por inflaci\u00f3n": { + "account_number": "539599", + "account_type": "Expense Account" + } + } + }, + "Impuesto de renta y complementarios": { + "account_number": "54", + "account_type": "Expense Account", + "Impuesto de renta y complementarios": { + "account_number": "5405", + "account_type": "Expense Account", + "Impuesto de renta y complementarios": { + "account_number": "540505", + "account_type": "Expense Account" + } + } + }, + "Ganancias y p\u00e9rdidas": { + "account_number": "59", + "account_type": "Expense Account", + "Ganancias y p\u00e9rdidas": { + "account_number": "5905", + "account_type": "Expense Account", + "Ganancias y p\u00e9rdidas": { + "account_number": "590505", + "account_type": "Expense Account" + } + } + } + }, + "Costos de ventas": { + "account_number": "6", + "account_type": "Cost of Goods Sold", + "root_type": "Expense", + "Costo de ventas y de prestaci\u00f3n de servicios": { + "account_number": "61", + "account_type": "Cost of Goods Sold", + "Agricultura, ganader\u00eda, caza y silvicultura": { + "account_number": "6105", + "account_type": "Cost of Goods Sold", + "Cultivo de cereales": { + "account_number": "610505", + "account_type": "Cost of Goods Sold" + }, + "Cultivos de hortalizas, legumbres y plantas ornamentales": { + "account_number": "610510", + "account_type": "Cost of Goods Sold" + }, + "Cultivos de frutas, nueces y plantas arom\u00e1ticas": { + "account_number": "610515", + "account_type": "Cost of Goods Sold" + }, + "Cultivo de caf\u00e9": { + "account_number": "610520", + "account_type": "Cost of Goods Sold" + }, + "Cultivo de flores": { + "account_number": "610525", + "account_type": "Cost of Goods Sold" + }, + "Cultivo de ca\u00f1a de az\u00facar": { + "account_number": "610530", + "account_type": "Cost of Goods Sold" + }, + "Cultivo de algod\u00f3n y plantas para material textil": { + "account_number": "610535", + "account_type": "Cost of Goods Sold" + }, + "Cultivo de banano": { + "account_number": "610540", + "account_type": "Cost of Goods Sold" + }, + "Otros cultivos agr\u00edcolas": { + "account_number": "610545", + "account_type": "Cost of Goods Sold" + }, + "Cr\u00eda de ovejas, cabras, asnos, mulas y burd\u00e9ganos": { + "account_number": "610550", + "account_type": "Cost of Goods Sold" + }, + "Cr\u00eda de ganado caballar y vacuno": { + "account_number": "610555", + "account_type": "Cost of Goods Sold" + }, + "Producci\u00f3n av\u00edcola": { + "account_number": "610560", + "account_type": "Cost of Goods Sold" + }, + "Cr\u00eda de otros animales": { + "account_number": "610565", + "account_type": "Cost of Goods Sold" + }, + "Servicios agr\u00edcolas y ganaderos": { + "account_number": "610570", + "account_type": "Cost of Goods Sold" + }, + "Actividad de caza": { + "account_number": "610575", + "account_type": "Cost of Goods Sold" + }, + "Actividad de silvicultura": { + "account_number": "610580", + "account_type": "Cost of Goods Sold" + }, + "Actividades conexas": { + "account_number": "610595", + "account_type": "Cost of Goods Sold" + }, + "Ajustes por inflaci\u00f3n": { + "account_number": "610599", + "account_type": "Cost of Goods Sold" + } + }, + "Pesca": { + "account_number": "6110", + "account_type": "Cost of Goods Sold", + "Actividad de pesca": { + "account_number": "611005", + "account_type": "Cost of Goods Sold" + }, + "Explotaci\u00f3n de criaderos de peces": { + "account_number": "611010", + "account_type": "Cost of Goods Sold" + }, + "Actividades conexas": { + "account_number": "611095", + "account_type": "Cost of Goods Sold" + }, + "Ajustes por inflaci\u00f3n": { + "account_number": "611099", + "account_type": "Cost of Goods Sold" + } + }, + "Explotaci\u00f3n de minas y canteras": { + "account_number": "6115", + "account_type": "Cost of Goods Sold", + "Carb\u00f3n": { + "account_number": "611505", + "account_type": "Cost of Goods Sold" + }, + "Petr\u00f3leo crudo": { + "account_number": "611510", + "account_type": "Cost of Goods Sold" + }, + "Gas natural": { + "account_number": "611512", + "account_type": "Cost of Goods Sold" + }, + "Servicios relacionados con extracci\u00f3n de petr\u00f3leo y gas": { + "account_number": "611514", + "account_type": "Cost of Goods Sold" + }, + "Minerales de hierro": { + "account_number": "611515", + "account_type": "Cost of Goods Sold" + }, + "Minerales metal\u00edferos no ferrosos": { + "account_number": "611520", + "account_type": "Cost of Goods Sold" + }, + "Piedra, arena y arcilla": { + "account_number": "611525", + "account_type": "Cost of Goods Sold" + }, + "Piedras preciosas": { + "account_number": "611527", + "account_type": "Cost of Goods Sold" + }, + "Oro": { + "account_number": "611528", + "account_type": "Cost of Goods Sold" + }, + "Otras minas y canteras": { + "account_number": "611530", + "account_type": "Cost of Goods Sold" + }, + "Prestaci\u00f3n de servicios sector minero": { + "account_number": "611532", + "account_type": "Cost of Goods Sold" + }, + "Actividades conexas": { + "account_number": "611595", + "account_type": "Cost of Goods Sold" + }, + "Ajustes por inflaci\u00f3n": { + "account_number": "611599", + "account_type": "Cost of Goods Sold" + } + }, + "Industrias manufactureras": { + "account_number": "6120", + "account_type": "Cost of Goods Sold", + "Producci\u00f3n y procesamiento de carnes y productos c\u00e1rnicos": { + "account_number": "612001", + "account_type": "Cost of Goods Sold" + }, + "Productos de pescado": { + "account_number": "612002", + "account_type": "Cost of Goods Sold" + }, + "Productos de frutas, legumbres y hortalizas": { + "account_number": "612003", + "account_type": "Cost of Goods Sold" + }, + "Elaboraci\u00f3n de aceites y grasas": { + "account_number": "612004", + "account_type": "Cost of Goods Sold" + }, + "Elaboraci\u00f3n de productos l\u00e1cteos": { + "account_number": "612005", + "account_type": "Cost of Goods Sold" + }, + "Elaboraci\u00f3n de productos de moliner\u00eda": { + "account_number": "612006", + "account_type": "Cost of Goods Sold" + }, + "Elaboraci\u00f3n de almidones y derivados": { + "account_number": "612007", + "account_type": "Cost of Goods Sold" + }, + "Elaboraci\u00f3n de alimentos para animales": { + "account_number": "612008", + "account_type": "Cost of Goods Sold" + }, + "Elaboraci\u00f3n de productos para panader\u00eda": { + "account_number": "612009", + "account_type": "Cost of Goods Sold" + }, + "Elaboraci\u00f3n de az\u00facar y melazas": { + "account_number": "612010", + "account_type": "Cost of Goods Sold" + }, + "Elaboraci\u00f3n de cacao, chocolate y confiter\u00eda": { + "account_number": "612011", + "account_type": "Cost of Goods Sold" + }, + "Elaboraci\u00f3n de pastas y productos farin\u00e1ceos": { + "account_number": "612012", + "account_type": "Cost of Goods Sold" + }, + "Elaboraci\u00f3n de productos de caf\u00e9": { + "account_number": "612013", + "account_type": "Cost of Goods Sold" + }, + "Elaboraci\u00f3n de otros productos alimenticios": { + "account_number": "612014", + "account_type": "Cost of Goods Sold" + }, + "Elaboraci\u00f3n de bebidas alcoh\u00f3licas y alcohol et\u00edlico": { + "account_number": "612015", + "account_type": "Cost of Goods Sold" + }, + "Elaboraci\u00f3n de vinos": { + "account_number": "612016", + "account_type": "Cost of Goods Sold" + }, + "Elaboraci\u00f3n de bebidas malteadas y de malta": { + "account_number": "612017", + "account_type": "Cost of Goods Sold" + }, + "Elaboraci\u00f3n de bebidas no alcoh\u00f3licas": { + "account_number": "612018", + "account_type": "Cost of Goods Sold" + }, + "Elaboraci\u00f3n de productos de tabaco": { + "account_number": "612019", + "account_type": "Cost of Goods Sold" + }, + "Preparaci\u00f3n e hilatura de fibras textiles y tejedur\u00eda": { + "account_number": "612020", + "account_type": "Cost of Goods Sold" + }, + "Acabado de productos textiles": { + "account_number": "612021", + "account_type": "Cost of Goods Sold" + }, + "Elaboraci\u00f3n de art\u00edculos de materiales textiles": { + "account_number": "612022", + "account_type": "Cost of Goods Sold" + }, + "Elaboraci\u00f3n de tapices y alfombras": { + "account_number": "612023", + "account_type": "Cost of Goods Sold" + }, + "Elaboraci\u00f3n de cuerdas, cordeles, bramantes y redes": { + "account_number": "612024", + "account_type": "Cost of Goods Sold" + }, + "Elaboraci\u00f3n de otros productos textiles": { + "account_number": "612025", + "account_type": "Cost of Goods Sold" + }, + "Elaboraci\u00f3n de tejidos": { + "account_number": "612026", + "account_type": "Cost of Goods Sold" + }, + "Elaboraci\u00f3n de prendas de vestir": { + "account_number": "612027", + "account_type": "Cost of Goods Sold" + }, + "Preparaci\u00f3n, adobo y te\u00f1ido de pieles": { + "account_number": "612028", + "account_type": "Cost of Goods Sold" + }, + "Curtido, adobo o preparaci\u00f3n de cuero": { + "account_number": "612029", + "account_type": "Cost of Goods Sold" + }, + "Elaboraci\u00f3n de maletas, bolsos y similares": { + "account_number": "612030", + "account_type": "Cost of Goods Sold" + }, + "Elaboraci\u00f3n de calzado": { + "account_number": "612031", + "account_type": "Cost of Goods Sold" + }, + "Producci\u00f3n de madera, art\u00edculos de madera y corcho": { + "account_number": "612032", + "account_type": "Cost of Goods Sold" + }, + "Elaboraci\u00f3n de pasta y productos de madera, papel y cart\u00f3n": { + "account_number": "612033", + "account_type": "Cost of Goods Sold" + }, + "Ediciones y publicaciones": { + "account_number": "612034", + "account_type": "Cost of Goods Sold" + }, + "Impresi\u00f3n": { + "account_number": "612035", + "account_type": "Cost of Goods Sold" + }, + "Servicios relacionados con la edici\u00f3n y la impresi\u00f3n": { + "account_number": "612036", + "account_type": "Cost of Goods Sold" + }, + "Reproducci\u00f3n de grabaciones": { + "account_number": "612037", + "account_type": "Cost of Goods Sold" + }, + "Elaboraci\u00f3n de productos de horno de coque": { + "account_number": "612038", + "account_type": "Cost of Goods Sold" + }, + "Elaboraci\u00f3n de productos de la refinaci\u00f3n de petr\u00f3leo": { + "account_number": "612039", + "account_type": "Cost of Goods Sold" + }, + "Elaboraci\u00f3n de sustancias qu\u00edmicas b\u00e1sicas": { + "account_number": "612040", + "account_type": "Cost of Goods Sold" + }, + "Elaboraci\u00f3n de abonos y compuestos de nitr\u00f3geno": { + "account_number": "612041", + "account_type": "Cost of Goods Sold" + }, + "Elaboraci\u00f3n de pl\u00e1stico y caucho sint\u00e9tico": { + "account_number": "612042", + "account_type": "Cost of Goods Sold" + }, + "Elaboraci\u00f3n de productos qu\u00edmicos de uso agropecuario": { + "account_number": "612043", + "account_type": "Cost of Goods Sold" + }, + "Elaboraci\u00f3n de pinturas, tintas y masillas": { + "account_number": "612044", + "account_type": "Cost of Goods Sold" + }, + "Elaboraci\u00f3n de productos farmac\u00e9uticos y bot\u00e1nicos": { + "account_number": "612045", + "account_type": "Cost of Goods Sold" + }, + "Elaboraci\u00f3n de jabones, detergentes y preparados de tocador": { + "account_number": "612046", + "account_type": "Cost of Goods Sold" + }, + "Elaboraci\u00f3n de otros productos qu\u00edmicos": { + "account_number": "612047", + "account_type": "Cost of Goods Sold" + }, + "Elaboraci\u00f3n de fibras": { + "account_number": "612048", + "account_type": "Cost of Goods Sold" + }, + "Elaboraci\u00f3n de otros productos de caucho": { + "account_number": "612049", + "account_type": "Cost of Goods Sold" + }, + "Elaboraci\u00f3n de productos de pl\u00e1stico": { + "account_number": "612050", + "account_type": "Cost of Goods Sold" + }, + "Elaboraci\u00f3n de vidrio y productos de vidrio": { + "account_number": "612051", + "account_type": "Cost of Goods Sold" + }, + "Elaboraci\u00f3n de productos de cer\u00e1mica, loza, piedra, arcilla y porcelana": { + "account_number": "612052", + "account_type": "Cost of Goods Sold" + }, + "Elaboraci\u00f3n de cemento, cal y yeso": { + "account_number": "612053", + "account_type": "Cost of Goods Sold" + }, + "Elaboraci\u00f3n de art\u00edculos de hormig\u00f3n, cemento y yeso": { + "account_number": "612054", + "account_type": "Cost of Goods Sold" + }, + "Corte, tallado y acabado de la piedra": { + "account_number": "612055", + "account_type": "Cost of Goods Sold" + }, + "Elaboraci\u00f3n de otros productos minerales no met\u00e1licos": { + "account_number": "612056", + "account_type": "Cost of Goods Sold" + }, + "Industrias b\u00e1sicas y fundici\u00f3n de hierro y acero": { + "account_number": "612057", + "account_type": "Cost of Goods Sold" + }, + "Productos primarios de metales preciosos y de metales no ferrosos": { + "account_number": "612058", + "account_type": "Cost of Goods Sold" + }, + "Fundici\u00f3n de metales no ferrosos": { + "account_number": "612059", + "account_type": "Cost of Goods Sold" + }, + "Fabricaci\u00f3n de productos met\u00e1licos para uso estructural": { + "account_number": "612060", + "account_type": "Cost of Goods Sold" + }, + "Forja, prensado, estampado, laminado de metal y pulvimetalurgia": { + "account_number": "612061", + "account_type": "Cost of Goods Sold" + }, + "Revestimiento de metales y obras de ingenier\u00eda mec\u00e1nica": { + "account_number": "612062", + "account_type": "Cost of Goods Sold" + }, + "Fabricaci\u00f3n de art\u00edculos de ferreter\u00eda": { + "account_number": "612063", + "account_type": "Cost of Goods Sold" + }, + "Elaboraci\u00f3n de otros productos de metal": { + "account_number": "612064", + "account_type": "Cost of Goods Sold" + }, + "Fabricaci\u00f3n de maquinaria y equipo": { + "account_number": "612065", + "account_type": "Cost of Goods Sold" + }, + "Fabricaci\u00f3n de equipos de elevaci\u00f3n y manipulaci\u00f3n": { + "account_number": "612066", + "account_type": "Cost of Goods Sold" + }, + "Elaboraci\u00f3n de aparatos de uso dom\u00e9stico": { + "account_number": "612067", + "account_type": "Cost of Goods Sold" + }, + "Elaboraci\u00f3n de equipo de oficina": { + "account_number": "612068", + "account_type": "Cost of Goods Sold" + }, + "Elaboraci\u00f3n de pilas y bater\u00edas primarias": { + "account_number": "612069", + "account_type": "Cost of Goods Sold" + }, + "Elaboraci\u00f3n de equipo de iluminaci\u00f3n": { + "account_number": "612070", + "account_type": "Cost of Goods Sold" + }, + "Elaboraci\u00f3n de otros tipos de equipo el\u00e9ctrico": { + "account_number": "612071", + "account_type": "Cost of Goods Sold" + }, + "Fabricaci\u00f3n de equipos de radio, televisi\u00f3n y comunicaciones": { + "account_number": "612072", + "account_type": "Cost of Goods Sold" + }, + "Fabricaci\u00f3n de aparatos e instrumentos m\u00e9dicos": { + "account_number": "612073", + "account_type": "Cost of Goods Sold" + }, + "Fabricaci\u00f3n de instrumentos de medici\u00f3n y control": { + "account_number": "612074", + "account_type": "Cost of Goods Sold" + }, + "Fabricaci\u00f3n de instrumentos de \u00f3ptica y equipo fotogr\u00e1fico": { + "account_number": "612075", + "account_type": "Cost of Goods Sold" + }, + "Fabricaci\u00f3n de relojes": { + "account_number": "612076", + "account_type": "Cost of Goods Sold" + }, + "Fabricaci\u00f3n de veh\u00edculos automotores": { + "account_number": "612077", + "account_type": "Cost of Goods Sold" + }, + "Fabricaci\u00f3n de carrocer\u00edas para automotores": { + "account_number": "612078", + "account_type": "Cost of Goods Sold" + }, + "Fabricaci\u00f3n de partes, piezas y accesorios para automotores": { + "account_number": "612079", + "account_type": "Cost of Goods Sold" + }, + "Fabricaci\u00f3n y reparaci\u00f3n de buques y otras embarcaciones": { + "account_number": "612080", + "account_type": "Cost of Goods Sold" + }, + "Fabricaci\u00f3n de locomotoras y material rodante para ferrocarriles": { + "account_number": "612081", + "account_type": "Cost of Goods Sold" + }, + "Fabricaci\u00f3n de aeronaves": { + "account_number": "612082", + "account_type": "Cost of Goods Sold" + }, + "Fabricaci\u00f3n de motocicletas": { + "account_number": "612083", + "account_type": "Cost of Goods Sold" + }, + "Fabricaci\u00f3n de bicicletas y sillas de ruedas": { + "account_number": "612084", + "account_type": "Cost of Goods Sold" + }, + "Fabricaci\u00f3n de otros tipos de transporte": { + "account_number": "612085", + "account_type": "Cost of Goods Sold" + }, + "Fabricaci\u00f3n de muebles": { + "account_number": "612086", + "account_type": "Cost of Goods Sold" + }, + "Fabricaci\u00f3n de joyas y art\u00edculos conexos": { + "account_number": "612087", + "account_type": "Cost of Goods Sold" + }, + "Fabricaci\u00f3n de instrumentos de m\u00fasica": { + "account_number": "612088", + "account_type": "Cost of Goods Sold" + }, + "Fabricaci\u00f3n de art\u00edculos y equipo para deporte": { + "account_number": "612089", + "account_type": "Cost of Goods Sold" + }, + "Fabricaci\u00f3n de juegos y juguetes": { + "account_number": "612090", + "account_type": "Cost of Goods Sold" + }, + "Reciclamiento de desperdicios": { + "account_number": "612091", + "account_type": "Cost of Goods Sold" + }, + "Productos de otras industrias manufactureras": { + "account_number": "612095", + "account_type": "Cost of Goods Sold" + }, + "Ajustes por inflaci\u00f3n": { + "account_number": "612099", + "account_type": "Cost of Goods Sold" + } + }, + "Suministro de electricidad, gas y agua": { + "account_number": "6125", + "account_type": "Cost of Goods Sold", + "Generaci\u00f3n, captaci\u00f3n y distribuci\u00f3n de energ\u00eda el\u00e9ctrica": { + "account_number": "612505", + "account_type": "Cost of Goods Sold" + }, + "Fabricaci\u00f3n de gas y distribuci\u00f3n de combustibles gaseosos": { + "account_number": "612510", + "account_type": "Cost of Goods Sold" + }, + "Captaci\u00f3n, depuraci\u00f3n y distribuci\u00f3n de agua": { + "account_number": "612515", + "account_type": "Cost of Goods Sold" + }, + "Actividades conexas": { + "account_number": "612595", + "account_type": "Cost of Goods Sold" + }, + "Ajustes por inflaci\u00f3n": { + "account_number": "612599", + "account_type": "Cost of Goods Sold" + } + }, + "Construcci\u00f3n": { + "account_number": "6130", + "account_type": "Cost of Goods Sold", + "Preparaci\u00f3n de terrenos": { + "account_number": "613005", + "account_type": "Cost of Goods Sold" + }, + "Construcci\u00f3n de edificios y obras de ingenier\u00eda civil": { + "account_number": "613010", + "account_type": "Cost of Goods Sold" + }, + "Acondicionamiento de edificios": { + "account_number": "613015", + "account_type": "Cost of Goods Sold" + }, + "Terminaci\u00f3n de edificaciones": { + "account_number": "613020", + "account_type": "Cost of Goods Sold" + }, + "Alquiler de equipo con operario": { + "account_number": "613025", + "account_type": "Cost of Goods Sold" + }, + "Actividades conexas": { + "account_number": "613095", + "account_type": "Cost of Goods Sold" + }, + "Ajustes por inflaci\u00f3n": { + "account_number": "613099", + "account_type": "Cost of Goods Sold" + } + }, + "Comercio al por mayor y al por menor": { + "account_number": "6135", + "account_type": "Cost of Goods Sold", + "Venta de veh\u00edculos automotores": { + "account_number": "613502", + "account_type": "Cost of Goods Sold" + }, + "Mantenimiento, reparaci\u00f3n y lavado de veh\u00edculos automotores": { + "account_number": "613504", + "account_type": "Cost of Goods Sold" + }, + "Venta de partes, piezas y accesorios de veh\u00edculos automotores": { + "account_number": "613506", + "account_type": "Cost of Goods Sold" + }, + "Venta de combustibles s\u00f3lidos, l\u00edquidos, gaseosos": { + "account_number": "613508", + "account_type": "Cost of Goods Sold" + }, + "Venta de lubricantes, aditivos, llantas y lujos para automotores": { + "account_number": "613510", + "account_type": "Cost of Goods Sold" + }, + "Venta a cambio de retribuci\u00f3n o por contrata": { + "account_number": "613512", + "account_type": "Cost of Goods Sold" + }, + "Venta de insumos, materias primas agropecuarias y flores": { + "account_number": "613514", + "account_type": "Cost of Goods Sold" + }, + "Venta de otros insumos y materias primas no agropecuarias": { + "account_number": "613516", + "account_type": "Cost of Goods Sold" + }, + "Venta de animales vivos y cueros": { + "account_number": "613518", + "account_type": "Cost of Goods Sold" + }, + "Venta de productos en almacenes no especializados": { + "account_number": "613520", + "account_type": "Cost of Goods Sold" + }, + "Venta de productos agropecuarios": { + "account_number": "613522", + "account_type": "Cost of Goods Sold" + }, + "Venta de productos textiles, de vestir, de cuero y calzado": { + "account_number": "613524", + "account_type": "Cost of Goods Sold" + }, + "Venta de papel y cart\u00f3n": { + "account_number": "613526", + "account_type": "Cost of Goods Sold" + }, + "Venta de libros, revistas, elementos de papeler\u00eda, \u00fatiles y textos escolares": { + "account_number": "613528", + "account_type": "Cost of Goods Sold" + }, + "Venta de juegos, juguetes y art\u00edculos deportivos": { + "account_number": "613530", + "account_type": "Cost of Goods Sold" + }, + "Venta de instrumentos quir\u00fargicos y ortop\u00e9dicos": { + "account_number": "613532", + "account_type": "Cost of Goods Sold" + }, + "Venta de art\u00edculos en relojer\u00edas y joyer\u00edas": { + "account_number": "613534", + "account_type": "Cost of Goods Sold" + }, + "Venta de electrodom\u00e9sticos y muebles": { + "account_number": "613536", + "account_type": "Cost of Goods Sold" + }, + "Venta de productos de aseo, farmac\u00e9uticos, medicinales y art\u00edculos de tocador": { + "account_number": "613538", + "account_type": "Cost of Goods Sold" + }, + "Venta de cubiertos, vajillas, cristaler\u00eda, porcelanas, cer\u00e1micas y otros art\u00edculos de uso dom\u00e9stico": { + "account_number": "613540", + "account_type": "Cost of Goods Sold" + }, + "Venta de materiales de construcci\u00f3n, fontaner\u00eda y calefacci\u00f3n": { + "account_number": "613542", + "account_type": "Cost of Goods Sold" + }, + "Venta de pinturas y lacas": { + "account_number": "613544", + "account_type": "Cost of Goods Sold" + }, + "Venta de productos de vidrios y marqueter\u00eda": { + "account_number": "613546", + "account_type": "Cost of Goods Sold" + }, + "Venta de herramientas y art\u00edculos de ferreter\u00eda": { + "account_number": "613548", + "account_type": "Cost of Goods Sold" + }, + "Venta de qu\u00edmicos": { + "account_number": "613550", + "account_type": "Cost of Goods Sold" + }, + "Venta de productos intermedios, desperdicios y desechos": { + "account_number": "613552", + "account_type": "Cost of Goods Sold" + }, + "Venta de maquinaria, equipo de oficina y programas de computador": { + "account_number": "613554", + "account_type": "Cost of Goods Sold" + }, + "Venta de art\u00edculos en cacharrer\u00edas y miscel\u00e1neas": { + "account_number": "613556", + "account_type": "Cost of Goods Sold" + }, + "Venta de instrumentos musicales": { + "account_number": "613558", + "account_type": "Cost of Goods Sold" + }, + "Venta de art\u00edculos en casas de empe\u00f1o y prender\u00edas": { + "account_number": "613560", + "account_type": "Cost of Goods Sold" + }, + "Venta de equipo fotogr\u00e1fico": { + "account_number": "613562", + "account_type": "Cost of Goods Sold" + }, + "Venta de equipo \u00f3ptico y de precisi\u00f3n": { + "account_number": "613564", + "account_type": "Cost of Goods Sold" + }, + "Venta de empaques": { + "account_number": "613566", + "account_type": "Cost of Goods Sold" + }, + "Venta de equipo profesional y cient\u00edfico": { + "account_number": "613568", + "account_type": "Cost of Goods Sold" + }, + "Venta de loter\u00edas, rifas, chance, apuestas y similares": { + "account_number": "613570", + "account_type": "Cost of Goods Sold" + }, + "Reparaci\u00f3n de efectos personales y electrodom\u00e9sticos": { + "account_number": "613572", + "account_type": "Cost of Goods Sold" + }, + "Venta de otros productos": { + "account_number": "613595", + "account_type": "Cost of Goods Sold" + }, + "Ajustes por inflaci\u00f3n": { + "account_number": "613599", + "account_type": "Cost of Goods Sold" + } + }, + "Hoteles y restaurantes": { + "account_number": "6140", + "account_type": "Cost of Goods Sold", + "Hoteler\u00eda": { + "account_number": "614005", + "account_type": "Cost of Goods Sold" + }, + "Campamento y otros tipos de hospedaje": { + "account_number": "614010", + "account_type": "Cost of Goods Sold" + }, + "Restaurantes": { + "account_number": "614015", + "account_type": "Cost of Goods Sold" + }, + "Bares y cantinas": { + "account_number": "614020", + "account_type": "Cost of Goods Sold" + }, + "Actividades conexas": { + "account_number": "614095", + "account_type": "Cost of Goods Sold" + }, + "Ajustes por inflaci\u00f3n": { + "account_number": "614099", + "account_type": "Cost of Goods Sold" + } + }, + "Transporte, almacenamiento y comunicaciones": { + "account_number": "6145", + "account_type": "Cost of Goods Sold", + "Servicio de transporte por carretera": { + "account_number": "614505", + "account_type": "Cost of Goods Sold" + }, + "Servicio de transporte por v\u00eda f\u00e9rrea": { + "account_number": "614510", + "account_type": "Cost of Goods Sold" + }, + "Servicio de transporte por v\u00eda acu\u00e1tica": { + "account_number": "614515", + "account_type": "Cost of Goods Sold" + }, + "Servicio de transporte por v\u00eda a\u00e9rea": { + "account_number": "614520", + "account_type": "Cost of Goods Sold" + }, + "Servicio de transporte por tuber\u00edas": { + "account_number": "614525", + "account_type": "Cost of Goods Sold" + }, + "Manipulaci\u00f3n de carga": { + "account_number": "614530", + "account_type": "Cost of Goods Sold" + }, + "Almacenamiento y dep\u00f3sito": { + "account_number": "614535", + "account_type": "Cost of Goods Sold" + }, + "Servicios complementarios para el transporte": { + "account_number": "614540", + "account_type": "Cost of Goods Sold" + }, + "Agencias de viaje": { + "account_number": "614545", + "account_type": "Cost of Goods Sold" + }, + "Otras agencias de transporte": { + "account_number": "614550", + "account_type": "Cost of Goods Sold" + }, + "Servicio postal y de correo": { + "account_number": "614555", + "account_type": "Cost of Goods Sold" + }, + "Servicio telef\u00f3nico": { + "account_number": "614560", + "account_type": "Cost of Goods Sold" + }, + "Servicio de tel\u00e9grafo": { + "account_number": "614565", + "account_type": "Cost of Goods Sold" + }, + "Servicio de transmisi\u00f3n de datos": { + "account_number": "614570", + "account_type": "Cost of Goods Sold" + }, + "Servicio de radio y televisi\u00f3n por cable": { + "account_number": "614575", + "account_type": "Cost of Goods Sold" + }, + "Transmisi\u00f3n de sonido e im\u00e1genes por contrato": { + "account_number": "614580", + "account_type": "Cost of Goods Sold" + }, + "Actividades conexas": { + "account_number": "614595", + "account_type": "Cost of Goods Sold" + }, + "Ajustes por inflaci\u00f3n": { + "account_number": "614599", + "account_type": "Cost of Goods Sold" + } + }, + "Actividad financiera": { + "account_number": "6150", + "account_type": "Cost of Goods Sold", + "De inversiones": { + "account_number": "615005", + "account_type": "Cost of Goods Sold" + }, + "De servicio de bolsa": { + "account_number": "615010", + "account_type": "Cost of Goods Sold" + }, + "Ajustes por inflaci\u00f3n": { + "account_number": "615099", + "account_type": "Cost of Goods Sold" + } + }, + "Actividades inmobiliarias, empresariales y de alquiler": { + "account_number": "6155", + "account_type": "Cost of Goods Sold", + "Arrendamientos de bienes inmuebles": { + "account_number": "615505", + "account_type": "Cost of Goods Sold" + }, + "Inmobiliarias por retribuci\u00f3n o contrata": { + "account_number": "615510", + "account_type": "Cost of Goods Sold" + }, + "Alquiler equipo de transporte": { + "account_number": "615515", + "account_type": "Cost of Goods Sold" + }, + "Alquiler maquinaria y equipo": { + "account_number": "615520", + "account_type": "Cost of Goods Sold" + }, + "Alquiler de efectos personales y enseres dom\u00e9sticos": { + "account_number": "615525", + "account_type": "Cost of Goods Sold" + }, + "Consultor\u00eda en equipo y programas de inform\u00e1tica": { + "account_number": "615530", + "account_type": "Cost of Goods Sold" + }, + "Procesamiento de datos": { + "account_number": "615535", + "account_type": "Cost of Goods Sold" + }, + "Mantenimiento y reparaci\u00f3n de maquinaria de oficina": { + "account_number": "615540", + "account_type": "Cost of Goods Sold" + }, + "Investigaciones cient\u00edficas y de desarrollo": { + "account_number": "615545", + "account_type": "Cost of Goods Sold" + }, + "Actividades empresariales de consultor\u00eda": { + "account_number": "615550", + "account_type": "Cost of Goods Sold" + }, + "Publicidad": { + "account_number": "615555", + "account_type": "Cost of Goods Sold" + }, + "Dotaci\u00f3n de personal": { + "account_number": "615560", + "account_type": "Cost of Goods Sold" + }, + "Investigaci\u00f3n y seguridad": { + "account_number": "615565", + "account_type": "Cost of Goods Sold" + }, + "Limpieza de inmuebles": { + "account_number": "615570", + "account_type": "Cost of Goods Sold" + }, + "Fotograf\u00eda": { + "account_number": "615575", + "account_type": "Cost of Goods Sold" + }, + "Envase y empaque": { + "account_number": "615580", + "account_type": "Cost of Goods Sold" + }, + "Fotocopiado": { + "account_number": "615585", + "account_type": "Cost of Goods Sold" + }, + "Mantenimiento y reparaci\u00f3n de maquinaria y equipo": { + "account_number": "615590", + "account_type": "Cost of Goods Sold" + }, + "Actividades conexas": { + "account_number": "615595", + "account_type": "Cost of Goods Sold" + }, + "Ajustes por inflaci\u00f3n": { + "account_number": "615599", + "account_type": "Cost of Goods Sold" + } + }, + "Ense\u00f1anza": { + "account_number": "6160", + "account_type": "Cost of Goods Sold", + "Actividades relacionadas con la educaci\u00f3n": { + "account_number": "616005", + "account_type": "Cost of Goods Sold" + }, + "Actividades conexas": { + "account_number": "616095", + "account_type": "Cost of Goods Sold" + }, + "Ajustes por inflaci\u00f3n": { + "account_number": "616099", + "account_type": "Cost of Goods Sold" + } + }, + "Servicios sociales y de salud": { + "account_number": "6165", + "account_type": "Cost of Goods Sold", + "Servicio hospitalario": { + "account_number": "616505", + "account_type": "Cost of Goods Sold" + }, + "Servicio m\u00e9dico": { + "account_number": "616510", + "account_type": "Cost of Goods Sold" + }, + "Servicio odontol\u00f3gico": { + "account_number": "616515", + "account_type": "Cost of Goods Sold" + }, + "Servicio de laboratorio": { + "account_number": "616520", + "account_type": "Cost of Goods Sold" + }, + "Actividades veterinarias": { + "account_number": "616525", + "account_type": "Cost of Goods Sold" + }, + "Actividades de servicios sociales": { + "account_number": "616530", + "account_type": "Cost of Goods Sold" + }, + "Actividades conexas": { + "account_number": "616595", + "account_type": "Cost of Goods Sold" + }, + "Ajustes por inflaci\u00f3n": { + "account_number": "616599", + "account_type": "Cost of Goods Sold" + } + }, + "Otras actividades de servicios comunitarios, sociales y personales": { + "account_number": "6170", + "account_type": "Cost of Goods Sold", + "Eliminaci\u00f3n de desperdicios y aguas residuales": { + "account_number": "617005", + "account_type": "Cost of Goods Sold" + }, + "Actividades de asociaci\u00f3n": { + "account_number": "617010", + "account_type": "Cost of Goods Sold" + }, + "Producci\u00f3n y distribuci\u00f3n de filmes y videocintas": { + "account_number": "617015", + "account_type": "Cost of Goods Sold" + }, + "Exhibici\u00f3n de filmes y videocintas": { + "account_number": "617020", + "account_type": "Cost of Goods Sold" + }, + "Actividad de radio y televisi\u00f3n": { + "account_number": "617025", + "account_type": "Cost of Goods Sold" + }, + "Actividad teatral, musical y art\u00edstica": { + "account_number": "617030", + "account_type": "Cost of Goods Sold" + }, + "Grabaci\u00f3n y producci\u00f3n de discos": { + "account_number": "617035", + "account_type": "Cost of Goods Sold" + }, + "Entretenimiento y esparcimiento": { + "account_number": "617040", + "account_type": "Cost of Goods Sold" + }, + "Agencias de noticias": { + "account_number": "617045", + "account_type": "Cost of Goods Sold" + }, + "Lavander\u00edas y similares": { + "account_number": "617050", + "account_type": "Cost of Goods Sold" + }, + "Peluquer\u00edas y similares": { + "account_number": "617055", + "account_type": "Cost of Goods Sold" + }, + "Servicios funerarios": { + "account_number": "617060", + "account_type": "Cost of Goods Sold" + }, + "Zonas francas": { + "account_number": "617065", + "account_type": "Cost of Goods Sold" + }, + "Actividades conexas": { + "account_number": "617095", + "account_type": "Cost of Goods Sold" + }, + "Ajustes por inflaci\u00f3n": { + "account_number": "617099", + "account_type": "Cost of Goods Sold" + } + } + }, + "Compras": { + "account_number": "62", + "account_type": "Cost of Goods Sold", + "De mercanc\u00edas": { + "account_number": "6205", + "account_type": "Cost of Goods Sold", + "Ajustes por inflaci\u00f3n": { + "account_number": "620599", + "account_type": "Cost of Goods Sold" + } + }, + "De materias primas": { + "account_number": "6210", + "account_type": "Cost of Goods Sold", + "Ajustes por inflaci\u00f3n": { + "account_number": "621099", + "account_type": "Cost of Goods Sold" + } + }, + "De materiales indirectos": { + "account_number": "6215", + "account_type": "Cost of Goods Sold", + "Ajustes por inflaci\u00f3n": { + "account_number": "621599", + "account_type": "Cost of Goods Sold" + } + }, + "Compra de energ\u00eda": { + "account_number": "6220", + "account_type": "Cost of Goods Sold", + "Ajustes por inflaci\u00f3n": { + "account_number": "622099", + "account_type": "Cost of Goods Sold" + } + }, + "Devoluciones en compras (CR)": { + "account_number": "6225", + "account_type": "Cost of Goods Sold", + "Ajustes por inflaci\u00f3n": { + "account_number": "622599", + "account_type": "Cost of Goods Sold" + } + } + } + }, + "Costos de producci\u00f3n o de operaci\u00f3n": { + "account_number": "7", + "account_type": "Cost of Goods Sold", + "root_type": "Expense", + "Materia prima": { + "account_number": "71", + "account_type": "Cost of Goods Sold" + }, + "Mano de obra directa": { + "account_number": "72", + "account_type": "Cost of Goods Sold" + }, + "Costos indirectos": { + "account_number": "73", + "account_type": "Cost of Goods Sold" + }, + "Contratos de servicios": { + "account_number": "74", + "account_type": "Cost of Goods Sold" + } + }, + "Cuentas de orden deudoras": { + "account_number": "8", + "root_type": "Asset", + "Derechos contingentes": { + "account_number": "81", + "Bienes y valores entregados en custodia": { + "account_number": "8105", + "Valores mobiliarios": { + "account_number": "810505" + }, + "Bienes muebles": { + "account_number": "810510" + }, + "Ajustes por inflaci\u00f3n": { + "account_number": "810599" + } + }, + "Bienes y valores entregados en garant\u00eda": { + "account_number": "8110", + "Valores mobiliarios": { + "account_number": "811005" + }, + "Bienes muebles": { + "account_number": "811010" + }, + "Bienes inmuebles": { + "account_number": "811015" + }, + "Contratos de ganado en participaci\u00f3n": { + "account_number": "811020" + }, + "Ajustes por inflaci\u00f3n": { + "account_number": "811099" + } + }, + "Bienes y valores en poder de terceros": { + "account_number": "8115", + "En arrendamiento": { + "account_number": "811505" + }, + "En pr\u00e9stamo": { + "account_number": "811510" + }, + "En dep\u00f3sito": { + "account_number": "811515" + }, + "En consignaci\u00f3n": { + "account_number": "811520" + }, + "Ajustes por inflaci\u00f3n": { + "account_number": "811599" + } + }, + "Litigios y/o demandas": { + "account_number": "8120", + "Ejecutivos": { + "account_number": "812005" + }, + "Incumplimiento de contratos": { + "account_number": "812010" + } + }, + "Promesas de compraventa": { + "account_number": "8125" + }, + "Diversas": { + "account_number": "8195", + "Valores adquiridos por recibir": { + "account_number": "819505" + }, + "Otras": { + "account_number": "819595" + }, + "Ajustes por inflaci\u00f3n": { + "account_number": "819599" + } + } + }, + "Deudoras fiscales": { + "account_number": "82" + }, + "Deudoras de control": { + "account_number": "83", + "Bienes recibidos en arrendamiento financiero": { + "account_number": "8305", + "Bienes muebles": { + "account_number": "830505" + }, + "Bienes inmuebles": { + "account_number": "830510" + }, + "Ajustes por inflaci\u00f3n": { + "account_number": "830599" + } + }, + "T\u00edtulos de inversi\u00f3n no colocados": { + "account_number": "8310", + "Acciones": { + "account_number": "831005" + }, + "Bonos": { + "account_number": "831010" + }, + "Otros": { + "account_number": "831095" + } + }, + "Propiedades, planta y equipo totalmente depreciados, agotados y/o amortizados": { + "account_number": "8315", + "Materiales proyectos petroleros": { + "account_number": "831506" + }, + "Construcciones y edificaciones": { + "account_number": "831516" + }, + "Maquinaria y equipo": { + "account_number": "831520" + }, + "Equipo de oficina": { + "account_number": "831524" + }, + "Equipo de computaci\u00f3n y comunicaci\u00f3n": { + "account_number": "831528" + }, + "Equipo m\u00e9dico-cient\u00edfico": { + "account_number": "831532" + }, + "Equipo de hoteles y restaurantes": { + "account_number": "831536" + }, + "Flota y equipo de transporte": { + "account_number": "831540" + }, + "Flota y equipo fluvial y/o mar\u00edtimo": { + "account_number": "831544" + }, + "Flota y equipo a\u00e9reo": { + "account_number": "831548" + }, + "Flota y equipo f\u00e9rreo": { + "account_number": "831552" + }, + "Acueductos, plantas y redes": { + "account_number": "831556" + }, + "Armamento de vigilancia": { + "account_number": "831560" + }, + "Envases y empaques": { + "account_number": "831562" + }, + "Plantaciones agr\u00edcolas y forestales": { + "account_number": "831564" + }, + "V\u00edas de comunicaci\u00f3n": { + "account_number": "831568" + }, + "Minas y canteras": { + "account_number": "831572" + }, + "Pozos artesianos": { + "account_number": "831576" + }, + "Yacimientos": { + "account_number": "831580" + }, + "Semovientes": { + "account_number": "831584" + }, + "Ajustes por inflaci\u00f3n": { + "account_number": "831599" + } + }, + "Cr\u00e9ditos a favor no utilizados": { + "account_number": "8320", + "Pa\u00eds": { + "account_number": "832005" + }, + "Exterior": { + "account_number": "832010" + } + }, + "Activos castigados": { + "account_number": "8325", + "Inversiones": { + "account_number": "832505" + }, + "Deudores": { + "account_number": "832510" + }, + "Otros activos": { + "account_number": "832595" + } + }, + "T\u00edtulos de inversi\u00f3n amortizados": { + "account_number": "8330", + "Bonos": { + "account_number": "833005" + }, + "Otros": { + "account_number": "833095" + } + }, + "Capitalizaci\u00f3n por revalorizaci\u00f3n de patrimonio": { + "account_number": "8335" + }, + "Otras cuentas deudoras de control": { + "account_number": "8395", + "Cheques posfechados": { + "account_number": "839505" + }, + "Certificados de dep\u00f3sito a t\u00e9rmino": { + "account_number": "839510" + }, + "Cheques devueltos": { + "account_number": "839515" + }, + "Bienes y valores en fideicomiso": { + "account_number": "839520" + }, + "Intereses sobre deudas vencidas": { + "account_number": "839525" + }, + "Diversas": { + "account_number": "839595" + }, + "Ajustes por inflaci\u00f3n": { + "account_number": "839599" + } + }, + "Ajustes por inflaci\u00f3n activos": { + "account_number": "8399", + "Inversiones": { + "account_number": "839905" + }, + "Inventarios": { + "account_number": "839910" + }, + "Propiedades, planta y equipo": { + "account_number": "839915" + }, + "Intangibles": { + "account_number": "839920" + }, + "Cargos diferidos": { + "account_number": "839925" + }, + "Otros activos": { + "account_number": "839995" + } + } + }, + "Derechos contingentes por contra (CR)": { + "account_number": "84" + }, + "Deudoras fiscales por contra (CR)": { + "account_number": "85" + }, + "Deudoras de control por contra (CR)": { + "account_number": "86" + } + }, + "Cuentas de orden acreedoras": { + "account_number": "9", + "root_type": "Liability", + "Responsabilidades contingentes": { + "account_number": "91", + "Bienes y valores recibidos en custodia": { + "account_number": "9105", + "Valores mobiliarios": { + "account_number": "910505" + }, + "Bienes muebles": { + "account_number": "910510" + }, + "Ajustes por inflaci\u00f3n": { + "account_number": "910599" + } + }, + "Bienes y valores recibidos en garant\u00eda": { + "account_number": "9110", + "Valores mobiliarios": { + "account_number": "911005" + }, + "Bienes muebles": { + "account_number": "911010" + }, + "Bienes inmuebles": { + "account_number": "911015" + }, + "Contratos de ganado en participaci\u00f3n": { + "account_number": "911020" + }, + "Ajustes por inflaci\u00f3n": { + "account_number": "911099" + } + }, + "Bienes y valores recibidos de terceros": { + "account_number": "9115", + "En arrendamiento": { + "account_number": "911505" + }, + "En pr\u00e9stamo": { + "account_number": "911510" + }, + "En dep\u00f3sito": { + "account_number": "911515" + }, + "En consignaci\u00f3n": { + "account_number": "911520" + }, + "En comodato": { + "account_number": "911525" + }, + "Ajustes por inflaci\u00f3n": { + "account_number": "911599" + } + }, + "Litigios y/o demandas": { + "account_number": "9120", + "Laborales": { + "account_number": "912005" + }, + "Civiles": { + "account_number": "912010" + }, + "Administrativos o arbitrales": { + "account_number": "912015" + }, + "Tributarios": { + "account_number": "912020" + } + }, + "Promesas de compraventa": { + "account_number": "9125" + }, + "Contratos de administraci\u00f3n delegada": { + "account_number": "9130" + }, + "Cuentas en participaci\u00f3n": { + "account_number": "9135" + }, + "Otras responsabilidades contingentes": { + "account_number": "9195" + } + }, + "Acreedoras fiscales": { + "account_number": "92" + }, + "Acreedoras de control": { + "account_number": "93", + "Contratos de arrendamiento financiero": { + "account_number": "9305", + "Bienes muebles": { + "account_number": "930505" + }, + "Bienes inmuebles": { + "account_number": "930510" + } + }, + "Otras cuentas de orden acreedoras de control": { + "account_number": "9395", + "Documentos por cobrar descontados": { + "account_number": "939505" + }, + "Convenios de pago": { + "account_number": "939510" + }, + "Contratos de construcciones e instalaciones por ejecutar": { + "account_number": "939515" + }, + "Adjudicaciones pendientes de legalizar": { + "account_number": "939525" + }, + "Reserva art\u00edculo 3\u00ba Ley 4\u00aa de 1980": { + "account_number": "939530" + }, + "Reserva costo reposici\u00f3n semovientes": { + "account_number": "939535" + }, + "Diversas": { + "account_number": "939595" + }, + "Ajustes por inflaci\u00f3n": { + "account_number": "939599" + } + }, + "Ajustes por inflaci\u00f3n patrimonio": { + "account_number": "9399", + "Capital social": { + "account_number": "939905" + }, + "Super\u00e1vit de capital": { + "account_number": "939910" + }, + "Reservas": { + "account_number": "939915" + }, + "Dividendos o participaciones decretadas en acciones, cuotas o partes de inter\u00e9s social": { + "account_number": "939925" + }, + "Resultados de ejercicios anteriores": { + "account_number": "939930" + } + } + }, + "Responsabilidades contingentes por contra (DB)": { + "account_number": "94" + }, + "Acreedoras fiscales por contra (DB)": { + "account_number": "95" + }, + "Acreedoras de control por contra (DB)": { + "account_number": "96" + } + } + } +} \ No newline at end of file diff --git a/erpnext/accounts/doctype/account/chart_of_accounts/verified/co_plan_unico_de_cuentas_simple.json b/erpnext/accounts/doctype/account/chart_of_accounts/verified/co_plan_unico_de_cuentas_simple.json new file mode 100644 index 0000000000..cd6ce1edce --- /dev/null +++ b/erpnext/accounts/doctype/account/chart_of_accounts/verified/co_plan_unico_de_cuentas_simple.json @@ -0,0 +1,1746 @@ +{ + "country_code": "co", + "name": "Colombia PUC Simple", + "tree": { + "Activo": { + "account_number": "1", + "root_type": "Asset", + "Disponible": { + "account_number": "11", + "Caja": { + "account_number": "1105", + "account_type": "Cash", + "is_group": 1 + }, + "Bancos": { + "account_number": "1110", + "account_type": "Bank", + "is_group": 1 + }, + "Remesas en tr\u00e1nsito": { + "account_number": "1115", + "is_group": 1 + }, + "Cuentas de ahorro": { + "account_number": "1120", + "is_group": 1 + }, + "Fondos": { + "account_number": "1125", + "is_group": 1 + } + }, + "Inversiones": { + "account_number": "12", + "Acciones": { + "account_number": "1205", + "is_group": 1 + }, + "Cuotas o partes de inter\u00e9s social": { + "account_number": "1210", + "is_group": 1 + }, + "Bonos": { + "account_number": "1215", + "is_group": 1 + }, + "C\u00e9dulas": { + "account_number": "1220", + "is_group": 1 + }, + "Certificados": { + "account_number": "1225", + "is_group": 1 + }, + "Papeles comerciales": { + "account_number": "1230", + "is_group": 1 + }, + "T\u00edtulos": { + "account_number": "1235", + "is_group": 1 + }, + "Aceptaciones bancarias o financieras": { + "account_number": "1240", + "is_group": 1 + }, + "Derechos fiduciarios": { + "account_number": "1245", + "is_group": 1 + }, + "Derechos de recompra de inversiones negociadas (repos)": { + "account_number": "1250", + "is_group": 1 + }, + "Obligatorias": { + "account_number": "1255", + "is_group": 1 + }, + "Cuentas en participaci\u00f3n": { + "account_number": "1260", + "is_group": 1 + }, + "Otras inversiones": { + "account_number": "1295", + "is_group": 1 + }, + "Provisiones": { + "account_number": "1299", + "is_group": 1 + } + }, + "Deudores": { + "account_number": "13", + "account_type": "Receivable", + "Clientes": { + "account_number": "1305", + "account_type": "Receivable", + "is_group": 1 + }, + "Cuentas corrientes comerciales": { + "account_number": "1310", + "account_type": "Receivable", + "is_group": 1 + }, + "Cuentas por cobrar a casa matriz": { + "account_number": "1315", + "account_type": "Receivable", + "is_group": 1 + }, + "Cuentas por cobrar a vinculados econ\u00f3micos": { + "account_number": "1320", + "account_type": "Receivable", + "is_group": 1 + }, + "Cuentas por cobrar a directores": { + "account_number": "1323", + "account_type": "Receivable" + }, + "Cuentas por cobrar a socios y accionistas": { + "account_number": "1325", + "account_type": "Receivable", + "is_group": 1 + }, + "Aportes por cobrar": { + "account_number": "1328", + "account_type": "Receivable" + }, + "Anticipos y avances": { + "account_number": "1330", + "account_type": "Receivable", + "is_group": 1 + }, + "Cuentas de operaci\u00f3n conjunta": { + "account_number": "1332", + "account_type": "Receivable" + }, + "Dep\u00f3sitos": { + "account_number": "1335", + "account_type": "Receivable", + "is_group": 1 + }, + "Promesas de compra venta": { + "account_number": "1340", + "account_type": "Receivable", + "is_group": 1 + }, + "Ingresos por cobrar": { + "account_number": "1345", + "account_type": "Receivable", + "is_group": 1 + }, + "Retenci\u00f3n sobre contratos": { + "account_number": "1350", + "account_type": "Receivable", + "is_group": 1 + }, + "Anticipo de impuestos y contribuciones o saldos a favor": { + "account_number": "1355", + "account_type": "Receivable", + "is_group": 1 + }, + "Reclamaciones": { + "account_number": "1360", + "account_type": "Receivable", + "is_group": 1 + }, + "Cuentas por cobrar a trabajadores": { + "account_number": "1365", + "account_type": "Receivable", + "is_group": 1 + }, + "Pr\u00e9stamos a particulares": { + "account_number": "1370", + "account_type": "Receivable", + "is_group": 1 + }, + "Deudores varios": { + "account_number": "1380", + "account_type": "Receivable", + "is_group": 1 + }, + "Derechos de recompra de cartera negociada": { + "account_number": "1385", + "account_type": "Receivable" + }, + "Deudas de dif\u00edcil cobro": { + "account_number": "1390", + "account_type": "Receivable" + }, + "Provisiones": { + "account_number": "1399", + "account_type": "Receivable", + "is_group": 1 + } + }, + "Inventarios": { + "account_number": "14", + "account_type": "Stock", + "Materias primas": { + "account_number": "1405", + "account_type": "Stock", + "is_group": 1 + }, + "Productos en proceso": { + "account_number": "1410", + "account_type": "Stock", + "is_group": 1 + }, + "Obras de construcci\u00f3n en curso": { + "account_number": "1415", + "account_type": "Stock", + "is_group": 1 + }, + "Obras de urbanismo": { + "account_number": "1417", + "account_type": "Stock", + "is_group": 1 + }, + "Contratos en ejecuci\u00f3n": { + "account_number": "1420", + "account_type": "Stock", + "is_group": 1 + }, + "Cultivos en desarrollo": { + "account_number": "1425", + "account_type": "Stock", + "is_group": 1 + }, + "Plantaciones agr\u00edcolas": { + "account_number": "1428", + "account_type": "Stock", + "is_group": 1 + }, + "Productos terminados": { + "account_number": "1430", + "account_type": "Stock", + "is_group": 1 + }, + "Mercanc\u00edas no fabricadas por la empresa": { + "account_number": "1435", + "account_type": "Stock", + "is_group": 1 + }, + "Bienes ra\u00edces para la venta": { + "account_number": "1440", + "account_type": "Stock", + "is_group": 1 + }, + "Semovientes": { + "account_number": "1445", + "account_type": "Stock", + "is_group": 1 + }, + "Terrenos": { + "account_number": "1450", + "account_type": "Stock", + "is_group": 1 + }, + "Materiales, repuestos y accesorios": { + "account_number": "1455", + "account_type": "Stock", + "is_group": 1 + }, + "Envases y empaques": { + "account_number": "1460", + "account_type": "Stock", + "is_group": 1 + }, + "Inventarios en tr\u00e1nsito": { + "account_number": "1465", + "account_type": "Stock", + "is_group": 1 + }, + "Provisiones": { + "account_number": "1499", + "account_type": "Stock", + "is_group": 1 + } + }, + "Propiedades, planta y equipo": { + "account_number": "15", + "account_type": "Fixed Asset", + "Terrenos": { + "account_number": "1504", + "account_type": "Fixed Asset", + "is_group": 1 + }, + "Materiales proyectos petroleros": { + "account_number": "1506", + "account_type": "Fixed Asset", + "is_group": 1 + }, + "Construcciones en curso": { + "account_number": "1508", + "account_type": "Fixed Asset", + "is_group": 1 + }, + "Maquinaria y equipos en montaje": { + "account_number": "1512", + "account_type": "Fixed Asset", + "is_group": 1 + }, + "Construcciones y edificaciones": { + "account_number": "1516", + "account_type": "Fixed Asset", + "is_group": 1 + }, + "Maquinaria y equipo": { + "account_number": "1520", + "account_type": "Fixed Asset", + "is_group": 1 + }, + "Equipo de oficina": { + "account_number": "1524", + "account_type": "Fixed Asset", + "is_group": 1 + }, + "Equipo de computaci\u00f3n y comunicaci\u00f3n": { + "account_number": "1528", + "account_type": "Fixed Asset", + "is_group": 1 + }, + "Equipo m\u00e9dico-cient\u00edfico": { + "account_number": "1532", + "account_type": "Fixed Asset", + "is_group": 1 + }, + "Equipo de hoteles y restaurantes": { + "account_number": "1536", + "account_type": "Fixed Asset", + "is_group": 1 + }, + "Flota y equipo de transporte": { + "account_number": "1540", + "account_type": "Fixed Asset", + "is_group": 1 + }, + "Flota y equipo fluvial y/o mar\u00edtimo": { + "account_number": "1544", + "account_type": "Fixed Asset", + "is_group": 1 + }, + "Flota y equipo a\u00e9reo": { + "account_number": "1548", + "account_type": "Fixed Asset", + "is_group": 1 + }, + "Flota y equipo f\u00e9rreo": { + "account_number": "1552", + "account_type": "Fixed Asset", + "is_group": 1 + }, + "Acueductos, plantas y redes": { + "account_number": "1556", + "account_type": "Fixed Asset", + "is_group": 1 + }, + "Armamento de vigilancia": { + "account_number": "1560", + "account_type": "Fixed Asset", + "is_group": 1 + }, + "Envases y empaques": { + "account_number": "1562", + "account_type": "Fixed Asset", + "is_group": 1 + }, + "Plantaciones agr\u00edcolas y forestales": { + "account_number": "1564", + "account_type": "Fixed Asset", + "is_group": 1 + }, + "V\u00edas de comunicaci\u00f3n": { + "account_number": "1568", + "account_type": "Fixed Asset", + "is_group": 1 + }, + "Minas y canteras": { + "account_number": "1572", + "account_type": "Fixed Asset", + "is_group": 1 + }, + "Pozos artesianos": { + "account_number": "1576", + "account_type": "Fixed Asset", + "is_group": 1 + }, + "Yacimientos": { + "account_number": "1580", + "account_type": "Fixed Asset", + "is_group": 1 + }, + "Semovientes": { + "account_number": "1584", + "account_type": "Fixed Asset", + "is_group": 1 + }, + "Propiedades, planta y equipo en tr\u00e1nsito": { + "account_number": "1588", + "account_type": "Fixed Asset", + "is_group": 1 + }, + "Depreciaci\u00f3n acumulada": { + "account_number": "1592", + "account_type": "Fixed Asset", + "is_group": 1 + }, + "Depreciaci\u00f3n diferida": { + "account_number": "1596", + "account_type": "Fixed Asset", + "is_group": 1 + }, + "Amortizaci\u00f3n acumulada": { + "account_number": "1597", + "account_type": "Fixed Asset", + "is_group": 1 + }, + "Agotamiento acumulado": { + "account_number": "1598", + "account_type": "Fixed Asset", + "is_group": 1 + }, + "Provisiones": { + "account_number": "1599", + "account_type": "Fixed Asset", + "is_group": 1 + } + }, + "Intangibles": { + "account_number": "16", + "Cr\u00e9dito mercantil": { + "account_number": "1605", + "is_group": 1 + }, + "Marcas": { + "account_number": "1610", + "is_group": 1 + }, + "Patentes": { + "account_number": "1615", + "is_group": 1 + }, + "Concesiones y franquicias": { + "account_number": "1620", + "is_group": 1 + }, + "Derechos": { + "account_number": "1625", + "is_group": 1 + }, + "Know how": { + "account_number": "1630", + "is_group": 1 + }, + "Licencias": { + "account_number": "1635", + "is_group": 1 + }, + "Depreciaci\u00f3n y/o amortizaci\u00f3n acumulada": { + "account_number": "1698", + "is_group": 1 + }, + "Provisiones": { + "account_number": "1699", + "account_type": "Accumulated Depreciation" + } + }, + "Diferidos": { + "account_number": "17", + "Gastos pagados por anticipado": { + "account_number": "1705", + "is_group": 1 + }, + "Cargos diferidos": { + "account_number": "1710", + "is_group": 1 + }, + "Costos de exploraci\u00f3n por amortizar": { + "account_number": "1715", + "is_group": 1 + }, + "Costos de explotaci\u00f3n y desarrollo": { + "account_number": "1720", + "is_group": 1 + }, + "Cargos por correcci\u00f3n monetaria diferida": { + "account_number": "1730" + }, + "Amortizaci\u00f3n acumulada": { + "account_number": "1798", + "account_type": "Accumulated Depreciation", + "is_group": 1 + } + }, + "Otros activos": { + "account_number": "18", + "Bienes de arte y cultura": { + "account_number": "1805", + "is_group": 1 + }, + "Diversos": { + "account_number": "1895", + "is_group": 1 + }, + "Provisiones": { + "account_number": "1899", + "is_group": 1 + } + }, + "Valorizaciones": { + "account_number": "19", + "De inversiones": { + "account_number": "1905", + "is_group": 1 + }, + "De propiedades, planta y equipo": { + "account_number": "1910", + "is_group": 1 + }, + "De otros activos": { + "account_number": "1995", + "is_group": 1 + } + } + }, + "Pasivo": { + "account_number": "2", + "root_type": "Liability", + "Obligaciones financieras": { + "account_number": "21", + "Bancos nacionales": { + "account_number": "2105", + "is_group": 1 + }, + "Bancos del exterior": { + "account_number": "2110", + "is_group": 1 + }, + "Corporaciones financieras": { + "account_number": "2115", + "is_group": 1 + }, + "Compa\u00f1\u00edas de financiamiento comercial": { + "account_number": "2120", + "is_group": 1 + }, + "Corporaciones de ahorro y vivienda": { + "account_number": "2125", + "is_group": 1 + }, + "Entidades financieras del exterior": { + "account_number": "2130" + }, + "Compromisos de recompra de inversiones negociadas": { + "account_number": "2135", + "is_group": 1 + }, + "Compromisos de recompra de cartera negociada": { + "account_number": "2140" + }, + "Obligaciones gubernamentales": { + "account_number": "2145", + "is_group": 1 + }, + "Otras obligaciones": { + "account_number": "2195", + "is_group": 1 + } + }, + "Proveedores": { + "account_number": "22", + "account_type": "Payable", + "Nacionales": { + "account_number": "2205", + "account_type": "Payable" + }, + "Del exterior": { + "account_number": "2210", + "account_type": "Payable" + }, + "Cuentas corrientes comerciales": { + "account_number": "2215", + "account_type": "Payable" + }, + "Casa matriz": { + "account_number": "2220", + "account_type": "Payable" + }, + "Compa\u00f1\u00edas vinculadas": { + "account_number": "2225", + "account_type": "Payable" + } + }, + "Cuentas por pagar": { + "account_number": "23", + "account_type": "Payable", + "Cuentas corrientes comerciales": { + "account_number": "2305", + "account_type": "Payable" + }, + "A casa matriz": { + "account_number": "2310", + "account_type": "Payable" + }, + "A compa\u00f1\u00edas vinculadas": { + "account_number": "2315", + "account_type": "Payable" + }, + "A contratistas": { + "account_number": "2320", + "account_type": "Payable" + }, + "\u00d3rdenes de compra por utilizar": { + "account_number": "2330", + "account_type": "Payable" + }, + "Costos y gastos por pagar": { + "account_number": "2335", + "account_type": "Payable", + "is_group": 1 + }, + "Instalamentos por pagar": { + "account_number": "2340", + "account_type": "Payable" + }, + "Acreedores oficiales": { + "account_number": "2345", + "account_type": "Payable" + }, + "Regal\u00edas por pagar": { + "account_number": "2350", + "account_type": "Payable" + }, + "Deudas con accionistas o socios": { + "account_number": "2355", + "account_type": "Payable", + "is_group": 1 + }, + "Deudas con directores": { + "account_number": "2357", + "account_type": "Payable" + }, + "Dividendos o participaciones por pagar": { + "account_number": "2360", + "account_type": "Payable", + "is_group": 1 + }, + "Retenci\u00f3n en la fuente": { + "account_number": "2365", + "account_type": "Payable", + "is_group": 1 + }, + "Impuesto a las ventas retenido": { + "account_number": "2367", + "account_type": "Payable" + }, + "Impuesto de industria y comercio retenido": { + "account_number": "2368", + "account_type": "Payable" + }, + "Retenciones y aportes de n\u00f3mina": { + "account_number": "2370", + "account_type": "Payable", + "is_group": 1 + }, + "Cuotas por devolver": { + "account_number": "2375", + "account_type": "Payable" + }, + "Acreedores varios": { + "account_number": "2380", + "account_type": "Payable", + "is_group": 1 + } + }, + "Impuestos, grav\u00e1menes y tasas": { + "account_number": "24", + "account_type": "Tax", + "De renta y complementarios": { + "account_number": "2404", + "account_type": "Tax", + "is_group": 1 + }, + "Impuesto sobre las ventas por pagar": { + "account_number": "2408", + "account_type": "Tax" + }, + "De industria y comercio": { + "account_number": "2412", + "account_type": "Tax", + "is_group": 1 + }, + "A la propiedad ra\u00edz": { + "account_number": "2416", + "account_type": "Tax" + }, + "Derechos sobre instrumentos p\u00fablicos": { + "account_number": "2420", + "account_type": "Tax" + }, + "De valorizaci\u00f3n": { + "account_number": "2424", + "account_type": "Tax", + "is_group": 1 + }, + "De turismo": { + "account_number": "2428", + "account_type": "Tax" + }, + "Tasa por utilizaci\u00f3n de puertos": { + "account_number": "2432", + "account_type": "Tax" + }, + "De veh\u00edculos": { + "account_number": "2436", + "account_type": "Tax", + "is_group": 1 + }, + "De espect\u00e1culos p\u00fablicos": { + "account_number": "2440", + "account_type": "Tax" + }, + "De hidrocarburos y minas": { + "account_number": "2444", + "account_type": "Tax", + "is_group": 1 + }, + "Regal\u00edas e impuestos a la peque\u00f1a y mediana miner\u00eda": { + "account_number": "2448", + "account_type": "Tax" + }, + "A las exportaciones cafeteras": { + "account_number": "2452", + "account_type": "Tax" + }, + "A las importaciones": { + "account_number": "2456", + "account_type": "Tax" + }, + "Cuotas de fomento": { + "account_number": "2460", + "account_type": "Tax" + }, + "De licores, cervezas y cigarrillos": { + "account_number": "2464", + "account_type": "Tax", + "is_group": 1 + }, + "Al sacrificio de ganado": { + "account_number": "2468", + "account_type": "Tax" + }, + "Al azar y juegos": { + "account_number": "2472", + "account_type": "Tax" + }, + "Grav\u00e1menes y regal\u00edas por utilizaci\u00f3n del suelo": { + "account_number": "2476", + "account_type": "Tax" + }, + "Otros": { + "account_number": "2495", + "account_type": "Tax" + } + }, + "Obligaciones laborales": { + "account_number": "25", + "Salarios por pagar": { + "account_number": "2505" + }, + "Cesant\u00edas consolidadas": { + "account_number": "2510", + "is_group": 1 + }, + "Intereses sobre cesant\u00edas": { + "account_number": "2515" + }, + "Prima de servicios": { + "account_number": "2520" + }, + "Vacaciones consolidadas": { + "account_number": "2525" + }, + "Prestaciones extralegales": { + "account_number": "2530", + "is_group": 1 + }, + "Pensiones por pagar": { + "account_number": "2532" + }, + "Cuotas partes pensiones de jubilaci\u00f3n": { + "account_number": "2535" + }, + "Indemnizaciones laborales": { + "account_number": "2540" + } + }, + "Pasivos estimados y provisiones": { + "account_number": "26", + "Para costos y gastos": { + "account_number": "2605", + "is_group": 1 + }, + "Para obligaciones laborales": { + "account_number": "2610", + "is_group": 1 + }, + "Para obligaciones fiscales": { + "account_number": "2615", + "is_group": 1 + }, + "Pensiones de jubilaci\u00f3n": { + "account_number": "2620", + "is_group": 1 + }, + "Para obras de urbanismo": { + "account_number": "2625", + "is_group": 1 + }, + "Para mantenimiento y reparaciones": { + "account_number": "2630", + "is_group": 1 + }, + "Para contingencias": { + "account_number": "2635", + "is_group": 1 + }, + "Para obligaciones de garant\u00edas": { + "account_number": "2640" + }, + "Provisiones diversas": { + "account_number": "2695", + "is_group": 1 + } + }, + "Diferidos": { + "account_number": "27", + "Ingresos recibidos por anticipado": { + "account_number": "2705", + "is_group": 1 + }, + "Abonos diferidos": { + "account_number": "2710", + "is_group": 1 + }, + "Utilidad diferida en ventas a plazos": { + "account_number": "2715" + }, + "Cr\u00e9dito por correcci\u00f3n monetaria diferida": { + "account_number": "2720" + }, + "Impuestos diferidos": { + "account_number": "2725", + "is_group": 1 + } + }, + "Otros pasivos": { + "account_number": "28", + "Anticipos y avances recibidos": { + "account_number": "2805", + "is_group": 1 + }, + "Dep\u00f3sitos recibidos": { + "account_number": "2810", + "is_group": 1 + }, + "Ingresos recibidos para terceros": { + "account_number": "2815", + "is_group": 1 + }, + "Cuentas de operaci\u00f3n conjunta": { + "account_number": "2820" + }, + "Retenciones a terceros sobre contratos": { + "account_number": "2825", + "is_group": 1 + }, + "Embargos judiciales": { + "account_number": "2830", + "is_group": 1 + }, + "Acreedores del sistema": { + "account_number": "2835", + "is_group": 1 + }, + "Cuentas en participaci\u00f3n": { + "account_number": "2840" + }, + "Diversos": { + "account_number": "2895", + "is_group": 1 + } + }, + "Bonos y papeles comerciales": { + "account_number": "29", + "Bonos en circulaci\u00f3n": { + "account_number": "2905" + }, + "Bonos obligatoriamente convertibles en acciones": { + "account_number": "2910" + }, + "Papeles comerciales": { + "account_number": "2915" + }, + "Bonos pensionales": { + "account_number": "2920", + "is_group": 1 + }, + "T\u00edtulos pensionales": { + "account_number": "2925", + "is_group": 1 + } + } + }, + "Patrimonio": { + "account_number": "3", + "account_type": "Equity", + "root_type": "Equity", + "Capital social": { + "account_number": "31", + "account_type": "Equity", + "Capital suscrito y pagado": { + "account_number": "3105", + "account_type": "Equity", + "is_group": 1 + }, + "Aportes sociales": { + "account_number": "3115", + "account_type": "Equity", + "is_group": 1 + }, + "Capital asignado": { + "account_number": "3120", + "account_type": "Equity" + }, + "Inversi\u00f3n suplementaria al capital asignado": { + "account_number": "3125", + "account_type": "Equity" + }, + "Capital de personas naturales": { + "account_number": "3130", + "account_type": "Equity" + }, + "Aportes del Estado": { + "account_number": "3135", + "account_type": "Equity" + }, + "Fondo social": { + "account_number": "3140", + "account_type": "Equity" + } + }, + "Super\u00e1vit de capital": { + "account_number": "32", + "account_type": "Equity", + "Prima en colocaci\u00f3n de acciones, cuotas o partes de inter\u00e9s social": { + "account_number": "3205", + "account_type": "Equity", + "is_group": 1 + }, + "Donaciones": { + "account_number": "3210", + "account_type": "Equity", + "is_group": 1 + }, + "Cr\u00e9dito mercantil": { + "account_number": "3215", + "account_type": "Equity" + }, + "Know how": { + "account_number": "3220", + "account_type": "Equity" + }, + "Super\u00e1vit m\u00e9todo de participaci\u00f3n": { + "account_number": "3225", + "account_type": "Equity", + "is_group": 1 + } + }, + "Reservas": { + "account_number": "33", + "account_type": "Equity", + "Reservas obligatorias": { + "account_number": "3305", + "account_type": "Equity", + "is_group": 1 + }, + "Reservas estatutarias": { + "account_number": "3310", + "account_type": "Equity", + "is_group": 1 + }, + "Reservas ocasionales": { + "account_number": "3315", + "account_type": "Equity", + "is_group": 1 + } + }, + "Revalorizaci\u00f3n del patrimonio": { + "account_number": "34", + "account_type": "Equity", + "Ajustes por inflaci\u00f3n": { + "account_number": "3405", + "account_type": "Equity", + "is_group": 1 + }, + "Saneamiento fiscal": { + "account_number": "3410", + "account_type": "Equity" + }, + "Ajustes por inflaci\u00f3n Decreto 3019 de 1989": { + "account_number": "3415", + "account_type": "Equity" + } + }, + "Dividendos o participaciones decretados en acciones, cuotas o partes de inter\u00e9s social": { + "account_number": "35", + "account_type": "Equity", + "Dividendos decretados en acciones": { + "account_number": "3505", + "account_type": "Equity" + }, + "Participaciones decretadas en cuotas o partes de inter\u00e9s social": { + "account_number": "3510", + "account_type": "Equity" + } + }, + "Resultados del ejercicio": { + "account_number": "36", + "account_type": "Equity", + "Utilidad del ejercicio": { + "account_number": "3605", + "account_type": "Equity" + }, + "P\u00e9rdida del ejercicio": { + "account_number": "3610", + "account_type": "Equity" + } + }, + "Resultados de ejercicios anteriores": { + "account_number": "37", + "account_type": "Equity", + "Utilidades acumuladas": { + "account_number": "3705", + "account_type": "Equity" + }, + "P\u00e9rdidas acumuladas": { + "account_number": "3710", + "account_type": "Equity" + } + }, + "Super\u00e1vit por valorizaciones": { + "account_number": "38", + "account_type": "Equity", + "De inversiones": { + "account_number": "3805", + "account_type": "Equity", + "is_group": 1 + }, + "De propiedades, planta y equipo": { + "account_number": "3810", + "account_type": "Equity", + "is_group": 1 + }, + "De otros activos": { + "account_number": "3895", + "account_type": "Equity", + "is_group": 1 + } + } + }, + "Ingresos": { + "account_number": "4", + "account_type": "Income Account", + "root_type": "Income", + "Operacionales": { + "account_number": "41", + "account_type": "Income Account", + "Agricultura, ganader\u00eda, caza y silvicultura": { + "account_number": "4105", + "account_type": "Income Account", + "is_group": 1 + }, + "Pesca": { + "account_number": "4110", + "account_type": "Income Account", + "is_group": 1 + }, + "Explotaci\u00f3n de minas y canteras": { + "account_number": "4115", + "account_type": "Income Account", + "is_group": 1 + }, + "Industrias manufactureras": { + "account_number": "4120", + "account_type": "Income Account", + "is_group": 1 + }, + "Suministro de electricidad, gas y agua": { + "account_number": "4125", + "account_type": "Income Account", + "is_group": 1 + }, + "Construcci\u00f3n": { + "account_number": "4130", + "account_type": "Income Account", + "is_group": 1 + }, + "Comercio al por mayor y al por menor": { + "account_number": "4135", + "account_type": "Income Account", + "is_group": 1 + }, + "Hoteles y restaurantes": { + "account_number": "4140", + "account_type": "Income Account", + "is_group": 1 + }, + "Transporte, almacenamiento y comunicaciones": { + "account_number": "4145", + "account_type": "Income Account", + "is_group": 1 + }, + "Actividad financiera": { + "account_number": "4150", + "account_type": "Income Account", + "is_group": 1 + }, + "Actividades inmobiliarias, empresariales y de alquiler": { + "account_number": "4155", + "account_type": "Income Account", + "is_group": 1 + }, + "Ense\u00f1anza": { + "account_number": "4160", + "account_type": "Income Account", + "is_group": 1 + }, + "Servicios sociales y de salud": { + "account_number": "4165", + "account_type": "Income Account", + "is_group": 1 + }, + "Otras actividades de servicios comunitarios, sociales y personales": { + "account_number": "4170", + "account_type": "Income Account", + "is_group": 1 + }, + "Devoluciones en ventas (DB)": { + "account_number": "4175", + "account_type": "Income Account", + "is_group": 1 + } + }, + "No operacionales": { + "account_number": "42", + "account_type": "Income Account", + "Otras ventas": { + "account_number": "4205", + "account_type": "Income Account", + "is_group": 1 + }, + "Financieros": { + "account_number": "4210", + "account_type": "Income Account", + "is_group": 1 + }, + "Dividendos y participaciones": { + "account_number": "4215", + "account_type": "Income Account", + "is_group": 1 + }, + "Ingresos m\u00e9todo de participaci\u00f3n": { + "account_number": "4218", + "account_type": "Income Account", + "is_group": 1 + }, + "Arrendamientos": { + "account_number": "4220", + "account_type": "Income Account", + "is_group": 1 + }, + "Comisiones": { + "account_number": "4225", + "account_type": "Income Account", + "is_group": 1 + }, + "Honorarios": { + "account_number": "4230", + "account_type": "Income Account", + "is_group": 1 + }, + "Servicios": { + "account_number": "4235", + "account_type": "Income Account", + "is_group": 1 + }, + "Utilidad en venta de inversiones": { + "account_number": "4240", + "account_type": "Income Account", + "is_group": 1 + }, + "Utilidad en venta de propiedades, planta y equipo": { + "account_number": "4245", + "account_type": "Income Account", + "is_group": 1 + }, + "Utilidad en venta de otros bienes": { + "account_number": "4248", + "account_type": "Income Account", + "is_group": 1 + }, + "Recuperaciones": { + "account_number": "4250", + "account_type": "Income Account", + "is_group": 1 + }, + "Indemnizaciones": { + "account_number": "4255", + "account_type": "Income Account", + "is_group": 1 + }, + "Participaciones en concesiones": { + "account_number": "4260", + "account_type": "Income Account", + "is_group": 1 + }, + "Ingresos de ejercicios anteriores": { + "account_number": "4265", + "account_type": "Income Account", + "is_group": 1 + }, + "Devoluciones en otras ventas (DB)": { + "account_number": "4275", + "account_type": "Income Account", + "is_group": 1 + }, + "Diversos": { + "account_number": "4295", + "account_type": "Income Account", + "is_group": 1 + } + }, + "Ajustes por inflaci\u00f3n": { + "account_number": "47", + "account_type": "Income Account", + "Correcci\u00f3n monetaria": { + "account_number": "4705", + "account_type": "Income Account", + "is_group": 1 + } + } + }, + "Gastos": { + "account_number": "5", + "account_type": "Expense Account", + "root_type": "Expense", + "Operacionales de administraci\u00f3n": { + "account_number": "51", + "account_type": "Expense Account", + "Gastos de personal": { + "account_number": "5105", + "account_type": "Expense Account", + "is_group": 1 + }, + "Honorarios": { + "account_number": "5110", + "account_type": "Expense Account", + "is_group": 1 + }, + "Impuestos": { + "account_number": "5115", + "account_type": "Expense Account", + "is_group": 1 + }, + "Arrendamientos": { + "account_number": "5120", + "account_type": "Expense Account", + "is_group": 1 + }, + "Contribuciones y afiliaciones": { + "account_number": "5125", + "account_type": "Expense Account", + "is_group": 1 + }, + "Seguros": { + "account_number": "5130", + "account_type": "Expense Account", + "is_group": 1 + }, + "Servicios": { + "account_number": "5135", + "account_type": "Expense Account", + "is_group": 1 + }, + "Gastos legales": { + "account_number": "5140", + "account_type": "Expense Account", + "is_group": 1 + }, + "Mantenimiento y reparaciones": { + "account_number": "5145", + "account_type": "Expense Account", + "is_group": 1 + }, + "Adecuaci\u00f3n e instalaci\u00f3n": { + "account_number": "5150", + "account_type": "Expense Account", + "is_group": 1 + }, + "Gastos de viaje": { + "account_number": "5155", + "account_type": "Expense Account", + "is_group": 1 + }, + "Depreciaciones": { + "account_number": "5160", + "account_type": "Expense Account", + "is_group": 1 + }, + "Amortizaciones": { + "account_number": "5165", + "account_type": "Expense Account", + "is_group": 1 + }, + "Diversos": { + "account_number": "5195", + "account_type": "Expense Account", + "is_group": 1 + }, + "Provisiones": { + "account_number": "5199", + "account_type": "Expense Account", + "is_group": 1 + } + }, + "Operacionales de ventas": { + "account_number": "52", + "account_type": "Expense Account", + "Gastos de personal": { + "account_number": "5205", + "account_type": "Expense Account", + "is_group": 1 + }, + "Honorarios": { + "account_number": "5210", + "account_type": "Expense Account", + "is_group": 1 + }, + "Impuestos": { + "account_number": "5215", + "account_type": "Expense Account", + "is_group": 1 + }, + "Arrendamientos": { + "account_number": "5220", + "account_type": "Expense Account", + "is_group": 1 + }, + "Contribuciones y afiliaciones": { + "account_number": "5225", + "account_type": "Expense Account", + "is_group": 1 + }, + "Seguros": { + "account_number": "5230", + "account_type": "Expense Account", + "is_group": 1 + }, + "Servicios": { + "account_number": "5235", + "account_type": "Expense Account", + "is_group": 1 + }, + "Gastos legales": { + "account_number": "5240", + "account_type": "Expense Account", + "is_group": 1 + }, + "Mantenimiento y reparaciones": { + "account_number": "5245", + "account_type": "Expense Account", + "is_group": 1 + }, + "Adecuaci\u00f3n e instalaci\u00f3n": { + "account_number": "5250", + "account_type": "Expense Account", + "is_group": 1 + }, + "Gastos de viaje": { + "account_number": "5255", + "account_type": "Expense Account", + "is_group": 1 + }, + "Depreciaciones": { + "account_number": "5260", + "account_type": "Expense Account", + "is_group": 1 + }, + "Amortizaciones": { + "account_number": "5265", + "account_type": "Expense Account", + "is_group": 1 + }, + "Financieros-reajuste del sistema": { + "account_number": "5270", + "account_type": "Expense Account", + "is_group": 1 + }, + "P\u00e9rdidas m\u00e9todo de participaci\u00f3n": { + "account_number": "5275", + "account_type": "Expense Account", + "is_group": 1 + }, + "Diversos": { + "account_number": "5295", + "account_type": "Expense Account", + "is_group": 1 + }, + "Provisiones": { + "account_number": "5299", + "account_type": "Expense Account", + "is_group": 1 + } + }, + "No operacionales": { + "account_number": "53", + "account_type": "Expense Account", + "Financieros": { + "account_number": "5305", + "account_type": "Expense Account", + "is_group": 1 + }, + "P\u00e9rdida en venta y retiro de bienes": { + "account_number": "5310", + "account_type": "Expense Account", + "is_group": 1 + }, + "P\u00e9rdidas m\u00e9todo de participaci\u00f3n": { + "account_number": "5313", + "account_type": "Expense Account", + "is_group": 1 + }, + "Gastos extraordinarios": { + "account_number": "5315", + "account_type": "Expense Account", + "is_group": 1 + }, + "Gastos diversos": { + "account_number": "5395", + "account_type": "Expense Account", + "is_group": 1 + } + }, + "Impuesto de renta y complementarios": { + "account_number": "54", + "account_type": "Expense Account", + "Impuesto de renta y complementarios": { + "account_number": "5405", + "account_type": "Expense Account", + "is_group": 1 + } + }, + "Ganancias y p\u00e9rdidas": { + "account_number": "59", + "account_type": "Expense Account", + "Ganancias y p\u00e9rdidas": { + "account_number": "5905", + "account_type": "Expense Account", + "is_group": 1 + } + } + }, + "Costos de ventas": { + "account_number": "6", + "account_type": "Cost of Goods Sold", + "root_type": "Expense", + "Costo de ventas y de prestaci\u00f3n de servicios": { + "account_number": "61", + "account_type": "Cost of Goods Sold", + "Agricultura, ganader\u00eda, caza y silvicultura": { + "account_number": "6105", + "account_type": "Cost of Goods Sold", + "is_group": 1 + }, + "Pesca": { + "account_number": "6110", + "account_type": "Cost of Goods Sold", + "is_group": 1 + }, + "Explotaci\u00f3n de minas y canteras": { + "account_number": "6115", + "account_type": "Cost of Goods Sold", + "is_group": 1 + }, + "Industrias manufactureras": { + "account_number": "6120", + "account_type": "Cost of Goods Sold", + "is_group": 1 + }, + "Suministro de electricidad, gas y agua": { + "account_number": "6125", + "account_type": "Cost of Goods Sold", + "is_group": 1 + }, + "Construcci\u00f3n": { + "account_number": "6130", + "account_type": "Cost of Goods Sold", + "is_group": 1 + }, + "Comercio al por mayor y al por menor": { + "account_number": "6135", + "account_type": "Cost of Goods Sold", + "is_group": 1 + }, + "Hoteles y restaurantes": { + "account_number": "6140", + "account_type": "Cost of Goods Sold", + "is_group": 1 + }, + "Transporte, almacenamiento y comunicaciones": { + "account_number": "6145", + "account_type": "Cost of Goods Sold", + "is_group": 1 + }, + "Actividad financiera": { + "account_number": "6150", + "account_type": "Cost of Goods Sold", + "is_group": 1 + }, + "Actividades inmobiliarias, empresariales y de alquiler": { + "account_number": "6155", + "account_type": "Cost of Goods Sold", + "is_group": 1 + }, + "Ense\u00f1anza": { + "account_number": "6160", + "account_type": "Cost of Goods Sold", + "is_group": 1 + }, + "Servicios sociales y de salud": { + "account_number": "6165", + "account_type": "Cost of Goods Sold", + "is_group": 1 + }, + "Otras actividades de servicios comunitarios, sociales y personales": { + "account_number": "6170", + "account_type": "Cost of Goods Sold", + "is_group": 1 + } + }, + "Compras": { + "account_number": "62", + "account_type": "Cost of Goods Sold", + "De mercanc\u00edas": { + "account_number": "6205", + "account_type": "Cost of Goods Sold", + "is_group": 1 + }, + "De materias primas": { + "account_number": "6210", + "account_type": "Cost of Goods Sold", + "is_group": 1 + }, + "De materiales indirectos": { + "account_number": "6215", + "account_type": "Cost of Goods Sold", + "is_group": 1 + }, + "Compra de energ\u00eda": { + "account_number": "6220", + "account_type": "Cost of Goods Sold", + "is_group": 1 + }, + "Devoluciones en compras (CR)": { + "account_number": "6225", + "account_type": "Cost of Goods Sold", + "is_group": 1 + } + } + }, + "Costos de producci\u00f3n o de operaci\u00f3n": { + "account_number": "7", + "account_type": "Cost of Goods Sold", + "root_type": "Expense", + "Materia prima": { + "account_number": "71", + "account_type": "Cost of Goods Sold" + }, + "Mano de obra directa": { + "account_number": "72", + "account_type": "Cost of Goods Sold" + }, + "Costos indirectos": { + "account_number": "73", + "account_type": "Cost of Goods Sold" + }, + "Contratos de servicios": { + "account_number": "74", + "account_type": "Cost of Goods Sold" + } + }, + "Cuentas de orden deudoras": { + "account_number": "8", + "root_type": "Asset", + "Derechos contingentes": { + "account_number": "81", + "Bienes y valores entregados en custodia": { + "account_number": "8105", + "is_group": 1 + }, + "Bienes y valores entregados en garant\u00eda": { + "account_number": "8110", + "is_group": 1 + }, + "Bienes y valores en poder de terceros": { + "account_number": "8115", + "is_group": 1 + }, + "Litigios y/o demandas": { + "account_number": "8120", + "is_group": 1 + }, + "Promesas de compraventa": { + "account_number": "8125" + }, + "Diversas": { + "account_number": "8195", + "is_group": 1 + } + }, + "Deudoras fiscales": { + "account_number": "82" + }, + "Deudoras de control": { + "account_number": "83", + "Bienes recibidos en arrendamiento financiero": { + "account_number": "8305", + "is_group": 1 + }, + "T\u00edtulos de inversi\u00f3n no colocados": { + "account_number": "8310", + "is_group": 1 + }, + "Propiedades, planta y equipo totalmente depreciados, agotados y/o amortizados": { + "account_number": "8315", + "is_group": 1 + }, + "Cr\u00e9ditos a favor no utilizados": { + "account_number": "8320", + "is_group": 1 + }, + "Activos castigados": { + "account_number": "8325", + "is_group": 1 + }, + "T\u00edtulos de inversi\u00f3n amortizados": { + "account_number": "8330", + "is_group": 1 + }, + "Capitalizaci\u00f3n por revalorizaci\u00f3n de patrimonio": { + "account_number": "8335" + }, + "Otras cuentas deudoras de control": { + "account_number": "8395", + "is_group": 1 + }, + "Ajustes por inflaci\u00f3n activos": { + "account_number": "8399", + "is_group": 1 + } + }, + "Derechos contingentes por contra (CR)": { + "account_number": "84" + }, + "Deudoras fiscales por contra (CR)": { + "account_number": "85" + }, + "Deudoras de control por contra (CR)": { + "account_number": "86" + } + }, + "Cuentas de orden acreedoras": { + "account_number": "9", + "root_type": "Liability", + "Responsabilidades contingentes": { + "account_number": "91", + "Bienes y valores recibidos en custodia": { + "account_number": "9105", + "is_group": 1 + }, + "Bienes y valores recibidos en garant\u00eda": { + "account_number": "9110", + "is_group": 1 + }, + "Bienes y valores recibidos de terceros": { + "account_number": "9115", + "is_group": 1 + }, + "Litigios y/o demandas": { + "account_number": "9120", + "is_group": 1 + }, + "Promesas de compraventa": { + "account_number": "9125" + }, + "Contratos de administraci\u00f3n delegada": { + "account_number": "9130" + }, + "Cuentas en participaci\u00f3n": { + "account_number": "9135" + }, + "Otras responsabilidades contingentes": { + "account_number": "9195" + } + }, + "Acreedoras fiscales": { + "account_number": "92" + }, + "Acreedoras de control": { + "account_number": "93", + "Contratos de arrendamiento financiero": { + "account_number": "9305", + "is_group": 1 + }, + "Otras cuentas de orden acreedoras de control": { + "account_number": "9395", + "is_group": 1 + }, + "Ajustes por inflaci\u00f3n patrimonio": { + "account_number": "9399", + "is_group": 1 + } + }, + "Responsabilidades contingentes por contra (DB)": { + "account_number": "94" + }, + "Acreedoras fiscales por contra (DB)": { + "account_number": "95" + }, + "Acreedoras de control por contra (DB)": { + "account_number": "96" + } + } + } +} \ No newline at end of file From 93c0c26843ea640a4bf885d1f6fe552be7adf696 Mon Sep 17 00:00:00 2001 From: Lakshit Jain <108322669+ljain112@users.noreply.github.com> Date: Sun, 18 Jun 2023 22:25:28 +0530 Subject: [PATCH 33/89] fix: modify filters for account in journal entry (#35626) --- erpnext/accounts/doctype/journal_entry/journal_entry.js | 2 +- .../doctype/journal_entry_template/journal_entry_template.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/erpnext/accounts/doctype/journal_entry/journal_entry.js b/erpnext/accounts/doctype/journal_entry/journal_entry.js index b31cc3212e..6d9e3202f1 100644 --- a/erpnext/accounts/doctype/journal_entry/journal_entry.js +++ b/erpnext/accounts/doctype/journal_entry/journal_entry.js @@ -575,7 +575,7 @@ $.extend(erpnext.journal_entry, { }; if(!frm.doc.multi_currency) { $.extend(filters, { - account_currency: frappe.get_doc(":Company", frm.doc.company).default_currency + account_currency: ['in', [frappe.get_doc(":Company", frm.doc.company).default_currency, null]] }); } return { filters: filters }; diff --git a/erpnext/accounts/doctype/journal_entry_template/journal_entry_template.js b/erpnext/accounts/doctype/journal_entry_template/journal_entry_template.js index 5ebdf61db2..7d80754e7d 100644 --- a/erpnext/accounts/doctype/journal_entry_template/journal_entry_template.js +++ b/erpnext/accounts/doctype/journal_entry_template/journal_entry_template.js @@ -28,7 +28,7 @@ frappe.ui.form.on("Journal Entry Template", { if(!frm.doc.multi_currency) { $.extend(filters, { - account_currency: frappe.get_doc(":Company", frm.doc.company).default_currency + account_currency: ['in', [frappe.get_doc(":Company", frm.doc.company).default_currency, null]] }); } From 507c966aa7c516924626b7614d216feb6d947e59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?T=C3=BCrker=20Tunal=C4=B1?= Date: Sun, 18 Jun 2023 19:59:42 +0300 Subject: [PATCH 34/89] chore: Make material request title translatable (#35764) chore: Make material request title translatable --- erpnext/stock/doctype/material_request/material_request.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/stock/doctype/material_request/material_request.py b/erpnext/stock/doctype/material_request/material_request.py index 95c85da552..ee247fd093 100644 --- a/erpnext/stock/doctype/material_request/material_request.py +++ b/erpnext/stock/doctype/material_request/material_request.py @@ -115,7 +115,7 @@ class MaterialRequest(BuyingController): """Set title as comma separated list of items""" if not self.title: items = ", ".join([d.item_name for d in self.items][:3]) - self.title = _("{0} Request for {1}").format(self.material_request_type, items)[:100] + self.title = _("{0} Request for {1}").format(_(self.material_request_type), items)[:100] def on_submit(self): self.update_requested_qty() From d12c9b434e17651c2e4e93c48ef2bffa6ca5aba0 Mon Sep 17 00:00:00 2001 From: HENRY Florian Date: Sun, 18 Jun 2023 19:00:15 +0200 Subject: [PATCH 35/89] chore: fr translation lead vs prospect (#35697) chore: fr translation lead vs prospect --- erpnext/translations/fr.csv | 63 ++++++++++++++++++------------------- 1 file changed, 31 insertions(+), 32 deletions(-) diff --git a/erpnext/translations/fr.csv b/erpnext/translations/fr.csv index 35037fb5a5..bede718264 100644 --- a/erpnext/translations/fr.csv +++ b/erpnext/translations/fr.csv @@ -115,7 +115,7 @@ Add Customers,Ajouter des clients, Add Employees,Ajouter des employés, Add Item,Ajouter un Article, Add Items,Ajouter des articles, -Add Leads,Créer des Prospects, +Add Leads,Créer des Leads, Add Multiple Tasks,Ajouter plusieurs tâches, Add Row,Ajouter une Ligne, Add Sales Partners,Ajouter des partenaires commerciaux, @@ -658,8 +658,8 @@ Create Invoice,Créer une facture, Create Invoices,Créer des factures, Create Job Card,Créer une carte de travail, Create Journal Entry,Créer une entrée de journal, -Create Lead,Créer un Prospect, -Create Leads,Créer des Prospects, +Create Lead,Créer un Lead, +Create Leads,Créer des Lead, Create Maintenance Visit,Créer une visite de maintenance, Create Material Request,Créer une demande de matériel, Create Multiple,Créer plusieurs, @@ -1426,13 +1426,12 @@ Last Purchase Price,Dernier prix d'achat, Last Purchase Rate,Dernier Prix d'Achat, Latest,Dernier, Latest price updated in all BOMs,Prix les plus récents mis à jour dans toutes les nomenclatures, -Lead,Prospect, -Lead Count,Nombre de Prospects, +Lead Count,Nombre de Lead, Lead Owner,Responsable du Prospect, -Lead Owner cannot be same as the Lead,Le Responsable du Prospect ne peut pas être identique au Prospect, +Lead Owner cannot be same as the Lead,Le Responsable du Prospect ne peut pas être identique au Lead, Lead Time Days,Jours de Délai, Lead to Quotation,Du Prospect au Devis, -"Leads help you get business, add all your contacts and more as your leads","Les prospects vous aident à obtenir des contrats, ajoutez tous vos contacts et plus dans votre liste de prospects", +"Leads help you get business, add all your contacts and more as your leads","Les lead vous aident à obtenir des contrats, ajoutez tous vos contacts et plus dans votre liste de lead", Learn,Apprendre, Leave Approval Notification,Notification d'approbation de congés, Leave Blocked,Laisser Verrouillé, @@ -1596,7 +1595,7 @@ Middle Name,Deuxième Nom, Middle Name (Optional),Deuxième Prénom (Optionnel), Min Amt can not be greater than Max Amt,Min Amt ne peut pas être supérieur à Max Amt, Min Qty can not be greater than Max Qty,Qté Min ne peut pas être supérieure à Qté Max, -Minimum Lead Age (Days),Âge Minimum du Prospect (Jours), +Minimum Lead Age (Days),Âge Minimum du lead (Jours), Miscellaneous Expenses,Charges Diverses, Missing Currency Exchange Rates for {0},Taux de Change Manquant pour {0}, Missing email template for dispatch. Please set one in Delivery Settings.,Modèle de courrier électronique manquant pour l'envoi. Veuillez en définir un dans les paramètres de livraison., @@ -1676,7 +1675,7 @@ New {0} pricing rules are created,De nouvelles règles de tarification {0} sont Newsletters,Newsletters, Newspaper Publishers,Éditeurs de journaux, Next,Suivant, -Next Contact By cannot be same as the Lead Email Address,Prochain Contact Par ne peut être identique à l’Adresse Email du Prospect, +Next Contact By cannot be same as the Lead Email Address,Prochain Contact Par ne peut être identique à l’Adresse Email du Lead, Next Contact Date cannot be in the past,La Date de Prochain Contact ne peut pas être dans le passé, Next Steps,Prochaines étapes, No Action,Pas d'action, @@ -1808,9 +1807,9 @@ Operation Time must be greater than 0 for Operation {0},Temps de l'Opération do Operations,Opérations, Operations cannot be left blank,Les opérations ne peuvent pas être laissées vides, Opp Count,Compte d'Opportunités, -Opp/Lead %,Opp / Prospect %, +Opp/Lead %,Opp / Lead %, Opportunities,Opportunités, -Opportunities by lead source,Opportunités par source de plomb, +Opportunities by lead source,Opportunités par source de lead, Opportunity,Opportunité, Opportunity Amount,Montant de l'opportunité, Optional Holiday List not set for leave period {0},Une liste de vacances facultative n'est pas définie pour la période de congé {0}, @@ -2007,7 +2006,7 @@ Please mention Basic and HRA component in Company,Veuillez mentionner les compos Please mention Round Off Account in Company,Veuillez indiquer le Compte d’Arrondi de la Société, Please mention Round Off Cost Center in Company,Veuillez indiquer le Centre de Coûts d’Arrondi de la Société, Please mention no of visits required,Veuillez indiquer le nb de visites requises, -Please mention the Lead Name in Lead {0},Veuillez mentionner le nom du Prospect dans le Prospect {0}, +Please mention the Lead Name in Lead {0},Veuillez mentionner le nom du Lead dans le Lead {0}, Please pull items from Delivery Note,Veuillez récupérer les articles des Bons de Livraison, Please register the SIREN number in the company information file,Veuillez enregistrer le numéro SIREN dans la fiche d'information de la société, Please remove this Invoice {0} from C-Form {1},Veuillez retirez cette Facture {0} du C-Form {1}, @@ -2277,7 +2276,7 @@ Queued for replacing the BOM. It may take a few minutes.,En file d'attente pour Queued for updating latest price in all Bill of Materials. It may take a few minutes.,Mise à jour des prix les plus récents dans toutes les nomenclatures en file d'attente. Cela peut prendre quelques minutes., Quick Journal Entry,Écriture Rapide dans le Journal, Quot Count,Compte de Devis, -Quot/Lead %,Devis / Prospects %, +Quot/Lead %,Devis / Lead %, Quotation,Devis, Quotation {0} is cancelled,Devis {0} est annulée, Quotation {0} not of type {1},Le devis {0} n'est pas du type {1}, @@ -2285,7 +2284,7 @@ Quotations,Devis, "Quotations are proposals, bids you have sent to your customers","Les devis sont des propositions, offres que vous avez envoyées à vos clients", Quotations received from Suppliers.,Devis reçus des Fournisseurs., Quotations: ,Devis :, -Quotes to Leads or Customers.,Devis de Prospects ou Clients., +Quotes to Leads or Customers.,Devis de Lead ou Clients., RFQs are not allowed for {0} due to a scorecard standing of {1},Les Appels d'Offres ne sont pas autorisés pour {0} en raison d'une note de {1} sur la fiche d'évaluation, Range,Plage, Rate,Prix, @@ -3122,7 +3121,7 @@ Total(Amt),Total (Mnt), Total(Qty),Total (Qté), Traceability,Traçabilité, Traceback,Retraçage, -Track Leads by Lead Source.,Suivre les prospects par sources, +Track Leads by Lead Source.,Suivre les leads par sources, Training,Formation, Training Event,Événement de formation, Training Events,Événements de formation, @@ -3243,8 +3242,8 @@ View Chart of Accounts,Voir le plan comptable, View Fees Records,Voir les honoraires, View Form,Voir le formulaire, View Lab Tests,Afficher les tests de laboratoire, -View Leads,Voir Prospects, -View Ledger,Voir le Livre, +View Leads,Voir Lead, +View Ledger,Voir le Journal, View Now,Voir maintenant, View a list of all the help videos,Afficher la liste de toutes les vidéos d'aide, View in Cart,Voir Panier, @@ -3677,7 +3676,7 @@ Couldn't Set Service Level Agreement {0}.,Impossible de définir le contrat de s Country,Pays, Country Code in File does not match with country code set up in the system,Le code de pays dans le fichier ne correspond pas au code de pays configuré dans le système, Create New Contact,Créer un nouveau contact, -Create New Lead,Créer une nouvelle piste, +Create New Lead,Créer une nouvelle lead, Create Pick List,Créer une liste de choix, Create Quality Inspection for Item {0},Créer un contrôle qualité pour l'article {0}, Creating Accounts...,Création de comptes ..., @@ -3784,7 +3783,7 @@ Group Warehouses cannot be used in transactions. Please change the value of {0}, Help,Aidez-moi, Help Article,Article d’Aide, "Helps you keep tracks of Contracts based on Supplier, Customer and Employee","Vous aide à garder une trace des contrats en fonction du fournisseur, client et employé", -Helps you manage appointments with your leads,Vous aide à gérer les rendez-vous avec vos prospects, +Helps you manage appointments with your leads,Vous aide à gérer les rendez-vous avec vos leads, Home,Accueil, IBAN is not valid,IBAN n'est pas valide, Import Data from CSV / Excel files.,Importer des données à partir de fichiers CSV / Excel, @@ -3880,7 +3879,7 @@ Only expired allocation can be cancelled,Seule l'allocation expirée peut être Only users with the {0} role can create backdated leave applications,Seuls les utilisateurs avec le rôle {0} peuvent créer des demandes de congé antidatées, Open,Ouvert, Open Contact,Contact ouvert, -Open Lead,Ouvrir le Prospect, +Open Lead,Ouvrir le Lead, Opening and Closing,Ouverture et fermeture, Operating Cost as per Work Order / BOM,Coût d'exploitation selon l'ordre de fabrication / nomenclature, Order Amount,Montant de la commande, @@ -3926,7 +3925,7 @@ Please select another payment method. Stripe does not support transactions in cu Please select the customer.,S'il vous plaît sélectionner le client., Please set a Supplier against the Items to be considered in the Purchase Order.,Veuillez définir un fournisseur par rapport aux articles à prendre en compte dans la Commande d'Achat., Please set account heads in GST Settings for Compnay {0},Définissez les en-têtes de compte dans les paramètres de la TPS pour le service {0}., -Please set an email id for the Lead {0},Veuillez définir un identifiant de messagerie pour le prospect {0}., +Please set an email id for the Lead {0},Veuillez définir un identifiant de messagerie pour le lead {0}., Please set default UOM in Stock Settings,Veuillez définir l'UdM par défaut dans les paramètres de stock, Please set filter based on Item or Warehouse due to a large amount of entries.,Veuillez définir le filtre en fonction de l'article ou de l'entrepôt en raison d'une grande quantité d'entrées., Please set up the Campaign Schedule in the Campaign {0},Configurez le calendrier de la campagne dans la campagne {0}., @@ -5600,7 +5599,7 @@ Call Log,Journal d'appel, Received By,Reçu par, Caller Information,Informations sur l'appelant, Contact Name,Nom du Contact, -Lead Name,Nom du Prospect, +Lead Name,Nom du Lead, Ringing,Sonnerie, Missed,Manqué, Call Duration in seconds,Durée d'appel en secondes, @@ -5668,7 +5667,7 @@ Fulfilment Terms and Conditions,Termes et conditions d'exécution, Contract Template Fulfilment Terms,Conditions d'exécution du modèle de contrat, Email Campaign,Campagne Email, Email Campaign For ,Campagne d'email pour, -Lead is an Organization,Le prospect est une organisation, +Lead is an Organization,Le Lead est une organisation, CRM-LEAD-.YYYY.-,CRM-LEAD-.YYYY.-, Person Name,Nom de la Personne, Lost Quotation,Devis Perdu, @@ -5683,7 +5682,7 @@ Next Contact Date,Date du Prochain Contact, Ends On,Se termine le, Address & Contact,Adresse & Contact, Mobile No.,N° Mobile., -Lead Type,Type de Prospect, +Lead Type,Type de Lead, Channel Partner,Partenaire de Canal, Consultant,Consultant, Market Segment,Part de Marché, @@ -5706,7 +5705,7 @@ Opportunity Lost Reason,Raison perdue, Potential Sales Deal,Ventes Potentielles, CRM-OPP-.YYYY.-,CRM-OPP-YYYY.-, Opportunity From,Opportunité De, -Customer / Lead Name,Nom du Client / Prospect, +Customer / Lead Name,Nom du Client / Lead, Opportunity Type,Type d'Opportunité, Converted By,Converti par, Sales Stage,Stade de vente, @@ -5716,7 +5715,7 @@ To Discuss,À Discuter, With Items,Avec Articles, Probability (%),Probabilité (%), Contact Info,Information du Contact, -Customer / Lead Address,Adresse du Client / Prospect, +Customer / Lead Address,Adresse du Lead / Prospect, Contact Mobile No,N° de Portable du Contact, Enter name of campaign if source of enquiry is campaign,Entrez le nom de la campagne si la source de l'enquête est une campagne, Opportunity Date,Date d'Opportunité, @@ -7643,7 +7642,7 @@ Campaign Schedules,Horaires de campagne, Buyer of Goods and Services.,Acheteur des Biens et Services., CUST-.YYYY.-,CUST-.YYYY.-, Default Company Bank Account,Compte bancaire d'entreprise par défaut, -From Lead,Du Prospect, +From Lead,Du Lead, Account Manager,Gestionnaire de compte, Allow Sales Invoice Creation Without Sales Order,Autoriser la création de factures de vente sans commande client, Allow Sales Invoice Creation Without Delivery Note,Autoriser la création de factures de vente sans bon de livraison, @@ -7670,7 +7669,7 @@ Installation Date,Date d'Installation, Installation Time,Temps d'Installation, Installation Note Item,Article Remarque d'Installation, Installed Qty,Qté Installée, -Lead Source,Source du Prospect, +Lead Source,Source du Lead, Period Start Date,Date de début de la période, Period End Date,Date de fin de la période, Cashier,Caissier, @@ -8515,8 +8514,8 @@ Item-wise Sales Register,Registre des Ventes par Article, Items To Be Requested,Articles À Demander, Reserved,Réservé, Itemwise Recommended Reorder Level,Renouvellement Recommandé par Article, -Lead Details,Détails du Prospect, -Lead Owner Efficiency,Efficacité des Responsables des Prospects, +Lead Details,Détails du Lead, +Lead Owner Efficiency,Efficacité des Responsables des Leads, Loan Repayment and Closure,Remboursement et clôture de prêts, Loan Security Status,État de la sécurité du prêt, Lost Opportunity,Occasion perdue, @@ -9205,7 +9204,7 @@ Time Required (In Mins),Temps requis (en minutes), From Posting Date,À partir de la date de publication, To Posting Date,À la date de publication, No records found,Aucun enregistrement trouvé, -Customer/Lead Name,Nom du client / prospect, +Customer/Lead Name,Nom du client / lead, Unmarked Days,Jours non marqués, Jan,Jan, Feb,fév, @@ -9469,7 +9468,7 @@ Row {0}: Loan Security {1} added multiple times,Ligne {0}: Garantie de prêt {1} Row #{0}: Child Item should not be a Product Bundle. Please remove Item {1} and Save,Ligne n ° {0}: l'élément enfant ne doit pas être un ensemble de produits. Veuillez supprimer l'élément {1} et enregistrer, Credit limit reached for customer {0},Limite de crédit atteinte pour le client {0}, Could not auto create Customer due to the following missing mandatory field(s):,Impossible de créer automatiquement le client en raison du ou des champs obligatoires manquants suivants:, -Please create Customer from Lead {0}.,Veuillez créer un client à partir du prospect {0}., +Please create Customer from Lead {0}.,Veuillez créer un client à partir du lead {0}., Mandatory Missing,Obligatoire manquant, Please set Payroll based on in Payroll settings,Veuillez définir la paie en fonction des paramètres de paie, Additional Salary: {0} already exist for Salary Component: {1} for period {2} and {3},Salaire supplémentaire: {0} existe déjà pour le composant de salaire: {1} pour la période {2} et {3}, From 2a24423ad2cb6733359fc2b45f39e676e6f9ec24 Mon Sep 17 00:00:00 2001 From: Abhinav Raut Date: Sun, 18 Jun 2023 23:11:52 +0530 Subject: [PATCH 36/89] fix: loan interest accrual date (#35695) fix: loan interest accrual date --------- Co-authored-by: Abhinav Raut Co-authored-by: Deepesh Garg --- .../doctype/loan_interest_accrual/loan_interest_accrual.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/erpnext/loan_management/doctype/loan_interest_accrual/loan_interest_accrual.py b/erpnext/loan_management/doctype/loan_interest_accrual/loan_interest_accrual.py index ced63942ba..ab4ea4cb6b 100644 --- a/erpnext/loan_management/doctype/loan_interest_accrual/loan_interest_accrual.py +++ b/erpnext/loan_management/doctype/loan_interest_accrual/loan_interest_accrual.py @@ -293,8 +293,8 @@ def get_last_accrual_date(loan, posting_date): # interest for last interest accrual date is already booked, so add 1 day last_disbursement_date = get_last_disbursement_date(loan, posting_date) - if last_disbursement_date and getdate(last_disbursement_date) > getdate( - last_interest_accrual_date + if last_disbursement_date and getdate(last_disbursement_date) > add_days( + getdate(last_interest_accrual_date), 1 ): last_interest_accrual_date = last_disbursement_date From 78fbd6452b69097804446de61d799ae0c7a5a0ce Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Mon, 19 Jun 2023 09:14:43 +0530 Subject: [PATCH 37/89] fix: unsupported operand type(s) for //: 'float' and 'NoneType' for POS Barcode search (#35710) * fix: unsupported operand type(s) for //: 'float' and 'NoneType' for POS Barcode search (#35710) (cherry picked from commit 58a6bbcf6d95f59821484ff29b585c10529a0fe4) # Conflicts: # erpnext/selling/page/point_of_sale/point_of_sale.py * chore: resolve conflicts --------- Co-authored-by: Vishal Dhayagude Co-authored-by: Deepesh Garg --- erpnext/selling/page/point_of_sale/point_of_sale.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/selling/page/point_of_sale/point_of_sale.py b/erpnext/selling/page/point_of_sale/point_of_sale.py index 62b3105872..fd2338174c 100644 --- a/erpnext/selling/page/point_of_sale/point_of_sale.py +++ b/erpnext/selling/page/point_of_sale/point_of_sale.py @@ -65,7 +65,7 @@ def search_by_term(search_term, warehouse, price_list): "item_code": item_code, "batch_no": batch_no, }, - fields=["uom", "stock_uom", "currency", "price_list_rate", "batch_no"], + fields=["uom", "currency", "price_list_rate", "batch_no"], ) def __sort(p): From 9d27a25e5f2335386402f96f83a10729695b20c8 Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Mon, 19 Jun 2023 11:04:50 +0530 Subject: [PATCH 38/89] fix: Allocated amount validation for other party types (#35741) * fix: Allocated amount validation for other party types * chore: Validation for return allocations * chore: minor typo --------- Co-authored-by: anandbaburajan --- .../doctype/payment_entry/payment_entry.py | 27 ++++++++++++------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/erpnext/accounts/doctype/payment_entry/payment_entry.py b/erpnext/accounts/doctype/payment_entry/payment_entry.py index b6d3e5a30e..b9be5ec724 100644 --- a/erpnext/accounts/doctype/payment_entry/payment_entry.py +++ b/erpnext/accounts/doctype/payment_entry/payment_entry.py @@ -151,6 +151,19 @@ class PaymentEntry(AccountsController): if self.payment_type == "Internal Transfer": return + if self.party_type in ("Customer", "Supplier"): + self.validate_allocated_amount_with_latest_data() + else: + fail_message = _("Row #{0}: Allocated Amount cannot be greater than outstanding amount.") + for d in self.get("references"): + if (flt(d.allocated_amount)) > 0 and flt(d.allocated_amount) > flt(d.outstanding_amount): + frappe.throw(fail_message.format(d.idx)) + + # Check for negative outstanding invoices as well + if flt(d.allocated_amount) < 0 and flt(d.allocated_amount) < flt(d.outstanding_amount): + frappe.throw(fail_message.format(d.idx)) + + def validate_allocated_amount_with_latest_data(self): latest_references = get_outstanding_reference_documents( { "posting_date": self.posting_date, @@ -168,7 +181,7 @@ class PaymentEntry(AccountsController): d = frappe._dict(d) latest_lookup.update({(d.voucher_type, d.voucher_no): d}) - for d in self.get("references").copy(): + for d in self.get("references"): latest = latest_lookup.get((d.reference_doctype, d.reference_name)) # The reference has already been fully paid @@ -187,18 +200,14 @@ class PaymentEntry(AccountsController): ).format(d.reference_doctype, d.reference_name) ) - d.outstanding_amount = latest.outstanding_amount - fail_message = _("Row #{0}: Allocated Amount cannot be greater than outstanding amount.") - if (flt(d.allocated_amount)) > 0: - if flt(d.allocated_amount) > flt(d.outstanding_amount): - frappe.throw(fail_message.format(d.idx)) + if (flt(d.allocated_amount)) > 0 and flt(d.allocated_amount) > flt(latest.outstanding_amount): + frappe.throw(fail_message.format(d.idx)) # Check for negative outstanding invoices as well - if flt(d.allocated_amount) < 0: - if flt(d.allocated_amount) < flt(d.outstanding_amount): - frappe.throw(fail_message.format(d.idx)) + if flt(d.allocated_amount) < 0 and flt(d.allocated_amount) < flt(latest.outstanding_amount): + frappe.throw(fail_message.format(d.idx)) def delink_advance_entry_references(self): for reference in self.references: From 4f941ac5c07a60aa52d1a1ddfc37e55ec3bea886 Mon Sep 17 00:00:00 2001 From: s-aga-r Date: Mon, 19 Jun 2023 18:26:14 +0530 Subject: [PATCH 39/89] perf: index `purpose` in `Stock Entry` --- erpnext/stock/doctype/stock_entry/stock_entry.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.json b/erpnext/stock/doctype/stock_entry/stock_entry.json index fe42b1f135..564c380017 100644 --- a/erpnext/stock/doctype/stock_entry/stock_entry.json +++ b/erpnext/stock/doctype/stock_entry/stock_entry.json @@ -125,7 +125,8 @@ "oldfieldname": "purpose", "oldfieldtype": "Select", "options": "Material Issue\nMaterial Receipt\nMaterial Transfer\nMaterial Transfer for Manufacture\nMaterial Consumption for Manufacture\nManufacture\nRepack\nSend to Subcontractor", - "read_only": 1 + "read_only": 1, + "search_index": 1 }, { "fieldname": "company", @@ -678,7 +679,7 @@ "index_web_pages_for_search": 1, "is_submittable": 1, "links": [], - "modified": "2023-06-16 14:59:10.917235", + "modified": "2023-06-19 18:23:40.748114", "modified_by": "Administrator", "module": "Stock", "name": "Stock Entry", From c1da3ddbbf5e57a0f96733ef05682056051f9ebd Mon Sep 17 00:00:00 2001 From: Anand Baburajan Date: Mon, 19 Jun 2023 19:53:05 +0530 Subject: [PATCH 40/89] fix: fix get outstanding invoices btn and add get outstanding orders btn (#35776) * fix: fix get outstanding invoices btn and add get outstanding orders btn * chore: remove unnecessary arg --- .../doctype/payment_entry/payment_entry.js | 32 +++++- .../doctype/payment_entry/payment_entry.json | 23 ++-- .../doctype/payment_entry/payment_entry.py | 103 ++++++++++-------- 3 files changed, 102 insertions(+), 56 deletions(-) diff --git a/erpnext/accounts/doctype/payment_entry/payment_entry.js b/erpnext/accounts/doctype/payment_entry/payment_entry.js index 2843824934..9f55ba1167 100644 --- a/erpnext/accounts/doctype/payment_entry/payment_entry.js +++ b/erpnext/accounts/doctype/payment_entry/payment_entry.js @@ -612,7 +612,7 @@ frappe.ui.form.on('Payment Entry', { frm.events.set_unallocated_amount(frm); }, - get_outstanding_invoice: function(frm) { + get_outstanding_invoices_or_orders: function(frm, get_outstanding_invoices, get_orders_to_be_billed) { const today = frappe.datetime.get_today(); const fields = [ {fieldtype:"Section Break", label: __("Posting Date")}, @@ -642,12 +642,29 @@ frappe.ui.form.on('Payment Entry', { {fieldtype:"Check", label: __("Allocate Payment Amount"), fieldname:"allocate_payment_amount", default:1}, ]; + let btn_text = ""; + + if (get_outstanding_invoices) { + btn_text = "Get Outstanding Invoices"; + } + else if (get_orders_to_be_billed) { + btn_text = "Get Outstanding Orders"; + } + frappe.prompt(fields, function(filters){ frappe.flags.allocate_payment_amount = true; frm.events.validate_filters_data(frm, filters); frm.doc.cost_center = filters.cost_center; - frm.events.get_outstanding_documents(frm, filters); - }, __("Filters"), __("Get Outstanding Documents")); + frm.events.get_outstanding_documents(frm, filters, get_outstanding_invoices, get_orders_to_be_billed); + }, __("Filters"), __(btn_text)); + }, + + get_outstanding_invoices: function(frm) { + frm.events.get_outstanding_invoices_or_orders(frm, true, false); + }, + + get_outstanding_orders: function(frm) { + frm.events.get_outstanding_invoices_or_orders(frm, false, true); }, validate_filters_data: function(frm, filters) { @@ -673,7 +690,7 @@ frappe.ui.form.on('Payment Entry', { } }, - get_outstanding_documents: function(frm, filters) { + get_outstanding_documents: function(frm, filters, get_outstanding_invoices, get_orders_to_be_billed) { frm.clear_table("references"); if(!frm.doc.party) { @@ -697,6 +714,13 @@ frappe.ui.form.on('Payment Entry', { args[key] = filters[key]; } + if (get_outstanding_invoices) { + args["get_outstanding_invoices"] = true; + } + else if (get_orders_to_be_billed) { + args["get_orders_to_be_billed"] = true; + } + frappe.flags.allocate_payment_amount = filters['allocate_payment_amount']; return frappe.call({ diff --git a/erpnext/accounts/doctype/payment_entry/payment_entry.json b/erpnext/accounts/doctype/payment_entry/payment_entry.json index 3927ecae43..6224d4038d 100644 --- a/erpnext/accounts/doctype/payment_entry/payment_entry.json +++ b/erpnext/accounts/doctype/payment_entry/payment_entry.json @@ -48,7 +48,8 @@ "base_received_amount", "base_received_amount_after_tax", "section_break_14", - "get_outstanding_invoice", + "get_outstanding_invoices", + "get_outstanding_orders", "references", "section_break_34", "total_allocated_amount", @@ -355,12 +356,6 @@ "fieldtype": "Section Break", "label": "Reference" }, - { - "depends_on": "eval:doc.docstatus==0", - "fieldname": "get_outstanding_invoice", - "fieldtype": "Button", - "label": "Get Outstanding Invoice" - }, { "fieldname": "references", "fieldtype": "Table", @@ -728,12 +723,24 @@ "fieldname": "section_break_60", "fieldtype": "Section Break", "hide_border": 1 + }, + { + "depends_on": "eval:doc.docstatus==0", + "fieldname": "get_outstanding_invoices", + "fieldtype": "Button", + "label": "Get Outstanding Invoices" + }, + { + "depends_on": "eval:doc.docstatus==0", + "fieldname": "get_outstanding_orders", + "fieldtype": "Button", + "label": "Get Outstanding Orders" } ], "index_web_pages_for_search": 1, "is_submittable": 1, "links": [], - "modified": "2023-02-14 04:52:30.478523", + "modified": "2023-06-19 11:38:04.387219", "modified_by": "Administrator", "module": "Accounts", "name": "Payment Entry", diff --git a/erpnext/accounts/doctype/payment_entry/payment_entry.py b/erpnext/accounts/doctype/payment_entry/payment_entry.py index b9be5ec724..1f23fe1d54 100644 --- a/erpnext/accounts/doctype/payment_entry/payment_entry.py +++ b/erpnext/accounts/doctype/payment_entry/payment_entry.py @@ -172,6 +172,8 @@ class PaymentEntry(AccountsController): "payment_type": self.payment_type, "party": self.party, "party_account": self.paid_from if self.payment_type == "Receive" else self.paid_to, + "get_outstanding_invoices": True, + "get_orders_to_be_billed": True, } ) @@ -196,7 +198,7 @@ class PaymentEntry(AccountsController): ): frappe.throw( _( - "{0} {1} has already been partly paid. Please use the 'Get Outstanding Invoice' button to get the latest outstanding amount." + "{0} {1} has already been partly paid. Please use the 'Get Outstanding Invoice' or the 'Get Outstanding Orders' button to get the latest outstanding amounts." ).format(d.reference_doctype, d.reference_name) ) @@ -1356,62 +1358,75 @@ def get_outstanding_reference_documents(args): condition += " and company = {0}".format(frappe.db.escape(args.get("company"))) common_filter.append(ple.company == args.get("company")) - outstanding_invoices = get_outstanding_invoices( - args.get("party_type"), - args.get("party"), - args.get("party_account"), - common_filter=common_filter, - posting_date=posting_and_due_date, - min_outstanding=args.get("outstanding_amt_greater_than"), - max_outstanding=args.get("outstanding_amt_less_than"), - accounting_dimensions=accounting_dimensions_filter, - ) - - outstanding_invoices = split_invoices_based_on_payment_terms(outstanding_invoices) - - for d in outstanding_invoices: - d["exchange_rate"] = 1 - if party_account_currency != company_currency: - if d.voucher_type in frappe.get_hooks("invoice_doctypes"): - d["exchange_rate"] = frappe.db.get_value(d.voucher_type, d.voucher_no, "conversion_rate") - elif d.voucher_type == "Journal Entry": - d["exchange_rate"] = get_exchange_rate( - party_account_currency, company_currency, d.posting_date - ) - if d.voucher_type in ("Purchase Invoice"): - d["bill_no"] = frappe.db.get_value(d.voucher_type, d.voucher_no, "bill_no") - - # Get all SO / PO which are not fully billed or against which full advance not paid - orders_to_be_billed = [] - orders_to_be_billed = get_orders_to_be_billed( - args.get("posting_date"), - args.get("party_type"), - args.get("party"), - args.get("company"), - party_account_currency, - company_currency, - filters=args, - ) - - # Get negative outstanding sales /purchase invoices + outstanding_invoices = [] negative_outstanding_invoices = [] - if args.get("party_type") != "Employee" and not args.get("voucher_no"): - negative_outstanding_invoices = get_negative_outstanding_invoices( + + if args.get("get_outstanding_invoices"): + outstanding_invoices = get_outstanding_invoices( args.get("party_type"), args.get("party"), args.get("party_account"), + common_filter=common_filter, + posting_date=posting_and_due_date, + min_outstanding=args.get("outstanding_amt_greater_than"), + max_outstanding=args.get("outstanding_amt_less_than"), + accounting_dimensions=accounting_dimensions_filter, + ) + + outstanding_invoices = split_invoices_based_on_payment_terms(outstanding_invoices) + + for d in outstanding_invoices: + d["exchange_rate"] = 1 + if party_account_currency != company_currency: + if d.voucher_type in frappe.get_hooks("invoice_doctypes"): + d["exchange_rate"] = frappe.db.get_value(d.voucher_type, d.voucher_no, "conversion_rate") + elif d.voucher_type == "Journal Entry": + d["exchange_rate"] = get_exchange_rate( + party_account_currency, company_currency, d.posting_date + ) + if d.voucher_type in ("Purchase Invoice"): + d["bill_no"] = frappe.db.get_value(d.voucher_type, d.voucher_no, "bill_no") + + # Get negative outstanding sales /purchase invoices + if args.get("party_type") != "Employee" and not args.get("voucher_no"): + negative_outstanding_invoices = get_negative_outstanding_invoices( + args.get("party_type"), + args.get("party"), + args.get("party_account"), + party_account_currency, + company_currency, + condition=condition, + ) + + # Get all SO / PO which are not fully billed or against which full advance not paid + orders_to_be_billed = [] + if args.get("get_orders_to_be_billed"): + orders_to_be_billed = get_orders_to_be_billed( + args.get("posting_date"), + args.get("party_type"), + args.get("party"), + args.get("company"), party_account_currency, company_currency, - condition=condition, + filters=args, ) data = negative_outstanding_invoices + outstanding_invoices + orders_to_be_billed if not data: + if args.get("get_outstanding_invoices") and args.get("get_orders_to_be_billed"): + ref_document_type = "invoices or orders" + elif args.get("get_outstanding_invoices"): + ref_document_type = "invoices" + elif args.get("get_orders_to_be_billed"): + ref_document_type = "orders" + frappe.msgprint( _( - "No outstanding invoices found for the {0} {1} which qualify the filters you have specified." - ).format(_(args.get("party_type")).lower(), frappe.bold(args.get("party"))) + "No outstanding {0} found for the {1} {2} which qualify the filters you have specified." + ).format( + ref_document_type, _(args.get("party_type")).lower(), frappe.bold(args.get("party")) + ) ) return data From b3d565c91faca2b06d6814a6ea69e0191b267b7e Mon Sep 17 00:00:00 2001 From: Gursheen Anand Date: Mon, 19 Jun 2023 19:54:03 +0530 Subject: [PATCH 41/89] feat: Provision to send Accounts Receivable Reports using Process Statement of Accounts Issue #35707 --- .../process_statement_of_accounts.html | 2 +- .../process_statement_of_accounts.js | 14 + .../process_statement_of_accounts.json | 67 ++- .../process_statement_of_accounts.py | 191 ++++++--- .../accounts_receivable.html | 399 ++++++++++-------- 5 files changed, 429 insertions(+), 244 deletions(-) diff --git a/erpnext/accounts/doctype/process_statement_of_accounts/process_statement_of_accounts.html b/erpnext/accounts/doctype/process_statement_of_accounts/process_statement_of_accounts.html index 03abc93e0b..5307ccb193 100644 --- a/erpnext/accounts/doctype/process_statement_of_accounts/process_statement_of_accounts.html +++ b/erpnext/accounts/doctype/process_statement_of_accounts/process_statement_of_accounts.html @@ -1,6 +1,6 @@
- {% if letter_head %} + {% if letter_head.content %}
{{ letter_head.content }}

{% endif %} diff --git a/erpnext/accounts/doctype/process_statement_of_accounts/process_statement_of_accounts.js b/erpnext/accounts/doctype/process_statement_of_accounts/process_statement_of_accounts.js index 7dd5ef36f2..cec48c1d56 100644 --- a/erpnext/accounts/doctype/process_statement_of_accounts/process_statement_of_accounts.js +++ b/erpnext/accounts/doctype/process_statement_of_accounts/process_statement_of_accounts.js @@ -65,6 +65,20 @@ frappe.ui.form.on('Process Statement Of Accounts', { frm.set_value('to_date', frappe.datetime.get_today()); } }, + report: function(frm){ + let filters = { + 'company': frm.doc.company, + } + if(frm.doc.report == 'Accounts Receivable'){ + filters['account_type'] = 'Receivable'; + } + frm.set_query("account", function() { + return { + filters: filters + }; + }); + + }, customer_collection: function(frm){ frm.set_value('collection_name', ''); if(frm.doc.customer_collection){ diff --git a/erpnext/accounts/doctype/process_statement_of_accounts/process_statement_of_accounts.json b/erpnext/accounts/doctype/process_statement_of_accounts/process_statement_of_accounts.json index e23620fd4e..70e810439c 100644 --- a/erpnext/accounts/doctype/process_statement_of_accounts/process_statement_of_accounts.json +++ b/erpnext/accounts/doctype/process_statement_of_accounts/process_statement_of_accounts.json @@ -6,17 +6,24 @@ "editable_grid": 1, "engine": "InnoDB", "field_order": [ + "report", "section_break_11", "from_date", + "posting_date", "company", "account", "group_by", "cost_center", + "territory", "column_break_14", "to_date", "finance_book", "currency", "project", + "payment_terms_template", + "sales_partner", + "sales_person", + "based_on_payment_terms", "section_break_3", "customer_collection", "collection_name", @@ -67,14 +74,14 @@ "reqd": 1 }, { - "depends_on": "eval:doc.enable_auto_email == 0;", + "depends_on": "eval:(doc.enable_auto_email == 0 && doc.report == 'General Ledger');", "fieldname": "from_date", "fieldtype": "Date", "label": "From Date", "mandatory_depends_on": "eval:doc.frequency == '';" }, { - "depends_on": "eval:doc.enable_auto_email == 0;", + "depends_on": "eval:(doc.enable_auto_email == 0 && doc.report == 'General Ledger');", "fieldname": "to_date", "fieldtype": "Date", "label": "To Date", @@ -87,6 +94,7 @@ "options": "PSOA Cost Center" }, { + "depends_on": "eval: (doc.report == 'General Ledger');", "fieldname": "project", "fieldtype": "Table MultiSelect", "label": "Project", @@ -104,7 +112,7 @@ { "fieldname": "section_break_11", "fieldtype": "Section Break", - "label": "General Ledger Filters" + "label": "Report Filters" }, { "fieldname": "column_break_14", @@ -164,12 +172,14 @@ }, { "default": "Group by Voucher (Consolidated)", + "depends_on": "eval:(doc.report == 'General Ledger');", "fieldname": "group_by", "fieldtype": "Select", "label": "Group By", "options": "\nGroup by Voucher\nGroup by Voucher (Consolidated)" }, { + "depends_on": "eval: (doc.report == 'General Ledger');", "fieldname": "currency", "fieldtype": "Link", "label": "Currency", @@ -297,6 +307,7 @@ }, { "default": "0", + "depends_on": "eval: (doc.report == 'General Ledger');", "fieldname": "show_net_values_in_party_account", "fieldtype": "Check", "label": "Show Net Values in Party Account" @@ -310,10 +321,58 @@ { "fieldname": "column_break_ocfq", "fieldtype": "Column Break" + }, + { + "fieldname": "report", + "fieldtype": "Select", + "label": "Report", + "options": "General Ledger\nAccounts Receivable" + }, + { + "default": "Today", + "depends_on": "eval:(doc.report == 'Accounts Receivable');", + "fieldname": "posting_date", + "fieldtype": "Date", + "label": "Posting Date" + }, + { + "depends_on": "eval: (doc.report == 'Accounts Receivable');", + "fieldname": "payment_terms_template", + "fieldtype": "Link", + "label": "Payment Terms Template", + "options": "Payment Terms Template" + }, + { + "depends_on": "eval: (doc.report == 'Accounts Receivable');", + "fieldname": "sales_partner", + "fieldtype": "Link", + "label": "Sales Partner", + "options": "Sales Partner" + }, + { + "depends_on": "eval: (doc.report == 'Accounts Receivable');", + "fieldname": "sales_person", + "fieldtype": "Link", + "label": "Sales Person", + "options": "Sales Person" + }, + { + "depends_on": "eval: (doc.report == 'Accounts Receivable');", + "fieldname": "territory", + "fieldtype": "Link", + "label": "Territory", + "options": "Territory" + }, + { + "default": "0", + "depends_on": "eval:(doc.report == 'Accounts Receivable');", + "fieldname": "based_on_payment_terms", + "fieldtype": "Check", + "label": "Based On Payment Terms" } ], "links": [], - "modified": "2023-04-26 12:46:43.645455", + "modified": "2023-06-19 18:37:10.040570", "modified_by": "Administrator", "module": "Accounts", "name": "Process Statement Of Accounts", diff --git a/erpnext/accounts/doctype/process_statement_of_accounts/process_statement_of_accounts.py b/erpnext/accounts/doctype/process_statement_of_accounts/process_statement_of_accounts.py index 67dbe09d0d..db186d81a2 100644 --- a/erpnext/accounts/doctype/process_statement_of_accounts/process_statement_of_accounts.py +++ b/erpnext/accounts/doctype/process_statement_of_accounts/process_statement_of_accounts.py @@ -15,6 +15,7 @@ from frappe.www.printview import get_print_style from erpnext import get_company_currency from erpnext.accounts.party import get_party_account_currency +from erpnext.accounts.report.accounts_receivable.accounts_receivable import execute as get_ar_soa from erpnext.accounts.report.accounts_receivable_summary.accounts_receivable_summary import ( execute as get_ageing, ) @@ -43,29 +44,10 @@ class ProcessStatementOfAccounts(Document): def get_report_pdf(doc, consolidated=True): statement_dict = {} ageing = "" - base_template_path = "frappe/www/printview.html" - template_path = ( - "erpnext/accounts/doctype/process_statement_of_accounts/process_statement_of_accounts.html" - ) for entry in doc.customers: if doc.include_ageing: - ageing_filters = frappe._dict( - { - "company": doc.company, - "report_date": doc.to_date, - "ageing_based_on": doc.ageing_based_on, - "range1": 30, - "range2": 60, - "range3": 90, - "range4": 120, - "customer": entry.customer, - } - ) - col1, ageing = get_ageing(ageing_filters) - - if ageing: - ageing[0]["ageing_based_on"] = doc.ageing_based_on + ageing = set_ageing(doc, entry) tax_id = frappe.get_doc("Customer", entry.customer).tax_id presentation_currency = ( @@ -73,60 +55,25 @@ def get_report_pdf(doc, consolidated=True): or doc.currency or get_company_currency(doc.company) ) - if doc.letter_head: - from frappe.www.printview import get_letter_head - letter_head = get_letter_head(doc, 0) + filters = get_common_filters(doc) - filters = frappe._dict( - { - "from_date": doc.from_date, - "to_date": doc.to_date, - "company": doc.company, - "finance_book": doc.finance_book if doc.finance_book else None, - "account": [doc.account] if doc.account else None, - "party_type": "Customer", - "party": [entry.customer], - "party_name": [entry.customer_name] if entry.customer_name else None, - "presentation_currency": presentation_currency, - "group_by": doc.group_by, - "currency": doc.currency, - "cost_center": [cc.cost_center_name for cc in doc.cost_center], - "project": [p.project_name for p in doc.project], - "show_opening_entries": 0, - "include_default_book_entries": 0, - "tax_id": tax_id if tax_id else None, - "show_net_values_in_party_account": doc.show_net_values_in_party_account, - } - ) - col, res = get_soa(filters) + if doc.report == "General Ledger": + filters.update(get_gl_filters(doc, entry, tax_id, presentation_currency)) + else: + filters.update(get_ar_filters(doc, entry)) - for x in [0, -2, -1]: - res[x]["account"] = res[x]["account"].replace("'", "") + if doc.report == "General Ledger": + col, res = get_soa(filters) + for x in [0, -2, -1]: + res[x]["account"] = res[x]["account"].replace("'", "") + if len(res) == 3: + continue + else: + ar_res = get_ar_soa(filters) + col, res = ar_res[0], ar_res[1] - if len(res) == 3: - continue - - html = frappe.render_template( - template_path, - { - "filters": filters, - "data": res, - "ageing": ageing[0] if (doc.include_ageing and ageing) else None, - "letter_head": letter_head if doc.letter_head else None, - "terms_and_conditions": frappe.db.get_value( - "Terms and Conditions", doc.terms_and_conditions, "terms" - ) - if doc.terms_and_conditions - else None, - }, - ) - - html = frappe.render_template( - base_template_path, - {"body": html, "css": get_print_style(), "title": "Statement For " + entry.customer}, - ) - statement_dict[entry.customer] = html + statement_dict[entry.customer] = get_html(doc, filters, entry, col, res, ageing) if not bool(statement_dict): return False @@ -140,6 +87,110 @@ def get_report_pdf(doc, consolidated=True): return statement_dict +def set_ageing(doc, entry): + ageing_filters = frappe._dict( + { + "company": doc.company, + "report_date": doc.to_date, + "ageing_based_on": doc.ageing_based_on, + "range1": 30, + "range2": 60, + "range3": 90, + "range4": 120, + "customer": entry.customer, + } + ) + col1, ageing = get_ageing(ageing_filters) + + if ageing: + ageing[0]["ageing_based_on"] = doc.ageing_based_on + + return ageing + + +def get_common_filters(doc): + return frappe._dict( + { + "company": doc.company, + "finance_book": doc.finance_book if doc.finance_book else None, + "account": [doc.account] if doc.account else None, + "cost_center": [cc.cost_center_name for cc in doc.cost_center], + } + ) + + +def get_gl_filters(doc, entry, tax_id, presentation_currency): + return { + "from_date": doc.from_date, + "to_date": doc.to_date, + "party_type": "Customer", + "party": [entry.customer], + "party_name": [entry.customer_name] if entry.customer_name else None, + "presentation_currency": presentation_currency, + "group_by": doc.group_by, + "currency": doc.currency, + "project": [p.project_name for p in doc.project], + "show_opening_entries": 0, + "include_default_book_entries": 0, + "tax_id": tax_id if tax_id else None, + "show_net_values_in_party_account": doc.show_net_values_in_party_account, + } + + +def get_ar_filters(doc, entry): + return { + "report_date": doc.posting_date if doc.posting_date else None, + "customer_name": entry.customer, + "payment_terms_template": doc.payment_terms_template if doc.payment_terms_template else None, + "sales_partner": doc.sales_partner if doc.sales_partner else None, + "sales_person": doc.sales_person if doc.sales_person else None, + "territory": doc.territory if doc.territory else None, + "based_on_payment_terms": doc.based_on_payment_terms, + "report_name": "Accounts Receivable", + "ageing_based_on": doc.ageing_based_on, + "range1": 30, + "range2": 60, + "range3": 90, + "range4": 120, + } + + +def get_html(doc, filters, entry, col, res, ageing): + base_template_path = "frappe/www/printview.html" + template_path = ( + "erpnext/accounts/doctype/process_statement_of_accounts/process_statement_of_accounts.html" + if doc.report == "General Ledger" + else "erpnext/accounts/report/accounts_receivable/accounts_receivable.html" + ) + + if doc.letter_head: + from frappe.www.printview import get_letter_head + + letter_head = get_letter_head(doc, 0) + + html = frappe.render_template( + template_path, + { + "filters": filters, + "data": res, + "report": {"report_name": doc.report, "columns": col}, + "ageing": ageing[0] if (doc.include_ageing and ageing) else None, + "letter_head": letter_head if doc.letter_head else None, + "terms_and_conditions": frappe.db.get_value( + "Terms and Conditions", doc.terms_and_conditions, "terms" + ) + if doc.terms_and_conditions + else None, + }, + ) + + html = frappe.render_template( + base_template_path, + {"body": html, "css": get_print_style(), "title": "Statement For " + entry.customer}, + ) + return html + + def get_customers_based_on_territory_or_customer_group(customer_collection, collection_name): fields_dict = { "Customer Group": "customer_group", diff --git a/erpnext/accounts/report/accounts_receivable/accounts_receivable.html b/erpnext/accounts/report/accounts_receivable/accounts_receivable.html index f2bf9424f7..07e1896292 100644 --- a/erpnext/accounts/report/accounts_receivable/accounts_receivable.html +++ b/erpnext/accounts/report/accounts_receivable/accounts_receivable.html @@ -8,51 +8,56 @@ } -

{%= __(report.report_name) %}

+

{{ _(report.report_name) }}

- {% if (filters.customer_name) { %} - {%= filters.customer_name %} - {% } else { %} - {%= filters.customer || filters.supplier %} - {% } %} + {% if (filters.customer_name) %} + {{ filters.customer_name }} + {% else %} + {{ filters.customer ~ filters.supplier }} + {% endif %}

- {% if (filters.tax_id) { %} - {%= __("Tax Id: ")%} {%= filters.tax_id %} - {% } %} + {% if (filters.tax_id) %} + {{ _("Tax Id: ") }}{{ filters.tax_id }} + {% endif %}
- {%= __(filters.ageing_based_on) %} - {%= __("Until") %} - {%= frappe.datetime.str_to_user(filters.report_date) %} + {{ _(filters.ageing_based_on) }} + {{ _("Until") }} + {{ frappe.format(filters.report_date, 'Date') }}
- {% if(filters.payment_terms) { %} - {%= __("Payment Terms") %}: {%= filters.payment_terms %} - {% } %} + {% if(filters.payment_terms) %} + {{ _("Payment Terms") }}: {{ filters.payment_terms }} + {% endif %}
- {% if(filters.credit_limit) { %} - {%= __("Credit Limit") %}: {%= format_currency(filters.credit_limit) %} - {% } %} + {% if(filters.credit_limit) %} + {{ _("Credit Limit") }}: {{ frappe.utils.fmt_money(filters.credit_limit) }} + {% endif %}
- {% if(filters.show_future_payments) { %} - {% var balance_row = data.slice(-1).pop(); - var start = report.columns.findIndex((elem) => (elem.fieldname == 'age')); - var range1 = report.columns[start].label; - var range2 = report.columns[start+1].label; - var range3 = report.columns[start+2].label; - var range4 = report.columns[start+3].label; - var range5 = report.columns[start+4].label; - var range6 = report.columns[start+5].label; - %} - {% if(balance_row) { %} + {% if(filters.show_future_payments) %} + {% set balance_row = data.slice(-1).pop() %} + {% for i in report.columns %} + {% if i.fieldname == 'age' %} + {% set elem = i %} + {% endif %} + {% endfor %} + {% set start = report.columns.findIndex(elem) %} + {% set range1 = report.columns[start].label %} + {% set range2 = report.columns[start+1].label %} + {% set range3 = report.columns[start+2].label %} + {% set range4 = report.columns[start+3].label %} + {% set range5 = report.columns[start+4].label %} + {% set range6 = report.columns[start+5].label %} + + {% if(balance_row) %} - + @@ -66,42 +71,42 @@ - - - - - - - - + + + + + + + + - + - + @@ -109,10 +114,10 @@ - + @@ -120,168 +125,224 @@ + {{ frappe.utils.fmt_money(flt(balance_row["outstanding"] - balance_row[("future_amount")]), data[data.length-1]["currency"]) }}
(Amount in {%= data[0]["currency"] || "" %})(Amount in {{ data[0]["currency"] ~ "" }})
{%= __(" ") %}{%= __(range1) %}{%= __(range2) %}{%= __(range3) %}{%= __(range4) %}{%= __(range5) %}{%= __(range6) %}{%= __("Total") %}{{ _(" ") }}{{ _(range1) }}{{ _(range2) }}{{ _(range3) }}{{ _(range4) }}{{ _(range5) }}{{ _(range6) }}{{ _("Total") }}
{%= __("Total Outstanding") %}{{ _("Total Outstanding") }} - {%= format_number(balance_row["age"], null, 2) %} + {{ format_number(balance_row["age"], null, 2) }} - {%= format_currency(balance_row["range1"], data[data.length-1]["currency"]) %} + {{ frappe.utils.fmt_money(balance_row["range1"], data[data.length-1]["currency"]) }} - {%= format_currency(balance_row["range2"], data[data.length-1]["currency"]) %} + {{ frappe.utils.fmt_money(balance_row["range2"], data[data.length-1]["currency"]) }} - {%= format_currency(balance_row["range3"], data[data.length-1]["currency"]) %} + {{ frappe.utils.fmt_money(balance_row["range3"], data[data.length-1]["currency"]) }} - {%= format_currency(balance_row["range4"], data[data.length-1]["currency"]) %} + {{ frappe.utils.fmt_money(balance_row["range4"], data[data.length-1]["currency"]) }} - {%= format_currency(balance_row["range5"], data[data.length-1]["currency"]) %} + {{ frappe.utils.fmt_money(balance_row["range5"], data[data.length-1]["currency"]) }} - {%= format_currency(flt(balance_row["outstanding"]), data[data.length-1]["currency"]) %} + {{ frappe.utils.fmt_money(flt(balance_row["outstanding"]), data[data.length-1]["currency"]) }}
{%= __("Future Payments") %}{{ _("Future Payments") }} - {%= format_currency(flt(balance_row[("future_amount")]), data[data.length-1]["currency"]) %} + {{ frappe.utils.fmt_money(flt(balance_row[("future_amount")]), data[data.length-1]["currency"]) }}
- {% } %} - {% } %} + {% endif %} + {% endif %} - {% if(report.report_name === "Accounts Receivable" || report.report_name === "Accounts Payable") { %} - - + {% if(report.report_name == "Accounts Receivable" or report.report_name == "Accounts Payable") %} + + - {% if(report.report_name === "Accounts Receivable" && filters.show_sales_person) { %} - - - {% } else { %} - - {% } %} - {% if(!filters.show_future_payments) { %} - - {% } %} - - {% if(!filters.show_future_payments) { %} - - - {% } %} - - {% if(filters.show_future_payments) { %} - {% if(report.report_name === "Accounts Receivable") { %} - - {% } %} - - - - {% } %} - {% } else { %} - - - - - - {% } %} + {% if(report.report_name == "Accounts Receivable" and filters.show_sales_person) %} + + + {% else %} + + {% endif %} + {% if not(filters.show_future_payments) %} + + {% endif %} + + {% if not(filters.show_future_payments) %} + + + {% endif %} + + {% if(filters.show_future_payments) %} + {% if(report.report_name == "Accounts Receivable") %} + + {% endif %} + + + + {% endif %} + {% else %} + + + + + + {% endif %} - {% for(var i=0, l=data.length; i - {% if(report.report_name === "Accounts Receivable" || report.report_name === "Accounts Payable") { %} - {% if(data[i]["party"]) { %} - - + {% if(report.report_name == "Accounts Receivable" or report.report_name == "Accounts Payable") %} + {% if(data[i]["party"]) %} + + - {% if(report.report_name === "Accounts Receivable" && filters.show_sales_person) { %} - - {% } %} + {% if(report.report_name == "Accounts Receivable" and filters.show_sales_person) %} + + {% endif %} - {% if(!filters.show_future_payments) { %} + {% if not (filters.show_future_payments) %} - {% } %} + {% endif %} + {{ frappe.utils.fmt_money(data[i]["invoiced"], currency=data[i]["currency"]) }} - {% if(!filters.show_future_payments) { %} + {% if not(filters.show_future_payments) %} + {{ frappe.utils.fmt_money(data[i]["paid"], currency=data[i]["currency"]) }} - {% } %} + {{ frappe.utils.fmt_money(data[i]["credit_note"], currency=data[i]["currency"]) }} + {% endif %} + {{ frappe.utils.fmt_money(data[i]["outstanding"], currency=data[i]["currency"]) }} - {% if(filters.show_future_payments) { %} - {% if(report.report_name === "Accounts Receivable") { %} + {% if(filters.show_future_payments) %} + {% if(report.report_name == "Accounts Receivable") %} - {% } %} - - - - {% } %} - {% } else { %} + {{ data[i]["po_no"] }} + {% endif %} + + + + {% endif %} + {% else %} - {% if(!filters.show_future_payments) { %} + {% if not(filters.show_future_payments) %} - {% } %} - {% if(report.report_name === "Accounts Receivable" && filters.show_sales_person) { %} + {% endif %} + {% if(report.report_name == "Accounts Receivable" and filters.show_sales_person) %} - {% } %} + {% endif %} - + + {{ frappe.utils.fmt_money(data[i]["invoiced"], data[i]["currency"]) }} - {% if(!filters.show_future_payments) { %} + {% if not(filters.show_future_payments) %} - - {% } %} + {{ frappe.utils.fmt_money(data[i]["paid"], currency=data[i]["currency"]) }} + + {% endif %} + {{ frappe.utils.fmt_money(data[i]["outstanding"], currency=data[i]["currency"]) }} - {% if(filters.show_future_payments) { %} - {% if(report.report_name === "Accounts Receivable") { %} + {% if(filters.show_future_payments) %} + {% if(report.report_name == "Accounts Receivable") %} - {% } %} - - - - {% } %} - {% } %} - {% } else { %} - {% if(data[i]["party"]|| " ") { %} - {% if(!data[i]["is_total_row"]) { %} + {{ data[i]["po_no"] }} + {% endif %} + + + + {% endif %} + {% endif %} + {% else %} + {% if(data[i]["party"] or " ") %} + {% if not(data[i]["is_total_row"]) %} - {% } else { %} - - {% } %} - - - - - {% } %} - {% } %} + {% else %} + + {% endif %} + + + + + {% endif %} + {% endif %} - {% } %} + {% endfor %} + + + + + + + +
{%= __("Date") %}{%= __("Age (Days)") %}{{ _("Date") }}{{ _("Age (Days)") }}{%= __("Reference") %}{%= __("Sales Person") %}{%= __("Reference") %}{%= (filters.customer || filters.supplier) ? __("Remarks"): __("Party") %}{%= __("Invoiced Amount") %}{%= __("Paid Amount") %}{%= report.report_name === "Accounts Receivable" ? __('Credit Note') : __('Debit Note') %}{%= __("Outstanding Amount") %}{%= __("Customer LPO No.") %}{%= __("Future Payment Ref") %}{%= __("Future Payment Amount") %}{%= __("Remaining Balance") %}{%= (filters.customer || filters.supplier) ? __("Remarks"): __("Party") %}{%= __("Total Invoiced Amount") %}{%= __("Total Paid Amount") %}{%= report.report_name === "Accounts Receivable Summary" ? __('Credit Note Amount') : __('Debit Note Amount') %}{%= __("Total Outstanding Amount") %}{{ _("Reference") }}{{ _("Sales Person") }}{{ _("Reference") }} + {% if (filters.customer or filters.supplier or filters.customer_name) %} + {{ _("Remarks") }} + {% else %} + {{ _("Party") }} + {% endif %} + {{ _("Invoiced Amount") }}{{ _("Paid Amount") }} + {% if report.report_name == "Accounts Receivable" %} + {{ _('Credit Note') }} + {% else %} + {{ _('Debit Note') }} + {% endif %} + {{ _("Outstanding Amount") }}{{ _("Customer LPO No.") }}{{ _("Future Payment Ref") }}{{ _("Future Payment Amount") }}{{ _("Remaining Balance") }} + {% if (filters.customer or filters.supplier or filters.customer_name) %} + {{ _("Remarks")}} + {% else %} + {{ _("Party") }} + {% endif %} + {{ _("Total Invoiced Amount") }}{{ _("Total Paid Amount") }} + {% if report.report_name == "Accounts Receivable Summary" %} + {{ _('Credit Note Amount') }} + {% else %} + {{ _('Debit Note Amount') }} + {% endif %} + {{ _("Total Outstanding Amount") }}
{%= frappe.datetime.str_to_user(data[i]["posting_date"]) %}{%= data[i]["age"] %}{{ (data[i]["posting_date"]) }}{{ data[i]["age"] }} - {% if(!filters.show_future_payments) { %} - {%= data[i]["voucher_type"] %} + {% if not(filters.show_future_payments) %} + {{ data[i]["voucher_type"] }}
- {% } %} - {%= data[i]["voucher_no"] %} + {% endif %} + {{ data[i]["voucher_no"] }}
{%= data[i]["sales_person"] %}{{ data[i]["sales_person"] }} - {% if(!(filters.customer || filters.supplier)) { %} - {%= data[i]["party"] %} - {% if(data[i]["customer_name"] && data[i]["customer_name"] != data[i]["party"]) { %} -
{%= data[i]["customer_name"] %} - {% } else if(data[i]["supplier_name"] != data[i]["party"]) { %} -
{%= data[i]["supplier_name"] %} - {% } %} - {% } %} + {% if(not(filters.customer or filters.supplier or filters.customer_name)) %} + {{ data[i]["party"] }} + {% if(data[i]["customer_name"] and data[i]["customer_name"] != data[i]["party"]) %} +
{{ data[i]["customer_name"] }} + {% elif(data[i]["supplier_name"] != data[i]["party"]) %} +
{{ data[i]["supplier_name"] }} + {% endif %} + {% endif %}
{% if data[i]["remarks"] %} - {%= __("Remarks") %}: - {%= data[i]["remarks"] %} - {% } %} + {{ _("Remarks") }}: + {{ data[i]["remarks"] }} + {% endif %}
- {%= format_currency(data[i]["invoiced"], data[i]["currency"]) %} - {%= format_currency(data[i]["paid"], data[i]["currency"]) %} - {%= format_currency(data[i]["credit_note"], data[i]["currency"]) %} - {%= format_currency(data[i]["outstanding"], data[i]["currency"]) %} - {%= data[i]["po_no"] %}{%= data[i]["future_ref"] %}{%= format_currency(data[i]["future_amount"], data[i]["currency"]) %}{%= format_currency(data[i]["remaining_balance"], data[i]["currency"]) %}{{ data[i]["future_ref"] }}{{ frappe.utils.fmt_money(data[i]["future_amount"], currency=data[i]["currency"]) }}{{ frappe.utils.fmt_money(data[i]["remaining_balance"], currency=data[i]["currency"]) }}{%= __("Total") %}{{ _("Total") }} - {%= format_currency(data[i]["invoiced"], data[i]["currency"] ) %} - {%= format_currency(data[i]["paid"], data[i]["currency"]) %}{%= format_currency(data[i]["credit_note"], data[i]["currency"]) %} {{ frappe.utils.fmt_money(data[i]["credit_note"], currency=data[i]["currency"]) }} - {%= format_currency(data[i]["outstanding"], data[i]["currency"]) %} - {%= data[i]["po_no"] %}{%= data[i]["future_ref"] %}{%= format_currency(data[i]["future_amount"], data[i]["currency"]) %}{%= format_currency(data[i]["remaining_balance"], data[i]["currency"]) %}{{ data[i]["future_ref"] }}{{ frappe.utils.fmt_money(data[i]["future_amount"], currency=data[i]["currency"]) }}{{ frappe.utils.fmt_money(data[i]["remaining_balance"], currency=data[i]["currency"]) }} - {% if(!(filters.customer || filters.supplier)) { %} - {%= data[i]["party"] %} - {% if(data[i]["customer_name"] && data[i]["customer_name"] != data[i]["party"]) { %} -
{%= data[i]["customer_name"] %} - {% } else if(data[i]["supplier_name"] != data[i]["party"]) { %} -
{%= data[i]["supplier_name"] %} - {% } %} - {% } %} -
{%= __("Remarks") %}: - {%= data[i]["remarks"] %} + {% if(not(filters.customer | filters.supplier)) %} + {{ data[i]["party"] }} + {% if(data[i]["customer_name"] and data[i]["customer_name"] != data[i]["party"]) %} +
{{ data[i]["customer_name"] }} + {% elif(data[i]["supplier_name"] != data[i]["party"]) %} +
{{ data[i]["supplier_name"] }} + {% endif %} + {% endif %} +
{{ _("Remarks") }}: + {{ data[i]["remarks"] }}
{%= __("Total") %}{%= format_currency(data[i]["invoiced"], data[i]["currency"]) %}{%= format_currency(data[i]["paid"], data[i]["currency"]) %}{%= format_currency(data[i]["credit_note"], data[i]["currency"]) %}{%= format_currency(data[i]["outstanding"], data[i]["currency"]) %}{{ _("Total") }}{{ frappe.utils.fmt_money(data[i]["invoiced"], currency=data[i]["currency"]) }}{{ frappe.utils.fmt_money(data[i]["paid"], currency=data[i]["currency"]) }}{{ frappe.utils.fmt_money(data[i]["credit_note"], currency=data[i]["currency"]) }}{{ frappe.utils.fmt_money(data[i]["outstanding"], currency=data[i]["currency"]) }}
{{ frappe.utils.fmt_money(data|sum(attribute="invoiced"), currency=data[0]["currency"]) }}{{ frappe.utils.fmt_money(data|sum(attribute="paid"), currency=data[0]["currency"]) }}{{ frappe.utils.fmt_money(data|sum(attribute="credit_note"), currency=data[0]["currency"]) }}{{ frappe.utils.fmt_money(data|sum(attribute="outstanding"), currency=data[0]["currency"]) }}
-

{{ __("Printed On ") }}{%= frappe.datetime.str_to_user(frappe.datetime.get_datetime_as_string()) %}

+
+ {% if ageing %} +

{{ _("Ageing Report based on ") }} {{ ageing.ageing_based_on }} + {{ _("up to " ) }} {{ frappe.format(filters.report_date, 'Date')}} +

+ + + + + + + + + + + + + + + + + +
30 Days60 Days90 Days120 Days
{{ frappe.utils.fmt_money(ageing.range1, currency=data[0]["currency"]) }}{{ frappe.utils.fmt_money(ageing.range2, currency=data[0]["currency"]) }}{{ frappe.utils.fmt_money(ageing.range3, currency=data[0]["currency"]) }}{{ frappe.utils.fmt_money(ageing.range4, currency=data[0]["currency"]) }}
+ {% endif %} +

{{ _("Printed On ") }}{{ frappe.utils.now() }}

From 4fbff2095447f12e6941d39b156b50fa4f1c7b80 Mon Sep 17 00:00:00 2001 From: Smit Vora Date: Mon, 19 Jun 2023 21:14:42 +0530 Subject: [PATCH 42/89] fix: make credit note and debit note exclusive (#35781) --- erpnext/accounts/doctype/sales_invoice/sales_invoice.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.json b/erpnext/accounts/doctype/sales_invoice/sales_invoice.json index 7b68dd41d9..ab4aab3da2 100644 --- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.json +++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.json @@ -320,6 +320,7 @@ }, { "default": "0", + "depends_on": "eval: !doc.is_debit_note", "fieldname": "is_return", "fieldtype": "Check", "hide_days": 1, @@ -1960,6 +1961,7 @@ }, { "default": "0", + "depends_on": "eval: !doc.is_return", "description": "Issue a debit note with 0 qty against an existing Sales Invoice", "fieldname": "is_debit_note", "fieldtype": "Check", @@ -2155,7 +2157,7 @@ "link_fieldname": "consolidated_invoice" } ], - "modified": "2023-06-03 16:22:16.219333", + "modified": "2023-06-19 16:02:05.309332", "modified_by": "Administrator", "module": "Accounts", "name": "Sales Invoice", From 0d125885836f0ae5015195401dd41653314fddfe Mon Sep 17 00:00:00 2001 From: Anand Baburajan Date: Tue, 20 Jun 2023 12:06:27 +0530 Subject: [PATCH 43/89] fix: date and finance book fixes in fixed asset register (#35751) * fix: handle finance books properly and show all assets by default in fixed asset register * chore: rename value to depr amount * chore: get asset value for correct fb properly * chore: rename include_default_book_entries to include_default_book_assets --- .../fixed_asset_register.js | 119 +++++++------- .../fixed_asset_register.py | 146 +++++++++++------- 2 files changed, 147 insertions(+), 118 deletions(-) diff --git a/erpnext/assets/report/fixed_asset_register/fixed_asset_register.js b/erpnext/assets/report/fixed_asset_register/fixed_asset_register.js index 4f7b836107..b788a32d6a 100644 --- a/erpnext/assets/report/fixed_asset_register/fixed_asset_register.js +++ b/erpnext/assets/report/fixed_asset_register/fixed_asset_register.js @@ -19,56 +19,6 @@ frappe.query_reports["Fixed Asset Register"] = { options: "\nIn Location\nDisposed", default: 'In Location' }, - { - "fieldname":"filter_based_on", - "label": __("Period Based On"), - "fieldtype": "Select", - "options": ["Fiscal Year", "Date Range"], - "default": "Fiscal Year", - "reqd": 1 - }, - { - "fieldname":"from_date", - "label": __("Start Date"), - "fieldtype": "Date", - "default": frappe.datetime.add_months(frappe.datetime.nowdate(), -12), - "depends_on": "eval: doc.filter_based_on == 'Date Range'", - "reqd": 1 - }, - { - "fieldname":"to_date", - "label": __("End Date"), - "fieldtype": "Date", - "default": frappe.datetime.nowdate(), - "depends_on": "eval: doc.filter_based_on == 'Date Range'", - "reqd": 1 - }, - { - "fieldname":"from_fiscal_year", - "label": __("Start Year"), - "fieldtype": "Link", - "options": "Fiscal Year", - "default": frappe.defaults.get_user_default("fiscal_year"), - "depends_on": "eval: doc.filter_based_on == 'Fiscal Year'", - "reqd": 1 - }, - { - "fieldname":"to_fiscal_year", - "label": __("End Year"), - "fieldtype": "Link", - "options": "Fiscal Year", - "default": frappe.defaults.get_user_default("fiscal_year"), - "depends_on": "eval: doc.filter_based_on == 'Fiscal Year'", - "reqd": 1 - }, - { - "fieldname":"date_based_on", - "label": __("Date Based On"), - "fieldtype": "Select", - "options": ["Purchase Date", "Available For Use Date"], - "default": "Purchase Date", - "reqd": 1 - }, { fieldname:"asset_category", label: __("Asset Category"), @@ -89,22 +39,67 @@ frappe.query_reports["Fixed Asset Register"] = { default: "--Select a group--", reqd: 1 }, - { - fieldname:"finance_book", - label: __("Finance Book"), - fieldtype: "Link", - options: "Finance Book", - depends_on: "eval: doc.filter_by_finance_book == 1", - }, - { - fieldname:"filter_by_finance_book", - label: __("Filter by Finance Book"), - fieldtype: "Check" - }, { fieldname:"only_existing_assets", label: __("Only existing assets"), fieldtype: "Check" }, + { + fieldname:"finance_book", + label: __("Finance Book"), + fieldtype: "Link", + options: "Finance Book", + }, + { + "fieldname": "include_default_book_assets", + "label": __("Include Default Book Assets"), + "fieldtype": "Check", + "default": 1 + }, + { + "fieldname":"filter_based_on", + "label": __("Period Based On"), + "fieldtype": "Select", + "options": ["--Select a period--", "Fiscal Year", "Date Range"], + "default": "--Select a period--", + }, + { + "fieldname":"from_date", + "label": __("Start Date"), + "fieldtype": "Date", + "default": frappe.datetime.add_months(frappe.datetime.nowdate(), -12), + "depends_on": "eval: doc.filter_based_on == 'Date Range'", + }, + { + "fieldname":"to_date", + "label": __("End Date"), + "fieldtype": "Date", + "default": frappe.datetime.nowdate(), + "depends_on": "eval: doc.filter_based_on == 'Date Range'", + }, + { + "fieldname":"from_fiscal_year", + "label": __("Start Year"), + "fieldtype": "Link", + "options": "Fiscal Year", + "default": frappe.defaults.get_user_default("fiscal_year"), + "depends_on": "eval: doc.filter_based_on == 'Fiscal Year'", + }, + { + "fieldname":"to_fiscal_year", + "label": __("End Year"), + "fieldtype": "Link", + "options": "Fiscal Year", + "default": frappe.defaults.get_user_default("fiscal_year"), + "depends_on": "eval: doc.filter_based_on == 'Fiscal Year'", + }, + { + "fieldname":"date_based_on", + "label": __("Date Based On"), + "fieldtype": "Select", + "options": ["Purchase Date", "Available For Use Date"], + "default": "Purchase Date", + "depends_on": "eval: doc.filter_based_on == 'Date Range' || doc.filter_based_on == 'Fiscal Year'", + }, ] }; diff --git a/erpnext/assets/report/fixed_asset_register/fixed_asset_register.py b/erpnext/assets/report/fixed_asset_register/fixed_asset_register.py index 984b3fd982..cb61914c25 100644 --- a/erpnext/assets/report/fixed_asset_register/fixed_asset_register.py +++ b/erpnext/assets/report/fixed_asset_register/fixed_asset_register.py @@ -2,9 +2,11 @@ # For license information, please see license.txt +from itertools import chain + import frappe from frappe import _ -from frappe.query_builder.functions import Sum +from frappe.query_builder.functions import IfNull, Sum from frappe.utils import cstr, flt, formatdate, getdate from erpnext.accounts.report.financial_statements import ( @@ -13,7 +15,6 @@ from erpnext.accounts.report.financial_statements import ( validate_fiscal_year, ) from erpnext.assets.doctype.asset.asset import get_asset_value_after_depreciation -from erpnext.assets.doctype.asset.depreciation import get_depreciation_accounts def execute(filters=None): @@ -64,11 +65,9 @@ def get_conditions(filters): def get_data(filters): - data = [] conditions = get_conditions(filters) - depreciation_amount_map = get_finance_book_value_map(filters) pr_supplier_map = get_purchase_receipt_supplier_map() pi_supplier_map = get_purchase_invoice_supplier_map() @@ -102,20 +101,27 @@ def get_data(filters): ] assets_record = frappe.db.get_all("Asset", filters=conditions, fields=fields) - assets_linked_to_fb = None + assets_linked_to_fb = get_assets_linked_to_fb(filters) - if filters.filter_by_finance_book: - assets_linked_to_fb = frappe.db.get_all( - doctype="Asset Finance Book", - filters={"finance_book": filters.finance_book or ("is", "not set")}, - pluck="parent", - ) + company_fb = frappe.get_cached_value("Company", filters.company, "default_finance_book") + + if filters.include_default_book_assets and company_fb: + finance_book = company_fb + elif filters.finance_book: + finance_book = filters.finance_book + else: + finance_book = None + + depreciation_amount_map = get_asset_depreciation_amount_map(filters, finance_book) for asset in assets_record: if assets_linked_to_fb and asset.asset_id not in assets_linked_to_fb: continue - asset_value = get_asset_value_after_depreciation(asset.asset_id, filters.finance_book) + asset_value = get_asset_value_after_depreciation( + asset.asset_id, finance_book + ) or get_asset_value_after_depreciation(asset.asset_id) + row = { "asset_id": asset.asset_id, "asset_name": asset.asset_name, @@ -126,7 +132,7 @@ def get_data(filters): or pi_supplier_map.get(asset.purchase_invoice), "gross_purchase_amount": asset.gross_purchase_amount, "opening_accumulated_depreciation": asset.opening_accumulated_depreciation, - "depreciated_amount": get_depreciation_amount_of_asset(asset, depreciation_amount_map, filters), + "depreciated_amount": get_depreciation_amount_of_asset(asset, depreciation_amount_map), "available_for_use_date": asset.available_for_use_date, "location": asset.location, "asset_category": asset.asset_category, @@ -140,14 +146,23 @@ def get_data(filters): def prepare_chart_data(data, filters): labels_values_map = {} - date_field = frappe.scrub(filters.date_based_on) + if filters.filter_based_on not in ("Date Range", "Fiscal Year"): + filters_filter_based_on = "Date Range" + date_field = "purchase_date" + filters_from_date = min(data, key=lambda a: a.get(date_field)).get(date_field) + filters_to_date = max(data, key=lambda a: a.get(date_field)).get(date_field) + else: + filters_filter_based_on = filters.filter_based_on + date_field = frappe.scrub(filters.date_based_on) + filters_from_date = filters.from_date + filters_to_date = filters.to_date period_list = get_period_list( filters.from_fiscal_year, filters.to_fiscal_year, - filters.from_date, - filters.to_date, - filters.filter_based_on, + filters_from_date, + filters_to_date, + filters_filter_based_on, "Monthly", company=filters.company, ignore_fiscal_year=True, @@ -184,59 +199,78 @@ def prepare_chart_data(data, filters): } -def get_depreciation_amount_of_asset(asset, depreciation_amount_map, filters): - if asset.calculate_depreciation: - depr_amount = depreciation_amount_map.get(asset.asset_id) or 0.0 - else: - depr_amount = get_manual_depreciation_amount_of_asset(asset, filters) +def get_assets_linked_to_fb(filters): + afb = frappe.qb.DocType("Asset Finance Book") - return flt(depr_amount, 2) - - -def get_finance_book_value_map(filters): - date = filters.to_date if filters.filter_based_on == "Date Range" else filters.year_end_date - - return frappe._dict( - frappe.db.sql( - """ Select - ads.asset, SUM(depreciation_amount) - FROM `tabAsset Depreciation Schedule` ads, `tabDepreciation Schedule` ds - WHERE - ds.parent = ads.name - AND ifnull(ads.finance_book, '')=%s - AND ads.docstatus=1 - AND ds.parentfield='depreciation_schedule' - AND ds.schedule_date<=%s - AND ds.journal_entry IS NOT NULL - GROUP BY ads.asset""", - (cstr(filters.finance_book or ""), date), - ) + query = frappe.qb.from_(afb).select( + afb.parent, ) + if filters.include_default_book_assets: + company_fb = frappe.get_cached_value("Company", filters.company, "default_finance_book") -def get_manual_depreciation_amount_of_asset(asset, filters): + if filters.finance_book and company_fb and cstr(filters.finance_book) != cstr(company_fb): + frappe.throw( + _("To use a different finance book, please uncheck 'Include Default Book Entries'") + ) + + query = query.where( + (afb.finance_book.isin([cstr(filters.finance_book), cstr(company_fb), ""])) + | (afb.finance_book.isnull()) + ) + else: + query = query.where( + (afb.finance_book.isin([cstr(filters.finance_book), ""])) | (afb.finance_book.isnull()) + ) + + assets_linked_to_fb = list(chain(*query.run(as_list=1))) + + return assets_linked_to_fb + + +def get_depreciation_amount_of_asset(asset, depreciation_amount_map): + return depreciation_amount_map.get(asset.asset_id) or 0.0 + + +def get_asset_depreciation_amount_map(filters, finance_book): date = filters.to_date if filters.filter_based_on == "Date Range" else filters.year_end_date - (_, _, depreciation_expense_account) = get_depreciation_accounts(asset) - + asset = frappe.qb.DocType("Asset") gle = frappe.qb.DocType("GL Entry") + aca = frappe.qb.DocType("Asset Category Account") + company = frappe.qb.DocType("Company") - result = ( + query = ( frappe.qb.from_(gle) - .select(Sum(gle.debit)) - .where(gle.against_voucher == asset.asset_id) - .where(gle.account == depreciation_expense_account) + .join(asset) + .on(gle.against_voucher == asset.name) + .join(aca) + .on((aca.parent == asset.asset_category) & (aca.company_name == asset.company)) + .join(company) + .on(company.name == asset.company) + .select(asset.name.as_("asset"), Sum(gle.debit).as_("depreciation_amount")) + .where( + gle.account == IfNull(aca.depreciation_expense_account, company.depreciation_expense_account) + ) .where(gle.debit != 0) .where(gle.is_cancelled == 0) - .where(gle.posting_date <= date) - ).run() + .where(asset.docstatus == 1) + .groupby(asset.name) + ) - if result and result[0] and result[0][0]: - depr_amount = result[0][0] + if finance_book: + query = query.where( + (gle.finance_book.isin([cstr(finance_book), ""])) | (gle.finance_book.isnull()) + ) else: - depr_amount = 0 + query = query.where((gle.finance_book.isin([""])) | (gle.finance_book.isnull())) - return depr_amount + if filters.filter_based_on in ("Date Range", "Fiscal Year"): + query = query.where(gle.posting_date <= date) + + asset_depr_amount_map = query.run() + + return dict(asset_depr_amount_map) def get_purchase_receipt_supplier_map(): From 1b33afd69987f04c1c92e236c8eeb86bf9e3e76d Mon Sep 17 00:00:00 2001 From: ruthra kumar Date: Tue, 20 Jun 2023 07:19:59 +0530 Subject: [PATCH 44/89] fix: for zero bal accounts, dr/cr only on currency that has balance --- .../exchange_rate_revaluation.py | 48 +++++++++++++------ 1 file changed, 33 insertions(+), 15 deletions(-) diff --git a/erpnext/accounts/doctype/exchange_rate_revaluation/exchange_rate_revaluation.py b/erpnext/accounts/doctype/exchange_rate_revaluation/exchange_rate_revaluation.py index 5d239c91f7..4926006c96 100644 --- a/erpnext/accounts/doctype/exchange_rate_revaluation/exchange_rate_revaluation.py +++ b/erpnext/accounts/doctype/exchange_rate_revaluation/exchange_rate_revaluation.py @@ -373,6 +373,24 @@ class ExchangeRateRevaluation(Document): "credit": 0, } ) + + journal_entry_accounts.append(journal_account) + + journal_entry_accounts.append( + { + "account": unrealized_exchange_gain_loss_account, + "balance": get_balance_on(unrealized_exchange_gain_loss_account), + "debit": 0, + "credit": 0, + "debit_in_account_currency": abs(d.gain_loss) if d.gain_loss < 0 else 0, + "credit_in_account_currency": abs(d.gain_loss) if d.gain_loss > 0 else 0, + "cost_center": erpnext.get_default_cost_center(self.company), + "exchange_rate": 1, + "reference_type": "Exchange Rate Revaluation", + "reference_name": self.name, + } + ) + elif d.get("balance_in_base_currency") and not d.get("new_balance_in_base_currency"): # Base currency has balance dr_or_cr = "credit" if d.get("balance_in_base_currency") > 0 else "debit" @@ -388,22 +406,22 @@ class ExchangeRateRevaluation(Document): } ) - journal_entry_accounts.append(journal_account) + journal_entry_accounts.append(journal_account) - journal_entry_accounts.append( - { - "account": unrealized_exchange_gain_loss_account, - "balance": get_balance_on(unrealized_exchange_gain_loss_account), - "debit": abs(self.gain_loss_booked) if self.gain_loss_booked < 0 else 0, - "credit": abs(self.gain_loss_booked) if self.gain_loss_booked > 0 else 0, - "debit_in_account_currency": abs(self.gain_loss_booked) if self.gain_loss_booked < 0 else 0, - "credit_in_account_currency": self.gain_loss_booked if self.gain_loss_booked > 0 else 0, - "cost_center": erpnext.get_default_cost_center(self.company), - "exchange_rate": 1, - "reference_type": "Exchange Rate Revaluation", - "reference_name": self.name, - } - ) + journal_entry_accounts.append( + { + "account": unrealized_exchange_gain_loss_account, + "balance": get_balance_on(unrealized_exchange_gain_loss_account), + "debit": abs(d.gain_loss) if d.gain_loss < 0 else 0, + "credit": abs(d.gain_loss) if d.gain_loss > 0 else 0, + "debit_in_account_currency": 0, + "credit_in_account_currency": 0, + "cost_center": erpnext.get_default_cost_center(self.company), + "exchange_rate": 1, + "reference_type": "Exchange Rate Revaluation", + "reference_name": self.name, + } + ) journal_entry.set("accounts", journal_entry_accounts) journal_entry.set_total_debit_credit() From 9d04af9ecc865b77e9408f621eed0c4d933aa543 Mon Sep 17 00:00:00 2001 From: ruthra kumar Date: Tue, 20 Jun 2023 07:21:51 +0530 Subject: [PATCH 45/89] refactor: allow higher precision for new exchange rate --- .../exchange_rate_revaluation_account.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/erpnext/accounts/doctype/exchange_rate_revaluation_account/exchange_rate_revaluation_account.json b/erpnext/accounts/doctype/exchange_rate_revaluation_account/exchange_rate_revaluation_account.json index 2968359a0d..0a7d0579b1 100644 --- a/erpnext/accounts/doctype/exchange_rate_revaluation_account/exchange_rate_revaluation_account.json +++ b/erpnext/accounts/doctype/exchange_rate_revaluation_account/exchange_rate_revaluation_account.json @@ -92,6 +92,7 @@ "fieldtype": "Float", "in_list_view": 1, "label": "New Exchange Rate", + "precision": "9", "reqd": 1 }, { @@ -147,7 +148,7 @@ ], "istable": 1, "links": [], - "modified": "2022-12-29 19:38:52.915295", + "modified": "2023-06-20 07:21:40.743460", "modified_by": "Administrator", "module": "Accounts", "name": "Exchange Rate Revaluation Account", From 4567474418d159e6334c7b69c3a7f7f6ccc9741d Mon Sep 17 00:00:00 2001 From: ruthra kumar Date: Tue, 20 Jun 2023 07:23:51 +0530 Subject: [PATCH 46/89] refactor: allow '0' rounding allowance --- .../exchange_rate_revaluation/exchange_rate_revaluation.js | 2 +- .../exchange_rate_revaluation/exchange_rate_revaluation.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/erpnext/accounts/doctype/exchange_rate_revaluation/exchange_rate_revaluation.js b/erpnext/accounts/doctype/exchange_rate_revaluation/exchange_rate_revaluation.js index f51b90d8f6..1ef5c83740 100644 --- a/erpnext/accounts/doctype/exchange_rate_revaluation/exchange_rate_revaluation.js +++ b/erpnext/accounts/doctype/exchange_rate_revaluation/exchange_rate_revaluation.js @@ -37,7 +37,7 @@ frappe.ui.form.on('Exchange Rate Revaluation', { validate_rounding_loss: function(frm) { let allowance = frm.doc.rounding_loss_allowance; - if (!(allowance > 0 && allowance < 1)) { + if (!(allowance >= 0 && allowance < 1)) { frappe.throw(__("Rounding Loss Allowance should be between 0 and 1")); } }, diff --git a/erpnext/accounts/doctype/exchange_rate_revaluation/exchange_rate_revaluation.py b/erpnext/accounts/doctype/exchange_rate_revaluation/exchange_rate_revaluation.py index 4926006c96..598db642f3 100644 --- a/erpnext/accounts/doctype/exchange_rate_revaluation/exchange_rate_revaluation.py +++ b/erpnext/accounts/doctype/exchange_rate_revaluation/exchange_rate_revaluation.py @@ -22,7 +22,7 @@ class ExchangeRateRevaluation(Document): self.set_total_gain_loss() def validate_rounding_loss_allowance(self): - if not (self.rounding_loss_allowance > 0 and self.rounding_loss_allowance < 1): + if not (self.rounding_loss_allowance >= 0 and self.rounding_loss_allowance < 1): frappe.throw(_("Rounding Loss Allowance should be between 0 and 1")) def set_total_gain_loss(self): From 6694175a517dc942f056e5b9b9918e55419f85b0 Mon Sep 17 00:00:00 2001 From: ruthra kumar Date: Tue, 20 Jun 2023 07:29:21 +0530 Subject: [PATCH 47/89] refactor: higher precision for rounding loss and allow '0' --- .../exchange_rate_revaluation.json | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/erpnext/accounts/doctype/exchange_rate_revaluation/exchange_rate_revaluation.json b/erpnext/accounts/doctype/exchange_rate_revaluation/exchange_rate_revaluation.json index 2310d1272c..79428d591b 100644 --- a/erpnext/accounts/doctype/exchange_rate_revaluation/exchange_rate_revaluation.json +++ b/erpnext/accounts/doctype/exchange_rate_revaluation/exchange_rate_revaluation.json @@ -100,15 +100,16 @@ }, { "default": "0.05", - "description": "Only values between 0 and 1 are allowed. \nEx: If allowance is set at 0.07, accounts that have balance of 0.07 in either of the currencies will be considered as zero balance account", + "description": "Only values between [0,1) are allowed. Like {0.00, 0.04, 0.09, ...}\nEx: If allowance is set at 0.07, accounts that have balance of 0.07 in either of the currencies will be considered as zero balance account", "fieldname": "rounding_loss_allowance", "fieldtype": "Float", - "label": "Rounding Loss Allowance" + "label": "Rounding Loss Allowance", + "precision": "9" } ], "is_submittable": 1, "links": [], - "modified": "2023-06-12 21:02:09.818208", + "modified": "2023-06-20 07:29:06.972434", "modified_by": "Administrator", "module": "Accounts", "name": "Exchange Rate Revaluation", From df090cbe873d827f5fee64feee20a68b6eab15ce Mon Sep 17 00:00:00 2001 From: Anand Baburajan Date: Tue, 20 Jun 2023 13:03:15 +0530 Subject: [PATCH 48/89] chore: minor typo in fixed asset register (#35801) chore: renaming entries to assets --- .../report/fixed_asset_register/fixed_asset_register.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/erpnext/assets/report/fixed_asset_register/fixed_asset_register.py b/erpnext/assets/report/fixed_asset_register/fixed_asset_register.py index cb61914c25..f810819b4f 100644 --- a/erpnext/assets/report/fixed_asset_register/fixed_asset_register.py +++ b/erpnext/assets/report/fixed_asset_register/fixed_asset_register.py @@ -210,9 +210,7 @@ def get_assets_linked_to_fb(filters): company_fb = frappe.get_cached_value("Company", filters.company, "default_finance_book") if filters.finance_book and company_fb and cstr(filters.finance_book) != cstr(company_fb): - frappe.throw( - _("To use a different finance book, please uncheck 'Include Default Book Entries'") - ) + frappe.throw(_("To use a different finance book, please uncheck 'Include Default Book Assets'")) query = query.where( (afb.finance_book.isin([cstr(filters.finance_book), cstr(company_fb), ""])) From a627d2a38cc6b194694066da256dda28d3c7ddba Mon Sep 17 00:00:00 2001 From: Rohit Waghchaure Date: Tue, 20 Jun 2023 15:55:18 +0530 Subject: [PATCH 49/89] fix: keyerror while checking the stock balance report --- erpnext/stock/utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/stock/utils.py b/erpnext/stock/utils.py index 402f998677..02444064c1 100644 --- a/erpnext/stock/utils.py +++ b/erpnext/stock/utils.py @@ -475,7 +475,7 @@ def add_additional_uom_columns(columns, result, include_uom, conversion_factors) for row_idx, row in enumerate(result): for convertible_col, data in convertible_column_map.items(): - conversion_factor = conversion_factors[row.get("item_code")] or 1 + conversion_factor = conversion_factors.get(row.get("item_code")) or 1.0 for_type = data.for_type value_before_conversion = row.get(convertible_col) if for_type == "rate": From 32965f1af9403b20b8d783c6e8f609a565b2864c Mon Sep 17 00:00:00 2001 From: Rohit Waghchaure Date: Tue, 20 Jun 2023 16:27:23 +0530 Subject: [PATCH 50/89] fix: stock error for service item --- erpnext/e_commerce/variant_selector/utils.py | 1 + erpnext/templates/generators/item/item_configure.js | 6 ++++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/erpnext/e_commerce/variant_selector/utils.py b/erpnext/e_commerce/variant_selector/utils.py index 1a3e737928..4466c45743 100644 --- a/erpnext/e_commerce/variant_selector/utils.py +++ b/erpnext/e_commerce/variant_selector/utils.py @@ -162,6 +162,7 @@ def get_next_attribute_and_values(item_code, selected_attributes): product_info = get_item_variant_price_dict(exact_match[0], cart_settings) if product_info: + product_info["is_stock_item"] = frappe.get_cached_value("Item", exact_match[0], "is_stock_item") product_info["allow_items_not_in_stock"] = cint(cart_settings.allow_items_not_in_stock) else: product_info = None diff --git a/erpnext/templates/generators/item/item_configure.js b/erpnext/templates/generators/item/item_configure.js index 613c967e3d..9beba3fd01 100644 --- a/erpnext/templates/generators/item/item_configure.js +++ b/erpnext/templates/generators/item/item_configure.js @@ -219,7 +219,8 @@ class ItemConfigure { : '' } - ${available_qty === 0 ? '(' + __('Out of Stock') + ')' : ''} + ${available_qty === 0 && product_info && product_info?.is_stock_item + ? '(' + __('Out of Stock') + ')' : ''}
@@ -236,7 +237,8 @@ class ItemConfigure { `; /* eslint-disable indent */ - if (!product_info?.allow_items_not_in_stock && available_qty === 0) { + if (!product_info?.allow_items_not_in_stock && available_qty === 0 + && product_info && product_info?.is_stock_item) { item_add_to_cart = ''; } From 96c5c7b1dfb953e665c2683ac68ad67b55474bcb Mon Sep 17 00:00:00 2001 From: Rohit Waghchaure Date: Thu, 8 Jun 2023 17:08:22 +0530 Subject: [PATCH 51/89] fix: don't allow to make reposting entry for closing stock balance period --- .../repost_item_valuation.py | 41 ++++++++++++++++++- .../test_repost_item_valuation.py | 30 ++++++++++++++ 2 files changed, 70 insertions(+), 1 deletion(-) diff --git a/erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.py b/erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.py index d5fc710625..27066b825c 100644 --- a/erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.py +++ b/erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.py @@ -13,6 +13,7 @@ from frappe.utils.user import get_users_with_role from rq.timeouts import JobTimeoutException import erpnext +from erpnext.accounts.general_ledger import validate_accounting_period from erpnext.accounts.utils import get_future_stock_vouchers, repost_gle_for_stock_vouchers from erpnext.stock.stock_ledger import ( get_affected_transactions, @@ -44,11 +45,49 @@ class RepostItemValuation(Document): self.validate_accounts_freeze() def validate_period_closing_voucher(self): + # Period Closing Voucher year_end_date = self.get_max_year_end_date(self.company) if year_end_date and getdate(self.posting_date) <= getdate(year_end_date): - msg = f"Due to period closing, you cannot repost item valuation before {year_end_date}" + date = frappe.format(year_end_date, "Date") + msg = f"Due to period closing, you cannot repost item valuation before {date}" frappe.throw(_(msg)) + # Accounting Period + if self.voucher_type: + validate_accounting_period( + [ + frappe._dict( + { + "posting_date": self.posting_date, + "company": self.company, + "voucher_type": self.voucher_type, + } + ) + ] + ) + + # Closing Stock Balance + closing_stock = self.get_closing_stock_balance() + if closing_stock and closing_stock[0].name: + name = get_link_to_form("Closing Stock Balance", closing_stock[0].name) + to_date = frappe.format(closing_stock[0].to_date, "Date") + msg = f"Due to closing stock balance {name}, you cannot repost item valuation before {to_date}" + frappe.throw(_(msg)) + + def get_closing_stock_balance(self): + filters = { + "company": self.company, + "status": "Completed", + "docstatus": 1, + "to_date": (">=", self.posting_date), + } + + for field in ["warehouse", "item_code"]: + if self.get(field): + filters.update({field: ("in", ["", self.get(field)])}) + + return frappe.get_all("Closing Stock Balance", fields=["name", "to_date"], filters=filters) + @staticmethod def get_max_year_end_date(company): data = frappe.get_all( diff --git a/erpnext/stock/doctype/repost_item_valuation/test_repost_item_valuation.py b/erpnext/stock/doctype/repost_item_valuation/test_repost_item_valuation.py index 9c4d997b31..1853f45f58 100644 --- a/erpnext/stock/doctype/repost_item_valuation/test_repost_item_valuation.py +++ b/erpnext/stock/doctype/repost_item_valuation/test_repost_item_valuation.py @@ -392,3 +392,33 @@ class TestRepostItemValuation(FrappeTestCase, StockTestMixin): pr.cancel() self.assertTrue(pr.docstatus == 2) self.assertTrue(frappe.db.exists("Repost Item Valuation", {"voucher_no": pr.name})) + + def test_repost_item_valuation_for_closing_stock_balance(self): + from erpnext.stock.doctype.closing_stock_balance.closing_stock_balance import ( + prepare_closing_stock_balance, + ) + + doc = frappe.new_doc("Closing Stock Balance") + doc.company = "_Test Company" + doc.from_date = today() + doc.to_date = today() + doc.submit() + + prepare_closing_stock_balance(doc.name) + doc.load_from_db() + self.assertEqual(doc.docstatus, 1) + self.assertEqual(doc.status, "Completed") + + riv = frappe.new_doc("Repost Item Valuation") + riv.update( + { + "item_code": "_Test Item", + "warehouse": "_Test Warehouse - _TC", + "based_on": "Item and Warehouse", + "posting_date": today(), + "posting_time": "00:01:00", + } + ) + + self.assertRaises(frappe.ValidationError, riv.save) + doc.cancel() From ad758b8d8511853934b7cfcfde42eddeff9a333c Mon Sep 17 00:00:00 2001 From: ruthra kumar Date: Wed, 21 Jun 2023 14:19:02 +0530 Subject: [PATCH 52/89] fix: no permission for accounts settings on payment reconciliation --- .../payment_reconciliation.js | 40 ++++++++++--------- .../payment_reconciliation.py | 4 ++ 2 files changed, 26 insertions(+), 18 deletions(-) diff --git a/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.js b/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.js index 2283677634..89fa15172f 100644 --- a/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.js +++ b/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.js @@ -85,25 +85,29 @@ erpnext.accounts.PaymentReconciliationController = class PaymentReconciliationCo // check for any running reconciliation jobs if (this.frm.doc.receivable_payable_account) { - frappe.db.get_single_value("Accounts Settings", "auto_reconcile_payments").then((enabled) => { - if(enabled) { - this.frm.call({ - 'method': "erpnext.accounts.doctype.process_payment_reconciliation.process_payment_reconciliation.is_any_doc_running", - "args": { - for_filter: { - company: this.frm.doc.company, - party_type: this.frm.doc.party_type, - party: this.frm.doc.party, - receivable_payable_account: this.frm.doc.receivable_payable_account + this.frm.call({ + doc: this.frm.doc, + method: 'is_auto_process_enabled', + callback: (r) => { + if (r.message) { + this.frm.call({ + 'method': "erpnext.accounts.doctype.process_payment_reconciliation.process_payment_reconciliation.is_any_doc_running", + "args": { + for_filter: { + company: this.frm.doc.company, + party_type: this.frm.doc.party_type, + party: this.frm.doc.party, + receivable_payable_account: this.frm.doc.receivable_payable_account + } } - } - }).then(r => { - if (r.message) { - let doc_link = frappe.utils.get_form_link("Process Payment Reconciliation", r.message, true); - let msg = __("Payment Reconciliation Job: {0} is running for this party. Can't reconcile now.", [doc_link]); - this.frm.dashboard.add_comment(msg, "yellow"); - } - }); + }).then(r => { + if (r.message) { + let doc_link = frappe.utils.get_form_link("Process Payment Reconciliation", r.message, true); + let msg = __("Payment Reconciliation Job: {0} is running for this party. Can't reconcile now.", [doc_link]); + this.frm.dashboard.add_comment(msg, "yellow"); + } + }); + } } }); } diff --git a/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.py b/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.py index 2c8faecf4b..2e4e3b0e07 100644 --- a/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.py +++ b/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.py @@ -252,6 +252,10 @@ class PaymentReconciliation(Document): return difference_amount + @frappe.whitelist() + def is_auto_process_enabled(self): + return frappe.db.get_single_value("Accounts Settings", "auto_reconcile_payments") + @frappe.whitelist() def calculate_difference_on_allocation_change(self, payment_entry, invoice, allocated_amount): invoice_exchange_map = self.get_invoice_exchange_map(invoice, payment_entry) From 39a1f4a4c1dbe95ca784f307fd2c6d66b0ec4175 Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Wed, 21 Jun 2023 15:38:06 +0530 Subject: [PATCH 53/89] fix: issue of asset value_after_depreciation field getting updated twice if workflow is enabled in Journal Entry (backport #35821) (#35826) * Fixes issue of asset value_after_depreciation field getting updated twice if workflow is enabled in Journal Entry (#35821) * Fixes issue of asset value_after_depreciation field getting updated twice if workflow is enabled in Journal Entry * chore: remove unnecessary line break * chore: formatting --------- Co-authored-by: Anand Baburajan (cherry picked from commit 000ebe447991185e4d5a4050b066fa0781575e65) # Conflicts: # erpnext/assets/doctype/asset/depreciation.py * chore: resolve conflicts --------- Co-authored-by: saeedkola Co-authored-by: Anand Baburajan --- erpnext/assets/doctype/asset/depreciation.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/erpnext/assets/doctype/asset/depreciation.py b/erpnext/assets/doctype/asset/depreciation.py index bfef57e494..259568a24b 100644 --- a/erpnext/assets/doctype/asset/depreciation.py +++ b/erpnext/assets/doctype/asset/depreciation.py @@ -159,15 +159,15 @@ def make_depreciation_entry(asset_depr_schedule_name, date=None): je.flags.ignore_permissions = True je.flags.planned_depr_entry = True je.save() - if not je.meta.get_workflow(): - je.submit() d.db_set("journal_entry", je.name) - idx = cint(asset_depr_schedule_doc.finance_book_id) - row = asset.get("finance_books")[idx - 1] - row.value_after_depreciation -= d.depreciation_amount - row.db_update() + if not je.meta.get_workflow(): + je.submit() + idx = cint(asset_depr_schedule_doc.finance_book_id) + row = asset.get("finance_books")[idx - 1] + row.value_after_depreciation -= d.depreciation_amount + row.db_update() asset.db_set("depr_entry_posting_status", "Successful") From dcfc86e3afa53e393c4dec74fa3f7d3a01be2aa4 Mon Sep 17 00:00:00 2001 From: phot0n Date: Wed, 21 Jun 2023 16:49:54 +0530 Subject: [PATCH 54/89] fix: use correct fieldname for purchase receipt column in item_wise_purcchase_register report --- .../item_wise_purchase_register.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py b/erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py index d34c21348c..924c14bdb9 100644 --- a/erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py +++ b/erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py @@ -87,7 +87,7 @@ def _execute(filters=None, additional_table_columns=None, additional_query_colum "project": d.project, "company": d.company, "purchase_order": d.purchase_order, - "purchase_receipt": d.purchase_receipt, + "purchase_receipt": purchase_receipt, "expense_account": expense_account, "stock_qty": d.stock_qty, "stock_uom": d.stock_uom, @@ -241,7 +241,7 @@ def get_columns(additional_table_columns, filters): }, { "label": _("Purchase Receipt"), - "fieldname": "Purchase Receipt", + "fieldname": "purchase_receipt", "fieldtype": "Link", "options": "Purchase Receipt", "width": 100, From ed76ee3e161454af1eafa310cd6b207dd20e19fc Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Wed, 21 Jun 2023 17:15:46 +0530 Subject: [PATCH 55/89] fix: Move ledger display to dialog --- .../doctype/sales_invoice/sales_invoice.json | 32 ++--------------- .../public/js/controllers/stock_controller.js | 35 +++++++++++++++++-- 2 files changed, 34 insertions(+), 33 deletions(-) diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.json b/erpnext/accounts/doctype/sales_invoice/sales_invoice.json index 15be2e71ba..61c10d9cd5 100644 --- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.json +++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.json @@ -211,12 +211,7 @@ "is_discounted", "remarks", "repost_required", - "connections_tab", - "ledger_preview", - "accounting_ledger_section", - "accounting_ledger_preview_html", - "stock_ledger_section", - "stock_ledger_preview_html" + "connections_tab" ], "fields": [ { @@ -2147,29 +2142,6 @@ "fieldname": "use_company_roundoff_cost_center", "fieldtype": "Check", "label": "Use Company default Cost Center for Round off" - }, - { - "fieldname": "ledger_preview", - "fieldtype": "Tab Break", - "label": "Ledger Preview" - }, - { - "fieldname": "accounting_ledger_section", - "fieldtype": "Section Break", - "label": "Accounting Ledger" - }, - { - "fieldname": "accounting_ledger_preview_html", - "fieldtype": "HTML" - }, - { - "fieldname": "stock_ledger_section", - "fieldtype": "Section Break", - "label": "Stock Ledger" - }, - { - "fieldname": "stock_ledger_preview_html", - "fieldtype": "HTML" } ], "icon": "fa fa-file-text", @@ -2182,7 +2154,7 @@ "link_fieldname": "consolidated_invoice" } ], - "modified": "2023-06-11 11:18:14.024258", + "modified": "2023-06-21 16:02:18.988799", "modified_by": "Administrator", "module": "Accounts", "name": "Sales Invoice", diff --git a/erpnext/public/js/controllers/stock_controller.js b/erpnext/public/js/controllers/stock_controller.js index 0a14ed7935..ff593485be 100644 --- a/erpnext/public/js/controllers/stock_controller.js +++ b/erpnext/public/js/controllers/stock_controller.js @@ -94,15 +94,44 @@ erpnext.stock.StockController = class StockController extends frappe.ui.form.Con "docname": me.frm.doc.name }, "callback": function(response) { - me.get_datatable(response.message.gl_columns, response.message.gl_data, me.frm.get_field("accounting_ledger_preview_html").wrapper); - me.get_datatable(response.message.sl_columns, response.message.sl_data, me.frm.get_field("stock_ledger_preview_html").wrapper); - me.frm.scroll_to_field("accounting_ledger_preview_html"); + me.make_dialog(response.message); } }) }, __("View")); } } + make_dialog(data) { + let me = this; + let gl_columns = data.gl_columns; + let gl_data = data.gl_data; + let sl_columns = data.sl_columns; + let sl_data = data.sl_data; + + let dialog = new frappe.ui.Dialog({ + "size": "extra-large", + "title": __("Ledger Preview"), + "fields": [ + { + "fieldtype": "HTML", + "fieldname": "accounting_ledger_preview_html", + "label": __("Accounting Ledger"), + }, + { + "fieldtype": "HTML", + "fieldname": "stock_ledger_preview_html", + "label": __("Stock Ledger"), + } + ] + }); + + setTimeout(function() { + me.get_datatable(gl_columns, gl_data, dialog.get_field("accounting_ledger_preview_html").wrapper); + }, 200); + + dialog.show(); + } + get_datatable(columns, data, wrapper) { const datatable_options = { columns: columns, From 756dbe7ce89838a9cbff2e13e03c67f6f7c6e0ff Mon Sep 17 00:00:00 2001 From: Rohit Waghchaure Date: Wed, 21 Jun 2023 17:40:48 +0530 Subject: [PATCH 56/89] refactor: return against rejected warehouse --- .../controllers/sales_and_purchase_return.py | 13 +++++- .../purchase_receipt/purchase_receipt.js | 46 +++++++++++++++++-- .../purchase_receipt/purchase_receipt.py | 7 +++ .../purchase_receipt/test_purchase_receipt.py | 27 +++++++++++ 4 files changed, 88 insertions(+), 5 deletions(-) diff --git a/erpnext/controllers/sales_and_purchase_return.py b/erpnext/controllers/sales_and_purchase_return.py index 818c7894b7..954668055e 100644 --- a/erpnext/controllers/sales_and_purchase_return.py +++ b/erpnext/controllers/sales_and_purchase_return.py @@ -320,7 +320,9 @@ def get_returned_qty_map_for_row(return_against, party, row_name, doctype): return data[0] -def make_return_doc(doctype: str, source_name: str, target_doc=None): +def make_return_doc( + doctype: str, source_name: str, target_doc=None, return_against_rejected_qty=False +): from frappe.model.mapper import get_mapped_doc company = frappe.db.get_value("Delivery Note", source_name, "company") @@ -471,7 +473,7 @@ def make_return_doc(doctype: str, source_name: str, target_doc=None): target_doc.qty = -1 * flt(source_doc.qty - (returned_qty_map.get("qty") or 0)) - if hasattr(target_doc, "stock_qty"): + if hasattr(target_doc, "stock_qty") and not return_against_rejected_qty: target_doc.stock_qty = -1 * flt( source_doc.stock_qty - (returned_qty_map.get("stock_qty") or 0) ) @@ -490,6 +492,13 @@ def make_return_doc(doctype: str, source_name: str, target_doc=None): target_doc.rejected_warehouse = source_doc.rejected_warehouse target_doc.purchase_receipt_item = source_doc.name + if doctype == "Purchase Receipt" and return_against_rejected_qty: + target_doc.qty = -1 * flt(source_doc.rejected_qty - (returned_qty_map.get("qty") or 0)) + target_doc.rejected_qty = 0.0 + target_doc.rejected_warehouse = "" + target_doc.warehouse = source_doc.rejected_warehouse + target_doc.received_qty = target_doc.qty + elif doctype == "Purchase Invoice": returned_qty_map = get_returned_qty_map_for_row( source_parent.name, source_parent.supplier, source_doc.name, doctype diff --git a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.js b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.js index 312c166f8b..dc3e0d9935 100644 --- a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.js +++ b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.js @@ -209,10 +209,43 @@ erpnext.stock.PurchaseReceiptController = class PurchaseReceiptController extend } make_purchase_return() { - frappe.model.open_mapped_doc({ - method: "erpnext.stock.doctype.purchase_receipt.purchase_receipt.make_purchase_return", - frm: cur_frm + let me = this; + + let has_rejected_items = cur_frm.doc.items.filter((item) => { + if (item.rejected_qty > 0) { + return true; + } }) + + if (has_rejected_items && has_rejected_items.length > 0) { + frappe.prompt([ + { + label: __("Return Qty from Rejected Warehouse"), + fieldtype: "Check", + fieldname: "return_for_rejected_warehouse", + default: 1 + }, + ], function(values){ + if (values.return_for_rejected_warehouse) { + frappe.call({ + method: "erpnext.stock.doctype.purchase_receipt.purchase_receipt.make_purchase_return_against_rejected_warehouse", + args: { + source_name: cur_frm.doc.name + }, + callback: function(r) { + if(r.message) { + frappe.model.sync(r.message); + frappe.set_route("Form", r.message.doctype, r.message.name); + } + } + }) + } else { + cur_frm.cscript._make_purchase_return(); + } + }, __("Return Qty"), __("Make Return Entry")); + } else { + cur_frm.cscript._make_purchase_return(); + } } close_purchase_receipt() { @@ -322,6 +355,13 @@ frappe.ui.form.on('Purchase Receipt Item', { }, }); +cur_frm.cscript._make_purchase_return = function() { + frappe.model.open_mapped_doc({ + method: "erpnext.stock.doctype.purchase_receipt.purchase_receipt.make_purchase_return", + frm: cur_frm + }); +} + cur_frm.cscript['Make Stock Entry'] = function() { frappe.model.open_mapped_doc({ method: "erpnext.stock.doctype.purchase_receipt.purchase_receipt.make_stock_entry", diff --git a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py index 387f031380..0b5dc05c3a 100644 --- a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py +++ b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py @@ -1136,6 +1136,13 @@ def get_returned_qty_map(purchase_receipt): return returned_qty_map +@frappe.whitelist() +def make_purchase_return_against_rejected_warehouse(source_name): + from erpnext.controllers.sales_and_purchase_return import make_return_doc + + return make_return_doc("Purchase Receipt", source_name, return_against_rejected_qty=True) + + @frappe.whitelist() def make_purchase_return(source_name, target_doc=None): from erpnext.controllers.sales_and_purchase_return import make_return_doc diff --git a/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py b/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py index ddc055656f..1986722587 100644 --- a/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py +++ b/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py @@ -1827,6 +1827,33 @@ class TestPurchaseReceipt(FrappeTestCase): self.assertEqual(abs(data["stock_value_difference"]), 400.00) + def test_return_from_rejected_warehouse(self): + from erpnext.stock.doctype.purchase_receipt.purchase_receipt import ( + make_purchase_return_against_rejected_warehouse, + ) + + item_code = "_Test Item Return from Rejected Warehouse" + create_item(item_code) + + warehouse = create_warehouse("_Test Warehouse Return Qty Warehouse") + rejected_warehouse = create_warehouse("_Test Rejected Warehouse Return Qty Warehouse") + + # Step 1: Create Purchase Receipt with valuation rate 100 + pr = make_purchase_receipt( + item_code=item_code, + warehouse=warehouse, + qty=10, + rate=100, + rejected_qty=2, + rejected_warehouse=rejected_warehouse, + ) + + pr_return = make_purchase_return_against_rejected_warehouse(pr.name) + self.assertEqual(pr_return.items[0].warehouse, rejected_warehouse) + self.assertEqual(pr_return.items[0].qty, 2.0 * -1) + self.assertEqual(pr_return.items[0].rejected_qty, 0.0) + self.assertEqual(pr_return.items[0].rejected_warehouse, "") + def prepare_data_for_internal_transfer(): from erpnext.accounts.doctype.sales_invoice.test_sales_invoice import create_internal_supplier From 41b9e928680a5dca42e10c383d0b9301482540fb Mon Sep 17 00:00:00 2001 From: ruthra kumar Date: Wed, 21 Jun 2023 21:52:44 +0530 Subject: [PATCH 57/89] fix: incorrect cost center error in bank reconciliation --- .../bank_reconciliation_tool/bank_reconciliation_tool.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/erpnext/accounts/doctype/bank_reconciliation_tool/bank_reconciliation_tool.py b/erpnext/accounts/doctype/bank_reconciliation_tool/bank_reconciliation_tool.py index c4a23a640c..0eef3e9a67 100644 --- a/erpnext/accounts/doctype/bank_reconciliation_tool/bank_reconciliation_tool.py +++ b/erpnext/accounts/doctype/bank_reconciliation_tool/bank_reconciliation_tool.py @@ -10,6 +10,7 @@ from frappe.model.document import Document from frappe.query_builder.custom import ConstantColumn from frappe.utils import cint, flt +from erpnext import get_default_cost_center from erpnext.accounts.doctype.bank_transaction.bank_transaction import get_total_allocated_amount from erpnext.accounts.report.bank_reconciliation_statement.bank_reconciliation_statement import ( get_amounts_not_reflected_in_system, @@ -140,6 +141,9 @@ def create_journal_entry_bts( second_account ) ) + + company = frappe.get_value("Account", company_account, "company") + accounts = [] # Multi Currency? accounts.append( @@ -149,6 +153,7 @@ def create_journal_entry_bts( "debit_in_account_currency": bank_transaction.withdrawal, "party_type": party_type, "party": party, + "cost_center": get_default_cost_center(company), } ) @@ -158,11 +163,10 @@ def create_journal_entry_bts( "bank_account": bank_transaction.bank_account, "credit_in_account_currency": bank_transaction.withdrawal, "debit_in_account_currency": bank_transaction.deposit, + "cost_center": get_default_cost_center(company), } ) - company = frappe.get_value("Account", company_account, "company") - journal_entry_dict = { "voucher_type": entry_type, "company": company, From b4db25dd188134dba30e22977c0fa4665ba749be Mon Sep 17 00:00:00 2001 From: ruthra kumar Date: Thu, 22 Jun 2023 12:40:02 +0530 Subject: [PATCH 58/89] refactor: increase precision for current exc rate in ERR --- .../exchange_rate_revaluation_account.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/erpnext/accounts/doctype/exchange_rate_revaluation_account/exchange_rate_revaluation_account.json b/erpnext/accounts/doctype/exchange_rate_revaluation_account/exchange_rate_revaluation_account.json index 0a7d0579b1..fd2d931315 100644 --- a/erpnext/accounts/doctype/exchange_rate_revaluation_account/exchange_rate_revaluation_account.json +++ b/erpnext/accounts/doctype/exchange_rate_revaluation_account/exchange_rate_revaluation_account.json @@ -73,6 +73,7 @@ "fieldname": "current_exchange_rate", "fieldtype": "Float", "label": "Current Exchange Rate", + "precision": "9", "read_only": 1 }, { @@ -148,7 +149,7 @@ ], "istable": 1, "links": [], - "modified": "2023-06-20 07:21:40.743460", + "modified": "2023-06-22 12:39:56.446722", "modified_by": "Administrator", "module": "Accounts", "name": "Exchange Rate Revaluation Account", From 0e68da5a2ab2855635cd292ea478d727a0ab7601 Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Thu, 22 Jun 2023 15:43:32 +0530 Subject: [PATCH 59/89] feat: Show stock ledger preview --- .../doctype/payment_entry/payment_entry.js | 1 + .../purchase_invoice/purchase_invoice.js | 4 +- .../doctype/sales_invoice/sales_invoice.js | 7 +- erpnext/controllers/stock_controller.py | 34 +++++++-- .../public/js/controllers/stock_controller.js | 65 ---------------- erpnext/public/js/erpnext.bundle.js | 1 + erpnext/public/js/utils/ledger_preview.js | 76 +++++++++++++++++++ .../doctype/delivery_note/delivery_note.js | 3 + .../purchase_receipt/purchase_receipt.js | 4 + 9 files changed, 119 insertions(+), 76 deletions(-) create mode 100644 erpnext/public/js/utils/ledger_preview.js diff --git a/erpnext/accounts/doctype/payment_entry/payment_entry.js b/erpnext/accounts/doctype/payment_entry/payment_entry.js index 9f55ba1167..bac84db231 100644 --- a/erpnext/accounts/doctype/payment_entry/payment_entry.js +++ b/erpnext/accounts/doctype/payment_entry/payment_entry.js @@ -155,6 +155,7 @@ frappe.ui.form.on('Payment Entry', { frm.events.hide_unhide_fields(frm); frm.events.set_dynamic_labels(frm); frm.events.show_general_ledger(frm); + erpnext.accounts.ledger_preview.show_accounting_ledger_preview(frm); }, validate_company: (frm) => { diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js index ab7884d520..6a558ca606 100644 --- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js +++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js @@ -54,9 +54,11 @@ erpnext.accounts.PurchaseInvoice = class PurchaseInvoice extends erpnext.buying. hide_fields(this.frm.doc); // Show / Hide button this.show_general_ledger(); + erpnext.accounts.ledger_preview.show_accounting_ledger_preview(this.frm); - if(doc.update_stock==1 && doc.docstatus==1) { + if(doc.update_stock==1) { this.show_stock_ledger(); + erpnext.accounts.ledger_preview.show_stock_ledger_preview(this.frm); } if(!doc.is_return && doc.docstatus == 1 && doc.outstanding_amount != 0){ diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.js b/erpnext/accounts/doctype/sales_invoice/sales_invoice.js index 1ef0c51cba..68407e0221 100644 --- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.js +++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.js @@ -88,9 +88,12 @@ erpnext.accounts.SalesInvoiceController = class SalesInvoiceController extends e } this.show_general_ledger(); - this.show_ledger_preview(); + erpnext.accounts.ledger_preview.show_accounting_ledger_preview(this.frm); - if(doc.update_stock) this.show_stock_ledger(); + if(doc.update_stock){ + this.show_stock_ledger(); + erpnext.accounts.ledger_preview.show_stock_ledger_preview(this.frm); + } if (doc.docstatus == 1 && doc.outstanding_amount!=0 && !(cint(doc.is_return) && doc.return_against)) { diff --git a/erpnext/controllers/stock_controller.py b/erpnext/controllers/stock_controller.py index 0b057bc748..903ef658e3 100644 --- a/erpnext/controllers/stock_controller.py +++ b/erpnext/controllers/stock_controller.py @@ -846,20 +846,31 @@ class StockController(AccountsController): @frappe.whitelist() -def show_ledger_preview(company, doctype, docname): - frappe.db.savepoint("show_ledger_preview") +def show_accounting_ledger_preview(company, doctype, docname): + frappe.db.savepoint("show_accounting_ledger_preview") + + filters = {"company": company, "include_dimensions": 1} + doc = frappe.get_doc(doctype, docname) + + gl_columns, gl_data = get_accounting_ledger_preview(doc, filters) + + frappe.db.rollback(save_point="show_accounting_ledger_preview") + + return {"gl_columns": gl_columns, "gl_data": gl_data} + + +@frappe.whitelist() +def show_stock_ledger_preview(company, doctype, docname): + frappe.db.savepoint("show_stock_ledger_preview") filters = {"company": company} doc = frappe.get_doc(doctype, docname) sl_columns, sl_data = get_stock_ledger_preview(doc, filters) - gl_columns, gl_data = get_accounting_ledger_preview(doc, filters) - frappe.db.rollback(save_point="show_ledger_preview") + frappe.db.rollback(save_point="show_stock_ledger_preview") return { - "gl_columns": gl_columns, - "gl_data": gl_data, "sl_columns": sl_columns, "sl_data": sl_data, } @@ -877,11 +888,16 @@ def get_accounting_ledger_preview(doc, filters): "against", "party", "party_type", + "cost_center", "against_voucher_type", "against_voucher", ] doc.docstatus = 1 + + if doc.get("update_stock") or doc.doctype in ("Purchase Receipt", "Delivery Note"): + doc.update_stock_ledger() + doc.make_gl_entries() columns = get_gl_columns(filters) gl_entries = get_gl_entries_for_preview(doc.doctype, doc.name, fields) @@ -915,12 +931,12 @@ def get_stock_ledger_preview(doc, filters): "qty_after_transaction", "warehouse", "incoming_rate", - "valuation_rate", + "in_out_rate", "stock_value", "stock_value_difference", ] - if doc.update_stock or doc.doctype in ("Purchase Receipt", "Delivery Note"): + if doc.get("update_stock") or doc.doctype in ("Purchase Receipt", "Delivery Note"): doc.docstatus = 1 doc.update_stock_ledger() columns = get_sl_columns(filters) @@ -945,6 +961,8 @@ def get_sl_entries_for_preview(doctype, docname, fields): entry["out_qty"] = abs(entry.actual_qty) entry["in_qty"] = 0 + entry["in_out_rate"] = entry["valuation_rate"] + return sl_entries diff --git a/erpnext/public/js/controllers/stock_controller.js b/erpnext/public/js/controllers/stock_controller.js index ff593485be..720423b0a4 100644 --- a/erpnext/public/js/controllers/stock_controller.js +++ b/erpnext/public/js/controllers/stock_controller.js @@ -81,69 +81,4 @@ erpnext.stock.StockController = class StockController extends frappe.ui.form.Con }, __("View")); } } - - show_ledger_preview() { - let me = this - if(this.frm.doc.docstatus == 0) { - cur_frm.add_custom_button(__('Accounting Ledger Preview'), function() { - frappe.call({ - "method": "erpnext.controllers.stock_controller.show_ledger_preview", - "args": { - "company": me.frm.doc.company, - "doctype": me.frm.doc.doctype, - "docname": me.frm.doc.name - }, - "callback": function(response) { - me.make_dialog(response.message); - } - }) - }, __("View")); - } - } - - make_dialog(data) { - let me = this; - let gl_columns = data.gl_columns; - let gl_data = data.gl_data; - let sl_columns = data.sl_columns; - let sl_data = data.sl_data; - - let dialog = new frappe.ui.Dialog({ - "size": "extra-large", - "title": __("Ledger Preview"), - "fields": [ - { - "fieldtype": "HTML", - "fieldname": "accounting_ledger_preview_html", - "label": __("Accounting Ledger"), - }, - { - "fieldtype": "HTML", - "fieldname": "stock_ledger_preview_html", - "label": __("Stock Ledger"), - } - ] - }); - - setTimeout(function() { - me.get_datatable(gl_columns, gl_data, dialog.get_field("accounting_ledger_preview_html").wrapper); - }, 200); - - dialog.show(); - } - - get_datatable(columns, data, wrapper) { - const datatable_options = { - columns: columns, - data: data, - dynamicRowHeight: true, - checkboxColumn: false, - inlineFilters: true, - }; - - new frappe.DataTable( - wrapper, - datatable_options - ); - } }; diff --git a/erpnext/public/js/erpnext.bundle.js b/erpnext/public/js/erpnext.bundle.js index cc020fc2f1..4e028e4c31 100644 --- a/erpnext/public/js/erpnext.bundle.js +++ b/erpnext/public/js/erpnext.bundle.js @@ -17,6 +17,7 @@ import "./utils/customer_quick_entry"; import "./utils/supplier_quick_entry"; import "./call_popup/call_popup"; import "./utils/dimension_tree_filter"; +import "./utils/ledger_preview.js" import "./utils/barcode_scanner"; import "./telephony"; import "./templates/call_link.html"; diff --git a/erpnext/public/js/utils/ledger_preview.js b/erpnext/public/js/utils/ledger_preview.js new file mode 100644 index 0000000000..d1ee67b9c2 --- /dev/null +++ b/erpnext/public/js/utils/ledger_preview.js @@ -0,0 +1,76 @@ +frappe.provide('erpnext.accounts'); + +erpnext.accounts.ledger_preview = { + show_accounting_ledger_preview(frm) { + let me = this; + if(!frm.is_new() && frm.doc.docstatus == 0) { + frm.add_custom_button(__('Accounting Ledger'), function() { + frappe.call({ + "method": "erpnext.controllers.stock_controller.show_accounting_ledger_preview", + "args": { + "company": frm.doc.company, + "doctype": frm.doc.doctype, + "docname": frm.doc.name + }, + "callback": function(response) { + me.make_dialog("Accounting Ledger Preview", "accounting_ledger_preview_html", response.message.gl_columns, response.message.gl_data); + } + }) + }, __("Preview")); + } + }, + + show_stock_ledger_preview(frm) { + let me = this + if(!frm.is_new() && frm.doc.docstatus == 0) { + frm.add_custom_button(__('Stock Ledger'), function() { + frappe.call({ + "method": "erpnext.controllers.stock_controller.show_stock_ledger_preview", + "args": { + "company": frm.doc.company, + "doctype": frm.doc.doctype, + "docname": frm.doc.name + }, + "callback": function(response) { + me.make_dialog("Stock Ledger Preview", "stock_ledger_preview_html", response.message.sl_columns, response.message.sl_data); + } + }) + }, __("Preview")); + } + }, + + make_dialog(label, fieldname, columns, data) { + let me = this; + let dialog = new frappe.ui.Dialog({ + "size": "extra-large", + "title": __(label), + "fields": [ + { + "fieldtype": "HTML", + "fieldname": fieldname, + }, + ] + }); + + setTimeout(function() { + me.get_datatable(columns, data, dialog.get_field(fieldname).wrapper); + }, 200); + + dialog.show(); + }, + + get_datatable(columns, data, wrapper) { + const datatable_options = { + columns: columns, + data: data, + dynamicRowHeight: true, + checkboxColumn: false, + inlineFilters: true, + }; + + new frappe.DataTable( + wrapper, + datatable_options + ); + } +} \ No newline at end of file diff --git a/erpnext/stock/doctype/delivery_note/delivery_note.js b/erpnext/stock/doctype/delivery_note/delivery_note.js index 77545e0e1a..a648195933 100644 --- a/erpnext/stock/doctype/delivery_note/delivery_note.js +++ b/erpnext/stock/doctype/delivery_note/delivery_note.js @@ -200,6 +200,9 @@ erpnext.stock.DeliveryNoteController = class DeliveryNoteController extends erpn } } + erpnext.accounts.ledger_preview.show_accounting_ledger_preview(this.frm); + erpnext.accounts.ledger_preview.show_stock_ledger_preview(this.frm); + if (doc.docstatus > 0) { this.show_stock_ledger(); if (erpnext.is_perpetual_inventory_enabled(doc.company)) { diff --git a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.js b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.js index 312c166f8b..685209c02e 100644 --- a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.js +++ b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.js @@ -121,6 +121,10 @@ erpnext.stock.PurchaseReceiptController = class PurchaseReceiptController extend refresh() { var me = this; super.refresh(); + + erpnext.accounts.ledger_preview.show_accounting_ledger_preview(this.frm); + erpnext.accounts.ledger_preview.show_stock_ledger_preview(this.frm); + if(this.frm.doc.docstatus > 0) { this.show_stock_ledger(); //removed for temporary From 80fffbd64bce62cc61a6d5df3865cad18b46a730 Mon Sep 17 00:00:00 2001 From: Rohit Waghchaure Date: Thu, 22 Jun 2023 15:55:18 +0530 Subject: [PATCH 60/89] fix: multiple Work Orders agaist same production plan --- .../doctype/production_plan/production_plan.js | 2 +- .../doctype/production_plan/production_plan.py | 6 ++++++ .../doctype/production_plan/test_production_plan.py | 7 +++++++ 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/erpnext/manufacturing/doctype/production_plan/production_plan.js b/erpnext/manufacturing/doctype/production_plan/production_plan.js index 45a59cf732..48986910b0 100644 --- a/erpnext/manufacturing/doctype/production_plan/production_plan.js +++ b/erpnext/manufacturing/doctype/production_plan/production_plan.js @@ -99,7 +99,7 @@ frappe.ui.form.on('Production Plan', { }, __('Create')); } - if (frm.doc.mr_items && !in_list(['Material Requested', 'Closed'], frm.doc.status)) { + if (frm.doc.mr_items && frm.doc.mr_items.length && !in_list(['Material Requested', 'Closed'], frm.doc.status)) { frm.add_custom_button(__("Material Request"), ()=> { frm.trigger("make_material_request"); }, __('Create')); diff --git a/erpnext/manufacturing/doctype/production_plan/production_plan.py b/erpnext/manufacturing/doctype/production_plan/production_plan.py index 0800bdd2af..6dc1ff6a49 100644 --- a/erpnext/manufacturing/doctype/production_plan/production_plan.py +++ b/erpnext/manufacturing/doctype/production_plan/production_plan.py @@ -515,6 +515,9 @@ class ProductionPlan(Document): self.show_list_created_message("Work Order", wo_list) self.show_list_created_message("Purchase Order", po_list) + if not wo_list: + frappe.msgprint(_("No Work Orders were created")) + def make_work_order_for_finished_goods(self, wo_list, default_warehouses): items_data = self.get_production_items() @@ -618,6 +621,9 @@ class ProductionPlan(Document): def create_work_order(self, item): from erpnext.manufacturing.doctype.work_order.work_order import OverProductionError + if item.get("qty") <= 0: + return + wo = frappe.new_doc("Work Order") wo.update(item) wo.planned_start_date = item.get("planned_start_date") or item.get("schedule_date") diff --git a/erpnext/manufacturing/doctype/production_plan/test_production_plan.py b/erpnext/manufacturing/doctype/production_plan/test_production_plan.py index 75b43ec1c3..fcfba7fca5 100644 --- a/erpnext/manufacturing/doctype/production_plan/test_production_plan.py +++ b/erpnext/manufacturing/doctype/production_plan/test_production_plan.py @@ -76,6 +76,13 @@ class TestProductionPlan(FrappeTestCase): "Work Order", fields=["name"], filters={"production_plan": pln.name}, as_list=1 ) + pln.make_work_order() + nwork_orders = frappe.get_all( + "Work Order", fields=["name"], filters={"production_plan": pln.name}, as_list=1 + ) + + self.assertTrue(len(work_orders), len(nwork_orders)) + self.assertTrue(len(work_orders), len(pln.po_items)) for name in material_requests: From 5c6e3269fba8060935181cda7a952ea565d3abad Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Thu, 22 Jun 2023 15:58:41 +0530 Subject: [PATCH 61/89] fix: Use GET request --- erpnext/public/js/utils/ledger_preview.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/erpnext/public/js/utils/ledger_preview.js b/erpnext/public/js/utils/ledger_preview.js index d1ee67b9c2..85d4a7d51e 100644 --- a/erpnext/public/js/utils/ledger_preview.js +++ b/erpnext/public/js/utils/ledger_preview.js @@ -6,6 +6,7 @@ erpnext.accounts.ledger_preview = { if(!frm.is_new() && frm.doc.docstatus == 0) { frm.add_custom_button(__('Accounting Ledger'), function() { frappe.call({ + "type": "GET", "method": "erpnext.controllers.stock_controller.show_accounting_ledger_preview", "args": { "company": frm.doc.company, @@ -25,6 +26,7 @@ erpnext.accounts.ledger_preview = { if(!frm.is_new() && frm.doc.docstatus == 0) { frm.add_custom_button(__('Stock Ledger'), function() { frappe.call({ + "type": "GET", "method": "erpnext.controllers.stock_controller.show_stock_ledger_preview", "args": { "company": frm.doc.company, From d9e7bc545e3988b2af6e1b896286ba8673598c28 Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Thu, 22 Jun 2023 16:07:32 +0530 Subject: [PATCH 62/89] fix: Do full rollback --- erpnext/controllers/stock_controller.py | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/erpnext/controllers/stock_controller.py b/erpnext/controllers/stock_controller.py index 903ef658e3..5137e03058 100644 --- a/erpnext/controllers/stock_controller.py +++ b/erpnext/controllers/stock_controller.py @@ -847,28 +847,24 @@ class StockController(AccountsController): @frappe.whitelist() def show_accounting_ledger_preview(company, doctype, docname): - frappe.db.savepoint("show_accounting_ledger_preview") - filters = {"company": company, "include_dimensions": 1} doc = frappe.get_doc(doctype, docname) gl_columns, gl_data = get_accounting_ledger_preview(doc, filters) - frappe.db.rollback(save_point="show_accounting_ledger_preview") + frappe.db.rollback() return {"gl_columns": gl_columns, "gl_data": gl_data} @frappe.whitelist() def show_stock_ledger_preview(company, doctype, docname): - frappe.db.savepoint("show_stock_ledger_preview") - filters = {"company": company} doc = frappe.get_doc(doctype, docname) sl_columns, sl_data = get_stock_ledger_preview(doc, filters) - frappe.db.rollback(save_point="show_stock_ledger_preview") + frappe.db.rollback() return { "sl_columns": sl_columns, From e745312a10dc56615a885dcaa97a4467a3705988 Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Thu, 22 Jun 2023 19:21:52 +0530 Subject: [PATCH 63/89] fix: asset capitalization (backport #35832) (#35843) * fix: asset capitalization (#35832) * fix: misc asset capitalisation fixes * chore: add location in tests and remove unnecessary code * chore: more fixes and removals * chore: show company and fix tests * chore: make target qty read only on capitalization (cherry picked from commit fb823b53d1d9a631035016fa3b33003bf8ce297a) # Conflicts: # erpnext/assets/doctype/asset_capitalization/asset_capitalization.json # erpnext/assets/doctype/asset_capitalization/asset_capitalization.py * chore: fixing conflicts --------- Co-authored-by: Anand Baburajan --- .../asset_capitalization.js | 25 ---- .../asset_capitalization.json | 28 ++-- .../asset_capitalization.py | 137 ++++++------------ .../test_asset_capitalization.py | 25 +--- 4 files changed, 73 insertions(+), 142 deletions(-) diff --git a/erpnext/assets/doctype/asset_capitalization/asset_capitalization.js b/erpnext/assets/doctype/asset_capitalization/asset_capitalization.js index 01fcb11d81..6d55d7772b 100644 --- a/erpnext/assets/doctype/asset_capitalization/asset_capitalization.js +++ b/erpnext/assets/doctype/asset_capitalization/asset_capitalization.js @@ -15,7 +15,6 @@ erpnext.assets.AssetCapitalization = class AssetCapitalization extends erpnext.s } refresh() { - erpnext.hide_company(); this.show_general_ledger(); if ((this.frm.doc.stock_items && this.frm.doc.stock_items.length) || !this.frm.doc.target_is_fixed_asset) { this.show_stock_ledger(); @@ -129,10 +128,6 @@ erpnext.assets.AssetCapitalization = class AssetCapitalization extends erpnext.s return this.get_target_item_details(); } - target_asset() { - return this.get_target_asset_details(); - } - item_code(doc, cdt, cdn) { var row = frappe.get_doc(cdt, cdn); if (cdt === "Asset Capitalization Stock Item") { @@ -247,26 +242,6 @@ erpnext.assets.AssetCapitalization = class AssetCapitalization extends erpnext.s } } - get_target_asset_details() { - var me = this; - - if (me.frm.doc.target_asset) { - return me.frm.call({ - method: "erpnext.assets.doctype.asset_capitalization.asset_capitalization.get_target_asset_details", - child: me.frm.doc, - args: { - asset: me.frm.doc.target_asset, - company: me.frm.doc.company, - }, - callback: function (r) { - if (!r.exc) { - me.frm.refresh_fields(); - } - } - }); - } - } - get_consumed_stock_item_details(row) { var me = this; diff --git a/erpnext/assets/doctype/asset_capitalization/asset_capitalization.json b/erpnext/assets/doctype/asset_capitalization/asset_capitalization.json index 01b35f64ab..04b0c4e513 100644 --- a/erpnext/assets/doctype/asset_capitalization/asset_capitalization.json +++ b/erpnext/assets/doctype/asset_capitalization/asset_capitalization.json @@ -11,13 +11,14 @@ "naming_series", "entry_type", "target_item_code", + "target_asset", "target_item_name", "target_is_fixed_asset", "target_has_batch_no", "target_has_serial_no", "column_break_9", - "target_asset", "target_asset_name", + "target_asset_location", "target_warehouse", "target_qty", "target_stock_uom", @@ -85,14 +86,13 @@ "fieldtype": "Column Break" }, { - "depends_on": "eval:doc.entry_type=='Capitalization'", "fieldname": "target_asset", "fieldtype": "Link", "in_standard_filter": 1, "label": "Target Asset", - "mandatory_depends_on": "eval:doc.entry_type=='Capitalization'", "no_copy": 1, - "options": "Asset" + "options": "Asset", + "read_only": 1 }, { "depends_on": "eval:doc.entry_type=='Capitalization'", @@ -108,11 +108,11 @@ "fieldtype": "Column Break" }, { - "fetch_from": "asset.company", "fieldname": "company", "fieldtype": "Link", "label": "Company", "options": "Company", + "remember_last_selected_value": 1, "reqd": 1 }, { @@ -158,7 +158,7 @@ "read_only": 1 }, { - "depends_on": "eval:doc.docstatus == 0 || (doc.stock_items && doc.stock_items.length)", + "depends_on": "eval:doc.entry_type=='Capitalization' && (doc.docstatus == 0 || (doc.stock_items && doc.stock_items.length))", "fieldname": "section_break_16", "fieldtype": "Section Break", "label": "Consumed Stock Items" @@ -189,7 +189,7 @@ "fieldname": "target_qty", "fieldtype": "Float", "label": "Target Qty", - "read_only_depends_on": "target_is_fixed_asset" + "read_only_depends_on": "eval:doc.entry_type=='Capitalization'" }, { "fetch_from": "target_item_code.stock_uom", @@ -227,7 +227,7 @@ "depends_on": "eval:doc.docstatus == 0 || (doc.asset_items && doc.asset_items.length)", "fieldname": "section_break_26", "fieldtype": "Section Break", - "label": "Consumed Asset Items" + "label": "Consumed Assets" }, { "fieldname": "asset_items", @@ -266,7 +266,7 @@ "options": "Finance Book" }, { - "depends_on": "eval:doc.docstatus == 0 || (doc.service_items && doc.service_items.length)", + "depends_on": "eval:doc.entry_type=='Capitalization' && (doc.docstatus == 0 || (doc.service_items && doc.service_items.length))", "fieldname": "service_expenses_section", "fieldtype": "Section Break", "label": "Service Expenses" @@ -329,12 +329,20 @@ "label": "Target Fixed Asset Account", "options": "Account", "read_only": 1 + }, + { + "depends_on": "eval:doc.entry_type=='Capitalization'", + "fieldname": "target_asset_location", + "fieldtype": "Link", + "label": "Target Asset Location", + "mandatory_depends_on": "eval:doc.entry_type=='Capitalization'", + "options": "Location" } ], "index_web_pages_for_search": 1, "is_submittable": 1, "links": [], - "modified": "2022-10-12 15:09:40.771332", + "modified": "2023-06-22 14:17:07.995120", "modified_by": "Administrator", "module": "Assets", "name": "Asset Capitalization", diff --git a/erpnext/assets/doctype/asset_capitalization/asset_capitalization.py b/erpnext/assets/doctype/asset_capitalization/asset_capitalization.py index 6841c56b10..a883bec71b 100644 --- a/erpnext/assets/doctype/asset_capitalization/asset_capitalization.py +++ b/erpnext/assets/doctype/asset_capitalization/asset_capitalization.py @@ -19,9 +19,6 @@ from erpnext.assets.doctype.asset.depreciation import ( reverse_depreciation_entry_made_after_disposal, ) from erpnext.assets.doctype.asset_category.asset_category import get_asset_category_account -from erpnext.assets.doctype.asset_depreciation_schedule.asset_depreciation_schedule import ( - make_new_active_asset_depr_schedules_and_cancel_current_ones, -) from erpnext.controllers.stock_controller import StockController from erpnext.setup.doctype.brand.brand import get_brand_defaults from erpnext.setup.doctype.item_group.item_group import get_item_group_defaults @@ -45,7 +42,6 @@ force_fields = [ "target_has_batch_no", "target_stock_uom", "stock_uom", - "target_fixed_asset_account", "fixed_asset_account", "valuation_rate", ] @@ -56,7 +52,6 @@ class AssetCapitalization(StockController): self.validate_posting_time() self.set_missing_values(for_validate=True) self.validate_target_item() - self.validate_target_asset() self.validate_consumed_stock_item() self.validate_consumed_asset_item() self.validate_service_item() @@ -71,11 +66,12 @@ class AssetCapitalization(StockController): def before_submit(self): self.validate_source_mandatory() + if self.entry_type == "Capitalization": + self.create_target_asset() def on_submit(self): self.update_stock_ledger() self.make_gl_entries() - self.update_target_asset() def on_cancel(self): self.ignore_linked_doctypes = ( @@ -86,7 +82,7 @@ class AssetCapitalization(StockController): ) self.update_stock_ledger() self.make_gl_entries() - self.update_target_asset() + self.restore_consumed_asset_items() def set_title(self): self.title = self.target_asset_name or self.target_item_name or self.target_item_code @@ -97,15 +93,6 @@ class AssetCapitalization(StockController): if self.meta.has_field(k) and (not self.get(k) or k in force_fields): self.set(k, v) - # Remove asset if item not a fixed asset - if not self.target_is_fixed_asset: - self.target_asset = None - - target_asset_details = get_target_asset_details(self.target_asset, self.company) - for k, v in target_asset_details.items(): - if self.meta.has_field(k) and (not self.get(k) or k in force_fields): - self.set(k, v) - for d in self.stock_items: args = self.as_dict() args.update(d.as_dict()) @@ -157,9 +144,6 @@ class AssetCapitalization(StockController): if not target_item.is_stock_item: self.target_warehouse = None - if not target_item.is_fixed_asset: - self.target_asset = None - self.target_fixed_asset_account = None if not target_item.has_batch_no: self.target_batch_no = None if not target_item.has_serial_no: @@ -170,17 +154,6 @@ class AssetCapitalization(StockController): self.validate_item(target_item) - def validate_target_asset(self): - if self.target_asset: - target_asset = self.get_asset_for_validation(self.target_asset) - - if target_asset.item_code != self.target_item_code: - frappe.throw( - _("Asset {0} does not belong to Item {1}").format(self.target_asset, self.target_item_code) - ) - - self.validate_asset(target_asset) - def validate_consumed_stock_item(self): for d in self.stock_items: if d.item_code: @@ -386,7 +359,11 @@ class AssetCapitalization(StockController): gl_entries, target_account, target_against, precision ) + if not self.stock_items and not self.service_items and self.are_all_asset_items_non_depreciable: + return [] + self.get_gl_entries_for_target_item(gl_entries, target_against, precision) + return gl_entries def get_target_account(self): @@ -429,11 +406,14 @@ class AssetCapitalization(StockController): def get_gl_entries_for_consumed_asset_items( self, gl_entries, target_account, target_against, precision ): + self.are_all_asset_items_non_depreciable = True + # Consumed Assets for item in self.asset_items: - asset = self.get_asset(item) + asset = frappe.get_doc("Asset", item.asset) if asset.calculate_depreciation: + self.are_all_asset_items_non_depreciable = False notes = _( "This schedule was created when Asset {0} was consumed through Asset Capitalization {1}." ).format( @@ -519,40 +499,46 @@ class AssetCapitalization(StockController): ) ) - def update_target_asset(self): + def create_target_asset(self): total_target_asset_value = flt(self.total_value, self.precision("total_value")) - if self.docstatus == 1 and self.entry_type == "Capitalization": - asset_doc = frappe.get_doc("Asset", self.target_asset) - asset_doc.purchase_date = self.posting_date - asset_doc.gross_purchase_amount = total_target_asset_value - asset_doc.purchase_receipt_amount = total_target_asset_value - notes = _( - "This schedule was created when target Asset {0} was updated through Asset Capitalization {1}." - ).format( - get_link_to_form(asset_doc.doctype, asset_doc.name), get_link_to_form(self.doctype, self.name) - ) - make_new_active_asset_depr_schedules_and_cancel_current_ones(asset_doc, notes) - asset_doc.flags.ignore_validate_update_after_submit = True - asset_doc.save() - elif self.docstatus == 2: - for item in self.asset_items: - asset = self.get_asset(item) - asset.db_set("disposal_date", None) - self.set_consumed_asset_status(asset) + asset_doc = frappe.new_doc("Asset") + asset_doc.company = self.company + asset_doc.item_code = self.target_item_code + asset_doc.is_existing_asset = 1 + asset_doc.location = self.target_asset_location + asset_doc.available_for_use_date = self.posting_date + asset_doc.purchase_date = self.posting_date + asset_doc.gross_purchase_amount = total_target_asset_value + asset_doc.purchase_receipt_amount = total_target_asset_value + asset_doc.flags.ignore_validate = True + asset_doc.insert() - if asset.calculate_depreciation: - reverse_depreciation_entry_made_after_disposal(asset, self.posting_date) - notes = _( - "This schedule was created when Asset {0} was restored on Asset Capitalization {1}'s cancellation." - ).format( - get_link_to_form(asset.doctype, asset.name), get_link_to_form(self.doctype, self.name) - ) - reset_depreciation_schedule(asset, self.posting_date, notes) + self.target_asset = asset_doc.name - def get_asset(self, item): - asset = frappe.get_doc("Asset", item.asset) - self.check_finance_books(item, asset) - return asset + self.target_fixed_asset_account = get_asset_category_account( + "fixed_asset_account", item=self.target_item_code, company=asset_doc.company + ) + + frappe.msgprint( + _( + "Asset {0} has been created. Please set the depreciation details if any and submit it." + ).format(get_link_to_form("Asset", asset_doc.name)) + ) + + def restore_consumed_asset_items(self): + for item in self.asset_items: + asset = frappe.get_doc("Asset", item.asset) + asset.db_set("disposal_date", None) + self.set_consumed_asset_status(asset) + + if asset.calculate_depreciation: + reverse_depreciation_entry_made_after_disposal(asset, self.posting_date) + notes = _( + "This schedule was created when Asset {0} was restored on Asset Capitalization {1}'s cancellation." + ).format( + get_link_to_form(asset.doctype, asset.name), get_link_to_form(self.doctype, self.name) + ) + reset_depreciation_schedule(asset, self.posting_date, notes) def set_consumed_asset_status(self, asset): if self.docstatus == 1: @@ -602,33 +588,6 @@ def get_target_item_details(item_code=None, company=None): return out -@frappe.whitelist() -def get_target_asset_details(asset=None, company=None): - out = frappe._dict() - - # Get Asset Details - asset_details = frappe._dict() - if asset: - asset_details = frappe.db.get_value("Asset", asset, ["asset_name", "item_code"], as_dict=1) - if not asset_details: - frappe.throw(_("Asset {0} does not exist").format(asset)) - - # Re-set item code from Asset - out.target_item_code = asset_details.item_code - - # Set Asset Details - out.asset_name = asset_details.asset_name - - if asset_details.item_code: - out.target_fixed_asset_account = get_asset_category_account( - "fixed_asset_account", item=asset_details.item_code, company=company - ) - else: - out.target_fixed_asset_account = None - - return out - - @frappe.whitelist() def get_consumed_stock_item_details(args): if isinstance(args, str): diff --git a/erpnext/assets/doctype/asset_capitalization/test_asset_capitalization.py b/erpnext/assets/doctype/asset_capitalization/test_asset_capitalization.py index 5345d0e7f2..6e0a6856f5 100644 --- a/erpnext/assets/doctype/asset_capitalization/test_asset_capitalization.py +++ b/erpnext/assets/doctype/asset_capitalization/test_asset_capitalization.py @@ -47,13 +47,6 @@ class TestAssetCapitalization(unittest.TestCase): total_amount = 103000 - # Create assets - target_asset = create_asset( - asset_name="Asset Capitalization Target Asset", - submit=1, - warehouse="Stores - TCP1", - company=company, - ) consumed_asset = create_asset( asset_name="Asset Capitalization Consumable Asset", asset_value=consumed_asset_value, @@ -65,7 +58,8 @@ class TestAssetCapitalization(unittest.TestCase): # Create and submit Asset Captitalization asset_capitalization = create_asset_capitalization( entry_type="Capitalization", - target_asset=target_asset.name, + target_item_code="Macbook Pro", + target_asset_location="Test Location", stock_qty=stock_qty, stock_rate=stock_rate, consumed_asset=consumed_asset.name, @@ -94,7 +88,7 @@ class TestAssetCapitalization(unittest.TestCase): self.assertEqual(asset_capitalization.target_incoming_rate, total_amount) # Test Target Asset values - target_asset.reload() + target_asset = frappe.get_doc("Asset", asset_capitalization.target_asset) self.assertEqual(target_asset.gross_purchase_amount, total_amount) self.assertEqual(target_asset.purchase_receipt_amount, total_amount) @@ -142,13 +136,6 @@ class TestAssetCapitalization(unittest.TestCase): total_amount = 103000 - # Create assets - target_asset = create_asset( - asset_name="Asset Capitalization Target Asset", - submit=1, - warehouse="Stores - _TC", - company=company, - ) consumed_asset = create_asset( asset_name="Asset Capitalization Consumable Asset", asset_value=consumed_asset_value, @@ -160,7 +147,8 @@ class TestAssetCapitalization(unittest.TestCase): # Create and submit Asset Captitalization asset_capitalization = create_asset_capitalization( entry_type="Capitalization", - target_asset=target_asset.name, + target_item_code="Macbook Pro", + target_asset_location="Test Location", stock_qty=stock_qty, stock_rate=stock_rate, consumed_asset=consumed_asset.name, @@ -189,7 +177,7 @@ class TestAssetCapitalization(unittest.TestCase): self.assertEqual(asset_capitalization.target_incoming_rate, total_amount) # Test Target Asset values - target_asset.reload() + target_asset = frappe.get_doc("Asset", asset_capitalization.target_asset) self.assertEqual(target_asset.gross_purchase_amount, total_amount) self.assertEqual(target_asset.purchase_receipt_amount, total_amount) @@ -364,6 +352,7 @@ def create_asset_capitalization(**args): "posting_time": args.posting_time or now.strftime("%H:%M:%S.%f"), "target_item_code": target_item_code, "target_asset": target_asset.name, + "target_asset_location": "Test Location", "target_warehouse": target_warehouse, "target_qty": flt(args.target_qty) or 1, "target_batch_no": args.target_batch_no, From 56e81ada56332b7dfb721610575ee1bffb2a97d3 Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Thu, 22 Jun 2023 19:57:23 +0530 Subject: [PATCH 64/89] ci: use multiple python version in patch test --- .github/workflows/patch.yml | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/.github/workflows/patch.yml b/.github/workflows/patch.yml index d5f0052744..e2d89573cb 100644 --- a/.github/workflows/patch.yml +++ b/.github/workflows/patch.yml @@ -43,9 +43,11 @@ jobs: fi - name: Setup Python - uses: "gabrielfalcao/pyenv-action@v9" + uses: "actions/setup-python@v4" with: - versions: 3.10:latest, 3.7:latest + python-version: | + 3.7 + 3.10 - name: Setup Node uses: actions/setup-node@v2 @@ -92,7 +94,6 @@ jobs: - name: Install run: | pip install frappe-bench - pyenv global $(pyenv versions | grep '3.10') bash ${GITHUB_WORKSPACE}/.github/helper/install.sh env: DB: mariadb @@ -107,7 +108,6 @@ jobs: git -C "apps/frappe" remote set-url upstream https://github.com/frappe/frappe.git git -C "apps/erpnext" remote set-url upstream https://github.com/frappe/erpnext.git - pyenv global $(pyenv versions | grep '3.7') for version in $(seq 12 13) do echo "Updating to v$version" @@ -120,7 +120,7 @@ jobs: git -C "apps/erpnext" checkout -q -f $branch_name rm -rf ~/frappe-bench/env - bench setup env + bench setup env --python python3.7 bench pip install -e ./apps/payments bench pip install -e ./apps/erpnext @@ -132,9 +132,8 @@ jobs: git -C "apps/frappe" checkout -q -f "${GITHUB_BASE_REF:-${GITHUB_REF##*/}}" git -C "apps/erpnext" checkout -q -f "$GITHUB_SHA" - pyenv global $(pyenv versions | grep '3.10') rm -rf ~/frappe-bench/env - bench -v setup env + bench -v setup env --python python3.10 bench pip install -e ./apps/payments bench pip install -e ./apps/erpnext From f37484c6fe6d95cd854befbf2f056a6d02244d5e Mon Sep 17 00:00:00 2001 From: Anand Baburajan Date: Thu, 22 Jun 2023 22:32:06 +0530 Subject: [PATCH 65/89] chore: better err msg on cancelling JE for asset scrap [dev] (#35850) chore: better err msg on cancelling JE for asset scrap --- .../doctype/journal_entry/journal_entry.js | 2 +- .../doctype/journal_entry/journal_entry.py | 15 +++++++++++---- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/erpnext/accounts/doctype/journal_entry/journal_entry.js b/erpnext/accounts/doctype/journal_entry/journal_entry.js index 6d9e3202f1..a51e38eefe 100644 --- a/erpnext/accounts/doctype/journal_entry/journal_entry.js +++ b/erpnext/accounts/doctype/journal_entry/journal_entry.js @@ -8,7 +8,7 @@ frappe.provide("erpnext.journal_entry"); frappe.ui.form.on("Journal Entry", { setup: function(frm) { frm.add_fetch("bank_account", "account", "account"); - frm.ignore_doctypes_on_cancel_all = ['Sales Invoice', 'Purchase Invoice', 'Journal Entry', "Repost Payment Ledger", 'Asset Depreciation Schedule']; + frm.ignore_doctypes_on_cancel_all = ['Sales Invoice', 'Purchase Invoice', 'Journal Entry', "Repost Payment Ledger", 'Asset', 'Asset Movement', 'Asset Depreciation Schedule']; }, refresh: function(frm) { diff --git a/erpnext/accounts/doctype/journal_entry/journal_entry.py b/erpnext/accounts/doctype/journal_entry/journal_entry.py index 74fd559612..83312dbd22 100644 --- a/erpnext/accounts/doctype/journal_entry/journal_entry.py +++ b/erpnext/accounts/doctype/journal_entry/journal_entry.py @@ -326,12 +326,10 @@ class JournalEntry(AccountsController): d.db_update() def unlink_asset_reference(self): - if self.voucher_type != "Depreciation Entry": - return - for d in self.get("accounts"): if ( - d.reference_type == "Asset" + self.voucher_type == "Depreciation Entry" + and d.reference_type == "Asset" and d.reference_name and d.account_type == "Depreciation" and d.debit @@ -370,6 +368,15 @@ class JournalEntry(AccountsController): else: asset.db_set("value_after_depreciation", asset.value_after_depreciation + d.debit) asset.set_status() + elif self.voucher_type == "Journal Entry" and d.reference_type == "Asset" and d.reference_name: + journal_entry_for_scrap = frappe.db.get_value( + "Asset", d.reference_name, "journal_entry_for_scrap" + ) + + if journal_entry_for_scrap == self.name: + frappe.throw( + _("Journal Entry for Asset scrapping cannot be cancelled. Please restore the Asset.") + ) def unlink_inter_company_jv(self): if ( From 9a993b0364fcee14a9887a5a7b91a23aa69701f1 Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Fri, 23 Jun 2023 08:25:00 +0530 Subject: [PATCH 66/89] fix: show non-depreciable assets in fixed asset register (backport #35858) (#35860) fix: show non-depreciable assets in fixed asset register (#35858) fix: show non-depr assets in fixed asset register (cherry picked from commit 42d09448eed316268d9a5a2c9e25791bc48fa326) Co-authored-by: Anand Baburajan --- .../report/fixed_asset_register/fixed_asset_register.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/erpnext/assets/report/fixed_asset_register/fixed_asset_register.py b/erpnext/assets/report/fixed_asset_register/fixed_asset_register.py index f810819b4f..6911f94bbb 100644 --- a/erpnext/assets/report/fixed_asset_register/fixed_asset_register.py +++ b/erpnext/assets/report/fixed_asset_register/fixed_asset_register.py @@ -115,7 +115,11 @@ def get_data(filters): depreciation_amount_map = get_asset_depreciation_amount_map(filters, finance_book) for asset in assets_record: - if assets_linked_to_fb and asset.asset_id not in assets_linked_to_fb: + if ( + assets_linked_to_fb + and asset.calculate_depreciation + and asset.asset_id not in assets_linked_to_fb + ): continue asset_value = get_asset_value_after_depreciation( From 555c126eb9b2badeacfa742fa379f33038b7085b Mon Sep 17 00:00:00 2001 From: Gursheen Anand Date: Fri, 23 Jun 2023 10:52:25 +0530 Subject: [PATCH 67/89] fix: add patch for setting default value of report field --- .../process_statement_of_accounts.json | 5 +- .../process_statement_of_accounts.py | 2 +- ...ement_of_accounts_accounts_receivable.html | 348 +++++++++++++++ .../accounts_receivable.html | 399 ++++++++---------- erpnext/patches.txt | 1 + .../v14_0/set_report_in_process_SOA.py | 10 + 6 files changed, 532 insertions(+), 233 deletions(-) create mode 100644 erpnext/accounts/doctype/process_statement_of_accounts/process_statement_of_accounts_accounts_receivable.html create mode 100644 erpnext/patches/v14_0/set_report_in_process_SOA.py diff --git a/erpnext/accounts/doctype/process_statement_of_accounts/process_statement_of_accounts.json b/erpnext/accounts/doctype/process_statement_of_accounts/process_statement_of_accounts.json index 70e810439c..8004659065 100644 --- a/erpnext/accounts/doctype/process_statement_of_accounts/process_statement_of_accounts.json +++ b/erpnext/accounts/doctype/process_statement_of_accounts/process_statement_of_accounts.json @@ -326,7 +326,8 @@ "fieldname": "report", "fieldtype": "Select", "label": "Report", - "options": "General Ledger\nAccounts Receivable" + "options": "General Ledger\nAccounts Receivable", + "reqd": 1 }, { "default": "Today", @@ -372,7 +373,7 @@ } ], "links": [], - "modified": "2023-06-19 18:37:10.040570", + "modified": "2023-06-23 10:13:15.051950", "modified_by": "Administrator", "module": "Accounts", "name": "Process Statement Of Accounts", diff --git a/erpnext/accounts/doctype/process_statement_of_accounts/process_statement_of_accounts.py b/erpnext/accounts/doctype/process_statement_of_accounts/process_statement_of_accounts.py index db186d81a2..08f4cf45d6 100644 --- a/erpnext/accounts/doctype/process_statement_of_accounts/process_statement_of_accounts.py +++ b/erpnext/accounts/doctype/process_statement_of_accounts/process_statement_of_accounts.py @@ -160,7 +160,7 @@ def get_html(doc, filters, entry, col, res, ageing): template_path = ( "erpnext/accounts/doctype/process_statement_of_accounts/process_statement_of_accounts.html" if doc.report == "General Ledger" - else "erpnext/accounts/report/accounts_receivable/accounts_receivable.html" + else "erpnext/accounts/doctype/process_statement_of_accounts/process_statement_of_accounts_accounts_receivable.html" ) if doc.letter_head: diff --git a/erpnext/accounts/doctype/process_statement_of_accounts/process_statement_of_accounts_accounts_receivable.html b/erpnext/accounts/doctype/process_statement_of_accounts/process_statement_of_accounts_accounts_receivable.html new file mode 100644 index 0000000000..07e1896292 --- /dev/null +++ b/erpnext/accounts/doctype/process_statement_of_accounts/process_statement_of_accounts_accounts_receivable.html @@ -0,0 +1,348 @@ + + +

{{ _(report.report_name) }}

+

+ {% if (filters.customer_name) %} + {{ filters.customer_name }} + {% else %} + {{ filters.customer ~ filters.supplier }} + {% endif %} +

+
+ {% if (filters.tax_id) %} + {{ _("Tax Id: ") }}{{ filters.tax_id }} + {% endif %} +
+
+ {{ _(filters.ageing_based_on) }} + {{ _("Until") }} + {{ frappe.format(filters.report_date, 'Date') }} +
+ +
+
+ {% if(filters.payment_terms) %} + {{ _("Payment Terms") }}: {{ filters.payment_terms }} + {% endif %} +
+
+ {% if(filters.credit_limit) %} + {{ _("Credit Limit") }}: {{ frappe.utils.fmt_money(filters.credit_limit) }} + {% endif %} +
+
+ + {% if(filters.show_future_payments) %} + {% set balance_row = data.slice(-1).pop() %} + {% for i in report.columns %} + {% if i.fieldname == 'age' %} + {% set elem = i %} + {% endif %} + {% endfor %} + {% set start = report.columns.findIndex(elem) %} + {% set range1 = report.columns[start].label %} + {% set range2 = report.columns[start+1].label %} + {% set range3 = report.columns[start+2].label %} + {% set range4 = report.columns[start+3].label %} + {% set range5 = report.columns[start+4].label %} + {% set range6 = report.columns[start+5].label %} + + {% if(balance_row) %} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
(Amount in {{ data[0]["currency"] ~ "" }})
{{ _(" ") }}{{ _(range1) }}{{ _(range2) }}{{ _(range3) }}{{ _(range4) }}{{ _(range5) }}{{ _(range6) }}{{ _("Total") }}
{{ _("Total Outstanding") }} + {{ format_number(balance_row["age"], null, 2) }} + + {{ frappe.utils.fmt_money(balance_row["range1"], data[data.length-1]["currency"]) }} + + {{ frappe.utils.fmt_money(balance_row["range2"], data[data.length-1]["currency"]) }} + + {{ frappe.utils.fmt_money(balance_row["range3"], data[data.length-1]["currency"]) }} + + {{ frappe.utils.fmt_money(balance_row["range4"], data[data.length-1]["currency"]) }} + + {{ frappe.utils.fmt_money(balance_row["range5"], data[data.length-1]["currency"]) }} + + {{ frappe.utils.fmt_money(flt(balance_row["outstanding"]), data[data.length-1]["currency"]) }} +
{{ _("Future Payments") }} + {{ frappe.utils.fmt_money(flt(balance_row[("future_amount")]), data[data.length-1]["currency"]) }} +
+ {% endif %} + {% endif %} + + + + {% if(report.report_name == "Accounts Receivable" or report.report_name == "Accounts Payable") %} + + + + {% if(report.report_name == "Accounts Receivable" and filters.show_sales_person) %} + + + {% else %} + + {% endif %} + {% if not(filters.show_future_payments) %} + + {% endif %} + + {% if not(filters.show_future_payments) %} + + + {% endif %} + + {% if(filters.show_future_payments) %} + {% if(report.report_name == "Accounts Receivable") %} + + {% endif %} + + + + {% endif %} + {% else %} + + + + + + {% endif %} + + + + {% for i in range(data|length) %} + + {% if(report.report_name == "Accounts Receivable" or report.report_name == "Accounts Payable") %} + {% if(data[i]["party"]) %} + + + + + {% if(report.report_name == "Accounts Receivable" and filters.show_sales_person) %} + + {% endif %} + + {% if not (filters.show_future_payments) %} + + {% endif %} + + + + {% if not(filters.show_future_payments) %} + + + {% endif %} + + + {% if(filters.show_future_payments) %} + {% if(report.report_name == "Accounts Receivable") %} + + {% endif %} + + + + {% endif %} + {% else %} + + {% if not(filters.show_future_payments) %} + + {% endif %} + {% if(report.report_name == "Accounts Receivable" and filters.show_sales_person) %} + + {% endif %} + + + + + {% if not(filters.show_future_payments) %} + + + {% endif %} + + + {% if(filters.show_future_payments) %} + {% if(report.report_name == "Accounts Receivable") %} + + {% endif %} + + + + {% endif %} + {% endif %} + {% else %} + {% if(data[i]["party"] or " ") %} + {% if not(data[i]["is_total_row"]) %} + + {% else %} + + {% endif %} + + + + + {% endif %} + {% endif %} + + {% endfor %} + + + + + + + + + +
{{ _("Date") }}{{ _("Age (Days)") }}{{ _("Reference") }}{{ _("Sales Person") }}{{ _("Reference") }} + {% if (filters.customer or filters.supplier or filters.customer_name) %} + {{ _("Remarks") }} + {% else %} + {{ _("Party") }} + {% endif %} + {{ _("Invoiced Amount") }}{{ _("Paid Amount") }} + {% if report.report_name == "Accounts Receivable" %} + {{ _('Credit Note') }} + {% else %} + {{ _('Debit Note') }} + {% endif %} + {{ _("Outstanding Amount") }}{{ _("Customer LPO No.") }}{{ _("Future Payment Ref") }}{{ _("Future Payment Amount") }}{{ _("Remaining Balance") }} + {% if (filters.customer or filters.supplier or filters.customer_name) %} + {{ _("Remarks")}} + {% else %} + {{ _("Party") }} + {% endif %} + {{ _("Total Invoiced Amount") }}{{ _("Total Paid Amount") }} + {% if report.report_name == "Accounts Receivable Summary" %} + {{ _('Credit Note Amount') }} + {% else %} + {{ _('Debit Note Amount') }} + {% endif %} + {{ _("Total Outstanding Amount") }}
{{ (data[i]["posting_date"]) }}{{ data[i]["age"] }} + {% if not(filters.show_future_payments) %} + {{ data[i]["voucher_type"] }} +
+ {% endif %} + {{ data[i]["voucher_no"] }} +
{{ data[i]["sales_person"] }} + {% if(not(filters.customer or filters.supplier or filters.customer_name)) %} + {{ data[i]["party"] }} + {% if(data[i]["customer_name"] and data[i]["customer_name"] != data[i]["party"]) %} +
{{ data[i]["customer_name"] }} + {% elif(data[i]["supplier_name"] != data[i]["party"]) %} +
{{ data[i]["supplier_name"] }} + {% endif %} + {% endif %} +
+ {% if data[i]["remarks"] %} + {{ _("Remarks") }}: + {{ data[i]["remarks"] }} + {% endif %} +
+
+ {{ frappe.utils.fmt_money(data[i]["invoiced"], currency=data[i]["currency"]) }} + {{ frappe.utils.fmt_money(data[i]["paid"], currency=data[i]["currency"]) }} + {{ frappe.utils.fmt_money(data[i]["credit_note"], currency=data[i]["currency"]) }} + {{ frappe.utils.fmt_money(data[i]["outstanding"], currency=data[i]["currency"]) }} + {{ data[i]["po_no"] }}{{ data[i]["future_ref"] }}{{ frappe.utils.fmt_money(data[i]["future_amount"], currency=data[i]["currency"]) }}{{ frappe.utils.fmt_money(data[i]["remaining_balance"], currency=data[i]["currency"]) }}{{ _("Total") }} + {{ frappe.utils.fmt_money(data[i]["invoiced"], data[i]["currency"]) }} + {{ frappe.utils.fmt_money(data[i]["paid"], currency=data[i]["currency"]) }}{{ frappe.utils.fmt_money(data[i]["credit_note"], currency=data[i]["currency"]) }} + {{ frappe.utils.fmt_money(data[i]["outstanding"], currency=data[i]["currency"]) }} + {{ data[i]["po_no"] }}{{ data[i]["future_ref"] }}{{ frappe.utils.fmt_money(data[i]["future_amount"], currency=data[i]["currency"]) }}{{ frappe.utils.fmt_money(data[i]["remaining_balance"], currency=data[i]["currency"]) }} + {% if(not(filters.customer | filters.supplier)) %} + {{ data[i]["party"] }} + {% if(data[i]["customer_name"] and data[i]["customer_name"] != data[i]["party"]) %} +
{{ data[i]["customer_name"] }} + {% elif(data[i]["supplier_name"] != data[i]["party"]) %} +
{{ data[i]["supplier_name"] }} + {% endif %} + {% endif %} +
{{ _("Remarks") }}: + {{ data[i]["remarks"] }} +
{{ _("Total") }}{{ frappe.utils.fmt_money(data[i]["invoiced"], currency=data[i]["currency"]) }}{{ frappe.utils.fmt_money(data[i]["paid"], currency=data[i]["currency"]) }}{{ frappe.utils.fmt_money(data[i]["credit_note"], currency=data[i]["currency"]) }}{{ frappe.utils.fmt_money(data[i]["outstanding"], currency=data[i]["currency"]) }}
{{ frappe.utils.fmt_money(data|sum(attribute="invoiced"), currency=data[0]["currency"]) }}{{ frappe.utils.fmt_money(data|sum(attribute="paid"), currency=data[0]["currency"]) }}{{ frappe.utils.fmt_money(data|sum(attribute="credit_note"), currency=data[0]["currency"]) }}{{ frappe.utils.fmt_money(data|sum(attribute="outstanding"), currency=data[0]["currency"]) }}
+
+ {% if ageing %} +

{{ _("Ageing Report based on ") }} {{ ageing.ageing_based_on }} + {{ _("up to " ) }} {{ frappe.format(filters.report_date, 'Date')}} +

+ + + + + + + + + + + + + + + + + +
30 Days60 Days90 Days120 Days
{{ frappe.utils.fmt_money(ageing.range1, currency=data[0]["currency"]) }}{{ frappe.utils.fmt_money(ageing.range2, currency=data[0]["currency"]) }}{{ frappe.utils.fmt_money(ageing.range3, currency=data[0]["currency"]) }}{{ frappe.utils.fmt_money(ageing.range4, currency=data[0]["currency"]) }}
+ {% endif %} +

{{ _("Printed On ") }}{{ frappe.utils.now() }}

diff --git a/erpnext/accounts/report/accounts_receivable/accounts_receivable.html b/erpnext/accounts/report/accounts_receivable/accounts_receivable.html index 07e1896292..ed3b991559 100644 --- a/erpnext/accounts/report/accounts_receivable/accounts_receivable.html +++ b/erpnext/accounts/report/accounts_receivable/accounts_receivable.html @@ -8,56 +8,51 @@ } -

{{ _(report.report_name) }}

+

{%= __(report.report_name) %}

- {% if (filters.customer_name) %} - {{ filters.customer_name }} - {% else %} - {{ filters.customer ~ filters.supplier }} - {% endif %} + {% if (filters.customer_name) { %} + {%= filters.customer_name %} + {% } else { %} + {%= filters.customer || filters.supplier %} + {% } %}

- {% if (filters.tax_id) %} - {{ _("Tax Id: ") }}{{ filters.tax_id }} - {% endif %} + {% if (filters.tax_id) { %} + {%= __("Tax Id: ")%} {%= filters.tax_id %} + {% } %}
- {{ _(filters.ageing_based_on) }} - {{ _("Until") }} - {{ frappe.format(filters.report_date, 'Date') }} + {%= __(filters.ageing_based_on) %} + {%= __("Until") %} + {%= frappe.datetime.str_to_user(filters.report_date) %}
- {% if(filters.payment_terms) %} - {{ _("Payment Terms") }}: {{ filters.payment_terms }} - {% endif %} + {% if(filters.payment_terms) { %} + {%= __("Payment Terms") %}: {%= filters.payment_terms %} + {% } %}
- {% if(filters.credit_limit) %} - {{ _("Credit Limit") }}: {{ frappe.utils.fmt_money(filters.credit_limit) }} - {% endif %} + {% if(filters.credit_limit) { %} + {%= __("Credit Limit") %}: {%= format_currency(filters.credit_limit) %} + {% } %}
- {% if(filters.show_future_payments) %} - {% set balance_row = data.slice(-1).pop() %} - {% for i in report.columns %} - {% if i.fieldname == 'age' %} - {% set elem = i %} - {% endif %} - {% endfor %} - {% set start = report.columns.findIndex(elem) %} - {% set range1 = report.columns[start].label %} - {% set range2 = report.columns[start+1].label %} - {% set range3 = report.columns[start+2].label %} - {% set range4 = report.columns[start+3].label %} - {% set range5 = report.columns[start+4].label %} - {% set range6 = report.columns[start+5].label %} - - {% if(balance_row) %} + {% if(filters.show_future_payments) { %} + {% var balance_row = data.slice(-1).pop(); + var start = report.columns.findIndex((elem) => (elem.fieldname == 'age')); + var range1 = report.columns[start].label; + var range2 = report.columns[start+1].label; + var range3 = report.columns[start+2].label; + var range4 = report.columns[start+3].label; + var range5 = report.columns[start+4].label; + var range6 = report.columns[start+5].label; + %} + {% if(balance_row) { %} - + @@ -71,42 +66,42 @@ - - - - - - - - + + + + + + + + - + - + @@ -114,10 +109,10 @@ - + @@ -125,224 +120,168 @@ + {%= format_currency(flt(balance_row["outstanding"] - balance_row[("future_amount")]), data[data.length-1]["currency"]) %}
(Amount in {{ data[0]["currency"] ~ "" }})(Amount in {%= data[0]["currency"] || "" %})
{{ _(" ") }}{{ _(range1) }}{{ _(range2) }}{{ _(range3) }}{{ _(range4) }}{{ _(range5) }}{{ _(range6) }}{{ _("Total") }}{%= __(" ") %}{%= __(range1) %}{%= __(range2) %}{%= __(range3) %}{%= __(range4) %}{%= __(range5) %}{%= __(range6) %}{%= __("Total") %}
{{ _("Total Outstanding") }}{%= __("Total Outstanding") %} - {{ format_number(balance_row["age"], null, 2) }} + {%= format_number(balance_row["age"], null, 2) %} - {{ frappe.utils.fmt_money(balance_row["range1"], data[data.length-1]["currency"]) }} + {%= format_currency(balance_row["range1"], data[data.length-1]["currency"]) %} - {{ frappe.utils.fmt_money(balance_row["range2"], data[data.length-1]["currency"]) }} + {%= format_currency(balance_row["range2"], data[data.length-1]["currency"]) %} - {{ frappe.utils.fmt_money(balance_row["range3"], data[data.length-1]["currency"]) }} + {%= format_currency(balance_row["range3"], data[data.length-1]["currency"]) %} - {{ frappe.utils.fmt_money(balance_row["range4"], data[data.length-1]["currency"]) }} + {%= format_currency(balance_row["range4"], data[data.length-1]["currency"]) %} - {{ frappe.utils.fmt_money(balance_row["range5"], data[data.length-1]["currency"]) }} + {%= format_currency(balance_row["range5"], data[data.length-1]["currency"]) %} - {{ frappe.utils.fmt_money(flt(balance_row["outstanding"]), data[data.length-1]["currency"]) }} + {%= format_currency(flt(balance_row["outstanding"]), data[data.length-1]["currency"]) %}
{{ _("Future Payments") }}{%= __("Future Payments") %} - {{ frappe.utils.fmt_money(flt(balance_row[("future_amount")]), data[data.length-1]["currency"]) }} + {%= format_currency(flt(balance_row[("future_amount")]), data[data.length-1]["currency"]) %}
- {% endif %} - {% endif %} + {% } %} + {% } %} - {% if(report.report_name == "Accounts Receivable" or report.report_name == "Accounts Payable") %} - - + {% if(report.report_name === "Accounts Receivable" || report.report_name === "Accounts Payable") { %} + + - {% if(report.report_name == "Accounts Receivable" and filters.show_sales_person) %} - - - {% else %} - - {% endif %} - {% if not(filters.show_future_payments) %} - - {% endif %} - - {% if not(filters.show_future_payments) %} - - - {% endif %} - - {% if(filters.show_future_payments) %} - {% if(report.report_name == "Accounts Receivable") %} - - {% endif %} - - - - {% endif %} - {% else %} - - - - - - {% endif %} + {% if(report.report_name === "Accounts Receivable" && filters.show_sales_person) { %} + + + {% } else { %} + + {% } %} + {% if(!filters.show_future_payments) { %} + + {% } %} + + {% if(!filters.show_future_payments) { %} + + + {% } %} + + {% if(filters.show_future_payments) { %} + {% if(report.report_name === "Accounts Receivable") { %} + + {% } %} + + + + {% } %} + {% } else { %} + + + + + + {% } %} - {% for i in range(data|length) %} + {% for(var i=0, l=data.length; i - {% if(report.report_name == "Accounts Receivable" or report.report_name == "Accounts Payable") %} - {% if(data[i]["party"]) %} - - + {% if(report.report_name === "Accounts Receivable" || report.report_name === "Accounts Payable") { %} + {% if(data[i]["party"]) { %} + + - {% if(report.report_name == "Accounts Receivable" and filters.show_sales_person) %} - - {% endif %} + {% if(report.report_name === "Accounts Receivable" && filters.show_sales_person) { %} + + {% } %} - {% if not (filters.show_future_payments) %} + {% if(!filters.show_future_payments) { %} - {% endif %} + {% } %} + {%= format_currency(data[i]["invoiced"], data[i]["currency"]) %} - {% if not(filters.show_future_payments) %} + {% if(!filters.show_future_payments) { %} + {%= format_currency(data[i]["paid"], data[i]["currency"]) %} - {% endif %} + {%= format_currency(data[i]["credit_note"], data[i]["currency"]) %} + {% } %} + {%= format_currency(data[i]["outstanding"], data[i]["currency"]) %} - {% if(filters.show_future_payments) %} - {% if(report.report_name == "Accounts Receivable") %} + {% if(filters.show_future_payments) { %} + {% if(report.report_name === "Accounts Receivable") { %} - {% endif %} - - - - {% endif %} - {% else %} + {%= data[i]["po_no"] %} + {% } %} + + + + {% } %} + {% } else { %} - {% if not(filters.show_future_payments) %} + {% if(!filters.show_future_payments) { %} - {% endif %} - {% if(report.report_name == "Accounts Receivable" and filters.show_sales_person) %} + {% } %} + {% if(report.report_name === "Accounts Receivable" && filters.show_sales_person) { %} - {% endif %} + {% } %} - + + {%= format_currency(data[i]["invoiced"], data[i]["currency"] ) %} - {% if not(filters.show_future_payments) %} + {% if(!filters.show_future_payments) { %} - - {% endif %} + {%= format_currency(data[i]["paid"], data[i]["currency"]) %} + + {% } %} + {%= format_currency(data[i]["outstanding"], data[i]["currency"]) %} - {% if(filters.show_future_payments) %} - {% if(report.report_name == "Accounts Receivable") %} + {% if(filters.show_future_payments) { %} + {% if(report.report_name === "Accounts Receivable") { %} - {% endif %} - - - - {% endif %} - {% endif %} - {% else %} - {% if(data[i]["party"] or " ") %} - {% if not(data[i]["is_total_row"]) %} + {%= data[i]["po_no"] %} + {% } %} + + + + {% } %} + {% } %} + {% } else { %} + {% if(data[i]["party"]|| " ") { %} + {% if(!data[i]["is_total_row"]) { %} - {% else %} - - {% endif %} - - - - - {% endif %} - {% endif %} + {% } else { %} + + {% } %} + + + + + {% } %} + {% } %} - {% endfor %} - - - - - - - - + {% } %}
{{ _("Date") }}{{ _("Age (Days)") }}{%= __("Date") %}{%= __("Age (Days)") %}{{ _("Reference") }}{{ _("Sales Person") }}{{ _("Reference") }} - {% if (filters.customer or filters.supplier or filters.customer_name) %} - {{ _("Remarks") }} - {% else %} - {{ _("Party") }} - {% endif %} - {{ _("Invoiced Amount") }}{{ _("Paid Amount") }} - {% if report.report_name == "Accounts Receivable" %} - {{ _('Credit Note') }} - {% else %} - {{ _('Debit Note') }} - {% endif %} - {{ _("Outstanding Amount") }}{{ _("Customer LPO No.") }}{{ _("Future Payment Ref") }}{{ _("Future Payment Amount") }}{{ _("Remaining Balance") }} - {% if (filters.customer or filters.supplier or filters.customer_name) %} - {{ _("Remarks")}} - {% else %} - {{ _("Party") }} - {% endif %} - {{ _("Total Invoiced Amount") }}{{ _("Total Paid Amount") }} - {% if report.report_name == "Accounts Receivable Summary" %} - {{ _('Credit Note Amount') }} - {% else %} - {{ _('Debit Note Amount') }} - {% endif %} - {{ _("Total Outstanding Amount") }}{%= __("Reference") %}{%= __("Sales Person") %}{%= __("Reference") %}{%= (filters.customer || filters.supplier) ? __("Remarks"): __("Party") %}{%= __("Invoiced Amount") %}{%= __("Paid Amount") %}{%= report.report_name === "Accounts Receivable" ? __('Credit Note') : __('Debit Note') %}{%= __("Outstanding Amount") %}{%= __("Customer LPO No.") %}{%= __("Future Payment Ref") %}{%= __("Future Payment Amount") %}{%= __("Remaining Balance") %}{%= (filters.customer || filters.supplier) ? __("Remarks"): __("Party") %}{%= __("Total Invoiced Amount") %}{%= __("Total Paid Amount") %}{%= report.report_name === "Accounts Receivable Summary" ? __('Credit Note Amount') : __('Debit Note Amount') %}{%= __("Total Outstanding Amount") %}
{{ (data[i]["posting_date"]) }}{{ data[i]["age"] }}{%= frappe.datetime.str_to_user(data[i]["posting_date"]) %}{%= data[i]["age"] %} - {% if not(filters.show_future_payments) %} - {{ data[i]["voucher_type"] }} + {% if(!filters.show_future_payments) { %} + {%= data[i]["voucher_type"] %}
- {% endif %} - {{ data[i]["voucher_no"] }} + {% } %} + {%= data[i]["voucher_no"] %}
{{ data[i]["sales_person"] }}{%= data[i]["sales_person"] %} - {% if(not(filters.customer or filters.supplier or filters.customer_name)) %} - {{ data[i]["party"] }} - {% if(data[i]["customer_name"] and data[i]["customer_name"] != data[i]["party"]) %} -
{{ data[i]["customer_name"] }} - {% elif(data[i]["supplier_name"] != data[i]["party"]) %} -
{{ data[i]["supplier_name"] }} - {% endif %} - {% endif %} + {% if(!(filters.customer || filters.supplier)) { %} + {%= data[i]["party"] %} + {% if(data[i]["customer_name"] && data[i]["customer_name"] != data[i]["party"]) { %} +
{%= data[i]["customer_name"] %} + {% } else if(data[i]["supplier_name"] != data[i]["party"]) { %} +
{%= data[i]["supplier_name"] %} + {% } %} + {% } %}
{% if data[i]["remarks"] %} - {{ _("Remarks") }}: - {{ data[i]["remarks"] }} - {% endif %} + {%= __("Remarks") %}: + {%= data[i]["remarks"] %} + {% } %}
- {{ frappe.utils.fmt_money(data[i]["invoiced"], currency=data[i]["currency"]) }} - {{ frappe.utils.fmt_money(data[i]["paid"], currency=data[i]["currency"]) }} - {{ frappe.utils.fmt_money(data[i]["credit_note"], currency=data[i]["currency"]) }} - {{ frappe.utils.fmt_money(data[i]["outstanding"], currency=data[i]["currency"]) }} - {{ data[i]["po_no"] }}{{ data[i]["future_ref"] }}{{ frappe.utils.fmt_money(data[i]["future_amount"], currency=data[i]["currency"]) }}{{ frappe.utils.fmt_money(data[i]["remaining_balance"], currency=data[i]["currency"]) }}{%= data[i]["future_ref"] %}{%= format_currency(data[i]["future_amount"], data[i]["currency"]) %}{%= format_currency(data[i]["remaining_balance"], data[i]["currency"]) %}{{ _("Total") }}{%= __("Total") %} - {{ frappe.utils.fmt_money(data[i]["invoiced"], data[i]["currency"]) }} - {{ frappe.utils.fmt_money(data[i]["paid"], currency=data[i]["currency"]) }}{{ frappe.utils.fmt_money(data[i]["credit_note"], currency=data[i]["currency"]) }} {%= format_currency(data[i]["credit_note"], data[i]["currency"]) %} - {{ frappe.utils.fmt_money(data[i]["outstanding"], currency=data[i]["currency"]) }} - {{ data[i]["po_no"] }}{{ data[i]["future_ref"] }}{{ frappe.utils.fmt_money(data[i]["future_amount"], currency=data[i]["currency"]) }}{{ frappe.utils.fmt_money(data[i]["remaining_balance"], currency=data[i]["currency"]) }}{%= data[i]["future_ref"] %}{%= format_currency(data[i]["future_amount"], data[i]["currency"]) %}{%= format_currency(data[i]["remaining_balance"], data[i]["currency"]) %} - {% if(not(filters.customer | filters.supplier)) %} - {{ data[i]["party"] }} - {% if(data[i]["customer_name"] and data[i]["customer_name"] != data[i]["party"]) %} -
{{ data[i]["customer_name"] }} - {% elif(data[i]["supplier_name"] != data[i]["party"]) %} -
{{ data[i]["supplier_name"] }} - {% endif %} - {% endif %} -
{{ _("Remarks") }}: - {{ data[i]["remarks"] }} + {% if(!(filters.customer || filters.supplier)) { %} + {%= data[i]["party"] %} + {% if(data[i]["customer_name"] && data[i]["customer_name"] != data[i]["party"]) { %} +
{%= data[i]["customer_name"] %} + {% } else if(data[i]["supplier_name"] != data[i]["party"]) { %} +
{%= data[i]["supplier_name"] %} + {% } %} + {% } %} +
{%= __("Remarks") %}: + {%= data[i]["remarks"] %}
{{ _("Total") }}{{ frappe.utils.fmt_money(data[i]["invoiced"], currency=data[i]["currency"]) }}{{ frappe.utils.fmt_money(data[i]["paid"], currency=data[i]["currency"]) }}{{ frappe.utils.fmt_money(data[i]["credit_note"], currency=data[i]["currency"]) }}{{ frappe.utils.fmt_money(data[i]["outstanding"], currency=data[i]["currency"]) }}{%= __("Total") %}{%= format_currency(data[i]["invoiced"], data[i]["currency"]) %}{%= format_currency(data[i]["paid"], data[i]["currency"]) %}{%= format_currency(data[i]["credit_note"], data[i]["currency"]) %}{%= format_currency(data[i]["outstanding"], data[i]["currency"]) %}
{{ frappe.utils.fmt_money(data|sum(attribute="invoiced"), currency=data[0]["currency"]) }}{{ frappe.utils.fmt_money(data|sum(attribute="paid"), currency=data[0]["currency"]) }}{{ frappe.utils.fmt_money(data|sum(attribute="credit_note"), currency=data[0]["currency"]) }}{{ frappe.utils.fmt_money(data|sum(attribute="outstanding"), currency=data[0]["currency"]) }}
-
- {% if ageing %} -

{{ _("Ageing Report based on ") }} {{ ageing.ageing_based_on }} - {{ _("up to " ) }} {{ frappe.format(filters.report_date, 'Date')}} -

- - - - - - - - - - - - - - - - - -
30 Days60 Days90 Days120 Days
{{ frappe.utils.fmt_money(ageing.range1, currency=data[0]["currency"]) }}{{ frappe.utils.fmt_money(ageing.range2, currency=data[0]["currency"]) }}{{ frappe.utils.fmt_money(ageing.range3, currency=data[0]["currency"]) }}{{ frappe.utils.fmt_money(ageing.range4, currency=data[0]["currency"]) }}
- {% endif %} -

{{ _("Printed On ") }}{{ frappe.utils.now() }}

+

{{ __("Printed On ") }}{%= frappe.datetime.str_to_user(frappe.datetime.get_datetime_as_string()) %}

\ No newline at end of file diff --git a/erpnext/patches.txt b/erpnext/patches.txt index 18bd10f45f..8c0fa6bbcd 100644 --- a/erpnext/patches.txt +++ b/erpnext/patches.txt @@ -339,3 +339,4 @@ execute:frappe.delete_doc('DocType', 'Cash Flow Mapper', ignore_missing=True) execute:frappe.delete_doc('DocType', 'Cash Flow Mapping Template', ignore_missing=True) execute:frappe.delete_doc('DocType', 'Cash Flow Mapping Accounts', ignore_missing=True) erpnext.patches.v14_0.cleanup_workspaces +erpnext.patches.v14_0.set_report_in_process_SOA diff --git a/erpnext/patches/v14_0/set_report_in_process_SOA.py b/erpnext/patches/v14_0/set_report_in_process_SOA.py new file mode 100644 index 0000000000..1cb7e415d8 --- /dev/null +++ b/erpnext/patches/v14_0/set_report_in_process_SOA.py @@ -0,0 +1,10 @@ +# Copyright (c) 2022, Frappe Technologies Pvt. Ltd. and Contributors +# License: MIT. See LICENSE + +import frappe + + +def execute(): + process_soa = frappe.qb.DocType("Process Statement of Accounts") + q = frappe.qb.update(process_soa).set(process_soa.report, "General Ledger") + q.run() From cde82bc0cc978c3f4fec183825b709460062f8a8 Mon Sep 17 00:00:00 2001 From: Gursheen Anand Date: Fri, 23 Jun 2023 12:12:32 +0530 Subject: [PATCH 68/89] fix: modify patch --- erpnext/patches/v14_0/set_report_in_process_SOA.py | 1 + 1 file changed, 1 insertion(+) diff --git a/erpnext/patches/v14_0/set_report_in_process_SOA.py b/erpnext/patches/v14_0/set_report_in_process_SOA.py index 1cb7e415d8..0f65b36404 100644 --- a/erpnext/patches/v14_0/set_report_in_process_SOA.py +++ b/erpnext/patches/v14_0/set_report_in_process_SOA.py @@ -5,6 +5,7 @@ import frappe def execute(): + frappe.reload_doc("accounts", "doctype", "Process Statement of Accounts", force=True) process_soa = frappe.qb.DocType("Process Statement of Accounts") q = frappe.qb.update(process_soa).set(process_soa.report, "General Ledger") q.run() From 9e73af891d9ff514521a2b4613aab938ef74437f Mon Sep 17 00:00:00 2001 From: ruthra kumar Date: Fri, 23 Jun 2023 14:50:14 +0530 Subject: [PATCH 69/89] fix: get base grand total while pulling reference details in PE --- erpnext/accounts/doctype/payment_entry/payment_entry.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/accounts/doctype/payment_entry/payment_entry.py b/erpnext/accounts/doctype/payment_entry/payment_entry.py index 1f23fe1d54..712023fdf9 100644 --- a/erpnext/accounts/doctype/payment_entry/payment_entry.py +++ b/erpnext/accounts/doctype/payment_entry/payment_entry.py @@ -1735,7 +1735,7 @@ def get_reference_details(reference_doctype, reference_name, party_account_curre if not total_amount: if party_account_currency == company_currency: # for handling cases that don't have multi-currency (base field) - total_amount = ref_doc.get("grand_total") or ref_doc.get("base_grand_total") + total_amount = ref_doc.get("base_grand_total") or ref_doc.get("grand_total") exchange_rate = 1 else: total_amount = ref_doc.get("grand_total") From 2868baebab6a3c76ca4121c7098ebc27d0f4b04a Mon Sep 17 00:00:00 2001 From: Marica Date: Fri, 23 Jun 2023 16:00:20 +0530 Subject: [PATCH 70/89] fix: Payment Term must be mandatory if `Allocate Payment based on ..` is checked (#35798) - Front and Back end validation of condition - Fix test to accomodate fix --- .../payment_terms_template/payment_terms_template.js | 6 +++++- .../payment_terms_template/payment_terms_template.py | 7 +++++-- .../doctype/purchase_receipt/test_purchase_receipt.py | 7 +++++++ 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/erpnext/accounts/doctype/payment_terms_template/payment_terms_template.js b/erpnext/accounts/doctype/payment_terms_template/payment_terms_template.js index ea18adefa3..6046c13e14 100644 --- a/erpnext/accounts/doctype/payment_terms_template/payment_terms_template.js +++ b/erpnext/accounts/doctype/payment_terms_template/payment_terms_template.js @@ -2,7 +2,11 @@ // For license information, please see license.txt frappe.ui.form.on('Payment Terms Template', { - setup: function(frm) { + refresh: function(frm) { + frm.fields_dict.terms.grid.toggle_reqd("payment_term", frm.doc.allocate_payment_based_on_payment_terms); + }, + allocate_payment_based_on_payment_terms: function(frm) { + frm.fields_dict.terms.grid.toggle_reqd("payment_term", frm.doc.allocate_payment_based_on_payment_terms); } }); diff --git a/erpnext/accounts/doctype/payment_terms_template/payment_terms_template.py b/erpnext/accounts/doctype/payment_terms_template/payment_terms_template.py index ea3b76c524..7b04a68e89 100644 --- a/erpnext/accounts/doctype/payment_terms_template/payment_terms_template.py +++ b/erpnext/accounts/doctype/payment_terms_template/payment_terms_template.py @@ -11,7 +11,7 @@ from frappe.utils import flt class PaymentTermsTemplate(Document): def validate(self): self.validate_invoice_portion() - self.check_duplicate_terms() + self.validate_terms() def validate_invoice_portion(self): total_portion = 0 @@ -23,9 +23,12 @@ class PaymentTermsTemplate(Document): _("Combined invoice portion must equal 100%"), raise_exception=1, indicator="red" ) - def check_duplicate_terms(self): + def validate_terms(self): terms = [] for term in self.terms: + if self.allocate_payment_based_on_payment_terms and not term.payment_term: + frappe.throw(_("Row {0}: Payment Term is mandatory").format(term.idx)) + term_info = (term.payment_term, term.credit_days, term.credit_months, term.due_date_based_on) if term_info in terms: frappe.msgprint( diff --git a/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py b/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py index 1986722587..c6c84cadc8 100644 --- a/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py +++ b/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py @@ -72,6 +72,11 @@ class TestPurchaseReceipt(FrappeTestCase): self.assertEqual(sl_entry_cancelled[1].actual_qty, -0.5) def test_make_purchase_invoice(self): + from erpnext.accounts.doctype.payment_entry.test_payment_entry import create_payment_term + + create_payment_term("_Test Payment Term 1 for Purchase Invoice") + create_payment_term("_Test Payment Term 2 for Purchase Invoice") + if not frappe.db.exists( "Payment Terms Template", "_Test Payment Terms Template For Purchase Invoice" ): @@ -83,12 +88,14 @@ class TestPurchaseReceipt(FrappeTestCase): "terms": [ { "doctype": "Payment Terms Template Detail", + "payment_term": "_Test Payment Term 1 for Purchase Invoice", "invoice_portion": 50.00, "credit_days_based_on": "Day(s) after invoice date", "credit_days": 00, }, { "doctype": "Payment Terms Template Detail", + "payment_term": "_Test Payment Term 2 for Purchase Invoice", "invoice_portion": 50.00, "credit_days_based_on": "Day(s) after invoice date", "credit_days": 30, From 9655d786428467c5ce27f556612f9bf1ea5f802c Mon Sep 17 00:00:00 2001 From: ruthra kumar Date: Fri, 23 Jun 2023 16:35:44 +0530 Subject: [PATCH 71/89] test: test reference details response --- .../payment_entry/test_payment_entry.py | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/erpnext/accounts/doctype/payment_entry/test_payment_entry.py b/erpnext/accounts/doctype/payment_entry/test_payment_entry.py index 278b12f659..ae2625b653 100644 --- a/erpnext/accounts/doctype/payment_entry/test_payment_entry.py +++ b/erpnext/accounts/doctype/payment_entry/test_payment_entry.py @@ -11,6 +11,7 @@ from frappe.utils import flt, nowdate from erpnext.accounts.doctype.payment_entry.payment_entry import ( InvalidPaymentEntry, get_payment_entry, + get_reference_details, ) from erpnext.accounts.doctype.purchase_invoice.test_purchase_invoice import ( make_purchase_invoice, @@ -1037,6 +1038,29 @@ class TestPaymentEntry(FrappeTestCase): self.assertRaises(frappe.ValidationError, pe_draft.submit) + def test_details_update_on_reference_table(self): + so = make_sales_order( + customer="_Test Customer USD", currency="USD", qty=1, rate=100, do_not_submit=True + ) + so.conversion_rate = 50 + so.submit() + pe = get_payment_entry("Sales Order", so.name) + pe.references.clear() + pe.paid_from = "Debtors - _TC" + pe.paid_from_account_currency = "INR" + pe.source_exchange_rate = 50 + pe.save() + + ref_details = get_reference_details(so.doctype, so.name, pe.paid_from_account_currency) + expected_response = { + "total_amount": 5000.0, + "outstanding_amount": 5000.0, + "exchange_rate": 1.0, + "due_date": None, + "bill_no": None, + } + self.assertDictEqual(ref_details, expected_response) + def create_payment_entry(**args): payment_entry = frappe.new_doc("Payment Entry") From 802c89ffb33aa7ff8971a00db5a48c4b8ae737de Mon Sep 17 00:00:00 2001 From: Devin Slauenwhite Date: Sat, 24 Jun 2023 03:01:16 -0400 Subject: [PATCH 72/89] feat: allow Sales Invoice as data source (#35855) * feat: allow Sales Invoice as data source * chore: linter --- .../exponential_smoothing_forecasting.js | 2 +- .../exponential_smoothing_forecasting.py | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/erpnext/manufacturing/report/exponential_smoothing_forecasting/exponential_smoothing_forecasting.js b/erpnext/manufacturing/report/exponential_smoothing_forecasting/exponential_smoothing_forecasting.js index 123a82a388..a3f0d00877 100644 --- a/erpnext/manufacturing/report/exponential_smoothing_forecasting/exponential_smoothing_forecasting.js +++ b/erpnext/manufacturing/report/exponential_smoothing_forecasting/exponential_smoothing_forecasting.js @@ -30,7 +30,7 @@ frappe.query_reports["Exponential Smoothing Forecasting"] = { "fieldname":"based_on_document", "label": __("Based On Document"), "fieldtype": "Select", - "options": ["Sales Order", "Delivery Note", "Quotation"], + "options": ["Sales Order", "Sales Invoice", "Delivery Note", "Quotation"], "default": "Sales Order", "reqd": 1 }, diff --git a/erpnext/manufacturing/report/exponential_smoothing_forecasting/exponential_smoothing_forecasting.py b/erpnext/manufacturing/report/exponential_smoothing_forecasting/exponential_smoothing_forecasting.py index d3bce83155..daef7f6cca 100644 --- a/erpnext/manufacturing/report/exponential_smoothing_forecasting/exponential_smoothing_forecasting.py +++ b/erpnext/manufacturing/report/exponential_smoothing_forecasting/exponential_smoothing_forecasting.py @@ -99,7 +99,9 @@ class ForecastingReport(ExponentialSmoothingForecast): parent = frappe.qb.DocType(self.doctype) child = frappe.qb.DocType(self.child_doctype) - date_field = "posting_date" if self.doctype == "Delivery Note" else "transaction_date" + date_field = ( + "posting_date" if self.doctype in ("Delivery Note", "Sales Invoice") else "transaction_date" + ) query = ( frappe.qb.from_(parent) From f9ed8c10ab97e39e655c345a66779e3bf3387359 Mon Sep 17 00:00:00 2001 From: Devin Slauenwhite Date: Sat, 24 Jun 2023 06:33:15 -0400 Subject: [PATCH 73/89] fix: make reorder_level not required (#35831) * fix: make reorder_level not required * fix: allow material request to be made if projected_qty <= reorder_level --- erpnext/stock/doctype/item_reorder/item_reorder.json | 6 +++--- erpnext/stock/reorder_item.py | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/erpnext/stock/doctype/item_reorder/item_reorder.json b/erpnext/stock/doctype/item_reorder/item_reorder.json index fb4c558cfd..a03bd458d4 100644 --- a/erpnext/stock/doctype/item_reorder/item_reorder.json +++ b/erpnext/stock/doctype/item_reorder/item_reorder.json @@ -81,7 +81,7 @@ "print_hide_if_no_value": 0, "read_only": 0, "report_hide": 0, - "reqd": 1, + "reqd": 0, "search_index": 0, "set_only_once": 0, "unique": 0 @@ -147,7 +147,7 @@ "issingle": 0, "istable": 1, "max_attachments": 0, - "modified": "2016-07-28 19:15:38.270046", + "modified": "2023-06-21 15:13:38.270046", "modified_by": "Administrator", "module": "Stock", "name": "Item Reorder", @@ -158,4 +158,4 @@ "read_only_onload": 0, "sort_order": "ASC", "track_seen": 0 -} \ No newline at end of file +} diff --git a/erpnext/stock/reorder_item.py b/erpnext/stock/reorder_item.py index 136c78ff58..907560826b 100644 --- a/erpnext/stock/reorder_item.py +++ b/erpnext/stock/reorder_item.py @@ -67,7 +67,7 @@ def _reorder_item(): else: projected_qty = flt(item_warehouse_projected_qty.get(item_code, {}).get(warehouse)) - if (reorder_level or reorder_qty) and projected_qty < reorder_level: + if (reorder_level or reorder_qty) and projected_qty <= reorder_level: deficiency = reorder_level - projected_qty if deficiency > reorder_qty: reorder_qty = deficiency From 4de7a4c5718acbc144729f143cdfc0f61a3693f7 Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Sat, 24 Jun 2023 16:31:19 +0530 Subject: [PATCH 74/89] chore: update typo in patch --- erpnext/patches/v14_0/set_report_in_process_SOA.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/erpnext/patches/v14_0/set_report_in_process_SOA.py b/erpnext/patches/v14_0/set_report_in_process_SOA.py index 0f65b36404..9eb5e3ab9b 100644 --- a/erpnext/patches/v14_0/set_report_in_process_SOA.py +++ b/erpnext/patches/v14_0/set_report_in_process_SOA.py @@ -5,7 +5,6 @@ import frappe def execute(): - frappe.reload_doc("accounts", "doctype", "Process Statement of Accounts", force=True) - process_soa = frappe.qb.DocType("Process Statement of Accounts") + process_soa = frappe.qb.DocType("Process Statement Of Accounts") q = frappe.qb.update(process_soa).set(process_soa.report, "General Ledger") q.run() From 1e2001605973741f7cf7d919b79d7f618cac632a Mon Sep 17 00:00:00 2001 From: HarryPaulo Date: Sat, 24 Jun 2023 08:04:24 -0300 Subject: [PATCH 75/89] fix: POS Closing Entry load all invoices with one request on save (#35819) fix: load all invoices with one request --- .../pos_closing_entry/pos_closing_entry.js | 39 +++++++++++-------- 1 file changed, 23 insertions(+), 16 deletions(-) diff --git a/erpnext/accounts/doctype/pos_closing_entry/pos_closing_entry.js b/erpnext/accounts/doctype/pos_closing_entry/pos_closing_entry.js index e6d9fe2b54..a6c0102a7f 100644 --- a/erpnext/accounts/doctype/pos_closing_entry/pos_closing_entry.js +++ b/erpnext/accounts/doctype/pos_closing_entry/pos_closing_entry.js @@ -123,22 +123,29 @@ frappe.ui.form.on('POS Closing Entry', { row.expected_amount = row.opening_amount; } - const pos_inv_promises = frm.doc.pos_transactions.map( - row => frappe.db.get_doc("POS Invoice", row.pos_invoice) - ); - - const pos_invoices = await Promise.all(pos_inv_promises); - - for (let doc of pos_invoices) { - frm.doc.grand_total += flt(doc.grand_total); - frm.doc.net_total += flt(doc.net_total); - frm.doc.total_quantity += flt(doc.total_qty); - refresh_payments(doc, frm); - refresh_taxes(doc, frm); - refresh_fields(frm); - set_html_data(frm); - } - + await Promise.all([ + frappe.call({ + method: 'erpnext.accounts.doctype.pos_closing_entry.pos_closing_entry.get_pos_invoices', + args: { + start: frappe.datetime.get_datetime_as_string(frm.doc.period_start_date), + end: frappe.datetime.get_datetime_as_string(frm.doc.period_end_date), + pos_profile: frm.doc.pos_profile, + user: frm.doc.user + }, + callback: (r) => { + let pos_invoices = r.message; + for (let doc of pos_invoices) { + frm.doc.grand_total += flt(doc.grand_total); + frm.doc.net_total += flt(doc.net_total); + frm.doc.total_quantity += flt(doc.total_qty); + refresh_payments(doc, frm); + refresh_taxes(doc, frm); + refresh_fields(frm); + set_html_data(frm); + } + } + }) + ]) frappe.dom.unfreeze(); } }); From feafa956f70e448033a216fdfc77782bcbd08f58 Mon Sep 17 00:00:00 2001 From: Patrick Eissler <77415730+PatrickDenis-stack@users.noreply.github.com> Date: Sat, 24 Jun 2023 13:05:52 +0200 Subject: [PATCH 76/89] feat: add German translations for new email template feature (#35865) --- erpnext/translations/de.csv | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/erpnext/translations/de.csv b/erpnext/translations/de.csv index 68358c6b10..f9ec68935c 100644 --- a/erpnext/translations/de.csv +++ b/erpnext/translations/de.csv @@ -9905,3 +9905,7 @@ Select Alternative Items for Sales Order,Alternativpositionen für Auftragsbest Select an item from each set to be used in the Sales Order.,"Wählen Sie aus den Alternativen jeweils einen Artikel aus, der in die Auftragsbestätigung übernommen werden soll.", Is Alternative,Ist Alternative, Alternative Items,Alternativpositionen, +Add Template,Vorlage einfügen, +Prepend the template to the email message,Vorlage oberhalb der Email-Nachricht einfügen, +Clear & Add Template,Leeren und Vorlage einfügen, +Clear the email message and add the template,Email-Feld leeren und Vorlage einfügen, From bcff4b0e5afea4d1abd17af8ef2138fa0a93bdd2 Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Sun, 25 Jun 2023 16:03:58 +0530 Subject: [PATCH 77/89] chore: linting issues --- .../accounting_dimension_filter/accounting_dimension_filter.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/accounts/doctype/accounting_dimension_filter/accounting_dimension_filter.py b/erpnext/accounts/doctype/accounting_dimension_filter/accounting_dimension_filter.py index 2a6c76dd4a..a79f13df05 100644 --- a/erpnext/accounts/doctype/accounting_dimension_filter/accounting_dimension_filter.py +++ b/erpnext/accounts/doctype/accounting_dimension_filter/accounting_dimension_filter.py @@ -13,7 +13,7 @@ class AccountingDimensionFilter(Document): # If restriction is not applied on values, then remove all the dimensions and set allow_or_restrict to Restrict if not self.apply_restriction_on_values: self.allow_or_restrict = "Restrict" - self.set('dimensions', []) + self.set("dimensions", []) def validate(self): self.validate_applicable_accounts() From 63b126967ea685e9d2cecc525b97864b91b48363 Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Sun, 25 Jun 2023 16:24:22 +0530 Subject: [PATCH 78/89] chore: Linting Issues --- .../accounting_dimension_filter/accounting_dimension_filter.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/erpnext/accounts/doctype/accounting_dimension_filter/accounting_dimension_filter.py b/erpnext/accounts/doctype/accounting_dimension_filter/accounting_dimension_filter.py index a79f13df05..de1b82c1d5 100644 --- a/erpnext/accounts/doctype/accounting_dimension_filter/accounting_dimension_filter.py +++ b/erpnext/accounts/doctype/accounting_dimension_filter/accounting_dimension_filter.py @@ -8,13 +8,12 @@ from frappe.model.document import Document class AccountingDimensionFilter(Document): - def before_save(self): # If restriction is not applied on values, then remove all the dimensions and set allow_or_restrict to Restrict if not self.apply_restriction_on_values: self.allow_or_restrict = "Restrict" self.set("dimensions", []) - + def validate(self): self.validate_applicable_accounts() From 36d26d40a0e8e38b5a76dd13147060fd5a7af980 Mon Sep 17 00:00:00 2001 From: Anand Baburajan Date: Mon, 26 Jun 2023 10:58:36 +0530 Subject: [PATCH 79/89] perf: improve asset depr schedule creation patch (#35867) --- ...sset_depreciation_schedules_from_assets.py | 74 ++++++++++++++++--- 1 file changed, 62 insertions(+), 12 deletions(-) diff --git a/erpnext/patches/v15_0/create_asset_depreciation_schedules_from_assets.py b/erpnext/patches/v15_0/create_asset_depreciation_schedules_from_assets.py index 5c46bf3280..a53adf1a83 100644 --- a/erpnext/patches/v15_0/create_asset_depreciation_schedules_from_assets.py +++ b/erpnext/patches/v15_0/create_asset_depreciation_schedules_from_assets.py @@ -6,10 +6,14 @@ def execute(): assets = get_details_of_draft_or_submitted_depreciable_assets() - for asset in assets: - finance_book_rows = get_details_of_asset_finance_books_rows(asset.name) + asset_finance_books_map = get_asset_finance_books_map() - for fb_row in finance_book_rows: + asset_depreciation_schedules_map = get_asset_depreciation_schedules_map() + + for asset in assets: + depreciation_schedules = asset_depreciation_schedules_map[asset.name] + + for fb_row in asset_finance_books_map[asset.name]: asset_depr_schedule_doc = frappe.new_doc("Asset Depreciation Schedule") asset_depr_schedule_doc.set_draft_asset_depr_schedule_details(asset, fb_row) @@ -19,7 +23,11 @@ def execute(): if asset.docstatus == 1: asset_depr_schedule_doc.submit() - update_depreciation_schedules(asset.name, asset_depr_schedule_doc.name, fb_row.idx) + depreciation_schedules_of_fb_row = [ + ds for ds in depreciation_schedules if ds["finance_book_id"] == str(fb_row.idx) + ] + + update_depreciation_schedules(depreciation_schedules_of_fb_row, asset_depr_schedule_doc.name) def get_details_of_draft_or_submitted_depreciable_assets(): @@ -41,12 +49,33 @@ def get_details_of_draft_or_submitted_depreciable_assets(): return records -def get_details_of_asset_finance_books_rows(asset_name): +def group_records_by_asset_name(records): + grouped_dict = {} + + for item in records: + key = list(item.keys())[0] + value = item[key] + + if value not in grouped_dict: + grouped_dict[value] = [] + + del item["asset_name"] + + grouped_dict[value].append(item) + + return grouped_dict + + +def get_asset_finance_books_map(): afb = frappe.qb.DocType("Asset Finance Book") + asset = frappe.qb.DocType("Asset") records = ( frappe.qb.from_(afb) + .join(asset) + .on(afb.parent == asset.name) .select( + asset.name.as_("asset_name"), afb.finance_book, afb.idx, afb.depreciation_method, @@ -55,23 +84,44 @@ def get_details_of_asset_finance_books_rows(asset_name): afb.rate_of_depreciation, afb.expected_value_after_useful_life, ) - .where(afb.parent == asset_name) + .where(asset.docstatus < 2) + .orderby(afb.idx) ).run(as_dict=True) - return records + asset_finance_books_map = group_records_by_asset_name(records) + + return asset_finance_books_map -def update_depreciation_schedules(asset_name, asset_depr_schedule_name, fb_row_idx): +def get_asset_depreciation_schedules_map(): ds = frappe.qb.DocType("Depreciation Schedule") + asset = frappe.qb.DocType("Asset") - depr_schedules = ( + records = ( frappe.qb.from_(ds) - .select(ds.name) - .where((ds.parent == asset_name) & (ds.finance_book_id == str(fb_row_idx))) + .join(asset) + .on(ds.parent == asset.name) + .select( + asset.name.as_("asset_name"), + ds.name, + ds.finance_book_id, + ) + .where(asset.docstatus < 2) .orderby(ds.idx) ).run(as_dict=True) - for idx, depr_schedule in enumerate(depr_schedules, start=1): + asset_depreciation_schedules_map = group_records_by_asset_name(records) + + return asset_depreciation_schedules_map + + +def update_depreciation_schedules( + depreciation_schedules, + asset_depr_schedule_name, +): + ds = frappe.qb.DocType("Depreciation Schedule") + + for idx, depr_schedule in enumerate(depreciation_schedules, start=1): ( frappe.qb.update(ds) .set(ds.idx, idx) From 881e95b44067b3de6aa7782804ed9ce7773e8324 Mon Sep 17 00:00:00 2001 From: Suraj Shetty Date: Mon, 26 Jun 2023 13:02:08 +0530 Subject: [PATCH 80/89] chore: Update required node version to v18 --- .github/workflows/patch.yml | 2 +- .github/workflows/semantic-commits.yml | 2 +- .github/workflows/server-tests-mariadb.yml | 2 +- .github/workflows/server-tests-postgres.yml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/patch.yml b/.github/workflows/patch.yml index e2d89573cb..aae2928bf0 100644 --- a/.github/workflows/patch.yml +++ b/.github/workflows/patch.yml @@ -52,7 +52,7 @@ jobs: - name: Setup Node uses: actions/setup-node@v2 with: - node-version: 14 + node-version: 18 check-latest: true - name: Add to Hosts diff --git a/.github/workflows/semantic-commits.yml b/.github/workflows/semantic-commits.yml index 1744bc33a9..0e478d551d 100644 --- a/.github/workflows/semantic-commits.yml +++ b/.github/workflows/semantic-commits.yml @@ -21,7 +21,7 @@ jobs: - uses: actions/setup-node@v3 with: - node-version: 14 + node-version: 18 check-latest: true - name: Check commit titles diff --git a/.github/workflows/server-tests-mariadb.yml b/.github/workflows/server-tests-mariadb.yml index 8959f7fd45..9b4db49d08 100644 --- a/.github/workflows/server-tests-mariadb.yml +++ b/.github/workflows/server-tests-mariadb.yml @@ -71,7 +71,7 @@ jobs: - name: Setup Node uses: actions/setup-node@v2 with: - node-version: 14 + node-version: 18 check-latest: true - name: Add to Hosts diff --git a/.github/workflows/server-tests-postgres.yml b/.github/workflows/server-tests-postgres.yml index df43801478..a688706657 100644 --- a/.github/workflows/server-tests-postgres.yml +++ b/.github/workflows/server-tests-postgres.yml @@ -59,7 +59,7 @@ jobs: - name: Setup Node uses: actions/setup-node@v2 with: - node-version: 14 + node-version: 18 check-latest: true - name: Add to Hosts From 9cf645e07f4f711d9761129fa6e5d7f6eb2ac04b Mon Sep 17 00:00:00 2001 From: Rohit Waghchaure Date: Mon, 26 Jun 2023 16:00:53 +0530 Subject: [PATCH 81/89] fix: serial and batch bundle values in the standard print format --- erpnext/controllers/print_settings.py | 1 + ...receipt_serial_and_batch_bundle_print.json | 4 +-- erpnext/stock/serial_batch_bundle.py | 30 ++++++++++++++++++- .../includes/serial_and_batch_bundle.html | 4 +++ 4 files changed, 36 insertions(+), 3 deletions(-) create mode 100644 erpnext/templates/print_formats/includes/serial_and_batch_bundle.html diff --git a/erpnext/controllers/print_settings.py b/erpnext/controllers/print_settings.py index c951154a9e..d86607d8db 100644 --- a/erpnext/controllers/print_settings.py +++ b/erpnext/controllers/print_settings.py @@ -10,6 +10,7 @@ def set_print_templates_for_item_table(doc, settings): doc.child_print_templates = { "items": { "qty": "templates/print_formats/includes/item_table_qty.html", + "serial_and_batch_bundle": "templates/print_formats/includes/serial_and_batch_bundle.html", } } diff --git a/erpnext/stock/print_format/purchase_receipt_serial_and_batch_bundle_print/purchase_receipt_serial_and_batch_bundle_print.json b/erpnext/stock/print_format/purchase_receipt_serial_and_batch_bundle_print/purchase_receipt_serial_and_batch_bundle_print.json index 21132e070c..a8ab8f6ac7 100644 --- a/erpnext/stock/print_format/purchase_receipt_serial_and_batch_bundle_print/purchase_receipt_serial_and_batch_bundle_print.json +++ b/erpnext/stock/print_format/purchase_receipt_serial_and_batch_bundle_print/purchase_receipt_serial_and_batch_bundle_print.json @@ -8,14 +8,14 @@ "docstatus": 0, "doctype": "Print Format", "font_size": 14, - "format_data": "[{\"fieldname\": \"print_heading_template\", \"fieldtype\": \"Custom HTML\", \"options\": \"
\\t\\t\\t\\t

Purchase Receipt

{{ doc.name }}\\t\\t\\t\\t

\"}, {\"fieldtype\": \"Section Break\", \"label\": \"\"}, {\"fieldtype\": \"Column Break\"}, {\"fieldname\": \"supplier_name\", \"print_hide\": 0, \"label\": \"Supplier Name\"}, {\"fieldname\": \"supplier_delivery_note\", \"print_hide\": 0, \"label\": \"Supplier Delivery Note\"}, {\"fieldname\": \"rack\", \"print_hide\": 0, \"label\": \"Rack\"}, {\"fieldtype\": \"Column Break\"}, {\"fieldname\": \"posting_date\", \"print_hide\": 0, \"label\": \"Date\"}, {\"fieldtype\": \"Column Break\"}, {\"fieldname\": \"apply_putaway_rule\", \"print_hide\": 0, \"label\": \"Apply Putaway Rule\"}, {\"fieldtype\": \"Section Break\", \"label\": \"Accounting Dimensions\"}, {\"fieldtype\": \"Column Break\"}, {\"fieldname\": \"region\", \"print_hide\": 0, \"label\": \"Region\"}, {\"fieldname\": \"function\", \"print_hide\": 0, \"label\": \"Function\"}, {\"fieldname\": \"depot\", \"print_hide\": 0, \"label\": \"Depot\"}, {\"fieldname\": \"cost_center\", \"print_hide\": 0, \"label\": \"Cost Center\"}, {\"fieldtype\": \"Column Break\"}, {\"fieldname\": \"location\", \"print_hide\": 0, \"label\": \"Location\"}, {\"fieldname\": \"country\", \"print_hide\": 0, \"label\": \"Country\"}, {\"fieldname\": \"project\", \"print_hide\": 0, \"label\": \"Project\"}, {\"fieldtype\": \"Section Break\", \"label\": \"Items\"}, {\"fieldtype\": \"Column Break\"}, {\"fieldname\": \"scan_barcode\", \"print_hide\": 0, \"label\": \"Scan Barcode\"}, {\"fieldtype\": \"Column Break\"}, {\"fieldname\": \"set_from_warehouse\", \"print_hide\": 0, \"label\": \"Set From Warehouse\"}, {\"fieldtype\": \"Column Break\"}, {\"fieldtype\": \"Section Break\", \"label\": \"\"}, {\"fieldtype\": \"Column Break\"}, {\"fieldname\": \"_custom_html\", \"print_hide\": 0, \"label\": \"Custom HTML\", \"fieldtype\": \"HTML\", \"options\": \"\\n\\t\\n\\t\\t\\n\\t\\t\\t\\n\\t\\t\\t\\n\\t\\t\\t\\n\\t\\t\\t\\n\\t\\t\\t\\n\\t\\t\\t\\n\\t\\t\\n\\t\\t{%- for row in doc.items -%}\\n\\t\\t\\n\\t\\t {% set bundle_data = get_serial_or_batch_nos(row.serial_and_batch_bundle) %}\\n\\t\\t {% set serial_nos = [] %}\\n {% set batches = {} %}\\n\\n\\t\\t\\t\\n\\t\\t\\t\\n\\t\\t\\t\\n\\t\\t\\t\\n\\t\\t\\t\\n\\t\\t\\t\\n\\t\\t\\t\\n\\t\\t\\n\\t\\t{%- endfor -%}\\n\\t\\n
SrItem NameDescriptionQtyRateAmount
{{ row.idx }}\\n\\t\\t\\t\\t{{ row.item_name }}\\n\\t\\t\\t\\t{% if row.item_code != row.item_name -%}\\n\\t\\t\\t\\t
Item Code: {{ row.item_code}}\\n\\t\\t\\t\\t{%- endif %}\\n\\t\\t\\t
\\n\\t\\t\\t\\t
{{ row.description }}
{{ row.qty }} {{ row.uom or row.stock_uom }}{{\\n\\t\\t\\t\\trow.get_formatted(\\\"rate\\\", doc) }}{{\\n\\t\\t\\t\\trow.get_formatted(\\\"amount\\\", doc) }}
\\n\"}, {\"fieldtype\": \"Section Break\", \"label\": \"\"}, {\"fieldtype\": \"Column Break\"}, {\"fieldname\": \"total_qty\", \"print_hide\": 0, \"label\": \"Total Quantity\"}, {\"fieldtype\": \"Column Break\"}, {\"fieldname\": \"total\", \"print_hide\": 0, \"label\": \"Total\"}, {\"fieldtype\": \"Section Break\", \"label\": \"\"}, {\"fieldtype\": \"Column Break\"}, {\"fieldname\": \"taxes\", \"print_hide\": 0, \"label\": \"Purchase Taxes and Charges\", \"visible_columns\": [{\"fieldname\": \"category\", \"print_width\": \"\", \"print_hide\": 0}, {\"fieldname\": \"add_deduct_tax\", \"print_width\": \"\", \"print_hide\": 0}, {\"fieldname\": \"charge_type\", \"print_width\": \"\", \"print_hide\": 0}, {\"fieldname\": \"row_id\", \"print_width\": \"\", \"print_hide\": 0}, {\"fieldname\": \"included_in_print_rate\", \"print_width\": \"\", \"print_hide\": 0}, {\"fieldname\": \"included_in_paid_amount\", \"print_width\": \"\", \"print_hide\": 0}, {\"fieldname\": \"account_head\", \"print_width\": \"\", \"print_hide\": 0}, {\"fieldname\": \"description\", \"print_width\": \"300px\", \"print_hide\": 0}, {\"fieldname\": \"rate\", \"print_width\": \"\", \"print_hide\": 0}, {\"fieldname\": \"region\", \"print_width\": \"\", \"print_hide\": 0}, {\"fieldname\": \"function\", \"print_width\": \"\", \"print_hide\": 0}, {\"fieldname\": \"location\", \"print_width\": \"\", \"print_hide\": 0}, {\"fieldname\": \"cost_center\", \"print_width\": \"\", \"print_hide\": 0}, {\"fieldname\": \"depot\", \"print_width\": \"\", \"print_hide\": 0}, {\"fieldname\": \"country\", \"print_width\": \"\", \"print_hide\": 0}, {\"fieldname\": \"account_currency\", \"print_width\": \"\", \"print_hide\": 0}, {\"fieldname\": \"tax_amount\", \"print_width\": \"\", \"print_hide\": 0}, {\"fieldname\": \"total\", \"print_width\": \"\", \"print_hide\": 0}]}, {\"fieldtype\": \"Section Break\", \"label\": \"Totals\"}, {\"fieldtype\": \"Column Break\"}, {\"fieldtype\": \"Column Break\"}, {\"fieldname\": \"grand_total\", \"print_hide\": 0, \"label\": \"Grand Total\"}, {\"fieldname\": \"rounded_total\", \"print_hide\": 0, \"label\": \"Rounded Total\"}, {\"fieldname\": \"in_words\", \"print_hide\": 0, \"label\": \"In Words\"}, {\"fieldname\": \"disable_rounded_total\", \"print_hide\": 0, \"label\": \"Disable Rounded Total\"}, {\"fieldtype\": \"Section Break\", \"label\": \"Supplier Address\"}, {\"fieldtype\": \"Column Break\"}, {\"fieldname\": \"address_display\", \"print_hide\": 0, \"label\": \"Address\"}, {\"fieldtype\": \"Column Break\"}, {\"fieldname\": \"contact_display\", \"print_hide\": 0, \"label\": \"Contact\"}, {\"fieldname\": \"contact_mobile\", \"print_hide\": 0, \"label\": \"Mobile No\"}, {\"fieldtype\": \"Section Break\", \"label\": \"Company Billing Address\"}, {\"fieldtype\": \"Column Break\"}, {\"fieldname\": \"billing_address\", \"print_hide\": 0, \"label\": \"Billing Address\"}, {\"fieldtype\": \"Column Break\"}, {\"fieldname\": \"billing_address_display\", \"print_hide\": 0, \"label\": \"Billing Address\"}, {\"fieldname\": \"terms\", \"print_hide\": 0, \"label\": \"Terms and Conditions\"}, {\"fieldtype\": \"Section Break\", \"label\": \"\"}, {\"fieldtype\": \"Column Break\"}, {\"fieldname\": \"_custom_html\", \"print_hide\": 0, \"label\": \"Custom HTML\", \"fieldtype\": \"HTML\", \"options\": \"\\n\\t\\n\\t\\t\\n\\t\\t\\t\\n\\t\\t\\t\\n\\t\\t\\t\\n\\t\\t\\t\\n\\t\\t\\t\\n\\t\\t\\n\\t\\t{%- for row in doc.items -%}\\n\\t\\t\\n\\t\\t {% set bundle_data = get_serial_or_batch_nos(row.serial_and_batch_bundle) %}\\n\\t\\t {% set serial_nos = [] %}\\n {% set batches = {} %}\\n \\n {% if bundle_data %}\\n\\t\\t\\t {% for data in bundle_data %}\\n\\t\\t\\t {% if data.serial_no %}\\n\\t\\t\\t {{ serial_nos.append(data.serial_no) or \\\"\\\" }}\\n\\t\\t\\t {% endif %}\\n\\t\\t\\t \\n\\t\\t\\t {% if data.batch_no %}\\n\\t\\t\\t {{ batches.update({data.batch_no: data.qty}) or \\\"\\\" }}\\n\\t\\t\\t {% endif %}\\n\\t\\t\\t {% endfor %}\\n\\t\\t\\t{% endif %}\\n\\n\\t\\t\\t\\n\\t\\t\\t\\n\\t\\t\\t\\n\\t\\t\\t\\n\\t\\t\\t\\n\\t\\t\\t\\n\\t\\t\\t\\n\\t\\t\\n\\t\\t{%- endfor -%}\\n\\t\\n
SrItem NameQtySerial NosBatch Nos (Qty)
{{ row.idx }}\\n\\t\\t\\t\\t{{ row.item_name }}\\n\\t\\t\\t\\t{% if row.item_code != row.item_name -%}\\n\\t\\t\\t\\t
Item Code: {{ row.item_code}}\\n\\t\\t\\t\\t{%- endif %}\\n\\t\\t\\t
{{ row.qty }} {{ row.uom or row.stock_uom }}{{ serial_nos|join(',') }}\\n\\t\\t\\t {% if batches %}\\n {% for batch_no, qty in batches.items() %}\\n

{{batch_no}} : {{qty}} {{ row.uom or row.stock_uom }}

\\n {% endfor %}\\n {% endif %}\\n\\t\\t\\t
\\n\"}]", + "format_data": "[{\"fieldname\": \"print_heading_template\", \"fieldtype\": \"Custom HTML\", \"options\": \"
\\t\\t\\t\\t

Purchase Receipt

{{ doc.name }}\\t\\t\\t\\t

\"}, {\"fieldtype\": \"Section Break\", \"label\": \"\"}, {\"fieldtype\": \"Column Break\"}, {\"fieldname\": \"supplier_name\", \"print_hide\": 0, \"label\": \"Supplier Name\"}, {\"fieldname\": \"supplier_delivery_note\", \"print_hide\": 0, \"label\": \"Supplier Delivery Note\"}, {\"fieldname\": \"rack\", \"print_hide\": 0, \"label\": \"Rack\"}, {\"fieldtype\": \"Column Break\"}, {\"fieldname\": \"posting_date\", \"print_hide\": 0, \"label\": \"Date\"}, {\"fieldtype\": \"Column Break\"}, {\"fieldname\": \"apply_putaway_rule\", \"print_hide\": 0, \"label\": \"Apply Putaway Rule\"}, {\"fieldtype\": \"Section Break\", \"label\": \"Accounting Dimensions\"}, {\"fieldtype\": \"Column Break\"}, {\"fieldname\": \"region\", \"print_hide\": 0, \"label\": \"Region\"}, {\"fieldname\": \"function\", \"print_hide\": 0, \"label\": \"Function\"}, {\"fieldname\": \"depot\", \"print_hide\": 0, \"label\": \"Depot\"}, {\"fieldname\": \"cost_center\", \"print_hide\": 0, \"label\": \"Cost Center\"}, {\"fieldtype\": \"Column Break\"}, {\"fieldname\": \"location\", \"print_hide\": 0, \"label\": \"Location\"}, {\"fieldname\": \"country\", \"print_hide\": 0, \"label\": \"Country\"}, {\"fieldname\": \"project\", \"print_hide\": 0, \"label\": \"Project\"}, {\"fieldtype\": \"Section Break\", \"label\": \"Items\"}, {\"fieldtype\": \"Column Break\"}, {\"fieldname\": \"scan_barcode\", \"print_hide\": 0, \"label\": \"Scan Barcode\"}, {\"fieldtype\": \"Column Break\"}, {\"fieldname\": \"set_from_warehouse\", \"print_hide\": 0, \"label\": \"Set From Warehouse\"}, {\"fieldtype\": \"Column Break\"}, {\"fieldtype\": \"Section Break\", \"label\": \"\"}, {\"fieldtype\": \"Column Break\"}, {\"fieldname\": \"_custom_html\", \"print_hide\": 0, \"label\": \"Custom HTML\", \"fieldtype\": \"HTML\", \"options\": \"\\n\\t\\n\\t\\t\\n\\t\\t\\t\\n\\t\\t\\t\\n\\t\\t\\t\\n\\t\\t\\t\\n\\t\\t\\t\\n\\t\\t\\t\\n\\t\\t\\n\\t\\t{%- for row in doc.items -%}\\n\\t\\t\\n\\t\\t {% set bundle_data = get_serial_or_batch_nos(row.serial_and_batch_bundle) %}\\n\\t\\t {% set serial_nos = [] %}\\n {% set batches = {} %}\\n\\n\\t\\t\\t\\n\\t\\t\\t\\n\\t\\t\\t\\n\\t\\t\\t\\n\\t\\t\\t\\n\\t\\t\\t\\n\\t\\t\\t\\n\\t\\t\\n\\t\\t{%- endfor -%}\\n\\t\\n
SrItem NameDescriptionQtyRateAmount
{{ row.idx }}\\n\\t\\t\\t\\t{{ row.item_name }}\\n\\t\\t\\t\\t{% if row.item_code != row.item_name -%}\\n\\t\\t\\t\\t
Item Code: {{ row.item_code}}\\n\\t\\t\\t\\t{%- endif %}\\n\\t\\t\\t
\\n\\t\\t\\t\\t
{{ row.description }}
{{ row.qty }} {{ row.uom or row.stock_uom }}{{\\n\\t\\t\\t\\trow.get_formatted(\\\"rate\\\", doc) }}{{\\n\\t\\t\\t\\trow.get_formatted(\\\"amount\\\", doc) }}
\\n\"}, {\"fieldtype\": \"Section Break\", \"label\": \"\"}, {\"fieldtype\": \"Column Break\"}, {\"fieldname\": \"total_qty\", \"print_hide\": 0, \"label\": \"Total Quantity\"}, {\"fieldtype\": \"Column Break\"}, {\"fieldname\": \"total\", \"print_hide\": 0, \"label\": \"Total\"}, {\"fieldtype\": \"Section Break\", \"label\": \"\"}, {\"fieldtype\": \"Column Break\"}, {\"fieldname\": \"taxes\", \"print_hide\": 0, \"label\": \"Purchase Taxes and Charges\", \"visible_columns\": [{\"fieldname\": \"category\", \"print_width\": \"\", \"print_hide\": 0}, {\"fieldname\": \"add_deduct_tax\", \"print_width\": \"\", \"print_hide\": 0}, {\"fieldname\": \"charge_type\", \"print_width\": \"\", \"print_hide\": 0}, {\"fieldname\": \"row_id\", \"print_width\": \"\", \"print_hide\": 0}, {\"fieldname\": \"included_in_print_rate\", \"print_width\": \"\", \"print_hide\": 0}, {\"fieldname\": \"included_in_paid_amount\", \"print_width\": \"\", \"print_hide\": 0}, {\"fieldname\": \"account_head\", \"print_width\": \"\", \"print_hide\": 0}, {\"fieldname\": \"description\", \"print_width\": \"300px\", \"print_hide\": 0}, {\"fieldname\": \"rate\", \"print_width\": \"\", \"print_hide\": 0}, {\"fieldname\": \"region\", \"print_width\": \"\", \"print_hide\": 0}, {\"fieldname\": \"function\", \"print_width\": \"\", \"print_hide\": 0}, {\"fieldname\": \"location\", \"print_width\": \"\", \"print_hide\": 0}, {\"fieldname\": \"cost_center\", \"print_width\": \"\", \"print_hide\": 0}, {\"fieldname\": \"depot\", \"print_width\": \"\", \"print_hide\": 0}, {\"fieldname\": \"country\", \"print_width\": \"\", \"print_hide\": 0}, {\"fieldname\": \"account_currency\", \"print_width\": \"\", \"print_hide\": 0}, {\"fieldname\": \"tax_amount\", \"print_width\": \"\", \"print_hide\": 0}, {\"fieldname\": \"total\", \"print_width\": \"\", \"print_hide\": 0}]}, {\"fieldtype\": \"Section Break\", \"label\": \"Totals\"}, {\"fieldtype\": \"Column Break\"}, {\"fieldtype\": \"Column Break\"}, {\"fieldname\": \"grand_total\", \"print_hide\": 0, \"label\": \"Grand Total\"}, {\"fieldname\": \"rounded_total\", \"print_hide\": 0, \"label\": \"Rounded Total\"}, {\"fieldname\": \"in_words\", \"print_hide\": 0, \"label\": \"In Words\"}, {\"fieldname\": \"disable_rounded_total\", \"print_hide\": 0, \"label\": \"Disable Rounded Total\"}, {\"fieldtype\": \"Section Break\", \"label\": \"Supplier Address\"}, {\"fieldtype\": \"Column Break\"}, {\"fieldname\": \"address_display\", \"print_hide\": 0, \"label\": \"Address\"}, {\"fieldtype\": \"Column Break\"}, {\"fieldname\": \"contact_display\", \"print_hide\": 0, \"label\": \"Contact\"}, {\"fieldname\": \"contact_mobile\", \"print_hide\": 0, \"label\": \"Mobile No\"}, {\"fieldtype\": \"Section Break\", \"label\": \"Company Billing Address\"}, {\"fieldtype\": \"Column Break\"}, {\"fieldname\": \"billing_address\", \"print_hide\": 0, \"label\": \"Billing Address\"}, {\"fieldtype\": \"Column Break\"}, {\"fieldname\": \"billing_address_display\", \"print_hide\": 0, \"label\": \"Billing Address\"}, {\"fieldname\": \"terms\", \"print_hide\": 0, \"label\": \"Terms and Conditions\"}, {\"fieldtype\": \"Section Break\", \"label\": \"\"}, {\"fieldtype\": \"Column Break\"}, {\"fieldname\": \"_custom_html\", \"print_hide\": 0, \"label\": \"Custom HTML\", \"fieldtype\": \"HTML\", \"options\": \"\\n\\t\\n\\t\\t\\n\\t\\t\\t\\n\\t\\t\\t\\n\\t\\t\\t\\n\\t\\t\\t\\n\\t\\t\\t\\n\\t\\t\\n\\t\\t{%- for row in doc.items -%}\\n\\t\\t\\n\\t\\t {% set bundle_data = frappe.get_all(\\\"Serial and Batch Entry\\\", \\n\\t\\t fields=[\\\"serial_no\\\", \\\"batch_no\\\", \\\"qty\\\"], \\n\\t\\t filters={\\\"parent\\\": row.serial_and_batch_bundle}) %}\\n\\t\\t {% set serial_nos = [] %}\\n {% set batches = {} %}\\n \\n {% if bundle_data %}\\n\\t\\t\\t {% for data in bundle_data %}\\n\\t\\t\\t {% if data.serial_no %}\\n\\t\\t\\t {{ serial_nos.append(data.serial_no) or \\\"\\\" }}\\n\\t\\t\\t {% endif %}\\n\\t\\t\\t \\n\\t\\t\\t {% if data.batch_no %}\\n\\t\\t\\t {{ batches.update({data.batch_no: data.qty}) or \\\"\\\" }}\\n\\t\\t\\t {% endif %}\\n\\t\\t\\t {% endfor %}\\n\\t\\t\\t{% endif %}\\n\\n\\t\\t\\t\\n\\t\\t\\t\\n\\t\\t\\t\\n\\t\\t\\t\\n\\t\\t\\t\\n\\t\\t\\t\\n\\t\\t\\t\\n\\t\\t\\n\\t\\t{%- endfor -%}\\n\\t\\n
SrItem NameQtySerial NosBatch Nos (Qty)
{{ row.idx }}\\n\\t\\t\\t\\t{{ row.item_name }}\\n\\t\\t\\t\\t{% if row.item_code != row.item_name -%}\\n\\t\\t\\t\\t
Item Code: {{ row.item_code}}\\n\\t\\t\\t\\t{%- endif %}\\n\\t\\t\\t
{{ row.qty }} {{ row.uom or row.stock_uom }}{{ serial_nos|join(',') }}\\n\\t\\t\\t {% if batches %}\\n {% for batch_no, qty in batches.items() %}\\n

{{batch_no}} : {{qty}} {{ row.uom or row.stock_uom }}

\\n {% endfor %}\\n {% endif %}\\n\\t\\t\\t
\\n\"}]", "idx": 0, "line_breaks": 0, "margin_bottom": 15.0, "margin_left": 15.0, "margin_right": 15.0, "margin_top": 15.0, - "modified": "2023-06-02 00:09:37.315002", + "modified": "2023-06-26 14:51:20.609682", "modified_by": "Administrator", "module": "Stock", "name": "Purchase Receipt Serial and Batch Bundle Print", diff --git a/erpnext/stock/serial_batch_bundle.py b/erpnext/stock/serial_batch_bundle.py index 2c18f99acd..d6c840f133 100644 --- a/erpnext/stock/serial_batch_bundle.py +++ b/erpnext/stock/serial_batch_bundle.py @@ -312,7 +312,35 @@ def get_serial_nos_from_bundle(serial_and_batch_bundle, serial_nos=None): def get_serial_or_batch_nos(bundle): - return frappe.get_all("Serial and Batch Entry", fields=["*"], filters={"parent": bundle}) + # For print format + + bundle_data = frappe.get_cached_value( + "Serial and Batch Bundle", bundle, ["has_serial_no", "has_batch_no"], as_dict=True + ) + + fields = [] + if bundle_data.has_serial_no: + fields.append("serial_no") + + if bundle_data.has_batch_no: + fields.extend(["batch_no", "qty"]) + + data = frappe.get_all("Serial and Batch Entry", fields=fields, filters={"parent": bundle}) + + if bundle_data.has_serial_no and not bundle_data.has_batch_no: + return ", ".join([d.serial_no for d in data]) + + elif bundle_data.has_batch_no: + html = "" + for d in data: + if d.serial_no: + html += f"" + else: + html += f"" + + html += "
{d.batch_no}{d.serial_no}{abs(d.qty)}
{d.batch_no}{abs(d.qty)}
" + + return html class SerialNoValuation(DeprecatedSerialNoValuation): diff --git a/erpnext/templates/print_formats/includes/serial_and_batch_bundle.html b/erpnext/templates/print_formats/includes/serial_and_batch_bundle.html new file mode 100644 index 0000000000..8e625863fb --- /dev/null +++ b/erpnext/templates/print_formats/includes/serial_and_batch_bundle.html @@ -0,0 +1,4 @@ +{% if doc.get("serial_and_batch_bundle") %} + {% set bundle_print = get_serial_or_batch_nos(doc.serial_and_batch_bundle) %} + {{bundle_print}} +{%- endif %} From af75f6cea7aac9f765201b8c97b687dec5dc67de Mon Sep 17 00:00:00 2001 From: ruthra kumar Date: Mon, 26 Jun 2023 15:31:20 +0530 Subject: [PATCH 82/89] refactor: simplify exchange logic on cr/dr note reconciliation --- .../payment_reconciliation.py | 38 ++++++++++--------- 1 file changed, 20 insertions(+), 18 deletions(-) diff --git a/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.py b/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.py index a709740d2f..216d4eccac 100644 --- a/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.py +++ b/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.py @@ -336,7 +336,6 @@ class PaymentReconciliation(Document): entry_list = [] dr_or_cr_notes = [] - difference_entries = [] for row in self.get("allocation"): reconciled_entry = [] if row.invoice_number and row.allocated_amount: @@ -348,16 +347,17 @@ class PaymentReconciliation(Document): payment_details = self.get_payment_details(row, dr_or_cr) reconciled_entry.append(payment_details) - if payment_details.difference_amount: - difference_entries.append( - self.make_difference_entry(payment_details, do_not_save_and_submit=bool(dr_or_cr_notes)) - ) + if payment_details.difference_amount and row.reference_type not in [ + "Sales Invoice", + "Purchase Invoice", + ]: + self.make_difference_entry(payment_details) if entry_list: reconcile_against_document(entry_list, skip_ref_details_update_for_pe) if dr_or_cr_notes: - reconcile_dr_cr_note(dr_or_cr_notes, difference_entries, self.company) + reconcile_dr_cr_note(dr_or_cr_notes, self.company) @frappe.whitelist() def reconcile(self): @@ -385,7 +385,7 @@ class PaymentReconciliation(Document): self.get_unreconciled_entries() - def make_difference_entry(self, row, do_not_save_and_submit=False): + def make_difference_entry(self, row): journal_entry = frappe.new_doc("Journal Entry") journal_entry.voucher_type = "Exchange Gain Or Loss" journal_entry.company = self.company @@ -433,9 +433,8 @@ class PaymentReconciliation(Document): journal_entry.append("accounts", journal_account) - if not do_not_save_and_submit: - journal_entry.save() - journal_entry.submit() + journal_entry.save() + journal_entry.submit() return journal_entry @@ -603,13 +602,16 @@ class PaymentReconciliation(Document): return condition -def reconcile_dr_cr_note(dr_cr_notes, difference_entries, company): - def find_difference_entry(voucher_type, voucher_no): - for jv in difference_entries: - accounts = iter(jv.accounts) - for account in accounts: - if account.reference_type == voucher_type and account.reference_name == voucher_no: - return next(accounts) +def reconcile_dr_cr_note(dr_cr_notes, company): + def get_difference_row(inv): + if inv.difference_amount != 0 and inv.difference_account: + difference_row = { + "account": inv.difference_account, + inv.dr_or_cr: abs(inv.difference_amount) if inv.difference_amount > 0 else 0, + reconcile_dr_or_cr: abs(inv.difference_amount) if inv.difference_amount < 0 else 0, + "cost_center": erpnext.get_default_cost_center(company), + } + return difference_row for inv in dr_cr_notes: voucher_type = "Credit Note" if inv.voucher_type == "Sales Invoice" else "Debit Note" @@ -656,7 +658,7 @@ def reconcile_dr_cr_note(dr_cr_notes, difference_entries, company): } ) - if difference_entry := find_difference_entry(inv.against_voucher_type, inv.against_voucher): + if difference_entry := get_difference_row(inv): jv.append("accounts", difference_entry) jv.flags.ignore_mandatory = True From 1f9ef6c48faf330c47daafae485ac833489db08d Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Mon, 26 Jun 2023 22:01:12 +0530 Subject: [PATCH 83/89] fix: TDS amount calculation post LDC breach --- .../tax_withholding_category/tax_withholding_category.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/erpnext/accounts/doctype/tax_withholding_category/tax_withholding_category.py b/erpnext/accounts/doctype/tax_withholding_category/tax_withholding_category.py index c2b7ff0f35..58792d1d8a 100644 --- a/erpnext/accounts/doctype/tax_withholding_category/tax_withholding_category.py +++ b/erpnext/accounts/doctype/tax_withholding_category/tax_withholding_category.py @@ -585,7 +585,9 @@ def get_tds_amount_from_ldc(ldc, parties, tax_details, posting_date, net_total): "supplier": ("in", parties), "apply_tds": 1, "docstatus": 1, + "tax_withholding_category": ldc.tax_withholding_category, "posting_date": ("between", (ldc.valid_from, ldc.valid_upto)), + "company": ldc.company, }, "sum(tax_withholding_net_total)", ) @@ -615,7 +617,7 @@ def is_valid_certificate( ): valid = False - available_amount = flt(certificate_limit) - flt(deducted_amount) - flt(current_amount) + available_amount = flt(certificate_limit) - flt(deducted_amount) if (getdate(valid_from) <= getdate(posting_date) <= getdate(valid_upto)) and available_amount > 0: valid = True From 742df8a25e6249e67eb755e449bdbe969e052b7e Mon Sep 17 00:00:00 2001 From: David Arnold Date: Tue, 27 Jun 2023 01:06:44 -0500 Subject: [PATCH 84/89] fix: delivery trip driver is only required on submit (#35876) This allows drafting trips and stops without yet deciding on the assignable driver which, in real life, may well be decided on after preparing and planning the trip. --- erpnext/stock/doctype/delivery_trip/delivery_trip.json | 7 ++++--- erpnext/stock/doctype/delivery_trip/delivery_trip.py | 3 +++ 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/erpnext/stock/doctype/delivery_trip/delivery_trip.json b/erpnext/stock/doctype/delivery_trip/delivery_trip.json index 11b71c2076..9d8fe46e8c 100644 --- a/erpnext/stock/doctype/delivery_trip/delivery_trip.json +++ b/erpnext/stock/doctype/delivery_trip/delivery_trip.json @@ -66,8 +66,7 @@ "fieldname": "driver", "fieldtype": "Link", "label": "Driver", - "options": "Driver", - "reqd": 1 + "options": "Driver" }, { "fetch_from": "driver.full_name", @@ -189,10 +188,11 @@ ], "is_submittable": 1, "links": [], - "modified": "2021-04-30 21:21:36.610142", + "modified": "2023-06-27 11:22:27.927637", "modified_by": "Administrator", "module": "Stock", "name": "Delivery Trip", + "naming_rule": "By \"Naming Series\" field", "owner": "Administrator", "permissions": [ { @@ -228,5 +228,6 @@ ], "sort_field": "modified", "sort_order": "DESC", + "states": [], "title_field": "driver_name" } \ No newline at end of file diff --git a/erpnext/stock/doctype/delivery_trip/delivery_trip.py b/erpnext/stock/doctype/delivery_trip/delivery_trip.py index 1febbded52..af2f4113e1 100644 --- a/erpnext/stock/doctype/delivery_trip/delivery_trip.py +++ b/erpnext/stock/doctype/delivery_trip/delivery_trip.py @@ -24,6 +24,9 @@ class DeliveryTrip(Document): ) def validate(self): + if self._action == "submit" and not self.driver: + frappe.throw(_("A driver must be set to submit.")) + self.validate_stop_addresses() def on_submit(self): From 3a00bf83d68be5f083f9290f9cfcdf756e67570a Mon Sep 17 00:00:00 2001 From: s-aga-r Date: Tue, 27 Jun 2023 11:48:29 +0530 Subject: [PATCH 85/89] fix(ux): PO Get Items From Open Material Requests --- erpnext/buying/doctype/purchase_order/purchase_order.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/buying/doctype/purchase_order/purchase_order.js b/erpnext/buying/doctype/purchase_order/purchase_order.js index c6c9f1f98a..8fa8f30554 100644 --- a/erpnext/buying/doctype/purchase_order/purchase_order.js +++ b/erpnext/buying/doctype/purchase_order/purchase_order.js @@ -286,7 +286,7 @@ erpnext.buying.PurchaseOrderController = class PurchaseOrderController extends e source_name: this.frm.doc.supplier, target: this.frm, setters: { - company: me.frm.doc.company + company: this.frm.doc.company }, get_query_filters: { docstatus: ["!=", 2], From af418d2342281c5a1fe6291971ee94e2eca42b3b Mon Sep 17 00:00:00 2001 From: HLD Date: Tue, 27 Jun 2023 15:47:52 +0800 Subject: [PATCH 86/89] fix: filter parent warehouses not showing (#35897) --- erpnext/stock/doctype/warehouse/warehouse.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/stock/doctype/warehouse/warehouse.js b/erpnext/stock/doctype/warehouse/warehouse.js index 87a23efc59..746a1cbaf1 100644 --- a/erpnext/stock/doctype/warehouse/warehouse.js +++ b/erpnext/stock/doctype/warehouse/warehouse.js @@ -13,7 +13,7 @@ frappe.ui.form.on("Warehouse", { }; }); - frm.set_query("parent_warehouse", function () { + frm.set_query("parent_warehouse", function (doc) { return { filters: { is_group: 1, From e832455790754385e9f64134889a5335883bc142 Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Wed, 28 Jun 2023 10:25:03 +0530 Subject: [PATCH 87/89] perf: improve item wise register reports (backport #35908) (#35911) perf: improve item wise register reports (#35908) (cherry picked from commit 33ee01174bb909ee46bb3d714d6f94fa0aefe48f) Co-authored-by: Anand Baburajan --- .../item_wise_purchase_register.py | 31 ++++++++++++------- .../item_wise_sales_register.py | 30 ++++++++++++------ 2 files changed, 39 insertions(+), 22 deletions(-) diff --git a/erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py b/erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py index 924c14bdb9..6fdb2f337c 100644 --- a/erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py +++ b/erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py @@ -15,7 +15,6 @@ from erpnext.accounts.report.item_wise_sales_register.item_wise_sales_register i get_group_by_conditions, get_tax_accounts, ) -from erpnext.selling.report.item_wise_sales_history.item_wise_sales_history import get_item_details def execute(filters=None): @@ -40,6 +39,16 @@ def _execute(filters=None, additional_table_columns=None, additional_query_colum tax_doctype="Purchase Taxes and Charges", ) + scrubbed_tax_fields = {} + + for tax in tax_columns: + scrubbed_tax_fields.update( + { + tax + " Rate": frappe.scrub(tax + " Rate"), + tax + " Amount": frappe.scrub(tax + " Amount"), + } + ) + po_pr_map = get_purchase_receipts_against_purchase_order(item_list) data = [] @@ -50,11 +59,7 @@ def _execute(filters=None, additional_table_columns=None, additional_query_colum if filters.get("group_by"): grand_total = get_grand_total(filters, "Purchase Invoice") - item_details = get_item_details() - for d in item_list: - item_record = item_details.get(d.item_code) - purchase_receipt = None if d.purchase_receipt: purchase_receipt = d.purchase_receipt @@ -67,8 +72,8 @@ def _execute(filters=None, additional_table_columns=None, additional_query_colum row = { "item_code": d.item_code, - "item_name": item_record.item_name if item_record else d.item_name, - "item_group": item_record.item_group if item_record else d.item_group, + "item_name": d.pi_item_name if d.pi_item_name else d.i_item_name, + "item_group": d.pi_item_group if d.pi_item_group else d.i_item_group, "description": d.description, "invoice": d.parent, "posting_date": d.posting_date, @@ -101,8 +106,8 @@ def _execute(filters=None, additional_table_columns=None, additional_query_colum item_tax = itemised_tax.get(d.name, {}).get(tax, {}) row.update( { - frappe.scrub(tax + " Rate"): item_tax.get("tax_rate", 0), - frappe.scrub(tax + " Amount"): item_tax.get("tax_amount", 0), + scrubbed_tax_fields[tax + " Rate"]: item_tax.get("tax_rate", 0), + scrubbed_tax_fields[tax + " Amount"]: item_tax.get("tax_amount", 0), } ) total_tax += flt(item_tax.get("tax_amount")) @@ -325,15 +330,17 @@ def get_items(filters, additional_query_columns): `tabPurchase Invoice`.supplier, `tabPurchase Invoice`.remarks, `tabPurchase Invoice`.base_net_total, `tabPurchase Invoice`.unrealized_profit_loss_account, `tabPurchase Invoice Item`.`item_code`, `tabPurchase Invoice Item`.description, - `tabPurchase Invoice Item`.`item_name`, `tabPurchase Invoice Item`.`item_group`, + `tabPurchase Invoice Item`.`item_name` as pi_item_name, `tabPurchase Invoice Item`.`item_group` as pi_item_group, + `tabItem`.`item_name` as i_item_name, `tabItem`.`item_group` as i_item_group, `tabPurchase Invoice Item`.`project`, `tabPurchase Invoice Item`.`purchase_order`, `tabPurchase Invoice Item`.`purchase_receipt`, `tabPurchase Invoice Item`.`po_detail`, `tabPurchase Invoice Item`.`expense_account`, `tabPurchase Invoice Item`.`stock_qty`, `tabPurchase Invoice Item`.`stock_uom`, `tabPurchase Invoice Item`.`base_net_amount`, `tabPurchase Invoice`.`supplier_name`, `tabPurchase Invoice`.`mode_of_payment` {0} - from `tabPurchase Invoice`, `tabPurchase Invoice Item` + from `tabPurchase Invoice`, `tabPurchase Invoice Item`, `tabItem` where `tabPurchase Invoice`.name = `tabPurchase Invoice Item`.`parent` and - `tabPurchase Invoice`.docstatus = 1 %s + `tabItem`.name = `tabPurchase Invoice Item`.`item_code` and + `tabPurchase Invoice`.docstatus = 1 %s """.format( additional_query_columns ) diff --git a/erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py b/erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py index 0ebe13f4f3..bd7d02e043 100644 --- a/erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py +++ b/erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py @@ -11,7 +11,6 @@ from frappe.utils.xlsxutils import handle_html from erpnext.accounts.report.sales_register.sales_register import get_mode_of_payments from erpnext.selling.report.item_wise_sales_history.item_wise_sales_history import ( get_customer_details, - get_item_details, ) @@ -35,6 +34,16 @@ def _execute( if item_list: itemised_tax, tax_columns = get_tax_accounts(item_list, columns, company_currency) + scrubbed_tax_fields = {} + + for tax in tax_columns: + scrubbed_tax_fields.update( + { + tax + " Rate": frappe.scrub(tax + " Rate"), + tax + " Amount": frappe.scrub(tax + " Amount"), + } + ) + mode_of_payments = get_mode_of_payments(set(d.parent for d in item_list)) so_dn_map = get_delivery_notes_against_sales_order(item_list) @@ -47,11 +56,9 @@ def _execute( grand_total = get_grand_total(filters, "Sales Invoice") customer_details = get_customer_details() - item_details = get_item_details() for d in item_list: customer_record = customer_details.get(d.customer) - item_record = item_details.get(d.item_code) delivery_note = None if d.delivery_note: @@ -64,8 +71,8 @@ def _execute( row = { "item_code": d.item_code, - "item_name": item_record.item_name if item_record else d.item_name, - "item_group": item_record.item_group if item_record else d.item_group, + "item_name": d.si_item_name if d.si_item_name else d.i_item_name, + "item_group": d.si_item_group if d.si_item_group else d.i_item_group, "description": d.description, "invoice": d.parent, "posting_date": d.posting_date, @@ -107,8 +114,8 @@ def _execute( item_tax = itemised_tax.get(d.name, {}).get(tax, {}) row.update( { - frappe.scrub(tax + " Rate"): item_tax.get("tax_rate", 0), - frappe.scrub(tax + " Amount"): item_tax.get("tax_amount", 0), + scrubbed_tax_fields[tax + " Rate"]: item_tax.get("tax_rate", 0), + scrubbed_tax_fields[tax + " Amount"]: item_tax.get("tax_amount", 0), } ) if item_tax.get("is_other_charges"): @@ -404,15 +411,18 @@ def get_items(filters, additional_query_columns, additional_conditions=None): `tabSales Invoice Item`.project, `tabSales Invoice Item`.item_code, `tabSales Invoice Item`.description, `tabSales Invoice Item`.`item_name`, `tabSales Invoice Item`.`item_group`, + `tabSales Invoice Item`.`item_name` as si_item_name, `tabSales Invoice Item`.`item_group` as si_item_group, + `tabItem`.`item_name` as i_item_name, `tabItem`.`item_group` as i_item_group, `tabSales Invoice Item`.sales_order, `tabSales Invoice Item`.delivery_note, `tabSales Invoice Item`.income_account, `tabSales Invoice Item`.cost_center, `tabSales Invoice Item`.stock_qty, `tabSales Invoice Item`.stock_uom, `tabSales Invoice Item`.base_net_rate, `tabSales Invoice Item`.base_net_amount, `tabSales Invoice`.customer_name, `tabSales Invoice`.customer_group, `tabSales Invoice Item`.so_detail, `tabSales Invoice`.update_stock, `tabSales Invoice Item`.uom, `tabSales Invoice Item`.qty {0} - from `tabSales Invoice`, `tabSales Invoice Item` - where `tabSales Invoice`.name = `tabSales Invoice Item`.parent - and `tabSales Invoice`.docstatus = 1 {1} + from `tabSales Invoice`, `tabSales Invoice Item`, `tabItem` + where `tabSales Invoice`.name = `tabSales Invoice Item`.parent and + `tabItem`.name = `tabSales Invoice Item`.`item_code` and + `tabSales Invoice`.docstatus = 1 {1} """.format( additional_query_columns or "", conditions ), From 5113a417a1dc6e4efb75ba035c9b885d0d98d98d Mon Sep 17 00:00:00 2001 From: Gursheen Kaur Anand <40693548+GursheenK@users.noreply.github.com> Date: Wed, 28 Jun 2023 11:22:40 +0530 Subject: [PATCH 88/89] fix!: UX of supplier linking with supplier users on portal pages (#35836) * fix: create and add Portal Users child table in Supplier/Customer Issue #35772 * fix: modify the original permission check hook * fix: auto-add role for portal users * fix: added patch for auto-populating portal users * fix: modify patch to fetch users correctly * fix: remove unnecessary code for updating naming_series * fix(UX): show portal user in list view Also split columns to reduce whitespace. * refactor: simpler role checking * fix: consider parenttype while fetching portal user * refactor: simpler code, rename variable * test: supplier portal user can access their docs * refactor: only add role if not added * refactor: rename and move patch to supplier * refactor: dont add role if no perm or existing doc * fix: add role before save * refactor: run query directly * refactor: split patch and apply roles - if role isn't present dont add portal user - ignore failure as it's not critical * test: fix permission creation for webform test --------- Co-authored-by: Ankush Menat --- .../doctype/supplier/patches/__init__.py | 0 .../patches/migrate_supplier_portal_users.py | 56 +++++++++++++++++++ erpnext/buying/doctype/supplier/supplier.js | 8 +++ erpnext/buying/doctype/supplier/supplier.json | 23 +++++++- erpnext/buying/doctype/supplier/supplier.py | 31 +++++++++- .../buying/doctype/supplier/test_supplier.py | 26 +++++++++ .../controllers/website_list_for_contact.py | 54 ++++++++++++------ erpnext/patches.txt | 3 +- erpnext/selling/doctype/customer/customer.js | 8 +++ .../selling/doctype/customer/customer.json | 18 +++++- erpnext/selling/doctype/customer/customer.py | 6 ++ erpnext/tests/test_webform.py | 30 +++------- .../utilities/doctype/portal_user/__init__.py | 0 .../doctype/portal_user/portal_user.json | 34 +++++++++++ .../doctype/portal_user/portal_user.py | 9 +++ 15 files changed, 259 insertions(+), 47 deletions(-) create mode 100644 erpnext/buying/doctype/supplier/patches/__init__.py create mode 100644 erpnext/buying/doctype/supplier/patches/migrate_supplier_portal_users.py create mode 100644 erpnext/utilities/doctype/portal_user/__init__.py create mode 100644 erpnext/utilities/doctype/portal_user/portal_user.json create mode 100644 erpnext/utilities/doctype/portal_user/portal_user.py diff --git a/erpnext/buying/doctype/supplier/patches/__init__.py b/erpnext/buying/doctype/supplier/patches/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/erpnext/buying/doctype/supplier/patches/migrate_supplier_portal_users.py b/erpnext/buying/doctype/supplier/patches/migrate_supplier_portal_users.py new file mode 100644 index 0000000000..5834952d5b --- /dev/null +++ b/erpnext/buying/doctype/supplier/patches/migrate_supplier_portal_users.py @@ -0,0 +1,56 @@ +import os + +import frappe + +in_ci = os.environ.get("CI") + + +def execute(): + try: + contacts = get_portal_user_contacts() + add_portal_users(contacts) + except Exception: + frappe.db.rollback() + frappe.log_error("Failed to migrate portal users") + + if in_ci: # TODO: better way to handle this. + raise + + +def get_portal_user_contacts(): + contact = frappe.qb.DocType("Contact") + dynamic_link = frappe.qb.DocType("Dynamic Link") + + return ( + frappe.qb.from_(contact) + .inner_join(dynamic_link) + .on(contact.name == dynamic_link.parent) + .select( + (dynamic_link.link_doctype).as_("doctype"), + (dynamic_link.link_name).as_("parent"), + (contact.email_id).as_("portal_user"), + ) + .where( + (dynamic_link.parenttype == "Contact") + & (dynamic_link.link_doctype.isin(["Supplier", "Customer"])) + ) + ).run(as_dict=True) + + +def add_portal_users(contacts): + for contact in contacts: + user = frappe.db.get_value("User", {"email": contact.portal_user}, "name") + if not user: + continue + + roles = frappe.get_roles(user) + required_role = contact.doctype + if required_role not in roles: + continue + + portal_user_doc = frappe.new_doc("Portal User") + portal_user_doc.parenttype = contact.doctype + portal_user_doc.parentfield = "portal_users" + portal_user_doc.parent = contact.parent + portal_user_doc.user = user + portal_user_doc.insert() diff --git a/erpnext/buying/doctype/supplier/supplier.js b/erpnext/buying/doctype/supplier/supplier.js index 1ae6f03647..a536578b2e 100644 --- a/erpnext/buying/doctype/supplier/supplier.js +++ b/erpnext/buying/doctype/supplier/supplier.js @@ -42,6 +42,14 @@ frappe.ui.form.on("Supplier", { } }; }); + + frm.set_query("user", "portal_users", function(doc) { + return { + filters: { + "ignore_user_type": true, + } + }; + }); }, refresh: function (frm) { diff --git a/erpnext/buying/doctype/supplier/supplier.json b/erpnext/buying/doctype/supplier/supplier.json index f0097898f6..b3b6185e35 100644 --- a/erpnext/buying/doctype/supplier/supplier.json +++ b/erpnext/buying/doctype/supplier/supplier.json @@ -68,7 +68,10 @@ "on_hold", "hold_type", "column_break_59", - "release_date" + "release_date", + "portal_users_tab", + "portal_users", + "column_break_1mqv" ], "fields": [ { @@ -445,6 +448,21 @@ { "fieldname": "column_break_59", "fieldtype": "Column Break" + }, + { + "fieldname": "portal_users_tab", + "fieldtype": "Tab Break", + "label": "Portal Users" + }, + { + "fieldname": "portal_users", + "fieldtype": "Table", + "label": "Supplier Portal Users", + "options": "Portal User" + }, + { + "fieldname": "column_break_1mqv", + "fieldtype": "Column Break" } ], "icon": "fa fa-user", @@ -457,7 +475,7 @@ "link_fieldname": "party" } ], - "modified": "2023-05-09 15:34:13.408932", + "modified": "2023-06-26 14:20:00.961554", "modified_by": "Administrator", "module": "Buying", "name": "Supplier", @@ -489,7 +507,6 @@ "read": 1, "report": 1, "role": "Purchase Master Manager", - "set_user_permissions": 1, "share": 1, "write": 1 }, diff --git a/erpnext/buying/doctype/supplier/supplier.py b/erpnext/buying/doctype/supplier/supplier.py index 01b5c8f064..31bf439dbb 100644 --- a/erpnext/buying/doctype/supplier/supplier.py +++ b/erpnext/buying/doctype/supplier/supplier.py @@ -16,6 +16,7 @@ from erpnext.accounts.party import ( # noqa get_timeline_data, validate_party_accounts, ) +from erpnext.controllers.website_list_for_contact import add_role_for_portal_user from erpnext.utilities.transaction_base import TransactionBase @@ -46,12 +47,35 @@ class Supplier(TransactionBase): self.name = set_name_from_naming_options(frappe.get_meta(self.doctype).autoname, self) def on_update(self): - if not self.naming_series: - self.naming_series = "" - self.create_primary_contact() self.create_primary_address() + def add_role_for_user(self): + for portal_user in self.portal_users: + add_role_for_portal_user(portal_user, "Supplier") + + def _add_supplier_role(self, portal_user): + if not portal_user.is_new(): + return + + user_doc = frappe.get_doc("User", portal_user.user) + roles = {r.role for r in user_doc.roles} + + if "Supplier" in roles: + return + + if "System Manager" not in frappe.get_roles(): + frappe.msgprint( + _("Please add 'Supplier' role to user {0}.").format(portal_user.user), + alert=True, + ) + return + + user_doc.add_roles("Supplier") + frappe.msgprint( + _("Added Supplier Role to User {0}.").format(frappe.bold(user_doc.name)), alert=True + ) + def validate(self): self.flags.is_new_doc = self.is_new() @@ -62,6 +86,7 @@ class Supplier(TransactionBase): validate_party_accounts(self) self.validate_internal_supplier() + self.add_role_for_user() @frappe.whitelist() def get_supplier_group_details(self): diff --git a/erpnext/buying/doctype/supplier/test_supplier.py b/erpnext/buying/doctype/supplier/test_supplier.py index 7a205ac20c..7be1d834a6 100644 --- a/erpnext/buying/doctype/supplier/test_supplier.py +++ b/erpnext/buying/doctype/supplier/test_supplier.py @@ -7,6 +7,7 @@ from frappe.custom.doctype.property_setter.property_setter import make_property_ from frappe.test_runner import make_test_records from erpnext.accounts.party import get_due_date +from erpnext.controllers.website_list_for_contact import get_customers_suppliers from erpnext.exceptions import PartyDisabled test_dependencies = ["Payment Term", "Payment Terms Template"] @@ -195,6 +196,9 @@ class TestSupplier(FrappeTestCase): def create_supplier(**args): args = frappe._dict(args) + if not args.supplier_name: + args.supplier_name = frappe.generate_hash() + if frappe.db.exists("Supplier", args.supplier_name): return frappe.get_doc("Supplier", args.supplier_name) @@ -209,3 +213,25 @@ def create_supplier(**args): ).insert() return doc + + +class TestSupplierPortal(FrappeTestCase): + def test_portal_user_can_access_supplier_data(self): + + supplier = create_supplier() + + user = frappe.generate_hash() + "@example.com" + frappe.new_doc( + "User", + first_name="Supplier Portal User", + email=user, + send_welcome_email=False, + ).insert() + + supplier.append("portal_users", {"user": user}) + supplier.save() + + frappe.set_user(user) + _, suppliers = get_customers_suppliers("Purchase Order", user) + + self.assertIn(supplier.name, suppliers) diff --git a/erpnext/controllers/website_list_for_contact.py b/erpnext/controllers/website_list_for_contact.py index 7c3c38706d..642722ae6b 100644 --- a/erpnext/controllers/website_list_for_contact.py +++ b/erpnext/controllers/website_list_for_contact.py @@ -232,22 +232,8 @@ def get_customers_suppliers(doctype, user): has_supplier_field = meta.has_field("supplier") if has_common(["Supplier", "Customer"], frappe.get_roles(user)): - contacts = frappe.db.sql( - """ - select - `tabContact`.email_id, - `tabDynamic Link`.link_doctype, - `tabDynamic Link`.link_name - from - `tabContact`, `tabDynamic Link` - where - `tabContact`.name=`tabDynamic Link`.parent and `tabContact`.email_id =%s - """, - user, - as_dict=1, - ) - customers = [c.link_name for c in contacts if c.link_doctype == "Customer"] - suppliers = [c.link_name for c in contacts if c.link_doctype == "Supplier"] + suppliers = get_parents_for_user("Supplier") + customers = get_parents_for_user("Customer") elif frappe.has_permission(doctype, "read", user=user): customer_list = frappe.get_list("Customer") customers = suppliers = [customer.name for customer in customer_list] @@ -255,6 +241,17 @@ def get_customers_suppliers(doctype, user): return customers if has_customer_field else None, suppliers if has_supplier_field else None +def get_parents_for_user(parenttype: str) -> list[str]: + portal_user = frappe.qb.DocType("Portal User") + + return ( + frappe.qb.from_(portal_user) + .select(portal_user.parent) + .where(portal_user.user == frappe.session.user) + .where(portal_user.parenttype == parenttype) + ).run(pluck="name") + + def has_website_permission(doc, ptype, user, verbose=False): doctype = doc.doctype customers, suppliers = get_customers_suppliers(doctype, user) @@ -282,3 +279,28 @@ def get_customer_field_name(doctype): return "party_name" else: return "customer" + + +def add_role_for_portal_user(portal_user, role): + """When a new portal user is added, give appropriate roles to user if + posssible, else warn user to add roles.""" + if not portal_user.is_new(): + return + + user_doc = frappe.get_doc("User", portal_user.user) + roles = {r.role for r in user_doc.roles} + + if role in roles: + return + + if "System Manager" not in frappe.get_roles(): + frappe.msgprint( + _("Please add {1} role to user {0}.").format(portal_user.user, role), + alert=True, + ) + return + + user_doc.add_roles(role) + frappe.msgprint( + _("Added {1} Role to User {0}.").format(frappe.bold(user_doc.name), role), alert=True + ) diff --git a/erpnext/patches.txt b/erpnext/patches.txt index 8c0fa6bbcd..fe6346e81e 100644 --- a/erpnext/patches.txt +++ b/erpnext/patches.txt @@ -339,4 +339,5 @@ execute:frappe.delete_doc('DocType', 'Cash Flow Mapper', ignore_missing=True) execute:frappe.delete_doc('DocType', 'Cash Flow Mapping Template', ignore_missing=True) execute:frappe.delete_doc('DocType', 'Cash Flow Mapping Accounts', ignore_missing=True) erpnext.patches.v14_0.cleanup_workspaces -erpnext.patches.v14_0.set_report_in_process_SOA +erpnext.patches.v14_0.set_report_in_process_SOA +erpnext.buying.doctype.supplier.patches.migrate_supplier_portal_users diff --git a/erpnext/selling/doctype/customer/customer.js b/erpnext/selling/doctype/customer/customer.js index b53f339229..3a446e171a 100644 --- a/erpnext/selling/doctype/customer/customer.js +++ b/erpnext/selling/doctype/customer/customer.js @@ -63,6 +63,14 @@ frappe.ui.form.on("Customer", { } } }); + + frm.set_query("user", "portal_users", function() { + return { + filters: { + "ignore_user_type": true, + } + }; + }); }, customer_primary_address: function(frm){ if(frm.doc.customer_primary_address){ diff --git a/erpnext/selling/doctype/customer/customer.json b/erpnext/selling/doctype/customer/customer.json index 72a1594b2d..edfe0050de 100644 --- a/erpnext/selling/doctype/customer/customer.json +++ b/erpnext/selling/doctype/customer/customer.json @@ -81,7 +81,9 @@ "dn_required", "column_break_53", "is_frozen", - "disabled" + "disabled", + "portal_users_tab", + "portal_users" ], "fields": [ { @@ -555,6 +557,17 @@ { "fieldname": "column_break_54", "fieldtype": "Column Break" + }, + { + "fieldname": "portal_users_tab", + "fieldtype": "Tab Break", + "label": "Portal Users" + }, + { + "fieldname": "portal_users", + "fieldtype": "Table", + "label": "Customer Portal Users", + "options": "Portal User" } ], "icon": "fa fa-user", @@ -568,7 +581,7 @@ "link_fieldname": "party" } ], - "modified": "2023-05-09 15:38:40.255193", + "modified": "2023-06-22 13:21:10.678382", "modified_by": "Administrator", "module": "Selling", "name": "Customer", @@ -607,7 +620,6 @@ "read": 1, "report": 1, "role": "Sales Master Manager", - "set_user_permissions": 1, "share": 1, "write": 1 }, diff --git a/erpnext/selling/doctype/customer/customer.py b/erpnext/selling/doctype/customer/customer.py index 6367e3cb6a..555db59b08 100644 --- a/erpnext/selling/doctype/customer/customer.py +++ b/erpnext/selling/doctype/customer/customer.py @@ -22,6 +22,7 @@ from erpnext.accounts.party import ( # noqa get_timeline_data, validate_party_accounts, ) +from erpnext.controllers.website_list_for_contact import add_role_for_portal_user from erpnext.utilities.transaction_base import TransactionBase @@ -82,6 +83,7 @@ class Customer(TransactionBase): self.check_customer_group_change() self.validate_default_bank_account() self.validate_internal_customer() + self.add_role_for_user() # set loyalty program tier if frappe.db.exists("Customer", self.name): @@ -170,6 +172,10 @@ class Customer(TransactionBase): self.update_customer_groups() + def add_role_for_user(self): + for portal_user in self.portal_users: + add_role_for_portal_user(portal_user, "Customer") + def update_customer_groups(self): ignore_doctypes = ["Lead", "Opportunity", "POS Profile", "Tax Rule", "Pricing Rule"] if frappe.flags.customer_group_changed: diff --git a/erpnext/tests/test_webform.py b/erpnext/tests/test_webform.py index 202467b545..af50a057b8 100644 --- a/erpnext/tests/test_webform.py +++ b/erpnext/tests/test_webform.py @@ -3,18 +3,21 @@ import unittest import frappe from erpnext.buying.doctype.purchase_order.test_purchase_order import create_purchase_order +from erpnext.buying.doctype.supplier.test_supplier import create_supplier class TestWebsite(unittest.TestCase): def test_permission_for_custom_doctype(self): create_user("Supplier 1", "supplier1@gmail.com") create_user("Supplier 2", "supplier2@gmail.com") - create_supplier_with_contact( - "Supplier1", "All Supplier Groups", "Supplier 1", "supplier1@gmail.com" - ) - create_supplier_with_contact( - "Supplier2", "All Supplier Groups", "Supplier 2", "supplier2@gmail.com" - ) + + supplier1 = create_supplier(supplier_name="Supplier1") + supplier2 = create_supplier(supplier_name="Supplier2") + supplier1.append("portal_users", {"user": "supplier1@gmail.com"}) + supplier1.save() + supplier2.append("portal_users", {"user": "supplier2@gmail.com"}) + supplier2.save() + po1 = create_purchase_order(supplier="Supplier1") po2 = create_purchase_order(supplier="Supplier2") @@ -61,21 +64,6 @@ def create_user(name, email): ).insert(ignore_if_duplicate=True) -def create_supplier_with_contact(name, group, contact_name, contact_email): - supplier = frappe.get_doc( - {"doctype": "Supplier", "supplier_name": name, "supplier_group": group} - ).insert(ignore_if_duplicate=True) - - if not frappe.db.exists("Contact", contact_name + "-1-" + name): - new_contact = frappe.new_doc("Contact") - new_contact.first_name = contact_name - new_contact.is_primary_contact = (True,) - new_contact.append("links", {"link_doctype": "Supplier", "link_name": supplier.name}) - new_contact.append("email_ids", {"email_id": contact_email, "is_primary": 1}) - - new_contact.insert(ignore_mandatory=True) - - def create_custom_doctype(): frappe.get_doc( { diff --git a/erpnext/utilities/doctype/portal_user/__init__.py b/erpnext/utilities/doctype/portal_user/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/erpnext/utilities/doctype/portal_user/portal_user.json b/erpnext/utilities/doctype/portal_user/portal_user.json new file mode 100644 index 0000000000..361166cb65 --- /dev/null +++ b/erpnext/utilities/doctype/portal_user/portal_user.json @@ -0,0 +1,34 @@ +{ + "actions": [], + "allow_rename": 1, + "creation": "2023-06-20 14:01:35.362233", + "doctype": "DocType", + "editable_grid": 1, + "engine": "InnoDB", + "field_order": [ + "user" + ], + "fields": [ + { + "fieldname": "user", + "fieldtype": "Link", + "in_list_view": 1, + "label": "User", + "options": "User", + "reqd": 1, + "search_index": 1 + } + ], + "index_web_pages_for_search": 1, + "istable": 1, + "links": [], + "modified": "2023-06-26 14:15:34.695605", + "modified_by": "Administrator", + "module": "Utilities", + "name": "Portal User", + "owner": "Administrator", + "permissions": [], + "sort_field": "modified", + "sort_order": "DESC", + "states": [] +} \ No newline at end of file diff --git a/erpnext/utilities/doctype/portal_user/portal_user.py b/erpnext/utilities/doctype/portal_user/portal_user.py new file mode 100644 index 0000000000..2e0064d198 --- /dev/null +++ b/erpnext/utilities/doctype/portal_user/portal_user.py @@ -0,0 +1,9 @@ +# Copyright (c) 2023, Frappe Technologies Pvt. Ltd. and contributors +# For license information, please see license.txt + +# import frappe +from frappe.model.document import Document + + +class PortalUser(Document): + pass From b9e9204e522ea46dfcefc16deed474dd4e7d78d9 Mon Sep 17 00:00:00 2001 From: Gursheen Kaur Anand <40693548+GursheenK@users.noreply.github.com> Date: Wed, 28 Jun 2023 15:39:00 +0530 Subject: [PATCH 89/89] fix: create multiple variants button count and status (#35915) fix: change class for fetching columns in multiple variants --- erpnext/stock/doctype/item/item.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/stock/doctype/item/item.js b/erpnext/stock/doctype/item/item.js index 6f1f981e2b..31a3ecbc47 100644 --- a/erpnext/stock/doctype/item/item.js +++ b/erpnext/stock/doctype/item/item.js @@ -590,7 +590,7 @@ $.extend(erpnext.item, { let selected_attributes = {}; me.multiple_variant_dialog.$wrapper.find('.form-column').each((i, col) => { if(i===0) return; - let attribute_name = $(col).find('.control-label').html().trim(); + let attribute_name = $(col).find('.column-label').html().trim(); selected_attributes[attribute_name] = []; let checked_opts = $(col).find('.checkbox input'); checked_opts.each((i, opt) => {