diff --git a/.travis.yml b/.travis.yml index 59acb5c0e4..1b4e3403f1 100644 --- a/.travis.yml +++ b/.travis.yml @@ -14,8 +14,15 @@ install: - sudo apt-get update - sudo apt-get purge -y mysql-common - sudo apt-get install mariadb-server mariadb-common libmariadbclient-dev - - CFLAGS=-O0 pip install git+https://github.com/frappe/frappe.git@develop && - - pip install --editable . + - wget http://downloads.sourceforge.net/project/wkhtmltopdf/0.12.1/wkhtmltox-0.12.1_linux-precise-amd64.deb + - sudo dpkg -i wkhtmltox-0.12.1_linux-precise-amd64.deb + - CFLAGS=-O0 pip install git+https://github.com/frappe/frappe.git@develop + - CFLAGS=-O0 pip install --editable . + +before_script: + - mysql -e 'create database test_frappe' + - echo "USE mysql;\nCREATE USER 'test_frappe'@'localhost' IDENTIFIED BY 'test_frappe';\nFLUSH PRIVILEGES;\n" | mysql -u root + - echo "USE mysql;\nGRANT ALL PRIVILEGES ON \`test_frappe\`.* TO 'test_frappe'@'localhost';\n" | mysql -u root script: - cd ./test_sites/ @@ -23,9 +30,6 @@ script: - frappe --reinstall - frappe --install_app erpnext --verbose - frappe -b + - frappe --build_website - frappe --serve_test & - frappe --verbose --run_tests --app erpnext - -before_script: - - mysql -e 'create database test_frappe' - - echo "USE mysql;\nCREATE USER 'test_frappe'@'localhost' IDENTIFIED BY 'test_frappe';\nFLUSH PRIVILEGES;\n" | mysql -u root diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 57fca34c40..a29e0badee 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,16 +1,19 @@ -# Contributing to ERPNext +# Contributing to Frappe / ERPNext ## Reporting issues We only accept issues that are bug reports or feature requests. Bugs must be isolated and reproducible problems. Please read the following guidelines before opening any issue. -1. **Search for existing issues.** We want to avoid duplication, and you'd help us out a lot by first checking if someone else has reported the same issue. The issue may have already been resolved with a fix available. +1. **Search for existing issues:** We want to avoid duplication, and you'd help us out a lot by first checking if someone else has reported the same issue. The issue may have already been resolved with a fix available. +1. **Report each issue separately:** Don't club multiple, unreleated issues in one note. +1. **Mention the version number:** Please mention the application, browser and platform version numbers. ### Issues -1. **Share as much information as possible.** Include operating system and version, browser and version, when did you last update ERPNext, how is it customized, etc. where appropriate. Also include steps to reproduce the bug. -1. Consider adding screenshots annotated with what goes wrong. -1. If you are reporting an issue from the browser, Open the Javascript Console and paste us any error messages you see. +1. **Share as much information as possible:** Include operating system and version, browser and version, when did you last update ERPNext, how is it customized, etc. where appropriate. Also include steps to reproduce the bug. +1. **Include Screenshots if possible:** Consider adding screenshots annotated with what goes wrong. +1. **Find and post the trace for bugs:** If you are reporting an issue from the browser, Open the Javascript Console and paste us any error messages you see. + ### Feature Requests @@ -37,14 +40,10 @@ that function to accommodate your use case. DocTypes are easy to create but hard to maintain. If you find that there is a another DocType with a similar functionality, then please try and extend that functionality. For example, by adding a "type" field to classify the new type of record. -#### Don't Send Trivial Requests - -Don't send pull requests for fixing a simple typo in a code comment. - #### Tabs or spaces? Tabs! ### Copyright -Please see README.md \ No newline at end of file +Please see README.md diff --git a/MANIFEST.in b/MANIFEST.in index 53477f2ed0..3e467e5362 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -16,4 +16,5 @@ recursive-include erpnext *.md recursive-include erpnext *.png recursive-include erpnext *.py recursive-include erpnext *.svg +recursive-include erpnext/public * recursive-exclude * *.pyc diff --git a/README.md b/README.md index 8ad696ea40..ec7605e90e 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ [https://erpnext.com](https://erpnext.com) -Includes Accounting, Inventory, CRM, Sales, Purchase, Projects, HRMS. Built on Python / MySQL. +Includes Accounting, Inventory, CRM, Sales, Purchase, Projects, HRMS. Built on Python / MariaDB. ERPNext is built on [frappe](https://github.com/frappe/frappe) @@ -13,9 +13,9 @@ ERPNext is built on [frappe](https://github.com/frappe/frappe) --- -### Development install +### Install -Use the bench, https://github.com/frappe/frappe-bench. +Use the bench, https://github.com/frappe/bench ### Admin Login diff --git a/erpnext/__init__.py b/erpnext/__init__.py index 4391764022..60bec4fbec 100644 --- a/erpnext/__init__.py +++ b/erpnext/__init__.py @@ -1 +1 @@ -__version__ = '4.0.2' +from erpnext.__version__ import __version__ diff --git a/erpnext/__version__.py b/erpnext/__version__.py new file mode 100644 index 0000000000..5ee6158c52 --- /dev/null +++ b/erpnext/__version__.py @@ -0,0 +1 @@ +__version__ = '4.3.0' diff --git a/erpnext/accounts/doctype/account/account.js b/erpnext/accounts/doctype/account/account.js index f085c8bb6b..aee2d3cf6a 100644 --- a/erpnext/accounts/doctype/account/account.js +++ b/erpnext/accounts/doctype/account/account.js @@ -49,28 +49,25 @@ cur_frm.cscript.master_type = function(doc, cdt, cdn) { } cur_frm.add_fetch('parent_account', 'report_type', 'report_type'); +cur_frm.add_fetch('parent_account', 'root_type', 'root_type'); cur_frm.cscript.account_type = function(doc, cdt, cdn) { if(doc.group_or_ledger=='Ledger') { cur_frm.toggle_display(['tax_rate'], doc.account_type == 'Tax'); - cur_frm.toggle_display('master_type', cstr(doc.account_type)==''); cur_frm.toggle_display('master_name', doc.account_type=='Warehouse' || in_list(['Customer', 'Supplier'], doc.master_type)); } } cur_frm.cscript.add_toolbar_buttons = function(doc) { - cur_frm.appframe.add_button(__('Chart of Accounts'), + cur_frm.add_custom_button(__('Chart of Accounts'), function() { frappe.set_route("Accounts Browser", "Account"); }, 'icon-sitemap') if (cstr(doc.group_or_ledger) == 'Group') { cur_frm.add_custom_button(__('Convert to Ledger'), - function() { cur_frm.cscript.convert_to_ledger(); }, 'icon-retweet') + function() { cur_frm.cscript.convert_to_ledger(); }, 'icon-retweet', 'btn-default'); } else if (cstr(doc.group_or_ledger) == 'Ledger') { - cur_frm.add_custom_button(__('Convert to Group'), - function() { cur_frm.cscript.convert_to_group(); }, 'icon-retweet') - - cur_frm.appframe.add_button(__('View Ledger'), function() { + cur_frm.add_custom_button(__('View Ledger'), function() { frappe.route_options = { "account": doc.name, "from_date": sys_defaults.year_start_date, @@ -79,6 +76,9 @@ cur_frm.cscript.add_toolbar_buttons = function(doc) { }; frappe.set_route("query-report", "General Ledger"); }, "icon-table"); + + cur_frm.add_custom_button(__('Convert to Group'), + function() { cur_frm.cscript.convert_to_group(); }, 'icon-retweet', 'btn-default') } } diff --git a/erpnext/accounts/doctype/account/account.json b/erpnext/accounts/doctype/account/account.json index cf9adc59ae..f909ef60b2 100644 --- a/erpnext/accounts/doctype/account/account.json +++ b/erpnext/accounts/doctype/account/account.json @@ -1,322 +1,332 @@ { - "allow_copy": 1, - "allow_import": 1, - "allow_rename": 1, - "creation": "2013-01-30 12:49:46", - "description": "Heads (or groups) against which Accounting Entries are made and balances are maintained.", - "docstatus": 0, - "doctype": "DocType", - "document_type": "Master", + "allow_copy": 1, + "allow_import": 1, + "allow_rename": 1, + "creation": "2013-01-30 12:49:46", + "description": "Heads (or groups) against which Accounting Entries are made and balances are maintained.", + "docstatus": 0, + "doctype": "DocType", + "document_type": "Master", "fields": [ { - "fieldname": "properties", - "fieldtype": "Section Break", - "in_list_view": 0, - "label": "Account Details", - "oldfieldtype": "Section Break", + "fieldname": "properties", + "fieldtype": "Section Break", + "in_list_view": 0, + "label": "Account Details", + "oldfieldtype": "Section Break", "permlevel": 0 - }, + }, { - "fieldname": "column_break0", - "fieldtype": "Column Break", - "in_list_view": 0, - "permlevel": 0, + "fieldname": "column_break0", + "fieldtype": "Column Break", + "in_list_view": 0, + "permlevel": 0, "width": "50%" - }, + }, { - "fieldname": "account_name", - "fieldtype": "Data", - "in_filter": 1, - "in_list_view": 1, - "label": "Account Name", - "no_copy": 1, - "oldfieldname": "account_name", - "oldfieldtype": "Data", - "permlevel": 0, - "read_only": 1, - "reqd": 1, + "fieldname": "account_name", + "fieldtype": "Data", + "in_filter": 1, + "in_list_view": 1, + "label": "Account Name", + "no_copy": 1, + "oldfieldname": "account_name", + "oldfieldtype": "Data", + "permlevel": 0, + "read_only": 1, + "reqd": 1, "search_index": 1 - }, + }, { - "default": "Ledger", - "fieldname": "group_or_ledger", - "fieldtype": "Select", - "in_filter": 1, - "in_list_view": 1, - "label": "Group or Ledger", - "oldfieldname": "group_or_ledger", - "oldfieldtype": "Select", - "options": "\nLedger\nGroup", - "permlevel": 0, - "read_only": 1, - "reqd": 1, + "default": "Ledger", + "fieldname": "group_or_ledger", + "fieldtype": "Select", + "in_filter": 1, + "in_list_view": 1, + "label": "Group or Ledger", + "oldfieldname": "group_or_ledger", + "oldfieldtype": "Select", + "options": "\nLedger\nGroup", + "permlevel": 0, + "read_only": 1, + "reqd": 1, "search_index": 1 - }, + }, { - "fieldname": "company", - "fieldtype": "Link", - "in_filter": 1, - "label": "Company", - "oldfieldname": "company", - "oldfieldtype": "Link", - "options": "Company", - "permlevel": 0, - "read_only": 1, - "reqd": 1, + "fieldname": "company", + "fieldtype": "Link", + "in_filter": 1, + "label": "Company", + "oldfieldname": "company", + "oldfieldtype": "Link", + "options": "Company", + "permlevel": 0, + "read_only": 1, + "reqd": 1, "search_index": 1 - }, + }, { - "fieldname": "column_break1", - "fieldtype": "Column Break", - "permlevel": 0, + "fieldname": "column_break1", + "fieldtype": "Column Break", + "permlevel": 0, "width": "50%" - }, + }, { - "fieldname": "parent_account", - "fieldtype": "Link", - "ignore_restrictions": 1, - "label": "Parent Account", - "oldfieldname": "parent_account", - "oldfieldtype": "Link", - "options": "Account", - "permlevel": 0, + "fieldname": "parent_account", + "fieldtype": "Link", + "ignore_user_permissions": 1, + "label": "Parent Account", + "oldfieldname": "parent_account", + "oldfieldtype": "Link", + "options": "Account", + "permlevel": 0, + "reqd": 1, "search_index": 1 - }, + }, { - "fieldname": "report_type", - "fieldtype": "Select", - "label": "Report Type", - "options": "\nBalance Sheet\nProfit and Loss", - "permlevel": 0 - }, - { - "description": "Setting Account Type helps in selecting this Account in transactions.", - "fieldname": "account_type", - "fieldtype": "Select", - "in_filter": 1, - "label": "Account Type", - "oldfieldname": "account_type", - "oldfieldtype": "Select", - "options": "\nBank\nCash\nTax\nChargeable\nWarehouse\nReceivable\nPayable\nEquity\nFixed Asset\nCost of Goods Sold\nExpense Account\nIncome Account\nStock Received But Not Billed\nExpenses Included In Valuation\nStock Adjustment", - "permlevel": 0, + "description": "Setting Account Type helps in selecting this Account in transactions.", + "fieldname": "account_type", + "fieldtype": "Select", + "in_filter": 1, + "label": "Account Type", + "oldfieldname": "account_type", + "oldfieldtype": "Select", + "options": "\nBank\nCash\nTax\nChargeable\nWarehouse\nReceivable\nPayable\nEquity\nFixed Asset\nCost of Goods Sold\nExpense Account\nIncome Account\nStock Received But Not Billed\nExpenses Included In Valuation\nStock Adjustment\nStock", + "permlevel": 0, "search_index": 0 - }, + }, { - "description": "Rate at which this tax is applied", - "fieldname": "tax_rate", - "fieldtype": "Float", - "hidden": 0, - "label": "Rate", - "oldfieldname": "tax_rate", - "oldfieldtype": "Currency", - "permlevel": 0, + "description": "Rate at which this tax is applied", + "fieldname": "tax_rate", + "fieldtype": "Float", + "hidden": 0, + "label": "Rate", + "oldfieldname": "tax_rate", + "oldfieldtype": "Currency", + "permlevel": 0, "reqd": 0 - }, + }, { - "description": "If the account is frozen, entries are allowed to restricted users.", - "fieldname": "freeze_account", - "fieldtype": "Select", - "label": "Frozen", - "oldfieldname": "freeze_account", - "oldfieldtype": "Select", - "options": "No\nYes", + "description": "If the account is frozen, entries are allowed to restricted users.", + "fieldname": "freeze_account", + "fieldtype": "Select", + "label": "Frozen", + "oldfieldname": "freeze_account", + "oldfieldtype": "Select", + "options": "No\nYes", "permlevel": 0 - }, + }, { - "fieldname": "credit_days", - "fieldtype": "Int", - "hidden": 1, - "label": "Credit Days", - "oldfieldname": "credit_days", - "oldfieldtype": "Int", - "permlevel": 0, + "fieldname": "credit_days", + "fieldtype": "Int", + "hidden": 1, + "label": "Credit Days", + "oldfieldname": "credit_days", + "oldfieldtype": "Int", + "permlevel": 0, "print_hide": 1 - }, + }, { - "fieldname": "credit_limit", - "fieldtype": "Currency", - "hidden": 1, - "label": "Credit Limit", - "oldfieldname": "credit_limit", - "oldfieldtype": "Currency", - "options": "Company:company:default_currency", - "permlevel": 0, + "fieldname": "credit_limit", + "fieldtype": "Currency", + "hidden": 1, + "label": "Credit Limit", + "oldfieldname": "credit_limit", + "oldfieldtype": "Currency", + "options": "Company:company:default_currency", + "permlevel": 0, "print_hide": 1 - }, + }, { - "description": "If this Account represents a Customer, Supplier or Employee, set it here.", - "fieldname": "master_type", - "fieldtype": "Select", - "label": "Master Type", - "oldfieldname": "master_type", - "oldfieldtype": "Select", - "options": "\nSupplier\nCustomer\nEmployee", + "description": "If this Account represents a Customer, Supplier or Employee, set it here.", + "fieldname": "master_type", + "fieldtype": "Select", + "label": "Master Type", + "oldfieldname": "master_type", + "oldfieldtype": "Select", + "options": "\nSupplier\nCustomer\nEmployee", "permlevel": 0 - }, + }, { - "fieldname": "master_name", - "fieldtype": "Link", - "label": "Master Name", - "oldfieldname": "master_name", - "oldfieldtype": "Link", - "options": "[Select]", + "fieldname": "master_name", + "fieldtype": "Link", + "label": "Master Name", + "oldfieldname": "master_name", + "oldfieldtype": "Link", + "options": "[Select]", "permlevel": 0 - }, + }, { - "fieldname": "balance_must_be", - "fieldtype": "Select", - "label": "Balance must be", - "options": "\nDebit\nCredit", + "fieldname": "balance_must_be", + "fieldtype": "Select", + "label": "Balance must be", + "options": "\nDebit\nCredit", "permlevel": 0 - }, + }, { - "fieldname": "lft", - "fieldtype": "Int", - "hidden": 1, - "label": "Lft", - "permlevel": 0, - "print_hide": 1, + "fieldname": "root_type", + "fieldtype": "Select", + "label": "Root Type", + "options": "\nAsset\nLiability\nIncome\nExpense\nEquity", + "permlevel": 0, "read_only": 1 - }, + }, { - "fieldname": "rgt", - "fieldtype": "Int", - "hidden": 1, - "label": "Rgt", - "permlevel": 0, - "print_hide": 1, + "fieldname": "report_type", + "fieldtype": "Select", + "label": "Report Type", + "options": "\nBalance Sheet\nProfit and Loss", + "permlevel": 0, "read_only": 1 - }, + }, { - "fieldname": "old_parent", - "fieldtype": "Data", - "hidden": 1, - "label": "Old Parent", - "permlevel": 0, - "print_hide": 1, + "fieldname": "lft", + "fieldtype": "Int", + "hidden": 1, + "label": "Lft", + "permlevel": 0, + "print_hide": 1, + "read_only": 1 + }, + { + "fieldname": "rgt", + "fieldtype": "Int", + "hidden": 1, + "label": "Rgt", + "permlevel": 0, + "print_hide": 1, + "read_only": 1 + }, + { + "fieldname": "old_parent", + "fieldtype": "Data", + "hidden": 1, + "label": "Old Parent", + "permlevel": 0, + "print_hide": 1, "read_only": 1 } - ], - "icon": "icon-money", - "idx": 1, - "in_create": 1, - "modified": "2014-05-12 17:03:19.733139", - "modified_by": "Administrator", - "module": "Accounts", - "name": "Account", - "owner": "Administrator", + ], + "icon": "icon-money", + "idx": 1, + "in_create": 1, + "modified": "2014-06-19 18:27:58.109303", + "modified_by": "Administrator", + "module": "Accounts", + "name": "Account", + "owner": "Administrator", "permissions": [ { - "amend": 0, - "cancel": 0, - "create": 1, - "delete": 1, - "email": 1, - "export": 1, - "import": 1, - "permlevel": 0, - "print": 1, - "read": 1, - "report": 1, - "role": "Accounts User", - "submit": 0, + "amend": 0, + "apply_user_permissions": 1, + "create": 1, + "delete": 1, + "email": 1, + "export": 1, + "import": 1, + "permlevel": 0, + "print": 1, + "read": 1, + "report": 1, + "role": "Accounts User", + "submit": 0, "write": 1 - }, + }, { - "amend": 0, - "cancel": 0, - "create": 0, - "delete": 0, - "email": 1, - "permlevel": 0, - "print": 1, - "read": 1, - "report": 1, - "role": "Auditor", - "submit": 0, + "amend": 0, + "apply_user_permissions": 1, + "create": 0, + "delete": 0, + "email": 1, + "permlevel": 0, + "print": 1, + "read": 1, + "report": 1, + "role": "Auditor", + "submit": 0, "write": 0 - }, + }, { - "amend": 0, - "cancel": 0, - "create": 0, - "delete": 0, - "email": 1, - "permlevel": 0, - "print": 1, - "read": 1, - "report": 1, - "role": "Sales User", - "submit": 0, + "amend": 0, + "apply_user_permissions": 1, + "create": 0, + "delete": 0, + "email": 1, + "permlevel": 0, + "print": 1, + "read": 1, + "report": 1, + "role": "Sales User", + "submit": 0, "write": 0 - }, + }, { - "amend": 0, - "cancel": 0, - "create": 0, - "delete": 0, - "email": 1, - "permlevel": 0, - "print": 1, - "read": 1, - "report": 1, - "role": "Purchase User", - "submit": 0, + "amend": 0, + "apply_user_permissions": 1, + "create": 0, + "delete": 0, + "email": 1, + "permlevel": 0, + "print": 1, + "read": 1, + "report": 1, + "role": "Purchase User", + "submit": 0, "write": 0 - }, + }, { - "amend": 0, - "cancel": 0, - "create": 0, - "delete": 0, - "permlevel": 2, - "read": 1, - "report": 1, - "role": "Auditor", - "submit": 0, + "amend": 0, + "cancel": 0, + "create": 0, + "delete": 0, + "permlevel": 2, + "read": 1, + "report": 1, + "role": "Auditor", + "submit": 0, "write": 0 - }, + }, { - "amend": 0, - "cancel": 0, - "create": 1, - "delete": 1, - "email": 1, - "export": 1, - "import": 1, - "permlevel": 0, - "print": 1, - "read": 1, - "report": 1, - "restrict": 1, - "role": "Accounts Manager", - "submit": 0, + "amend": 0, + "apply_user_permissions": 0, + "create": 1, + "delete": 1, + "email": 1, + "export": 1, + "import": 1, + "permlevel": 0, + "print": 1, + "read": 1, + "report": 1, + "role": "Accounts Manager", + "set_user_permissions": 1, + "submit": 0, "write": 1 - }, + }, { - "amend": 0, - "cancel": 0, - "create": 0, - "delete": 0, - "permlevel": 2, - "read": 1, - "report": 1, - "role": "Accounts Manager", - "submit": 0, + "amend": 0, + "cancel": 0, + "create": 0, + "delete": 0, + "permlevel": 2, + "read": 1, + "report": 1, + "role": "Accounts Manager", + "submit": 0, "write": 1 - }, + }, { - "amend": 0, - "cancel": 0, - "create": 0, - "delete": 0, - "permlevel": 2, - "read": 1, - "report": 1, - "role": "Accounts User", - "submit": 0, + "amend": 0, + "cancel": 0, + "create": 0, + "delete": 0, + "permlevel": 2, + "read": 1, + "report": 1, + "role": "Accounts User", + "submit": 0, "write": 0 } - ], + ], "search_fields": "group_or_ledger" -} \ No newline at end of file +} diff --git a/erpnext/accounts/doctype/account/account.py b/erpnext/accounts/doctype/account/account.py index ad588b5291..e067c70bf0 100644 --- a/erpnext/accounts/doctype/account/account.py +++ b/erpnext/accounts/doctype/account/account.py @@ -11,11 +11,11 @@ class Account(Document): nsm_parent_field = 'parent_account' def onload(self): - frozen_accounts_modifier = frappe.db.get_value("Accounts Settings", "Accounts Settings", "frozen_accounts_modifier") - if frozen_accounts_modifier in frappe.user.get_roles(): + frozen_accounts_modifier = frappe.db.get_value("Accounts Settings", "Accounts Settings", + "frozen_accounts_modifier") + if not frozen_accounts_modifier or frozen_accounts_modifier in frappe.user.get_roles(): self.get("__onload").can_freeze_account = True - def autoname(self): self.name = self.account_name.strip() + ' - ' + \ frappe.db.get_value("Company", self.company, "abbr") @@ -30,6 +30,7 @@ class Account(Document): self.validate_mandatory() self.validate_warehouse_account() self.validate_frozen_accounts_modifier() + self.validate_balance_must_be_debit_or_credit() def validate_master_name(self): if self.master_type in ('Customer', 'Supplier') or self.account_type == "Warehouse": @@ -39,19 +40,24 @@ class Account(Document): throw(_("Invalid Master Name")) def validate_parent(self): - """Fetch Parent Details and validation for account not to be created under ledger""" + """Fetch Parent Details and validate parent account""" if self.parent_account: par = frappe.db.get_value("Account", self.parent_account, - ["name", "group_or_ledger", "report_type"], as_dict=1) + ["name", "group_or_ledger", "report_type", "root_type", "company"], as_dict=1) if not par: - throw(_("Parent account does not exist")) - elif par["name"] == self.name: - throw(_("You can not assign itself as parent account")) - elif par["group_or_ledger"] != 'Group': - throw(_("Parent account can not be a ledger")) + throw(_("Account {0}: Parent account {1} does not exist").format(self.name, self.parent_account)) + elif par.name == self.name: + throw(_("Account {0}: You can not assign itself as parent account").format(self.name)) + elif par.group_or_ledger != 'Group': + throw(_("Account {0}: Parent account {1} can not be a ledger").format(self.name, self.parent_account)) + elif par.company != self.company: + throw(_("Account {0}: Parent account {1} does not belong to company: {2}") + .format(self.name, self.parent_account, self.company)) - if par["report_type"]: - self.report_type = par["report_type"] + if par.report_type: + self.report_type = par.report_type + if par.root_type: + self.root_type = par.root_type def validate_root_details(self): #does not exists parent @@ -67,6 +73,16 @@ class Account(Document): frozen_accounts_modifier not in frappe.user.get_roles(): throw(_("You are not authorized to set Frozen value")) + def validate_balance_must_be_debit_or_credit(self): + from erpnext.accounts.utils import get_balance_on + if not self.get("__islocal") and self.balance_must_be: + account_balance = get_balance_on(self.name) + + if account_balance > 0 and self.balance_must_be == "Credit": + frappe.throw(_("Account balance already in Debit, you are not allowed to set 'Balance Must Be' as 'Credit'")) + elif account_balance < 0 and self.balance_must_be == "Debit": + frappe.throw(_("Account balance already in Credit, you are not allowed to set 'Balance Must Be' as 'Debit'")) + def convert_group_to_ledger(self): if self.check_if_child_exists(): throw(_("Account with child nodes cannot be converted to ledger")) @@ -99,6 +115,9 @@ class Account(Document): if not self.report_type: throw(_("Report Type is mandatory")) + if not self.root_type: + throw(_("Root Type is mandatory")) + def validate_warehouse_account(self): if not cint(frappe.defaults.get_global_default("auto_accounting_for_stock")): return @@ -146,7 +165,7 @@ class Account(Document): # If outstanding greater than credit limit and not authorized person raise exception if credit_limit > 0 and flt(total_outstanding) > credit_limit \ and not self.get_authorized_user(): - throw(_("{0} Credit limit {0} crossed").format(_(credit_limit_from), credit_limit)) + throw(_("{0} Credit limit {1} crossed").format(_(credit_limit_from), credit_limit)) def validate_due_date(self, posting_date, due_date): credit_days = (self.credit_days or frappe.db.get_value("Company", self.company, "credit_days")) @@ -194,10 +213,10 @@ class Account(Document): throw(_("Account {0} does not exist").format(new)) val = list(frappe.db.get_value("Account", new_account, - ["group_or_ledger", "report_type", "company"])) + ["group_or_ledger", "root_type", "company"])) - if val != [self.group_or_ledger, self.report_type, self.company]: - throw(_("""Merging is only possible if following properties are same in both records. Group or Ledger, Report Type, Company""")) + if val != [self.group_or_ledger, self.root_type, self.company]: + throw(_("""Merging is only possible if following properties are same in both records. Group or Ledger, Root Type, Company""")) return new_account diff --git a/erpnext/accounts/doctype/account/test_account.py b/erpnext/accounts/doctype/account/test_account.py index 37746299e6..bb9102f1f6 100644 --- a/erpnext/accounts/doctype/account/test_account.py +++ b/erpnext/accounts/doctype/account/test_account.py @@ -14,6 +14,7 @@ def _make_test_records(verbose): ["_Test Account Stock Expenses", "Direct Expenses", "Group", None], ["_Test Account Shipping Charges", "_Test Account Stock Expenses", "Ledger", "Chargeable"], ["_Test Account Customs Duty", "_Test Account Stock Expenses", "Ledger", "Tax"], + ["_Test Account Insurance Charges", "_Test Account Stock Expenses", "Ledger", "Chargeable"], ["_Test Account Tax Assets", "Current Assets", "Group", None], diff --git a/erpnext/accounts/doctype/bank_reconciliation/bank_reconciliation.json b/erpnext/accounts/doctype/bank_reconciliation/bank_reconciliation.json index d0757fd493..6af86edb4d 100644 --- a/erpnext/accounts/doctype/bank_reconciliation/bank_reconciliation.json +++ b/erpnext/accounts/doctype/bank_reconciliation/bank_reconciliation.json @@ -85,7 +85,7 @@ "icon": "icon-check", "idx": 1, "issingle": 1, - "modified": "2014-05-06 16:26:08.984595", + "modified": "2014-05-27 03:37:21.783216", "modified_by": "Administrator", "module": "Accounts", "name": "Bank Reconciliation", @@ -93,6 +93,7 @@ "permissions": [ { "amend": 0, + "apply_user_permissions": 0, "cancel": 0, "create": 1, "permlevel": 0, diff --git a/erpnext/accounts/doctype/bank_reconciliation/bank_reconciliation.py b/erpnext/accounts/doctype/bank_reconciliation/bank_reconciliation.py index a4118989b0..2838afab88 100644 --- a/erpnext/accounts/doctype/bank_reconciliation/bank_reconciliation.py +++ b/erpnext/accounts/doctype/bank_reconciliation/bank_reconciliation.py @@ -24,7 +24,8 @@ class BankReconciliation(Document): `tabJournal Voucher` t1, `tabJournal Voucher Detail` t2 where t2.parent = t1.name and t2.account = %s - and t1.posting_date >= %s and t1.posting_date <= %s and t1.docstatus=1 %s""" % + and t1.posting_date >= %s and t1.posting_date <= %s and t1.docstatus=1 + and ifnull(t1.is_opening, 'No') = 'No' %s""" % ('%s', '%s', '%s', condition), (self.bank_account, self.from_date, self.to_date), as_dict=1) self.set('entries', []) diff --git a/erpnext/accounts/doctype/c_form/c_form.json b/erpnext/accounts/doctype/c_form/c_form.json index 87d2922c63..0fa6635b13 100644 --- a/erpnext/accounts/doctype/c_form/c_form.json +++ b/erpnext/accounts/doctype/c_form/c_form.json @@ -1,5 +1,5 @@ { - "allow_attach": 1, + "allow_import": 1, "autoname": "naming_series:", "creation": "2013-03-07 11:55:06", "docstatus": 0, @@ -126,7 +126,7 @@ { "fieldname": "amended_from", "fieldtype": "Link", - "ignore_restrictions": 1, + "ignore_user_permissions": 1, "label": "Amended From", "no_copy": 1, "options": "C-Form", @@ -139,13 +139,14 @@ "idx": 1, "is_submittable": 1, "max_attachments": 3, - "modified": "2014-05-09 02:18:00.162685", + "modified": "2014-09-05 12:58:43.333698", "modified_by": "Administrator", "module": "Accounts", "name": "C-Form", "owner": "Administrator", "permissions": [ { + "apply_user_permissions": 1, "create": 1, "email": 1, "permlevel": 0, diff --git a/erpnext/accounts/doctype/c_form/c_form.py b/erpnext/accounts/doctype/c_form/c_form.py index 11d05470aa..88ced9a813 100644 --- a/erpnext/accounts/doctype/c_form/c_form.py +++ b/erpnext/accounts/doctype/c_form/c_form.py @@ -55,22 +55,12 @@ class CForm(Document): def get_invoice_details(self, invoice_no): """ Pull details from invoices for referrence """ - - inv = frappe.db.get_value("Sales Invoice", invoice_no, - ["posting_date", "territory", "net_total", "grand_total"], as_dict=True) - return { - 'invoice_date' : inv.posting_date, - 'territory' : inv.territory, - 'net_total' : inv.net_total, - 'grand_total' : inv.grand_total - } - -def get_invoice_nos(doctype, txt, searchfield, start, page_len, filters): - from erpnext.utilities import build_filter_conditions - conditions, filter_values = build_filter_conditions(filters) - - return frappe.db.sql("""select name from `tabSales Invoice` where docstatus = 1 - and c_form_applicable = 'Yes' and ifnull(c_form_no, '') = '' %s - and %s like %s order by name limit %s, %s""" % - (conditions, searchfield, "%s", "%s", "%s"), - tuple(filter_values + ["%%%s%%" % txt, start, page_len])) + if invoice_no: + inv = frappe.db.get_value("Sales Invoice", invoice_no, + ["posting_date", "territory", "net_total", "grand_total"], as_dict=True) + return { + 'invoice_date' : inv.posting_date, + 'territory' : inv.territory, + 'net_total' : inv.net_total, + 'grand_total' : inv.grand_total + } diff --git a/erpnext/accounts/doctype/chart_of_accounts/charts/import_from_openerp.py b/erpnext/accounts/doctype/chart_of_accounts/charts/import_from_openerp.py index 7a3a877aae..a03cab4c99 100644 --- a/erpnext/accounts/doctype/chart_of_accounts/charts/import_from_openerp.py +++ b/erpnext/accounts/doctype/chart_of_accounts/charts/import_from_openerp.py @@ -9,7 +9,7 @@ from __future__ import unicode_literals import os, json import ast from xml.etree import ElementTree as ET -from frappe.utils.datautils import read_csv_content +from frappe.utils.csvutils import read_csv_content from frappe.utils import cstr import frappe diff --git a/erpnext/accounts/doctype/chart_of_accounts/import_charts.py b/erpnext/accounts/doctype/chart_of_accounts/import_charts.py index 9e60551665..7a47f6ee36 100644 --- a/erpnext/accounts/doctype/chart_of_accounts/import_charts.py +++ b/erpnext/accounts/doctype/chart_of_accounts/import_charts.py @@ -5,6 +5,7 @@ from __future__ import unicode_literals import frappe, os, json def import_charts(): + print "Importing Chart of Accounts" frappe.db.sql("""delete from `tabChart of Accounts`""") charts_dir = os.path.join(os.path.dirname(__file__), "charts") for fname in os.listdir(charts_dir): @@ -19,8 +20,8 @@ def import_charts(): "source_file": fname, "country": country }).insert() - print doc.name.encode("utf-8") - else: - print "No chart for: " + chart.get("name").encode("utf-8") - - frappe.db.commit() \ No newline at end of file + #print doc.name.encode("utf-8") + #else: + #print "No chart for: " + chart.get("name").encode("utf-8") + + frappe.db.commit() diff --git a/erpnext/accounts/doctype/cost_center/cost_center.js b/erpnext/accounts/doctype/cost_center/cost_center.js index 808ad52889..d9e71d98ed 100644 --- a/erpnext/accounts/doctype/cost_center/cost_center.js +++ b/erpnext/accounts/doctype/cost_center/cost_center.js @@ -64,10 +64,12 @@ cur_frm.cscript.parent_cost_center = function(doc, cdt, cdn) { cur_frm.cscript.hide_unhide_group_ledger = function(doc) { if (cstr(doc.group_or_ledger) == 'Group') { cur_frm.add_custom_button(__('Convert to Ledger'), - function() { cur_frm.cscript.convert_to_ledger(); }, 'icon-retweet') + function() { cur_frm.cscript.convert_to_ledger(); }, 'icon-retweet', + "btn-default") } else if (cstr(doc.group_or_ledger) == 'Ledger') { cur_frm.add_custom_button(__('Convert to Group'), - function() { cur_frm.cscript.convert_to_group(); }, 'icon-retweet') + function() { cur_frm.cscript.convert_to_group(); }, 'icon-retweet', + "btn-default") } } diff --git a/erpnext/accounts/doctype/cost_center/cost_center.json b/erpnext/accounts/doctype/cost_center/cost_center.json index d497974e43..e65f74bdb9 100644 --- a/erpnext/accounts/doctype/cost_center/cost_center.json +++ b/erpnext/accounts/doctype/cost_center/cost_center.json @@ -31,7 +31,7 @@ { "fieldname": "parent_cost_center", "fieldtype": "Link", - "ignore_restrictions": 1, + "ignore_user_permissions": 1, "in_list_view": 1, "label": "Parent Cost Center", "oldfieldname": "parent_cost_center", @@ -131,7 +131,7 @@ "fieldname": "old_parent", "fieldtype": "Link", "hidden": 1, - "ignore_restrictions": 1, + "ignore_user_permissions": 1, "label": "old_parent", "no_copy": 1, "oldfieldname": "old_parent", @@ -144,8 +144,8 @@ ], "icon": "icon-money", "idx": 1, - "in_create": 1, - "modified": "2014-05-07 06:37:48.038993", + "in_create": 0, + "modified": "2014-08-26 12:16:11.163750", "modified_by": "Administrator", "module": "Accounts", "name": "Cost Center", @@ -153,7 +153,6 @@ "permissions": [ { "amend": 0, - "cancel": 0, "create": 1, "delete": 1, "email": 1, @@ -167,7 +166,7 @@ }, { "amend": 0, - "cancel": 0, + "apply_user_permissions": 1, "create": 0, "delete": 0, "email": 1, @@ -180,16 +179,19 @@ "write": 0 }, { + "apply_user_permissions": 1, "permlevel": 0, "read": 1, "role": "Sales User" }, { + "apply_user_permissions": 1, "permlevel": 0, "read": 1, "role": "Purchase User" }, { + "apply_user_permissions": 1, "permlevel": 0, "read": 1, "role": "Material User" diff --git a/erpnext/accounts/doctype/cost_center/test_records.json b/erpnext/accounts/doctype/cost_center/test_records.json index 9e3e011fe2..7ffc687a9c 100644 --- a/erpnext/accounts/doctype/cost_center/test_records.json +++ b/erpnext/accounts/doctype/cost_center/test_records.json @@ -15,5 +15,12 @@ "doctype": "Cost Center", "group_or_ledger": "Ledger", "parent_cost_center": "_Test Company - _TC" + }, + { + "company": "_Test Company", + "cost_center_name": "_Test Cost Center 2", + "doctype": "Cost Center", + "group_or_ledger": "Ledger", + "parent_cost_center": "_Test Company - _TC" } ] \ No newline at end of file diff --git a/erpnext/accounts/doctype/fiscal_year/fiscal_year.js b/erpnext/accounts/doctype/fiscal_year/fiscal_year.js index f6f19f7e82..b68cfb990c 100644 --- a/erpnext/accounts/doctype/fiscal_year/fiscal_year.js +++ b/erpnext/accounts/doctype/fiscal_year/fiscal_year.js @@ -14,7 +14,8 @@ $.extend(cur_frm.cscript, { this.frm.toggle_enable('year_end_date', doc.__islocal) if (!doc.__islocal && (doc.name != sys_defaults.fiscal_year)) { - this.frm.add_custom_button(__("Set as Default"), this.frm.cscript.set_as_default); + this.frm.add_custom_button(__("Set as Default"), + this.frm.cscript.set_as_default, "icon-star"); this.frm.set_intro(__("To set this Fiscal Year as Default, click on 'Set as Default'")); } else { this.frm.set_intro(""); diff --git a/erpnext/accounts/doctype/fiscal_year/fiscal_year.json b/erpnext/accounts/doctype/fiscal_year/fiscal_year.json index 314dfab1a7..0f7aefd312 100644 --- a/erpnext/accounts/doctype/fiscal_year/fiscal_year.json +++ b/erpnext/accounts/doctype/fiscal_year/fiscal_year.json @@ -1,7 +1,7 @@ { "allow_import": 1, "autoname": "field:year", - "creation": "2013-01-22 16:50:25.000000", + "creation": "2013-01-22 16:50:25", "description": "**Fiscal Year** represents a Financial Year. All accounting entries and other major transactions are tracked against **Fiscal Year**.", "docstatus": 0, "doctype": "DocType", @@ -11,6 +11,7 @@ "description": "For e.g. 2012, 2012-13", "fieldname": "year", "fieldtype": "Data", + "in_list_view": 1, "label": "Year Name", "oldfieldname": "year", "oldfieldtype": "Data", @@ -20,6 +21,7 @@ { "fieldname": "year_start_date", "fieldtype": "Date", + "in_list_view": 1, "label": "Year Start Date", "no_copy": 1, "oldfieldname": "year_start_date", @@ -30,6 +32,7 @@ { "fieldname": "year_end_date", "fieldtype": "Date", + "in_list_view": 1, "label": "Year End Date", "no_copy": 1, "permlevel": 0, @@ -40,6 +43,7 @@ "description": "Entries are not allowed against this Fiscal Year if the year is closed.", "fieldname": "is_fiscal_year_closed", "fieldtype": "Select", + "in_list_view": 1, "label": "Year Closed", "no_copy": 1, "oldfieldname": "is_fiscal_year_closed", @@ -51,14 +55,13 @@ ], "icon": "icon-calendar", "idx": 1, - "modified": "2014-01-20 17:48:46.000000", + "modified": "2014-07-14 05:30:56.843180", "modified_by": "Administrator", "module": "Accounts", "name": "Fiscal Year", "owner": "Administrator", "permissions": [ { - "cancel": 0, "create": 1, "delete": 1, "email": 1, @@ -71,6 +74,7 @@ "write": 1 }, { + "apply_user_permissions": 1, "delete": 0, "email": 1, "permlevel": 0, @@ -78,5 +82,7 @@ "read": 1, "role": "All" } - ] + ], + "sort_field": "name", + "sort_order": "DESC" } \ No newline at end of file diff --git a/erpnext/accounts/doctype/fiscal_year/fiscal_year.py b/erpnext/accounts/doctype/fiscal_year/fiscal_year.py index 0a7a98565a..cb36581302 100644 --- a/erpnext/accounts/doctype/fiscal_year/fiscal_year.py +++ b/erpnext/accounts/doctype/fiscal_year/fiscal_year.py @@ -25,15 +25,15 @@ class FiscalYear(Document): if year_start_end_dates: if getdate(self.year_start_date) != year_start_end_dates[0][0] or getdate(self.year_end_date) != year_start_end_dates[0][1]: - frappe.throw(_("Cannot change Year Start Date and Year End Date once the Fiscal Year is saved.")) + frappe.throw(_("Cannot change Fiscal Year Start Date and Fiscal Year End Date once the Fiscal Year is saved.")) def on_update(self): # validate year start date and year end date if getdate(self.year_start_date) > getdate(self.year_end_date): - frappe.throw(_("Year Start Date should not be greater than Year End Date")) + frappe.throw(_("Fiscal Year Start Date should not be greater than Fiscal Year End Date")) if (getdate(self.year_end_date) - getdate(self.year_start_date)).days > 366: - frappe.throw(_("Year Start Date and Year End Date are not within Fiscal Year.")) + frappe.throw(_("Fiscal Year Start Date and Fiscal Year End Date cannot be more than a year apart.")) year_start_end_dates = frappe.db.sql("""select name, year_start_date, year_end_date from `tabFiscal Year` where name!=%s""", (self.name)) @@ -41,4 +41,4 @@ class FiscalYear(Document): for fiscal_year, ysd, yed in year_start_end_dates: if (getdate(self.year_start_date) == ysd and getdate(self.year_end_date) == yed) \ and (not frappe.flags.in_test): - frappe.throw(_("Year Start Date and Year End Date are already set in Fiscal Year {0}").format(fiscal_year)) + frappe.throw(_("Fiscal Year Start Date and Fiscal Year End Date are already set in Fiscal Year {0}").format(fiscal_year)) diff --git a/erpnext/accounts/doctype/gl_entry/gl_entry.json b/erpnext/accounts/doctype/gl_entry/gl_entry.json index e6290a3835..07578e2761 100644 --- a/erpnext/accounts/doctype/gl_entry/gl_entry.json +++ b/erpnext/accounts/doctype/gl_entry/gl_entry.json @@ -86,44 +86,47 @@ "oldfieldtype": "Text", "permlevel": 0 }, - { - "fieldname": "against_voucher", - "fieldtype": "Data", - "in_filter": 1, - "label": "Against Voucher", - "oldfieldname": "against_voucher", - "oldfieldtype": "Data", - "permlevel": 0, - "search_index": 0 - }, { "fieldname": "against_voucher_type", - "fieldtype": "Data", + "fieldtype": "Link", "in_filter": 0, "label": "Against Voucher Type", "oldfieldname": "against_voucher_type", "oldfieldtype": "Data", + "options": "DocType", + "permlevel": 0, + "search_index": 0 + }, + { + "fieldname": "against_voucher", + "fieldtype": "Dynamic Link", + "in_filter": 1, + "label": "Against Voucher", + "oldfieldname": "against_voucher", + "oldfieldtype": "Data", + "options": "against_voucher_type", "permlevel": 0, "search_index": 0 }, { "fieldname": "voucher_type", - "fieldtype": "Select", + "fieldtype": "Link", "in_filter": 1, "label": "Voucher Type", "oldfieldname": "voucher_type", "oldfieldtype": "Select", - "options": "Journal Voucher\nSales Invoice\nPurchase Invoice", + "options": "DocType", "permlevel": 0, "search_index": 0 }, { "fieldname": "voucher_no", - "fieldtype": "Data", + "fieldtype": "Dynamic Link", "in_filter": 1, "label": "Voucher No", "oldfieldname": "voucher_no", "oldfieldtype": "Data", + "options": "voucher_type", "permlevel": 0, "search_index": 1 }, @@ -186,7 +189,7 @@ "icon": "icon-list", "idx": 1, "in_create": 1, - "modified": "2014-05-09 02:16:29.981405", + "modified": "2014-06-23 08:07:30.678730", "modified_by": "Administrator", "module": "Accounts", "name": "GL Entry", @@ -194,9 +197,10 @@ "permissions": [ { "amend": 0, - "cancel": 0, + "apply_user_permissions": 1, "create": 0, "email": 1, + "export": 1, "permlevel": 0, "print": 1, "read": 1, @@ -207,9 +211,9 @@ }, { "amend": 0, - "cancel": 0, "create": 0, "email": 1, + "export": 1, "permlevel": 0, "print": 1, "read": 1, @@ -217,17 +221,6 @@ "role": "Accounts Manager", "submit": 0, "write": 0 - }, - { - "create": 0, - "email": 1, - "permlevel": 0, - "print": 1, - "read": 1, - "report": 1, - "role": "System Manager", - "submit": 0, - "write": 0 } ], "search_fields": "voucher_no,account,posting_date,against_voucher", diff --git a/erpnext/accounts/doctype/journal_voucher/journal_voucher.js b/erpnext/accounts/doctype/journal_voucher/journal_voucher.js index bc0108eba0..9174873406 100644 --- a/erpnext/accounts/doctype/journal_voucher/journal_voucher.js +++ b/erpnext/accounts/doctype/journal_voucher/journal_voucher.js @@ -7,6 +7,11 @@ erpnext.accounts.JournalVoucher = frappe.ui.form.Controller.extend({ onload: function() { this.load_defaults(); this.setup_queries(); + this.setup_balance_formatter(); + }, + + onload_post_render: function() { + cur_frm.get_field("entries").grid.set_multiple_add("account"); }, load_defaults: function() { @@ -62,6 +67,18 @@ erpnext.accounts.JournalVoucher = frappe.ui.form.Controller.extend({ }); }, + setup_balance_formatter: function() { + var df = frappe.meta.get_docfield("Journal Voucher Detail", "balance", this.frm.doc.name); + df.formatter = function(value, df, options, doc) { + var currency = frappe.meta.get_field_currency(df, doc); + var dr_or_cr = value ? ('') : ""; + return "
" + + ((value==null || value==="") ? "" : format_currency(Math.abs(value), currency)) + + " " + dr_or_cr + + "
"; + } + }, + against_voucher: function(doc, cdt, cdn) { var d = frappe.get_doc(cdt, cdn); if (d.against_voucher && !flt(d.debit)) { @@ -104,7 +121,6 @@ erpnext.accounts.JournalVoucher = frappe.ui.form.Controller.extend({ } }); } - }); cur_frm.script_manager.make(erpnext.accounts.JournalVoucher); diff --git a/erpnext/accounts/doctype/journal_voucher/journal_voucher.json b/erpnext/accounts/doctype/journal_voucher/journal_voucher.json index c214f988a0..0351fd1da8 100644 --- a/erpnext/accounts/doctype/journal_voucher/journal_voucher.json +++ b/erpnext/accounts/doctype/journal_voucher/journal_voucher.json @@ -123,12 +123,6 @@ "permlevel": 0, "read_only": 1 }, - { - "fieldname": "column_break99", - "fieldtype": "Column Break", - "permlevel": 0, - "read_only": 0 - }, { "fieldname": "difference", "fieldtype": "Currency", @@ -150,10 +144,8 @@ "read_only": 0 }, { - "fieldname": "reference", - "fieldtype": "Section Break", - "label": "Reference", - "options": "icon-pushpin", + "fieldname": "column_break99", + "fieldtype": "Column Break", "permlevel": 0, "read_only": 0 }, @@ -181,6 +173,31 @@ "permlevel": 0, "read_only": 0 }, + { + "fieldname": "user_remark", + "fieldtype": "Small Text", + "in_filter": 1, + "label": "User Remark", + "no_copy": 1, + "oldfieldname": "user_remark", + "oldfieldtype": "Small Text", + "permlevel": 0, + "read_only": 0 + }, + { + "fieldname": "view_details", + "fieldtype": "Fold", + "label": "View Details", + "permlevel": 0 + }, + { + "fieldname": "reference", + "fieldtype": "Section Break", + "label": "Reference", + "options": "icon-pushpin", + "permlevel": 0, + "read_only": 0 + }, { "fieldname": "clearance_date", "fieldtype": "Date", @@ -194,23 +211,6 @@ "read_only": 1, "search_index": 1 }, - { - "fieldname": "column_break98", - "fieldtype": "Column Break", - "permlevel": 0, - "read_only": 0 - }, - { - "fieldname": "user_remark", - "fieldtype": "Small Text", - "in_filter": 1, - "label": "User Remark", - "no_copy": 1, - "oldfieldname": "user_remark", - "oldfieldtype": "Small Text", - "permlevel": 0, - "read_only": 0 - }, { "description": "User Remark will be added to Auto Remark", "fieldname": "remark", @@ -224,6 +224,12 @@ "read_only": 1, "reqd": 0 }, + { + "fieldname": "column_break98", + "fieldtype": "Column Break", + "permlevel": 0, + "read_only": 0 + }, { "fieldname": "bill_no", "fieldtype": "Data", @@ -426,7 +432,7 @@ { "fieldname": "amended_from", "fieldtype": "Link", - "ignore_restrictions": 1, + "ignore_user_permissions": 1, "label": "Amended From", "no_copy": 1, "oldfieldname": "amended_from", @@ -440,7 +446,7 @@ "icon": "icon-file-text", "idx": 1, "is_submittable": 1, - "modified": "2014-05-09 02:16:47.686703", + "modified": "2014-08-14 01:37:14.822939", "modified_by": "Administrator", "module": "Accounts", "name": "Journal Voucher", @@ -448,6 +454,7 @@ "permissions": [ { "amend": 1, + "apply_user_permissions": 1, "cancel": 1, "create": 1, "delete": 1, @@ -476,6 +483,7 @@ }, { "amend": 0, + "apply_user_permissions": 1, "cancel": 0, "create": 0, "delete": 0, diff --git a/erpnext/accounts/doctype/journal_voucher/journal_voucher.py b/erpnext/accounts/doctype/journal_voucher/journal_voucher.py index 70bee90016..03bedc708d 100644 --- a/erpnext/accounts/doctype/journal_voucher/journal_voucher.py +++ b/erpnext/accounts/doctype/journal_voucher/journal_voucher.py @@ -142,12 +142,12 @@ class JournalVoucher(AccountsController): if self.cheque_date: r.append(_('Reference #{0} dated {1}').format(self.cheque_no, formatdate(self.cheque_date))) else: - msgprint(_("Please enter Reference date"), raise_exception=1) + msgprint(_("Please enter Reference date"), raise_exception=frappe.MandatoryError) for d in self.get('entries'): if d.against_invoice and d.credit: currency = frappe.db.get_value("Sales Invoice", d.against_invoice, "currency") - r.append(_("{0} {1} against Invoice {1}").format(currency, fmt_money(flt(d.credit)), d.against_invoice)) + r.append(_("{0} {1} against Invoice {2}").format(currency, fmt_money(flt(d.credit)), d.against_invoice)) if d.against_voucher and d.debit: bill_no = frappe.db.sql("""select bill_no, bill_date, currency @@ -164,7 +164,7 @@ class JournalVoucher(AccountsController): if r: self.remark = ("\n").join(r) else: - frappe.msgprint(_("User Remarks is mandatory"), raise_exception=1) + frappe.msgprint(_("User Remarks is mandatory"), raise_exception=frappe.MandatoryError) def set_aging_date(self): if self.is_opening != 'Yes': @@ -186,9 +186,14 @@ class JournalVoucher(AccountsController): def set_print_format_fields(self): for d in self.get('entries'): - account_type, master_type = frappe.db.get_value("Account", d.account, + result = frappe.db.get_value("Account", d.account, ["account_type", "master_type"]) + if not result: + continue + + account_type, master_type = result + if master_type in ['Supplier', 'Customer']: if not self.pay_to_recd_from: self.pay_to_recd_from = frappe.db.get_value(master_type, @@ -198,7 +203,7 @@ class JournalVoucher(AccountsController): if account_type in ['Bank', 'Cash']: company_currency = get_company_currency(self.company) amt = flt(d.debit) and d.debit or d.credit - self.total_amount = company_currency + ' ' + cstr(amt) + self.total_amount = fmt_money(amt, currency=company_currency) from frappe.utils import money_in_words self.total_amount_in_words = money_in_words(amt, company_currency) @@ -410,7 +415,7 @@ def get_opening_accounts(company): """get all balance sheet accounts for opening entry""" from erpnext.accounts.utils import get_balance_on accounts = frappe.db.sql_list("""select name from tabAccount - where group_or_ledger='Ledger' and report_type='Profit and Loss' and company=%s""", company) + where group_or_ledger='Ledger' and report_type='Balance Sheet' and company=%s""", company) return [{"account": a, "balance": get_balance_on(a)} for a in accounts] diff --git a/erpnext/accounts/doctype/journal_voucher/journal_voucher_list.html b/erpnext/accounts/doctype/journal_voucher/journal_voucher_list.html new file mode 100644 index 0000000000..aaa3854fef --- /dev/null +++ b/erpnext/accounts/doctype/journal_voucher/journal_voucher_list.html @@ -0,0 +1,20 @@ +
+
+
+ {%= list.get_avatar_and_id(doc) %} + + {%= doc.get_formatted("posting_date") %} + + {%= doc.voucher_type %} + + {% if(doc.docstatus===0) { %} + {%= __("Draft") %} + {% } %} +
+
+
+ {%= doc.get_formatted("total_debit") %} +
+
diff --git a/erpnext/accounts/doctype/journal_voucher/journal_voucher_list.js b/erpnext/accounts/doctype/journal_voucher/journal_voucher_list.js new file mode 100644 index 0000000000..06d578abaa --- /dev/null +++ b/erpnext/accounts/doctype/journal_voucher/journal_voucher_list.js @@ -0,0 +1,3 @@ +frappe.listview_settings['Journal Voucher'] = { + add_fields: ["voucher_type", "posting_date", "total_debit", "company"] +}; diff --git a/erpnext/accounts/doctype/journal_voucher_detail/journal_voucher_detail.json b/erpnext/accounts/doctype/journal_voucher_detail/journal_voucher_detail.json index defd88e6db..a751ed9c66 100644 --- a/erpnext/accounts/doctype/journal_voucher_detail/journal_voucher_detail.json +++ b/erpnext/accounts/doctype/journal_voucher_detail/journal_voucher_detail.json @@ -1,6 +1,6 @@ { "autoname": "JVD.######", - "creation": "2013-02-22 01:27:39.000000", + "creation": "2013-02-22 01:27:39", "docstatus": 0, "doctype": "DocType", "fields": [ @@ -31,6 +31,7 @@ "oldfieldtype": "Link", "options": "Cost Center", "permlevel": 0, + "print_hide": 1, "print_width": "180px", "search_index": 0, "width": "180px" @@ -50,6 +51,7 @@ "oldfieldtype": "Data", "options": "Company:company:default_currency", "permlevel": 0, + "print_hide": 1, "read_only": 1 }, { @@ -158,9 +160,10 @@ ], "idx": 1, "istable": 1, - "modified": "2014-02-03 12:44:31.000000", + "modified": "2014-07-25 03:16:51.149899", "modified_by": "Administrator", "module": "Accounts", "name": "Journal Voucher Detail", - "owner": "Administrator" + "owner": "Administrator", + "permissions": [] } \ No newline at end of file diff --git a/erpnext/accounts/doctype/mode_of_payment/mode_of_payment.json b/erpnext/accounts/doctype/mode_of_payment/mode_of_payment.json index ef508829f5..2ad9897b05 100644 --- a/erpnext/accounts/doctype/mode_of_payment/mode_of_payment.json +++ b/erpnext/accounts/doctype/mode_of_payment/mode_of_payment.json @@ -31,7 +31,7 @@ "description": "Default Bank / Cash account will be automatically updated in POS Invoice when this mode is selected.", "fieldname": "default_account", "fieldtype": "Link", - "ignore_restrictions": 1, + "ignore_user_permissions": 1, "in_list_view": 1, "label": "Default Account", "options": "Account", @@ -41,7 +41,7 @@ ], "icon": "icon-credit-card", "idx": 1, - "modified": "2014-05-07 05:06:13.702313", + "modified": "2014-05-27 03:49:13.846602", "modified_by": "Administrator", "module": "Accounts", "name": "Mode of Payment", @@ -59,6 +59,7 @@ "write": 1 }, { + "apply_user_permissions": 1, "permlevel": 0, "read": 1, "report": 1, diff --git a/erpnext/accounts/print_format/sales_invoice/__init__.py b/erpnext/accounts/doctype/payment_reconciliation/__init__.py similarity index 100% rename from erpnext/accounts/print_format/sales_invoice/__init__.py rename to erpnext/accounts/doctype/payment_reconciliation/__init__.py diff --git a/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.js b/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.js new file mode 100644 index 0000000000..c495a35825 --- /dev/null +++ b/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.js @@ -0,0 +1,82 @@ +// Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors +// For license information, please see license.txt + +frappe.provide("erpnext.accounts"); + +erpnext.accounts.PaymentReconciliationController = frappe.ui.form.Controller.extend({ + + onload: function() { + var me = this + this.frm.set_query('party_account', function() { + if(!me.frm.doc.company) { + msgprint(__("Please select company first")); + } else { + return{ + filters:[ + ['Account', 'company', '=', me.frm.doc.company], + ['Account', 'group_or_ledger', '=', 'Ledger'], + ['Account', 'master_type', 'in', ['Customer', 'Supplier']] + ] + }; + } + + }); + + this.frm.set_query('bank_cash_account', function() { + if(!me.frm.doc.company) { + msgprint(__("Please select company first")); + } else { + return{ + filters:[ + ['Account', 'company', '=', me.frm.doc.company], + ['Account', 'group_or_ledger', '=', 'Ledger'], + ['Account', 'account_type', 'in', ['Bank', 'Cash']] + ] + }; + } + }); + + var help_content = ' Note:
'+ + ''; + this.frm.set_value("reconcile_help", help_content); + }, + + get_unreconciled_entries: function() { + var me = this; + return this.frm.call({ + doc: me.frm.doc, + method: 'get_unreconciled_entries', + callback: function(r, rt) { + var invoices = []; + + $.each(me.frm.doc.payment_reconciliation_invoices || [], function(i, row) { + if (row.invoice_number && !inList(invoices, row.invoice_number)) + invoices.push(row.invoice_number); + }); + + frappe.meta.get_docfield("Payment Reconciliation Payment", "invoice_number", + me.frm.doc.name).options = invoices.join("\n"); + + $.each(me.frm.doc.payment_reconciliation_payments || [], function(i, p) { + if(!inList(invoices, cstr(p.invoice_number))) p.invoice_number = null; + }); + + refresh_field("payment_reconciliation_payments"); + } + }); + + }, + + reconcile: function() { + var me = this; + return this.frm.call({ + doc: me.frm.doc, + method: 'reconcile' + }); + } + +}); + +$.extend(cur_frm.cscript, new erpnext.accounts.PaymentReconciliationController({frm: cur_frm})); + +cur_frm.add_fetch('party_account', 'master_type', 'party_type') \ No newline at end of file diff --git a/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.json b/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.json new file mode 100644 index 0000000000..51cb306157 --- /dev/null +++ b/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.json @@ -0,0 +1,163 @@ +{ + "allow_copy": 1, + "creation": "2014-07-09 12:04:51.681583", + "custom": 0, + "docstatus": 0, + "doctype": "DocType", + "document_type": "", + "fields": [ + { + "fieldname": "company", + "fieldtype": "Link", + "label": "Company", + "options": "Company", + "permlevel": 0, + "reqd": 1 + }, + { + "depends_on": "", + "fieldname": "party_account", + "fieldtype": "Link", + "in_list_view": 0, + "label": "Party Account", + "options": "Account", + "permlevel": 0, + "reqd": 1, + "search_index": 0 + }, + { + "fieldname": "party_type", + "fieldtype": "Select", + "hidden": 1, + "in_list_view": 1, + "label": "Party Type", + "options": "\nCustomer\nSupplier", + "permlevel": 0, + "read_only": 1, + "reqd": 0 + }, + { + "fieldname": "bank_cash_account", + "fieldtype": "Link", + "in_list_view": 1, + "label": "Bank / Cash Account", + "options": "Account", + "permlevel": 0, + "reqd": 0, + "search_index": 0 + }, + { + "fieldname": "col_break1", + "fieldtype": "Column Break", + "label": "Column Break", + "permlevel": 0 + }, + { + "fieldname": "from_date", + "fieldtype": "Date", + "in_list_view": 1, + "label": "From Date", + "permlevel": 0, + "search_index": 1 + }, + { + "fieldname": "to_date", + "fieldtype": "Date", + "in_list_view": 1, + "label": "To Date", + "permlevel": 0, + "search_index": 1 + }, + { + "fieldname": "minimum_amount", + "fieldtype": "Currency", + "label": "Minimum Amount", + "permlevel": 0 + }, + { + "fieldname": "maximum_amount", + "fieldtype": "Currency", + "label": "Maximum Amount", + "permlevel": 0 + }, + { + "fieldname": "get_unreconciled_entries", + "fieldtype": "Button", + "label": "Get Unreconciled Entries", + "permlevel": 0 + }, + { + "fieldname": "sec_break1", + "fieldtype": "Section Break", + "label": "Unreconciled Payment Details", + "permlevel": 0 + }, + { + "fieldname": "payment_reconciliation_payments", + "fieldtype": "Table", + "label": "Payment Reconciliation Payments", + "options": "Payment Reconciliation Payment", + "permlevel": 0 + }, + { + "fieldname": "reconcile", + "fieldtype": "Button", + "label": "Reconcile", + "permlevel": 0 + }, + { + "fieldname": "sec_break2", + "fieldtype": "Section Break", + "label": "Invoice/Journal Voucher Details", + "permlevel": 0 + }, + { + "fieldname": "payment_reconciliation_invoices", + "fieldtype": "Table", + "label": "Payment Reconciliation Invoices", + "options": "Payment Reconciliation Invoice", + "permlevel": 0, + "read_only": 1 + }, + { + "fieldname": "reconcile_help", + "fieldtype": "Small Text", + "label": "", + "permlevel": 0, + "read_only": 1 + } + ], + "hide_toolbar": 1, + "icon": "icon-resize-horizontal", + "issingle": 1, + "modified": "2014-07-31 05:43:03.410832", + "modified_by": "Administrator", + "module": "Accounts", + "name": "Payment Reconciliation", + "name_case": "", + "owner": "Administrator", + "permissions": [ + { + "cancel": 0, + "create": 1, + "delete": 1, + "permlevel": 0, + "read": 1, + "role": "Accounts Manager", + "submit": 0, + "write": 1 + }, + { + "cancel": 0, + "create": 1, + "delete": 1, + "permlevel": 0, + "read": 1, + "role": "Accounts User", + "submit": 0, + "write": 1 + } + ], + "sort_field": "modified", + "sort_order": "DESC" +} \ No newline at end of file diff --git a/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.py b/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.py new file mode 100644 index 0000000000..a5a56aee0a --- /dev/null +++ b/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.py @@ -0,0 +1,187 @@ +# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors +# For license information, please see license.txt + +from __future__ import unicode_literals +import frappe + +from frappe.utils import flt + +from frappe import msgprint, _ + +from frappe.model.document import Document + +class PaymentReconciliation(Document): + def get_unreconciled_entries(self): + self.get_jv_entries() + self.get_invoice_entries() + + def get_jv_entries(self): + self.check_mandatory_to_fetch() + dr_or_cr = "credit" if self.party_type == "Customer" else "debit" + + cond = self.check_condition(dr_or_cr) + + bank_account_condition = "t2.against_account like %(bank_cash_account)s" \ + if self.bank_cash_account else "1=1" + + jv_entries = frappe.db.sql(""" + select + t1.name as voucher_no, t1.posting_date, t1.remark, t2.account, + t2.name as voucher_detail_no, {dr_or_cr} as payment_amount, t2.is_advance + from + `tabJournal Voucher` t1, `tabJournal Voucher Detail` t2 + where + t1.name = t2.parent and t1.docstatus = 1 and t2.docstatus = 1 + and t2.account = %(party_account)s and {dr_or_cr} > 0 + and ifnull(t2.against_voucher, '')='' and ifnull(t2.against_invoice, '')='' + and ifnull(t2.against_jv, '')='' {cond} + and (CASE + WHEN t1.voucher_type in ('Debit Note', 'Credit Note') + THEN 1=1 + ELSE {bank_account_condition} + END) + """.format(**{ + "dr_or_cr": dr_or_cr, + "cond": cond, + "bank_account_condition": bank_account_condition, + }), { + "party_account": self.party_account, + "bank_cash_account": "%%%s%%" % self.bank_cash_account + }, as_dict=1) + + self.add_payment_entries(jv_entries) + + def add_payment_entries(self, jv_entries): + self.set('payment_reconciliation_payments', []) + for e in jv_entries: + ent = self.append('payment_reconciliation_payments', {}) + ent.journal_voucher = e.get('voucher_no') + ent.posting_date = e.get('posting_date') + ent.amount = flt(e.get('payment_amount')) + ent.remark = e.get('remark') + ent.voucher_detail_number = e.get('voucher_detail_no') + ent.is_advance = e.get('is_advance') + + def get_invoice_entries(self): + #Fetch JVs, Sales and Purchase Invoices for 'payment_reconciliation_invoices' to reconcile against + non_reconciled_invoices = [] + dr_or_cr = "debit" if self.party_type == "Customer" else "credit" + cond = self.check_condition(dr_or_cr) + + invoice_list = frappe.db.sql(""" + select + voucher_no, voucher_type, posting_date, + ifnull(sum({dr_or_cr}), 0) as invoice_amount + from + `tabGL Entry` + where + account = %s and {dr_or_cr} > 0 {cond} + group by voucher_type, voucher_no + """.format(**{ + "cond": cond, + "dr_or_cr": dr_or_cr + }), (self.party_account), as_dict=True) + + for d in invoice_list: + payment_amount = frappe.db.sql(""" + select + ifnull(sum(ifnull({0}, 0)), 0) + from + `tabGL Entry` + where + account = %s and {0} > 0 + and against_voucher_type = %s and ifnull(against_voucher, '') = %s + """.format("credit" if self.party_type == "Customer" else "debit"), + (self.party_account, d.voucher_type, d.voucher_no)) + + payment_amount = payment_amount[0][0] if payment_amount else 0 + + if d.invoice_amount > payment_amount: + non_reconciled_invoices.append({ + 'voucher_no': d.voucher_no, + 'voucher_type': d.voucher_type, + 'posting_date': d.posting_date, + 'invoice_amount': flt(d.invoice_amount), + 'outstanding_amount': d.invoice_amount - payment_amount}) + + self.add_invoice_entries(non_reconciled_invoices) + + def add_invoice_entries(self, non_reconciled_invoices): + #Populate 'payment_reconciliation_invoices' with JVs and Invoices to reconcile against + self.set('payment_reconciliation_invoices', []) + + for e in non_reconciled_invoices: + ent = self.append('payment_reconciliation_invoices', {}) + ent.invoice_type = e.get('voucher_type') + ent.invoice_number = e.get('voucher_no') + ent.invoice_date = e.get('posting_date') + ent.amount = flt(e.get('invoice_amount')) + ent.outstanding_amount = e.get('outstanding_amount') + + def reconcile(self, args): + self.get_invoice_entries() + self.validate_invoice() + dr_or_cr = "credit" if self.party_type == "Customer" else "debit" + lst = [] + for e in self.get('payment_reconciliation_payments'): + if e.invoice_type and e.invoice_number: + lst.append({ + 'voucher_no' : e.journal_voucher, + 'voucher_detail_no' : e.voucher_detail_number, + 'against_voucher_type' : e.invoice_type, + 'against_voucher' : e.invoice_number, + 'account' : self.party_account, + 'is_advance' : e.is_advance, + 'dr_or_cr' : dr_or_cr, + 'unadjusted_amt' : flt(e.amount), + 'allocated_amt' : flt(e.amount) + }) + + if lst: + from erpnext.accounts.utils import reconcile_against_document + reconcile_against_document(lst) + msgprint(_("Successfully Reconciled")) + self.get_unreconciled_entries() + + def check_mandatory_to_fetch(self): + for fieldname in ["company", "party_account"]: + if not self.get(fieldname): + frappe.throw(_("Please select {0} first").format(self.meta.get_label(fieldname))) + + + def validate_invoice(self): + if not self.get("payment_reconciliation_invoices"): + frappe.throw(_("No records found in the Invoice table")) + + if not self.get("payment_reconciliation_payments"): + frappe.throw(_("No records found in the Payment table")) + + unreconciled_invoices = frappe._dict() + for d in self.get("payment_reconciliation_invoices"): + unreconciled_invoices.setdefault(d.invoice_type, {}).setdefault(d.invoice_number, d.outstanding_amount) + + invoices_to_reconcile = [] + for p in self.get("payment_reconciliation_payments"): + if p.invoice_type and p.invoice_number: + invoices_to_reconcile.append(p.invoice_number) + + if p.invoice_number not in unreconciled_invoices.get(p.invoice_type, {}): + frappe.throw(_("{0}: {1} not found in Invoice Details table") + .format(p.invoice_type, p.invoice_number)) + + if p.amount > unreconciled_invoices.get(p.invoice_type, {}).get(p.invoice_number): + frappe.throw(_("Row {0}: Payment amount must be less than or equals to invoice outstanding amount. Please refer Note below.").format(p.idx)) + + if not invoices_to_reconcile: + frappe.throw(_("Please select Invoice Type and Invoice Number in atleast one row")) + + def check_condition(self, dr_or_cr): + cond = self.from_date and " and posting_date >= '" + self.from_date + "'" or "" + cond += self.to_date and " and posting_date <= '" + self.to_date + "'" or "" + + if self.minimum_amount: + cond += " and {0} >= %s".format(dr_or_cr) % self.minimum_amount + if self.maximum_amount: + cond += " and {0} <= %s".format(dr_or_cr) % self.maximum_amount + + return cond diff --git a/erpnext/stock/doctype/warehouse_user/__init__.py b/erpnext/accounts/doctype/payment_reconciliation_invoice/__init__.py similarity index 100% rename from erpnext/stock/doctype/warehouse_user/__init__.py rename to erpnext/accounts/doctype/payment_reconciliation_invoice/__init__.py diff --git a/erpnext/accounts/doctype/payment_reconciliation_invoice/payment_reconciliation_invoice.json b/erpnext/accounts/doctype/payment_reconciliation_invoice/payment_reconciliation_invoice.json new file mode 100644 index 0000000000..4e4ee1ae95 --- /dev/null +++ b/erpnext/accounts/doctype/payment_reconciliation_invoice/payment_reconciliation_invoice.json @@ -0,0 +1,66 @@ +{ + "creation": "2014-07-09 16:14:23.672922", + "docstatus": 0, + "doctype": "DocType", + "document_type": "", + "fields": [ + { + "fieldname": "invoice_type", + "fieldtype": "Data", + "in_list_view": 1, + "label": "Invoice Type", + "options": "Sales Invoice\nPurchase Invoice\nJournal Voucher", + "permlevel": 0, + "read_only": 1 + }, + { + "fieldname": "invoice_number", + "fieldtype": "Data", + "in_list_view": 1, + "label": "Invoice Number", + "options": "", + "permlevel": 0, + "read_only": 1 + }, + { + "fieldname": "invoice_date", + "fieldtype": "Date", + "in_list_view": 1, + "label": "Invoice Date", + "permlevel": 0, + "read_only": 1 + }, + { + "fieldname": "col_break1", + "fieldtype": "Column Break", + "label": "Column Break", + "permlevel": 0 + }, + { + "fieldname": "amount", + "fieldtype": "Currency", + "in_list_view": 1, + "label": "Amount", + "permlevel": 0, + "read_only": 1 + }, + { + "fieldname": "outstanding_amount", + "fieldtype": "Currency", + "in_list_view": 1, + "label": "Outstanding Amount", + "permlevel": 0, + "read_only": 1 + } + ], + "istable": 1, + "modified": "2014-07-18 12:20:51.269974", + "modified_by": "Administrator", + "module": "Accounts", + "name": "Payment Reconciliation Invoice", + "name_case": "", + "owner": "Administrator", + "permissions": [], + "sort_field": "modified", + "sort_order": "DESC" +} \ No newline at end of file diff --git a/erpnext/accounts/doctype/payment_to_invoice_matching_tool_detail/payment_to_invoice_matching_tool_detail.py b/erpnext/accounts/doctype/payment_reconciliation_invoice/payment_reconciliation_invoice.py similarity index 56% rename from erpnext/accounts/doctype/payment_to_invoice_matching_tool_detail/payment_to_invoice_matching_tool_detail.py rename to erpnext/accounts/doctype/payment_reconciliation_invoice/payment_reconciliation_invoice.py index a7bf686170..3094a173f0 100644 --- a/erpnext/accounts/doctype/payment_to_invoice_matching_tool_detail/payment_to_invoice_matching_tool_detail.py +++ b/erpnext/accounts/doctype/payment_reconciliation_invoice/payment_reconciliation_invoice.py @@ -1,10 +1,9 @@ -# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors -# License: GNU General Public License v3. See license.txt +# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors and contributors +# For license information, please see license.txt from __future__ import unicode_literals import frappe - from frappe.model.document import Document -class PaymentToInvoiceMatchingToolDetail(Document): - pass \ No newline at end of file +class PaymentReconciliationInvoice(Document): + pass diff --git a/erpnext/stock/report/purchase_in_transit/__init__.py b/erpnext/accounts/doctype/payment_reconciliation_payment/__init__.py similarity index 100% rename from erpnext/stock/report/purchase_in_transit/__init__.py rename to erpnext/accounts/doctype/payment_reconciliation_payment/__init__.py diff --git a/erpnext/accounts/doctype/payment_reconciliation_payment/payment_reconciliation_payment.json b/erpnext/accounts/doctype/payment_reconciliation_payment/payment_reconciliation_payment.json new file mode 100644 index 0000000000..73fd0f50f3 --- /dev/null +++ b/erpnext/accounts/doctype/payment_reconciliation_payment/payment_reconciliation_payment.json @@ -0,0 +1,107 @@ +{ + "creation": "2014-07-09 16:13:35.452759", + "docstatus": 0, + "doctype": "DocType", + "document_type": "", + "fields": [ + { + "fieldname": "journal_voucher", + "fieldtype": "Link", + "in_list_view": 1, + "label": "Journal Voucher", + "options": "Journal Voucher", + "permlevel": 0, + "read_only": 1, + "reqd": 0 + }, + { + "fieldname": "posting_date", + "fieldtype": "Date", + "in_list_view": 1, + "label": "Posting Date", + "permlevel": 0, + "read_only": 1 + }, + { + "fieldname": "amount", + "fieldtype": "Currency", + "in_list_view": 1, + "label": "Amount", + "permlevel": 0, + "read_only": 1 + }, + { + "fieldname": "is_advance", + "fieldtype": "Data", + "hidden": 1, + "label": "Is Advance", + "permlevel": 0, + "read_only": 1 + }, + { + "fieldname": "voucher_detail_number", + "fieldtype": "Data", + "hidden": 1, + "in_list_view": 0, + "label": "Voucher Detail Number", + "permlevel": 0, + "read_only": 1 + }, + { + "fieldname": "col_break1", + "fieldtype": "Column Break", + "label": "Column Break", + "permlevel": 0 + }, + { + "default": "Sales Invoice", + "fieldname": "invoice_type", + "fieldtype": "Select", + "in_list_view": 1, + "label": "Invoice Type", + "options": "\nSales Invoice\nPurchase Invoice\nJournal Voucher", + "permlevel": 0, + "read_only": 0, + "reqd": 1 + }, + { + "fieldname": "invoice_number", + "fieldtype": "Select", + "in_list_view": 1, + "label": "Invoice Number", + "options": "", + "permlevel": 0, + "reqd": 1 + }, + { + "fieldname": "sec_break1", + "fieldtype": "Section Break", + "label": "", + "permlevel": 0 + }, + { + "fieldname": "remark", + "fieldtype": "Small Text", + "in_list_view": 1, + "label": "Remark", + "permlevel": 0, + "read_only": 1 + }, + { + "fieldname": "col_break2", + "fieldtype": "Column Break", + "label": "Column Break", + "permlevel": 0 + } + ], + "istable": 1, + "modified": "2014-07-21 16:53:56.206169", + "modified_by": "Administrator", + "module": "Accounts", + "name": "Payment Reconciliation Payment", + "name_case": "", + "owner": "Administrator", + "permissions": [], + "sort_field": "modified", + "sort_order": "DESC" +} \ No newline at end of file diff --git a/erpnext/accounts/doctype/payment_reconciliation_payment/payment_reconciliation_payment.py b/erpnext/accounts/doctype/payment_reconciliation_payment/payment_reconciliation_payment.py new file mode 100644 index 0000000000..21e19bdd71 --- /dev/null +++ b/erpnext/accounts/doctype/payment_reconciliation_payment/payment_reconciliation_payment.py @@ -0,0 +1,9 @@ +# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors and contributors +# For license information, please see license.txt + +from __future__ import unicode_literals +import frappe +from frappe.model.document import Document + +class PaymentReconciliationPayment(Document): + pass diff --git a/erpnext/accounts/doctype/payment_to_invoice_matching_tool/README.md b/erpnext/accounts/doctype/payment_to_invoice_matching_tool/README.md deleted file mode 100644 index bcde4b3133..0000000000 --- a/erpnext/accounts/doctype/payment_to_invoice_matching_tool/README.md +++ /dev/null @@ -1 +0,0 @@ -Tool for mapping (cancelling) unpaid invoices and payments. \ No newline at end of file diff --git a/erpnext/accounts/doctype/payment_to_invoice_matching_tool/__init__.py b/erpnext/accounts/doctype/payment_to_invoice_matching_tool/__init__.py deleted file mode 100644 index baffc48825..0000000000 --- a/erpnext/accounts/doctype/payment_to_invoice_matching_tool/__init__.py +++ /dev/null @@ -1 +0,0 @@ -from __future__ import unicode_literals diff --git a/erpnext/accounts/doctype/payment_to_invoice_matching_tool/payment_to_invoice_matching_tool.js b/erpnext/accounts/doctype/payment_to_invoice_matching_tool/payment_to_invoice_matching_tool.js deleted file mode 100644 index 4c5a3822c0..0000000000 --- a/erpnext/accounts/doctype/payment_to_invoice_matching_tool/payment_to_invoice_matching_tool.js +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors -// License: GNU General Public License v3. See license.txt - -cur_frm.cscript.onload_post_render = function(doc) { - $(cur_frm.get_field("reconcile").input).addClass("btn-info"); -} - -cur_frm.fields_dict.voucher_no.get_query = function(doc) { - // TO-do: check for pos, it should not come - if (!doc.account) msgprint(__("Please select Account first")); - else { - return { - doctype: doc.voucher_type, - query: "erpnext.accounts.doctype.payment_to_invoice_matching_tool.payment_to_invoice_matching_tool.get_voucher_nos", - filters: { - "voucher_type": doc.voucher_type, - "account": doc.account - } - } - } -} - -cur_frm.cscript.voucher_no = function() { - return cur_frm.call({ - doc: cur_frm.doc, - method: "get_voucher_details" - }); -} - -cur_frm.cscript.get_against_entries = function() { - return cur_frm.call({ - doc: cur_frm.doc, - method: "get_against_entries" - }); -} - -cur_frm.cscript.reconcile = function() { - return cur_frm.call({ - doc: cur_frm.doc, - method: "reconcile" - }); -} - -cur_frm.cscript.allocated_amount = function(doc, cdt, cdn) { - var total_allocated_amount = 0 - $.each(cur_frm.doc.against_entries, function(i, d) { - if(d.allocated_amount > 0) total_allocated_amount += flt(d.allocated_amount); - else if (d.allocated_amount < 0) frappe.throw(__("Allocated amount can not be negative")); - }) - cur_frm.set_value("total_allocated_amount", total_allocated_amount); -} diff --git a/erpnext/accounts/doctype/payment_to_invoice_matching_tool/payment_to_invoice_matching_tool.json b/erpnext/accounts/doctype/payment_to_invoice_matching_tool/payment_to_invoice_matching_tool.json deleted file mode 100644 index 8d12f08f72..0000000000 --- a/erpnext/accounts/doctype/payment_to_invoice_matching_tool/payment_to_invoice_matching_tool.json +++ /dev/null @@ -1,187 +0,0 @@ -{ - "creation": "2013-01-30 12:49:46", - "docstatus": 0, - "doctype": "DocType", - "document_type": "Other", - "fields": [ - { - "fieldname": "account", - "fieldtype": "Link", - "in_list_view": 0, - "label": "Account", - "options": "Account", - "permlevel": 0, - "reqd": 1 - }, - { - "default": "Journal Voucher", - "fieldname": "voucher_type", - "fieldtype": "Select", - "in_list_view": 0, - "label": "Voucher Type", - "options": "Sales Invoice\nPurchase Invoice\nJournal Voucher", - "permlevel": 0, - "reqd": 1 - }, - { - "fieldname": "voucher_no", - "fieldtype": "Link", - "in_list_view": 1, - "label": "Voucher No", - "options": "[Select]", - "permlevel": 0, - "reqd": 1 - }, - { - "fieldname": "column_break1", - "fieldtype": "Column Break", - "in_list_view": 0, - "permlevel": 0, - "print_width": "50%", - "width": "50%" - }, - { - "fieldname": "total_amount", - "fieldtype": "Currency", - "in_list_view": 1, - "label": "Total Amount", - "options": "", - "permlevel": 0, - "read_only": 1 - }, - { - "fieldname": "unmatched_amount", - "fieldtype": "Currency", - "label": "Unmatched Amount", - "options": "", - "permlevel": 0, - "read_only": 1 - }, - { - "fieldname": "against_entries_section", - "fieldtype": "Section Break", - "label": "Against Entries", - "permlevel": 0 - }, - { - "fieldname": "from_date", - "fieldtype": "Date", - "label": "From Date", - "permlevel": 0 - }, - { - "fieldname": "to_date", - "fieldtype": "Date", - "label": "To Date", - "permlevel": 0 - }, - { - "fieldname": "column_break3", - "fieldtype": "Column Break", - "label": "", - "permlevel": 0, - "print_width": "50%", - "width": "50%" - }, - { - "fieldname": "amt_greater_than", - "fieldtype": "Currency", - "label": "Amount >=", - "permlevel": 0 - }, - { - "fieldname": "amt_less_than", - "fieldtype": "Currency", - "label": "Amount <=", - "permlevel": 0 - }, - { - "fieldname": "section_break0", - "fieldtype": "Section Break", - "options": "Simple", - "permlevel": 0 - }, - { - "fieldname": "get_against_entries", - "fieldtype": "Button", - "label": "Get Against Entries", - "options": "", - "permlevel": 0 - }, - { - "description": "Update allocated amount in the above table and then click \"Allocate\" button", - "fieldname": "against_entries", - "fieldtype": "Table", - "label": "Against Entries", - "options": "Payment to Invoice Matching Tool Detail", - "permlevel": 0 - }, - { - "fieldname": "sec_break1", - "fieldtype": "Section Break", - "options": "Simple", - "permlevel": 0 - }, - { - "fieldname": "total_allocated_amount", - "fieldtype": "Currency", - "label": "Total Allocated Amount", - "permlevel": 0, - "read_only": 1 - }, - { - "fieldname": "col_breal4", - "fieldtype": "Column Break", - "permlevel": 0 - }, - { - "default": "", - "fieldname": "allocate_amount_automatically", - "fieldtype": "Button", - "hidden": 1, - "label": "Allocate Amount Automatically", - "permlevel": 0, - "reqd": 0 - }, - { - "fieldname": "reconcile", - "fieldtype": "Button", - "label": "Reconcile", - "options": "", - "permlevel": 0 - } - ], - "hide_toolbar": 0, - "icon": "icon-magic", - "idx": 1, - "issingle": 1, - "modified": "2014-04-30 17:11:05.908619", - "modified_by": "Administrator", - "module": "Accounts", - "name": "Payment to Invoice Matching Tool", - "owner": "Administrator", - "permissions": [ - { - "create": 1, - "email": 1, - "permlevel": 0, - "print": 1, - "read": 1, - "report": 0, - "role": "Accounts Manager", - "submit": 0, - "write": 1 - }, - { - "create": 1, - "email": 1, - "permlevel": 0, - "print": 1, - "read": 1, - "report": 0, - "role": "Accounts User", - "submit": 0, - "write": 1 - } - ] -} \ No newline at end of file diff --git a/erpnext/accounts/doctype/payment_to_invoice_matching_tool/payment_to_invoice_matching_tool.py b/erpnext/accounts/doctype/payment_to_invoice_matching_tool/payment_to_invoice_matching_tool.py deleted file mode 100644 index 300d25efee..0000000000 --- a/erpnext/accounts/doctype/payment_to_invoice_matching_tool/payment_to_invoice_matching_tool.py +++ /dev/null @@ -1,173 +0,0 @@ -# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors -# License: GNU General Public License v3. See license.txt - -from __future__ import unicode_literals -import frappe - -from frappe.utils import flt - -from frappe import msgprint, _ - -from frappe.model.document import Document - -class PaymenttoInvoiceMatchingTool(Document): - def get_voucher_details(self): - total_amount = frappe.db.sql("""select sum(ifnull(debit, 0)) - sum(ifnull(credit, 0)) - from `tabGL Entry` - where voucher_type = %s and voucher_no = %s - and account = %s and ifnull(against_voucher, '') != voucher_no""", - (self.voucher_type, self.voucher_no, self.account)) - - self.total_amount = total_amount and flt(total_amount[0][0]) or 0 - - reconciled_payment = frappe.db.sql(""" - select abs(sum(ifnull(debit, 0)) - sum(ifnull(credit, 0))) - from `tabGL Entry` - where against_voucher_type = %s and against_voucher = %s and account = %s - """, (self.voucher_type, self.voucher_no, self.account)) - - reconciled_payment = reconciled_payment and flt(reconciled_payment[0][0]) or 0 - self.unmatched_amount = self.total_amount - reconciled_payment - - def get_against_entries(self): - self.set('against_entries', []) - gle = self.get_gl_entries() - self.create_against_entries_table(gle) - - def get_gl_entries(self): - self.validate_mandatory() - - dr_or_cr = "credit" if self.total_amount > 0 else "debit" - - cond = self.from_date and " and t1.posting_date >= '" + self.from_date + "'" or "" - cond += self.to_date and " and t1.posting_date <= '" + self.to_date + "'" or "" - - if self.amt_greater_than: - cond += ' and abs(ifnull(t2.debit, 0) - ifnull(t2.credit, 0)) >= ' + self.amt_greater_than - if self.amt_less_than: - cond += ' and abs(ifnull(t2.debit, 0) - ifnull(t2.credit, 0)) >= ' + self.amt_less_than - - gle = frappe.db.sql(""" - select - t1.name as voucher_no, t1.posting_date, t1.total_debit as total_amt, - abs(ifnull(t2.debit, 0) - ifnull(t2.credit, 0)) as unmatched_amount, t1.remark, - t2.against_account, t2.name as voucher_detail_no, t2.is_advance - from - `tabJournal Voucher` t1, `tabJournal Voucher Detail` t2 - where - t1.name = t2.parent and t1.docstatus = 1 and t2.account = %s - and ifnull(t2.against_voucher, '')='' and ifnull(t2.against_invoice, '')='' - and ifnull(t2.against_jv, '')='' and t2.%s > 0 and t1.name != %s - and not exists (select * from `tabJournal Voucher Detail` - where parent=%s and against_jv = t1.name) %s - group by t1.name, t2.name """ % ('%s', dr_or_cr, '%s', '%s', cond), - (self.account, self.voucher_no, self.voucher_no), as_dict=1) - - return gle - - def create_against_entries_table(self, gle): - adjusted_jv = {} - for d in gle: - if not adjusted_jv.has_key(d.get("voucher_no")): - matched_amount = frappe.db.sql(""" - select - ifnull(abs(sum(ifnull(debit, 0)) - sum(ifnull(credit, 0))), 0) - from - `tabGL Entry` - where - account = %s and against_voucher_type = "Journal Voucher" - and ifnull(against_voucher, '') = %s - """, (self.account, d.get('voucher_no'))) - matched_amount = matched_amount[0][0] if matched_amount else 0 - else: - matched_amount = adjusted_jv.get(d.get("voucher_no")) - - if matched_amount < flt(d.get('unmatched_amount')): - unmatched_amount = flt(d.get('unmatched_amount')) - matched_amount - adjusted_jv.setdefault(d.get("voucher_no"), 0) - else: - unmatched_amount = 0 - adjusted_jv.setdefault(d.get("voucher_no"), matched_amount - flt(d.get('unmatched_amount'))) - - if unmatched_amount: - ch = self.append('against_entries', {}) - ch.voucher_no = d.get('voucher_no') - ch.posting_date = d.get('posting_date') - ch.unmatched_amount = unmatched_amount - ch.total_amt = flt(d.get('total_amt')) - ch.against_account = d.get('against_account') - ch.remarks = d.get('remark') - ch.voucher_detail_no = d.get('voucher_detail_no') - ch.is_advance = d.get("is_advance") - ch.original_amount = flt(d.get('unmatched_amount')) - - def validate_mandatory(self): - for fieldname in ["account", "voucher_type", "voucher_no"]: - if not self.get(fieldname): - frappe.throw(_("Please select {0} first").format(self.meta.get_label("fieldname"))) - - if not frappe.db.exists(self.voucher_type, self.voucher_no): - frappe.throw(_("Voucher No is not valid")) - - def reconcile(self): - self.validate_mandatory() - self.validate_allocated_amount() - - dr_or_cr = "credit" if self.total_amount > 0 else "debit" - - lst = [] - for d in self.get('against_entries'): - if flt(d.allocated_amount) > 0: - lst.append({ - 'voucher_no' : d.voucher_no, - 'voucher_detail_no' : d.voucher_detail_no, - 'against_voucher_type' : self.voucher_type, - 'against_voucher' : self.voucher_no, - 'account' : self.account, - 'is_advance' : d.is_advance, - 'dr_or_cr' : dr_or_cr, - 'unadjusted_amt' : flt(d.original_amount), - 'allocated_amt' : flt(d.allocated_amount) - }) - - if lst: - from erpnext.accounts.utils import reconcile_against_document - reconcile_against_document(lst) - self.get_voucher_details() - self.get_against_entries() - msgprint(_("Successfully allocated")) - - def validate_allocated_amount(self): - if not self.total_allocated_amount: - frappe.throw(_("You must allocate amount before reconcile")) - elif self.total_allocated_amount > self.unmatched_amount: - frappe.throw(_("Total Allocated Amount can not be greater than unmatched amount")) - -def get_voucher_nos(doctype, txt, searchfield, start, page_len, filters): - non_reconclied_entries = [] - entries = frappe.db.sql(""" - select - voucher_no, posting_date, ifnull(abs(sum(ifnull(debit, 0)) - sum(ifnull(credit, 0))), 0) as amount - from - `tabGL Entry` - where - account = %s and voucher_type = %s and voucher_no like %s - and ifnull(against_voucher, '') = '' - group by voucher_no - """, (filters["account"], filters["voucher_type"], "%%%s%%" % txt), as_dict=True) - - for d in entries: - adjusted_amount = frappe.db.sql(""" - select - ifnull(abs(sum(ifnull(debit, 0)) - sum(ifnull(credit, 0))), 0) - from - `tabGL Entry` - where - account = %s and against_voucher_type = %s and ifnull(against_voucher, '') = %s - """, (filters["account"], filters["voucher_type"], d.voucher_no)) - adjusted_amount = adjusted_amount[0][0] if adjusted_amount else 0 - - if d.amount > adjusted_amount: - non_reconclied_entries.append([d.voucher_no, d.posting_date, d.amount]) - - return non_reconclied_entries diff --git a/erpnext/accounts/doctype/payment_to_invoice_matching_tool/test_records.json b/erpnext/accounts/doctype/payment_to_invoice_matching_tool/test_records.json deleted file mode 100644 index 0637a088a0..0000000000 --- a/erpnext/accounts/doctype/payment_to_invoice_matching_tool/test_records.json +++ /dev/null @@ -1 +0,0 @@ -[] \ No newline at end of file diff --git a/erpnext/accounts/doctype/payment_to_invoice_matching_tool_detail/README.md b/erpnext/accounts/doctype/payment_to_invoice_matching_tool_detail/README.md deleted file mode 100644 index ed329911d3..0000000000 --- a/erpnext/accounts/doctype/payment_to_invoice_matching_tool_detail/README.md +++ /dev/null @@ -1 +0,0 @@ -Journal Voucher (payment) detail for matching to invoice. \ No newline at end of file diff --git a/erpnext/accounts/doctype/payment_to_invoice_matching_tool_detail/__init__.py b/erpnext/accounts/doctype/payment_to_invoice_matching_tool_detail/__init__.py deleted file mode 100644 index baffc48825..0000000000 --- a/erpnext/accounts/doctype/payment_to_invoice_matching_tool_detail/__init__.py +++ /dev/null @@ -1 +0,0 @@ -from __future__ import unicode_literals diff --git a/erpnext/accounts/doctype/payment_to_invoice_matching_tool_detail/payment_to_invoice_matching_tool_detail.json b/erpnext/accounts/doctype/payment_to_invoice_matching_tool_detail/payment_to_invoice_matching_tool_detail.json deleted file mode 100644 index 247f023b2b..0000000000 --- a/erpnext/accounts/doctype/payment_to_invoice_matching_tool_detail/payment_to_invoice_matching_tool_detail.json +++ /dev/null @@ -1,110 +0,0 @@ -{ - "creation": "2013-02-22 01:27:39", - "docstatus": 0, - "doctype": "DocType", - "fields": [ - { - "fieldname": "voucher_no", - "fieldtype": "Link", - "in_list_view": 1, - "label": "Voucher No", - "options": "Journal Voucher", - "permlevel": 0, - "print_width": "140px", - "read_only": 1, - "reqd": 0, - "width": "140px" - }, - { - "fieldname": "unmatched_amount", - "fieldtype": "Currency", - "in_list_view": 1, - "label": "Unmatched Amount", - "options": "Company:company:default_currency", - "permlevel": 0, - "read_only": 1 - }, - { - "fieldname": "allocated_amount", - "fieldtype": "Currency", - "in_list_view": 1, - "label": "Allocated Amount", - "options": "Company:company:default_currency", - "permlevel": 0, - "reqd": 1 - }, - { - "fieldname": "col_break1", - "fieldtype": "Column Break", - "permlevel": 0 - }, - { - "fieldname": "posting_date", - "fieldtype": "Date", - "in_list_view": 1, - "label": "Posting Date", - "permlevel": 0, - "read_only": 1 - }, - { - "fieldname": "total_amt", - "fieldtype": "Currency", - "in_list_view": 1, - "label": "Total Amount", - "options": "Company:company:default_currency", - "permlevel": 0, - "read_only": 1 - }, - { - "fieldname": "against_account", - "fieldtype": "Data", - "in_list_view": 1, - "label": "Against Account", - "permlevel": 0, - "read_only": 1 - }, - { - "fieldname": "remarks", - "fieldtype": "Small Text", - "label": "Remarks", - "permlevel": 0, - "print_width": "200px", - "read_only": 1, - "width": "200px" - }, - { - "fieldname": "voucher_detail_no", - "fieldtype": "Data", - "hidden": 1, - "label": "Voucher Detail No", - "permlevel": 0, - "print_hide": 1, - "read_only": 1, - "reqd": 0 - }, - { - "fieldname": "is_advance", - "fieldtype": "Data", - "hidden": 1, - "label": "Is Advance", - "permlevel": 0, - "read_only": 1 - }, - { - "fieldname": "original_amount", - "fieldtype": "Currency", - "hidden": 1, - "label": "Original Amount", - "permlevel": 0 - } - ], - "hide_toolbar": 1, - "idx": 1, - "istable": 1, - "modified": "2014-04-30 19:27:15.993641", - "modified_by": "Administrator", - "module": "Accounts", - "name": "Payment to Invoice Matching Tool Detail", - "owner": "Administrator", - "permissions": [] -} \ No newline at end of file diff --git a/erpnext/accounts/doctype/period_closing_voucher/period_closing_voucher.json b/erpnext/accounts/doctype/period_closing_voucher/period_closing_voucher.json index aaa8c8a84e..c9e7dc2c3d 100644 --- a/erpnext/accounts/doctype/period_closing_voucher/period_closing_voucher.json +++ b/erpnext/accounts/doctype/period_closing_voucher/period_closing_voucher.json @@ -43,13 +43,14 @@ }, { "fieldname": "amended_from", - "fieldtype": "Data", - "ignore_restrictions": 1, + "fieldtype": "Link", + "ignore_user_permissions": 1, "in_list_view": 1, "label": "Amended From", "no_copy": 1, "oldfieldname": "amended_from", "oldfieldtype": "Data", + "options": "Period Closing Voucher", "permlevel": 0, "read_only": 1 }, @@ -101,7 +102,7 @@ "icon": "icon-file-text", "idx": 1, "is_submittable": 1, - "modified": "2014-05-09 02:16:36.920034", + "modified": "2014-06-23 07:55:49.946225", "modified_by": "Administrator", "module": "Accounts", "name": "Period Closing Voucher", diff --git a/erpnext/accounts/doctype/pos_setting/pos_setting.json b/erpnext/accounts/doctype/pos_setting/pos_setting.json index 5bc3a07fcc..d0a338c92a 100755 --- a/erpnext/accounts/doctype/pos_setting/pos_setting.json +++ b/erpnext/accounts/doctype/pos_setting/pos_setting.json @@ -62,7 +62,7 @@ "options": "Price List", "permlevel": 0, "read_only": 0, - "reqd": 1 + "reqd": 0 }, { "fieldname": "company", @@ -147,7 +147,7 @@ "options": "Warehouse", "permlevel": 0, "read_only": 0, - "reqd": 1 + "reqd": 0 }, { "fieldname": "cost_center", @@ -205,14 +205,13 @@ ], "icon": "icon-cog", "idx": 1, - "modified": "2014-05-09 02:17:34.814856", + "modified": "2014-06-23 16:40:59.510132", "modified_by": "Administrator", "module": "Accounts", "name": "POS Setting", "owner": "Administrator", "permissions": [ { - "cancel": 0, "create": 1, "delete": 1, "email": 1, @@ -225,7 +224,7 @@ "write": 1 }, { - "cancel": 0, + "apply_user_permissions": 1, "delete": 0, "email": 1, "permlevel": 0, diff --git a/erpnext/accounts/doctype/pricing_rule/pricing_rule.js b/erpnext/accounts/doctype/pricing_rule/pricing_rule.js new file mode 100644 index 0000000000..a1859e5d57 --- /dev/null +++ b/erpnext/accounts/doctype/pricing_rule/pricing_rule.js @@ -0,0 +1,91 @@ +// Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors +// License: GNU General Public License v3. See license.txt + +frappe.ui.form.on("Pricing Rule", "refresh", function(frm) { + var help_content = ['', + '', + '', + '
', + '

', + __('Notes'), + ':

', + '
    ', + '
  • ', + __("Pricing Rule is made to overwrite Price List / define discount percentage, based on some criteria."), + '
  • ', + '
  • ', + __("If selected Pricing Rule is made for 'Price', it will overwrite Price List. Pricing Rule price is the final price, so no further discount should be applied. Hence, in transactions like Sales Order, Purchase Order etc, it will be fetched in 'Rate' field, rather than 'Price List Rate' field."), + '
  • ', + '
  • ', + __('Discount Percentage can be applied either against a Price List or for all Price List.'), + '
  • ', + '
  • ', + __('To not apply Pricing Rule in a particular transaction, all applicable Pricing Rules should be disabled.'), + '
  • ', + '
', + '
', + '

', + __('How Pricing Rule is applied?'), + '

', + '
    ', + '
  1. ', + __("Pricing Rule is first selected based on 'Apply On' field, which can be Item, Item Group or Brand."), + '
  2. ', + '
  3. ', + __("Then Pricing Rules are filtered out based on Customer, Customer Group, Territory, Supplier, Supplier Type, Campaign, Sales Partner etc."), + '
  4. ', + '
  5. ', + __('Pricing Rules are further filtered based on quantity.'), + '
  6. ', + '
  7. ', + __('If two or more Pricing Rules are found based on the above conditions, Priority is applied. Priority is a number between 0 to 20 while default value is zero (blank). Higher number means it will take precedence if there are multiple Pricing Rules with same conditions.'), + '
  8. ', + '
  9. ', + __('Even if there are multiple Pricing Rules with highest priority, then following internal priorities are applied:'), + '
      ', + '
    • ', + __('Item Code > Item Group > Brand'), + '
    • ', + '
    • ', + __('Customer > Customer Group > Territory'), + '
    • ', + '
    • ', + __('Supplier > Supplier Type'), + '
    • ', + '
    ', + '
  10. ', + '
  11. ', + __('If multiple Pricing Rules continue to prevail, users are asked to set Priority manually to resolve conflict.'), + '
  12. ', + '
', + '
'].join("\n"); + + set_field_options("pricing_rule_help", help_content); + + cur_frm.cscript.set_options_for_applicable_for(); +}); + +cur_frm.cscript.set_options_for_applicable_for = function() { + var options = [""]; + var applicable_for = cur_frm.doc.applicable_for; + + if(cur_frm.doc.selling) { + options = $.merge(options, ["Customer", "Customer Group", "Territory", "Sales Partner", "Campaign"]); + } + if(cur_frm.doc.buying) { + $.merge(options, ["Supplier", "Supplier Type"]); + } + + set_field_options("applicable_for", options.join("\n")); + + if(!in_list(options, applicable_for)) applicable_for = null; + cur_frm.set_value("applicable_for", applicable_for) +} + +cur_frm.cscript.selling = function() { + cur_frm.cscript.set_options_for_applicable_for(); +} + +cur_frm.cscript.buying = function() { + cur_frm.cscript.set_options_for_applicable_for(); +} diff --git a/erpnext/accounts/doctype/pricing_rule/pricing_rule.json b/erpnext/accounts/doctype/pricing_rule/pricing_rule.json index baefde26ef..2d318c6360 100644 --- a/erpnext/accounts/doctype/pricing_rule/pricing_rule.json +++ b/erpnext/accounts/doctype/pricing_rule/pricing_rule.json @@ -51,6 +51,18 @@ "options": "Brand", "permlevel": 0 }, + { + "fieldname": "selling", + "fieldtype": "Check", + "label": "Selling", + "permlevel": 0 + }, + { + "fieldname": "buying", + "fieldtype": "Check", + "label": "Buying", + "permlevel": 0 + }, { "fieldname": "applicable_for", "fieldtype": "Select", @@ -131,6 +143,13 @@ "fieldtype": "Column Break", "permlevel": 0 }, + { + "fieldname": "company", + "fieldtype": "Link", + "label": "Company", + "options": "Company", + "permlevel": 0 + }, { "default": "Today", "fieldname": "valid_from", @@ -198,12 +217,25 @@ "label": "For Price List", "options": "Price List", "permlevel": 0 + }, + { + "fieldname": "help_section", + "fieldtype": "Section Break", + "label": "", + "options": "Simple", + "permlevel": 0 + }, + { + "fieldname": "pricing_rule_help", + "fieldtype": "HTML", + "label": "Pricing Rule Help", + "permlevel": 0 } ], "icon": "icon-gift", "idx": 1, "istable": 0, - "modified": "2014-05-12 16:24:52.005162", + "modified": "2014-06-20 19:36:22.502381", "modified_by": "Administrator", "module": "Accounts", "name": "Pricing Rule", @@ -212,8 +244,8 @@ { "create": 1, "delete": 1, - "export": 0, - "import": 0, + "export": 1, + "import": 1, "permlevel": 0, "read": 1, "report": 1, @@ -258,7 +290,6 @@ "permlevel": 0, "read": 1, "report": 1, - "restrict": 1, "role": "System Manager", "write": 1 } diff --git a/erpnext/accounts/doctype/pricing_rule/pricing_rule.py b/erpnext/accounts/doctype/pricing_rule/pricing_rule.py index 39260a2e9e..0c090ca0ea 100644 --- a/erpnext/accounts/doctype/pricing_rule/pricing_rule.py +++ b/erpnext/accounts/doctype/pricing_rule/pricing_rule.py @@ -5,28 +5,46 @@ from __future__ import unicode_literals import frappe +import json +import copy from frappe import throw, _ -from frappe.utils import flt +from frappe.utils import flt, cint from frappe.model.document import Document +class MultiplePricingRuleConflict(frappe.ValidationError): pass + class PricingRule(Document): def validate(self): self.validate_mandatory() + self.validate_applicable_for_selling_or_buying() self.validate_min_max_qty() self.cleanup_fields_value() - + self.validate_price_or_discount() + self.validate_max_discount() def validate_mandatory(self): - for field in ["apply_on", "applicable_for", "price_or_discount"]: + for field in ["apply_on", "applicable_for"]: tocheck = frappe.scrub(self.get(field) or "") if tocheck and not self.get(tocheck): throw(_("{0} is required").format(self.meta.get_label(tocheck)), frappe.MandatoryError) + def validate_applicable_for_selling_or_buying(self): + if not self.selling and not self.buying: + throw(_("Atleast one of the Selling or Buying must be selected")) + + if not self.selling and self.applicable_for in ["Customer", "Customer Group", + "Territory", "Sales Partner", "Campaign"]: + throw(_("Selling must be checked, if Applicable For is selected as {0}" + .format(self.applicable_for))) + + if not self.buying and self.applicable_for in ["Supplier", "Supplier Type"]: + throw(_("Buying must be checked, if Applicable For is selected as {0}" + .format(self.applicable_for))) + def validate_min_max_qty(self): if self.min_qty and self.max_qty and flt(self.min_qty) > flt(self.max_qty): throw(_("Min Qty can not be greater than Max Qty")) - def cleanup_fields_value(self): for logic_field in ["apply_on", "applicable_for", "price_or_discount"]: fieldname = frappe.scrub(self.get(logic_field) or "") @@ -39,3 +57,204 @@ class PricingRule(Document): f = frappe.scrub(f) if f!=fieldname: self.set(f, None) + + def validate_price_or_discount(self): + for field in ["Price", "Discount Percentage"]: + if flt(self.get(frappe.scrub(field))) < 0: + throw(_("{0} can not be negative").format(field)) + + def validate_max_discount(self): + if self.price_or_discount == "Discount Percentage" and self.item_code: + max_discount = frappe.db.get_value("Item", self.item_code, "max_discount") + if max_discount and flt(self.discount_percentage) > flt(max_discount): + throw(_("Max discount allowed for item: {0} is {1}%").format(self.item_code, max_discount)) + + +#-------------------------------------------------------------------------------- + +@frappe.whitelist() +def apply_pricing_rule(args): + """ + args = { + "item_list": [{"doctype": "", "name": "", "item_code": "", "brand": "", "item_group": ""}, ...], + "customer": "something", + "customer_group": "something", + "territory": "something", + "supplier": "something", + "supplier_type": "something", + "currency": "something", + "conversion_rate": "something", + "price_list": "something", + "plc_conversion_rate": "something", + "company": "something", + "transaction_date": "something", + "campaign": "something", + "sales_partner": "something", + "ignore_pricing_rule": "something" + } + """ + if isinstance(args, basestring): + args = json.loads(args) + + args = frappe._dict(args) + + # list of dictionaries + out = [] + + if args.get("parenttype") == "Material Request": return out + + if not args.transaction_type: + args.transaction_type = "buying" if frappe.get_meta(args.parenttype).get_field("supplier") \ + else "selling" + + item_list = args.get("item_list") + args.pop("item_list") + + for item in item_list: + args_copy = copy.deepcopy(args) + args_copy.update(item) + out.append(get_pricing_rule_for_item(args_copy)) + + return out + +def get_pricing_rule_for_item(args): + if args.get("parenttype") == "Material Request": return {} + + item_details = frappe._dict({ + "doctype": args.doctype, + "name": args.name, + "pricing_rule": None + }) + + if args.ignore_pricing_rule or not args.item_code: + return item_details + + if not (args.item_group and args.brand): + args.item_group, args.brand = frappe.db.get_value("Item", args.item_code, ["item_group", "brand"]) + if not args.item_group: + frappe.throw(_("Item Group not mentioned in item master for item {0}").format(args.item_code)) + + if args.customer and not (args.customer_group and args.territory): + customer = frappe.db.get_value("Customer", args.customer, ["customer_group", "territory"]) + if customer: + args.customer_group, args.territory = customer + + elif args.supplier and not args.supplier_type: + args.supplier_type = frappe.db.get_value("Supplier", args.supplier, "supplier_type") + + pricing_rules = get_pricing_rules(args) + pricing_rule = filter_pricing_rules(args, pricing_rules) + + if pricing_rule: + item_details.pricing_rule = pricing_rule.name + if pricing_rule.price_or_discount == "Price": + item_details.update({ + "price_list_rate": pricing_rule.price/flt(args.conversion_rate) \ + if args.conversion_rate else 0.0, + "discount_percentage": 0.0 + }) + else: + item_details.discount_percentage = pricing_rule.discount_percentage + + return item_details + +def get_pricing_rules(args): + def _get_tree_conditions(parenttype, allow_blank=True): + field = frappe.scrub(parenttype) + condition = "" + if args.get(field): + lft, rgt = frappe.db.get_value(parenttype, args[field], ["lft", "rgt"]) + parent_groups = frappe.db.sql_list("""select name from `tab%s` + where lft<=%s and rgt>=%s""" % (parenttype, '%s', '%s'), (lft, rgt)) + + if parent_groups: + if allow_blank: parent_groups.append('') + condition = " ifnull("+field+", '') in ('" + \ + "', '".join([d.replace("'", "\\'").replace('"', '\\"') for d in parent_groups])+"')" + return condition + + + conditions = "" + for field in ["company", "customer", "supplier", "supplier_type", "campaign", "sales_partner"]: + if args.get(field): + conditions += " and ifnull("+field+", '') in (%("+field+")s, '')" + else: + conditions += " and ifnull("+field+", '') = ''" + + for parenttype in ["Customer Group", "Territory"]: + group_condition = _get_tree_conditions(parenttype) + if group_condition: + conditions += " and " + group_condition + if not args.price_list: args.price_list = None + conditions += " and ifnull(for_price_list, '') in (%(price_list)s, '')" + + if args.get("transaction_date"): + conditions += """ and %(transaction_date)s between ifnull(valid_from, '2000-01-01') + and ifnull(valid_upto, '2500-12-31')""" + + item_group_condition = _get_tree_conditions("Item Group", False) + if item_group_condition: item_group_condition = " or " + item_group_condition + + return frappe.db.sql("""select * from `tabPricing Rule` + where (item_code=%(item_code)s {item_group_condition} or brand=%(brand)s) + and docstatus < 2 and ifnull(disable, 0) = 0 + and ifnull({transaction_type}, 0) = 1 {conditions} + order by priority desc, name desc""".format( + item_group_condition=item_group_condition, + transaction_type=args.transaction_type, conditions=conditions), args, as_dict=1) + +def filter_pricing_rules(args, pricing_rules): + # filter for qty + if pricing_rules and args.get("qty"): + pricing_rules = filter(lambda x: (args.qty>=flt(x.min_qty) + and (args.qty<=x.max_qty if x.max_qty else True)), pricing_rules) + + # find pricing rule with highest priority + if pricing_rules: + max_priority = max([cint(p.priority) for p in pricing_rules]) + if max_priority: + pricing_rules = filter(lambda x: cint(x.priority)==max_priority, pricing_rules) + + # apply internal priority + all_fields = ["item_code", "item_group", "brand", "customer", "customer_group", "territory", + "supplier", "supplier_type", "campaign", "sales_partner"] + + if len(pricing_rules) > 1: + for field_set in [["item_code", "item_group", "brand"], + ["customer", "customer_group", "territory"], ["supplier", "supplier_type"]]: + remaining_fields = list(set(all_fields) - set(field_set)) + if if_all_rules_same(pricing_rules, remaining_fields): + pricing_rules = apply_internal_priority(pricing_rules, field_set, args) + break + + if len(pricing_rules) > 1: + price_or_discount = list(set([d.price_or_discount for d in pricing_rules])) + if len(price_or_discount) == 1 and price_or_discount[0] == "Discount Percentage": + pricing_rules = filter(lambda x: x.for_price_list==args.price_list, pricing_rules) \ + or pricing_rules + + if len(pricing_rules) > 1: + frappe.throw(_("Multiple Price Rule exists with same criteria, please resolve \ + conflict by assigning priority. Price Rules: {0}") + .format("\n".join([d.name for d in pricing_rules])), MultiplePricingRuleConflict) + elif pricing_rules: + return pricing_rules[0] + +def if_all_rules_same(pricing_rules, fields): + all_rules_same = True + val = [pricing_rules[0][k] for k in fields] + for p in pricing_rules[1:]: + if val != [p[k] for k in fields]: + all_rules_same = False + break + + return all_rules_same + +def apply_internal_priority(pricing_rules, field_set, args): + filtered_rules = [] + for field in field_set: + if args.get(field): + filtered_rules = filter(lambda x: x[field]==args[field], pricing_rules) + if filtered_rules: break + + return filtered_rules or pricing_rules diff --git a/erpnext/accounts/doctype/pricing_rule/test_pricing_rule.py b/erpnext/accounts/doctype/pricing_rule/test_pricing_rule.py index 003c6e66b4..e8496d068b 100644 --- a/erpnext/accounts/doctype/pricing_rule/test_pricing_rule.py +++ b/erpnext/accounts/doctype/pricing_rule/test_pricing_rule.py @@ -17,9 +17,11 @@ class TestPricingRule(unittest.TestCase): "doctype": "Pricing Rule", "apply_on": "Item Code", "item_code": "_Test Item", + "selling": 1, "price_or_discount": "Discount Percentage", "price": 0, "discount_percentage": 10, + "company": "_Test Company" } frappe.get_doc(test_record.copy()).insert() @@ -28,15 +30,16 @@ class TestPricingRule(unittest.TestCase): "company": "_Test Company", "price_list": "_Test Price List", "currency": "_Test Currency", - "doctype": "Sales Order", + "parenttype": "Sales Order", "conversion_rate": 1, "price_list_currency": "_Test Currency", "plc_conversion_rate": 1, "order_type": "Sales", "transaction_type": "selling", "customer": "_Test Customer", + "doctype": "Sales Order Item", + "name": None }) - details = get_item_details(args) self.assertEquals(details.get("discount_percentage"), 10) @@ -71,8 +74,8 @@ class TestPricingRule(unittest.TestCase): self.assertEquals(details.get("discount_percentage"), 5) frappe.db.sql("update `tabPricing Rule` set priority=NULL where campaign='_Test Campaign'") - from erpnext.stock.get_item_details import MultiplePricingRuleConflict - self.assertRaises (MultiplePricingRuleConflict, get_item_details, args) + from erpnext.accounts.doctype.pricing_rule.pricing_rule import MultiplePricingRuleConflict + self.assertRaises(MultiplePricingRuleConflict, get_item_details, args) args.item_code = "_Test Item 2" details = get_item_details(args) diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js index 158dec2046..49ed12cc24 100644 --- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js +++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js @@ -27,7 +27,8 @@ erpnext.accounts.PurchaseInvoice = erpnext.buying.BuyingController.extend({ // Show / Hide button if(doc.docstatus==1 && doc.outstanding_amount > 0) - this.frm.add_custom_button(__('Make Payment Entry'), this.make_bank_voucher); + this.frm.add_custom_button(__('Make Payment Entry'), this.make_bank_voucher, + frappe.boot.doctype_icons["Journal Voucher"]); if(doc.docstatus==1) { cur_frm.appframe.add_button(__('View Ledger'), function() { @@ -56,7 +57,7 @@ erpnext.accounts.PurchaseInvoice = erpnext.buying.BuyingController.extend({ company: cur_frm.doc.company } }) - }); + }, "icon-download", "btn-default"); cur_frm.add_custom_button(__('From Purchase Receipt'), function() { @@ -69,7 +70,7 @@ erpnext.accounts.PurchaseInvoice = erpnext.buying.BuyingController.extend({ company: cur_frm.doc.company } }) - }); + }, "icon-download", "btn-default"); } @@ -77,16 +78,19 @@ erpnext.accounts.PurchaseInvoice = erpnext.buying.BuyingController.extend({ }, supplier: function() { + var me = this; if(this.frm.updating_party_details) return; - erpnext.utils.get_party_details(this.frm, - "erpnext.accounts.party.get_party_details", { + erpnext.utils.get_party_details(this.frm, "erpnext.accounts.party.get_party_details", + { posting_date: this.frm.doc.posting_date, party: this.frm.doc.supplier, party_type: "Supplier", account: this.frm.doc.debit_to, price_list: this.frm.doc.buying_price_list, - }) + }, function() { + me.apply_pricing_rule(); + }) }, credit_to: function() { @@ -109,7 +113,8 @@ erpnext.accounts.PurchaseInvoice = erpnext.buying.BuyingController.extend({ entries_add: function(doc, cdt, cdn) { var row = frappe.get_doc(cdt, cdn); - this.frm.script_manager.copy_from_first_row("entries", row, ["expense_account", "cost_center"]); + this.frm.script_manager.copy_from_first_row("entries", row, + ["expense_account", "cost_center", "project_name"]); }, on_submit: function() { diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json index b3eb534577..489bc4648a 100755 --- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json +++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json @@ -1,828 +1,851 @@ { - "allow_attach": 1, - "allow_import": 1, - "autoname": "naming_series:", - "creation": "2013-05-21 16:16:39", - "docstatus": 0, - "doctype": "DocType", + "allow_import": 1, + "autoname": "naming_series:", + "creation": "2013-05-21 16:16:39", + "docstatus": 0, + "doctype": "DocType", "fields": [ { - "fieldname": "supplier_section", - "fieldtype": "Section Break", - "label": "Supplier", - "options": "icon-user", + "fieldname": "supplier_section", + "fieldtype": "Section Break", + "label": "Supplier", + "options": "icon-user", "permlevel": 0 - }, + }, { - "fieldname": "column_break0", - "fieldtype": "Column Break", - "oldfieldtype": "Column Break", - "permlevel": 0, - "read_only": 0, + "fieldname": "column_break0", + "fieldtype": "Column Break", + "oldfieldtype": "Column Break", + "permlevel": 0, + "read_only": 0, "width": "50%" - }, + }, { - "fieldname": "naming_series", - "fieldtype": "Select", - "label": "Series", - "no_copy": 1, - "oldfieldname": "naming_series", - "oldfieldtype": "Select", - "options": "PINV-", - "permlevel": 0, - "print_hide": 1, - "read_only": 0, - "report_hide": 0, + "fieldname": "naming_series", + "fieldtype": "Select", + "label": "Series", + "no_copy": 1, + "oldfieldname": "naming_series", + "oldfieldtype": "Select", + "options": "PINV-", + "permlevel": 0, + "print_hide": 1, + "read_only": 0, + "report_hide": 0, "reqd": 1 - }, + }, { - "fieldname": "supplier", - "fieldtype": "Link", - "hidden": 0, - "label": "Supplier", - "oldfieldname": "supplier", - "oldfieldtype": "Link", - "options": "Supplier", - "permlevel": 0, - "print_hide": 1, + "fieldname": "supplier", + "fieldtype": "Link", + "hidden": 0, + "label": "Supplier", + "oldfieldname": "supplier", + "oldfieldtype": "Link", + "options": "Supplier", + "permlevel": 0, + "print_hide": 1, "read_only": 0 - }, + }, { - "depends_on": "supplier", - "fieldname": "supplier_name", - "fieldtype": "Data", - "hidden": 0, - "in_list_view": 1, - "label": "Name", - "oldfieldname": "supplier_name", - "oldfieldtype": "Data", - "permlevel": 0, + "depends_on": "supplier", + "fieldname": "supplier_name", + "fieldtype": "Data", + "hidden": 0, + "in_list_view": 1, + "label": "Name", + "oldfieldname": "supplier_name", + "oldfieldtype": "Data", + "permlevel": 0, "read_only": 1 - }, + }, { - "fieldname": "address_display", - "fieldtype": "Small Text", - "hidden": 1, - "label": "Address", - "permlevel": 0, + "fieldname": "address_display", + "fieldtype": "Small Text", + "hidden": 1, + "label": "Address", + "permlevel": 0, "read_only": 1 - }, + }, { - "fieldname": "contact_display", - "fieldtype": "Small Text", - "hidden": 1, - "label": "Contact", - "permlevel": 0, + "fieldname": "contact_display", + "fieldtype": "Small Text", + "hidden": 1, + "label": "Contact", + "permlevel": 0, "read_only": 1 - }, + }, { - "fieldname": "contact_mobile", - "fieldtype": "Text", - "hidden": 1, - "label": "Mobile No", - "permlevel": 0, + "fieldname": "contact_mobile", + "fieldtype": "Small Text", + "hidden": 1, + "label": "Mobile No", + "permlevel": 0, "read_only": 1 - }, + }, { - "fieldname": "contact_email", - "fieldtype": "Text", - "hidden": 1, - "label": "Contact Email", - "permlevel": 0, - "print_hide": 1, + "fieldname": "contact_email", + "fieldtype": "Small Text", + "hidden": 1, + "label": "Contact Email", + "permlevel": 0, + "print_hide": 1, "read_only": 1 - }, + }, { - "fieldname": "column_break1", - "fieldtype": "Column Break", - "oldfieldtype": "Column Break", - "permlevel": 0, - "read_only": 0, - "reqd": 0, + "fieldname": "column_break1", + "fieldtype": "Column Break", + "oldfieldtype": "Column Break", + "permlevel": 0, + "read_only": 0, + "reqd": 0, "width": "50%" - }, + }, { - "default": "Today", - "fieldname": "posting_date", - "fieldtype": "Date", - "in_filter": 1, - "label": "Posting Date", - "no_copy": 0, - "oldfieldname": "posting_date", - "oldfieldtype": "Date", - "permlevel": 0, - "print_hide": 1, - "read_only": 0, - "reqd": 1, + "default": "Today", + "fieldname": "posting_date", + "fieldtype": "Date", + "in_filter": 1, + "label": "Date", + "no_copy": 0, + "oldfieldname": "posting_date", + "oldfieldtype": "Date", + "permlevel": 0, + "print_hide": 1, + "read_only": 0, + "reqd": 1, "search_index": 1 - }, + }, { - "description": "If not applicable please enter: NA", - "fieldname": "bill_no", - "fieldtype": "Data", - "in_filter": 1, - "label": "Supplier Invoice No", - "oldfieldname": "bill_no", - "oldfieldtype": "Data", - "permlevel": 0, - "print_hide": 1, - "read_only": 0, - "reqd": 1, + "description": "", + "fieldname": "bill_no", + "fieldtype": "Data", + "in_filter": 1, + "label": "Supplier Invoice No", + "oldfieldname": "bill_no", + "oldfieldtype": "Data", + "permlevel": 0, + "print_hide": 1, + "read_only": 0, + "reqd": 0, "search_index": 1 - }, + }, { - "fieldname": "bill_date", - "fieldtype": "Date", - "in_filter": 1, - "label": "Supplier Invoice Date", - "oldfieldname": "bill_date", - "oldfieldtype": "Date", - "permlevel": 0, - "print_hide": 1, - "read_only": 0, - "reqd": 0, + "fieldname": "bill_date", + "fieldtype": "Date", + "in_filter": 1, + "label": "Supplier Invoice Date", + "oldfieldname": "bill_date", + "oldfieldtype": "Date", + "permlevel": 0, + "print_hide": 1, + "read_only": 0, + "reqd": 0, "search_index": 1 - }, + }, { - "fieldname": "amended_from", - "fieldtype": "Link", - "ignore_restrictions": 1, - "label": "Amended From", - "no_copy": 1, - "oldfieldname": "amended_from", - "oldfieldtype": "Link", - "options": "Purchase Invoice", - "permlevel": 0, - "print_hide": 1, + "fieldname": "amended_from", + "fieldtype": "Link", + "ignore_user_permissions": 1, + "label": "Amended From", + "no_copy": 1, + "oldfieldname": "amended_from", + "oldfieldtype": "Link", + "options": "Purchase Invoice", + "permlevel": 0, + "print_hide": 1, "read_only": 1 - }, + }, { - "fieldname": "company", - "fieldtype": "Link", - "in_filter": 1, - "label": "Company", - "oldfieldname": "company", - "oldfieldtype": "Link", - "options": "Company", - "permlevel": 0, - "print_hide": 1, - "read_only": 0, + "fieldname": "company", + "fieldtype": "Link", + "in_filter": 1, + "label": "Company", + "oldfieldname": "company", + "oldfieldtype": "Link", + "options": "Company", + "permlevel": 0, + "print_hide": 1, + "read_only": 0, "search_index": 1 - }, + }, { - "fieldname": "currency_price_list", - "fieldtype": "Section Break", - "label": "Currency and Price List", - "options": "icon-tag", - "permlevel": 0, + "fieldname": "currency_price_list", + "fieldtype": "Section Break", + "label": "Currency and Price List", + "options": "icon-tag", + "permlevel": 0, "read_only": 0 - }, + }, { - "fieldname": "currency", - "fieldtype": "Link", - "label": "Currency", - "oldfieldname": "currency", - "oldfieldtype": "Select", - "options": "Currency", - "permlevel": 0, - "print_hide": 1, + "fieldname": "currency", + "fieldtype": "Link", + "label": "Currency", + "oldfieldname": "currency", + "oldfieldtype": "Select", + "options": "Currency", + "permlevel": 0, + "print_hide": 1, "read_only": 0 - }, + }, { - "description": "The rate at which Bill Currency is converted into company's base currency", - "fieldname": "conversion_rate", - "fieldtype": "Float", - "label": "Exchange Rate", - "oldfieldname": "conversion_rate", - "oldfieldtype": "Currency", - "permlevel": 0, - "print_hide": 1, + "description": "The rate at which Bill Currency is converted into company's base currency", + "fieldname": "conversion_rate", + "fieldtype": "Float", + "label": "Exchange Rate", + "oldfieldname": "conversion_rate", + "oldfieldtype": "Currency", + "permlevel": 0, + "print_hide": 1, "read_only": 0 - }, + }, { - "fieldname": "column_break2", - "fieldtype": "Column Break", - "permlevel": 0, + "fieldname": "column_break2", + "fieldtype": "Column Break", + "permlevel": 0, "read_only": 0 - }, + }, { - "fieldname": "buying_price_list", - "fieldtype": "Link", - "label": "Price List", - "options": "Price List", - "permlevel": 0, - "print_hide": 1, + "fieldname": "buying_price_list", + "fieldtype": "Link", + "label": "Price List", + "options": "Price List", + "permlevel": 0, + "print_hide": 1, "read_only": 0 - }, + }, { - "fieldname": "price_list_currency", - "fieldtype": "Link", - "label": "Price List Currency", - "options": "Currency", - "permlevel": 0, - "print_hide": 1, + "fieldname": "price_list_currency", + "fieldtype": "Link", + "label": "Price List Currency", + "options": "Currency", + "permlevel": 0, + "print_hide": 1, "read_only": 1 - }, + }, { - "fieldname": "plc_conversion_rate", - "fieldtype": "Float", - "label": "Price List Exchange Rate", - "permlevel": 0, - "print_hide": 1, + "fieldname": "plc_conversion_rate", + "fieldtype": "Float", + "label": "Price List Exchange Rate", + "permlevel": 0, + "print_hide": 1, "read_only": 0 - }, + }, { - "fieldname": "items", - "fieldtype": "Section Break", - "label": "Items", - "oldfieldtype": "Section Break", - "options": "icon-shopping-cart", - "permlevel": 0, + "fieldname": "ignore_pricing_rule", + "fieldtype": "Check", + "label": "Ignore Pricing Rule", + "no_copy": 1, + "permlevel": 1, + "print_hide": 1 + }, + { + "fieldname": "items", + "fieldtype": "Section Break", + "label": "Items", + "oldfieldtype": "Section Break", + "options": "icon-shopping-cart", + "permlevel": 0, "read_only": 0 - }, + }, { - "allow_on_submit": 1, - "fieldname": "entries", - "fieldtype": "Table", - "label": "Entries", - "oldfieldname": "entries", - "oldfieldtype": "Table", - "options": "Purchase Invoice Item", - "permlevel": 0, + "allow_on_submit": 1, + "fieldname": "entries", + "fieldtype": "Table", + "label": "Entries", + "oldfieldname": "entries", + "oldfieldtype": "Table", + "options": "Purchase Invoice Item", + "permlevel": 0, "read_only": 0 - }, + }, { - "fieldname": "section_break_26", - "fieldtype": "Section Break", + "fieldname": "section_break_26", + "fieldtype": "Section Break", "permlevel": 0 - }, + }, { - "fieldname": "net_total_import", - "fieldtype": "Currency", - "label": "Net Total", - "oldfieldname": "net_total_import", - "oldfieldtype": "Currency", - "options": "currency", - "permlevel": 0, - "print_hide": 0, + "description": "Will be calculated automatically when you enter the details", + "fieldname": "net_total", + "fieldtype": "Currency", + "label": "Net Total (Company Currency)", + "oldfieldname": "net_total", + "oldfieldtype": "Currency", + "options": "Company:company:default_currency", + "permlevel": 0, + "print_hide": 1, "read_only": 1 - }, + }, { - "fieldname": "column_break_28", - "fieldtype": "Column Break", + "fieldname": "column_break_28", + "fieldtype": "Column Break", "permlevel": 0 - }, + }, { - "description": "Will be calculated automatically when you enter the details", - "fieldname": "net_total", - "fieldtype": "Currency", - "label": "Net Total (Company Currency)", - "oldfieldname": "net_total", - "oldfieldtype": "Currency", - "options": "Company:company:default_currency", - "permlevel": 0, - "print_hide": 1, + "fieldname": "net_total_import", + "fieldtype": "Currency", + "label": "Net Total", + "oldfieldname": "net_total_import", + "oldfieldtype": "Currency", + "options": "currency", + "permlevel": 0, + "print_hide": 0, "read_only": 1 - }, + }, { - "fieldname": "taxes", - "fieldtype": "Section Break", - "label": "Taxes and Charges", - "oldfieldtype": "Section Break", - "options": "icon-money", - "permlevel": 0, + "fieldname": "taxes", + "fieldtype": "Section Break", + "label": "Taxes and Charges", + "oldfieldtype": "Section Break", + "options": "icon-money", + "permlevel": 0, "read_only": 0 - }, + }, { - "fieldname": "taxes_and_charges", - "fieldtype": "Link", - "label": "Taxes and Charges", - "oldfieldname": "purchase_other_charges", - "oldfieldtype": "Link", - "options": "Purchase Taxes and Charges Master", - "permlevel": 0, - "print_hide": 1, + "fieldname": "taxes_and_charges", + "fieldtype": "Link", + "label": "Taxes and Charges", + "oldfieldname": "purchase_other_charges", + "oldfieldtype": "Link", + "options": "Purchase Taxes and Charges Master", + "permlevel": 0, + "print_hide": 1, "read_only": 0 - }, + }, { - "fieldname": "other_charges", - "fieldtype": "Table", - "label": "Purchase Taxes and Charges", - "oldfieldname": "purchase_tax_details", - "oldfieldtype": "Table", - "options": "Purchase Taxes and Charges", - "permlevel": 0, + "fieldname": "other_charges", + "fieldtype": "Table", + "label": "Purchase Taxes and Charges", + "oldfieldname": "purchase_tax_details", + "oldfieldtype": "Table", + "options": "Purchase Taxes and Charges", + "permlevel": 0, "read_only": 0 - }, + }, { - "fieldname": "other_charges_calculation", - "fieldtype": "HTML", - "label": "Taxes and Charges Calculation", - "oldfieldtype": "HTML", - "permlevel": 0, - "print_hide": 1, + "fieldname": "other_charges_calculation", + "fieldtype": "HTML", + "label": "Taxes and Charges Calculation", + "oldfieldtype": "HTML", + "permlevel": 0, + "print_hide": 1, "read_only": 0 - }, + }, { - "fieldname": "totals", - "fieldtype": "Section Break", - "label": "Totals", - "oldfieldtype": "Section Break", - "options": "icon-money", - "permlevel": 0, + "fieldname": "totals", + "fieldtype": "Section Break", + "label": "Totals", + "oldfieldtype": "Section Break", + "options": "icon-money", + "permlevel": 0, "read_only": 0 - }, + }, { - "fieldname": "other_charges_added_import", - "fieldtype": "Currency", - "label": "Taxes and Charges Added", - "oldfieldname": "other_charges_added_import", - "oldfieldtype": "Currency", - "options": "currency", - "permlevel": 0, - "print_hide": 1, + "fieldname": "other_charges_added", + "fieldtype": "Currency", + "label": "Taxes and Charges Added (Company Currency)", + "oldfieldname": "other_charges_added", + "oldfieldtype": "Currency", + "options": "Company:company:default_currency", + "permlevel": 0, + "print_hide": 1, "read_only": 1 - }, + }, { - "fieldname": "other_charges_deducted_import", - "fieldtype": "Currency", - "label": "Taxes and Charges Deducted", - "oldfieldname": "other_charges_deducted_import", - "oldfieldtype": "Currency", - "options": "currency", - "permlevel": 0, - "print_hide": 1, + "fieldname": "other_charges_deducted", + "fieldtype": "Currency", + "label": "Taxes and Charges Deducted (Company Currency)", + "oldfieldname": "other_charges_deducted", + "oldfieldtype": "Currency", + "options": "Company:company:default_currency", + "permlevel": 0, + "print_hide": 1, "read_only": 1 - }, + }, { - "fieldname": "grand_total_import", - "fieldtype": "Currency", - "in_list_view": 1, - "label": "Grand Total", - "oldfieldname": "grand_total_import", - "oldfieldtype": "Currency", - "options": "currency", - "permlevel": 0, - "print_hide": 0, + "fieldname": "grand_total", + "fieldtype": "Currency", + "label": "Grand Total (Company Currency)", + "oldfieldname": "grand_total", + "oldfieldtype": "Currency", + "options": "Company:company:default_currency", + "permlevel": 0, + "print_hide": 1, "read_only": 1 - }, + }, { - "fieldname": "in_words_import", - "fieldtype": "Data", - "label": "In Words", - "oldfieldname": "in_words_import", - "oldfieldtype": "Data", - "permlevel": 0, - "print_hide": 0, + "description": "In Words will be visible once you save the Purchase Invoice.", + "fieldname": "in_words", + "fieldtype": "Data", + "label": "In Words (Company Currency)", + "oldfieldname": "in_words", + "oldfieldtype": "Data", + "permlevel": 0, + "print_hide": 1, "read_only": 1 - }, + }, { - "fieldname": "total_amount_to_pay", - "fieldtype": "Currency", - "hidden": 0, - "label": "Total Amount To Pay", - "no_copy": 1, - "oldfieldname": "total_amount_to_pay", - "oldfieldtype": "Currency", - "options": "Company:company:default_currency", - "permlevel": 0, - "print_hide": 1, - "read_only": 1 - }, - { - "fieldname": "total_advance", - "fieldtype": "Currency", - "label": "Total Advance", - "no_copy": 1, - "oldfieldname": "total_advance", - "oldfieldtype": "Currency", - "options": "Company:company:default_currency", - "permlevel": 0, - "print_hide": 1, - "read_only": 1 - }, - { - "fieldname": "outstanding_amount", - "fieldtype": "Currency", - "in_filter": 1, - "in_list_view": 1, - "label": "Outstanding Amount", - "no_copy": 1, - "oldfieldname": "outstanding_amount", - "oldfieldtype": "Currency", - "options": "Company:company:default_currency", - "permlevel": 0, - "print_hide": 1, - "read_only": 1, - "search_index": 1 - }, - { - "fieldname": "column_break8", - "fieldtype": "Column Break", - "oldfieldtype": "Column Break", - "permlevel": 0, - "print_hide": 1, - "read_only": 0, + "fieldname": "column_break8", + "fieldtype": "Column Break", + "oldfieldtype": "Column Break", + "permlevel": 0, + "print_hide": 1, + "read_only": 0, "width": "50%" - }, + }, { - "fieldname": "total_tax", - "fieldtype": "Currency", - "label": "Total Tax (Company Currency)", - "oldfieldname": "total_tax", - "oldfieldtype": "Currency", - "options": "Company:company:default_currency", - "permlevel": 0, - "print_hide": 1, + "fieldname": "other_charges_added_import", + "fieldtype": "Currency", + "label": "Taxes and Charges Added", + "oldfieldname": "other_charges_added_import", + "oldfieldtype": "Currency", + "options": "currency", + "permlevel": 0, + "print_hide": 1, "read_only": 1 - }, + }, { - "fieldname": "other_charges_added", - "fieldtype": "Currency", - "label": "Taxes and Charges Added (Company Currency)", - "oldfieldname": "other_charges_added", - "oldfieldtype": "Currency", - "options": "Company:company:default_currency", - "permlevel": 0, - "print_hide": 1, + "fieldname": "other_charges_deducted_import", + "fieldtype": "Currency", + "label": "Taxes and Charges Deducted", + "oldfieldname": "other_charges_deducted_import", + "oldfieldtype": "Currency", + "options": "currency", + "permlevel": 0, + "print_hide": 1, "read_only": 1 - }, + }, { - "fieldname": "other_charges_deducted", - "fieldtype": "Currency", - "label": "Taxes and Charges Deducted (Company Currency)", - "oldfieldname": "other_charges_deducted", - "oldfieldtype": "Currency", - "options": "Company:company:default_currency", - "permlevel": 0, - "print_hide": 1, + "fieldname": "grand_total_import", + "fieldtype": "Currency", + "in_list_view": 1, + "label": "Grand Total", + "oldfieldname": "grand_total_import", + "oldfieldtype": "Currency", + "options": "currency", + "permlevel": 0, + "print_hide": 0, "read_only": 1 - }, + }, { - "fieldname": "grand_total", - "fieldtype": "Currency", - "label": "Grand Total (Company Currency)", - "oldfieldname": "grand_total", - "oldfieldtype": "Currency", - "options": "Company:company:default_currency", - "permlevel": 0, - "print_hide": 1, + "fieldname": "in_words_import", + "fieldtype": "Data", + "label": "In Words", + "oldfieldname": "in_words_import", + "oldfieldtype": "Data", + "permlevel": 0, + "print_hide": 0, "read_only": 1 - }, + }, { - "description": "In Words will be visible once you save the Purchase Invoice.", - "fieldname": "in_words", - "fieldtype": "Data", - "label": "In Words (Company Currency)", - "oldfieldname": "in_words", - "oldfieldtype": "Data", - "permlevel": 0, - "print_hide": 1, + "fieldname": "total_amount_to_pay", + "fieldtype": "Currency", + "hidden": 0, + "label": "Total Amount To Pay", + "no_copy": 1, + "oldfieldname": "total_amount_to_pay", + "oldfieldtype": "Currency", + "options": "Company:company:default_currency", + "permlevel": 0, + "print_hide": 1, "read_only": 1 - }, + }, { - "fieldname": "write_off_amount", - "fieldtype": "Currency", - "label": "Write Off Amount", - "no_copy": 1, - "options": "Company:company:default_currency", - "permlevel": 0, - "print_hide": 1, + "fieldname": "total_advance", + "fieldtype": "Currency", + "label": "Total Advance", + "no_copy": 1, + "oldfieldname": "total_advance", + "oldfieldtype": "Currency", + "options": "Company:company:default_currency", + "permlevel": 0, + "print_hide": 1, + "read_only": 1 + }, + { + "fieldname": "total_tax", + "fieldtype": "Currency", + "label": "Total Tax (Company Currency)", + "oldfieldname": "total_tax", + "oldfieldtype": "Currency", + "options": "Company:company:default_currency", + "permlevel": 0, + "print_hide": 1, + "read_only": 1 + }, + { + "fieldname": "outstanding_amount", + "fieldtype": "Currency", + "in_filter": 1, + "in_list_view": 1, + "label": "Outstanding Amount", + "no_copy": 1, + "oldfieldname": "outstanding_amount", + "oldfieldtype": "Currency", + "options": "Company:company:default_currency", + "permlevel": 0, + "print_hide": 1, + "read_only": 1, + "search_index": 1 + }, + { + "fieldname": "write_off_amount", + "fieldtype": "Currency", + "label": "Write Off Amount", + "no_copy": 1, + "options": "Company:company:default_currency", + "permlevel": 0, + "print_hide": 1, "read_only": 0 - }, + }, { - "depends_on": "eval:flt(doc.write_off_amount)!=0", - "fieldname": "write_off_account", - "fieldtype": "Link", - "label": "Write Off Account", - "no_copy": 1, - "options": "Account", - "permlevel": 0, - "print_hide": 1, + "depends_on": "eval:flt(doc.write_off_amount)!=0", + "fieldname": "write_off_account", + "fieldtype": "Link", + "label": "Write Off Account", + "no_copy": 1, + "options": "Account", + "permlevel": 0, + "print_hide": 1, "read_only": 0 - }, + }, { - "depends_on": "eval:flt(doc.write_off_amount)!=0", - "fieldname": "write_off_cost_center", - "fieldtype": "Link", - "label": "Write Off Cost Center", - "no_copy": 1, - "options": "Cost Center", - "permlevel": 0, - "print_hide": 1, + "depends_on": "eval:flt(doc.write_off_amount)!=0", + "fieldname": "write_off_cost_center", + "fieldtype": "Link", + "label": "Write Off Cost Center", + "no_copy": 1, + "options": "Cost Center", + "permlevel": 0, + "print_hide": 1, "read_only": 0 - }, + }, { - "fieldname": "against_expense_account", - "fieldtype": "Small Text", - "hidden": 1, - "label": "Against Expense Account", - "no_copy": 1, - "oldfieldname": "against_expense_account", - "oldfieldtype": "Small Text", - "permlevel": 0, - "print_hide": 1, - "read_only": 0, + "fieldname": "against_expense_account", + "fieldtype": "Small Text", + "hidden": 1, + "label": "Against Expense Account", + "no_copy": 1, + "oldfieldname": "against_expense_account", + "oldfieldtype": "Small Text", + "permlevel": 0, + "print_hide": 1, + "read_only": 0, "report_hide": 0 - }, + }, { - "fieldname": "advances", - "fieldtype": "Section Break", - "label": "Advances", - "oldfieldtype": "Section Break", - "options": "icon-money", - "permlevel": 0, - "print_hide": 1, - "read_only": 0 - }, - { - "fieldname": "get_advances_paid", - "fieldtype": "Button", - "label": "Get Advances Paid", - "oldfieldtype": "Button", - "options": "get_advances", - "permlevel": 0, - "print_hide": 1, - "read_only": 0 - }, - { - "fieldname": "advance_allocation_details", - "fieldtype": "Table", - "label": "Purchase Invoice Advances", - "no_copy": 1, - "oldfieldname": "advance_allocation_details", - "oldfieldtype": "Table", - "options": "Purchase Invoice Advance", - "permlevel": 0, - "print_hide": 1, - "read_only": 0 - }, - { - "fieldname": "terms_section_break", - "fieldtype": "Section Break", - "label": "Terms and Conditions", - "options": "icon-legal", + "fieldname": "fold", + "fieldtype": "Fold", "permlevel": 0 - }, + }, { - "fieldname": "tc_name", - "fieldtype": "Link", - "label": "Terms", - "options": "Terms and Conditions", - "permlevel": 0, + "fieldname": "advances", + "fieldtype": "Section Break", + "label": "Advances", + "oldfieldtype": "Section Break", + "options": "icon-money", + "permlevel": 0, + "print_hide": 1, + "read_only": 0 + }, + { + "fieldname": "get_advances_paid", + "fieldtype": "Button", + "label": "Get Advances Paid", + "oldfieldtype": "Button", + "options": "get_advances", + "permlevel": 0, + "print_hide": 1, + "read_only": 0 + }, + { + "fieldname": "advance_allocation_details", + "fieldtype": "Table", + "label": "Purchase Invoice Advances", + "no_copy": 1, + "oldfieldname": "advance_allocation_details", + "oldfieldtype": "Table", + "options": "Purchase Invoice Advance", + "permlevel": 0, + "print_hide": 1, + "read_only": 0 + }, + { + "fieldname": "terms_section_break", + "fieldtype": "Section Break", + "label": "Terms and Conditions", + "options": "icon-legal", + "permlevel": 0 + }, + { + "fieldname": "tc_name", + "fieldtype": "Link", + "label": "Terms", + "options": "Terms and Conditions", + "permlevel": 0, "print_hide": 1 - }, + }, { - "fieldname": "terms", - "fieldtype": "Text Editor", - "label": "Terms and Conditions1", + "fieldname": "terms", + "fieldtype": "Text Editor", + "label": "Terms and Conditions1", "permlevel": 0 - }, + }, { - "depends_on": "supplier", - "fieldname": "contact_section", - "fieldtype": "Section Break", - "label": "Contact Info", - "options": "icon-bullhorn", - "permlevel": 0, + "depends_on": "supplier", + "fieldname": "contact_section", + "fieldtype": "Section Break", + "label": "Contact Info", + "options": "icon-bullhorn", + "permlevel": 0, "read_only": 0 - }, + }, { - "fieldname": "supplier_address", - "fieldtype": "Link", - "label": "Supplier Address", - "options": "Address", - "permlevel": 0, + "fieldname": "supplier_address", + "fieldtype": "Link", + "label": "Supplier Address", + "options": "Address", + "permlevel": 0, + "print_hide": 1, "read_only": 0 - }, + }, { - "fieldname": "col_break23", - "fieldtype": "Column Break", - "permlevel": 0, - "read_only": 0, + "fieldname": "col_break23", + "fieldtype": "Column Break", + "permlevel": 0, + "read_only": 0, "width": "50%" - }, + }, { - "fieldname": "contact_person", - "fieldtype": "Link", - "label": "Contact Person", - "options": "Contact", - "permlevel": 0, - "print_hide": 1, + "fieldname": "contact_person", + "fieldtype": "Link", + "label": "Contact Person", + "options": "Contact", + "permlevel": 0, + "print_hide": 1, "read_only": 0 - }, + }, { - "fieldname": "more_info", - "fieldtype": "Section Break", - "label": "More Info", - "oldfieldtype": "Section Break", - "options": "icon-file-text", - "permlevel": 0, - "print_hide": 1, + "fieldname": "more_info", + "fieldtype": "Section Break", + "label": "More Info", + "oldfieldtype": "Section Break", + "options": "icon-file-text", + "permlevel": 0, + "print_hide": 1, "read_only": 0 - }, + }, { - "description": "Supplier (Payable) Account", - "fieldname": "credit_to", - "fieldtype": "Link", - "in_filter": 1, - "label": "Credit To", - "oldfieldname": "credit_to", - "oldfieldtype": "Link", - "options": "Account", - "permlevel": 0, - "print_hide": 1, - "read_only": 0, - "reqd": 1, + "description": "Supplier (Payable) Account", + "fieldname": "credit_to", + "fieldtype": "Link", + "in_filter": 1, + "label": "Credit To", + "oldfieldname": "credit_to", + "oldfieldtype": "Link", + "options": "Account", + "permlevel": 0, + "print_hide": 1, + "read_only": 0, + "reqd": 1, "search_index": 1 - }, + }, { - "default": "No", - "description": "Considered as Opening Balance", - "fieldname": "is_opening", - "fieldtype": "Select", - "in_filter": 1, - "label": "Is Opening", - "oldfieldname": "is_opening", - "oldfieldtype": "Select", - "options": "No\nYes", - "permlevel": 0, - "print_hide": 1, - "read_only": 0, + "default": "No", + "description": "Considered as Opening Balance", + "fieldname": "is_opening", + "fieldtype": "Select", + "in_filter": 1, + "label": "Is Opening", + "oldfieldname": "is_opening", + "oldfieldtype": "Select", + "options": "No\nYes", + "permlevel": 0, + "print_hide": 1, + "read_only": 0, "search_index": 1 - }, + }, { - "description": "Actual Invoice Date", - "fieldname": "aging_date", - "fieldtype": "Date", - "label": "Aging Date", - "oldfieldname": "aging_date", - "oldfieldtype": "Date", - "permlevel": 0, - "print_hide": 1, - "read_only": 0, + "description": "Actual Invoice Date", + "fieldname": "aging_date", + "fieldtype": "Date", + "label": "Aging Date", + "oldfieldname": "aging_date", + "oldfieldtype": "Date", + "permlevel": 0, + "print_hide": 1, + "read_only": 0, "search_index": 0 - }, + }, { - "allow_on_submit": 1, - "fieldname": "select_print_heading", - "fieldtype": "Link", - "label": "Print Heading", - "no_copy": 1, - "oldfieldname": "select_print_heading", - "oldfieldtype": "Link", - "options": "Print Heading", - "permlevel": 0, - "print_hide": 1, - "read_only": 0, + "allow_on_submit": 1, + "fieldname": "select_print_heading", + "fieldtype": "Link", + "label": "Print Heading", + "no_copy": 1, + "oldfieldname": "select_print_heading", + "oldfieldtype": "Link", + "options": "Print Heading", + "permlevel": 0, + "print_hide": 1, + "read_only": 0, "report_hide": 1 - }, + }, { - "fieldname": "due_date", - "fieldtype": "Date", - "in_filter": 1, - "label": "Due Date", - "no_copy": 0, - "oldfieldname": "due_date", - "oldfieldtype": "Date", - "permlevel": 0, - "print_hide": 0, - "read_only": 0, + "fieldname": "due_date", + "fieldtype": "Date", + "in_filter": 1, + "label": "Due Date", + "no_copy": 0, + "oldfieldname": "due_date", + "oldfieldtype": "Date", + "permlevel": 0, + "print_hide": 1, + "read_only": 0, "search_index": 1 - }, + }, { - "fieldname": "mode_of_payment", - "fieldtype": "Link", - "label": "Mode of Payment", - "oldfieldname": "mode_of_payment", - "oldfieldtype": "Select", - "options": "Mode of Payment", - "permlevel": 0, + "fieldname": "mode_of_payment", + "fieldtype": "Link", + "label": "Mode of Payment", + "oldfieldname": "mode_of_payment", + "oldfieldtype": "Select", + "options": "Mode of Payment", + "permlevel": 0, "read_only": 0 - }, + }, { - "fieldname": "column_break_63", - "fieldtype": "Column Break", - "permlevel": 0, + "fieldname": "column_break_63", + "fieldtype": "Column Break", + "permlevel": 0, "read_only": 0 - }, + }, { - "allow_on_submit": 1, - "fieldname": "letter_head", - "fieldtype": "Link", - "label": "Letter Head", - "options": "Letter Head", - "permlevel": 0, + "allow_on_submit": 1, + "fieldname": "letter_head", + "fieldtype": "Link", + "label": "Letter Head", + "options": "Letter Head", + "permlevel": 0, "print_hide": 1 - }, + }, { - "fieldname": "fiscal_year", - "fieldtype": "Link", - "in_filter": 1, - "label": "Fiscal Year", - "oldfieldname": "fiscal_year", - "oldfieldtype": "Select", - "options": "Fiscal Year", - "permlevel": 0, - "print_hide": 1, - "read_only": 0, + "fieldname": "fiscal_year", + "fieldtype": "Link", + "in_filter": 1, + "label": "Fiscal Year", + "oldfieldname": "fiscal_year", + "oldfieldtype": "Select", + "options": "Fiscal Year", + "permlevel": 0, + "print_hide": 1, + "read_only": 0, "search_index": 1 - }, + }, { - "fieldname": "remarks", - "fieldtype": "Small Text", - "label": "Remarks", - "no_copy": 1, - "oldfieldname": "remarks", - "oldfieldtype": "Text", - "permlevel": 0, - "print_hide": 1, - "read_only": 0, + "fieldname": "remarks", + "fieldtype": "Small Text", + "label": "Remarks", + "no_copy": 1, + "oldfieldname": "remarks", + "oldfieldtype": "Text", + "permlevel": 0, + "print_hide": 1, + "read_only": 0, "reqd": 0 } - ], - "icon": "icon-file-text", - "idx": 1, - "is_submittable": 1, - "modified": "2014-05-09 02:16:52.618986", - "modified_by": "Administrator", - "module": "Accounts", - "name": "Purchase Invoice", - "owner": "Administrator", + ], + "icon": "icon-file-text", + "idx": 1, + "is_submittable": 1, + "modified": "2014-08-19 12:01:12.133942", + "modified_by": "Administrator", + "module": "Accounts", + "name": "Purchase Invoice", + "owner": "Administrator", "permissions": [ { - "amend": 0, - "cancel": 0, - "create": 0, - "delete": 0, - "email": 1, - "permlevel": 0, - "print": 1, - "read": 1, - "report": 1, - "role": "Accounts User", - "submit": 0, - "write": 0 - }, - { - "amend": 0, - "cancel": 0, - "create": 0, - "delete": 0, - "email": 1, - "permlevel": 0, - "print": 1, - "read": 1, - "report": 1, - "role": "Purchase User", - "submit": 0, - "write": 0 - }, - { - "amend": 0, - "cancel": 0, - "create": 0, - "delete": 0, - "email": 1, - "permlevel": 0, - "print": 1, - "read": 1, - "report": 1, - "role": "Supplier", - "submit": 0, - "write": 0 - }, - { - "amend": 1, - "cancel": 1, - "create": 1, - "delete": 1, - "email": 1, - "permlevel": 0, - "print": 1, - "read": 1, - "report": 1, - "role": "Accounts Manager", - "submit": 1, + "amend": 1, + "apply_user_permissions": 1, + "cancel": 1, + "create": 1, + "delete": 0, + "email": 1, + "permlevel": 0, + "print": 1, + "read": 1, + "report": 1, + "role": "Accounts User", + "submit": 1, "write": 1 - }, + }, { - "amend": 0, - "cancel": 0, - "create": 0, - "delete": 0, - "email": 1, - "permlevel": 0, - "print": 1, - "read": 1, - "report": 1, - "role": "Auditor", - "submit": 0, + "amend": 0, + "apply_user_permissions": 1, + "cancel": 0, + "create": 0, + "delete": 0, + "email": 1, + "permlevel": 0, + "print": 1, + "read": 1, + "report": 1, + "role": "Purchase User", + "submit": 0, "write": 0 + }, + { + "amend": 0, + "apply_user_permissions": 1, + "cancel": 0, + "create": 0, + "delete": 0, + "email": 1, + "permlevel": 0, + "print": 1, + "read": 1, + "report": 1, + "role": "Supplier", + "submit": 0, + "write": 0 + }, + { + "amend": 1, + "cancel": 1, + "create": 1, + "delete": 1, + "email": 1, + "permlevel": 0, + "print": 1, + "read": 1, + "report": 1, + "role": "Accounts Manager", + "submit": 1, + "write": 1 + }, + { + "amend": 0, + "apply_user_permissions": 1, + "cancel": 0, + "create": 0, + "delete": 0, + "email": 1, + "permlevel": 0, + "print": 1, + "read": 1, + "report": 1, + "role": "Auditor", + "submit": 0, + "write": 0 + }, + { + "permlevel": 1, + "read": 1, + "role": "Accounts Manager", + "write": 1 } - ], - "read_only_onload": 1, - "search_fields": "posting_date, credit_to, fiscal_year, bill_no, grand_total, outstanding_amount", - "sort_field": "modified", + ], + "read_only_onload": 1, + "search_fields": "posting_date, credit_to, fiscal_year, bill_no, grand_total, outstanding_amount", + "sort_field": "modified", "sort_order": "DESC" -} \ No newline at end of file +} diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py index 80aa73a197..956dacb55f 100644 --- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py +++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py @@ -14,6 +14,10 @@ import frappe.defaults from erpnext.controllers.buying_controller import BuyingController from erpnext.accounts.party import get_party_account, get_due_date +form_grid_templates = { + "entries": "templates/form_grid/item_grid.html" +} + class PurchaseInvoice(BuyingController): tname = 'Purchase Invoice Item' fname = 'entries' @@ -30,6 +34,7 @@ class PurchaseInvoice(BuyingController): 'target_ref_field': 'amount', 'source_field': 'amount', 'percent_join_field': 'purchase_order', + 'overflow_type': 'billing' }] def validate(self): @@ -42,7 +47,6 @@ class PurchaseInvoice(BuyingController): self.pr_required() self.check_active_purchase_items() self.check_conversion_rate() - self.validate_bill_no() self.validate_credit_acc() self.clear_unallocated_advances("Purchase Invoice Advance", "advance_allocation_details") self.check_for_acc_head_of_supplier() @@ -56,6 +60,14 @@ class PurchaseInvoice(BuyingController): self.update_valuation_rate("entries") self.validate_multiple_billing("Purchase Receipt", "pr_detail", "amount", "purchase_receipt_details") + self.create_remarks() + + def create_remarks(self): + if not self.remarks: + if self.bill_no and self.bill_date: + self.remarks = _("Against Supplier Invoice {0} dated {1}").format(self.bill_no, formatdate(self.bill_date)) + else: + self.remarks = _("No Remarks") def set_missing_values(self, for_validate=False): if not self.credit_to: @@ -83,23 +95,6 @@ class PurchaseInvoice(BuyingController): if (self.currency == default_currency and flt(self.conversion_rate) != 1.00) or not self.conversion_rate or (self.currency != default_currency and flt(self.conversion_rate) == 1.00): throw(_("Conversion rate cannot be 0 or 1")) - def validate_bill_no(self): - if self.bill_no and self.bill_no.lower().strip() \ - not in ['na', 'not applicable', 'none']: - b_no = frappe.db.sql("""select bill_no, name, ifnull(is_opening,'') from `tabPurchase Invoice` - where bill_no = %s and credit_to = %s and docstatus = 1 and name != %s""", - (self.bill_no, self.credit_to, self.name)) - if b_no and cstr(b_no[0][2]) == cstr(self.is_opening): - throw(_("Bill No {0} already booked in Purchase Invoice {1}").format(cstr(b_no[0][0]), - cstr(b_no[0][1]))) - - if not self.remarks and self.bill_date: - self.remarks = (self.remarks or '') + "\n" \ - + _("Against Bill {0} dated {1}").format(self.bill_no, formatdate(self.bill_date)) - - if not self.remarks: - self.remarks = "No Remarks" - def validate_credit_acc(self): if frappe.db.get_value("Account", self.credit_to, "report_type") != "Balance Sheet": frappe.throw(_("Account must be a balance sheet account")) @@ -269,6 +264,9 @@ class PurchaseInvoice(BuyingController): auto_accounting_for_stock = \ cint(frappe.defaults.get_global_default("auto_accounting_for_stock")) + stock_received_but_not_billed = self.get_company_default("stock_received_but_not_billed") + expenses_included_in_valuation = self.get_company_default("expenses_included_in_valuation") + gl_entries = [] # parent's gl entry @@ -308,30 +306,10 @@ class PurchaseInvoice(BuyingController): (tax.add_deduct_tax == "Add" and 1 or -1) * flt(tax.tax_amount) # item gl entries - stock_item_and_auto_accounting_for_stock = False + negative_expense_to_be_booked = 0.0 stock_items = self.get_stock_items() for item in self.get("entries"): - if auto_accounting_for_stock and item.item_code in stock_items: - if flt(item.valuation_rate): - # if auto inventory accounting enabled and stock item, - # then do stock related gl entries - # expense will be booked in sales invoice - stock_item_and_auto_accounting_for_stock = True - - valuation_amt = flt(item.base_amount + item.item_tax_amount, - self.precision("base_amount", item)) - - gl_entries.append( - self.get_gl_dict({ - "account": item.expense_account, - "against": self.credit_to, - "debit": valuation_amt, - "remarks": self.remarks or "Accounting Entry for Stock" - }) - ) - - elif flt(item.base_amount): - # if not a stock item or auto inventory accounting disabled, book the expense + if flt(item.base_amount): gl_entries.append( self.get_gl_dict({ "account": item.expense_account, @@ -342,23 +320,52 @@ class PurchaseInvoice(BuyingController): }) ) - if stock_item_and_auto_accounting_for_stock and valuation_tax: + if auto_accounting_for_stock and item.item_code in stock_items and item.item_tax_amount: + # Post reverse entry for Stock-Received-But-Not-Billed if it is booked in Purchase Receipt + negative_expense_booked_in_pi = None + if item.purchase_receipt: + negative_expense_booked_in_pi = frappe.db.sql("""select name from `tabGL Entry` + where voucher_type='Purchase Receipt' and voucher_no=%s and account=%s""", + (item.purchase_receipt, expenses_included_in_valuation)) + + if not negative_expense_booked_in_pi: + gl_entries.append( + self.get_gl_dict({ + "account": stock_received_but_not_billed, + "against": self.credit_to, + "debit": flt(item.item_tax_amount, self.precision("item_tax_amount", item)), + "remarks": self.remarks or "Accounting Entry for Stock" + }) + ) + + negative_expense_to_be_booked += flt(item.item_tax_amount, self.precision("item_tax_amount", item)) + + if negative_expense_to_be_booked and valuation_tax: # credit valuation tax amount in "Expenses Included In Valuation" # this will balance out valuation amount included in cost of goods sold - expenses_included_in_valuation = \ - self.get_company_default("expenses_included_in_valuation") + total_valuation_amount = sum(valuation_tax.values()) + amount_including_divisional_loss = negative_expense_to_be_booked + i = 1 for cost_center, amount in valuation_tax.items(): + if i == len(valuation_tax): + applicable_amount = amount_including_divisional_loss + else: + applicable_amount = negative_expense_to_be_booked * (amount / total_valuation_amount) + amount_including_divisional_loss -= applicable_amount + gl_entries.append( self.get_gl_dict({ "account": expenses_included_in_valuation, "cost_center": cost_center, "against": self.credit_to, - "credit": amount, + "credit": applicable_amount, "remarks": self.remarks or "Accounting Entry for Stock" }) ) + i += 1 + # writeoff account includes petty difference in the invoice amount # and the amount that is paid if self.write_off_account and flt(self.write_off_amount): @@ -382,7 +389,7 @@ class PurchaseInvoice(BuyingController): self.update_prevdoc_status() self.update_billing_status_for_zero_amount_refdoc("Purchase Order") - self.make_cancel_gl_entries() + self.make_gl_entries_on_cancel() def on_update(self): pass diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice_list.html b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice_list.html new file mode 100644 index 0000000000..cccd38a67c --- /dev/null +++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice_list.html @@ -0,0 +1,45 @@ +
+
+
+ {%= list.get_avatar_and_id(doc) %} + + + {%= doc.supplier_name %} + {% if(doc.outstanding_amount > 0 && doc.docstatus==1) { %} + {% if(frappe.datetime.get_diff(doc.due_date) < 0) { %} + + {%= __("Overdue: ") + comment_when(doc.due_date) %} + + {% } else { %} + + {%= doc.get_formatted("due_date") %} + {% } %} + {% } %} + {% if(doc.outstanding_amount==0 && doc.docstatus==1) { %} + + {%= __("Paid") %} + + {% } %} + {% if(doc.docstatus===0) { %} + {%= __("Draft") %} + {% } %} +
+
+
+ {% var completed = cint((doc.grand_total - doc.outstanding_amount) * 100 / doc.grand_total), title = __("Outstanding Amount") + ": " + doc.get_formatted("outstanding_amount") %} + {% include "templates/form_grid/includes/progress.html" %} +
+
+
+ {%= doc.get_formatted("grand_total_import") %} +
+
+
diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice_list.js b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice_list.js index 61d2750c3e..d72176a197 100644 --- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice_list.js +++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice_list.js @@ -3,10 +3,6 @@ // render frappe.listview_settings['Purchase Invoice'] = { - add_fields: ["`tabPurchase Invoice`.grand_total", "`tabPurchase Invoice`.outstanding_amount"], - add_columns: [{"content":"paid_amount", width:"10%", type:"bar-graph", label: "Paid"}], - prepare_data: function(data) { - data.paid_amount = flt(data.grand_total) ? (((flt(data.grand_total) - - flt(data.outstanding_amount)) / flt(data.grand_total)) * 100) : 0; - } + add_fields: ["supplier", "supplier_name", "grand_total", "outstanding_amount", "due_date", "company", + "currency"] }; diff --git a/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py b/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py index ca73518bd9..bc97b91d30 100644 --- a/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py +++ b/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py @@ -9,7 +9,8 @@ import frappe.model import json from frappe.utils import cint import frappe.defaults -from erpnext.stock.doctype.purchase_receipt.test_purchase_receipt import set_perpetual_inventory +from erpnext.stock.doctype.purchase_receipt.test_purchase_receipt import set_perpetual_inventory, \ + test_records as pr_test_records test_dependencies = ["Item", "Cost Center"] test_ignore = ["Serial No"] @@ -57,9 +58,41 @@ class TestPurchaseInvoice(unittest.TestCase): expected_values = sorted([ ["_Test Supplier - _TC", 0, 720], ["Stock Received But Not Billed - _TC", 750.0, 0], + ["Expenses Included In Valuation - _TC", 0.0, 250.0], + ["_Test Account Shipping Charges - _TC", 100.0, 0], + ["_Test Account VAT - _TC", 120.0, 0], + ]) + + 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) + + set_perpetual_inventory(0) + + def test_gl_entries_with_auto_accounting_for_stock_against_pr(self): + set_perpetual_inventory(1) + self.assertEqual(cint(frappe.defaults.get_global_default("auto_accounting_for_stock")), 1) + + pr = frappe.copy_doc(pr_test_records[0]) + pr.submit() + + pi = frappe.copy_doc(test_records[1]) + for d in pi.get("entries"): + d.purchase_receipt = pr.name + pi.insert() + pi.submit() + + gl_entries = frappe.db.sql("""select account, debit, credit + from `tabGL Entry` where voucher_type='Purchase Invoice' and voucher_no=%s + order by account asc""", pi.name, as_dict=1) + self.assertTrue(gl_entries) + + expected_values = sorted([ + ["_Test Supplier - _TC", 0, 720], + ["Stock Received But Not Billed - _TC", 500.0, 0], ["_Test Account Shipping Charges - _TC", 100.0, 0], ["_Test Account VAT - _TC", 120.0, 0], - ["Expenses Included In Valuation - _TC", 0, 250.0], ]) for i, gle in enumerate(gl_entries): diff --git a/erpnext/accounts/doctype/purchase_invoice/test_records.json b/erpnext/accounts/doctype/purchase_invoice/test_records.json index 67a705cc4a..3ddbcc76e1 100644 --- a/erpnext/accounts/doctype/purchase_invoice/test_records.json +++ b/erpnext/accounts/doctype/purchase_invoice/test_records.json @@ -1,206 +1,208 @@ [ { - "bill_no": "NA", - "buying_price_list": "_Test Price List", - "company": "_Test Company", - "conversion_rate": 1, - "credit_to": "_Test Supplier - _TC", - "currency": "INR", - "doctype": "Purchase Invoice", + "bill_no": "NA", + "buying_price_list": "_Test Price List", + "company": "_Test Company", + "conversion_rate": 1, + "credit_to": "_Test Supplier - _TC", + "currency": "INR", + "doctype": "Purchase Invoice", "entries": [ { - "amount": 500, - "base_amount": 500, - "base_rate": 50, - "conversion_factor": 1.0, - "cost_center": "_Test Cost Center - _TC", - "doctype": "Purchase Invoice Item", - "expense_account": "_Test Account Cost for Goods Sold - _TC", - "item_code": "_Test Item Home Desktop 100", - "item_name": "_Test Item Home Desktop 100", - "item_tax_rate": "{\"_Test Account Excise Duty - _TC\": 10}", - "parentfield": "entries", - "qty": 10, - "rate": 50, + "amount": 500, + "base_amount": 500, + "base_rate": 50, + "conversion_factor": 1.0, + "cost_center": "_Test Cost Center - _TC", + "doctype": "Purchase Invoice Item", + "expense_account": "_Test Account Cost for Goods Sold - _TC", + "item_code": "_Test Item Home Desktop 100", + "item_name": "_Test Item Home Desktop 100", + "item_tax_rate": "{\"_Test Account Excise Duty - _TC\": 10}", + "parentfield": "entries", + "qty": 10, + "rate": 50, "uom": "_Test UOM" - }, + }, { - "amount": 750, - "base_amount": 750, - "base_rate": 150, - "conversion_factor": 1.0, - "cost_center": "_Test Cost Center - _TC", - "doctype": "Purchase Invoice Item", - "expense_account": "_Test Account Cost for Goods Sold - _TC", - "item_code": "_Test Item Home Desktop 200", - "item_name": "_Test Item Home Desktop 200", - "parentfield": "entries", - "qty": 5, - "rate": 150, + "amount": 750, + "base_amount": 750, + "base_rate": 150, + "conversion_factor": 1.0, + "cost_center": "_Test Cost Center - _TC", + "doctype": "Purchase Invoice Item", + "expense_account": "_Test Account Cost for Goods Sold - _TC", + "item_code": "_Test Item Home Desktop 200", + "item_name": "_Test Item Home Desktop 200", + "parentfield": "entries", + "qty": 5, + "rate": 150, "uom": "_Test UOM" } - ], - "fiscal_year": "_Test Fiscal Year 2013", - "grand_total_import": 0, - "naming_series": "BILL", + ], + "fiscal_year": "_Test Fiscal Year 2013", + "grand_total_import": 0, + "naming_series": "_T-BILL", "other_charges": [ { - "account_head": "_Test Account Shipping Charges - _TC", - "add_deduct_tax": "Add", - "category": "Valuation and Total", - "charge_type": "Actual", - "cost_center": "_Test Cost Center - _TC", - "description": "Shipping Charges", - "doctype": "Purchase Taxes and Charges", - "parentfield": "other_charges", + "account_head": "_Test Account Shipping Charges - _TC", + "add_deduct_tax": "Add", + "category": "Valuation and Total", + "charge_type": "Actual", + "cost_center": "_Test Cost Center - _TC", + "description": "Shipping Charges", + "doctype": "Purchase Taxes and Charges", + "parentfield": "other_charges", "rate": 100 - }, + }, { - "account_head": "_Test Account Customs Duty - _TC", - "add_deduct_tax": "Add", - "category": "Valuation", - "charge_type": "On Net Total", - "cost_center": "_Test Cost Center - _TC", - "description": "Customs Duty", - "doctype": "Purchase Taxes and Charges", - "parentfield": "other_charges", + "account_head": "_Test Account Customs Duty - _TC", + "add_deduct_tax": "Add", + "category": "Valuation", + "charge_type": "On Net Total", + "cost_center": "_Test Cost Center - _TC", + "description": "Customs Duty", + "doctype": "Purchase Taxes and Charges", + "parentfield": "other_charges", "rate": 10 - }, + }, { - "account_head": "_Test Account Excise Duty - _TC", - "add_deduct_tax": "Add", - "category": "Total", - "charge_type": "On Net Total", - "cost_center": "_Test Cost Center - _TC", - "description": "Excise Duty", - "doctype": "Purchase Taxes and Charges", - "parentfield": "other_charges", + "account_head": "_Test Account Excise Duty - _TC", + "add_deduct_tax": "Add", + "category": "Total", + "charge_type": "On Net Total", + "cost_center": "_Test Cost Center - _TC", + "description": "Excise Duty", + "doctype": "Purchase Taxes and Charges", + "parentfield": "other_charges", "rate": 12 - }, + }, { - "account_head": "_Test Account Education Cess - _TC", - "add_deduct_tax": "Add", - "category": "Total", - "charge_type": "On Previous Row Amount", - "cost_center": "_Test Cost Center - _TC", - "description": "Education Cess", - "doctype": "Purchase Taxes and Charges", - "parentfield": "other_charges", - "rate": 2, + "account_head": "_Test Account Education Cess - _TC", + "add_deduct_tax": "Add", + "category": "Total", + "charge_type": "On Previous Row Amount", + "cost_center": "_Test Cost Center - _TC", + "description": "Education Cess", + "doctype": "Purchase Taxes and Charges", + "parentfield": "other_charges", + "rate": 2, "row_id": 3 - }, + }, { - "account_head": "_Test Account S&H Education Cess - _TC", - "add_deduct_tax": "Add", - "category": "Total", - "charge_type": "On Previous Row Amount", - "cost_center": "_Test Cost Center - _TC", - "description": "S&H Education Cess", - "doctype": "Purchase Taxes and Charges", - "parentfield": "other_charges", - "rate": 1, + "account_head": "_Test Account S&H Education Cess - _TC", + "add_deduct_tax": "Add", + "category": "Total", + "charge_type": "On Previous Row Amount", + "cost_center": "_Test Cost Center - _TC", + "description": "S&H Education Cess", + "doctype": "Purchase Taxes and Charges", + "parentfield": "other_charges", + "rate": 1, "row_id": 3 - }, + }, { - "account_head": "_Test Account CST - _TC", - "add_deduct_tax": "Add", - "category": "Total", - "charge_type": "On Previous Row Total", - "cost_center": "_Test Cost Center - _TC", - "description": "CST", - "doctype": "Purchase Taxes and Charges", - "parentfield": "other_charges", - "rate": 2, + "account_head": "_Test Account CST - _TC", + "add_deduct_tax": "Add", + "category": "Total", + "charge_type": "On Previous Row Total", + "cost_center": "_Test Cost Center - _TC", + "description": "CST", + "doctype": "Purchase Taxes and Charges", + "parentfield": "other_charges", + "rate": 2, "row_id": 5 - }, + }, { - "account_head": "_Test Account VAT - _TC", - "add_deduct_tax": "Add", - "category": "Total", - "charge_type": "On Net Total", - "cost_center": "_Test Cost Center - _TC", - "description": "VAT", - "doctype": "Purchase Taxes and Charges", - "parentfield": "other_charges", + "account_head": "_Test Account VAT - _TC", + "add_deduct_tax": "Add", + "category": "Total", + "charge_type": "On Net Total", + "cost_center": "_Test Cost Center - _TC", + "description": "VAT", + "doctype": "Purchase Taxes and Charges", + "parentfield": "other_charges", "rate": 12.5 - }, + }, { - "account_head": "_Test Account Discount - _TC", - "add_deduct_tax": "Deduct", - "category": "Total", - "charge_type": "On Previous Row Total", - "cost_center": "_Test Cost Center - _TC", - "description": "Discount", - "doctype": "Purchase Taxes and Charges", - "parentfield": "other_charges", - "rate": 10, + "account_head": "_Test Account Discount - _TC", + "add_deduct_tax": "Deduct", + "category": "Total", + "charge_type": "On Previous Row Total", + "cost_center": "_Test Cost Center - _TC", + "description": "Discount", + "doctype": "Purchase Taxes and Charges", + "parentfield": "other_charges", + "rate": 10, "row_id": 7 } - ], - "posting_date": "2013-02-03", + ], + "posting_date": "2013-02-03", + "supplier": "_Test Supplier", "supplier_name": "_Test Supplier" - }, + }, { - "bill_no": "NA", - "buying_price_list": "_Test Price List", - "company": "_Test Company", - "conversion_rate": 1.0, - "credit_to": "_Test Supplier - _TC", - "currency": "INR", - "doctype": "Purchase Invoice", + "bill_no": "NA", + "buying_price_list": "_Test Price List", + "company": "_Test Company", + "conversion_rate": 1.0, + "credit_to": "_Test Supplier - _TC", + "currency": "INR", + "doctype": "Purchase Invoice", "entries": [ { - "conversion_factor": 1.0, - "cost_center": "_Test Cost Center - _TC", - "doctype": "Purchase Invoice Item", - "expense_account": "_Test Account Cost for Goods Sold - _TC", - "item_code": "_Test Item", - "item_name": "_Test Item", - "parentfield": "entries", - "qty": 10.0, - "rate": 50.0, + "conversion_factor": 1.0, + "cost_center": "_Test Cost Center - _TC", + "doctype": "Purchase Invoice Item", + "expense_account": "_Test Account Cost for Goods Sold - _TC", + "item_code": "_Test Item", + "item_name": "_Test Item", + "parentfield": "entries", + "qty": 10.0, + "rate": 50.0, "uom": "_Test UOM" } - ], - "fiscal_year": "_Test Fiscal Year 2013", - "grand_total_import": 0, - "naming_series": "_T-Purchase Invoice-", + ], + "fiscal_year": "_Test Fiscal Year 2013", + "grand_total_import": 0, + "naming_series": "_T-Purchase Invoice-", "other_charges": [ { - "account_head": "_Test Account Shipping Charges - _TC", - "add_deduct_tax": "Add", - "category": "Valuation and Total", - "charge_type": "Actual", - "cost_center": "_Test Cost Center - _TC", - "description": "Shipping Charges", - "doctype": "Purchase Taxes and Charges", - "parentfield": "other_charges", + "account_head": "_Test Account Shipping Charges - _TC", + "add_deduct_tax": "Add", + "category": "Valuation and Total", + "charge_type": "Actual", + "cost_center": "_Test Cost Center - _TC", + "description": "Shipping Charges", + "doctype": "Purchase Taxes and Charges", + "parentfield": "other_charges", "rate": 100.0 - }, + }, { - "account_head": "_Test Account VAT - _TC", - "add_deduct_tax": "Add", - "category": "Total", - "charge_type": "Actual", - "cost_center": "_Test Cost Center - _TC", - "description": "VAT", - "doctype": "Purchase Taxes and Charges", - "parentfield": "other_charges", + "account_head": "_Test Account VAT - _TC", + "add_deduct_tax": "Add", + "category": "Total", + "charge_type": "Actual", + "cost_center": "_Test Cost Center - _TC", + "description": "VAT", + "doctype": "Purchase Taxes and Charges", + "parentfield": "other_charges", "rate": 120.0 - }, + }, { - "account_head": "_Test Account Customs Duty - _TC", - "add_deduct_tax": "Add", - "category": "Valuation", - "charge_type": "Actual", - "cost_center": "_Test Cost Center - _TC", - "description": "Customs Duty", - "doctype": "Purchase Taxes and Charges", - "parentfield": "other_charges", + "account_head": "_Test Account Customs Duty - _TC", + "add_deduct_tax": "Add", + "category": "Valuation", + "charge_type": "Actual", + "cost_center": "_Test Cost Center - _TC", + "description": "Customs Duty", + "doctype": "Purchase Taxes and Charges", + "parentfield": "other_charges", "rate": 150.0 } - ], - "posting_date": "2013-02-03", + ], + "posting_date": "2013-02-03", + "supplier": "_Test Supplier", "supplier_name": "_Test Supplier" } -] \ No newline at end of file +] diff --git a/erpnext/accounts/doctype/purchase_invoice_item/purchase_invoice_item.json b/erpnext/accounts/doctype/purchase_invoice_item/purchase_invoice_item.json index 26f3be7889..c81d065f02 100755 --- a/erpnext/accounts/doctype/purchase_invoice_item/purchase_invoice_item.json +++ b/erpnext/accounts/doctype/purchase_invoice_item/purchase_invoice_item.json @@ -1,6 +1,6 @@ { "autoname": "EVD.######", - "creation": "2013-05-22 12:43:10.000000", + "creation": "2013-05-22 12:43:10", "docstatus": 0, "doctype": "DocType", "fields": [ @@ -8,7 +8,7 @@ "fieldname": "item_code", "fieldtype": "Link", "in_filter": 1, - "in_list_view": 0, + "in_list_view": 1, "label": "Item", "oldfieldname": "item_code", "oldfieldtype": "Link", @@ -52,7 +52,6 @@ { "fieldname": "quantity_and_rate", "fieldtype": "Section Break", - "in_list_view": 0, "label": "Quantity and Rate", "permlevel": 0 }, @@ -76,7 +75,7 @@ { "fieldname": "uom", "fieldtype": "Link", - "in_list_view": 0, + "in_list_view": 1, "label": "UOM", "options": "UOM", "permlevel": 0, @@ -86,7 +85,6 @@ { "fieldname": "conversion_factor", "fieldtype": "Float", - "in_list_view": 0, "label": "Conversion Factor", "permlevel": 0, "print_hide": 1, @@ -100,7 +98,6 @@ { "fieldname": "price_list_rate", "fieldtype": "Currency", - "in_list_view": 0, "label": "Price List Rate", "options": "currency", "permlevel": 0, @@ -109,8 +106,8 @@ }, { "fieldname": "discount_percentage", - "fieldtype": "Float", - "in_list_view": 0, + "fieldtype": "Percent", + "in_list_view": 1, "label": "Discount %", "permlevel": 0, "print_hide": 0, @@ -124,7 +121,6 @@ { "fieldname": "base_price_list_rate", "fieldtype": "Currency", - "in_list_view": 0, "label": "Price List Rate (Company Currency)", "options": "Company:company:default_currency", "permlevel": 0, @@ -169,7 +165,6 @@ { "fieldname": "base_rate", "fieldtype": "Currency", - "in_list_view": 0, "label": "Rate (Company Currency)", "oldfieldname": "rate", "oldfieldtype": "Currency", @@ -182,7 +177,6 @@ { "fieldname": "base_amount", "fieldtype": "Currency", - "in_list_view": 0, "label": "Amount (Company Currency)", "oldfieldname": "amount", "oldfieldtype": "Currency", @@ -193,17 +187,9 @@ "reqd": 1 }, { - "fieldname": "pricing_rule_for_price", + "fieldname": "pricing_rule", "fieldtype": "Link", - "label": "Pricing Rule For Price", - "options": "Pricing Rule", - "permlevel": 0, - "read_only": 1 - }, - { - "fieldname": "pricing_rule_for_discount", - "fieldtype": "Link", - "label": "Pricing Rule For Discount", + "label": "Pricing Rule", "options": "Pricing Rule", "permlevel": 0, "read_only": 1 @@ -211,14 +197,12 @@ { "fieldname": "accounting", "fieldtype": "Section Break", - "in_list_view": 0, "label": "Accounting", "permlevel": 0 }, { "fieldname": "expense_account", "fieldtype": "Link", - "in_list_view": 0, "label": "Expense Head", "oldfieldname": "expense_head", "oldfieldtype": "Link", @@ -235,11 +219,20 @@ "fieldtype": "Column Break", "permlevel": 0 }, + { + "fieldname": "project_name", + "fieldtype": "Link", + "in_filter": 1, + "label": "Project Name", + "options": "Project", + "permlevel": 0, + "print_hide": 1, + "read_only": 0 + }, { "default": ":Company", "fieldname": "cost_center", "fieldtype": "Link", - "in_list_view": 0, "label": "Cost Center", "oldfieldname": "cost_center", "oldfieldtype": "Link", @@ -253,26 +246,13 @@ { "fieldname": "reference", "fieldtype": "Section Break", - "in_list_view": 0, "label": "Reference", "permlevel": 0 }, - { - "fieldname": "project_name", - "fieldtype": "Link", - "in_filter": 1, - "in_list_view": 0, - "label": "Project Name", - "options": "Project", - "permlevel": 0, - "print_hide": 1, - "read_only": 0 - }, { "fieldname": "brand", "fieldtype": "Data", "hidden": 1, - "in_list_view": 0, "label": "Brand", "oldfieldname": "brand", "oldfieldtype": "Data", @@ -286,7 +266,6 @@ "fieldtype": "Link", "hidden": 1, "in_filter": 1, - "in_list_view": 0, "label": "Item Group", "oldfieldname": "item_group", "oldfieldtype": "Link", @@ -301,7 +280,6 @@ "fieldname": "item_tax_rate", "fieldtype": "Small Text", "hidden": 1, - "in_list_view": 0, "label": "Item Tax Rate", "oldfieldname": "item_tax_rate", "oldfieldtype": "Small Text", @@ -314,7 +292,6 @@ "fieldname": "item_tax_amount", "fieldtype": "Currency", "hidden": 1, - "in_list_view": 0, "label": "Item Tax Amount", "no_copy": 1, "options": "Company:company:default_currency", @@ -325,28 +302,10 @@ "search_index": 0, "width": "150px" }, - { - "allow_on_submit": 1, - "fieldname": "page_break", - "fieldtype": "Check", - "in_list_view": 0, - "label": "Page Break", - "no_copy": 1, - "permlevel": 0, - "print_hide": 1, - "read_only": 0, - "report_hide": 1 - }, - { - "fieldname": "col_break6", - "fieldtype": "Column Break", - "permlevel": 0 - }, { "fieldname": "purchase_order", "fieldtype": "Link", "in_filter": 1, - "in_list_view": 0, "label": "Purchase Order", "no_copy": 1, "oldfieldname": "purchase_order", @@ -357,12 +316,16 @@ "read_only": 1, "search_index": 1 }, + { + "fieldname": "col_break6", + "fieldtype": "Column Break", + "permlevel": 0 + }, { "fieldname": "po_detail", "fieldtype": "Data", "hidden": 1, "in_filter": 1, - "in_list_view": 0, "label": "Purchase Order Item", "no_copy": 1, "oldfieldname": "po_detail", @@ -376,7 +339,6 @@ "fieldname": "purchase_receipt", "fieldtype": "Link", "in_filter": 1, - "in_list_view": 0, "label": "Purchase Receipt", "no_copy": 1, "oldfieldname": "purchase_receipt", @@ -387,12 +349,22 @@ "read_only": 1, "search_index": 1 }, + { + "allow_on_submit": 1, + "fieldname": "page_break", + "fieldtype": "Check", + "label": "Page Break", + "no_copy": 1, + "permlevel": 0, + "print_hide": 1, + "read_only": 0, + "report_hide": 1 + }, { "fieldname": "pr_detail", "fieldtype": "Data", "hidden": 1, "in_filter": 1, - "in_list_view": 0, "label": "PR Detail", "no_copy": 1, "oldfieldname": "pr_detail", @@ -406,7 +378,6 @@ "fieldname": "valuation_rate", "fieldtype": "Currency", "hidden": 1, - "in_list_view": 0, "label": "Valuation Rate", "no_copy": 1, "options": "Company:company:default_currency", @@ -418,7 +389,6 @@ "fieldname": "rm_supp_cost", "fieldtype": "Currency", "hidden": 1, - "in_list_view": 0, "label": "Raw Materials Supplied Cost", "no_copy": 1, "options": "Company:company:default_currency", @@ -429,9 +399,12 @@ ], "idx": 1, "istable": 1, - "modified": "2014-02-28 11:27:53.000000", + "modified": "2014-09-08 08:06:30.027289", "modified_by": "Administrator", "module": "Accounts", "name": "Purchase Invoice Item", - "owner": "Administrator" + "owner": "Administrator", + "permissions": [], + "sort_field": "modified", + "sort_order": "DESC" } \ No newline at end of file diff --git a/erpnext/accounts/doctype/purchase_taxes_and_charges/purchase_taxes_and_charges.json b/erpnext/accounts/doctype/purchase_taxes_and_charges/purchase_taxes_and_charges.json index 8bc96e210b..6079fa28d7 100644 --- a/erpnext/accounts/doctype/purchase_taxes_and_charges/purchase_taxes_and_charges.json +++ b/erpnext/accounts/doctype/purchase_taxes_and_charges/purchase_taxes_and_charges.json @@ -1,431 +1,164 @@ { - "_last_update": null, - "_user_tags": null, - "allow_attach": null, - "allow_copy": null, - "allow_email": null, - "allow_import": null, - "allow_print": null, - "allow_rename": null, - "allow_trash": null, - "autoname": "PVTD.######", - "change_log": null, - "client_script": null, - "client_script_core": null, - "client_string": null, - "colour": null, - "creation": "2013-05-21 16:16:04", - "custom": null, - "default_print_format": null, - "description": null, - "docstatus": 0, - "doctype": "DocType", - "document_type": null, - "dt_template": null, + "autoname": "PVTD.######", + "creation": "2013-05-21 16:16:04", + "docstatus": 0, + "doctype": "DocType", "fields": [ { - "allow_on_submit": null, - "default": "Valuation and Total", - "depends_on": null, - "description": null, - "fieldname": "category", - "fieldtype": "Select", - "hidden": null, - "ignore_restrictions": null, - "in_filter": null, - "in_list_view": 0, - "label": "Consider Tax or Charge for", - "no_column": null, - "no_copy": null, - "oldfieldname": "category", - "oldfieldtype": "Select", - "options": "Valuation and Total\nValuation\nTotal", - "permlevel": 0, - "print_hide": null, - "print_width": null, - "read_only": 0, - "report_hide": null, - "reqd": 1, - "search_index": null, - "set_only_once": null, - "trigger": null, - "width": null - }, + "default": "Valuation and Total", + "fieldname": "category", + "fieldtype": "Select", + "in_list_view": 0, + "label": "Consider Tax or Charge for", + "oldfieldname": "category", + "oldfieldtype": "Select", + "options": "Valuation and Total\nValuation\nTotal", + "permlevel": 0, + "read_only": 0, + "reqd": 1 + }, { - "allow_on_submit": null, - "default": "Add", - "depends_on": null, - "description": null, - "fieldname": "add_deduct_tax", - "fieldtype": "Select", - "hidden": null, - "ignore_restrictions": null, - "in_filter": null, - "in_list_view": null, - "label": "Add or Deduct", - "no_column": null, - "no_copy": null, - "oldfieldname": "add_deduct_tax", - "oldfieldtype": "Select", - "options": "Add\nDeduct", - "permlevel": 0, - "print_hide": null, - "print_width": null, - "read_only": 0, - "report_hide": null, - "reqd": 1, - "search_index": null, - "set_only_once": null, - "trigger": null, - "width": null - }, + "default": "Add", + "fieldname": "add_deduct_tax", + "fieldtype": "Select", + "label": "Add or Deduct", + "oldfieldname": "add_deduct_tax", + "oldfieldtype": "Select", + "options": "Add\nDeduct", + "permlevel": 0, + "read_only": 0, + "reqd": 1 + }, { - "allow_on_submit": null, - "default": null, - "depends_on": null, - "description": null, - "fieldname": "charge_type", - "fieldtype": "Select", - "hidden": null, - "ignore_restrictions": null, - "in_filter": null, - "in_list_view": 1, - "label": "Type", - "no_column": null, - "no_copy": null, - "oldfieldname": "charge_type", - "oldfieldtype": "Select", - "options": "\nActual\nOn Net Total\nOn Previous Row Amount\nOn Previous Row Total", - "permlevel": 0, - "print_hide": null, - "print_width": null, - "read_only": 0, - "report_hide": null, - "reqd": 1, - "search_index": null, - "set_only_once": null, - "trigger": null, - "width": null - }, + "fieldname": "charge_type", + "fieldtype": "Select", + "in_list_view": 1, + "label": "Type", + "oldfieldname": "charge_type", + "oldfieldtype": "Select", + "options": "\nActual\nOn Net Total\nOn Previous Row Amount\nOn Previous Row Total", + "permlevel": 0, + "read_only": 0, + "reqd": 1 + }, { - "allow_on_submit": null, - "default": null, - "depends_on": "eval:[\"On Previous Row Amount\", \"On Previous Row Total\"].indexOf(doc.charge_type)!==-1", - "description": null, - "fieldname": "row_id", - "fieldtype": "Data", - "hidden": 0, - "ignore_restrictions": null, - "in_filter": null, - "in_list_view": null, - "label": "Reference Row #", - "no_column": null, - "no_copy": null, - "oldfieldname": "row_id", - "oldfieldtype": "Data", - "options": null, - "permlevel": 0, - "print_hide": null, - "print_width": null, - "read_only": 0, - "report_hide": null, - "reqd": null, - "search_index": null, - "set_only_once": null, - "trigger": null, - "width": null - }, + "depends_on": "eval:[\"On Previous Row Amount\", \"On Previous Row Total\"].indexOf(doc.charge_type)!==-1", + "fieldname": "row_id", + "fieldtype": "Data", + "hidden": 0, + "label": "Reference Row #", + "oldfieldname": "row_id", + "oldfieldtype": "Data", + "permlevel": 0, + "read_only": 0 + }, { - "allow_on_submit": null, - "default": null, - "depends_on": null, - "description": null, - "fieldname": "description", - "fieldtype": "Small Text", - "hidden": null, - "ignore_restrictions": null, - "in_filter": null, - "in_list_view": 1, - "label": "Description", - "no_column": null, - "no_copy": null, - "oldfieldname": "description", - "oldfieldtype": "Small Text", - "options": null, - "permlevel": 0, - "print_hide": null, - "print_width": "300px", - "read_only": 0, - "report_hide": null, - "reqd": 1, - "search_index": null, - "set_only_once": null, - "trigger": null, + "fieldname": "description", + "fieldtype": "Small Text", + "in_list_view": 1, + "label": "Description", + "oldfieldname": "description", + "oldfieldtype": "Small Text", + "permlevel": 0, + "print_width": "300px", + "read_only": 0, + "reqd": 1, "width": "300px" - }, + }, { - "allow_on_submit": null, - "default": null, - "depends_on": null, - "description": null, - "fieldname": "col_break1", - "fieldtype": "Column Break", - "hidden": null, - "ignore_restrictions": null, - "in_filter": null, - "in_list_view": null, - "label": null, - "no_column": null, - "no_copy": null, - "oldfieldname": null, - "oldfieldtype": null, - "options": null, - "permlevel": 0, - "print_hide": null, - "print_width": null, - "read_only": null, - "report_hide": null, - "reqd": null, - "search_index": null, - "set_only_once": null, - "trigger": null, - "width": null - }, + "fieldname": "col_break1", + "fieldtype": "Column Break", + "permlevel": 0 + }, { - "allow_on_submit": null, - "default": null, - "depends_on": null, - "description": null, - "fieldname": "account_head", - "fieldtype": "Link", - "hidden": null, - "ignore_restrictions": null, - "in_filter": null, - "in_list_view": 0, - "label": "Account Head", - "no_column": null, - "no_copy": null, - "oldfieldname": "account_head", - "oldfieldtype": "Link", - "options": "Account", - "permlevel": 0, - "print_hide": null, - "print_width": null, - "read_only": 0, - "report_hide": null, - "reqd": 1, - "search_index": null, - "set_only_once": null, - "trigger": null, - "width": null - }, + "fieldname": "account_head", + "fieldtype": "Link", + "in_list_view": 0, + "label": "Account Head", + "oldfieldname": "account_head", + "oldfieldtype": "Link", + "options": "Account", + "permlevel": 0, + "read_only": 0, + "reqd": 1 + }, { - "allow_on_submit": null, - "default": ":Company", - "depends_on": null, - "description": null, - "fieldname": "cost_center", - "fieldtype": "Link", - "hidden": null, - "ignore_restrictions": null, - "in_filter": null, - "in_list_view": 0, - "label": "Cost Center", - "no_column": null, - "no_copy": null, - "oldfieldname": "cost_center", - "oldfieldtype": "Link", - "options": "Cost Center", - "permlevel": 0, - "print_hide": null, - "print_width": null, - "read_only": 0, - "report_hide": null, - "reqd": null, - "search_index": null, - "set_only_once": null, - "trigger": null, - "width": null - }, + "default": ":Company", + "fieldname": "cost_center", + "fieldtype": "Link", + "in_list_view": 0, + "label": "Cost Center", + "oldfieldname": "cost_center", + "oldfieldtype": "Link", + "options": "Cost Center", + "permlevel": 0, + "read_only": 0 + }, { - "allow_on_submit": null, - "default": null, - "depends_on": null, - "description": null, - "fieldname": "rate", - "fieldtype": "Float", - "hidden": null, - "ignore_restrictions": null, - "in_filter": null, - "in_list_view": 1, - "label": "Rate", - "no_column": null, - "no_copy": null, - "oldfieldname": "rate", - "oldfieldtype": "Currency", - "options": null, - "permlevel": 0, - "print_hide": null, - "print_width": null, - "read_only": 0, - "report_hide": null, - "reqd": 0, - "search_index": null, - "set_only_once": null, - "trigger": null, - "width": null - }, + "fieldname": "rate", + "fieldtype": "Float", + "in_list_view": 1, + "label": "Rate", + "oldfieldname": "rate", + "oldfieldtype": "Currency", + "permlevel": 0, + "read_only": 0, + "reqd": 0 + }, { - "allow_on_submit": null, - "default": null, - "depends_on": null, - "description": null, - "fieldname": "tax_amount", - "fieldtype": "Currency", - "hidden": null, - "ignore_restrictions": null, - "in_filter": null, - "in_list_view": 1, - "label": "Amount", - "no_column": null, - "no_copy": null, - "oldfieldname": "tax_amount", - "oldfieldtype": "Currency", - "options": "Company:company:default_currency", - "permlevel": 0, - "print_hide": null, - "print_width": null, - "read_only": 1, - "report_hide": null, - "reqd": 0, - "search_index": null, - "set_only_once": null, - "trigger": null, - "width": null - }, + "fieldname": "tax_amount", + "fieldtype": "Currency", + "in_list_view": 1, + "label": "Amount", + "oldfieldname": "tax_amount", + "oldfieldtype": "Currency", + "options": "Company:company:default_currency", + "permlevel": 0, + "read_only": 1, + "reqd": 0 + }, { - "allow_on_submit": null, - "default": null, - "depends_on": null, - "description": null, - "fieldname": "total", - "fieldtype": "Currency", - "hidden": null, - "ignore_restrictions": null, - "in_filter": null, - "in_list_view": null, - "label": "Total", - "no_column": null, - "no_copy": null, - "oldfieldname": "total", - "oldfieldtype": "Currency", - "options": "Company:company:default_currency", - "permlevel": 0, - "print_hide": null, - "print_width": null, - "read_only": 1, - "report_hide": null, - "reqd": null, - "search_index": null, - "set_only_once": null, - "trigger": null, - "width": null - }, + "fieldname": "total", + "fieldtype": "Currency", + "label": "Total", + "oldfieldname": "total", + "oldfieldtype": "Currency", + "options": "Company:company:default_currency", + "permlevel": 0, + "read_only": 1 + }, { - "allow_on_submit": null, - "default": null, - "depends_on": null, - "description": null, - "fieldname": "item_wise_tax_detail", - "fieldtype": "Small Text", - "hidden": 1, - "ignore_restrictions": null, - "in_filter": null, - "in_list_view": null, - "label": "Item Wise Tax Detail ", - "no_column": null, - "no_copy": null, - "oldfieldname": "item_wise_tax_detail", - "oldfieldtype": "Small Text", - "options": null, - "permlevel": 0, - "print_hide": 1, - "print_width": null, - "read_only": 1, - "report_hide": null, - "reqd": null, - "search_index": null, - "set_only_once": null, - "trigger": null, - "width": null - }, + "fieldname": "item_wise_tax_detail", + "fieldtype": "Small Text", + "hidden": 1, + "label": "Item Wise Tax Detail ", + "oldfieldname": "item_wise_tax_detail", + "oldfieldtype": "Small Text", + "permlevel": 0, + "print_hide": 1, + "read_only": 1 + }, { - "allow_on_submit": null, - "default": null, - "depends_on": null, - "description": null, - "fieldname": "parenttype", - "fieldtype": "Data", - "hidden": 1, - "ignore_restrictions": null, - "in_filter": 1, - "in_list_view": null, - "label": "Parenttype", - "no_column": null, - "no_copy": null, - "oldfieldname": "parenttype", - "oldfieldtype": "Data", - "options": null, - "permlevel": 0, - "print_hide": 1, - "print_width": null, - "read_only": 0, - "report_hide": null, - "reqd": null, - "search_index": 0, - "set_only_once": null, - "trigger": null, - "width": null + "fieldname": "parenttype", + "fieldtype": "Data", + "hidden": 1, + "in_filter": 1, + "label": "Parenttype", + "oldfieldname": "parenttype", + "oldfieldtype": "Data", + "permlevel": 0, + "print_hide": 1, + "read_only": 0, + "search_index": 0 } - ], - "hide_heading": 1, - "hide_toolbar": null, - "icon": null, - "idx": 1, - "in_create": null, - "in_dialog": null, - "is_submittable": null, - "is_transaction_doc": null, - "issingle": null, - "istable": 1, - "max_attachments": null, - "menu_index": null, - "modified": "2014-04-15 09:48:45.892548", - "modified_by": "Administrator", - "module": "Accounts", - "name": "Purchase Taxes and Charges", - "name_case": null, - "owner": "Administrator", - "parent": null, - "parent_node": null, - "parentfield": null, - "parenttype": null, - "permissions": [], - "plugin": null, - "print_outline": null, - "read_only": null, - "read_only_onload": null, - "search_fields": null, - "section_style": null, - "server_code": null, - "server_code_compiled": null, - "server_code_core": null, - "server_code_error": null, - "show_in_menu": null, - "smallicon": null, - "subject": null, - "tag_fields": null, - "title_field": null, - "use_template": null, - "version": null -} \ No newline at end of file + ], + "hide_heading": 1, + "idx": 1, + "istable": 1, + "modified": "2014-05-30 03:43:32.494112", + "modified_by": "Administrator", + "module": "Accounts", + "name": "Purchase Taxes and Charges", + "owner": "Administrator", + "permissions": [] +} diff --git a/erpnext/accounts/doctype/sales_invoice/pos.js b/erpnext/accounts/doctype/sales_invoice/pos.js index 2dcfc68a9e..8c6e3cdb82 100644 --- a/erpnext/accounts/doctype/sales_invoice/pos.js +++ b/erpnext/accounts/doctype/sales_invoice/pos.js @@ -21,9 +21,9 @@ erpnext.POS = Class.extend({ \ '+__("Item")+'\ \ - Qty\ + Qty\ \ - Rate\ + Rate\ \ \ \ @@ -367,10 +367,8 @@ erpnext.POS = Class.extend({ this.hide_payment_button(); // If quotation to is not Customer then remove party - if (this.frm.doctype == "Quotation") { + if (this.frm.doctype == "Quotation" && this.frm.doc.quotation_to!="Customer") { this.party_field.$wrapper.remove(); - if (this.frm.doc.quotation_to == "Customer") - this.make_party(); } }, refresh_item_list: function() { @@ -389,14 +387,19 @@ erpnext.POS = Class.extend({ $(repl('\ %(item_code)s%(item_name)s\ - \ + \
\ \
\ \ - \ - \ + \ + \ +
' + +__("Stock: ")+'%(actual_qty)s%(projected_qty)s
\ + \ + \
\ \
\ @@ -407,6 +410,9 @@ erpnext.POS = Class.extend({ item_code: d.item_code, item_name: d.item_name===d.item_code ? "" : ("
" + d.item_name), qty: d.qty, + actual_qty: d.actual_qty, + projected_qty: d.projected_qty ? (" (" + d.projected_qty + ")") : "", rate: format_currency(d.rate, me.frm.doc.currency), amount: format_currency(d.amount, me.frm.doc.currency) } @@ -481,7 +487,11 @@ erpnext.POS = Class.extend({ }); me.refresh_delete_btn(); - this.barcode.$input.focus(); + if(me.frm.doc[this.party]) { + this.barcode.$input.focus(); + } else { + this.party_field.$input.focus(); + } }, increase_decrease_qty: function(tr, operation) { var item_code = tr.attr("id"); @@ -489,7 +499,7 @@ erpnext.POS = Class.extend({ if (operation == "increase-qty") this.update_qty(item_code, item_qty + 1); - else if (operation == "decrease-qty" && item_qty != 1) + else if (operation == "decrease-qty" && item_qty != 0) this.update_qty(item_code, item_qty - 1); }, disable_text_box_and_button: function() { diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.js b/erpnext/accounts/doctype/sales_invoice/sales_invoice.js index a5707bb222..73832cec65 100644 --- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.js +++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.js @@ -11,7 +11,6 @@ cur_frm.pformat.print_heading = 'Invoice'; {% include 'selling/sales_common.js' %}; {% include 'accounts/doctype/sales_taxes_and_charges_master/sales_taxes_and_charges_master.js' %} -{% include 'utilities/doctype/sms_control/sms_control.js' %} {% include 'accounts/doctype/sales_invoice/pos.js' %} frappe.provide("erpnext.accounts"); @@ -25,7 +24,7 @@ erpnext.accounts.SalesInvoiceController = erpnext.selling.SellingController.exte } // toggle to pos view if is_pos is 1 in user_defaults - if ((cint(frappe.defaults.get_user_defaults("is_pos"))===1 || this.frm.doc.is_pos)) { + if ((is_null(this.frm.doc.is_pos) && cint(frappe.defaults.get_user_default("is_pos"))===1) || this.frm.doc.is_pos) { if(this.frm.doc.__islocal && !this.frm.doc.amended_from && !this.frm.doc.customer) { this.frm.set_value("is_pos", 1); this.is_pos(function() { @@ -35,8 +34,9 @@ erpnext.accounts.SalesInvoiceController = erpnext.selling.SellingController.exte } } - // if document is POS then change default print format to "POS Invoice" - if(cur_frm.doc.is_pos && cur_frm.doc.docstatus===1) { + // if document is POS then change default print format to "POS Invoice" if no default is specified + if(cur_frm.doc.is_pos && cur_frm.doc.docstatus===1 && cint(frappe.defaults.get_user_defaults("fs_pos_view"))===1 + && !locals.DocType[cur_frm.doctype].default_print_format) { locals.DocType[cur_frm.doctype].default_print_format = "POS Invoice"; cur_frm.setup_print_layout(); } @@ -73,12 +73,14 @@ erpnext.accounts.SalesInvoiceController = erpnext.selling.SellingController.exte return item.delivery_note ? true : false; }); - if(!from_delivery_note) - cur_frm.appframe.add_primary_action(__('Make Delivery'), cur_frm.cscript['Make Delivery Note']) + if(!from_delivery_note) { + cur_frm.appframe.add_primary_action(__('Make Delivery'), cur_frm.cscript['Make Delivery Note'], "icon-truck") + } } - if(doc.outstanding_amount!=0) - cur_frm.appframe.add_primary_action(__('Make Payment Entry'), cur_frm.cscript.make_bank_voucher); + if(doc.outstanding_amount!=0) { + cur_frm.appframe.add_primary_action(__('Make Payment Entry'), cur_frm.cscript.make_bank_voucher, "icon-money"); + } } // Show buttons only when pos view is active @@ -102,7 +104,7 @@ erpnext.accounts.SalesInvoiceController = erpnext.selling.SellingController.exte company: cur_frm.doc.company } }) - }); + }, "icon-download", "btn-default"); }, delivery_note_btn: function() { @@ -122,7 +124,7 @@ erpnext.accounts.SalesInvoiceController = erpnext.selling.SellingController.exte }; } }); - }); + }, "icon-download", "btn-default"); }, tc_name: function() { @@ -155,8 +157,9 @@ erpnext.accounts.SalesInvoiceController = erpnext.selling.SellingController.exte }, customer: function() { - if(this.frm.updating_party_details) - return; + var me = this; + if(this.frm.updating_party_details) return; + erpnext.utils.get_party_details(this.frm, "erpnext.accounts.party.get_party_details", { posting_date: this.frm.doc.posting_date, @@ -164,7 +167,9 @@ erpnext.accounts.SalesInvoiceController = erpnext.selling.SellingController.exte party_type: "Customer", account: this.frm.doc.debit_to, price_list: this.frm.doc.selling_price_list, - }) + }, function() { + me.apply_pricing_rule(); + }) }, debit_to: function() { @@ -181,8 +186,9 @@ erpnext.accounts.SalesInvoiceController = erpnext.selling.SellingController.exte frappe.model.round_floats_in(this.frm.doc, ["grand_total", "paid_amount"]); // this will make outstanding amount 0 this.frm.set_value("write_off_amount", - flt(this.frm.doc.grand_total - this.frm.doc.paid_amount), - precision("write_off_amount")); + flt(this.frm.doc.grand_total - this.frm.doc.paid_amount, + precision("write_off_amount")) + ); } this.calculate_outstanding_amount(false); @@ -222,7 +228,7 @@ cur_frm.cscript.hide_fields = function(doc) { par_flds = ['project_name', 'due_date', 'is_opening', 'source', 'total_advance', 'gross_profit', 'gross_profit_percent', 'get_advances_received', 'advance_adjustment_details', 'sales_partner', 'commission_rate', - 'total_commission', 'advances']; + 'total_commission', 'advances', 'from_date', 'to_date']; item_flds_normal = ['sales_order', 'delivery_note'] @@ -393,9 +399,9 @@ cur_frm.cscript.on_submit = function(doc, cdt, cdn) { }) } -cur_frm.cscript.convert_into_recurring_invoice = function(doc, dt, dn) { +cur_frm.cscript.is_recurring = function(doc, dt, dn) { // set default values for recurring invoices - if(doc.convert_into_recurring_invoice) { + if(doc.is_recurring) { var owner_email = doc.owner=="Administrator" ? frappe.user_info("Administrator").email : doc.owner; @@ -408,18 +414,24 @@ cur_frm.cscript.convert_into_recurring_invoice = function(doc, dt, dn) { refresh_many(["notification_email_address", "repeat_on_day_of_month"]); } -cur_frm.cscript.invoice_period_from_date = function(doc, dt, dn) { - // set invoice_period_to_date - if(doc.invoice_period_from_date) { +cur_frm.cscript.from_date = function(doc, dt, dn) { + // set to_date + if(doc.from_date) { var recurring_type_map = {'Monthly': 1, 'Quarterly': 3, 'Half-yearly': 6, 'Yearly': 12}; var months = recurring_type_map[doc.recurring_type]; if(months) { - var to_date = frappe.datetime.add_months(doc.invoice_period_from_date, + var to_date = frappe.datetime.add_months(doc.from_date, months); - doc.invoice_period_to_date = frappe.datetime.add_days(to_date, -1); - refresh_field('invoice_period_to_date'); + doc.to_date = frappe.datetime.add_days(to_date, -1); + refresh_field('to_date'); } } } + +cur_frm.cscript.send_sms = function() { + frappe.require("assets/erpnext/js/sms_manager.js"); + var sms_man = new SMSManager(cur_frm.doc); +} + diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.json b/erpnext/accounts/doctype/sales_invoice/sales_invoice.json index ad326df956..c26583b737 100644 --- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.json +++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.json @@ -71,7 +71,7 @@ }, { "fieldname": "contact_mobile", - "fieldtype": "Text", + "fieldtype": "Small Text", "hidden": 1, "label": "Mobile No", "permlevel": 0, @@ -79,13 +79,24 @@ }, { "fieldname": "contact_email", - "fieldtype": "Text", + "fieldtype": "Small Text", "hidden": 1, "label": "Contact Email", "permlevel": 0, "print_hide": 1, "read_only": 1 }, + { + "fieldname": "mode_of_payment", + "fieldtype": "Link", + "label": "Mode of Payment", + "no_copy": 0, + "oldfieldname": "mode_of_payment", + "oldfieldtype": "Select", + "options": "Mode of Payment", + "permlevel": 0, + "read_only": 0 + }, { "fieldname": "column_break1", "fieldtype": "Column Break", @@ -103,19 +114,6 @@ "print_hide": 1, "read_only": 0 }, - { - "fieldname": "amended_from", - "fieldtype": "Link", - "ignore_restrictions": 1, - "label": "Amended From", - "no_copy": 1, - "oldfieldname": "amended_from", - "oldfieldtype": "Link", - "options": "Sales Invoice", - "permlevel": 0, - "print_hide": 1, - "read_only": 1 - }, { "fieldname": "company", "fieldtype": "Link", @@ -130,12 +128,25 @@ "reqd": 1, "search_index": 0 }, + { + "fieldname": "amended_from", + "fieldtype": "Link", + "ignore_user_permissions": 1, + "label": "Amended From", + "no_copy": 1, + "oldfieldname": "amended_from", + "oldfieldtype": "Link", + "options": "Sales Invoice", + "permlevel": 0, + "print_hide": 1, + "read_only": 1 + }, { "default": "Today", "fieldname": "posting_date", "fieldtype": "Date", "in_filter": 1, - "label": "Posting Date", + "label": "Date", "no_copy": 1, "oldfieldname": "posting_date", "oldfieldtype": "Date", @@ -159,14 +170,27 @@ "search_index": 0 }, { - "fieldname": "mode_of_payment", - "fieldtype": "Link", - "label": "Mode of Payment", - "no_copy": 0, - "oldfieldname": "mode_of_payment", - "oldfieldtype": "Select", - "options": "Mode of Payment", + "allow_on_submit": 1, + "depends_on": "", + "description": "Start date of current invoice's period", + "fieldname": "from_date", + "fieldtype": "Date", + "label": "From", + "no_copy": 1, "permlevel": 0, + "print_hide": 0, + "read_only": 0 + }, + { + "allow_on_submit": 1, + "depends_on": "", + "description": "End date of current invoice's period", + "fieldname": "to_date", + "fieldtype": "Date", + "label": "To", + "no_copy": 1, + "permlevel": 0, + "print_hide": 0, "read_only": 0 }, { @@ -241,6 +265,14 @@ "read_only": 0, "reqd": 1 }, + { + "fieldname": "ignore_pricing_rule", + "fieldtype": "Check", + "label": "Ignore Pricing Rule", + "no_copy": 1, + "permlevel": 1, + "print_hide": 1 + }, { "fieldname": "items", "fieldtype": "Section Break", @@ -303,20 +335,6 @@ "fieldtype": "Section Break", "permlevel": 0 }, - { - "fieldname": "net_total_export", - "fieldtype": "Currency", - "label": "Net Total", - "options": "currency", - "permlevel": 0, - "print_hide": 0, - "read_only": 1 - }, - { - "fieldname": "column_break_32", - "fieldtype": "Column Break", - "permlevel": 0 - }, { "fieldname": "net_total", "fieldtype": "Currency", @@ -329,6 +347,20 @@ "read_only": 1, "reqd": 1 }, + { + "fieldname": "column_break_32", + "fieldtype": "Column Break", + "permlevel": 0 + }, + { + "fieldname": "net_total_export", + "fieldtype": "Currency", + "label": "Net Total", + "options": "currency", + "permlevel": 0, + "print_hide": 0, + "read_only": 1 + }, { "fieldname": "taxes", "fieldtype": "Section Break", @@ -395,10 +427,12 @@ "permlevel": 0 }, { - "fieldname": "other_charges_total_export", + "fieldname": "other_charges_total", "fieldtype": "Currency", - "label": "Total Taxes and Charges", - "options": "currency", + "label": "Total Taxes and Charges (Company Currency)", + "oldfieldname": "other_charges_total", + "oldfieldtype": "Currency", + "options": "Company:company:default_currency", "permlevel": 0, "print_hide": 1, "read_only": 1 @@ -409,12 +443,10 @@ "permlevel": 0 }, { - "fieldname": "other_charges_total", + "fieldname": "other_charges_total_export", "fieldtype": "Currency", - "label": "Total Taxes and Charges (Company Currency)", - "oldfieldname": "other_charges_total", - "oldfieldtype": "Currency", - "options": "Company:company:default_currency", + "label": "Total Taxes and Charges", + "options": "currency", "permlevel": 0, "print_hide": 1, "read_only": 1 @@ -437,70 +469,6 @@ "print_hide": 1, "read_only": 0 }, - { - "fieldname": "grand_total_export", - "fieldtype": "Currency", - "in_list_view": 1, - "label": "Grand Total", - "oldfieldname": "grand_total_export", - "oldfieldtype": "Currency", - "options": "currency", - "permlevel": 0, - "print_hide": 0, - "read_only": 1, - "reqd": 1 - }, - { - "fieldname": "rounded_total_export", - "fieldtype": "Currency", - "label": "Rounded Total", - "oldfieldname": "rounded_total_export", - "oldfieldtype": "Currency", - "options": "currency", - "permlevel": 0, - "print_hide": 0, - "read_only": 1 - }, - { - "fieldname": "in_words_export", - "fieldtype": "Data", - "label": "In Words", - "oldfieldname": "in_words_export", - "oldfieldtype": "Data", - "permlevel": 0, - "print_hide": 0, - "read_only": 1 - }, - { - "fieldname": "gross_profit", - "fieldtype": "Currency", - "label": "Gross Profit", - "oldfieldname": "gross_profit", - "oldfieldtype": "Currency", - "options": "Company:company:default_currency", - "permlevel": 0, - "print_hide": 1, - "read_only": 1 - }, - { - "fieldname": "gross_profit_percent", - "fieldtype": "Float", - "label": "Gross Profit (%)", - "oldfieldname": "gross_profit_percent", - "oldfieldtype": "Currency", - "permlevel": 0, - "print_hide": 1, - "read_only": 1 - }, - { - "fieldname": "column_break5", - "fieldtype": "Column Break", - "oldfieldtype": "Column Break", - "permlevel": 0, - "print_hide": 1, - "read_only": 0, - "width": "50%" - }, { "fieldname": "grand_total", "fieldtype": "Currency", @@ -561,6 +529,70 @@ "print_hide": 1, "read_only": 1 }, + { + "fieldname": "column_break5", + "fieldtype": "Column Break", + "oldfieldtype": "Column Break", + "permlevel": 0, + "print_hide": 1, + "read_only": 0, + "width": "50%" + }, + { + "fieldname": "grand_total_export", + "fieldtype": "Currency", + "in_list_view": 1, + "label": "Grand Total", + "oldfieldname": "grand_total_export", + "oldfieldtype": "Currency", + "options": "currency", + "permlevel": 0, + "print_hide": 0, + "read_only": 1, + "reqd": 1 + }, + { + "fieldname": "rounded_total_export", + "fieldtype": "Currency", + "label": "Rounded Total", + "oldfieldname": "rounded_total_export", + "oldfieldtype": "Currency", + "options": "currency", + "permlevel": 0, + "print_hide": 0, + "read_only": 1 + }, + { + "fieldname": "in_words_export", + "fieldtype": "Data", + "label": "In Words", + "oldfieldname": "in_words_export", + "oldfieldtype": "Data", + "permlevel": 0, + "print_hide": 0, + "read_only": 1 + }, + { + "fieldname": "gross_profit", + "fieldtype": "Currency", + "label": "Gross Profit", + "oldfieldname": "gross_profit", + "oldfieldtype": "Currency", + "options": "Company:company:default_currency", + "permlevel": 0, + "print_hide": 1, + "read_only": 1 + }, + { + "fieldname": "gross_profit_percent", + "fieldtype": "Float", + "label": "Gross Profit (%)", + "oldfieldname": "gross_profit_percent", + "oldfieldtype": "Currency", + "permlevel": 0, + "print_hide": 1, + "read_only": 1 + }, { "fieldname": "advances", "fieldtype": "Section Break", @@ -682,6 +714,11 @@ "print_hide": 1, "read_only": 0 }, + { + "fieldname": "fold", + "fieldtype": "Fold", + "permlevel": 0 + }, { "fieldname": "terms_section_break", "fieldtype": "Section Break", @@ -1051,9 +1088,9 @@ "allow_on_submit": 1, "depends_on": "eval:doc.docstatus<2", "description": "Check if recurring invoice, uncheck to stop recurring or put proper End Date", - "fieldname": "convert_into_recurring_invoice", + "fieldname": "is_recurring", "fieldtype": "Check", - "label": "Convert into Recurring Invoice", + "label": "Is Recurring", "no_copy": 1, "permlevel": 0, "print_hide": 1, @@ -1061,7 +1098,7 @@ }, { "allow_on_submit": 1, - "depends_on": "eval:doc.convert_into_recurring_invoice==1", + "depends_on": "eval:doc.is_recurring==1", "description": "Select the period when the invoice will be generated automatically", "fieldname": "recurring_type", "fieldtype": "Select", @@ -1074,7 +1111,7 @@ }, { "allow_on_submit": 1, - "depends_on": "eval:doc.convert_into_recurring_invoice==1", + "depends_on": "eval:doc.is_recurring==1", "description": "The day of the month on which auto invoice will be generated e.g. 05, 28 etc ", "fieldname": "repeat_on_day_of_month", "fieldtype": "Int", @@ -1085,24 +1122,23 @@ "read_only": 0 }, { - "allow_on_submit": 1, - "depends_on": "eval:doc.convert_into_recurring_invoice==1", - "description": "Start date of current invoice's period", - "fieldname": "invoice_period_from_date", + "depends_on": "eval:doc.is_recurring==1", + "description": "The date on which next invoice will be generated. It is generated on submit.\n", + "fieldname": "next_date", "fieldtype": "Date", - "label": "Invoice Period From Date", + "label": "Next Date", "no_copy": 1, "permlevel": 0, "print_hide": 1, - "read_only": 0 + "read_only": 1 }, { "allow_on_submit": 1, - "depends_on": "eval:doc.convert_into_recurring_invoice==1", - "description": "End date of current invoice's period", - "fieldname": "invoice_period_to_date", + "depends_on": "eval:doc.is_recurring==1", + "description": "The date on which recurring invoice will be stop", + "fieldname": "end_date", "fieldtype": "Date", - "label": "Invoice Period To Date", + "label": "End Date", "no_copy": 1, "permlevel": 0, "print_hide": 1, @@ -1118,19 +1154,7 @@ "width": "50%" }, { - "allow_on_submit": 1, - "depends_on": "eval:doc.convert_into_recurring_invoice==1", - "description": "Enter email id separated by commas, invoice will be mailed automatically on particular date", - "fieldname": "notification_email_address", - "fieldtype": "Small Text", - "label": "Notification Email Address", - "no_copy": 1, - "permlevel": 0, - "print_hide": 1, - "read_only": 0 - }, - { - "depends_on": "eval:doc.convert_into_recurring_invoice==1", + "depends_on": "eval:doc.is_recurring==1", "description": "The unique id for tracking all recurring invoices.\u00a0It is generated on submit.", "fieldname": "recurring_id", "fieldtype": "Data", @@ -1140,24 +1164,13 @@ "print_hide": 1, "read_only": 1 }, - { - "depends_on": "eval:doc.convert_into_recurring_invoice==1", - "description": "The date on which next invoice will be generated. It is generated on submit.\n", - "fieldname": "next_date", - "fieldtype": "Date", - "label": "Next Date", - "no_copy": 1, - "permlevel": 0, - "print_hide": 1, - "read_only": 1 - }, { "allow_on_submit": 1, - "depends_on": "eval:doc.convert_into_recurring_invoice==1", - "description": "The date on which recurring invoice will be stop", - "fieldname": "end_date", - "fieldtype": "Date", - "label": "End Date", + "depends_on": "eval:doc.is_recurring==1", + "description": "Enter email id separated by commas, invoice will be mailed automatically on particular date", + "fieldname": "notification_email_address", + "fieldtype": "Small Text", + "label": "Notification Email Address", "no_copy": 1, "permlevel": 0, "print_hide": 1, @@ -1180,7 +1193,7 @@ "icon": "icon-file-text", "idx": 1, "is_submittable": 1, - "modified": "2014-05-09 02:17:00.217556", + "modified": "2014-08-28 11:21:00.726344", "modified_by": "Administrator", "module": "Accounts", "name": "Sales Invoice", @@ -1202,6 +1215,7 @@ }, { "amend": 1, + "apply_user_permissions": 1, "cancel": 0, "create": 1, "delete": 0, @@ -1215,6 +1229,7 @@ "write": 1 }, { + "apply_user_permissions": 1, "cancel": 0, "delete": 0, "email": 1, @@ -1223,6 +1238,12 @@ "read": 1, "report": 1, "role": "Customer" + }, + { + "permlevel": 1, + "read": 1, + "role": "Accounts Manager", + "write": 1 } ], "read_only_onload": 1, diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py index 982df17b69..a20d906b8c 100644 --- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py +++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py @@ -14,10 +14,14 @@ from erpnext.accounts.party import get_party_account, get_due_date from erpnext.controllers.stock_controller import update_gl_entries_after from frappe.model.mapper import get_mapped_doc -month_map = {'Monthly': 1, 'Quarterly': 3, 'Half-yearly': 6, 'Yearly': 12} +from erpnext.controllers.recurring_document import * from erpnext.controllers.selling_controller import SellingController +form_grid_templates = { + "entries": "templates/form_grid/item_grid.html" +} + class SalesInvoice(SellingController): tname = 'Sales Invoice Item' fname = 'entries' @@ -36,7 +40,8 @@ class SalesInvoice(SellingController): 'join_field': 'so_detail', 'percent_join_field': 'sales_order', 'status_field': 'billing_status', - 'keyword': 'Billed' + 'keyword': 'Billed', + 'overflow_type': 'billing' }] def validate(self): @@ -70,7 +75,7 @@ class SalesInvoice(SellingController): self.set_against_income_account() self.validate_c_form() self.validate_time_logs_are_submitted() - self.validate_recurring_invoice() + validate_recurring_document(self) self.validate_multiple_billing("Delivery Note", "dn_detail", "amount", "delivery_note_details") @@ -98,7 +103,7 @@ class SalesInvoice(SellingController): self.update_c_form() self.update_time_log_batch(self.name) - self.convert_to_recurring() + convert_to_recurring(self, "RECINV.#####", self.posting_date) def before_cancel(self): self.update_time_log_batch(None) @@ -116,7 +121,7 @@ class SalesInvoice(SellingController): self.update_prevdoc_status() self.update_billing_status_for_zero_amount_refdoc("Sales Order") - self.make_cancel_gl_entries() + self.make_gl_entries_on_cancel() def update_status_updater_args(self): if cint(self.update_stock): @@ -134,12 +139,13 @@ class SalesInvoice(SellingController): 'keyword':'Delivered', 'second_source_dt': 'Delivery Note Item', 'second_source_field': 'qty', - 'second_join_field': 'prevdoc_detail_docname' + 'second_join_field': 'prevdoc_detail_docname', + 'overflow_type': 'delivery' }) def on_update_after_submit(self): - self.validate_recurring_invoice() - self.convert_to_recurring() + validate_recurring_document(self) + convert_to_recurring(self, "RECINV.#####", self.posting_date) def get_portal_page(self): return "invoice" if self.docstatus==1 else None @@ -262,11 +268,11 @@ class SalesInvoice(SellingController): """Validate Fixed Asset and whether Income Account Entered Exists""" for d in self.get('entries'): item = frappe.db.sql("""select name,is_asset_item,is_sales_item from `tabItem` - where name = %s and (ifnull(end_of_life,'')='' or end_of_life > now())""", d.item_code) - acc = frappe.db.sql("""select account_type from `tabAccount` + where name = %s""", d.item_code) + acc = frappe.db.sql("""select account_type from `tabAccount` where name = %s and docstatus != 2""", d.income_account) - if item and item[0][1] == 'Yes' and not acc[0][0] == 'Fixed Asset': - msgprint(_("Account {0} must be of type 'Fixed Asset' as Item {1} is an Asset Item").format(d.item_code), raise_exception=True) + if item and item[0][1] == 'Yes' and acc and acc[0][0] != 'Fixed Asset': + msgprint(_("Account {0} must be of type 'Fixed Asset' as Item {1} is an Asset Item").format(acc[0][0], d.item_code), raise_exception=True) def validate_with_previous_doc(self): super(SalesInvoice, self).validate_with_previous_doc(self.tname, { @@ -339,8 +345,8 @@ class SalesInvoice(SellingController): def validate_pos(self): if not self.cash_bank_account and flt(self.paid_amount): - msgprint(_("Cash or Bank Account is mandatory for making payment entry")) - raise Exception + frappe.throw(_("Cash or Bank Account is mandatory for making payment entry")) + if flt(self.paid_amount) + flt(self.write_off_amount) \ - flt(self.grand_total) > 1/(10**(self.precision("grand_total") + 1)): frappe.throw(_("""Paid amount + Write Off Amount can not be greater than Grand Total""")) @@ -383,20 +389,20 @@ class SalesInvoice(SellingController): def get_warehouse(self): - w = frappe.db.sql("""select warehouse from `tabPOS Setting` - where ifnull(user,'') = %s and company = %s""", - (frappe.session['user'], self.company)) - w = w and w[0][0] or '' - if not w: - ps = frappe.db.sql("""select name, warehouse from `tabPOS Setting` + user_pos_setting = frappe.db.sql("""select name, warehouse from `tabPOS Setting` + where ifnull(user,'') = %s and company = %s""", (frappe.session['user'], self.company)) + warehouse = user_pos_setting[0][1] if user_pos_setting else None + + if not warehouse: + global_pos_setting = frappe.db.sql("""select name, warehouse from `tabPOS Setting` where ifnull(user,'') = '' and company = %s""", self.company) - if not ps: + + if global_pos_setting: + warehouse = global_pos_setting[0][1] + elif not user_pos_setting: msgprint(_("POS Setting required to make POS Entry"), raise_exception=True) - elif not ps[0][1]: - msgprint(_("Warehouse required in POS Setting")) - else: - w = ps[0][1] - return w + + return warehouse def on_update(self): if cint(self.update_stock) == 1: @@ -431,8 +437,7 @@ class SalesInvoice(SellingController): submitted = frappe.db.sql("""select name from `tabSales Order` where docstatus = 1 and name = %s""", d.sales_order) if not submitted: - msgprint(_("Sales Order {0} is not submitted").format(d.sales_order)) - raise Exception + frappe.throw(_("Sales Order {0} is not submitted").format(d.sales_order)) if d.delivery_note: submitted = frappe.db.sql("""select name from `tabDelivery Note` @@ -587,170 +592,6 @@ class SalesInvoice(SellingController): grand_total = %s where invoice_no = %s and parent = %s""", (self.name, self.amended_from, self.c_form_no)) - def validate_recurring_invoice(self): - if self.convert_into_recurring_invoice: - self.validate_notification_email_id() - - if not self.recurring_type: - msgprint(_("Please select {0}").format(self.meta.get_label("recurring_type")), - raise_exception=1) - - elif not (self.invoice_period_from_date and \ - self.invoice_period_to_date): - throw(_("Invoice Period From and Invoice Period To dates mandatory for recurring invoice")) - - def convert_to_recurring(self): - if self.convert_into_recurring_invoice: - if not self.recurring_id: - frappe.db.set(self, "recurring_id", - make_autoname("RECINV/.#####")) - - self.set_next_date() - - elif self.recurring_id: - frappe.db.sql("""update `tabSales Invoice` - set convert_into_recurring_invoice = 0 - where recurring_id = %s""", (self.recurring_id,)) - - def validate_notification_email_id(self): - if self.notification_email_address: - email_list = filter(None, [cstr(email).strip() for email in - self.notification_email_address.replace("\n", "").split(",")]) - - from frappe.utils import validate_email_add - for email in email_list: - if not validate_email_add(email): - throw(_("{0} is an invalid email address in 'Notification Email Address'").format(email)) - - else: - throw(_("'Notification Email Addresses' not specified for recurring invoice")) - - def set_next_date(self): - """ Set next date on which auto invoice will be created""" - if not self.repeat_on_day_of_month: - msgprint(_("Please enter 'Repeat on Day of Month' field value"), raise_exception=1) - - next_date = get_next_date(self.posting_date, - month_map[self.recurring_type], cint(self.repeat_on_day_of_month)) - - frappe.db.set(self, 'next_date', next_date) - -def get_next_date(dt, mcount, day=None): - dt = getdate(dt) - - from dateutil.relativedelta import relativedelta - dt += relativedelta(months=mcount, day=day) - - return dt - -def manage_recurring_invoices(next_date=None, commit=True): - """ - Create recurring invoices on specific date by copying the original one - and notify the concerned people - """ - next_date = next_date or nowdate() - recurring_invoices = frappe.db.sql("""select name, recurring_id - from `tabSales Invoice` where ifnull(convert_into_recurring_invoice, 0)=1 - and docstatus=1 and next_date=%s - and next_date <= ifnull(end_date, '2199-12-31')""", next_date) - - exception_list = [] - for ref_invoice, recurring_id in recurring_invoices: - if not frappe.db.sql("""select name from `tabSales Invoice` - where posting_date=%s and recurring_id=%s and docstatus=1""", - (next_date, recurring_id)): - try: - ref_wrapper = frappe.get_doc('Sales Invoice', ref_invoice) - new_invoice_wrapper = make_new_invoice(ref_wrapper, next_date) - send_notification(new_invoice_wrapper) - if commit: - frappe.db.commit() - except: - if commit: - frappe.db.rollback() - - frappe.db.begin() - frappe.db.sql("update `tabSales Invoice` set \ - convert_into_recurring_invoice = 0 where name = %s", ref_invoice) - notify_errors(ref_invoice, ref_wrapper.customer, ref_wrapper.owner) - frappe.db.commit() - - exception_list.append(frappe.get_traceback()) - finally: - if commit: - frappe.db.begin() - - if exception_list: - exception_message = "\n\n".join([cstr(d) for d in exception_list]) - raise Exception, exception_message - -def make_new_invoice(ref_wrapper, posting_date): - from erpnext.accounts.utils import get_fiscal_year - new_invoice = frappe.copy_doc(ref_wrapper) - - mcount = month_map[ref_wrapper.recurring_type] - - invoice_period_from_date = get_next_date(ref_wrapper.invoice_period_from_date, mcount) - - # get last day of the month to maintain period if the from date is first day of its own month - # and to date is the last day of its own month - if (cstr(get_first_day(ref_wrapper.invoice_period_from_date)) == \ - cstr(ref_wrapper.invoice_period_from_date)) and \ - (cstr(get_last_day(ref_wrapper.invoice_period_to_date)) == \ - cstr(ref_wrapper.invoice_period_to_date)): - invoice_period_to_date = get_last_day(get_next_date(ref_wrapper.invoice_period_to_date, - mcount)) - else: - invoice_period_to_date = get_next_date(ref_wrapper.invoice_period_to_date, mcount) - - new_invoice.update({ - "posting_date": posting_date, - "aging_date": posting_date, - "due_date": add_days(posting_date, cint(date_diff(ref_wrapper.due_date, - ref_wrapper.posting_date))), - "invoice_period_from_date": invoice_period_from_date, - "invoice_period_to_date": invoice_period_to_date, - "fiscal_year": get_fiscal_year(posting_date)[0], - "owner": ref_wrapper.owner, - }) - - new_invoice.submit() - - return new_invoice - -def send_notification(new_rv): - """Notify concerned persons about recurring invoice generation""" - - from frappe.core.doctype.print_format.print_format import get_html - frappe.sendmail(new_rv.notification_email_address, - subject="New Invoice : " + new_rv.name, - message = get_html(new_rv, new_rv, "SalesInvoice")) - -def notify_errors(inv, customer, owner): - from frappe.utils.user import get_system_managers - recipients=get_system_managers() - - frappe.sendmail(recipients + [frappe.db.get_value("User", owner, "email")], - subject="[Urgent] Error while creating recurring invoice for %s" % inv, - message = frappe.get_template("template/emails/recurring_invoice_failed.html").render({ - "name": inv, - "customer": customer - })) - - assign_task_to_owner(inv, "Recurring Invoice Failed", recipients) - -def assign_task_to_owner(inv, msg, users): - for d in users: - from frappe.widgets.form import assign_to - args = { - 'assign_to' : d, - 'doctype' : 'Sales Invoice', - 'name' : inv, - 'description' : msg, - 'priority' : 'Urgent' - } - assign_to.add(args) - @frappe.whitelist() def get_bank_cash_account(mode_of_payment): val = frappe.db.get_value("Mode of Payment", mode_of_payment, "default_account") @@ -783,6 +624,7 @@ def get_income_account(doctype, txt, searchfield, start, page_len, filters): @frappe.whitelist() def make_delivery_note(source_name, target_doc=None): def set_missing_values(source, target): + target.ignore_pricing_rule = 1 target.run_method("set_missing_values") target.run_method("calculate_taxes_and_totals") diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice_list.html b/erpnext/accounts/doctype/sales_invoice/sales_invoice_list.html new file mode 100644 index 0000000000..47fadb5420 --- /dev/null +++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice_list.html @@ -0,0 +1,45 @@ +
+
+
+ {%= list.get_avatar_and_id(doc) %} + + + {%= doc.customer_name %} + {% if(doc.outstanding_amount > 0 && doc.docstatus==1) { %} + {% if(frappe.datetime.get_diff(doc.due_date) < 0) { %} + + {%= __("Overdue: ") + comment_when(doc.due_date) %} + + {% } else { %} + + {%= doc.get_formatted("due_date") %} + {% } %} + {% } %} + {% if(doc.outstanding_amount==0 && doc.docstatus==1) { %} + + {%= __("Paid") %} + + {% } %} + {% if(doc.docstatus===0) { %} + {%= __("Draft") %} + {% } %} +
+
+
+ {% var completed = cint((doc.grand_total - doc.outstanding_amount) * 100 / doc.grand_total), title = __("Outstanding Amount") + ": " + doc.get_formatted("outstanding_amount") %} + {% include "templates/form_grid/includes/progress.html" %} +
+
+
+ {%= doc.get_formatted("grand_total_export") %} +
+
+
diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice_list.js b/erpnext/accounts/doctype/sales_invoice/sales_invoice_list.js index 5592bc5220..ea2986a79f 100644 --- a/erpnext/accounts/doctype/sales_invoice/sales_invoice_list.js +++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice_list.js @@ -3,12 +3,7 @@ // render frappe.listview_settings['Sales Invoice'] = { - add_fields: ["`tabSales Invoice`.grand_total", "`tabSales Invoice`.outstanding_amount"], - add_columns: [{"content":"Percent Paid", width:"10%", type:"bar-graph", - label: "Payment Received"}], - prepare_data: function(data) { - data["Percent Paid"] = (data.docstatus===1 && flt(data.grand_total)) - ? (((flt(data.grand_total) - flt(data.outstanding_amount)) / flt(data.grand_total)) * 100) - : 0; - } + add_fields: ["customer", "customer_name", "grand_total", "outstanding_amount", "due_date", "company", + "currency"], + filters: [["outstanding_amount", ">", "0"]] }; diff --git a/erpnext/accounts/doctype/sales_invoice/test_records.json b/erpnext/accounts/doctype/sales_invoice/test_records.json index b0828f5c7e..76c70cc416 100644 --- a/erpnext/accounts/doctype/sales_invoice/test_records.json +++ b/erpnext/accounts/doctype/sales_invoice/test_records.json @@ -1,385 +1,390 @@ [ { - "company": "_Test Company", - "conversion_rate": 1.0, - "currency": "INR", - "customer": "_Test Customer", - "customer_name": "_Test Customer", - "debit_to": "_Test Customer - _TC", - "doctype": "Sales Invoice", - "due_date": "2013-01-23", + "company": "_Test Company", + "conversion_rate": 1.0, + "currency": "INR", + "customer": "_Test Customer", + "customer_name": "_Test Customer", + "debit_to": "_Test Customer - _TC", + "doctype": "Sales Invoice", + "due_date": "2013-01-23", "entries": [ { - "amount": 500.0, - "base_amount": 500.0, - "base_rate": 500.0, - "cost_center": "_Test Cost Center - _TC", - "description": "138-CMS Shoe", - "doctype": "Sales Invoice Item", - "income_account": "Sales - _TC", - "item_name": "138-CMS Shoe", - "parentfield": "entries", - "qty": 1.0, + "amount": 500.0, + "base_amount": 500.0, + "base_rate": 500.0, + "cost_center": "_Test Cost Center - _TC", + "description": "138-CMS Shoe", + "doctype": "Sales Invoice Item", + "income_account": "Sales - _TC", + "expense_account": "_Test Account Cost for Goods Sold - _TC", + "item_name": "138-CMS Shoe", + "parentfield": "entries", + "qty": 1.0, "rate": 500.0 } - ], - "fiscal_year": "_Test Fiscal Year 2013", - "grand_total": 561.8, - "grand_total_export": 561.8, - "is_pos": 0, - "naming_series": "_T-Sales Invoice-", - "net_total": 500.0, + ], + "fiscal_year": "_Test Fiscal Year 2013", + "grand_total": 561.8, + "grand_total_export": 561.8, + "is_pos": 0, + "naming_series": "_T-Sales Invoice-", + "net_total": 500.0, "other_charges": [ { - "account_head": "_Test Account VAT - _TC", - "charge_type": "On Net Total", - "description": "VAT", - "doctype": "Sales Taxes and Charges", - "parentfield": "other_charges", + "account_head": "_Test Account VAT - _TC", + "charge_type": "On Net Total", + "description": "VAT", + "doctype": "Sales Taxes and Charges", + "parentfield": "other_charges", "rate": 6 - }, + }, { - "account_head": "_Test Account Service Tax - _TC", - "charge_type": "On Net Total", - "description": "Service Tax", - "doctype": "Sales Taxes and Charges", - "parentfield": "other_charges", + "account_head": "_Test Account Service Tax - _TC", + "charge_type": "On Net Total", + "description": "Service Tax", + "doctype": "Sales Taxes and Charges", + "parentfield": "other_charges", "rate": 6.36 } - ], - "plc_conversion_rate": 1.0, - "posting_date": "2013-01-23", - "price_list_currency": "INR", + ], + "plc_conversion_rate": 1.0, + "posting_date": "2013-01-23", + "price_list_currency": "INR", "sales_team": [ { - "allocated_percentage": 65.5, - "doctype": "Sales Team", - "parentfield": "sales_team", + "allocated_percentage": 65.5, + "doctype": "Sales Team", + "parentfield": "sales_team", "sales_person": "_Test Sales Person 1" - }, + }, { - "allocated_percentage": 34.5, - "doctype": "Sales Team", - "parentfield": "sales_team", + "allocated_percentage": 34.5, + "doctype": "Sales Team", + "parentfield": "sales_team", "sales_person": "_Test Sales Person 2" } - ], - "selling_price_list": "_Test Price List", + ], + "selling_price_list": "_Test Price List", "territory": "_Test Territory" - }, + }, { - "company": "_Test Company", - "conversion_rate": 1.0, - "currency": "INR", - "customer": "_Test Customer", - "customer_name": "_Test Customer", - "debit_to": "_Test Customer - _TC", - "doctype": "Sales Invoice", - "due_date": "2013-01-23", + "company": "_Test Company", + "conversion_rate": 1.0, + "currency": "INR", + "customer": "_Test Customer", + "customer_name": "_Test Customer", + "debit_to": "_Test Customer - _TC", + "doctype": "Sales Invoice", + "due_date": "2013-03-07", "entries": [ { - "amount": 500.0, - "base_amount": 500.0, - "base_rate": 500.0, - "cost_center": "_Test Cost Center - _TC", - "description": "_Test Item", - "doctype": "Sales Invoice Item", - "expense_account": "_Test Account Cost for Goods Sold - _TC", - "income_account": "Sales - _TC", - "item_code": "_Test Item", - "item_name": "_Test Item", - "parentfield": "entries", - "price_list_rate": 500.0, + "amount": 500.0, + "base_amount": 500.0, + "base_rate": 500.0, + "cost_center": "_Test Cost Center - _TC", + "description": "_Test Item", + "doctype": "Sales Invoice Item", + "expense_account": "_Test Account Cost for Goods Sold - _TC", + "income_account": "Sales - _TC", + "item_code": "_Test Item", + "item_name": "_Test Item", + "parentfield": "entries", + "price_list_rate": 500.0, "qty": 1.0 } - ], - "fiscal_year": "_Test Fiscal Year 2013", - "grand_total": 630.0, - "grand_total_export": 630.0, - "is_pos": 0, - "naming_series": "_T-Sales Invoice-", - "net_total": 500.0, + ], + "fiscal_year": "_Test Fiscal Year 2013", + "grand_total": 630.0, + "grand_total_export": 630.0, + "is_pos": 0, + "naming_series": "_T-Sales Invoice-", + "net_total": 500.0, "other_charges": [ { - "account_head": "_Test Account VAT - _TC", - "charge_type": "On Net Total", - "description": "VAT", - "doctype": "Sales Taxes and Charges", - "parentfield": "other_charges", + "account_head": "_Test Account VAT - _TC", + "charge_type": "On Net Total", + "description": "VAT", + "doctype": "Sales Taxes and Charges", + "parentfield": "other_charges", "rate": 16 - }, + }, { - "account_head": "_Test Account Service Tax - _TC", - "charge_type": "On Net Total", - "description": "Service Tax", - "doctype": "Sales Taxes and Charges", - "parentfield": "other_charges", + "account_head": "_Test Account Service Tax - _TC", + "charge_type": "On Net Total", + "description": "Service Tax", + "doctype": "Sales Taxes and Charges", + "parentfield": "other_charges", "rate": 10 } - ], - "plc_conversion_rate": 1.0, - "posting_date": "2013-03-07", - "price_list_currency": "INR", - "selling_price_list": "_Test Price List", + ], + "plc_conversion_rate": 1.0, + "posting_date": "2013-03-07", + "price_list_currency": "INR", + "selling_price_list": "_Test Price List", "territory": "_Test Territory" - }, + }, { - "company": "_Test Company", - "conversion_rate": 1.0, - "currency": "INR", - "customer": "_Test Customer", - "customer_name": "_Test Customer", - "debit_to": "_Test Customer - _TC", - "doctype": "Sales Invoice", - "due_date": "2013-01-23", + "company": "_Test Company", + "conversion_rate": 1.0, + "currency": "INR", + "customer": "_Test Customer", + "customer_name": "_Test Customer", + "debit_to": "_Test Customer - _TC", + "doctype": "Sales Invoice", + "due_date": "2013-01-23", "entries": [ { - "cost_center": "_Test Cost Center - _TC", - "doctype": "Sales Invoice Item", - "income_account": "Sales - _TC", - "item_code": "_Test Item Home Desktop 100", - "item_name": "_Test Item Home Desktop 100", - "item_tax_rate": "{\"_Test Account Excise Duty - _TC\": 10}", - "parentfield": "entries", - "price_list_rate": 50, - "qty": 10, - "rate": 50, + "cost_center": "_Test Cost Center - _TC", + "doctype": "Sales Invoice Item", + "income_account": "Sales - _TC", + "expense_account": "_Test Account Cost for Goods Sold - _TC", + "item_code": "_Test Item Home Desktop 100", + "item_name": "_Test Item Home Desktop 100", + "item_tax_rate": "{\"_Test Account Excise Duty - _TC\": 10}", + "parentfield": "entries", + "price_list_rate": 50, + "qty": 10, + "rate": 50, "stock_uom": "_Test UOM" - }, + }, { - "cost_center": "_Test Cost Center - _TC", - "doctype": "Sales Invoice Item", - "income_account": "Sales - _TC", - "item_code": "_Test Item Home Desktop 200", - "item_name": "_Test Item Home Desktop 200", - "parentfield": "entries", - "price_list_rate": 150, - "qty": 5, - "rate": 150, + "cost_center": "_Test Cost Center - _TC", + "doctype": "Sales Invoice Item", + "income_account": "Sales - _TC", + "expense_account": "_Test Account Cost for Goods Sold - _TC", + "item_code": "_Test Item Home Desktop 200", + "item_name": "_Test Item Home Desktop 200", + "parentfield": "entries", + "price_list_rate": 150, + "qty": 5, + "rate": 150, "stock_uom": "_Test UOM" } - ], - "fiscal_year": "_Test Fiscal Year 2013", - "grand_total_export": 0, - "is_pos": 0, - "naming_series": "_T-Sales Invoice-", + ], + "fiscal_year": "_Test Fiscal Year 2013", + "grand_total_export": 0, + "is_pos": 0, + "naming_series": "_T-Sales Invoice-", "other_charges": [ { - "account_head": "_Test Account Shipping Charges - _TC", - "charge_type": "Actual", - "cost_center": "_Test Cost Center - _TC", - "description": "Shipping Charges", - "doctype": "Sales Taxes and Charges", - "parentfield": "other_charges", + "account_head": "_Test Account Shipping Charges - _TC", + "charge_type": "Actual", + "cost_center": "_Test Cost Center - _TC", + "description": "Shipping Charges", + "doctype": "Sales Taxes and Charges", + "parentfield": "other_charges", "rate": 100 - }, + }, { - "account_head": "_Test Account Customs Duty - _TC", - "charge_type": "On Net Total", - "cost_center": "_Test Cost Center - _TC", - "description": "Customs Duty", - "doctype": "Sales Taxes and Charges", - "parentfield": "other_charges", + "account_head": "_Test Account Customs Duty - _TC", + "charge_type": "On Net Total", + "cost_center": "_Test Cost Center - _TC", + "description": "Customs Duty", + "doctype": "Sales Taxes and Charges", + "parentfield": "other_charges", "rate": 10 - }, + }, { - "account_head": "_Test Account Excise Duty - _TC", - "charge_type": "On Net Total", - "cost_center": "_Test Cost Center - _TC", - "description": "Excise Duty", - "doctype": "Sales Taxes and Charges", - "parentfield": "other_charges", + "account_head": "_Test Account Excise Duty - _TC", + "charge_type": "On Net Total", + "cost_center": "_Test Cost Center - _TC", + "description": "Excise Duty", + "doctype": "Sales Taxes and Charges", + "parentfield": "other_charges", "rate": 12 - }, + }, { - "account_head": "_Test Account Education Cess - _TC", - "charge_type": "On Previous Row Amount", - "cost_center": "_Test Cost Center - _TC", - "description": "Education Cess", - "doctype": "Sales Taxes and Charges", - "parentfield": "other_charges", - "rate": 2, + "account_head": "_Test Account Education Cess - _TC", + "charge_type": "On Previous Row Amount", + "cost_center": "_Test Cost Center - _TC", + "description": "Education Cess", + "doctype": "Sales Taxes and Charges", + "parentfield": "other_charges", + "rate": 2, "row_id": 3 - }, + }, { - "account_head": "_Test Account S&H Education Cess - _TC", - "charge_type": "On Previous Row Amount", - "cost_center": "_Test Cost Center - _TC", - "description": "S&H Education Cess", - "doctype": "Sales Taxes and Charges", - "parentfield": "other_charges", - "rate": 1, + "account_head": "_Test Account S&H Education Cess - _TC", + "charge_type": "On Previous Row Amount", + "cost_center": "_Test Cost Center - _TC", + "description": "S&H Education Cess", + "doctype": "Sales Taxes and Charges", + "parentfield": "other_charges", + "rate": 1, "row_id": 3 - }, + }, { - "account_head": "_Test Account CST - _TC", - "charge_type": "On Previous Row Total", - "cost_center": "_Test Cost Center - _TC", - "description": "CST", - "doctype": "Sales Taxes and Charges", - "parentfield": "other_charges", - "rate": 2, + "account_head": "_Test Account CST - _TC", + "charge_type": "On Previous Row Total", + "cost_center": "_Test Cost Center - _TC", + "description": "CST", + "doctype": "Sales Taxes and Charges", + "parentfield": "other_charges", + "rate": 2, "row_id": 5 - }, + }, { - "account_head": "_Test Account VAT - _TC", - "charge_type": "On Net Total", - "cost_center": "_Test Cost Center - _TC", - "description": "VAT", - "doctype": "Sales Taxes and Charges", - "parentfield": "other_charges", + "account_head": "_Test Account VAT - _TC", + "charge_type": "On Net Total", + "cost_center": "_Test Cost Center - _TC", + "description": "VAT", + "doctype": "Sales Taxes and Charges", + "parentfield": "other_charges", "rate": 12.5 - }, + }, { - "account_head": "_Test Account Discount - _TC", - "charge_type": "On Previous Row Total", - "cost_center": "_Test Cost Center - _TC", - "description": "Discount", - "doctype": "Sales Taxes and Charges", - "parentfield": "other_charges", - "rate": -10, + "account_head": "_Test Account Discount - _TC", + "charge_type": "On Previous Row Total", + "cost_center": "_Test Cost Center - _TC", + "description": "Discount", + "doctype": "Sales Taxes and Charges", + "parentfield": "other_charges", + "rate": -10, "row_id": 7 } - ], - "plc_conversion_rate": 1.0, - "posting_date": "2013-01-23", - "price_list_currency": "INR", - "selling_price_list": "_Test Price List", + ], + "plc_conversion_rate": 1.0, + "posting_date": "2013-01-23", + "price_list_currency": "INR", + "selling_price_list": "_Test Price List", "territory": "_Test Territory" - }, + }, { - "company": "_Test Company", - "conversion_rate": 1.0, - "currency": "INR", - "customer": "_Test Customer", - "customer_name": "_Test Customer", - "debit_to": "_Test Customer - _TC", - "doctype": "Sales Invoice", - "due_date": "2013-01-23", + "company": "_Test Company", + "conversion_rate": 1.0, + "currency": "INR", + "customer": "_Test Customer", + "customer_name": "_Test Customer", + "debit_to": "_Test Customer - _TC", + "doctype": "Sales Invoice", + "due_date": "2013-01-23", "entries": [ { - "cost_center": "_Test Cost Center - _TC", - "doctype": "Sales Invoice Item", - "income_account": "Sales - _TC", - "item_code": "_Test Item Home Desktop 100", - "item_name": "_Test Item Home Desktop 100", - "item_tax_rate": "{\"_Test Account Excise Duty - _TC\": 10}", - "parentfield": "entries", - "price_list_rate": 62.5, - "qty": 10, + "cost_center": "_Test Cost Center - _TC", + "doctype": "Sales Invoice Item", + "income_account": "Sales - _TC", + "expense_account": "_Test Account Cost for Goods Sold - _TC", + "item_code": "_Test Item Home Desktop 100", + "item_name": "_Test Item Home Desktop 100", + "item_tax_rate": "{\"_Test Account Excise Duty - _TC\": 10}", + "parentfield": "entries", + "price_list_rate": 62.5, + "qty": 10, "stock_uom": "_Test UOM" - }, + }, { - "cost_center": "_Test Cost Center - _TC", - "doctype": "Sales Invoice Item", - "income_account": "Sales - _TC", - "item_code": "_Test Item Home Desktop 200", - "item_name": "_Test Item Home Desktop 200", - "parentfield": "entries", - "price_list_rate": 190.66, - "qty": 5, + "cost_center": "_Test Cost Center - _TC", + "doctype": "Sales Invoice Item", + "income_account": "Sales - _TC", + "expense_account": "_Test Account Cost for Goods Sold - _TC", + "item_code": "_Test Item Home Desktop 200", + "item_name": "_Test Item Home Desktop 200", + "parentfield": "entries", + "price_list_rate": 190.66, + "qty": 5, "stock_uom": "_Test UOM" } - ], - "fiscal_year": "_Test Fiscal Year 2013", - "grand_total_export": 0, - "is_pos": 0, - "naming_series": "_T-Sales Invoice-", + ], + "fiscal_year": "_Test Fiscal Year 2013", + "grand_total_export": 0, + "is_pos": 0, + "naming_series": "_T-Sales Invoice-", "other_charges": [ { - "account_head": "_Test Account Excise Duty - _TC", - "charge_type": "On Net Total", - "cost_center": "_Test Cost Center - _TC", - "description": "Excise Duty", - "doctype": "Sales Taxes and Charges", - "idx": 1, - "included_in_print_rate": 1, - "parentfield": "other_charges", + "account_head": "_Test Account Excise Duty - _TC", + "charge_type": "On Net Total", + "cost_center": "_Test Cost Center - _TC", + "description": "Excise Duty", + "doctype": "Sales Taxes and Charges", + "idx": 1, + "included_in_print_rate": 1, + "parentfield": "other_charges", "rate": 12 - }, + }, { - "account_head": "_Test Account Education Cess - _TC", - "charge_type": "On Previous Row Amount", - "cost_center": "_Test Cost Center - _TC", - "description": "Education Cess", - "doctype": "Sales Taxes and Charges", - "idx": 2, - "included_in_print_rate": 1, - "parentfield": "other_charges", - "rate": 2, + "account_head": "_Test Account Education Cess - _TC", + "charge_type": "On Previous Row Amount", + "cost_center": "_Test Cost Center - _TC", + "description": "Education Cess", + "doctype": "Sales Taxes and Charges", + "idx": 2, + "included_in_print_rate": 1, + "parentfield": "other_charges", + "rate": 2, "row_id": 1 - }, + }, { - "account_head": "_Test Account S&H Education Cess - _TC", - "charge_type": "On Previous Row Amount", - "cost_center": "_Test Cost Center - _TC", - "description": "S&H Education Cess", - "doctype": "Sales Taxes and Charges", - "idx": 3, - "included_in_print_rate": 1, - "parentfield": "other_charges", - "rate": 1, + "account_head": "_Test Account S&H Education Cess - _TC", + "charge_type": "On Previous Row Amount", + "cost_center": "_Test Cost Center - _TC", + "description": "S&H Education Cess", + "doctype": "Sales Taxes and Charges", + "idx": 3, + "included_in_print_rate": 1, + "parentfield": "other_charges", + "rate": 1, "row_id": 1 - }, + }, { - "account_head": "_Test Account CST - _TC", - "charge_type": "On Previous Row Total", - "cost_center": "_Test Cost Center - _TC", - "description": "CST", - "doctype": "Sales Taxes and Charges", - "idx": 4, - "included_in_print_rate": 1, - "parentfield": "other_charges", - "rate": 2, + "account_head": "_Test Account CST - _TC", + "charge_type": "On Previous Row Total", + "cost_center": "_Test Cost Center - _TC", + "description": "CST", + "doctype": "Sales Taxes and Charges", + "idx": 4, + "included_in_print_rate": 1, + "parentfield": "other_charges", + "rate": 2, "row_id": 3 - }, + }, { - "account_head": "_Test Account VAT - _TC", - "charge_type": "On Net Total", - "cost_center": "_Test Cost Center - _TC", - "description": "VAT", - "doctype": "Sales Taxes and Charges", - "idx": 5, - "included_in_print_rate": 1, - "parentfield": "other_charges", + "account_head": "_Test Account VAT - _TC", + "charge_type": "On Net Total", + "cost_center": "_Test Cost Center - _TC", + "description": "VAT", + "doctype": "Sales Taxes and Charges", + "idx": 5, + "included_in_print_rate": 1, + "parentfield": "other_charges", "rate": 12.5 - }, + }, { - "account_head": "_Test Account Customs Duty - _TC", - "charge_type": "On Net Total", - "cost_center": "_Test Cost Center - _TC", - "description": "Customs Duty", - "doctype": "Sales Taxes and Charges", - "idx": 6, - "parentfield": "other_charges", + "account_head": "_Test Account Customs Duty - _TC", + "charge_type": "On Net Total", + "cost_center": "_Test Cost Center - _TC", + "description": "Customs Duty", + "doctype": "Sales Taxes and Charges", + "idx": 6, + "parentfield": "other_charges", "rate": 10 - }, + }, { - "account_head": "_Test Account Shipping Charges - _TC", - "charge_type": "Actual", - "cost_center": "_Test Cost Center - _TC", - "description": "Shipping Charges", - "doctype": "Sales Taxes and Charges", - "idx": 7, - "parentfield": "other_charges", + "account_head": "_Test Account Shipping Charges - _TC", + "charge_type": "Actual", + "cost_center": "_Test Cost Center - _TC", + "description": "Shipping Charges", + "doctype": "Sales Taxes and Charges", + "idx": 7, + "parentfield": "other_charges", "rate": 100 - }, + }, { - "account_head": "_Test Account Discount - _TC", - "charge_type": "On Previous Row Total", - "cost_center": "_Test Cost Center - _TC", - "description": "Discount", - "doctype": "Sales Taxes and Charges", - "idx": 8, - "parentfield": "other_charges", - "rate": -10, + "account_head": "_Test Account Discount - _TC", + "charge_type": "On Previous Row Total", + "cost_center": "_Test Cost Center - _TC", + "description": "Discount", + "doctype": "Sales Taxes and Charges", + "idx": 8, + "parentfield": "other_charges", + "rate": -10, "row_id": 7 } - ], - "plc_conversion_rate": 1.0, - "posting_date": "2013-01-23", - "price_list_currency": "INR", - "selling_price_list": "_Test Price List", + ], + "plc_conversion_rate": 1.0, + "posting_date": "2013-01-23", + "price_list_currency": "INR", + "selling_price_list": "_Test Price List", "territory": "_Test Territory" } -] \ No newline at end of file +] diff --git a/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py index 85e57822e2..8231650167 100644 --- a/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py +++ b/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py @@ -502,7 +502,8 @@ class TestSalesInvoice(unittest.TestCase): "warehouse": "_Test Warehouse - _TC" }) - pos_setting.insert() + if not frappe.db.exists("POS Setting", "_Test POS Setting"): + pos_setting.insert() def test_si_gl_entry_with_aii_and_update_stock_with_warehouse_but_no_account(self): self.clear_stock_account_balance() @@ -664,142 +665,9 @@ class TestSalesInvoice(unittest.TestCase): where against_invoice=%s""", si.name)) def test_recurring_invoice(self): - from frappe.utils import get_first_day, get_last_day, add_to_date, nowdate, getdate - from erpnext.accounts.utils import get_fiscal_year - today = nowdate() - base_si = frappe.copy_doc(test_records[0]) - base_si.update({ - "convert_into_recurring_invoice": 1, - "recurring_type": "Monthly", - "notification_email_address": "test@example.com, test1@example.com, test2@example.com", - "repeat_on_day_of_month": getdate(today).day, - "posting_date": today, - "fiscal_year": get_fiscal_year(today)[0], - "invoice_period_from_date": get_first_day(today), - "invoice_period_to_date": get_last_day(today) - }) + from erpnext.controllers.tests.test_recurring_document import test_recurring_document - # monthly - si1 = frappe.copy_doc(base_si) - si1.insert() - si1.submit() - self._test_recurring_invoice(si1, True) - - # monthly without a first and last day period - si2 = frappe.copy_doc(base_si) - si2.update({ - "invoice_period_from_date": today, - "invoice_period_to_date": add_to_date(today, days=30) - }) - si2.insert() - si2.submit() - self._test_recurring_invoice(si2, False) - - # quarterly - si3 = frappe.copy_doc(base_si) - si3.update({ - "recurring_type": "Quarterly", - "invoice_period_from_date": get_first_day(today), - "invoice_period_to_date": get_last_day(add_to_date(today, months=3)) - }) - si3.insert() - si3.submit() - self._test_recurring_invoice(si3, True) - - # quarterly without a first and last day period - si4 = frappe.copy_doc(base_si) - si4.update({ - "recurring_type": "Quarterly", - "invoice_period_from_date": today, - "invoice_period_to_date": add_to_date(today, months=3) - }) - si4.insert() - si4.submit() - self._test_recurring_invoice(si4, False) - - # yearly - si5 = frappe.copy_doc(base_si) - si5.update({ - "recurring_type": "Yearly", - "invoice_period_from_date": get_first_day(today), - "invoice_period_to_date": get_last_day(add_to_date(today, years=1)) - }) - si5.insert() - si5.submit() - self._test_recurring_invoice(si5, True) - - # yearly without a first and last day period - si6 = frappe.copy_doc(base_si) - si6.update({ - "recurring_type": "Yearly", - "invoice_period_from_date": today, - "invoice_period_to_date": add_to_date(today, years=1) - }) - si6.insert() - si6.submit() - self._test_recurring_invoice(si6, False) - - # change posting date but keep recuring day to be today - si7 = frappe.copy_doc(base_si) - si7.update({ - "posting_date": add_to_date(today, days=-1) - }) - si7.insert() - si7.submit() - - # setting so that _test function works - si7.posting_date = today - self._test_recurring_invoice(si7, True) - - def _test_recurring_invoice(self, base_si, first_and_last_day): - from frappe.utils import add_months, get_last_day - from erpnext.accounts.doctype.sales_invoice.sales_invoice \ - import manage_recurring_invoices, get_next_date - - no_of_months = ({"Monthly": 1, "Quarterly": 3, "Yearly": 12})[base_si.recurring_type] - - def _test(i): - self.assertEquals(i+1, frappe.db.sql("""select count(*) from `tabSales Invoice` - where recurring_id=%s and docstatus=1""", base_si.recurring_id)[0][0]) - - next_date = get_next_date(base_si.posting_date, no_of_months, - base_si.repeat_on_day_of_month) - - manage_recurring_invoices(next_date=next_date, commit=False) - - recurred_invoices = frappe.db.sql("""select name from `tabSales Invoice` - where recurring_id=%s and docstatus=1 order by name desc""", - base_si.recurring_id) - - self.assertEquals(i+2, len(recurred_invoices)) - - new_si = frappe.get_doc("Sales Invoice", recurred_invoices[0][0]) - - for fieldname in ["convert_into_recurring_invoice", "recurring_type", - "repeat_on_day_of_month", "notification_email_address"]: - self.assertEquals(base_si.get(fieldname), - new_si.get(fieldname)) - - self.assertEquals(new_si.posting_date, unicode(next_date)) - - self.assertEquals(new_si.invoice_period_from_date, - unicode(add_months(base_si.invoice_period_from_date, no_of_months))) - - if first_and_last_day: - self.assertEquals(new_si.invoice_period_to_date, - unicode(get_last_day(add_months(base_si.invoice_period_to_date, - no_of_months)))) - else: - self.assertEquals(new_si.invoice_period_to_date, - unicode(add_months(base_si.invoice_period_to_date, no_of_months))) - - - return new_si - - # if yearly, test 1 repetition, else test 5 repetitions - count = 1 if (no_of_months == 12) else 5 - for i in xrange(count): - base_si = _test(i) + test_recurring_document(self, test_records) def clear_stock_account_balance(self): frappe.db.sql("delete from `tabStock Ledger Entry`") diff --git a/erpnext/accounts/doctype/sales_invoice_item/sales_invoice_item.json b/erpnext/accounts/doctype/sales_invoice_item/sales_invoice_item.json index 527213be01..19c124f617 100644 --- a/erpnext/accounts/doctype/sales_invoice_item/sales_invoice_item.json +++ b/erpnext/accounts/doctype/sales_invoice_item/sales_invoice_item.json @@ -1,13 +1,12 @@ { "autoname": "INVD.######", - "creation": "2013-06-04 11:02:19.000000", + "creation": "2013-06-04 11:02:19", "docstatus": 0, "doctype": "DocType", "fields": [ { "fieldname": "barcode", "fieldtype": "Data", - "in_list_view": 0, "label": "Barcode", "permlevel": 0, "print_hide": 1, @@ -32,7 +31,7 @@ "fieldname": "item_name", "fieldtype": "Data", "in_filter": 0, - "in_list_view": 0, + "in_list_view": 1, "label": "Item Name", "oldfieldname": "item_name", "oldfieldtype": "Data", @@ -51,7 +50,6 @@ "fieldname": "customer_item_code", "fieldtype": "Data", "hidden": 1, - "in_list_view": 0, "label": "Customer's Item Code", "permlevel": 0, "print_hide": 1, @@ -73,7 +71,6 @@ { "fieldname": "quantity_and_rate", "fieldtype": "Section Break", - "in_list_view": 0, "label": "Quantity and Rate", "permlevel": 0 }, @@ -91,7 +88,6 @@ { "fieldname": "price_list_rate", "fieldtype": "Currency", - "in_list_view": 0, "label": "Price List Rate", "oldfieldname": "ref_rate", "oldfieldtype": "Currency", @@ -103,8 +99,8 @@ }, { "fieldname": "discount_percentage", - "fieldtype": "Float", - "in_list_view": 0, + "fieldtype": "Percent", + "in_list_view": 1, "label": "Discount (%)", "oldfieldname": "adj_rate", "oldfieldtype": "Float", @@ -120,7 +116,7 @@ { "fieldname": "stock_uom", "fieldtype": "Link", - "in_list_view": 0, + "in_list_view": 1, "label": "UOM", "options": "UOM", "permlevel": 0, @@ -129,7 +125,6 @@ { "fieldname": "base_price_list_rate", "fieldtype": "Currency", - "in_list_view": 0, "label": "Price List Rate (Company Currency)", "oldfieldname": "base_ref_rate", "oldfieldtype": "Currency", @@ -176,7 +171,6 @@ "fieldname": "base_rate", "fieldtype": "Currency", "in_filter": 0, - "in_list_view": 0, "label": "Rate (Company Currency)", "oldfieldname": "basic_rate", "oldfieldtype": "Currency", @@ -190,7 +184,6 @@ { "fieldname": "base_amount", "fieldtype": "Currency", - "in_list_view": 0, "label": "Amount (Company Currency)", "oldfieldname": "amount", "oldfieldtype": "Currency", @@ -201,17 +194,9 @@ "reqd": 1 }, { - "fieldname": "pricing_rule_for_price", + "fieldname": "pricing_rule", "fieldtype": "Link", - "label": "Pricing Rule For Price", - "options": "Pricing Rule", - "permlevel": 0, - "read_only": 1 - }, - { - "fieldname": "pricing_rule_for_discount", - "fieldtype": "Link", - "label": "Pricing Rule For Discount", + "label": "Pricing Rule", "options": "Pricing Rule", "permlevel": 0, "read_only": 1 @@ -219,7 +204,6 @@ { "fieldname": "accounting", "fieldtype": "Section Break", - "in_list_view": 0, "label": "Accounting", "permlevel": 0 }, @@ -227,7 +211,6 @@ "fieldname": "income_account", "fieldtype": "Link", "in_filter": 1, - "in_list_view": 0, "label": "Income Account", "oldfieldname": "income_account", "oldfieldtype": "Link", @@ -244,7 +227,6 @@ "fieldtype": "Link", "hidden": 0, "in_filter": 1, - "in_list_view": 0, "label": "Expense Account", "options": "Account", "permlevel": 0, @@ -262,7 +244,6 @@ "fieldname": "cost_center", "fieldtype": "Link", "in_filter": 1, - "in_list_view": 0, "label": "Cost Center", "oldfieldname": "cost_center", "oldfieldtype": "Link", @@ -271,13 +252,12 @@ "print_hide": 1, "print_width": "120px", "read_only": 0, - "reqd": 0, + "reqd": 1, "width": "120px" }, { "fieldname": "warehouse_and_reference", "fieldtype": "Section Break", - "in_list_view": 0, "label": "Warehouse and Reference", "permlevel": 0 }, @@ -285,7 +265,7 @@ "fieldname": "warehouse", "fieldtype": "Link", "hidden": 0, - "in_list_view": 0, + "in_list_view": 1, "label": "Warehouse", "oldfieldname": "warehouse", "oldfieldtype": "Link", @@ -310,6 +290,7 @@ { "fieldname": "batch_no", "fieldtype": "Link", + "in_list_view": 1, "label": "Batch No", "options": "Batch", "permlevel": 0, @@ -359,6 +340,7 @@ "permlevel": 0 }, { + "allow_on_submit": 1, "fieldname": "actual_qty", "fieldtype": "Float", "label": "Available Qty at Warehouse", @@ -380,6 +362,7 @@ "fieldname": "sales_order", "fieldtype": "Link", "in_filter": 1, + "in_list_view": 1, "label": "Sales Order", "no_copy": 1, "oldfieldname": "sales_order", @@ -456,9 +439,12 @@ ], "idx": 1, "istable": 1, - "modified": "2014-02-28 11:04:19.000000", + "modified": "2014-09-08 08:06:30.382092", "modified_by": "Administrator", "module": "Accounts", "name": "Sales Invoice Item", - "owner": "Administrator" + "owner": "Administrator", + "permissions": [], + "sort_field": "modified", + "sort_order": "DESC" } \ No newline at end of file diff --git a/erpnext/accounts/doctype/sales_taxes_and_charges/sales_taxes_and_charges.json b/erpnext/accounts/doctype/sales_taxes_and_charges/sales_taxes_and_charges.json index c47990f394..7bde84ff0c 100644 --- a/erpnext/accounts/doctype/sales_taxes_and_charges/sales_taxes_and_charges.json +++ b/erpnext/accounts/doctype/sales_taxes_and_charges/sales_taxes_and_charges.json @@ -1,431 +1,155 @@ { - "_last_update": null, - "_user_tags": null, - "allow_attach": null, - "allow_copy": null, - "allow_email": null, - "allow_import": null, - "allow_print": null, - "allow_rename": null, - "allow_trash": null, - "autoname": "INVTD.######", - "change_log": null, - "client_script": null, - "client_script_core": null, - "client_string": null, - "colour": null, - "creation": "2013-04-24 11:39:32", - "custom": null, - "default_print_format": null, - "description": null, - "docstatus": 0, - "doctype": "DocType", - "document_type": null, - "dt_template": null, + "autoname": "INVTD.######", + "creation": "2013-04-24 11:39:32", + "docstatus": 0, + "doctype": "DocType", "fields": [ { - "allow_on_submit": null, - "default": null, - "depends_on": null, - "description": null, - "fieldname": "charge_type", - "fieldtype": "Select", - "hidden": null, - "ignore_restrictions": null, - "in_filter": null, - "in_list_view": 1, - "label": "Type", - "no_column": null, - "no_copy": null, - "oldfieldname": "charge_type", - "oldfieldtype": "Select", - "options": "\nActual\nOn Net Total\nOn Previous Row Amount\nOn Previous Row Total", - "permlevel": 0, - "print_hide": null, - "print_width": null, - "read_only": null, - "report_hide": null, - "reqd": 1, - "search_index": null, - "set_only_once": null, - "trigger": null, - "width": null - }, + "fieldname": "charge_type", + "fieldtype": "Select", + "in_list_view": 1, + "label": "Type", + "oldfieldname": "charge_type", + "oldfieldtype": "Select", + "options": "\nActual\nOn Net Total\nOn Previous Row Amount\nOn Previous Row Total", + "permlevel": 0, + "reqd": 1 + }, { - "allow_on_submit": null, - "default": null, - "depends_on": "eval:[\"On Previous Row Amount\", \"On Previous Row Total\"].indexOf(doc.charge_type)!==-1", - "description": null, - "fieldname": "row_id", - "fieldtype": "Data", - "hidden": 0, - "ignore_restrictions": null, - "in_filter": null, - "in_list_view": null, - "label": "Reference Row #", - "no_column": null, - "no_copy": null, - "oldfieldname": "row_id", - "oldfieldtype": "Data", - "options": null, - "permlevel": 0, - "print_hide": null, - "print_width": null, - "read_only": null, - "report_hide": null, - "reqd": null, - "search_index": null, - "set_only_once": null, - "trigger": null, - "width": null - }, + "depends_on": "eval:[\"On Previous Row Amount\", \"On Previous Row Total\"].indexOf(doc.charge_type)!==-1", + "fieldname": "row_id", + "fieldtype": "Data", + "hidden": 0, + "label": "Reference Row #", + "oldfieldname": "row_id", + "oldfieldtype": "Data", + "permlevel": 0 + }, { - "allow_on_submit": null, - "default": null, - "depends_on": null, - "description": null, - "fieldname": "description", - "fieldtype": "Small Text", - "hidden": null, - "ignore_restrictions": null, - "in_filter": null, - "in_list_view": 1, - "label": "Description", - "no_column": null, - "no_copy": null, - "oldfieldname": "description", - "oldfieldtype": "Small Text", - "options": null, - "permlevel": 0, - "print_hide": null, - "print_width": "300px", - "read_only": null, - "report_hide": null, - "reqd": 1, - "search_index": null, - "set_only_once": null, - "trigger": null, + "fieldname": "description", + "fieldtype": "Small Text", + "in_list_view": 1, + "label": "Description", + "oldfieldname": "description", + "oldfieldtype": "Small Text", + "permlevel": 0, + "print_width": "300px", + "reqd": 1, "width": "300px" - }, + }, { - "allow_on_submit": null, - "default": null, - "depends_on": null, - "description": null, - "fieldname": "col_break_1", - "fieldtype": "Column Break", - "hidden": null, - "ignore_restrictions": null, - "in_filter": null, - "in_list_view": null, - "label": null, - "no_column": null, - "no_copy": null, - "oldfieldname": null, - "oldfieldtype": null, - "options": null, - "permlevel": 0, - "print_hide": null, - "print_width": null, - "read_only": null, - "report_hide": null, - "reqd": null, - "search_index": null, - "set_only_once": null, - "trigger": null, + "fieldname": "col_break_1", + "fieldtype": "Column Break", + "permlevel": 0, "width": "50%" - }, + }, { - "allow_on_submit": null, - "default": null, - "depends_on": null, - "description": null, - "fieldname": "account_head", - "fieldtype": "Link", - "hidden": null, - "ignore_restrictions": null, - "in_filter": null, - "in_list_view": 0, - "label": "Account Head", - "no_column": null, - "no_copy": null, - "oldfieldname": "account_head", - "oldfieldtype": "Link", - "options": "Account", - "permlevel": 0, - "print_hide": null, - "print_width": null, - "read_only": null, - "report_hide": null, - "reqd": 1, - "search_index": 1, - "set_only_once": null, - "trigger": null, - "width": null - }, + "fieldname": "account_head", + "fieldtype": "Link", + "in_list_view": 0, + "label": "Account Head", + "oldfieldname": "account_head", + "oldfieldtype": "Link", + "options": "Account", + "permlevel": 0, + "reqd": 1, + "search_index": 1 + }, { - "allow_on_submit": null, - "default": ":Company", - "depends_on": null, - "description": null, - "fieldname": "cost_center", - "fieldtype": "Link", - "hidden": null, - "ignore_restrictions": null, - "in_filter": null, - "in_list_view": 0, - "label": "Cost Center", - "no_column": null, - "no_copy": null, - "oldfieldname": "cost_center_other_charges", - "oldfieldtype": "Link", - "options": "Cost Center", - "permlevel": 0, - "print_hide": null, - "print_width": null, - "read_only": null, - "report_hide": null, - "reqd": null, - "search_index": null, - "set_only_once": null, - "trigger": null, - "width": null - }, + "default": ":Company", + "fieldname": "cost_center", + "fieldtype": "Link", + "in_list_view": 0, + "label": "Cost Center", + "oldfieldname": "cost_center_other_charges", + "oldfieldtype": "Link", + "options": "Cost Center", + "permlevel": 0 + }, { - "allow_on_submit": null, - "default": null, - "depends_on": null, - "description": null, - "fieldname": "rate", - "fieldtype": "Float", - "hidden": null, - "ignore_restrictions": null, - "in_filter": null, - "in_list_view": 1, - "label": "Rate", - "no_column": null, - "no_copy": null, - "oldfieldname": "rate", - "oldfieldtype": "Currency", - "options": null, - "permlevel": 0, - "print_hide": null, - "print_width": null, - "read_only": null, - "report_hide": null, - "reqd": 1, - "search_index": null, - "set_only_once": null, - "trigger": null, - "width": null - }, + "fieldname": "rate", + "fieldtype": "Float", + "in_list_view": 1, + "label": "Rate", + "oldfieldname": "rate", + "oldfieldtype": "Currency", + "permlevel": 0, + "reqd": 1 + }, { - "allow_on_submit": null, - "default": null, - "depends_on": null, - "description": null, - "fieldname": "tax_amount", - "fieldtype": "Currency", - "hidden": null, - "ignore_restrictions": null, - "in_filter": null, - "in_list_view": 1, - "label": "Amount", - "no_column": null, - "no_copy": null, - "oldfieldname": "tax_amount", - "oldfieldtype": "Currency", - "options": "Company:company:default_currency", - "permlevel": 0, - "print_hide": null, - "print_width": null, - "read_only": 1, - "report_hide": null, - "reqd": 0, - "search_index": null, - "set_only_once": null, - "trigger": null, - "width": null - }, + "fieldname": "tax_amount", + "fieldtype": "Currency", + "in_list_view": 1, + "label": "Amount", + "oldfieldname": "tax_amount", + "oldfieldtype": "Currency", + "options": "Company:company:default_currency", + "permlevel": 0, + "read_only": 1, + "reqd": 0 + }, { - "allow_on_submit": null, - "default": null, - "depends_on": null, - "description": null, - "fieldname": "total", - "fieldtype": "Currency", - "hidden": null, - "ignore_restrictions": null, - "in_filter": null, - "in_list_view": null, - "label": "Total", - "no_column": null, - "no_copy": null, - "oldfieldname": "total", - "oldfieldtype": "Currency", - "options": "Company:company:default_currency", - "permlevel": 0, - "print_hide": null, - "print_width": null, - "read_only": 1, - "report_hide": null, - "reqd": null, - "search_index": null, - "set_only_once": null, - "trigger": null, - "width": null - }, + "fieldname": "total", + "fieldtype": "Currency", + "label": "Total", + "oldfieldname": "total", + "oldfieldtype": "Currency", + "options": "Company:company:default_currency", + "permlevel": 0, + "read_only": 1 + }, { - "allow_on_submit": 0, - "default": null, - "depends_on": null, - "description": "If checked, the tax amount will be considered as already included in the Print Rate / Print Amount", - "fieldname": "included_in_print_rate", - "fieldtype": "Check", - "hidden": null, - "ignore_restrictions": null, - "in_filter": null, - "in_list_view": null, - "label": "Is this Tax included in Basic Rate?", - "no_column": null, - "no_copy": 0, - "oldfieldname": null, - "oldfieldtype": null, - "options": null, - "permlevel": 0, - "print_hide": 1, - "print_width": "150px", - "read_only": null, - "report_hide": 1, - "reqd": null, - "search_index": null, - "set_only_once": null, - "trigger": null, + "allow_on_submit": 0, + "description": "If checked, the tax amount will be considered as already included in the Print Rate / Print Amount", + "fieldname": "included_in_print_rate", + "fieldtype": "Check", + "label": "Is this Tax included in Basic Rate?", + "no_copy": 0, + "permlevel": 0, + "print_hide": 1, + "print_width": "150px", + "report_hide": 1, "width": "150px" - }, + }, { - "allow_on_submit": null, - "default": null, - "depends_on": null, - "description": null, - "fieldname": "tax_amount_after_discount_amount", - "fieldtype": "Currency", - "hidden": 1, - "ignore_restrictions": null, - "in_filter": null, - "in_list_view": null, - "label": "Tax Amount After Discount Amount", - "no_column": null, - "no_copy": null, - "oldfieldname": null, - "oldfieldtype": null, - "options": "Company:company:default_currency", - "permlevel": 0, - "print_hide": null, - "print_width": null, - "read_only": 1, - "report_hide": null, - "reqd": null, - "search_index": null, - "set_only_once": null, - "trigger": null, - "width": null - }, + "fieldname": "tax_amount_after_discount_amount", + "fieldtype": "Currency", + "hidden": 1, + "label": "Tax Amount After Discount Amount", + "options": "Company:company:default_currency", + "permlevel": 0, + "read_only": 1 + }, { - "allow_on_submit": null, - "default": null, - "depends_on": null, - "description": null, - "fieldname": "item_wise_tax_detail", - "fieldtype": "Small Text", - "hidden": 1, - "ignore_restrictions": null, - "in_filter": null, - "in_list_view": null, - "label": "Item Wise Tax Detail", - "no_column": null, - "no_copy": null, - "oldfieldname": "item_wise_tax_detail", - "oldfieldtype": "Small Text", - "options": null, - "permlevel": 0, - "print_hide": null, - "print_width": null, - "read_only": 1, - "report_hide": null, - "reqd": null, - "search_index": null, - "set_only_once": null, - "trigger": null, - "width": null - }, + "fieldname": "item_wise_tax_detail", + "fieldtype": "Small Text", + "hidden": 1, + "label": "Item Wise Tax Detail", + "oldfieldname": "item_wise_tax_detail", + "oldfieldtype": "Small Text", + "permlevel": 0, + "read_only": 1 + }, { - "allow_on_submit": null, - "default": null, - "depends_on": null, - "description": null, - "fieldname": "parenttype", - "fieldtype": "Data", - "hidden": 1, - "ignore_restrictions": null, - "in_filter": 1, - "in_list_view": null, - "label": "Parenttype", - "no_column": null, - "no_copy": null, - "oldfieldname": "parenttype", - "oldfieldtype": "Data", - "options": null, - "permlevel": 0, - "print_hide": 1, - "print_width": null, - "read_only": null, - "report_hide": null, - "reqd": null, - "search_index": 1, - "set_only_once": null, - "trigger": null, - "width": null + "fieldname": "parenttype", + "fieldtype": "Data", + "hidden": 1, + "in_filter": 1, + "label": "Parenttype", + "oldfieldname": "parenttype", + "oldfieldtype": "Data", + "permlevel": 0, + "print_hide": 1, + "search_index": 1 } - ], - "hide_heading": 1, - "hide_toolbar": null, - "icon": null, - "idx": 1, - "in_create": null, - "in_dialog": null, - "is_submittable": null, - "is_transaction_doc": null, - "issingle": null, - "istable": 1, - "max_attachments": null, - "menu_index": null, - "modified": "2014-04-14 18:40:48.450796", - "modified_by": "Administrator", - "module": "Accounts", - "name": "Sales Taxes and Charges", - "name_case": null, - "owner": "Administrator", - "parent": null, - "parent_node": null, - "parentfield": null, - "parenttype": null, - "permissions": [], - "plugin": null, - "print_outline": null, - "read_only": null, - "read_only_onload": null, - "search_fields": null, - "section_style": null, - "server_code": null, - "server_code_compiled": null, - "server_code_core": null, - "server_code_error": null, - "show_in_menu": null, - "smallicon": null, - "subject": null, - "tag_fields": null, - "title_field": null, - "use_template": null, - "version": null -} \ No newline at end of file + ], + "hide_heading": 1, + "idx": 1, + "istable": 1, + "modified": "2014-05-30 03:43:39.740638", + "modified_by": "Administrator", + "module": "Accounts", + "name": "Sales Taxes and Charges", + "owner": "Administrator", + "permissions": [] +} diff --git a/erpnext/accounts/doctype/sales_taxes_and_charges_master/sales_taxes_and_charges_master.json b/erpnext/accounts/doctype/sales_taxes_and_charges_master/sales_taxes_and_charges_master.json index 81cd189d35..47d385be6a 100644 --- a/erpnext/accounts/doctype/sales_taxes_and_charges_master/sales_taxes_and_charges_master.json +++ b/erpnext/accounts/doctype/sales_taxes_and_charges_master/sales_taxes_and_charges_master.json @@ -2,7 +2,7 @@ "allow_import": 1, "allow_rename": 1, "autoname": "field:title", - "creation": "2013-01-10 16:34:09.000000", + "creation": "2013-01-10 16:34:09", "description": "Standard tax template that can be applied to all Sales Transactions. This template can contain list of tax heads and also other expense / income heads like \"Shipping\", \"Insurance\", \"Handling\" etc.\n\n#### Note\n\nThe tax rate you define here will be the standard tax rate for all **Items**. If there are **Items** that have different rates, they must be added in the **Item Tax** table in the **Item** master.\n\n#### Description of Columns\n\n1. Calculation Type: \n - This can be on **Net Total** (that is the sum of basic amount).\n - **On Previous Row Total / Amount** (for cumulative taxes or charges). If you select this option, the tax will be applied as a percentage of the previous row (in the tax table) amount or total.\n - **Actual** (as mentioned).\n2. Account Head: The Account ledger under which this tax will be booked\n3. Cost Center: If the tax / charge is an income (like shipping) or expense it needs to be booked against a Cost Center.\n4. Description: Description of the tax (that will be printed in invoices / quotes).\n5. Rate: Tax rate.\n6. Amount: Tax amount.\n7. Total: Cumulative total to this point.\n8. Enter Row: If based on \"Previous Row Total\" you can select the row number which will be taken as a base for this calculation (default is the previous row).\n9. Is this Tax included in Basic Rate?: If you check this, it means that this tax will not be shown below the item table, but will be included in the Basic Rate in your main item table. This is useful where you want give a flat price (inclusive of all taxes) price to customers.", "docstatus": 0, "doctype": "DocType", @@ -12,6 +12,7 @@ "fieldname": "title", "fieldtype": "Data", "in_filter": 1, + "in_list_view": 1, "label": "Title", "oldfieldname": "title", "oldfieldtype": "Data", @@ -22,6 +23,7 @@ { "fieldname": "is_default", "fieldtype": "Check", + "in_list_view": 1, "label": "Default", "permlevel": 0 }, @@ -34,6 +36,7 @@ "fieldname": "company", "fieldtype": "Link", "in_filter": 1, + "in_list_view": 1, "label": "Company", "oldfieldname": "company", "oldfieldtype": "Link", @@ -69,7 +72,7 @@ ], "icon": "icon-money", "idx": 1, - "modified": "2014-01-28 12:28:27.000000", + "modified": "2014-05-27 03:49:19.023941", "modified_by": "Administrator", "module": "Accounts", "name": "Sales Taxes and Charges Master", @@ -77,7 +80,7 @@ "permissions": [ { "amend": 0, - "cancel": 0, + "apply_user_permissions": 1, "create": 0, "delete": 0, "email": 1, @@ -91,7 +94,6 @@ }, { "amend": 0, - "cancel": 0, "create": 1, "delete": 1, "email": 1, @@ -105,7 +107,6 @@ }, { "amend": 0, - "cancel": 0, "create": 1, "delete": 1, "email": 1, diff --git a/erpnext/accounts/doctype/shipping_rule/shipping_rule.json b/erpnext/accounts/doctype/shipping_rule/shipping_rule.json index d46bfdf37d..1701c88ba2 100644 --- a/erpnext/accounts/doctype/shipping_rule/shipping_rule.json +++ b/erpnext/accounts/doctype/shipping_rule/shipping_rule.json @@ -1,6 +1,6 @@ { "autoname": "Prompt", - "creation": "2013-06-25 11:48:03.000000", + "creation": "2013-06-25 11:48:03", "description": "Specify conditions to calculate shipping amount", "docstatus": 0, "doctype": "DocType", @@ -102,13 +102,14 @@ ], "icon": "icon-truck", "idx": 1, - "modified": "2014-01-20 17:49:27.000000", + "modified": "2014-05-27 03:49:19.387875", "modified_by": "Administrator", "module": "Accounts", "name": "Shipping Rule", "owner": "Administrator", "permissions": [ { + "apply_user_permissions": 1, "delete": 0, "email": 1, "permlevel": 0, @@ -118,6 +119,7 @@ "role": "Accounts User" }, { + "apply_user_permissions": 1, "delete": 0, "email": 1, "permlevel": 0, @@ -127,7 +129,6 @@ "role": "Sales User" }, { - "cancel": 1, "create": 1, "delete": 1, "email": 1, @@ -139,7 +140,6 @@ "write": 1 }, { - "cancel": 1, "create": 1, "delete": 1, "email": 1, diff --git a/erpnext/accounts/general_ledger.py b/erpnext/accounts/general_ledger.py index 3fbbe39e2c..211476822f 100644 --- a/erpnext/accounts/general_ledger.py +++ b/erpnext/accounts/general_ledger.py @@ -15,7 +15,10 @@ def make_gl_entries(gl_map, cancel=False, adv_adj=False, merge_entries=True, if gl_map: if not cancel: gl_map = process_gl_map(gl_map, merge_entries) - save_entries(gl_map, adv_adj, update_outstanding) + if gl_map and len(gl_map) > 1: + save_entries(gl_map, adv_adj, update_outstanding) + else: + frappe.throw(_("Incorrect number of General Ledger Entries found. You might have selected a wrong Account in the transaction.")) else: delete_gl_entries(gl_map, adv_adj=adv_adj, update_outstanding=update_outstanding) diff --git a/erpnext/accounts/page/accounts_browser/accounts_browser.js b/erpnext/accounts/page/accounts_browser/accounts_browser.js index ca6ebffdd1..ba8d747d72 100644 --- a/erpnext/accounts/page/accounts_browser/accounts_browser.js +++ b/erpnext/accounts/page/accounts_browser/accounts_browser.js @@ -25,16 +25,16 @@ pscript['onload_Accounts Browser'] = function(wrapper){ '
  • '+__('To add child nodes, explore tree and click on the node under which you want to add more nodes.')+'
  • '+ '
  • '+ __('Accounting Entries can be made against leaf nodes, called')+ - '' +__('Ledgers')+'.'+ __('Entries against') + - '' +__('Groups') + ''+ __('are not allowed.')+ + ' ' +__('Ledgers')+'. '+ __('Entries against ') + + '' +__('Groups') + ' '+ __('are not allowed.')+ '
  • '+ '
  • '+__('Please do NOT create Account (Ledgers) for Customers and Suppliers. They are created directly from the Customer / Supplier masters.')+'
  • '+ '
  • '+ - ''+__('To create a Bank Account:')+''+ + ''+__('To create a Bank Account')+': '+ __('Go to the appropriate group (usually Application of Funds > Current Assets > Bank Accounts and create a new Account Ledger (by clicking on Add Child) of type "Bank"')+ '
  • '+ '
  • '+ - ''+__('To create a Tax Account:')+''+ + ''+__('To create a Tax Account') +': '+ __('Go to the appropriate group (usually Source of Funds > Current Liabilities > Taxes and Duties and create a new Account Ledger (by clicking on Add Child) of type "Tax" and do mention the Tax rate.')+ '
  • '+ ''+ @@ -66,7 +66,7 @@ pscript['onload_Accounts Browser'] = function(wrapper){ $.each(r.message, function(i, v) { $('