From a1d4b78fbe946c213288d4c681a8b36a38fdc099 Mon Sep 17 00:00:00 2001 From: Anand Doshi Date: Tue, 26 Feb 2013 18:09:47 +0530 Subject: [PATCH] started with Auto Inventory Accounting - test case for purchase receipt --- accounts/doctype/account/test_account.py | 18 +- .../purchase_invoice/purchase_invoice.py | 2 +- controllers/accounts_controller.py | 33 ++- controllers/buying_controller.py | 25 +- setup/doctype/company/company.py | 211 +++++++------- setup/doctype/company/company.txt | 29 +- stock/doctype/delivery_note/delivery_note.py | 7 +- .../purchase_receipt/purchase_receipt.py | 64 ++++- .../purchase_receipt/test_purchase_receipt.py | 267 +++++++----------- 9 files changed, 341 insertions(+), 315 deletions(-) diff --git a/accounts/doctype/account/test_account.py b/accounts/doctype/account/test_account.py index db2ca19ec0..ad6319c2b5 100644 --- a/accounts/doctype/account/test_account.py +++ b/accounts/doctype/account/test_account.py @@ -1,27 +1,41 @@ +from __future__ import unicode_literals +import webnotes + def make_test_records(verbose): from webnotes.test_runner import make_test_objects accounts = [ # [account_name, parent_account, group_or_ledger] ["_Test Account Bank Account", "Bank Accounts - _TC", "Ledger"], + ["_Test Account Stock Expenses", "Direct Expenses - _TC", "Group"], ["_Test Account Shipping Charges", "_Test Account Stock Expenses - _TC", "Ledger"], ["_Test Account Customs Duty", "_Test Account Stock Expenses - _TC", "Ledger"], + ["_Test Account Tax Assets", "Current Assets - _TC", "Group"], ["_Test Account VAT", "_Test Account Tax Assets - _TC", "Ledger"], ["_Test Account Service Tax", "_Test Account Tax Assets - _TC", "Ledger"], + ["_Test Account Cost for Goods Sold", "Expenses - _TC", "Ledger"], ["_Test Account Excise Duty", "_Test Account Tax Assets - _TC", "Ledger"], ["_Test Account Education Cess", "_Test Account Tax Assets - _TC", "Ledger"], ["_Test Account S&H Education Cess", "_Test Account Tax Assets - _TC", "Ledger"], ["_Test Account CST", "Direct Expenses - _TC", "Ledger"], ["_Test Account Discount", "Direct Expenses - _TC", "Ledger"], + + # related to Account Inventory Integration + ["_Test Account Stock In Hand", "Current Assets - _TC", "Ledger"], ] - return make_test_objects("Account", [[{ + test_objects = make_test_objects("Account", [[{ "doctype": "Account", "account_name": account_name, "parent_account": parent_account, "company": "_Test Company", "group_or_ledger": group_or_ledger - }] for account_name, parent_account, group_or_ledger in accounts]) \ No newline at end of file + }] for account_name, parent_account, group_or_ledger in accounts]) + + webnotes.conn.set_value("Company", "_Test Company", "stock_in_hand_account", + "_Test Account Stock In Hand - _TC") + + return test_objects \ No newline at end of file diff --git a/accounts/doctype/purchase_invoice/purchase_invoice.py b/accounts/doctype/purchase_invoice/purchase_invoice.py index 3318e4e5dc..96cfc006be 100644 --- a/accounts/doctype/purchase_invoice/purchase_invoice.py +++ b/accounts/doctype/purchase_invoice/purchase_invoice.py @@ -385,7 +385,7 @@ class DocType(BuyingController): gl_entries = [] valuation_tax = 0 auto_inventory_accounting = webnotes.conn.get_value("Global Defaults", None, - "automatic_inventory_accounting") + "auto_inventory_accounting") abbr = self.get_company_abbr() # parent's gl entry diff --git a/controllers/accounts_controller.py b/controllers/accounts_controller.py index 60535ccfb2..47a0138fa8 100644 --- a/controllers/accounts_controller.py +++ b/controllers/accounts_controller.py @@ -16,6 +16,7 @@ from __future__ import unicode_literals import webnotes +from webnotes import msgprint, _ from webnotes.utils import flt from utilities.transaction_base import TransactionBase @@ -37,15 +38,7 @@ class AccountsController(TransactionBase): } gl_dict.update(args) return gl_dict - - def get_stock_in_hand_account(self): - stock_in_hand = webnotes.conn.get_value("Company", self.doc.company, "stock_in_hand") - if not stock_in_hand: - webnotes.msgprint("""Please specify "Stock In Hand" account - for company: %s""" % (self.doc.company,), raise_exception=1) - - return stock_in_hand - + def clear_unallocated_advances(self, childtype, parentfield): self.doclist.remove_items({"parentfield": parentfield, "allocated_amount": ["in", [0, None, ""]]}) @@ -73,4 +66,24 @@ class AccountsController(TransactionBase): "remarks": d.remark, "advance_amount": flt(d.amount), "allocate_amount": 0 - }) \ No newline at end of file + }) + + def get_stock_in_hand_account(self): + stock_in_hand_account = webnotes.conn.get_value("Company", self.doc.company, "stock_in_hand_account") + + if not stock_in_hand_account: + msgprint(_("Missing") + ": " + + _(webnotes.get_doctype("company").get_label("stock_in_hand_account") + + " " + _("for Company") + " " + self.doc.company), raise_exception=True) + + return stock_in_hand_account + + @property + def stock_items(self): + if not hasattr(self, "_stock_items"): + item_codes = list(set(item.item_code for item in self.doclist.get({"parentfield": self.fname}))) + self._stock_items = [r[0] for r in webnotes.conn.sql("""select name + from `tabItem` where name in (%s) and is_stock_item='Yes'""" % \ + (", ".join((["%s"]*len(item_codes))),), item_codes)] + + return self._stock_items \ No newline at end of file diff --git a/controllers/buying_controller.py b/controllers/buying_controller.py index df2f429a14..bbcd4926c3 100644 --- a/controllers/buying_controller.py +++ b/controllers/buying_controller.py @@ -113,6 +113,14 @@ class BuyingController(AccountsController): for item in self.item_doclist: round_floats_in_doc(item, self.precision.item) + + # hack! - cleaned up in _cleanup() + if self.doc.doctype != "Purchase Invoice": + item.rate = item.purchase_rate + self.precision.item.rate = self.precision.item.purchase_rate + + item.discount = item.discount_rate + self.precision.item.discount = self.precision.item.discount_rate if item.discount == 100: if not item.import_ref_rate: @@ -128,10 +136,10 @@ class BuyingController(AccountsController): item.import_ref_rate = flt(item.import_rate / (1.0 - (item.discount_rate / 100.0)), self.precision.item.import_ref_rate) - + item.import_amount = flt(item.import_rate * item.qty, self.precision.item.import_amount) - + _set_base(item, "import_ref_rate", "purchase_ref_rate") _set_base(item, "import_rate", "rate") _set_base(item, "import_amount", "amount") @@ -256,6 +264,9 @@ class BuyingController(AccountsController): for item in self.item_doclist: item.purchase_rate = item.rate del item.fields["rate"] + + item.discount_rate = item.discount + del item.fields["discount"] def validate_on_previous_row(self, tax): """ @@ -315,16 +326,6 @@ class BuyingController(AccountsController): item.item_tax_amount += flt(current_tax_amount, self.precision.item.item_tax_amount) - @property - def stock_items(self): - if not hasattr(self, "_stock_items"): - item_codes = list(set(item.item_code for item in self.item_doclist)) - self._stock_items = [r[0] for r in webnotes.conn.sql("""select name - from `tabItem` where name in (%s) and is_stock_item='Yes'""" % \ - (", ".join((["%s"]*len(item_codes))),), item_codes)] - - return self._stock_items - @property def precision(self): if not hasattr(self, "_precision"): diff --git a/setup/doctype/company/company.py b/setup/doctype/company/company.py index 94c8f1c929..552dae2a9a 100644 --- a/setup/doctype/company/company.py +++ b/setup/doctype/company/company.py @@ -37,111 +37,116 @@ class DocType: # --------------------------------------------------- def create_default_accounts(self): self.fld_dict = {'account_name':0,'parent_account':1,'group_or_ledger':2,'is_pl_account':3,'account_type':4,'debit_or_credit':5,'company':6,'tax_rate':7} - acc_list_common = [['Application of Funds (Assets)','','Group','No','','Debit',self.doc.name,''], - ['Current Assets','Application of Funds (Assets)','Group','No','','Debit',self.doc.name,''], - ['Accounts Receivable','Current Assets','Group','No','','Debit',self.doc.name,''], - ['Bank Accounts','Current Assets','Group','No','Bank or Cash','Debit',self.doc.name,''], - ['Cash In Hand','Current Assets','Group','No','Bank or Cash','Debit',self.doc.name,''], - ['Cash','Cash In Hand','Ledger','No','Bank or Cash','Debit',self.doc.name,''], - ['Loans and Advances (Assets)','Current Assets','Group','No','','Debit',self.doc.name,''], - ['Securities and Deposits','Current Assets','Group','No','','Debit',self.doc.name,''], - ['Earnest Money','Securities and Deposits','Ledger','No','','Debit',self.doc.name,''], - ['Stock In Hand','Current Assets','Group','No','','Debit',self.doc.name,''], - ['Stock','Stock In Hand','Ledger','No','','Debit',self.doc.name,''], - ['Tax Assets','Current Assets','Group','No','','Debit',self.doc.name,''], - ['Fixed Assets','Application of Funds (Assets)','Group','No','','Debit',self.doc.name,''], - ['Capital Equipments','Fixed Assets','Ledger','No','Fixed Asset Account','Debit',self.doc.name,''], - ['Computers','Fixed Assets','Ledger','No','Fixed Asset Account','Debit',self.doc.name,''], - ['Furniture and Fixture','Fixed Assets','Ledger','No','Fixed Asset Account','Debit',self.doc.name,''], - ['Office Equipments','Fixed Assets','Ledger','No','Fixed Asset Account','Debit',self.doc.name,''], - ['Plant and Machinery','Fixed Assets','Ledger','No','Fixed Asset Account','Debit',self.doc.name,''], - ['Investments','Application of Funds (Assets)','Group','No','','Debit',self.doc.name,''], - ['Temporary Accounts (Assets)','Application of Funds (Assets)','Group','No','','Debit',self.doc.name,''], - ['Temporary Account (Assets)','Temporary Accounts (Assets)','Ledger','No','','Debit',self.doc.name,''], - ['Expenses','','Group','Yes','Expense Account','Debit',self.doc.name,''], - ['Direct Expenses','Expenses','Group','Yes','Expense Account','Debit',self.doc.name,''], - ['Cost of Goods Sold','Direct Expenses','Ledger','Yes','Expense Account','Debit',self.doc.name,''], - ['Indirect Expenses','Expenses','Group','Yes','Expense Account','Debit',self.doc.name,''], - ['Advertising and Publicity','Indirect Expenses','Ledger','Yes','Chargeable','Debit',self.doc.name,''], - ['Bad Debts Written Off','Indirect Expenses','Ledger','Yes','Expense Account','Debit',self.doc.name,''], - ['Bank Charges','Indirect Expenses','Ledger','Yes','Expense Account','Debit',self.doc.name,''], - ['Books and Periodicals','Indirect Expenses','Ledger','Yes','Expense Account','Debit',self.doc.name,''], - ['Charity and Donations','Indirect Expenses','Ledger','Yes','Expense Account','Debit',self.doc.name,''], - ['Commission on Sales','Indirect Expenses','Ledger','Yes','Expense Account','Debit',self.doc.name,''], - ['Conveyance Expenses','Indirect Expenses','Ledger','Yes','Expense Account','Debit',self.doc.name,''], - ['Customer Entertainment Expenses','Indirect Expenses','Ledger','Yes','Expense Account','Debit',self.doc.name,''], - ['Depreciation Account','Indirect Expenses','Ledger','Yes','Expense Account','Debit',self.doc.name,''], - ['Freight and Forwarding Charges','Indirect Expenses','Ledger','Yes','Chargeable','Debit',self.doc.name,''], - ['Legal Expenses','Indirect Expenses','Ledger','Yes','Expense Account','Debit',self.doc.name,''], - ['Miscellaneous Expenses','Indirect Expenses','Ledger','Yes','Chargeable','Debit',self.doc.name,''], - ['Office Maintenance Expenses','Indirect Expenses','Ledger','Yes','Expense Account','Debit',self.doc.name,''], - ['Office Rent','Indirect Expenses','Ledger','Yes','Expense Account','Debit',self.doc.name,''], - ['Postal Expenses','Indirect Expenses','Ledger','Yes','Expense Account','Debit',self.doc.name,''], - ['Print and Stationary','Indirect Expenses','Ledger','Yes','Expense Account','Debit',self.doc.name,''], - ['Rounded Off','Indirect Expenses','Ledger','Yes','Expense Account','Debit',self.doc.name,''], - ['Salary','Indirect Expenses','Ledger','Yes','Expense Account','Debit',self.doc.name,''], - ['Sales Promotion Expenses','Indirect Expenses','Ledger','Yes','Chargeable','Debit',self.doc.name,''], - ['Service Charges Paid','Indirect Expenses','Ledger','Yes','Expense Account','Debit',self.doc.name,''], - ['Staff Welfare Expenses','Indirect Expenses','Ledger','Yes','Expense Account','Debit',self.doc.name,''], - ['Telephone Expenses','Indirect Expenses','Ledger','Yes','Expense Account','Debit',self.doc.name,''], - ['Travelling Expenses','Indirect Expenses','Ledger','Yes','Expense Account','Debit',self.doc.name,''], - ['Water and Electricity Expenses','Indirect Expenses','Ledger','Yes','Expense Account','Debit',self.doc.name,''], - ['Income','','Group','Yes','','Credit',self.doc.name,''], - ['Direct Income','Income','Group','Yes','Income Account','Credit',self.doc.name,''], - ['Sales','Direct Income','Ledger','Yes','Income Account','Credit',self.doc.name,''], - ['Service','Direct Income','Ledger','Yes','Income Account','Credit',self.doc.name,''], - ['Indirect Income','Income','Group','Yes','Income Account','Credit',self.doc.name,''], - ['Source of Funds (Liabilities)','','Group','No','','Credit',self.doc.name,''], - ['Capital Account','Source of Funds (Liabilities)','Group','No','','Credit',self.doc.name,''], - ['Reserves and Surplus','Capital Account','Group','No','','Credit',self.doc.name,''], - ['Shareholders Funds','Capital Account','Group','No','','Credit',self.doc.name,''], - ['Current Liabilities','Source of Funds (Liabilities)','Group','No','','Credit',self.doc.name,''], - ['Accounts Payable','Current Liabilities','Group','No','','Credit',self.doc.name,''], - ['Duties and Taxes','Current Liabilities','Group','No','','Credit',self.doc.name,''], - ['Loans (Liabilities)','Current Liabilities','Group','No','','Credit',self.doc.name,''], - ['Secured Loans','Loans (Liabilities)','Group','No','','Credit',self.doc.name,''], - ['Unsecured Loans','Loans (Liabilities)','Group','No','','Credit',self.doc.name,''], - ['Bank Overdraft Account','Loans (Liabilities)','Group','No','','Credit',self.doc.name,''], - ['Temporary Accounts (Liabilities)','Source of Funds (Liabilities)','Group','No','','Credit',self.doc.name,''], - ['Temporary Account (Liabilities)','Temporary Accounts (Liabilities)','Ledger','No','','Credit',self.doc.name,''] - ] + acc_list_common = [ + ['Application of Funds (Assets)','','Group','No','','Debit',self.doc.name,''], + ['Current Assets','Application of Funds (Assets)','Group','No','','Debit',self.doc.name,''], + ['Accounts Receivable','Current Assets','Group','No','','Debit',self.doc.name,''], + ['Bank Accounts','Current Assets','Group','No','Bank or Cash','Debit',self.doc.name,''], + ['Cash In Hand','Current Assets','Group','No','Bank or Cash','Debit',self.doc.name,''], + ['Cash','Cash In Hand','Ledger','No','Bank or Cash','Debit',self.doc.name,''], + ['Loans and Advances (Assets)','Current Assets','Group','No','','Debit',self.doc.name,''], + ['Securities and Deposits','Current Assets','Group','No','','Debit',self.doc.name,''], + ['Earnest Money','Securities and Deposits','Ledger','No','','Debit',self.doc.name,''], + ['Stock In Hand','Current Assets','Group','No','','Debit',self.doc.name,''], + ['Stock','Stock In Hand','Ledger','No','','Debit',self.doc.name,''], + ['Tax Assets','Current Assets','Group','No','','Debit',self.doc.name,''], + ['Stock Delivered But Not Billed','Current Assets','Ledger','No','','Debit',self.doc.name,''], + ['Fixed Assets','Application of Funds (Assets)','Group','No','','Debit',self.doc.name,''], + ['Capital Equipments','Fixed Assets','Ledger','No','Fixed Asset Account','Debit',self.doc.name,''], + ['Computers','Fixed Assets','Ledger','No','Fixed Asset Account','Debit',self.doc.name,''], + ['Furniture and Fixture','Fixed Assets','Ledger','No','Fixed Asset Account','Debit',self.doc.name,''], + ['Office Equipments','Fixed Assets','Ledger','No','Fixed Asset Account','Debit',self.doc.name,''], + ['Plant and Machinery','Fixed Assets','Ledger','No','Fixed Asset Account','Debit',self.doc.name,''], + ['Investments','Application of Funds (Assets)','Group','No','','Debit',self.doc.name,''], + ['Temporary Accounts (Assets)','Application of Funds (Assets)','Group','No','','Debit',self.doc.name,''], + ['Temporary Account (Assets)','Temporary Accounts (Assets)','Ledger','No','','Debit',self.doc.name,''], + ['Expenses','','Group','Yes','Expense Account','Debit',self.doc.name,''], + ['Direct Expenses','Expenses','Group','Yes','Expense Account','Debit',self.doc.name,''], + ['Cost of Goods Sold','Direct Expenses','Ledger','Yes','Expense Account','Debit',self.doc.name,''], + ['Expenses Included In Valuation','Direct Expenses','Ledger','Yes','Expense Account','Debit',self.doc.name,''], + ['Stock Adjustment','Direct Expenses','Ledger','Yes','Expense Account','Debit',self.doc.name,''], + ['Indirect Expenses','Expenses','Group','Yes','Expense Account','Debit',self.doc.name,''], + ['Advertising and Publicity','Indirect Expenses','Ledger','Yes','Chargeable','Debit',self.doc.name,''], + ['Bad Debts Written Off','Indirect Expenses','Ledger','Yes','Expense Account','Debit',self.doc.name,''], + ['Bank Charges','Indirect Expenses','Ledger','Yes','Expense Account','Debit',self.doc.name,''], + ['Books and Periodicals','Indirect Expenses','Ledger','Yes','Expense Account','Debit',self.doc.name,''], + ['Charity and Donations','Indirect Expenses','Ledger','Yes','Expense Account','Debit',self.doc.name,''], + ['Commission on Sales','Indirect Expenses','Ledger','Yes','Expense Account','Debit',self.doc.name,''], + ['Conveyance Expenses','Indirect Expenses','Ledger','Yes','Expense Account','Debit',self.doc.name,''], + ['Customer Entertainment Expenses','Indirect Expenses','Ledger','Yes','Expense Account','Debit',self.doc.name,''], + ['Depreciation Account','Indirect Expenses','Ledger','Yes','Expense Account','Debit',self.doc.name,''], + ['Freight and Forwarding Charges','Indirect Expenses','Ledger','Yes','Chargeable','Debit',self.doc.name,''], + ['Legal Expenses','Indirect Expenses','Ledger','Yes','Expense Account','Debit',self.doc.name,''], + ['Miscellaneous Expenses','Indirect Expenses','Ledger','Yes','Chargeable','Debit',self.doc.name,''], + ['Office Maintenance Expenses','Indirect Expenses','Ledger','Yes','Expense Account','Debit',self.doc.name,''], + ['Office Rent','Indirect Expenses','Ledger','Yes','Expense Account','Debit',self.doc.name,''], + ['Postal Expenses','Indirect Expenses','Ledger','Yes','Expense Account','Debit',self.doc.name,''], + ['Print and Stationary','Indirect Expenses','Ledger','Yes','Expense Account','Debit',self.doc.name,''], + ['Rounded Off','Indirect Expenses','Ledger','Yes','Expense Account','Debit',self.doc.name,''], + ['Salary','Indirect Expenses','Ledger','Yes','Expense Account','Debit',self.doc.name,''], + ['Sales Promotion Expenses','Indirect Expenses','Ledger','Yes','Chargeable','Debit',self.doc.name,''], + ['Service Charges Paid','Indirect Expenses','Ledger','Yes','Expense Account','Debit',self.doc.name,''], + ['Staff Welfare Expenses','Indirect Expenses','Ledger','Yes','Expense Account','Debit',self.doc.name,''], + ['Telephone Expenses','Indirect Expenses','Ledger','Yes','Expense Account','Debit',self.doc.name,''], + ['Travelling Expenses','Indirect Expenses','Ledger','Yes','Expense Account','Debit',self.doc.name,''], + ['Water and Electricity Expenses','Indirect Expenses','Ledger','Yes','Expense Account','Debit',self.doc.name,''], + ['Income','','Group','Yes','','Credit',self.doc.name,''], + ['Direct Income','Income','Group','Yes','Income Account','Credit',self.doc.name,''], + ['Sales','Direct Income','Ledger','Yes','Income Account','Credit',self.doc.name,''], + ['Service','Direct Income','Ledger','Yes','Income Account','Credit',self.doc.name,''], + ['Indirect Income','Income','Group','Yes','Income Account','Credit',self.doc.name,''], + ['Source of Funds (Liabilities)','','Group','No','','Credit',self.doc.name,''], + ['Capital Account','Source of Funds (Liabilities)','Group','No','','Credit',self.doc.name,''], + ['Reserves and Surplus','Capital Account','Group','No','','Credit',self.doc.name,''], + ['Shareholders Funds','Capital Account','Group','No','','Credit',self.doc.name,''], + ['Current Liabilities','Source of Funds (Liabilities)','Group','No','','Credit',self.doc.name,''], + ['Accounts Payable','Current Liabilities','Group','No','','Credit',self.doc.name,''], + ['Duties and Taxes','Current Liabilities','Group','No','','Credit',self.doc.name,''], + ['Loans (Liabilities)','Current Liabilities','Group','No','','Credit',self.doc.name,''], + ['Secured Loans','Loans (Liabilities)','Group','No','','Credit',self.doc.name,''], + ['Unsecured Loans','Loans (Liabilities)','Group','No','','Credit',self.doc.name,''], + ['Bank Overdraft Account','Loans (Liabilities)','Group','No','','Credit',self.doc.name,''], + ['Stock Received But Not Billed','Current Liabilities','Ledger','No','','Credit',self.doc.name,''], + ['Temporary Accounts (Liabilities)','Source of Funds (Liabilities)','Group','No','','Credit',self.doc.name,''], + ['Temporary Account (Liabilities)','Temporary Accounts (Liabilities)','Ledger','No','','Credit',self.doc.name,''] + ] acc_list_india = [ - ['CENVAT Capital Goods','Tax Assets','Ledger','No','Chargeable','Debit',self.doc.name,''], - ['CENVAT','Tax Assets','Ledger','No','Chargeable','Debit',self.doc.name,''], - ['CENVAT Service Tax','Tax Assets','Ledger','No','Chargeable','Debit',self.doc.name,''], - ['CENVAT Service Tax Cess 1','Tax Assets','Ledger','No','Chargeable','Debit',self.doc.name,''], - ['CENVAT Service Tax Cess 2','Tax Assets','Ledger','No','Chargeable','Debit',self.doc.name,''], - ['CENVAT Edu Cess','Tax Assets','Ledger','No','Chargeable','Debit',self.doc.name,''], - ['CENVAT SHE Cess','Tax Assets','Ledger','No','Chargeable','Debit',self.doc.name,''], - ['Excise Duty 4','Tax Assets','Ledger','No','Tax','Debit',self.doc.name,'4.00'], - ['Excise Duty 8','Tax Assets','Ledger','No','Tax','Debit',self.doc.name,'8.00'], - ['Excise Duty 10','Tax Assets','Ledger','No','Tax','Debit',self.doc.name,'10.00'], - ['Excise Duty 14','Tax Assets','Ledger','No','Tax','Debit',self.doc.name,'14.00'], - ['Excise Duty Edu Cess 2','Tax Assets','Ledger','No','Tax','Debit',self.doc.name,'2.00'], - ['Excise Duty SHE Cess 1','Tax Assets','Ledger','No','Tax','Debit',self.doc.name,'1.00'], - ['P L A','Tax Assets','Ledger','No','Chargeable','Debit',self.doc.name,''], - ['P L A - Cess Portion','Tax Assets','Ledger','No','Chargeable','Debit',self.doc.name,''], - ['Edu. Cess on Excise','Duties and Taxes','Ledger','No','Tax','Credit',self.doc.name,'2.00'], - ['Edu. Cess on Service Tax','Duties and Taxes','Ledger','No','Tax','Credit',self.doc.name,'2.00'], - ['Edu. Cess on TDS','Duties and Taxes','Ledger','No','Tax','Credit',self.doc.name,'2.00'], - ['Excise Duty @ 4','Duties and Taxes','Ledger','No','Tax','Credit',self.doc.name,'4.00'], - ['Excise Duty @ 8','Duties and Taxes','Ledger','No','Tax','Credit',self.doc.name,'8.00'], - ['Excise Duty @ 10','Duties and Taxes','Ledger','No','Tax','Credit',self.doc.name,'10.00'], - ['Excise Duty @ 14','Duties and Taxes','Ledger','No','Tax','Credit',self.doc.name,'14.00'], - ['Service Tax','Duties and Taxes','Ledger','No','Tax','Credit',self.doc.name,'10.3'], - ['SHE Cess on Excise','Duties and Taxes','Ledger','No','Tax','Credit',self.doc.name,'1.00'], - ['SHE Cess on Service Tax','Duties and Taxes','Ledger','No','Tax','Credit',self.doc.name,'1.00'], - ['SHE Cess on TDS','Duties and Taxes','Ledger','No','Tax','Credit',self.doc.name,'1.00'], - ['Professional Tax','Duties and Taxes','Ledger','No','Chargeable','Credit',self.doc.name,''], - ['VAT','Duties and Taxes','Ledger','No','Chargeable','Credit',self.doc.name,''], - ['TDS (Advertisement)','Duties and Taxes','Ledger','No','Chargeable','Credit',self.doc.name,''], - ['TDS (Commission)','Duties and Taxes','Ledger','No','Chargeable','Credit',self.doc.name,''], - ['TDS (Contractor)','Duties and Taxes','Ledger','No','Chargeable','Credit',self.doc.name,''], - ['TDS (Interest)','Duties and Taxes','Ledger','No','Chargeable','Credit',self.doc.name,''], - ['TDS (Rent)','Duties and Taxes','Ledger','No','Chargeable','Credit',self.doc.name,''], - ['TDS (Salary)','Duties and Taxes','Ledger','No','Chargeable','Credit',self.doc.name,''] - ] + ['CENVAT Capital Goods','Tax Assets','Ledger','No','Chargeable','Debit',self.doc.name,''], + ['CENVAT','Tax Assets','Ledger','No','Chargeable','Debit',self.doc.name,''], + ['CENVAT Service Tax','Tax Assets','Ledger','No','Chargeable','Debit',self.doc.name,''], + ['CENVAT Service Tax Cess 1','Tax Assets','Ledger','No','Chargeable','Debit',self.doc.name,''], + ['CENVAT Service Tax Cess 2','Tax Assets','Ledger','No','Chargeable','Debit',self.doc.name,''], + ['CENVAT Edu Cess','Tax Assets','Ledger','No','Chargeable','Debit',self.doc.name,''], + ['CENVAT SHE Cess','Tax Assets','Ledger','No','Chargeable','Debit',self.doc.name,''], + ['Excise Duty 4','Tax Assets','Ledger','No','Tax','Debit',self.doc.name,'4.00'], + ['Excise Duty 8','Tax Assets','Ledger','No','Tax','Debit',self.doc.name,'8.00'], + ['Excise Duty 10','Tax Assets','Ledger','No','Tax','Debit',self.doc.name,'10.00'], + ['Excise Duty 14','Tax Assets','Ledger','No','Tax','Debit',self.doc.name,'14.00'], + ['Excise Duty Edu Cess 2','Tax Assets','Ledger','No','Tax','Debit',self.doc.name,'2.00'], + ['Excise Duty SHE Cess 1','Tax Assets','Ledger','No','Tax','Debit',self.doc.name,'1.00'], + ['P L A','Tax Assets','Ledger','No','Chargeable','Debit',self.doc.name,''], + ['P L A - Cess Portion','Tax Assets','Ledger','No','Chargeable','Debit',self.doc.name,''], + ['Edu. Cess on Excise','Duties and Taxes','Ledger','No','Tax','Credit',self.doc.name,'2.00'], + ['Edu. Cess on Service Tax','Duties and Taxes','Ledger','No','Tax','Credit',self.doc.name,'2.00'], + ['Edu. Cess on TDS','Duties and Taxes','Ledger','No','Tax','Credit',self.doc.name,'2.00'], + ['Excise Duty @ 4','Duties and Taxes','Ledger','No','Tax','Credit',self.doc.name,'4.00'], + ['Excise Duty @ 8','Duties and Taxes','Ledger','No','Tax','Credit',self.doc.name,'8.00'], + ['Excise Duty @ 10','Duties and Taxes','Ledger','No','Tax','Credit',self.doc.name,'10.00'], + ['Excise Duty @ 14','Duties and Taxes','Ledger','No','Tax','Credit',self.doc.name,'14.00'], + ['Service Tax','Duties and Taxes','Ledger','No','Tax','Credit',self.doc.name,'10.3'], + ['SHE Cess on Excise','Duties and Taxes','Ledger','No','Tax','Credit',self.doc.name,'1.00'], + ['SHE Cess on Service Tax','Duties and Taxes','Ledger','No','Tax','Credit',self.doc.name,'1.00'], + ['SHE Cess on TDS','Duties and Taxes','Ledger','No','Tax','Credit',self.doc.name,'1.00'], + ['Professional Tax','Duties and Taxes','Ledger','No','Chargeable','Credit',self.doc.name,''], + ['VAT','Duties and Taxes','Ledger','No','Chargeable','Credit',self.doc.name,''], + ['TDS (Advertisement)','Duties and Taxes','Ledger','No','Chargeable','Credit',self.doc.name,''], + ['TDS (Commission)','Duties and Taxes','Ledger','No','Chargeable','Credit',self.doc.name,''], + ['TDS (Contractor)','Duties and Taxes','Ledger','No','Chargeable','Credit',self.doc.name,''], + ['TDS (Interest)','Duties and Taxes','Ledger','No','Chargeable','Credit',self.doc.name,''], + ['TDS (Rent)','Duties and Taxes','Ledger','No','Chargeable','Credit',self.doc.name,''], + ['TDS (Salary)','Duties and Taxes','Ledger','No','Chargeable','Credit',self.doc.name,''] + ] # load common account heads for d in acc_list_common: self.add_acc(d) diff --git a/setup/doctype/company/company.txt b/setup/doctype/company/company.txt index a43ec938da..d97cfc34af 100644 --- a/setup/doctype/company/company.txt +++ b/setup/doctype/company/company.txt @@ -1,8 +1,8 @@ [ { - "creation": "2013-01-22 16:50:36", + "creation": "2013-02-22 01:27:54", "docstatus": 0, - "modified": "2013-01-23 16:51:54", + "modified": "2013-02-26 10:57:39", "modified_by": "Administrator", "owner": "Administrator" }, @@ -51,12 +51,13 @@ "oldfieldtype": "Section Break" }, { + "description": "Please Enter Abbreviation or Short Name properly as it will be added as Suffix to all Account Heads.", "doctype": "DocField", - "fieldname": "company_name", + "fieldname": "abbr", "fieldtype": "Data", - "label": "Company", + "label": "Abbr", "no_copy": 0, - "oldfieldname": "company_name", + "oldfieldname": "abbr", "oldfieldtype": "Data", "reqd": 1 }, @@ -66,13 +67,12 @@ "fieldtype": "Column Break" }, { - "description": "Please Enter Abbreviation or Short Name properly as it will be added as Suffix to all Account Heads.", "doctype": "DocField", - "fieldname": "abbr", + "fieldname": "company_name", "fieldtype": "Data", - "label": "Abbr", + "label": "Company", "no_copy": 0, - "oldfieldname": "abbr", + "oldfieldname": "company_name", "oldfieldtype": "Data", "reqd": 1 }, @@ -124,6 +124,17 @@ "oldfieldtype": "Link", "options": "Account" }, + { + "depends_on": "eval:!doc.__islocal", + "description": "This account will be used to maintain value of available stock", + "doctype": "DocField", + "fieldname": "stock_in_hand_account", + "fieldtype": "Link", + "label": "Stock In Hand Account", + "no_copy": 1, + "options": "Account", + "read_only": 0 + }, { "doctype": "DocField", "fieldname": "column_break0", diff --git a/stock/doctype/delivery_note/delivery_note.py b/stock/doctype/delivery_note/delivery_note.py index f54edf221a..35d008bcca 100644 --- a/stock/doctype/delivery_note/delivery_note.py +++ b/stock/doctype/delivery_note/delivery_note.py @@ -174,7 +174,12 @@ class DocType(SellingController): def validate_reference_value(self): """Validate values with reference document with previous document""" - get_obj('DocType Mapper', 'Sales Order-Delivery Note', with_children = 1).validate_reference_value(self, self.doc.name) + validate_ref = any([d.prevdoc_docname for d in self.doclist.get({"parentfield": self.fname}) + if d.prevdoc_doctype == "Sales Order"]) + + if validate_ref: + get_obj('DocType Mapper', 'Sales Order-Delivery Note', + with_children = 1).validate_reference_value(self, self.doc.name) def validate_for_items(self): diff --git a/stock/doctype/purchase_receipt/purchase_receipt.py b/stock/doctype/purchase_receipt/purchase_receipt.py index 8858fd52e1..a957468032 100644 --- a/stock/doctype/purchase_receipt/purchase_receipt.py +++ b/stock/doctype/purchase_receipt/purchase_receipt.py @@ -17,7 +17,7 @@ from __future__ import unicode_literals import webnotes -from webnotes.utils import cstr, flt +from webnotes.utils import cstr, flt, cint from webnotes.model.doc import addchild from webnotes.model.bean import getlist from webnotes.model.code import get_obj @@ -92,11 +92,12 @@ class DocType(BuyingController): # update valuation rate def update_valuation_rate(self): - total_b_cost = flt(self.doc.buying_cost_transport) + flt(self.doc.buying_cost_taxes) + flt(self.doc.buying_cost_other) - for d in getlist(self.doclist, 'purchase_receipt_details'): - if flt(self.doc.net_total) and flt(d.qty): - #d.valuation_rate = (flt(d.purchase_rate) + ((flt(d.amount) * (total_b_cost)) / (self.doc.net_total * flt(d.qty))) + (flt(d.rm_supp_cost) / flt(d.qty))) / flt(d.conversion_factor) - d.valuation_rate = (flt(d.purchase_rate) + ((flt(d.amount) * (total_b_cost)) / (self.doc.net_total * flt(d.qty))) + (flt(d.rm_supp_cost) / flt(d.qty)) + (flt(d.item_tax_amount)/flt(d.qty))) / flt(d.conversion_factor) + for d in self.doclist.get({"parentfield": "purchase_receipt_details"}): + if d.qty: + d.valuation_rate = (flt(d.purchase_rate) + flt(d.item_tax_amount)/flt(d.qty) + + flt(d.rm_supp_cost) / flt(d.qty)) / flt(d.conversion_factor) + else: + d.valuation_rate = 0.0 #check in manage account if purchase order required or not. # ==================================================================================== @@ -263,11 +264,9 @@ class DocType(BuyingController): # Update last purchase rate purchase_controller.update_last_purchase_rate(self, 1) + + self.make_gl_entries() - - - #On Cancel - #---------------------------------------------------------------------------------------------------- def check_next_docstatus(self): submit_rv = sql("select t1.name from `tabPurchase Invoice` t1,`tabPurchase Invoice Item` t2 where t1.name = t2.parent and t2.purchase_receipt = '%s' and t1.docstatus = 1" % (self.doc.name)) if submit_rv: @@ -301,10 +300,10 @@ class DocType(BuyingController): # 6. Update last purchase rate pc_obj.update_last_purchase_rate(self, 0) + + self.make_gl_entries() -#----------- code for Sub-contracted Items ------------------- - #--------check for sub-contracted items and accordingly update PR raw material detail table-------- def update_rw_material_detail(self): for d in getlist(self.doclist,'purchase_receipt_details'): @@ -431,3 +430,44 @@ class DocType(BuyingController): def get_purchase_tax_details(self): self.doclist = get_obj('Purchase Common').get_purchase_tax_details(self) + + def make_gl_entries(self): + if not cint(webnotes.defaults.get_global_default("auto_inventory_accounting")): + return + + abbr = webnotes.conn.get_value("Company", self.doc.company, "abbr") + stock_received_account = "Stock Received But Not Billed - %s" % (abbr,) + stock_in_hand_account = self.get_stock_in_hand_account() + + total_valuation_amount = self.get_total_valuation_amount() + + if total_valuation_amount: + gl_entries = [ + # debit stock in hand account + self.get_gl_dict({ + "account": stock_in_hand_account, + "against": stock_received_account, + "debit": total_valuation_amount, + "remarks": self.doc.remarks or "Accounting Entry for Stock", + }, self.doc.docstatus == 2), + + # credit stock received but not billed account + self.get_gl_dict({ + "account": stock_received_account, + "against": stock_in_hand_account, + "credit": total_valuation_amount, + "remarks": self.doc.remarks or "Accounting Entry for Stock", + }, self.doc.docstatus == 2), + ] + from accounts.general_ledger import make_gl_entries + make_gl_entries(gl_entries, cancel=self.doc.docstatus == 2) + + def get_total_valuation_amount(self): + total_valuation_amount = 0.0 + + for item in self.doclist.get({"parentfield": "purchase_receipt_details"}): + if item.item_code in self.stock_items: + total_valuation_amount += flt(item.valuation_rate) * \ + flt(item.qty) * flt(item.conversion_factor) + + return total_valuation_amount \ No newline at end of file diff --git a/stock/doctype/purchase_receipt/test_purchase_receipt.py b/stock/doctype/purchase_receipt/test_purchase_receipt.py index f91455f4d3..d833d65b2b 100644 --- a/stock/doctype/purchase_receipt/test_purchase_receipt.py +++ b/stock/doctype/purchase_receipt/test_purchase_receipt.py @@ -18,178 +18,115 @@ from __future__ import unicode_literals import unittest import webnotes -import webnotes.model -from webnotes.model.doclist import DocList -from webnotes.utils import nowdate - -company = webnotes.conn.get_default("company") -abbr = webnotes.conn.get_value("Company", company, "abbr") - -def load_data(): - insert_accounts() - - # create default warehouse - if not webnotes.conn.exists("Warehouse", "Default Warehouse"): - webnotes.insert({"doctype": "Warehouse", - "warehouse_name": "Default Warehouse", - "warehouse_type": "Stores"}) - - # create UOM: Nos. - if not webnotes.conn.exists("UOM", "Nos"): - webnotes.insert({"doctype": "UOM", "uom_name": "Nos"}) - - from webnotes.tests import insert_test_data - # create item groups and items - insert_test_data("Item Group", - sort_fn=lambda ig: (ig[0].get('parent_item_group'), ig[0].get('name'))) - insert_test_data("Item") - - # create supplier type - webnotes.insert({"doctype": "Supplier Type", "supplier_type": "Manufacturing"}) - - # create supplier - webnotes.insert({"doctype": "Supplier", "supplier_name": "East Wind Inc.", - "supplier_type": "Manufacturing", "company": company}) - - # create default cost center if not exists - if not webnotes.conn.exists("Cost Center", "Default Cost Center - %s" % abbr): - webnotes.insert({"doctype": "Cost Center", "group_or_ledger": "Ledger", - "cost_center_name": "Default Cost Center", - "parent_cost_center": "Root - %s" % abbr, - "company_name": company}) - - # create account heads for taxes - - webnotes.insert({"doctype": "Account", "account_name": "Shipping Charges", - "parent_account": "Stock Expenses - %s" % abbr, "company": company, - "group_or_ledger": "Ledger"}) - - webnotes.insert({"doctype": "Account", "account_name": "Customs Duty", - "parent_account": "Stock Expenses - %s" % abbr, "company": company, - "group_or_ledger": "Ledger"}) - webnotes.insert({"doctype": "Account", "account_name": "_Test Tax Assets", - "parent_account": "Current Assets - %s" % abbr, "company": company, - "group_or_ledger": "Group"}) - webnotes.insert({"doctype": "Account", "account_name": "VAT - Test", - "parent_account": "_Test Tax Assets - %s" % abbr, "company": company, - "group_or_ledger": "Ledger"}) - - # create BOM - # webnotes.insert(DocList([ - # {"doctype": "BOM", "item": "Nebula 7", "quantity": 1, - # "is_active": "Yes", "is_default": 1, "uom": "Nos"}, - # {"doctype": "BOM Operation", "operation_no": 1, "parentfield": "bom_operations", - # "opn_description": "Development"}, - # {"doctype": "BOM Item", "item_code": "Android Jack D", "operation_no": 1, "qty": 5, - # "rate": 20, "amount": 100, "stock_uom": "Nos", "parentfield": "bom_materials"} - # ])) - - -base_purchase_receipt = [ - { - "doctype": "Purchase Receipt", "supplier": "East Wind Inc.", - "naming_series": "PR", "posting_date": nowdate(), "posting_time": "12:05", - "company": company, "fiscal_year": webnotes.conn.get_default("fiscal_year"), - "currency": webnotes.conn.get_default("currency"), "conversion_rate": 1 - }, - { - "doctype": "Purchase Receipt Item", - "item_code": "Home Desktop 100", - "qty": 10, "received_qty": 10, "rejected_qty": 0, "purchase_rate": 50, - "amount": 500, "warehouse": "Default Warehouse", - "parentfield": "purchase_receipt_details", - "conversion_factor": 1, "uom": "Nos", "stock_uom": "Nos" - }, - { - "doctype": "Purchase Taxes and Charges", "charge_type": "Actual", - "account_head": "Shipping Charges - %s" % abbr, "rate": 100, "tax_amount": 100, - "category": "Valuation and Total", "parentfield": "purchase_tax_details", - "cost_center": "Default Cost Center - %s" % abbr - }, - { - "doctype": "Purchase Taxes and Charges", "charge_type": "Actual", - "account_head": "VAT - Test - %s" % abbr, "rate": 120, "tax_amount": 120, - "category": "Total", "parentfield": "purchase_tax_details" - }, - { - "doctype": "Purchase Taxes and Charges", "charge_type": "Actual", - "account_head": "Customs Duty - %s" % abbr, "rate": 150, "tax_amount": 150, - "category": "Valuation", "parentfield": "purchase_tax_details", - "cost_center": "Default Cost Center - %s" % abbr - } -] - -def insert_accounts(): - for d in webnotes.conn.sql("""select name, abbr from tabCompany""", as_dict=1): - acc_list = [ - make_account_dict('Stock Assets', 'Current Assets', d, 'Group'), - make_account_dict('Stock In Hand', 'Stock Assets', d, 'Ledger'), - make_account_dict('Stock Delivered But Not Billed', 'Stock Assets', - d, 'Ledger'), - make_account_dict('Stock Liabilities', 'Current Liabilities', d, 'Group'), - make_account_dict('Stock Received But Not Billed', 'Stock Liabilities', - d, 'Ledger'), - make_account_dict('Stock Expenses', 'Direct Expenses', d, 'Group'), - make_account_dict('Stock Variance', 'Stock Expenses', d, 'Ledger'), - make_account_dict('Expenses Included In Valuation', 'Stock Expenses', - d, 'Ledger'), - ] - for acc in acc_list: - acc_name = "%s - %s" % (acc['account_name'], d['abbr']) - if not webnotes.conn.exists('Account', acc_name): - webnotes.insert(acc) - -def make_account_dict(account, parent, company_detail, group_or_ledger): - return { - "doctype": "Account", - "account_name": account, - "parent_account": "%s - %s" % (parent, company_detail['abbr']), - "company": company_detail['name'], - "group_or_ledger": group_or_ledger - } - +import webnotes.defaults +from webnotes.utils import cint class TestPurchaseReceipt(unittest.TestCase): - def setUp(self): - webnotes.conn.begin() - load_data() - webnotes.conn.set_value("Global Defaults", None, "automatic_inventory_accounting", 1) + def test_purchase_receipt_no_gl_entry(self): + pr = webnotes.bean(copy=test_records[0]) + pr.run_method("calculate_taxes_and_totals") + pr.insert() + pr.submit() - def test_purchase_receipt(self): - # warehouse does not have stock in hand specified - self.run_purchase_receipt_test(base_purchase_receipt, - "Stock In Hand - %s" % (abbr,), - "Stock Received But Not Billed - %s" % (abbr,), 750.0) - - def run_purchase_receipt_test(self, purchase_receipt, debit_account, - credit_account, stock_value): - dl = webnotes.insert(DocList(purchase_receipt)) + gl_entries = webnotes.conn.sql("""select account, debit, credit + from `tabGL Entry` where voucher_type='Purchase Receipt' and voucher_no=%s + order by account desc""", pr.doc.name, as_dict=1) + + self.assertTrue(not gl_entries) - from controllers.tax_controller import TaxController - tax_controller = TaxController(dl.doc, dl.doclist) - tax_controller.item_table_field = "purchase_receipt_details" - tax_controller.calculate_taxes_and_totals() - dl.doc = tax_controller.doc - dl.doclist = tax_controller.doclist + def test_purchase_receipt_gl_entry(self): + webnotes.defaults.set_global_default("auto_inventory_accounting", 1) - dl.submit() - dl.load_from_db() + self.assertEqual(cint(webnotes.defaults.get_global_default("auto_inventory_accounting")), 1) - gle = webnotes.conn.sql("""select account, ifnull(debit, 0), ifnull(credit, 0) - from `tabGL Entry` where voucher_no = %s""", dl.doclist[0].name) + pr = webnotes.bean(copy=test_records[0]) + pr.run_method("calculate_taxes_and_totals") + pr.insert() + pr.submit() - gle_map = dict(((entry[0], entry) for entry in gle)) + gl_entries = webnotes.conn.sql("""select account, debit, credit + from `tabGL Entry` where voucher_type='Purchase Receipt' and voucher_no=%s + order by account desc""", pr.doc.name, as_dict=1) + + self.assertTrue(gl_entries) - self.assertEquals(gle_map[debit_account], (debit_account, stock_value, 0.0)) - self.assertEquals(gle_map[credit_account], (credit_account, 0.0, stock_value)) + stock_in_hand_account = webnotes.conn.get_value("Company", pr.doc.company, + "stock_in_hand_account") - def atest_subcontracting(self): - pr = base_purchase_receipt.copy() - pr[1].update({"item_code": "Nebula 7"}) + expected_values = [ + [stock_in_hand_account, 750.0, 0.0], + ["Stock Received But Not Billed - _TC", 0.0, 750.0] + ] - self.run_purchase_receipt_test(pr, - "Stock In Hand - %s" % (abbr,), - "Stock Received But Not Billed - %s" % (abbr,), 1750.0) - - def tearDown(self): - webnotes.conn.rollback() \ No newline at end of file + for i, gle in enumerate(gl_entries): + self.assertEquals(expected_values[i][0], gle.account) + self.assertEquals(expected_values[i][1], gle.debit) + self.assertEquals(expected_values[i][2], gle.credit) + + webnotes.defaults.set_global_default("auto_inventory_accounting", 0) + +test_records = [ + [ + { + "company": "_Test Company", + "conversion_rate": 1.0, + "currency": "INR", + "doctype": "Purchase Receipt", + "fiscal_year": "_Test Fiscal Year 2013", + "posting_date": "2013-02-12", + "posting_time": "15:33:30", + "supplier": "_Test Supplier", + "net_total": 500.0, + "grand_total": 720.0, + }, + { + "conversion_factor": 1.0, + "description": "_Test Item", + "doctype": "Purchase Receipt Item", + "item_code": "_Test Item", + "item_name": "_Test Item", + "parentfield": "purchase_receipt_details", + "received_qty": 10.0, + "qty": 10.0, + "rejected_qty": 0.0, + "import_rate": 50.0, + "amount": 500.0, + "warehouse": "_Test Warehouse", + "stock_uom": "Nos", + "uom": "_Test UOM", + }, + { + "account_head": "_Test Account Shipping Charges - _TC", + "add_deduct_tax": "Add", + "category": "Valuation and Total", + "charge_type": "Actual", + "description": "Shipping Charges", + "doctype": "Purchase Taxes and Charges", + "parentfield": "purchase_tax_details", + "rate": 100.0, + "tax_amount": 100.0, + }, + { + "account_head": "_Test Account VAT - _TC", + "add_deduct_tax": "Add", + "category": "Total", + "charge_type": "Actual", + "description": "VAT", + "doctype": "Purchase Taxes and Charges", + "parentfield": "purchase_tax_details", + "rate": 120.0, + "tax_amount": 120.0, + }, + { + "account_head": "_Test Account Customs Duty - _TC", + "add_deduct_tax": "Add", + "category": "Valuation", + "charge_type": "Actual", + "description": "Customs Duty", + "doctype": "Purchase Taxes and Charges", + "parentfield": "purchase_tax_details", + "rate": 150.0, + "tax_amount": 150.0, + }, + ], +] \ No newline at end of file