Merge branch 'develop'

This commit is contained in:
Pratik Vyas 2014-09-09 15:10:47 +05:30
commit 6e566fb154
681 changed files with 49010 additions and 18162 deletions

View File

@ -14,8 +14,15 @@ install:
- sudo apt-get update - sudo apt-get update
- sudo apt-get purge -y mysql-common - sudo apt-get purge -y mysql-common
- sudo apt-get install mariadb-server mariadb-common libmariadbclient-dev - sudo apt-get install mariadb-server mariadb-common libmariadbclient-dev
- CFLAGS=-O0 pip install git+https://github.com/frappe/frappe.git@develop && - wget http://downloads.sourceforge.net/project/wkhtmltopdf/0.12.1/wkhtmltox-0.12.1_linux-precise-amd64.deb
- pip install --editable . - 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: script:
- cd ./test_sites/ - cd ./test_sites/
@ -23,9 +30,6 @@ script:
- frappe --reinstall - frappe --reinstall
- frappe --install_app erpnext --verbose - frappe --install_app erpnext --verbose
- frappe -b - frappe -b
- frappe --build_website
- frappe --serve_test & - frappe --serve_test &
- frappe --verbose --run_tests --app erpnext - 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

View File

@ -1,16 +1,19 @@
# Contributing to ERPNext # Contributing to Frappe / ERPNext
## Reporting issues ## 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. 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 ### 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. **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. **Include Screenshots if possible:** 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. **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 ### 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. 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 or spaces?
Tabs! Tabs!
### Copyright ### Copyright
Please see README.md Please see README.md

View File

@ -16,4 +16,5 @@ recursive-include erpnext *.md
recursive-include erpnext *.png recursive-include erpnext *.png
recursive-include erpnext *.py recursive-include erpnext *.py
recursive-include erpnext *.svg recursive-include erpnext *.svg
recursive-include erpnext/public *
recursive-exclude * *.pyc recursive-exclude * *.pyc

View File

@ -2,7 +2,7 @@
[https://erpnext.com](https://erpnext.com) [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) 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 ### Admin Login

View File

@ -1 +1 @@
__version__ = '4.0.2' from erpnext.__version__ import __version__

1
erpnext/__version__.py Normal file
View File

@ -0,0 +1 @@
__version__ = '4.3.0'

View File

@ -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', 'report_type', 'report_type');
cur_frm.add_fetch('parent_account', 'root_type', 'root_type');
cur_frm.cscript.account_type = function(doc, cdt, cdn) { cur_frm.cscript.account_type = function(doc, cdt, cdn) {
if(doc.group_or_ledger=='Ledger') { if(doc.group_or_ledger=='Ledger') {
cur_frm.toggle_display(['tax_rate'], doc.account_type == 'Tax'); 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' || cur_frm.toggle_display('master_name', doc.account_type=='Warehouse' ||
in_list(['Customer', 'Supplier'], doc.master_type)); in_list(['Customer', 'Supplier'], doc.master_type));
} }
} }
cur_frm.cscript.add_toolbar_buttons = function(doc) { 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') function() { frappe.set_route("Accounts Browser", "Account"); }, 'icon-sitemap')
if (cstr(doc.group_or_ledger) == 'Group') { if (cstr(doc.group_or_ledger) == 'Group') {
cur_frm.add_custom_button(__('Convert to Ledger'), 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') { } else if (cstr(doc.group_or_ledger) == 'Ledger') {
cur_frm.add_custom_button(__('Convert to Group'), cur_frm.add_custom_button(__('View Ledger'), function() {
function() { cur_frm.cscript.convert_to_group(); }, 'icon-retweet')
cur_frm.appframe.add_button(__('View Ledger'), function() {
frappe.route_options = { frappe.route_options = {
"account": doc.name, "account": doc.name,
"from_date": sys_defaults.year_start_date, "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"); frappe.set_route("query-report", "General Ledger");
}, "icon-table"); }, "icon-table");
cur_frm.add_custom_button(__('Convert to Group'),
function() { cur_frm.cscript.convert_to_group(); }, 'icon-retweet', 'btn-default')
} }
} }

View File

@ -1,322 +1,332 @@
{ {
"allow_copy": 1, "allow_copy": 1,
"allow_import": 1, "allow_import": 1,
"allow_rename": 1, "allow_rename": 1,
"creation": "2013-01-30 12:49:46", "creation": "2013-01-30 12:49:46",
"description": "Heads (or groups) against which Accounting Entries are made and balances are maintained.", "description": "Heads (or groups) against which Accounting Entries are made and balances are maintained.",
"docstatus": 0, "docstatus": 0,
"doctype": "DocType", "doctype": "DocType",
"document_type": "Master", "document_type": "Master",
"fields": [ "fields": [
{ {
"fieldname": "properties", "fieldname": "properties",
"fieldtype": "Section Break", "fieldtype": "Section Break",
"in_list_view": 0, "in_list_view": 0,
"label": "Account Details", "label": "Account Details",
"oldfieldtype": "Section Break", "oldfieldtype": "Section Break",
"permlevel": 0 "permlevel": 0
}, },
{ {
"fieldname": "column_break0", "fieldname": "column_break0",
"fieldtype": "Column Break", "fieldtype": "Column Break",
"in_list_view": 0, "in_list_view": 0,
"permlevel": 0, "permlevel": 0,
"width": "50%" "width": "50%"
}, },
{ {
"fieldname": "account_name", "fieldname": "account_name",
"fieldtype": "Data", "fieldtype": "Data",
"in_filter": 1, "in_filter": 1,
"in_list_view": 1, "in_list_view": 1,
"label": "Account Name", "label": "Account Name",
"no_copy": 1, "no_copy": 1,
"oldfieldname": "account_name", "oldfieldname": "account_name",
"oldfieldtype": "Data", "oldfieldtype": "Data",
"permlevel": 0, "permlevel": 0,
"read_only": 1, "read_only": 1,
"reqd": 1, "reqd": 1,
"search_index": 1 "search_index": 1
}, },
{ {
"default": "Ledger", "default": "Ledger",
"fieldname": "group_or_ledger", "fieldname": "group_or_ledger",
"fieldtype": "Select", "fieldtype": "Select",
"in_filter": 1, "in_filter": 1,
"in_list_view": 1, "in_list_view": 1,
"label": "Group or Ledger", "label": "Group or Ledger",
"oldfieldname": "group_or_ledger", "oldfieldname": "group_or_ledger",
"oldfieldtype": "Select", "oldfieldtype": "Select",
"options": "\nLedger\nGroup", "options": "\nLedger\nGroup",
"permlevel": 0, "permlevel": 0,
"read_only": 1, "read_only": 1,
"reqd": 1, "reqd": 1,
"search_index": 1 "search_index": 1
}, },
{ {
"fieldname": "company", "fieldname": "company",
"fieldtype": "Link", "fieldtype": "Link",
"in_filter": 1, "in_filter": 1,
"label": "Company", "label": "Company",
"oldfieldname": "company", "oldfieldname": "company",
"oldfieldtype": "Link", "oldfieldtype": "Link",
"options": "Company", "options": "Company",
"permlevel": 0, "permlevel": 0,
"read_only": 1, "read_only": 1,
"reqd": 1, "reqd": 1,
"search_index": 1 "search_index": 1
}, },
{ {
"fieldname": "column_break1", "fieldname": "column_break1",
"fieldtype": "Column Break", "fieldtype": "Column Break",
"permlevel": 0, "permlevel": 0,
"width": "50%" "width": "50%"
}, },
{ {
"fieldname": "parent_account", "fieldname": "parent_account",
"fieldtype": "Link", "fieldtype": "Link",
"ignore_restrictions": 1, "ignore_user_permissions": 1,
"label": "Parent Account", "label": "Parent Account",
"oldfieldname": "parent_account", "oldfieldname": "parent_account",
"oldfieldtype": "Link", "oldfieldtype": "Link",
"options": "Account", "options": "Account",
"permlevel": 0, "permlevel": 0,
"reqd": 1,
"search_index": 1 "search_index": 1
}, },
{ {
"fieldname": "report_type", "description": "Setting Account Type helps in selecting this Account in transactions.",
"fieldtype": "Select", "fieldname": "account_type",
"label": "Report Type", "fieldtype": "Select",
"options": "\nBalance Sheet\nProfit and Loss", "in_filter": 1,
"permlevel": 0 "label": "Account Type",
}, "oldfieldname": "account_type",
{ "oldfieldtype": "Select",
"description": "Setting Account Type helps in selecting this Account in transactions.", "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",
"fieldname": "account_type", "permlevel": 0,
"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,
"search_index": 0 "search_index": 0
}, },
{ {
"description": "Rate at which this tax is applied", "description": "Rate at which this tax is applied",
"fieldname": "tax_rate", "fieldname": "tax_rate",
"fieldtype": "Float", "fieldtype": "Float",
"hidden": 0, "hidden": 0,
"label": "Rate", "label": "Rate",
"oldfieldname": "tax_rate", "oldfieldname": "tax_rate",
"oldfieldtype": "Currency", "oldfieldtype": "Currency",
"permlevel": 0, "permlevel": 0,
"reqd": 0 "reqd": 0
}, },
{ {
"description": "If the account is frozen, entries are allowed to restricted users.", "description": "If the account is frozen, entries are allowed to restricted users.",
"fieldname": "freeze_account", "fieldname": "freeze_account",
"fieldtype": "Select", "fieldtype": "Select",
"label": "Frozen", "label": "Frozen",
"oldfieldname": "freeze_account", "oldfieldname": "freeze_account",
"oldfieldtype": "Select", "oldfieldtype": "Select",
"options": "No\nYes", "options": "No\nYes",
"permlevel": 0 "permlevel": 0
}, },
{ {
"fieldname": "credit_days", "fieldname": "credit_days",
"fieldtype": "Int", "fieldtype": "Int",
"hidden": 1, "hidden": 1,
"label": "Credit Days", "label": "Credit Days",
"oldfieldname": "credit_days", "oldfieldname": "credit_days",
"oldfieldtype": "Int", "oldfieldtype": "Int",
"permlevel": 0, "permlevel": 0,
"print_hide": 1 "print_hide": 1
}, },
{ {
"fieldname": "credit_limit", "fieldname": "credit_limit",
"fieldtype": "Currency", "fieldtype": "Currency",
"hidden": 1, "hidden": 1,
"label": "Credit Limit", "label": "Credit Limit",
"oldfieldname": "credit_limit", "oldfieldname": "credit_limit",
"oldfieldtype": "Currency", "oldfieldtype": "Currency",
"options": "Company:company:default_currency", "options": "Company:company:default_currency",
"permlevel": 0, "permlevel": 0,
"print_hide": 1 "print_hide": 1
}, },
{ {
"description": "If this Account represents a Customer, Supplier or Employee, set it here.", "description": "If this Account represents a Customer, Supplier or Employee, set it here.",
"fieldname": "master_type", "fieldname": "master_type",
"fieldtype": "Select", "fieldtype": "Select",
"label": "Master Type", "label": "Master Type",
"oldfieldname": "master_type", "oldfieldname": "master_type",
"oldfieldtype": "Select", "oldfieldtype": "Select",
"options": "\nSupplier\nCustomer\nEmployee", "options": "\nSupplier\nCustomer\nEmployee",
"permlevel": 0 "permlevel": 0
}, },
{ {
"fieldname": "master_name", "fieldname": "master_name",
"fieldtype": "Link", "fieldtype": "Link",
"label": "Master Name", "label": "Master Name",
"oldfieldname": "master_name", "oldfieldname": "master_name",
"oldfieldtype": "Link", "oldfieldtype": "Link",
"options": "[Select]", "options": "[Select]",
"permlevel": 0 "permlevel": 0
}, },
{ {
"fieldname": "balance_must_be", "fieldname": "balance_must_be",
"fieldtype": "Select", "fieldtype": "Select",
"label": "Balance must be", "label": "Balance must be",
"options": "\nDebit\nCredit", "options": "\nDebit\nCredit",
"permlevel": 0 "permlevel": 0
}, },
{ {
"fieldname": "lft", "fieldname": "root_type",
"fieldtype": "Int", "fieldtype": "Select",
"hidden": 1, "label": "Root Type",
"label": "Lft", "options": "\nAsset\nLiability\nIncome\nExpense\nEquity",
"permlevel": 0, "permlevel": 0,
"print_hide": 1,
"read_only": 1 "read_only": 1
}, },
{ {
"fieldname": "rgt", "fieldname": "report_type",
"fieldtype": "Int", "fieldtype": "Select",
"hidden": 1, "label": "Report Type",
"label": "Rgt", "options": "\nBalance Sheet\nProfit and Loss",
"permlevel": 0, "permlevel": 0,
"print_hide": 1,
"read_only": 1 "read_only": 1
}, },
{ {
"fieldname": "old_parent", "fieldname": "lft",
"fieldtype": "Data", "fieldtype": "Int",
"hidden": 1, "hidden": 1,
"label": "Old Parent", "label": "Lft",
"permlevel": 0, "permlevel": 0,
"print_hide": 1, "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 "read_only": 1
} }
], ],
"icon": "icon-money", "icon": "icon-money",
"idx": 1, "idx": 1,
"in_create": 1, "in_create": 1,
"modified": "2014-05-12 17:03:19.733139", "modified": "2014-06-19 18:27:58.109303",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Accounts", "module": "Accounts",
"name": "Account", "name": "Account",
"owner": "Administrator", "owner": "Administrator",
"permissions": [ "permissions": [
{ {
"amend": 0, "amend": 0,
"cancel": 0, "apply_user_permissions": 1,
"create": 1, "create": 1,
"delete": 1, "delete": 1,
"email": 1, "email": 1,
"export": 1, "export": 1,
"import": 1, "import": 1,
"permlevel": 0, "permlevel": 0,
"print": 1, "print": 1,
"read": 1, "read": 1,
"report": 1, "report": 1,
"role": "Accounts User", "role": "Accounts User",
"submit": 0, "submit": 0,
"write": 1 "write": 1
}, },
{ {
"amend": 0, "amend": 0,
"cancel": 0, "apply_user_permissions": 1,
"create": 0, "create": 0,
"delete": 0, "delete": 0,
"email": 1, "email": 1,
"permlevel": 0, "permlevel": 0,
"print": 1, "print": 1,
"read": 1, "read": 1,
"report": 1, "report": 1,
"role": "Auditor", "role": "Auditor",
"submit": 0, "submit": 0,
"write": 0 "write": 0
}, },
{ {
"amend": 0, "amend": 0,
"cancel": 0, "apply_user_permissions": 1,
"create": 0, "create": 0,
"delete": 0, "delete": 0,
"email": 1, "email": 1,
"permlevel": 0, "permlevel": 0,
"print": 1, "print": 1,
"read": 1, "read": 1,
"report": 1, "report": 1,
"role": "Sales User", "role": "Sales User",
"submit": 0, "submit": 0,
"write": 0 "write": 0
}, },
{ {
"amend": 0, "amend": 0,
"cancel": 0, "apply_user_permissions": 1,
"create": 0, "create": 0,
"delete": 0, "delete": 0,
"email": 1, "email": 1,
"permlevel": 0, "permlevel": 0,
"print": 1, "print": 1,
"read": 1, "read": 1,
"report": 1, "report": 1,
"role": "Purchase User", "role": "Purchase User",
"submit": 0, "submit": 0,
"write": 0 "write": 0
}, },
{ {
"amend": 0, "amend": 0,
"cancel": 0, "cancel": 0,
"create": 0, "create": 0,
"delete": 0, "delete": 0,
"permlevel": 2, "permlevel": 2,
"read": 1, "read": 1,
"report": 1, "report": 1,
"role": "Auditor", "role": "Auditor",
"submit": 0, "submit": 0,
"write": 0 "write": 0
}, },
{ {
"amend": 0, "amend": 0,
"cancel": 0, "apply_user_permissions": 0,
"create": 1, "create": 1,
"delete": 1, "delete": 1,
"email": 1, "email": 1,
"export": 1, "export": 1,
"import": 1, "import": 1,
"permlevel": 0, "permlevel": 0,
"print": 1, "print": 1,
"read": 1, "read": 1,
"report": 1, "report": 1,
"restrict": 1, "role": "Accounts Manager",
"role": "Accounts Manager", "set_user_permissions": 1,
"submit": 0, "submit": 0,
"write": 1 "write": 1
}, },
{ {
"amend": 0, "amend": 0,
"cancel": 0, "cancel": 0,
"create": 0, "create": 0,
"delete": 0, "delete": 0,
"permlevel": 2, "permlevel": 2,
"read": 1, "read": 1,
"report": 1, "report": 1,
"role": "Accounts Manager", "role": "Accounts Manager",
"submit": 0, "submit": 0,
"write": 1 "write": 1
}, },
{ {
"amend": 0, "amend": 0,
"cancel": 0, "cancel": 0,
"create": 0, "create": 0,
"delete": 0, "delete": 0,
"permlevel": 2, "permlevel": 2,
"read": 1, "read": 1,
"report": 1, "report": 1,
"role": "Accounts User", "role": "Accounts User",
"submit": 0, "submit": 0,
"write": 0 "write": 0
} }
], ],
"search_fields": "group_or_ledger" "search_fields": "group_or_ledger"
} }

View File

@ -11,11 +11,11 @@ class Account(Document):
nsm_parent_field = 'parent_account' nsm_parent_field = 'parent_account'
def onload(self): def onload(self):
frozen_accounts_modifier = frappe.db.get_value("Accounts Settings", "Accounts Settings", "frozen_accounts_modifier") frozen_accounts_modifier = frappe.db.get_value("Accounts Settings", "Accounts Settings",
if frozen_accounts_modifier in frappe.user.get_roles(): "frozen_accounts_modifier")
if not frozen_accounts_modifier or frozen_accounts_modifier in frappe.user.get_roles():
self.get("__onload").can_freeze_account = True self.get("__onload").can_freeze_account = True
def autoname(self): def autoname(self):
self.name = self.account_name.strip() + ' - ' + \ self.name = self.account_name.strip() + ' - ' + \
frappe.db.get_value("Company", self.company, "abbr") frappe.db.get_value("Company", self.company, "abbr")
@ -30,6 +30,7 @@ class Account(Document):
self.validate_mandatory() self.validate_mandatory()
self.validate_warehouse_account() self.validate_warehouse_account()
self.validate_frozen_accounts_modifier() self.validate_frozen_accounts_modifier()
self.validate_balance_must_be_debit_or_credit()
def validate_master_name(self): def validate_master_name(self):
if self.master_type in ('Customer', 'Supplier') or self.account_type == "Warehouse": if self.master_type in ('Customer', 'Supplier') or self.account_type == "Warehouse":
@ -39,19 +40,24 @@ class Account(Document):
throw(_("Invalid Master Name")) throw(_("Invalid Master Name"))
def validate_parent(self): 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: if self.parent_account:
par = frappe.db.get_value("Account", 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: if not par:
throw(_("Parent account does not exist")) throw(_("Account {0}: Parent account {1} does not exist").format(self.name, self.parent_account))
elif par["name"] == self.name: elif par.name == self.name:
throw(_("You can not assign itself as parent account")) throw(_("Account {0}: You can not assign itself as parent account").format(self.name))
elif par["group_or_ledger"] != 'Group': elif par.group_or_ledger != 'Group':
throw(_("Parent account can not be a ledger")) 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"]: if par.report_type:
self.report_type = par["report_type"] self.report_type = par.report_type
if par.root_type:
self.root_type = par.root_type
def validate_root_details(self): def validate_root_details(self):
#does not exists parent #does not exists parent
@ -67,6 +73,16 @@ class Account(Document):
frozen_accounts_modifier not in frappe.user.get_roles(): frozen_accounts_modifier not in frappe.user.get_roles():
throw(_("You are not authorized to set Frozen value")) 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): def convert_group_to_ledger(self):
if self.check_if_child_exists(): if self.check_if_child_exists():
throw(_("Account with child nodes cannot be converted to ledger")) throw(_("Account with child nodes cannot be converted to ledger"))
@ -99,6 +115,9 @@ class Account(Document):
if not self.report_type: if not self.report_type:
throw(_("Report Type is mandatory")) throw(_("Report Type is mandatory"))
if not self.root_type:
throw(_("Root Type is mandatory"))
def validate_warehouse_account(self): def validate_warehouse_account(self):
if not cint(frappe.defaults.get_global_default("auto_accounting_for_stock")): if not cint(frappe.defaults.get_global_default("auto_accounting_for_stock")):
return return
@ -146,7 +165,7 @@ class Account(Document):
# If outstanding greater than credit limit and not authorized person raise exception # If outstanding greater than credit limit and not authorized person raise exception
if credit_limit > 0 and flt(total_outstanding) > credit_limit \ if credit_limit > 0 and flt(total_outstanding) > credit_limit \
and not self.get_authorized_user(): 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): def validate_due_date(self, posting_date, due_date):
credit_days = (self.credit_days or frappe.db.get_value("Company", self.company, "credit_days")) 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)) throw(_("Account {0} does not exist").format(new))
val = list(frappe.db.get_value("Account", new_account, 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]: 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, Report Type, Company""")) throw(_("""Merging is only possible if following properties are same in both records. Group or Ledger, Root Type, Company"""))
return new_account return new_account

View File

@ -14,6 +14,7 @@ def _make_test_records(verbose):
["_Test Account Stock Expenses", "Direct Expenses", "Group", None], ["_Test Account Stock Expenses", "Direct Expenses", "Group", None],
["_Test Account Shipping Charges", "_Test Account Stock Expenses", "Ledger", "Chargeable"], ["_Test Account Shipping Charges", "_Test Account Stock Expenses", "Ledger", "Chargeable"],
["_Test Account Customs Duty", "_Test Account Stock Expenses", "Ledger", "Tax"], ["_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], ["_Test Account Tax Assets", "Current Assets", "Group", None],

View File

@ -85,7 +85,7 @@
"icon": "icon-check", "icon": "icon-check",
"idx": 1, "idx": 1,
"issingle": 1, "issingle": 1,
"modified": "2014-05-06 16:26:08.984595", "modified": "2014-05-27 03:37:21.783216",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Accounts", "module": "Accounts",
"name": "Bank Reconciliation", "name": "Bank Reconciliation",
@ -93,6 +93,7 @@
"permissions": [ "permissions": [
{ {
"amend": 0, "amend": 0,
"apply_user_permissions": 0,
"cancel": 0, "cancel": 0,
"create": 1, "create": 1,
"permlevel": 0, "permlevel": 0,

View File

@ -24,7 +24,8 @@ class BankReconciliation(Document):
`tabJournal Voucher` t1, `tabJournal Voucher Detail` t2 `tabJournal Voucher` t1, `tabJournal Voucher Detail` t2
where where
t2.parent = t1.name and t2.account = %s 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) ('%s', '%s', '%s', condition), (self.bank_account, self.from_date, self.to_date), as_dict=1)
self.set('entries', []) self.set('entries', [])

View File

@ -1,5 +1,5 @@
{ {
"allow_attach": 1, "allow_import": 1,
"autoname": "naming_series:", "autoname": "naming_series:",
"creation": "2013-03-07 11:55:06", "creation": "2013-03-07 11:55:06",
"docstatus": 0, "docstatus": 0,
@ -126,7 +126,7 @@
{ {
"fieldname": "amended_from", "fieldname": "amended_from",
"fieldtype": "Link", "fieldtype": "Link",
"ignore_restrictions": 1, "ignore_user_permissions": 1,
"label": "Amended From", "label": "Amended From",
"no_copy": 1, "no_copy": 1,
"options": "C-Form", "options": "C-Form",
@ -139,13 +139,14 @@
"idx": 1, "idx": 1,
"is_submittable": 1, "is_submittable": 1,
"max_attachments": 3, "max_attachments": 3,
"modified": "2014-05-09 02:18:00.162685", "modified": "2014-09-05 12:58:43.333698",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Accounts", "module": "Accounts",
"name": "C-Form", "name": "C-Form",
"owner": "Administrator", "owner": "Administrator",
"permissions": [ "permissions": [
{ {
"apply_user_permissions": 1,
"create": 1, "create": 1,
"email": 1, "email": 1,
"permlevel": 0, "permlevel": 0,

View File

@ -55,22 +55,12 @@ class CForm(Document):
def get_invoice_details(self, invoice_no): def get_invoice_details(self, invoice_no):
""" Pull details from invoices for referrence """ """ Pull details from invoices for referrence """
if invoice_no:
inv = frappe.db.get_value("Sales Invoice", invoice_no, inv = frappe.db.get_value("Sales Invoice", invoice_no,
["posting_date", "territory", "net_total", "grand_total"], as_dict=True) ["posting_date", "territory", "net_total", "grand_total"], as_dict=True)
return { return {
'invoice_date' : inv.posting_date, 'invoice_date' : inv.posting_date,
'territory' : inv.territory, 'territory' : inv.territory,
'net_total' : inv.net_total, 'net_total' : inv.net_total,
'grand_total' : inv.grand_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]))

View File

@ -9,7 +9,7 @@ from __future__ import unicode_literals
import os, json import os, json
import ast import ast
from xml.etree import ElementTree as ET 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 from frappe.utils import cstr
import frappe import frappe

View File

@ -5,6 +5,7 @@ from __future__ import unicode_literals
import frappe, os, json import frappe, os, json
def import_charts(): def import_charts():
print "Importing Chart of Accounts"
frappe.db.sql("""delete from `tabChart of Accounts`""") frappe.db.sql("""delete from `tabChart of Accounts`""")
charts_dir = os.path.join(os.path.dirname(__file__), "charts") charts_dir = os.path.join(os.path.dirname(__file__), "charts")
for fname in os.listdir(charts_dir): for fname in os.listdir(charts_dir):
@ -19,8 +20,8 @@ def import_charts():
"source_file": fname, "source_file": fname,
"country": country "country": country
}).insert() }).insert()
print doc.name.encode("utf-8") #print doc.name.encode("utf-8")
else: #else:
print "No chart for: " + chart.get("name").encode("utf-8") #print "No chart for: " + chart.get("name").encode("utf-8")
frappe.db.commit() frappe.db.commit()

View File

@ -64,10 +64,12 @@ cur_frm.cscript.parent_cost_center = function(doc, cdt, cdn) {
cur_frm.cscript.hide_unhide_group_ledger = function(doc) { cur_frm.cscript.hide_unhide_group_ledger = function(doc) {
if (cstr(doc.group_or_ledger) == 'Group') { if (cstr(doc.group_or_ledger) == 'Group') {
cur_frm.add_custom_button(__('Convert to Ledger'), 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') { } else if (cstr(doc.group_or_ledger) == 'Ledger') {
cur_frm.add_custom_button(__('Convert to Group'), 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")
} }
} }

View File

@ -31,7 +31,7 @@
{ {
"fieldname": "parent_cost_center", "fieldname": "parent_cost_center",
"fieldtype": "Link", "fieldtype": "Link",
"ignore_restrictions": 1, "ignore_user_permissions": 1,
"in_list_view": 1, "in_list_view": 1,
"label": "Parent Cost Center", "label": "Parent Cost Center",
"oldfieldname": "parent_cost_center", "oldfieldname": "parent_cost_center",
@ -131,7 +131,7 @@
"fieldname": "old_parent", "fieldname": "old_parent",
"fieldtype": "Link", "fieldtype": "Link",
"hidden": 1, "hidden": 1,
"ignore_restrictions": 1, "ignore_user_permissions": 1,
"label": "old_parent", "label": "old_parent",
"no_copy": 1, "no_copy": 1,
"oldfieldname": "old_parent", "oldfieldname": "old_parent",
@ -144,8 +144,8 @@
], ],
"icon": "icon-money", "icon": "icon-money",
"idx": 1, "idx": 1,
"in_create": 1, "in_create": 0,
"modified": "2014-05-07 06:37:48.038993", "modified": "2014-08-26 12:16:11.163750",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Accounts", "module": "Accounts",
"name": "Cost Center", "name": "Cost Center",
@ -153,7 +153,6 @@
"permissions": [ "permissions": [
{ {
"amend": 0, "amend": 0,
"cancel": 0,
"create": 1, "create": 1,
"delete": 1, "delete": 1,
"email": 1, "email": 1,
@ -167,7 +166,7 @@
}, },
{ {
"amend": 0, "amend": 0,
"cancel": 0, "apply_user_permissions": 1,
"create": 0, "create": 0,
"delete": 0, "delete": 0,
"email": 1, "email": 1,
@ -180,16 +179,19 @@
"write": 0 "write": 0
}, },
{ {
"apply_user_permissions": 1,
"permlevel": 0, "permlevel": 0,
"read": 1, "read": 1,
"role": "Sales User" "role": "Sales User"
}, },
{ {
"apply_user_permissions": 1,
"permlevel": 0, "permlevel": 0,
"read": 1, "read": 1,
"role": "Purchase User" "role": "Purchase User"
}, },
{ {
"apply_user_permissions": 1,
"permlevel": 0, "permlevel": 0,
"read": 1, "read": 1,
"role": "Material User" "role": "Material User"

View File

@ -15,5 +15,12 @@
"doctype": "Cost Center", "doctype": "Cost Center",
"group_or_ledger": "Ledger", "group_or_ledger": "Ledger",
"parent_cost_center": "_Test Company - _TC" "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"
} }
] ]

View File

@ -14,7 +14,8 @@ $.extend(cur_frm.cscript, {
this.frm.toggle_enable('year_end_date', doc.__islocal) this.frm.toggle_enable('year_end_date', doc.__islocal)
if (!doc.__islocal && (doc.name != sys_defaults.fiscal_year)) { 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'")); this.frm.set_intro(__("To set this Fiscal Year as Default, click on 'Set as Default'"));
} else { } else {
this.frm.set_intro(""); this.frm.set_intro("");

View File

@ -1,7 +1,7 @@
{ {
"allow_import": 1, "allow_import": 1,
"autoname": "field:year", "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**.", "description": "**Fiscal Year** represents a Financial Year. All accounting entries and other major transactions are tracked against **Fiscal Year**.",
"docstatus": 0, "docstatus": 0,
"doctype": "DocType", "doctype": "DocType",
@ -11,6 +11,7 @@
"description": "For e.g. 2012, 2012-13", "description": "For e.g. 2012, 2012-13",
"fieldname": "year", "fieldname": "year",
"fieldtype": "Data", "fieldtype": "Data",
"in_list_view": 1,
"label": "Year Name", "label": "Year Name",
"oldfieldname": "year", "oldfieldname": "year",
"oldfieldtype": "Data", "oldfieldtype": "Data",
@ -20,6 +21,7 @@
{ {
"fieldname": "year_start_date", "fieldname": "year_start_date",
"fieldtype": "Date", "fieldtype": "Date",
"in_list_view": 1,
"label": "Year Start Date", "label": "Year Start Date",
"no_copy": 1, "no_copy": 1,
"oldfieldname": "year_start_date", "oldfieldname": "year_start_date",
@ -30,6 +32,7 @@
{ {
"fieldname": "year_end_date", "fieldname": "year_end_date",
"fieldtype": "Date", "fieldtype": "Date",
"in_list_view": 1,
"label": "Year End Date", "label": "Year End Date",
"no_copy": 1, "no_copy": 1,
"permlevel": 0, "permlevel": 0,
@ -40,6 +43,7 @@
"description": "Entries are not allowed against this Fiscal Year if the year is closed.", "description": "Entries are not allowed against this Fiscal Year if the year is closed.",
"fieldname": "is_fiscal_year_closed", "fieldname": "is_fiscal_year_closed",
"fieldtype": "Select", "fieldtype": "Select",
"in_list_view": 1,
"label": "Year Closed", "label": "Year Closed",
"no_copy": 1, "no_copy": 1,
"oldfieldname": "is_fiscal_year_closed", "oldfieldname": "is_fiscal_year_closed",
@ -51,14 +55,13 @@
], ],
"icon": "icon-calendar", "icon": "icon-calendar",
"idx": 1, "idx": 1,
"modified": "2014-01-20 17:48:46.000000", "modified": "2014-07-14 05:30:56.843180",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Accounts", "module": "Accounts",
"name": "Fiscal Year", "name": "Fiscal Year",
"owner": "Administrator", "owner": "Administrator",
"permissions": [ "permissions": [
{ {
"cancel": 0,
"create": 1, "create": 1,
"delete": 1, "delete": 1,
"email": 1, "email": 1,
@ -71,6 +74,7 @@
"write": 1 "write": 1
}, },
{ {
"apply_user_permissions": 1,
"delete": 0, "delete": 0,
"email": 1, "email": 1,
"permlevel": 0, "permlevel": 0,
@ -78,5 +82,7 @@
"read": 1, "read": 1,
"role": "All" "role": "All"
} }
] ],
"sort_field": "name",
"sort_order": "DESC"
} }

View File

@ -25,15 +25,15 @@ class FiscalYear(Document):
if year_start_end_dates: 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]: 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): def on_update(self):
# validate year start date and year end date # validate year start date and year end date
if getdate(self.year_start_date) > getdate(self.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: 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 year_start_end_dates = frappe.db.sql("""select name, year_start_date, year_end_date
from `tabFiscal Year` where name!=%s""", (self.name)) 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: for fiscal_year, ysd, yed in year_start_end_dates:
if (getdate(self.year_start_date) == ysd and getdate(self.year_end_date) == yed) \ if (getdate(self.year_start_date) == ysd and getdate(self.year_end_date) == yed) \
and (not frappe.flags.in_test): 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))

View File

@ -86,44 +86,47 @@
"oldfieldtype": "Text", "oldfieldtype": "Text",
"permlevel": 0 "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", "fieldname": "against_voucher_type",
"fieldtype": "Data", "fieldtype": "Link",
"in_filter": 0, "in_filter": 0,
"label": "Against Voucher Type", "label": "Against Voucher Type",
"oldfieldname": "against_voucher_type", "oldfieldname": "against_voucher_type",
"oldfieldtype": "Data", "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, "permlevel": 0,
"search_index": 0 "search_index": 0
}, },
{ {
"fieldname": "voucher_type", "fieldname": "voucher_type",
"fieldtype": "Select", "fieldtype": "Link",
"in_filter": 1, "in_filter": 1,
"label": "Voucher Type", "label": "Voucher Type",
"oldfieldname": "voucher_type", "oldfieldname": "voucher_type",
"oldfieldtype": "Select", "oldfieldtype": "Select",
"options": "Journal Voucher\nSales Invoice\nPurchase Invoice", "options": "DocType",
"permlevel": 0, "permlevel": 0,
"search_index": 0 "search_index": 0
}, },
{ {
"fieldname": "voucher_no", "fieldname": "voucher_no",
"fieldtype": "Data", "fieldtype": "Dynamic Link",
"in_filter": 1, "in_filter": 1,
"label": "Voucher No", "label": "Voucher No",
"oldfieldname": "voucher_no", "oldfieldname": "voucher_no",
"oldfieldtype": "Data", "oldfieldtype": "Data",
"options": "voucher_type",
"permlevel": 0, "permlevel": 0,
"search_index": 1 "search_index": 1
}, },
@ -186,7 +189,7 @@
"icon": "icon-list", "icon": "icon-list",
"idx": 1, "idx": 1,
"in_create": 1, "in_create": 1,
"modified": "2014-05-09 02:16:29.981405", "modified": "2014-06-23 08:07:30.678730",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Accounts", "module": "Accounts",
"name": "GL Entry", "name": "GL Entry",
@ -194,9 +197,10 @@
"permissions": [ "permissions": [
{ {
"amend": 0, "amend": 0,
"cancel": 0, "apply_user_permissions": 1,
"create": 0, "create": 0,
"email": 1, "email": 1,
"export": 1,
"permlevel": 0, "permlevel": 0,
"print": 1, "print": 1,
"read": 1, "read": 1,
@ -207,9 +211,9 @@
}, },
{ {
"amend": 0, "amend": 0,
"cancel": 0,
"create": 0, "create": 0,
"email": 1, "email": 1,
"export": 1,
"permlevel": 0, "permlevel": 0,
"print": 1, "print": 1,
"read": 1, "read": 1,
@ -217,17 +221,6 @@
"role": "Accounts Manager", "role": "Accounts Manager",
"submit": 0, "submit": 0,
"write": 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", "search_fields": "voucher_no,account,posting_date,against_voucher",

View File

@ -7,6 +7,11 @@ erpnext.accounts.JournalVoucher = frappe.ui.form.Controller.extend({
onload: function() { onload: function() {
this.load_defaults(); this.load_defaults();
this.setup_queries(); this.setup_queries();
this.setup_balance_formatter();
},
onload_post_render: function() {
cur_frm.get_field("entries").grid.set_multiple_add("account");
}, },
load_defaults: function() { 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 ? ('<label>' + (value > 0.0 ? __("Dr") : __("Cr")) + '</label>') : "";
return "<div style='text-align: right'>"
+ ((value==null || value==="") ? "" : format_currency(Math.abs(value), currency))
+ " " + dr_or_cr
+ "</div>";
}
},
against_voucher: function(doc, cdt, cdn) { against_voucher: function(doc, cdt, cdn) {
var d = frappe.get_doc(cdt, cdn); var d = frappe.get_doc(cdt, cdn);
if (d.against_voucher && !flt(d.debit)) { 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); cur_frm.script_manager.make(erpnext.accounts.JournalVoucher);

View File

@ -123,12 +123,6 @@
"permlevel": 0, "permlevel": 0,
"read_only": 1 "read_only": 1
}, },
{
"fieldname": "column_break99",
"fieldtype": "Column Break",
"permlevel": 0,
"read_only": 0
},
{ {
"fieldname": "difference", "fieldname": "difference",
"fieldtype": "Currency", "fieldtype": "Currency",
@ -150,10 +144,8 @@
"read_only": 0 "read_only": 0
}, },
{ {
"fieldname": "reference", "fieldname": "column_break99",
"fieldtype": "Section Break", "fieldtype": "Column Break",
"label": "Reference",
"options": "icon-pushpin",
"permlevel": 0, "permlevel": 0,
"read_only": 0 "read_only": 0
}, },
@ -181,6 +173,31 @@
"permlevel": 0, "permlevel": 0,
"read_only": 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", "fieldname": "clearance_date",
"fieldtype": "Date", "fieldtype": "Date",
@ -194,23 +211,6 @@
"read_only": 1, "read_only": 1,
"search_index": 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", "description": "User Remark will be added to Auto Remark",
"fieldname": "remark", "fieldname": "remark",
@ -224,6 +224,12 @@
"read_only": 1, "read_only": 1,
"reqd": 0 "reqd": 0
}, },
{
"fieldname": "column_break98",
"fieldtype": "Column Break",
"permlevel": 0,
"read_only": 0
},
{ {
"fieldname": "bill_no", "fieldname": "bill_no",
"fieldtype": "Data", "fieldtype": "Data",
@ -426,7 +432,7 @@
{ {
"fieldname": "amended_from", "fieldname": "amended_from",
"fieldtype": "Link", "fieldtype": "Link",
"ignore_restrictions": 1, "ignore_user_permissions": 1,
"label": "Amended From", "label": "Amended From",
"no_copy": 1, "no_copy": 1,
"oldfieldname": "amended_from", "oldfieldname": "amended_from",
@ -440,7 +446,7 @@
"icon": "icon-file-text", "icon": "icon-file-text",
"idx": 1, "idx": 1,
"is_submittable": 1, "is_submittable": 1,
"modified": "2014-05-09 02:16:47.686703", "modified": "2014-08-14 01:37:14.822939",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Accounts", "module": "Accounts",
"name": "Journal Voucher", "name": "Journal Voucher",
@ -448,6 +454,7 @@
"permissions": [ "permissions": [
{ {
"amend": 1, "amend": 1,
"apply_user_permissions": 1,
"cancel": 1, "cancel": 1,
"create": 1, "create": 1,
"delete": 1, "delete": 1,
@ -476,6 +483,7 @@
}, },
{ {
"amend": 0, "amend": 0,
"apply_user_permissions": 1,
"cancel": 0, "cancel": 0,
"create": 0, "create": 0,
"delete": 0, "delete": 0,

View File

@ -142,12 +142,12 @@ class JournalVoucher(AccountsController):
if self.cheque_date: if self.cheque_date:
r.append(_('Reference #{0} dated {1}').format(self.cheque_no, formatdate(self.cheque_date))) r.append(_('Reference #{0} dated {1}').format(self.cheque_no, formatdate(self.cheque_date)))
else: else:
msgprint(_("Please enter Reference date"), raise_exception=1) msgprint(_("Please enter Reference date"), raise_exception=frappe.MandatoryError)
for d in self.get('entries'): for d in self.get('entries'):
if d.against_invoice and d.credit: if d.against_invoice and d.credit:
currency = frappe.db.get_value("Sales Invoice", d.against_invoice, "currency") 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: if d.against_voucher and d.debit:
bill_no = frappe.db.sql("""select bill_no, bill_date, currency bill_no = frappe.db.sql("""select bill_no, bill_date, currency
@ -164,7 +164,7 @@ class JournalVoucher(AccountsController):
if r: if r:
self.remark = ("\n").join(r) self.remark = ("\n").join(r)
else: 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): def set_aging_date(self):
if self.is_opening != 'Yes': if self.is_opening != 'Yes':
@ -186,9 +186,14 @@ class JournalVoucher(AccountsController):
def set_print_format_fields(self): def set_print_format_fields(self):
for d in self.get('entries'): 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"]) ["account_type", "master_type"])
if not result:
continue
account_type, master_type = result
if master_type in ['Supplier', 'Customer']: if master_type in ['Supplier', 'Customer']:
if not self.pay_to_recd_from: if not self.pay_to_recd_from:
self.pay_to_recd_from = frappe.db.get_value(master_type, self.pay_to_recd_from = frappe.db.get_value(master_type,
@ -198,7 +203,7 @@ class JournalVoucher(AccountsController):
if account_type in ['Bank', 'Cash']: if account_type in ['Bank', 'Cash']:
company_currency = get_company_currency(self.company) company_currency = get_company_currency(self.company)
amt = flt(d.debit) and d.debit or d.credit 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 from frappe.utils import money_in_words
self.total_amount_in_words = money_in_words(amt, company_currency) 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""" """get all balance sheet accounts for opening entry"""
from erpnext.accounts.utils import get_balance_on from erpnext.accounts.utils import get_balance_on
accounts = frappe.db.sql_list("""select name from tabAccount 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] return [{"account": a, "balance": get_balance_on(a)} for a in accounts]

View File

@ -0,0 +1,20 @@
<div class="row" style="max-height: 30px;">
<div class="col-xs-10">
<div class="text-ellipsis">
{%= list.get_avatar_and_id(doc) %}
<span class="text-muted" style="margin-right: 8px;">
{%= doc.get_formatted("posting_date") %}</span>
<span class="label label-info filterable"
data-filter="voucher_type,=,{%= doc.voucher_type %}">
{%= doc.voucher_type %}
</span>
{% if(doc.docstatus===0) { %}
<span class="label label-danger filterable"
data-filter="docstatus,=,0">{%= __("Draft") %}</span>
{% } %}
</div>
</div>
<div class="col-xs-2 text-right">
{%= doc.get_formatted("total_debit") %}
</div>
</div>

View File

@ -0,0 +1,3 @@
frappe.listview_settings['Journal Voucher'] = {
add_fields: ["voucher_type", "posting_date", "total_debit", "company"]
};

View File

@ -1,6 +1,6 @@
{ {
"autoname": "JVD.######", "autoname": "JVD.######",
"creation": "2013-02-22 01:27:39.000000", "creation": "2013-02-22 01:27:39",
"docstatus": 0, "docstatus": 0,
"doctype": "DocType", "doctype": "DocType",
"fields": [ "fields": [
@ -31,6 +31,7 @@
"oldfieldtype": "Link", "oldfieldtype": "Link",
"options": "Cost Center", "options": "Cost Center",
"permlevel": 0, "permlevel": 0,
"print_hide": 1,
"print_width": "180px", "print_width": "180px",
"search_index": 0, "search_index": 0,
"width": "180px" "width": "180px"
@ -50,6 +51,7 @@
"oldfieldtype": "Data", "oldfieldtype": "Data",
"options": "Company:company:default_currency", "options": "Company:company:default_currency",
"permlevel": 0, "permlevel": 0,
"print_hide": 1,
"read_only": 1 "read_only": 1
}, },
{ {
@ -158,9 +160,10 @@
], ],
"idx": 1, "idx": 1,
"istable": 1, "istable": 1,
"modified": "2014-02-03 12:44:31.000000", "modified": "2014-07-25 03:16:51.149899",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Accounts", "module": "Accounts",
"name": "Journal Voucher Detail", "name": "Journal Voucher Detail",
"owner": "Administrator" "owner": "Administrator",
"permissions": []
} }

View File

@ -31,7 +31,7 @@
"description": "Default Bank / Cash account will be automatically updated in POS Invoice when this mode is selected.", "description": "Default Bank / Cash account will be automatically updated in POS Invoice when this mode is selected.",
"fieldname": "default_account", "fieldname": "default_account",
"fieldtype": "Link", "fieldtype": "Link",
"ignore_restrictions": 1, "ignore_user_permissions": 1,
"in_list_view": 1, "in_list_view": 1,
"label": "Default Account", "label": "Default Account",
"options": "Account", "options": "Account",
@ -41,7 +41,7 @@
], ],
"icon": "icon-credit-card", "icon": "icon-credit-card",
"idx": 1, "idx": 1,
"modified": "2014-05-07 05:06:13.702313", "modified": "2014-05-27 03:49:13.846602",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Accounts", "module": "Accounts",
"name": "Mode of Payment", "name": "Mode of Payment",
@ -59,6 +59,7 @@
"write": 1 "write": 1
}, },
{ {
"apply_user_permissions": 1,
"permlevel": 0, "permlevel": 0,
"read": 1, "read": 1,
"report": 1, "report": 1,

View File

@ -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 = '<i class="icon-hand-right"></i> Note:<br>'+
'<ul>If you are unable to match the exact amount, then amend your Journal Voucher and split rows such that payment amount match the invoice amount.</ul>';
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')

View File

@ -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"
}

View File

@ -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

View File

@ -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"
}

View File

@ -1,10 +1,9 @@
# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors # Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors and contributors
# License: GNU General Public License v3. See license.txt # For license information, please see license.txt
from __future__ import unicode_literals from __future__ import unicode_literals
import frappe import frappe
from frappe.model.document import Document from frappe.model.document import Document
class PaymentToInvoiceMatchingToolDetail(Document): class PaymentReconciliationInvoice(Document):
pass pass

View File

@ -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"
}

View File

@ -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

View File

@ -1 +0,0 @@
Tool for mapping (cancelling) unpaid invoices and payments.

View File

@ -1 +0,0 @@
from __future__ import unicode_literals

View File

@ -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);
}

View File

@ -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
}
]
}

View File

@ -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

View File

@ -1 +0,0 @@
Journal Voucher (payment) detail for matching to invoice.

View File

@ -1 +0,0 @@
from __future__ import unicode_literals

View File

@ -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": []
}

View File

@ -43,13 +43,14 @@
}, },
{ {
"fieldname": "amended_from", "fieldname": "amended_from",
"fieldtype": "Data", "fieldtype": "Link",
"ignore_restrictions": 1, "ignore_user_permissions": 1,
"in_list_view": 1, "in_list_view": 1,
"label": "Amended From", "label": "Amended From",
"no_copy": 1, "no_copy": 1,
"oldfieldname": "amended_from", "oldfieldname": "amended_from",
"oldfieldtype": "Data", "oldfieldtype": "Data",
"options": "Period Closing Voucher",
"permlevel": 0, "permlevel": 0,
"read_only": 1 "read_only": 1
}, },
@ -101,7 +102,7 @@
"icon": "icon-file-text", "icon": "icon-file-text",
"idx": 1, "idx": 1,
"is_submittable": 1, "is_submittable": 1,
"modified": "2014-05-09 02:16:36.920034", "modified": "2014-06-23 07:55:49.946225",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Accounts", "module": "Accounts",
"name": "Period Closing Voucher", "name": "Period Closing Voucher",

View File

@ -62,7 +62,7 @@
"options": "Price List", "options": "Price List",
"permlevel": 0, "permlevel": 0,
"read_only": 0, "read_only": 0,
"reqd": 1 "reqd": 0
}, },
{ {
"fieldname": "company", "fieldname": "company",
@ -147,7 +147,7 @@
"options": "Warehouse", "options": "Warehouse",
"permlevel": 0, "permlevel": 0,
"read_only": 0, "read_only": 0,
"reqd": 1 "reqd": 0
}, },
{ {
"fieldname": "cost_center", "fieldname": "cost_center",
@ -205,14 +205,13 @@
], ],
"icon": "icon-cog", "icon": "icon-cog",
"idx": 1, "idx": 1,
"modified": "2014-05-09 02:17:34.814856", "modified": "2014-06-23 16:40:59.510132",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Accounts", "module": "Accounts",
"name": "POS Setting", "name": "POS Setting",
"owner": "Administrator", "owner": "Administrator",
"permissions": [ "permissions": [
{ {
"cancel": 0,
"create": 1, "create": 1,
"delete": 1, "delete": 1,
"email": 1, "email": 1,
@ -225,7 +224,7 @@
"write": 1 "write": 1
}, },
{ {
"cancel": 0, "apply_user_permissions": 1,
"delete": 0, "delete": 0,
"email": 1, "email": 1,
"permlevel": 0, "permlevel": 0,

View File

@ -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 = ['<table class="table table-bordered" style="background-color: #f9f9f9;">',
'<tr><td>',
'<h4><i class="icon-hand-right"></i> ',
__('Notes'),
':</h4>',
'<ul>',
'<li>',
__("Pricing Rule is made to overwrite Price List / define discount percentage, based on some criteria."),
'</li>',
'<li>',
__("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."),
'</li>',
'<li>',
__('Discount Percentage can be applied either against a Price List or for all Price List.'),
'</li>',
'<li>',
__('To not apply Pricing Rule in a particular transaction, all applicable Pricing Rules should be disabled.'),
'</li>',
'</ul>',
'</td></tr>',
'<tr><td>',
'<h4><i class="icon-question-sign"></i> ',
__('How Pricing Rule is applied?'),
'</h4>',
'<ol>',
'<li>',
__("Pricing Rule is first selected based on 'Apply On' field, which can be Item, Item Group or Brand."),
'</li>',
'<li>',
__("Then Pricing Rules are filtered out based on Customer, Customer Group, Territory, Supplier, Supplier Type, Campaign, Sales Partner etc."),
'</li>',
'<li>',
__('Pricing Rules are further filtered based on quantity.'),
'</li>',
'<li>',
__('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.'),
'</li>',
'<li>',
__('Even if there are multiple Pricing Rules with highest priority, then following internal priorities are applied:'),
'<ul>',
'<li>',
__('Item Code > Item Group > Brand'),
'</li>',
'<li>',
__('Customer > Customer Group > Territory'),
'</li>',
'<li>',
__('Supplier > Supplier Type'),
'</li>',
'</ul>',
'</li>',
'<li>',
__('If multiple Pricing Rules continue to prevail, users are asked to set Priority manually to resolve conflict.'),
'</li>',
'</ol>',
'</td></tr>',
'</table>'].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();
}

View File

@ -51,6 +51,18 @@
"options": "Brand", "options": "Brand",
"permlevel": 0 "permlevel": 0
}, },
{
"fieldname": "selling",
"fieldtype": "Check",
"label": "Selling",
"permlevel": 0
},
{
"fieldname": "buying",
"fieldtype": "Check",
"label": "Buying",
"permlevel": 0
},
{ {
"fieldname": "applicable_for", "fieldname": "applicable_for",
"fieldtype": "Select", "fieldtype": "Select",
@ -131,6 +143,13 @@
"fieldtype": "Column Break", "fieldtype": "Column Break",
"permlevel": 0 "permlevel": 0
}, },
{
"fieldname": "company",
"fieldtype": "Link",
"label": "Company",
"options": "Company",
"permlevel": 0
},
{ {
"default": "Today", "default": "Today",
"fieldname": "valid_from", "fieldname": "valid_from",
@ -198,12 +217,25 @@
"label": "For Price List", "label": "For Price List",
"options": "Price List", "options": "Price List",
"permlevel": 0 "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", "icon": "icon-gift",
"idx": 1, "idx": 1,
"istable": 0, "istable": 0,
"modified": "2014-05-12 16:24:52.005162", "modified": "2014-06-20 19:36:22.502381",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Accounts", "module": "Accounts",
"name": "Pricing Rule", "name": "Pricing Rule",
@ -212,8 +244,8 @@
{ {
"create": 1, "create": 1,
"delete": 1, "delete": 1,
"export": 0, "export": 1,
"import": 0, "import": 1,
"permlevel": 0, "permlevel": 0,
"read": 1, "read": 1,
"report": 1, "report": 1,
@ -258,7 +290,6 @@
"permlevel": 0, "permlevel": 0,
"read": 1, "read": 1,
"report": 1, "report": 1,
"restrict": 1,
"role": "System Manager", "role": "System Manager",
"write": 1 "write": 1
} }

View File

@ -5,28 +5,46 @@
from __future__ import unicode_literals from __future__ import unicode_literals
import frappe import frappe
import json
import copy
from frappe import throw, _ from frappe import throw, _
from frappe.utils import flt from frappe.utils import flt, cint
from frappe.model.document import Document from frappe.model.document import Document
class MultiplePricingRuleConflict(frappe.ValidationError): pass
class PricingRule(Document): class PricingRule(Document):
def validate(self): def validate(self):
self.validate_mandatory() self.validate_mandatory()
self.validate_applicable_for_selling_or_buying()
self.validate_min_max_qty() self.validate_min_max_qty()
self.cleanup_fields_value() self.cleanup_fields_value()
self.validate_price_or_discount()
self.validate_max_discount()
def validate_mandatory(self): 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 "") tocheck = frappe.scrub(self.get(field) or "")
if tocheck and not self.get(tocheck): if tocheck and not self.get(tocheck):
throw(_("{0} is required").format(self.meta.get_label(tocheck)), frappe.MandatoryError) 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): def validate_min_max_qty(self):
if self.min_qty and self.max_qty and flt(self.min_qty) > flt(self.max_qty): 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")) throw(_("Min Qty can not be greater than Max Qty"))
def cleanup_fields_value(self): def cleanup_fields_value(self):
for logic_field in ["apply_on", "applicable_for", "price_or_discount"]: for logic_field in ["apply_on", "applicable_for", "price_or_discount"]:
fieldname = frappe.scrub(self.get(logic_field) or "") fieldname = frappe.scrub(self.get(logic_field) or "")
@ -39,3 +57,204 @@ class PricingRule(Document):
f = frappe.scrub(f) f = frappe.scrub(f)
if f!=fieldname: if f!=fieldname:
self.set(f, None) 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

View File

@ -17,9 +17,11 @@ class TestPricingRule(unittest.TestCase):
"doctype": "Pricing Rule", "doctype": "Pricing Rule",
"apply_on": "Item Code", "apply_on": "Item Code",
"item_code": "_Test Item", "item_code": "_Test Item",
"selling": 1,
"price_or_discount": "Discount Percentage", "price_or_discount": "Discount Percentage",
"price": 0, "price": 0,
"discount_percentage": 10, "discount_percentage": 10,
"company": "_Test Company"
} }
frappe.get_doc(test_record.copy()).insert() frappe.get_doc(test_record.copy()).insert()
@ -28,15 +30,16 @@ class TestPricingRule(unittest.TestCase):
"company": "_Test Company", "company": "_Test Company",
"price_list": "_Test Price List", "price_list": "_Test Price List",
"currency": "_Test Currency", "currency": "_Test Currency",
"doctype": "Sales Order", "parenttype": "Sales Order",
"conversion_rate": 1, "conversion_rate": 1,
"price_list_currency": "_Test Currency", "price_list_currency": "_Test Currency",
"plc_conversion_rate": 1, "plc_conversion_rate": 1,
"order_type": "Sales", "order_type": "Sales",
"transaction_type": "selling", "transaction_type": "selling",
"customer": "_Test Customer", "customer": "_Test Customer",
"doctype": "Sales Order Item",
"name": None
}) })
details = get_item_details(args) details = get_item_details(args)
self.assertEquals(details.get("discount_percentage"), 10) self.assertEquals(details.get("discount_percentage"), 10)
@ -71,8 +74,8 @@ class TestPricingRule(unittest.TestCase):
self.assertEquals(details.get("discount_percentage"), 5) self.assertEquals(details.get("discount_percentage"), 5)
frappe.db.sql("update `tabPricing Rule` set priority=NULL where campaign='_Test Campaign'") frappe.db.sql("update `tabPricing Rule` set priority=NULL where campaign='_Test Campaign'")
from erpnext.stock.get_item_details import MultiplePricingRuleConflict from erpnext.accounts.doctype.pricing_rule.pricing_rule import MultiplePricingRuleConflict
self.assertRaises (MultiplePricingRuleConflict, get_item_details, args) self.assertRaises(MultiplePricingRuleConflict, get_item_details, args)
args.item_code = "_Test Item 2" args.item_code = "_Test Item 2"
details = get_item_details(args) details = get_item_details(args)

View File

@ -27,7 +27,8 @@ erpnext.accounts.PurchaseInvoice = erpnext.buying.BuyingController.extend({
// Show / Hide button // Show / Hide button
if(doc.docstatus==1 && doc.outstanding_amount > 0) 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) { if(doc.docstatus==1) {
cur_frm.appframe.add_button(__('View Ledger'), function() { cur_frm.appframe.add_button(__('View Ledger'), function() {
@ -56,7 +57,7 @@ erpnext.accounts.PurchaseInvoice = erpnext.buying.BuyingController.extend({
company: cur_frm.doc.company company: cur_frm.doc.company
} }
}) })
}); }, "icon-download", "btn-default");
cur_frm.add_custom_button(__('From Purchase Receipt'), cur_frm.add_custom_button(__('From Purchase Receipt'),
function() { function() {
@ -69,7 +70,7 @@ erpnext.accounts.PurchaseInvoice = erpnext.buying.BuyingController.extend({
company: cur_frm.doc.company company: cur_frm.doc.company
} }
}) })
}); }, "icon-download", "btn-default");
} }
@ -77,16 +78,19 @@ erpnext.accounts.PurchaseInvoice = erpnext.buying.BuyingController.extend({
}, },
supplier: function() { supplier: function() {
var me = this;
if(this.frm.updating_party_details) if(this.frm.updating_party_details)
return; return;
erpnext.utils.get_party_details(this.frm, erpnext.utils.get_party_details(this.frm, "erpnext.accounts.party.get_party_details",
"erpnext.accounts.party.get_party_details", { {
posting_date: this.frm.doc.posting_date, posting_date: this.frm.doc.posting_date,
party: this.frm.doc.supplier, party: this.frm.doc.supplier,
party_type: "Supplier", party_type: "Supplier",
account: this.frm.doc.debit_to, account: this.frm.doc.debit_to,
price_list: this.frm.doc.buying_price_list, price_list: this.frm.doc.buying_price_list,
}) }, function() {
me.apply_pricing_rule();
})
}, },
credit_to: function() { credit_to: function() {
@ -109,7 +113,8 @@ erpnext.accounts.PurchaseInvoice = erpnext.buying.BuyingController.extend({
entries_add: function(doc, cdt, cdn) { entries_add: function(doc, cdt, cdn) {
var row = frappe.get_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() { on_submit: function() {

File diff suppressed because it is too large Load Diff

View File

@ -14,6 +14,10 @@ import frappe.defaults
from erpnext.controllers.buying_controller import BuyingController from erpnext.controllers.buying_controller import BuyingController
from erpnext.accounts.party import get_party_account, get_due_date from erpnext.accounts.party import get_party_account, get_due_date
form_grid_templates = {
"entries": "templates/form_grid/item_grid.html"
}
class PurchaseInvoice(BuyingController): class PurchaseInvoice(BuyingController):
tname = 'Purchase Invoice Item' tname = 'Purchase Invoice Item'
fname = 'entries' fname = 'entries'
@ -30,6 +34,7 @@ class PurchaseInvoice(BuyingController):
'target_ref_field': 'amount', 'target_ref_field': 'amount',
'source_field': 'amount', 'source_field': 'amount',
'percent_join_field': 'purchase_order', 'percent_join_field': 'purchase_order',
'overflow_type': 'billing'
}] }]
def validate(self): def validate(self):
@ -42,7 +47,6 @@ class PurchaseInvoice(BuyingController):
self.pr_required() self.pr_required()
self.check_active_purchase_items() self.check_active_purchase_items()
self.check_conversion_rate() self.check_conversion_rate()
self.validate_bill_no()
self.validate_credit_acc() self.validate_credit_acc()
self.clear_unallocated_advances("Purchase Invoice Advance", "advance_allocation_details") self.clear_unallocated_advances("Purchase Invoice Advance", "advance_allocation_details")
self.check_for_acc_head_of_supplier() self.check_for_acc_head_of_supplier()
@ -56,6 +60,14 @@ class PurchaseInvoice(BuyingController):
self.update_valuation_rate("entries") self.update_valuation_rate("entries")
self.validate_multiple_billing("Purchase Receipt", "pr_detail", "amount", self.validate_multiple_billing("Purchase Receipt", "pr_detail", "amount",
"purchase_receipt_details") "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): def set_missing_values(self, for_validate=False):
if not self.credit_to: 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): 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")) 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): def validate_credit_acc(self):
if frappe.db.get_value("Account", self.credit_to, "report_type") != "Balance Sheet": if frappe.db.get_value("Account", self.credit_to, "report_type") != "Balance Sheet":
frappe.throw(_("Account must be a balance sheet account")) frappe.throw(_("Account must be a balance sheet account"))
@ -269,6 +264,9 @@ class PurchaseInvoice(BuyingController):
auto_accounting_for_stock = \ auto_accounting_for_stock = \
cint(frappe.defaults.get_global_default("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 = [] gl_entries = []
# parent's gl entry # parent's gl entry
@ -308,30 +306,10 @@ class PurchaseInvoice(BuyingController):
(tax.add_deduct_tax == "Add" and 1 or -1) * flt(tax.tax_amount) (tax.add_deduct_tax == "Add" and 1 or -1) * flt(tax.tax_amount)
# item gl entries # item gl entries
stock_item_and_auto_accounting_for_stock = False negative_expense_to_be_booked = 0.0
stock_items = self.get_stock_items() stock_items = self.get_stock_items()
for item in self.get("entries"): for item in self.get("entries"):
if auto_accounting_for_stock and item.item_code in stock_items: if flt(item.base_amount):
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
gl_entries.append( gl_entries.append(
self.get_gl_dict({ self.get_gl_dict({
"account": item.expense_account, "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" # credit valuation tax amount in "Expenses Included In Valuation"
# this will balance out valuation amount included in cost of goods sold # 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(): 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( gl_entries.append(
self.get_gl_dict({ self.get_gl_dict({
"account": expenses_included_in_valuation, "account": expenses_included_in_valuation,
"cost_center": cost_center, "cost_center": cost_center,
"against": self.credit_to, "against": self.credit_to,
"credit": amount, "credit": applicable_amount,
"remarks": self.remarks or "Accounting Entry for Stock" "remarks": self.remarks or "Accounting Entry for Stock"
}) })
) )
i += 1
# writeoff account includes petty difference in the invoice amount # writeoff account includes petty difference in the invoice amount
# and the amount that is paid # and the amount that is paid
if self.write_off_account and flt(self.write_off_amount): if self.write_off_account and flt(self.write_off_amount):
@ -382,7 +389,7 @@ class PurchaseInvoice(BuyingController):
self.update_prevdoc_status() self.update_prevdoc_status()
self.update_billing_status_for_zero_amount_refdoc("Purchase Order") 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): def on_update(self):
pass pass

View File

@ -0,0 +1,45 @@
<div class="row" style="max-height: 30px;">
<div class="col-xs-9">
<div class="text-ellipsis">
{%= list.get_avatar_and_id(doc) %}
<span style="margin-right: 8px; display: inline-block">
<span class="filterable"
data-filter="supplier,=,{%= doc.supplier %}">
{%= doc.supplier_name %}</span></span>
{% if(doc.outstanding_amount > 0 && doc.docstatus==1) { %}
{% if(frappe.datetime.get_diff(doc.due_date) < 0) { %}
<span class="label label-danger filterable"
title="{%= doc.get_formatted("due_date")%}"
data-filter="outstanding_amount,>,0|due_date,<,Today">
{%= __("Overdue: ") + comment_when(doc.due_date) %}
</span>
{% } else { %}
<span class="label label-warning filterable"
data-filter="outstanding_amount,>,0|due,>=,Today"
title="{%= __("Payment Pending") %}">
{%= doc.get_formatted("due_date") %}</span>
{% } %}
{% } %}
{% if(doc.outstanding_amount==0 && doc.docstatus==1) { %}
<span class="label label-success filterable"
title="{%= doc.get_formatted("due_date")%}"
data-filter="outstanding_amount,=,0">
<i class="icon-ok-sign"></i> {%= __("Paid") %}
</span>
{% } %}
{% if(doc.docstatus===0) { %}
<span class="label label-danger filterable"
data-filter="docstatus,=,0">{%= __("Draft") %}</span>
{% } %}
</div>
</div>
<div class="col-xs-1 text-right">
{% 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" %}
</div>
<div class="col-xs-2 text-right">
<div class="text-ellipsis" title="{%= doc.get_formatted('grand_total_import') %}">
{%= doc.get_formatted("grand_total_import") %}
</div>
</div>
</div>

View File

@ -3,10 +3,6 @@
// render // render
frappe.listview_settings['Purchase Invoice'] = { frappe.listview_settings['Purchase Invoice'] = {
add_fields: ["`tabPurchase Invoice`.grand_total", "`tabPurchase Invoice`.outstanding_amount"], add_fields: ["supplier", "supplier_name", "grand_total", "outstanding_amount", "due_date", "company",
add_columns: [{"content":"paid_amount", width:"10%", type:"bar-graph", label: "Paid"}], "currency"]
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;
}
}; };

View File

@ -9,7 +9,8 @@ import frappe.model
import json import json
from frappe.utils import cint from frappe.utils import cint
import frappe.defaults 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_dependencies = ["Item", "Cost Center"]
test_ignore = ["Serial No"] test_ignore = ["Serial No"]
@ -57,9 +58,41 @@ class TestPurchaseInvoice(unittest.TestCase):
expected_values = sorted([ expected_values = sorted([
["_Test Supplier - _TC", 0, 720], ["_Test Supplier - _TC", 0, 720],
["Stock Received But Not Billed - _TC", 750.0, 0], ["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 Shipping Charges - _TC", 100.0, 0],
["_Test Account VAT - _TC", 120.0, 0], ["_Test Account VAT - _TC", 120.0, 0],
["Expenses Included In Valuation - _TC", 0, 250.0],
]) ])
for i, gle in enumerate(gl_entries): for i, gle in enumerate(gl_entries):

View File

@ -1,206 +1,208 @@
[ [
{ {
"bill_no": "NA", "bill_no": "NA",
"buying_price_list": "_Test Price List", "buying_price_list": "_Test Price List",
"company": "_Test Company", "company": "_Test Company",
"conversion_rate": 1, "conversion_rate": 1,
"credit_to": "_Test Supplier - _TC", "credit_to": "_Test Supplier - _TC",
"currency": "INR", "currency": "INR",
"doctype": "Purchase Invoice", "doctype": "Purchase Invoice",
"entries": [ "entries": [
{ {
"amount": 500, "amount": 500,
"base_amount": 500, "base_amount": 500,
"base_rate": 50, "base_rate": 50,
"conversion_factor": 1.0, "conversion_factor": 1.0,
"cost_center": "_Test Cost Center - _TC", "cost_center": "_Test Cost Center - _TC",
"doctype": "Purchase Invoice Item", "doctype": "Purchase Invoice Item",
"expense_account": "_Test Account Cost for Goods Sold - _TC", "expense_account": "_Test Account Cost for Goods Sold - _TC",
"item_code": "_Test Item Home Desktop 100", "item_code": "_Test Item Home Desktop 100",
"item_name": "_Test Item Home Desktop 100", "item_name": "_Test Item Home Desktop 100",
"item_tax_rate": "{\"_Test Account Excise Duty - _TC\": 10}", "item_tax_rate": "{\"_Test Account Excise Duty - _TC\": 10}",
"parentfield": "entries", "parentfield": "entries",
"qty": 10, "qty": 10,
"rate": 50, "rate": 50,
"uom": "_Test UOM" "uom": "_Test UOM"
}, },
{ {
"amount": 750, "amount": 750,
"base_amount": 750, "base_amount": 750,
"base_rate": 150, "base_rate": 150,
"conversion_factor": 1.0, "conversion_factor": 1.0,
"cost_center": "_Test Cost Center - _TC", "cost_center": "_Test Cost Center - _TC",
"doctype": "Purchase Invoice Item", "doctype": "Purchase Invoice Item",
"expense_account": "_Test Account Cost for Goods Sold - _TC", "expense_account": "_Test Account Cost for Goods Sold - _TC",
"item_code": "_Test Item Home Desktop 200", "item_code": "_Test Item Home Desktop 200",
"item_name": "_Test Item Home Desktop 200", "item_name": "_Test Item Home Desktop 200",
"parentfield": "entries", "parentfield": "entries",
"qty": 5, "qty": 5,
"rate": 150, "rate": 150,
"uom": "_Test UOM" "uom": "_Test UOM"
} }
], ],
"fiscal_year": "_Test Fiscal Year 2013", "fiscal_year": "_Test Fiscal Year 2013",
"grand_total_import": 0, "grand_total_import": 0,
"naming_series": "BILL", "naming_series": "_T-BILL",
"other_charges": [ "other_charges": [
{ {
"account_head": "_Test Account Shipping Charges - _TC", "account_head": "_Test Account Shipping Charges - _TC",
"add_deduct_tax": "Add", "add_deduct_tax": "Add",
"category": "Valuation and Total", "category": "Valuation and Total",
"charge_type": "Actual", "charge_type": "Actual",
"cost_center": "_Test Cost Center - _TC", "cost_center": "_Test Cost Center - _TC",
"description": "Shipping Charges", "description": "Shipping Charges",
"doctype": "Purchase Taxes and Charges", "doctype": "Purchase Taxes and Charges",
"parentfield": "other_charges", "parentfield": "other_charges",
"rate": 100 "rate": 100
}, },
{ {
"account_head": "_Test Account Customs Duty - _TC", "account_head": "_Test Account Customs Duty - _TC",
"add_deduct_tax": "Add", "add_deduct_tax": "Add",
"category": "Valuation", "category": "Valuation",
"charge_type": "On Net Total", "charge_type": "On Net Total",
"cost_center": "_Test Cost Center - _TC", "cost_center": "_Test Cost Center - _TC",
"description": "Customs Duty", "description": "Customs Duty",
"doctype": "Purchase Taxes and Charges", "doctype": "Purchase Taxes and Charges",
"parentfield": "other_charges", "parentfield": "other_charges",
"rate": 10 "rate": 10
}, },
{ {
"account_head": "_Test Account Excise Duty - _TC", "account_head": "_Test Account Excise Duty - _TC",
"add_deduct_tax": "Add", "add_deduct_tax": "Add",
"category": "Total", "category": "Total",
"charge_type": "On Net Total", "charge_type": "On Net Total",
"cost_center": "_Test Cost Center - _TC", "cost_center": "_Test Cost Center - _TC",
"description": "Excise Duty", "description": "Excise Duty",
"doctype": "Purchase Taxes and Charges", "doctype": "Purchase Taxes and Charges",
"parentfield": "other_charges", "parentfield": "other_charges",
"rate": 12 "rate": 12
}, },
{ {
"account_head": "_Test Account Education Cess - _TC", "account_head": "_Test Account Education Cess - _TC",
"add_deduct_tax": "Add", "add_deduct_tax": "Add",
"category": "Total", "category": "Total",
"charge_type": "On Previous Row Amount", "charge_type": "On Previous Row Amount",
"cost_center": "_Test Cost Center - _TC", "cost_center": "_Test Cost Center - _TC",
"description": "Education Cess", "description": "Education Cess",
"doctype": "Purchase Taxes and Charges", "doctype": "Purchase Taxes and Charges",
"parentfield": "other_charges", "parentfield": "other_charges",
"rate": 2, "rate": 2,
"row_id": 3 "row_id": 3
}, },
{ {
"account_head": "_Test Account S&H Education Cess - _TC", "account_head": "_Test Account S&H Education Cess - _TC",
"add_deduct_tax": "Add", "add_deduct_tax": "Add",
"category": "Total", "category": "Total",
"charge_type": "On Previous Row Amount", "charge_type": "On Previous Row Amount",
"cost_center": "_Test Cost Center - _TC", "cost_center": "_Test Cost Center - _TC",
"description": "S&H Education Cess", "description": "S&H Education Cess",
"doctype": "Purchase Taxes and Charges", "doctype": "Purchase Taxes and Charges",
"parentfield": "other_charges", "parentfield": "other_charges",
"rate": 1, "rate": 1,
"row_id": 3 "row_id": 3
}, },
{ {
"account_head": "_Test Account CST - _TC", "account_head": "_Test Account CST - _TC",
"add_deduct_tax": "Add", "add_deduct_tax": "Add",
"category": "Total", "category": "Total",
"charge_type": "On Previous Row Total", "charge_type": "On Previous Row Total",
"cost_center": "_Test Cost Center - _TC", "cost_center": "_Test Cost Center - _TC",
"description": "CST", "description": "CST",
"doctype": "Purchase Taxes and Charges", "doctype": "Purchase Taxes and Charges",
"parentfield": "other_charges", "parentfield": "other_charges",
"rate": 2, "rate": 2,
"row_id": 5 "row_id": 5
}, },
{ {
"account_head": "_Test Account VAT - _TC", "account_head": "_Test Account VAT - _TC",
"add_deduct_tax": "Add", "add_deduct_tax": "Add",
"category": "Total", "category": "Total",
"charge_type": "On Net Total", "charge_type": "On Net Total",
"cost_center": "_Test Cost Center - _TC", "cost_center": "_Test Cost Center - _TC",
"description": "VAT", "description": "VAT",
"doctype": "Purchase Taxes and Charges", "doctype": "Purchase Taxes and Charges",
"parentfield": "other_charges", "parentfield": "other_charges",
"rate": 12.5 "rate": 12.5
}, },
{ {
"account_head": "_Test Account Discount - _TC", "account_head": "_Test Account Discount - _TC",
"add_deduct_tax": "Deduct", "add_deduct_tax": "Deduct",
"category": "Total", "category": "Total",
"charge_type": "On Previous Row Total", "charge_type": "On Previous Row Total",
"cost_center": "_Test Cost Center - _TC", "cost_center": "_Test Cost Center - _TC",
"description": "Discount", "description": "Discount",
"doctype": "Purchase Taxes and Charges", "doctype": "Purchase Taxes and Charges",
"parentfield": "other_charges", "parentfield": "other_charges",
"rate": 10, "rate": 10,
"row_id": 7 "row_id": 7
} }
], ],
"posting_date": "2013-02-03", "posting_date": "2013-02-03",
"supplier": "_Test Supplier",
"supplier_name": "_Test Supplier" "supplier_name": "_Test Supplier"
}, },
{ {
"bill_no": "NA", "bill_no": "NA",
"buying_price_list": "_Test Price List", "buying_price_list": "_Test Price List",
"company": "_Test Company", "company": "_Test Company",
"conversion_rate": 1.0, "conversion_rate": 1.0,
"credit_to": "_Test Supplier - _TC", "credit_to": "_Test Supplier - _TC",
"currency": "INR", "currency": "INR",
"doctype": "Purchase Invoice", "doctype": "Purchase Invoice",
"entries": [ "entries": [
{ {
"conversion_factor": 1.0, "conversion_factor": 1.0,
"cost_center": "_Test Cost Center - _TC", "cost_center": "_Test Cost Center - _TC",
"doctype": "Purchase Invoice Item", "doctype": "Purchase Invoice Item",
"expense_account": "_Test Account Cost for Goods Sold - _TC", "expense_account": "_Test Account Cost for Goods Sold - _TC",
"item_code": "_Test Item", "item_code": "_Test Item",
"item_name": "_Test Item", "item_name": "_Test Item",
"parentfield": "entries", "parentfield": "entries",
"qty": 10.0, "qty": 10.0,
"rate": 50.0, "rate": 50.0,
"uom": "_Test UOM" "uom": "_Test UOM"
} }
], ],
"fiscal_year": "_Test Fiscal Year 2013", "fiscal_year": "_Test Fiscal Year 2013",
"grand_total_import": 0, "grand_total_import": 0,
"naming_series": "_T-Purchase Invoice-", "naming_series": "_T-Purchase Invoice-",
"other_charges": [ "other_charges": [
{ {
"account_head": "_Test Account Shipping Charges - _TC", "account_head": "_Test Account Shipping Charges - _TC",
"add_deduct_tax": "Add", "add_deduct_tax": "Add",
"category": "Valuation and Total", "category": "Valuation and Total",
"charge_type": "Actual", "charge_type": "Actual",
"cost_center": "_Test Cost Center - _TC", "cost_center": "_Test Cost Center - _TC",
"description": "Shipping Charges", "description": "Shipping Charges",
"doctype": "Purchase Taxes and Charges", "doctype": "Purchase Taxes and Charges",
"parentfield": "other_charges", "parentfield": "other_charges",
"rate": 100.0 "rate": 100.0
}, },
{ {
"account_head": "_Test Account VAT - _TC", "account_head": "_Test Account VAT - _TC",
"add_deduct_tax": "Add", "add_deduct_tax": "Add",
"category": "Total", "category": "Total",
"charge_type": "Actual", "charge_type": "Actual",
"cost_center": "_Test Cost Center - _TC", "cost_center": "_Test Cost Center - _TC",
"description": "VAT", "description": "VAT",
"doctype": "Purchase Taxes and Charges", "doctype": "Purchase Taxes and Charges",
"parentfield": "other_charges", "parentfield": "other_charges",
"rate": 120.0 "rate": 120.0
}, },
{ {
"account_head": "_Test Account Customs Duty - _TC", "account_head": "_Test Account Customs Duty - _TC",
"add_deduct_tax": "Add", "add_deduct_tax": "Add",
"category": "Valuation", "category": "Valuation",
"charge_type": "Actual", "charge_type": "Actual",
"cost_center": "_Test Cost Center - _TC", "cost_center": "_Test Cost Center - _TC",
"description": "Customs Duty", "description": "Customs Duty",
"doctype": "Purchase Taxes and Charges", "doctype": "Purchase Taxes and Charges",
"parentfield": "other_charges", "parentfield": "other_charges",
"rate": 150.0 "rate": 150.0
} }
], ],
"posting_date": "2013-02-03", "posting_date": "2013-02-03",
"supplier": "_Test Supplier",
"supplier_name": "_Test Supplier" "supplier_name": "_Test Supplier"
} }
] ]

View File

@ -1,6 +1,6 @@
{ {
"autoname": "EVD.######", "autoname": "EVD.######",
"creation": "2013-05-22 12:43:10.000000", "creation": "2013-05-22 12:43:10",
"docstatus": 0, "docstatus": 0,
"doctype": "DocType", "doctype": "DocType",
"fields": [ "fields": [
@ -8,7 +8,7 @@
"fieldname": "item_code", "fieldname": "item_code",
"fieldtype": "Link", "fieldtype": "Link",
"in_filter": 1, "in_filter": 1,
"in_list_view": 0, "in_list_view": 1,
"label": "Item", "label": "Item",
"oldfieldname": "item_code", "oldfieldname": "item_code",
"oldfieldtype": "Link", "oldfieldtype": "Link",
@ -52,7 +52,6 @@
{ {
"fieldname": "quantity_and_rate", "fieldname": "quantity_and_rate",
"fieldtype": "Section Break", "fieldtype": "Section Break",
"in_list_view": 0,
"label": "Quantity and Rate", "label": "Quantity and Rate",
"permlevel": 0 "permlevel": 0
}, },
@ -76,7 +75,7 @@
{ {
"fieldname": "uom", "fieldname": "uom",
"fieldtype": "Link", "fieldtype": "Link",
"in_list_view": 0, "in_list_view": 1,
"label": "UOM", "label": "UOM",
"options": "UOM", "options": "UOM",
"permlevel": 0, "permlevel": 0,
@ -86,7 +85,6 @@
{ {
"fieldname": "conversion_factor", "fieldname": "conversion_factor",
"fieldtype": "Float", "fieldtype": "Float",
"in_list_view": 0,
"label": "Conversion Factor", "label": "Conversion Factor",
"permlevel": 0, "permlevel": 0,
"print_hide": 1, "print_hide": 1,
@ -100,7 +98,6 @@
{ {
"fieldname": "price_list_rate", "fieldname": "price_list_rate",
"fieldtype": "Currency", "fieldtype": "Currency",
"in_list_view": 0,
"label": "Price List Rate", "label": "Price List Rate",
"options": "currency", "options": "currency",
"permlevel": 0, "permlevel": 0,
@ -109,8 +106,8 @@
}, },
{ {
"fieldname": "discount_percentage", "fieldname": "discount_percentage",
"fieldtype": "Float", "fieldtype": "Percent",
"in_list_view": 0, "in_list_view": 1,
"label": "Discount %", "label": "Discount %",
"permlevel": 0, "permlevel": 0,
"print_hide": 0, "print_hide": 0,
@ -124,7 +121,6 @@
{ {
"fieldname": "base_price_list_rate", "fieldname": "base_price_list_rate",
"fieldtype": "Currency", "fieldtype": "Currency",
"in_list_view": 0,
"label": "Price List Rate (Company Currency)", "label": "Price List Rate (Company Currency)",
"options": "Company:company:default_currency", "options": "Company:company:default_currency",
"permlevel": 0, "permlevel": 0,
@ -169,7 +165,6 @@
{ {
"fieldname": "base_rate", "fieldname": "base_rate",
"fieldtype": "Currency", "fieldtype": "Currency",
"in_list_view": 0,
"label": "Rate (Company Currency)", "label": "Rate (Company Currency)",
"oldfieldname": "rate", "oldfieldname": "rate",
"oldfieldtype": "Currency", "oldfieldtype": "Currency",
@ -182,7 +177,6 @@
{ {
"fieldname": "base_amount", "fieldname": "base_amount",
"fieldtype": "Currency", "fieldtype": "Currency",
"in_list_view": 0,
"label": "Amount (Company Currency)", "label": "Amount (Company Currency)",
"oldfieldname": "amount", "oldfieldname": "amount",
"oldfieldtype": "Currency", "oldfieldtype": "Currency",
@ -193,17 +187,9 @@
"reqd": 1 "reqd": 1
}, },
{ {
"fieldname": "pricing_rule_for_price", "fieldname": "pricing_rule",
"fieldtype": "Link", "fieldtype": "Link",
"label": "Pricing Rule For Price", "label": "Pricing Rule",
"options": "Pricing Rule",
"permlevel": 0,
"read_only": 1
},
{
"fieldname": "pricing_rule_for_discount",
"fieldtype": "Link",
"label": "Pricing Rule For Discount",
"options": "Pricing Rule", "options": "Pricing Rule",
"permlevel": 0, "permlevel": 0,
"read_only": 1 "read_only": 1
@ -211,14 +197,12 @@
{ {
"fieldname": "accounting", "fieldname": "accounting",
"fieldtype": "Section Break", "fieldtype": "Section Break",
"in_list_view": 0,
"label": "Accounting", "label": "Accounting",
"permlevel": 0 "permlevel": 0
}, },
{ {
"fieldname": "expense_account", "fieldname": "expense_account",
"fieldtype": "Link", "fieldtype": "Link",
"in_list_view": 0,
"label": "Expense Head", "label": "Expense Head",
"oldfieldname": "expense_head", "oldfieldname": "expense_head",
"oldfieldtype": "Link", "oldfieldtype": "Link",
@ -235,11 +219,20 @@
"fieldtype": "Column Break", "fieldtype": "Column Break",
"permlevel": 0 "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", "default": ":Company",
"fieldname": "cost_center", "fieldname": "cost_center",
"fieldtype": "Link", "fieldtype": "Link",
"in_list_view": 0,
"label": "Cost Center", "label": "Cost Center",
"oldfieldname": "cost_center", "oldfieldname": "cost_center",
"oldfieldtype": "Link", "oldfieldtype": "Link",
@ -253,26 +246,13 @@
{ {
"fieldname": "reference", "fieldname": "reference",
"fieldtype": "Section Break", "fieldtype": "Section Break",
"in_list_view": 0,
"label": "Reference", "label": "Reference",
"permlevel": 0 "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", "fieldname": "brand",
"fieldtype": "Data", "fieldtype": "Data",
"hidden": 1, "hidden": 1,
"in_list_view": 0,
"label": "Brand", "label": "Brand",
"oldfieldname": "brand", "oldfieldname": "brand",
"oldfieldtype": "Data", "oldfieldtype": "Data",
@ -286,7 +266,6 @@
"fieldtype": "Link", "fieldtype": "Link",
"hidden": 1, "hidden": 1,
"in_filter": 1, "in_filter": 1,
"in_list_view": 0,
"label": "Item Group", "label": "Item Group",
"oldfieldname": "item_group", "oldfieldname": "item_group",
"oldfieldtype": "Link", "oldfieldtype": "Link",
@ -301,7 +280,6 @@
"fieldname": "item_tax_rate", "fieldname": "item_tax_rate",
"fieldtype": "Small Text", "fieldtype": "Small Text",
"hidden": 1, "hidden": 1,
"in_list_view": 0,
"label": "Item Tax Rate", "label": "Item Tax Rate",
"oldfieldname": "item_tax_rate", "oldfieldname": "item_tax_rate",
"oldfieldtype": "Small Text", "oldfieldtype": "Small Text",
@ -314,7 +292,6 @@
"fieldname": "item_tax_amount", "fieldname": "item_tax_amount",
"fieldtype": "Currency", "fieldtype": "Currency",
"hidden": 1, "hidden": 1,
"in_list_view": 0,
"label": "Item Tax Amount", "label": "Item Tax Amount",
"no_copy": 1, "no_copy": 1,
"options": "Company:company:default_currency", "options": "Company:company:default_currency",
@ -325,28 +302,10 @@
"search_index": 0, "search_index": 0,
"width": "150px" "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", "fieldname": "purchase_order",
"fieldtype": "Link", "fieldtype": "Link",
"in_filter": 1, "in_filter": 1,
"in_list_view": 0,
"label": "Purchase Order", "label": "Purchase Order",
"no_copy": 1, "no_copy": 1,
"oldfieldname": "purchase_order", "oldfieldname": "purchase_order",
@ -357,12 +316,16 @@
"read_only": 1, "read_only": 1,
"search_index": 1 "search_index": 1
}, },
{
"fieldname": "col_break6",
"fieldtype": "Column Break",
"permlevel": 0
},
{ {
"fieldname": "po_detail", "fieldname": "po_detail",
"fieldtype": "Data", "fieldtype": "Data",
"hidden": 1, "hidden": 1,
"in_filter": 1, "in_filter": 1,
"in_list_view": 0,
"label": "Purchase Order Item", "label": "Purchase Order Item",
"no_copy": 1, "no_copy": 1,
"oldfieldname": "po_detail", "oldfieldname": "po_detail",
@ -376,7 +339,6 @@
"fieldname": "purchase_receipt", "fieldname": "purchase_receipt",
"fieldtype": "Link", "fieldtype": "Link",
"in_filter": 1, "in_filter": 1,
"in_list_view": 0,
"label": "Purchase Receipt", "label": "Purchase Receipt",
"no_copy": 1, "no_copy": 1,
"oldfieldname": "purchase_receipt", "oldfieldname": "purchase_receipt",
@ -387,12 +349,22 @@
"read_only": 1, "read_only": 1,
"search_index": 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", "fieldname": "pr_detail",
"fieldtype": "Data", "fieldtype": "Data",
"hidden": 1, "hidden": 1,
"in_filter": 1, "in_filter": 1,
"in_list_view": 0,
"label": "PR Detail", "label": "PR Detail",
"no_copy": 1, "no_copy": 1,
"oldfieldname": "pr_detail", "oldfieldname": "pr_detail",
@ -406,7 +378,6 @@
"fieldname": "valuation_rate", "fieldname": "valuation_rate",
"fieldtype": "Currency", "fieldtype": "Currency",
"hidden": 1, "hidden": 1,
"in_list_view": 0,
"label": "Valuation Rate", "label": "Valuation Rate",
"no_copy": 1, "no_copy": 1,
"options": "Company:company:default_currency", "options": "Company:company:default_currency",
@ -418,7 +389,6 @@
"fieldname": "rm_supp_cost", "fieldname": "rm_supp_cost",
"fieldtype": "Currency", "fieldtype": "Currency",
"hidden": 1, "hidden": 1,
"in_list_view": 0,
"label": "Raw Materials Supplied Cost", "label": "Raw Materials Supplied Cost",
"no_copy": 1, "no_copy": 1,
"options": "Company:company:default_currency", "options": "Company:company:default_currency",
@ -429,9 +399,12 @@
], ],
"idx": 1, "idx": 1,
"istable": 1, "istable": 1,
"modified": "2014-02-28 11:27:53.000000", "modified": "2014-09-08 08:06:30.027289",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Accounts", "module": "Accounts",
"name": "Purchase Invoice Item", "name": "Purchase Invoice Item",
"owner": "Administrator" "owner": "Administrator",
"permissions": [],
"sort_field": "modified",
"sort_order": "DESC"
} }

View File

@ -1,431 +1,164 @@
{ {
"_last_update": null, "autoname": "PVTD.######",
"_user_tags": null, "creation": "2013-05-21 16:16:04",
"allow_attach": null, "docstatus": 0,
"allow_copy": null, "doctype": "DocType",
"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,
"fields": [ "fields": [
{ {
"allow_on_submit": null, "default": "Valuation and Total",
"default": "Valuation and Total", "fieldname": "category",
"depends_on": null, "fieldtype": "Select",
"description": null, "in_list_view": 0,
"fieldname": "category", "label": "Consider Tax or Charge for",
"fieldtype": "Select", "oldfieldname": "category",
"hidden": null, "oldfieldtype": "Select",
"ignore_restrictions": null, "options": "Valuation and Total\nValuation\nTotal",
"in_filter": null, "permlevel": 0,
"in_list_view": 0, "read_only": 0,
"label": "Consider Tax or Charge for", "reqd": 1
"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
},
{ {
"allow_on_submit": null, "default": "Add",
"default": "Add", "fieldname": "add_deduct_tax",
"depends_on": null, "fieldtype": "Select",
"description": null, "label": "Add or Deduct",
"fieldname": "add_deduct_tax", "oldfieldname": "add_deduct_tax",
"fieldtype": "Select", "oldfieldtype": "Select",
"hidden": null, "options": "Add\nDeduct",
"ignore_restrictions": null, "permlevel": 0,
"in_filter": null, "read_only": 0,
"in_list_view": null, "reqd": 1
"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
},
{ {
"allow_on_submit": null, "fieldname": "charge_type",
"default": null, "fieldtype": "Select",
"depends_on": null, "in_list_view": 1,
"description": null, "label": "Type",
"fieldname": "charge_type", "oldfieldname": "charge_type",
"fieldtype": "Select", "oldfieldtype": "Select",
"hidden": null, "options": "\nActual\nOn Net Total\nOn Previous Row Amount\nOn Previous Row Total",
"ignore_restrictions": null, "permlevel": 0,
"in_filter": null, "read_only": 0,
"in_list_view": 1, "reqd": 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
},
{ {
"allow_on_submit": null, "depends_on": "eval:[\"On Previous Row Amount\", \"On Previous Row Total\"].indexOf(doc.charge_type)!==-1",
"default": null, "fieldname": "row_id",
"depends_on": "eval:[\"On Previous Row Amount\", \"On Previous Row Total\"].indexOf(doc.charge_type)!==-1", "fieldtype": "Data",
"description": null, "hidden": 0,
"fieldname": "row_id", "label": "Reference Row #",
"fieldtype": "Data", "oldfieldname": "row_id",
"hidden": 0, "oldfieldtype": "Data",
"ignore_restrictions": null, "permlevel": 0,
"in_filter": null, "read_only": 0
"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
},
{ {
"allow_on_submit": null, "fieldname": "description",
"default": null, "fieldtype": "Small Text",
"depends_on": null, "in_list_view": 1,
"description": null, "label": "Description",
"fieldname": "description", "oldfieldname": "description",
"fieldtype": "Small Text", "oldfieldtype": "Small Text",
"hidden": null, "permlevel": 0,
"ignore_restrictions": null, "print_width": "300px",
"in_filter": null, "read_only": 0,
"in_list_view": 1, "reqd": 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,
"width": "300px" "width": "300px"
}, },
{ {
"allow_on_submit": null, "fieldname": "col_break1",
"default": null, "fieldtype": "Column Break",
"depends_on": null, "permlevel": 0
"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
},
{ {
"allow_on_submit": null, "fieldname": "account_head",
"default": null, "fieldtype": "Link",
"depends_on": null, "in_list_view": 0,
"description": null, "label": "Account Head",
"fieldname": "account_head", "oldfieldname": "account_head",
"fieldtype": "Link", "oldfieldtype": "Link",
"hidden": null, "options": "Account",
"ignore_restrictions": null, "permlevel": 0,
"in_filter": null, "read_only": 0,
"in_list_view": 0, "reqd": 1
"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
},
{ {
"allow_on_submit": null, "default": ":Company",
"default": ":Company", "fieldname": "cost_center",
"depends_on": null, "fieldtype": "Link",
"description": null, "in_list_view": 0,
"fieldname": "cost_center", "label": "Cost Center",
"fieldtype": "Link", "oldfieldname": "cost_center",
"hidden": null, "oldfieldtype": "Link",
"ignore_restrictions": null, "options": "Cost Center",
"in_filter": null, "permlevel": 0,
"in_list_view": 0, "read_only": 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
},
{ {
"allow_on_submit": null, "fieldname": "rate",
"default": null, "fieldtype": "Float",
"depends_on": null, "in_list_view": 1,
"description": null, "label": "Rate",
"fieldname": "rate", "oldfieldname": "rate",
"fieldtype": "Float", "oldfieldtype": "Currency",
"hidden": null, "permlevel": 0,
"ignore_restrictions": null, "read_only": 0,
"in_filter": null, "reqd": 0
"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
},
{ {
"allow_on_submit": null, "fieldname": "tax_amount",
"default": null, "fieldtype": "Currency",
"depends_on": null, "in_list_view": 1,
"description": null, "label": "Amount",
"fieldname": "tax_amount", "oldfieldname": "tax_amount",
"fieldtype": "Currency", "oldfieldtype": "Currency",
"hidden": null, "options": "Company:company:default_currency",
"ignore_restrictions": null, "permlevel": 0,
"in_filter": null, "read_only": 1,
"in_list_view": 1, "reqd": 0
"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
},
{ {
"allow_on_submit": null, "fieldname": "total",
"default": null, "fieldtype": "Currency",
"depends_on": null, "label": "Total",
"description": null, "oldfieldname": "total",
"fieldname": "total", "oldfieldtype": "Currency",
"fieldtype": "Currency", "options": "Company:company:default_currency",
"hidden": null, "permlevel": 0,
"ignore_restrictions": null, "read_only": 1
"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
},
{ {
"allow_on_submit": null, "fieldname": "item_wise_tax_detail",
"default": null, "fieldtype": "Small Text",
"depends_on": null, "hidden": 1,
"description": null, "label": "Item Wise Tax Detail ",
"fieldname": "item_wise_tax_detail", "oldfieldname": "item_wise_tax_detail",
"fieldtype": "Small Text", "oldfieldtype": "Small Text",
"hidden": 1, "permlevel": 0,
"ignore_restrictions": null, "print_hide": 1,
"in_filter": null, "read_only": 1
"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
},
{ {
"allow_on_submit": null, "fieldname": "parenttype",
"default": null, "fieldtype": "Data",
"depends_on": null, "hidden": 1,
"description": null, "in_filter": 1,
"fieldname": "parenttype", "label": "Parenttype",
"fieldtype": "Data", "oldfieldname": "parenttype",
"hidden": 1, "oldfieldtype": "Data",
"ignore_restrictions": null, "permlevel": 0,
"in_filter": 1, "print_hide": 1,
"in_list_view": null, "read_only": 0,
"label": "Parenttype", "search_index": 0
"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
} }
], ],
"hide_heading": 1, "hide_heading": 1,
"hide_toolbar": null, "idx": 1,
"icon": null, "istable": 1,
"idx": 1, "modified": "2014-05-30 03:43:32.494112",
"in_create": null, "modified_by": "Administrator",
"in_dialog": null, "module": "Accounts",
"is_submittable": null, "name": "Purchase Taxes and Charges",
"is_transaction_doc": null, "owner": "Administrator",
"issingle": null, "permissions": []
"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
}

View File

@ -21,9 +21,9 @@ erpnext.POS = Class.extend({
<tr>\ <tr>\
<th style="width: 40%">'+__("Item")+'</th>\ <th style="width: 40%">'+__("Item")+'</th>\
<th style="width: 9%"></th>\ <th style="width: 9%"></th>\
<th style="width: 17%; text-align: right;">Qty</th>\ <th style="width: 22%; text-align: right;">Qty</th>\
<th style="width: 9%"></th>\ <th style="width: 9%"></th>\
<th style="width: 25%; text-align: right;">Rate</th>\ <th style="width: 20%; text-align: right;">Rate</th>\
</tr>\ </tr>\
</thead>\ </thead>\
<tbody>\ <tbody>\
@ -367,10 +367,8 @@ erpnext.POS = Class.extend({
this.hide_payment_button(); this.hide_payment_button();
// If quotation to is not Customer then remove party // 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(); this.party_field.$wrapper.remove();
if (this.frm.doc.quotation_to == "Customer")
this.make_party();
} }
}, },
refresh_item_list: function() { refresh_item_list: function() {
@ -389,14 +387,19 @@ erpnext.POS = Class.extend({
$(repl('<tr id="%(item_code)s" data-selected="false">\ $(repl('<tr id="%(item_code)s" data-selected="false">\
<td>%(item_code)s%(item_name)s</td>\ <td>%(item_code)s%(item_name)s</td>\
<td style="vertical-align:middle;" align="right">\ <td style="vertical-align:top; padding-top: 10px;" \
align="right">\
<div class="decrease-qty" style="cursor:pointer;">\ <div class="decrease-qty" style="cursor:pointer;">\
<i class="icon-minus-sign icon-large text-danger"></i>\ <i class="icon-minus-sign icon-large text-danger"></i>\
</div>\ </div>\
</td>\ </td>\
<td style="vertical-align:middle;"><input type="text" value="%(qty)s" \ <td style="vertical-align:middle;">\
class="form-control qty" style="text-align: right;"></td>\ <input type="text" value="%(qty)s" \
<td style="vertical-align:middle;cursor:pointer;">\ class="form-control qty" style="text-align: right;">\
<div class="actual-qty small text-muted">'
+__("Stock: ")+'<span class="text-success">%(actual_qty)s</span>%(projected_qty)s</div>\
</td>\
<td style="vertical-align:top; padding-top: 10px;">\
<div class="increase-qty" style="cursor:pointer;">\ <div class="increase-qty" style="cursor:pointer;">\
<i class="icon-plus-sign icon-large text-success"></i>\ <i class="icon-plus-sign icon-large text-success"></i>\
</div>\ </div>\
@ -407,6 +410,9 @@ erpnext.POS = Class.extend({
item_code: d.item_code, item_code: d.item_code,
item_name: d.item_name===d.item_code ? "" : ("<br>" + d.item_name), item_name: d.item_name===d.item_code ? "" : ("<br>" + d.item_name),
qty: d.qty, qty: d.qty,
actual_qty: d.actual_qty,
projected_qty: d.projected_qty ? (" <span title='"+__("Projected Qty")
+"'>(" + d.projected_qty + ")<span>") : "",
rate: format_currency(d.rate, me.frm.doc.currency), rate: format_currency(d.rate, me.frm.doc.currency),
amount: format_currency(d.amount, 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(); 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) { increase_decrease_qty: function(tr, operation) {
var item_code = tr.attr("id"); var item_code = tr.attr("id");
@ -489,7 +499,7 @@ erpnext.POS = Class.extend({
if (operation == "increase-qty") if (operation == "increase-qty")
this.update_qty(item_code, item_qty + 1); 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); this.update_qty(item_code, item_qty - 1);
}, },
disable_text_box_and_button: function() { disable_text_box_and_button: function() {

View File

@ -11,7 +11,6 @@ cur_frm.pformat.print_heading = 'Invoice';
{% include 'selling/sales_common.js' %}; {% include 'selling/sales_common.js' %};
{% include 'accounts/doctype/sales_taxes_and_charges_master/sales_taxes_and_charges_master.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' %} {% include 'accounts/doctype/sales_invoice/pos.js' %}
frappe.provide("erpnext.accounts"); 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 // 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) { if(this.frm.doc.__islocal && !this.frm.doc.amended_from && !this.frm.doc.customer) {
this.frm.set_value("is_pos", 1); this.frm.set_value("is_pos", 1);
this.is_pos(function() { 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 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) { 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"; locals.DocType[cur_frm.doctype].default_print_format = "POS Invoice";
cur_frm.setup_print_layout(); cur_frm.setup_print_layout();
} }
@ -73,12 +73,14 @@ erpnext.accounts.SalesInvoiceController = erpnext.selling.SellingController.exte
return item.delivery_note ? true : false; return item.delivery_note ? true : false;
}); });
if(!from_delivery_note) if(!from_delivery_note) {
cur_frm.appframe.add_primary_action(__('Make Delivery'), cur_frm.cscript['Make Delivery Note']) cur_frm.appframe.add_primary_action(__('Make Delivery'), cur_frm.cscript['Make Delivery Note'], "icon-truck")
}
} }
if(doc.outstanding_amount!=0) if(doc.outstanding_amount!=0) {
cur_frm.appframe.add_primary_action(__('Make Payment Entry'), cur_frm.cscript.make_bank_voucher); 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 // Show buttons only when pos view is active
@ -102,7 +104,7 @@ erpnext.accounts.SalesInvoiceController = erpnext.selling.SellingController.exte
company: cur_frm.doc.company company: cur_frm.doc.company
} }
}) })
}); }, "icon-download", "btn-default");
}, },
delivery_note_btn: function() { delivery_note_btn: function() {
@ -122,7 +124,7 @@ erpnext.accounts.SalesInvoiceController = erpnext.selling.SellingController.exte
}; };
} }
}); });
}); }, "icon-download", "btn-default");
}, },
tc_name: function() { tc_name: function() {
@ -155,8 +157,9 @@ erpnext.accounts.SalesInvoiceController = erpnext.selling.SellingController.exte
}, },
customer: function() { customer: function() {
if(this.frm.updating_party_details) var me = this;
return; if(this.frm.updating_party_details) return;
erpnext.utils.get_party_details(this.frm, erpnext.utils.get_party_details(this.frm,
"erpnext.accounts.party.get_party_details", { "erpnext.accounts.party.get_party_details", {
posting_date: this.frm.doc.posting_date, posting_date: this.frm.doc.posting_date,
@ -164,7 +167,9 @@ erpnext.accounts.SalesInvoiceController = erpnext.selling.SellingController.exte
party_type: "Customer", party_type: "Customer",
account: this.frm.doc.debit_to, account: this.frm.doc.debit_to,
price_list: this.frm.doc.selling_price_list, price_list: this.frm.doc.selling_price_list,
}) }, function() {
me.apply_pricing_rule();
})
}, },
debit_to: function() { 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"]); frappe.model.round_floats_in(this.frm.doc, ["grand_total", "paid_amount"]);
// this will make outstanding amount 0 // this will make outstanding amount 0
this.frm.set_value("write_off_amount", this.frm.set_value("write_off_amount",
flt(this.frm.doc.grand_total - this.frm.doc.paid_amount), flt(this.frm.doc.grand_total - this.frm.doc.paid_amount,
precision("write_off_amount")); precision("write_off_amount"))
);
} }
this.calculate_outstanding_amount(false); 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', par_flds = ['project_name', 'due_date', 'is_opening', 'source', 'total_advance', 'gross_profit',
'gross_profit_percent', 'get_advances_received', 'gross_profit_percent', 'get_advances_received',
'advance_adjustment_details', 'sales_partner', 'commission_rate', 'advance_adjustment_details', 'sales_partner', 'commission_rate',
'total_commission', 'advances']; 'total_commission', 'advances', 'from_date', 'to_date'];
item_flds_normal = ['sales_order', 'delivery_note'] 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 // set default values for recurring invoices
if(doc.convert_into_recurring_invoice) { if(doc.is_recurring) {
var owner_email = doc.owner=="Administrator" var owner_email = doc.owner=="Administrator"
? frappe.user_info("Administrator").email ? frappe.user_info("Administrator").email
: doc.owner; : 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"]); refresh_many(["notification_email_address", "repeat_on_day_of_month"]);
} }
cur_frm.cscript.invoice_period_from_date = function(doc, dt, dn) { cur_frm.cscript.from_date = function(doc, dt, dn) {
// set invoice_period_to_date // set to_date
if(doc.invoice_period_from_date) { if(doc.from_date) {
var recurring_type_map = {'Monthly': 1, 'Quarterly': 3, 'Half-yearly': 6, var recurring_type_map = {'Monthly': 1, 'Quarterly': 3, 'Half-yearly': 6,
'Yearly': 12}; 'Yearly': 12};
var months = recurring_type_map[doc.recurring_type]; var months = recurring_type_map[doc.recurring_type];
if(months) { 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); months);
doc.invoice_period_to_date = frappe.datetime.add_days(to_date, -1); doc.to_date = frappe.datetime.add_days(to_date, -1);
refresh_field('invoice_period_to_date'); 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);
}

View File

@ -71,7 +71,7 @@
}, },
{ {
"fieldname": "contact_mobile", "fieldname": "contact_mobile",
"fieldtype": "Text", "fieldtype": "Small Text",
"hidden": 1, "hidden": 1,
"label": "Mobile No", "label": "Mobile No",
"permlevel": 0, "permlevel": 0,
@ -79,13 +79,24 @@
}, },
{ {
"fieldname": "contact_email", "fieldname": "contact_email",
"fieldtype": "Text", "fieldtype": "Small Text",
"hidden": 1, "hidden": 1,
"label": "Contact Email", "label": "Contact Email",
"permlevel": 0, "permlevel": 0,
"print_hide": 1, "print_hide": 1,
"read_only": 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", "fieldname": "column_break1",
"fieldtype": "Column Break", "fieldtype": "Column Break",
@ -103,19 +114,6 @@
"print_hide": 1, "print_hide": 1,
"read_only": 0 "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", "fieldname": "company",
"fieldtype": "Link", "fieldtype": "Link",
@ -130,12 +128,25 @@
"reqd": 1, "reqd": 1,
"search_index": 0 "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", "default": "Today",
"fieldname": "posting_date", "fieldname": "posting_date",
"fieldtype": "Date", "fieldtype": "Date",
"in_filter": 1, "in_filter": 1,
"label": "Posting Date", "label": "Date",
"no_copy": 1, "no_copy": 1,
"oldfieldname": "posting_date", "oldfieldname": "posting_date",
"oldfieldtype": "Date", "oldfieldtype": "Date",
@ -159,14 +170,27 @@
"search_index": 0 "search_index": 0
}, },
{ {
"fieldname": "mode_of_payment", "allow_on_submit": 1,
"fieldtype": "Link", "depends_on": "",
"label": "Mode of Payment", "description": "Start date of current invoice's period",
"no_copy": 0, "fieldname": "from_date",
"oldfieldname": "mode_of_payment", "fieldtype": "Date",
"oldfieldtype": "Select", "label": "From",
"options": "Mode of Payment", "no_copy": 1,
"permlevel": 0, "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 "read_only": 0
}, },
{ {
@ -241,6 +265,14 @@
"read_only": 0, "read_only": 0,
"reqd": 1 "reqd": 1
}, },
{
"fieldname": "ignore_pricing_rule",
"fieldtype": "Check",
"label": "Ignore Pricing Rule",
"no_copy": 1,
"permlevel": 1,
"print_hide": 1
},
{ {
"fieldname": "items", "fieldname": "items",
"fieldtype": "Section Break", "fieldtype": "Section Break",
@ -303,20 +335,6 @@
"fieldtype": "Section Break", "fieldtype": "Section Break",
"permlevel": 0 "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", "fieldname": "net_total",
"fieldtype": "Currency", "fieldtype": "Currency",
@ -329,6 +347,20 @@
"read_only": 1, "read_only": 1,
"reqd": 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", "fieldname": "taxes",
"fieldtype": "Section Break", "fieldtype": "Section Break",
@ -395,10 +427,12 @@
"permlevel": 0 "permlevel": 0
}, },
{ {
"fieldname": "other_charges_total_export", "fieldname": "other_charges_total",
"fieldtype": "Currency", "fieldtype": "Currency",
"label": "Total Taxes and Charges", "label": "Total Taxes and Charges (Company Currency)",
"options": "currency", "oldfieldname": "other_charges_total",
"oldfieldtype": "Currency",
"options": "Company:company:default_currency",
"permlevel": 0, "permlevel": 0,
"print_hide": 1, "print_hide": 1,
"read_only": 1 "read_only": 1
@ -409,12 +443,10 @@
"permlevel": 0 "permlevel": 0
}, },
{ {
"fieldname": "other_charges_total", "fieldname": "other_charges_total_export",
"fieldtype": "Currency", "fieldtype": "Currency",
"label": "Total Taxes and Charges (Company Currency)", "label": "Total Taxes and Charges",
"oldfieldname": "other_charges_total", "options": "currency",
"oldfieldtype": "Currency",
"options": "Company:company:default_currency",
"permlevel": 0, "permlevel": 0,
"print_hide": 1, "print_hide": 1,
"read_only": 1 "read_only": 1
@ -437,70 +469,6 @@
"print_hide": 1, "print_hide": 1,
"read_only": 0 "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", "fieldname": "grand_total",
"fieldtype": "Currency", "fieldtype": "Currency",
@ -561,6 +529,70 @@
"print_hide": 1, "print_hide": 1,
"read_only": 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", "fieldname": "advances",
"fieldtype": "Section Break", "fieldtype": "Section Break",
@ -682,6 +714,11 @@
"print_hide": 1, "print_hide": 1,
"read_only": 0 "read_only": 0
}, },
{
"fieldname": "fold",
"fieldtype": "Fold",
"permlevel": 0
},
{ {
"fieldname": "terms_section_break", "fieldname": "terms_section_break",
"fieldtype": "Section Break", "fieldtype": "Section Break",
@ -1051,9 +1088,9 @@
"allow_on_submit": 1, "allow_on_submit": 1,
"depends_on": "eval:doc.docstatus<2", "depends_on": "eval:doc.docstatus<2",
"description": "Check if recurring invoice, uncheck to stop recurring or put proper End Date", "description": "Check if recurring invoice, uncheck to stop recurring or put proper End Date",
"fieldname": "convert_into_recurring_invoice", "fieldname": "is_recurring",
"fieldtype": "Check", "fieldtype": "Check",
"label": "Convert into Recurring Invoice", "label": "Is Recurring",
"no_copy": 1, "no_copy": 1,
"permlevel": 0, "permlevel": 0,
"print_hide": 1, "print_hide": 1,
@ -1061,7 +1098,7 @@
}, },
{ {
"allow_on_submit": 1, "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", "description": "Select the period when the invoice will be generated automatically",
"fieldname": "recurring_type", "fieldname": "recurring_type",
"fieldtype": "Select", "fieldtype": "Select",
@ -1074,7 +1111,7 @@
}, },
{ {
"allow_on_submit": 1, "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 ", "description": "The day of the month on which auto invoice will be generated e.g. 05, 28 etc ",
"fieldname": "repeat_on_day_of_month", "fieldname": "repeat_on_day_of_month",
"fieldtype": "Int", "fieldtype": "Int",
@ -1085,24 +1122,23 @@
"read_only": 0 "read_only": 0
}, },
{ {
"allow_on_submit": 1, "depends_on": "eval:doc.is_recurring==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",
"description": "Start date of current invoice's period", "fieldname": "next_date",
"fieldname": "invoice_period_from_date",
"fieldtype": "Date", "fieldtype": "Date",
"label": "Invoice Period From Date", "label": "Next Date",
"no_copy": 1, "no_copy": 1,
"permlevel": 0, "permlevel": 0,
"print_hide": 1, "print_hide": 1,
"read_only": 0 "read_only": 1
}, },
{ {
"allow_on_submit": 1, "allow_on_submit": 1,
"depends_on": "eval:doc.convert_into_recurring_invoice==1", "depends_on": "eval:doc.is_recurring==1",
"description": "End date of current invoice's period", "description": "The date on which recurring invoice will be stop",
"fieldname": "invoice_period_to_date", "fieldname": "end_date",
"fieldtype": "Date", "fieldtype": "Date",
"label": "Invoice Period To Date", "label": "End Date",
"no_copy": 1, "no_copy": 1,
"permlevel": 0, "permlevel": 0,
"print_hide": 1, "print_hide": 1,
@ -1118,19 +1154,7 @@
"width": "50%" "width": "50%"
}, },
{ {
"allow_on_submit": 1, "depends_on": "eval:doc.is_recurring==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",
"description": "The unique id for tracking all recurring invoices.\u00a0It is generated on submit.", "description": "The unique id for tracking all recurring invoices.\u00a0It is generated on submit.",
"fieldname": "recurring_id", "fieldname": "recurring_id",
"fieldtype": "Data", "fieldtype": "Data",
@ -1140,24 +1164,13 @@
"print_hide": 1, "print_hide": 1,
"read_only": 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, "allow_on_submit": 1,
"depends_on": "eval:doc.convert_into_recurring_invoice==1", "depends_on": "eval:doc.is_recurring==1",
"description": "The date on which recurring invoice will be stop", "description": "Enter email id separated by commas, invoice will be mailed automatically on particular date",
"fieldname": "end_date", "fieldname": "notification_email_address",
"fieldtype": "Date", "fieldtype": "Small Text",
"label": "End Date", "label": "Notification Email Address",
"no_copy": 1, "no_copy": 1,
"permlevel": 0, "permlevel": 0,
"print_hide": 1, "print_hide": 1,
@ -1180,7 +1193,7 @@
"icon": "icon-file-text", "icon": "icon-file-text",
"idx": 1, "idx": 1,
"is_submittable": 1, "is_submittable": 1,
"modified": "2014-05-09 02:17:00.217556", "modified": "2014-08-28 11:21:00.726344",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Accounts", "module": "Accounts",
"name": "Sales Invoice", "name": "Sales Invoice",
@ -1202,6 +1215,7 @@
}, },
{ {
"amend": 1, "amend": 1,
"apply_user_permissions": 1,
"cancel": 0, "cancel": 0,
"create": 1, "create": 1,
"delete": 0, "delete": 0,
@ -1215,6 +1229,7 @@
"write": 1 "write": 1
}, },
{ {
"apply_user_permissions": 1,
"cancel": 0, "cancel": 0,
"delete": 0, "delete": 0,
"email": 1, "email": 1,
@ -1223,6 +1238,12 @@
"read": 1, "read": 1,
"report": 1, "report": 1,
"role": "Customer" "role": "Customer"
},
{
"permlevel": 1,
"read": 1,
"role": "Accounts Manager",
"write": 1
} }
], ],
"read_only_onload": 1, "read_only_onload": 1,

View File

@ -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 erpnext.controllers.stock_controller import update_gl_entries_after
from frappe.model.mapper import get_mapped_doc 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 from erpnext.controllers.selling_controller import SellingController
form_grid_templates = {
"entries": "templates/form_grid/item_grid.html"
}
class SalesInvoice(SellingController): class SalesInvoice(SellingController):
tname = 'Sales Invoice Item' tname = 'Sales Invoice Item'
fname = 'entries' fname = 'entries'
@ -36,7 +40,8 @@ class SalesInvoice(SellingController):
'join_field': 'so_detail', 'join_field': 'so_detail',
'percent_join_field': 'sales_order', 'percent_join_field': 'sales_order',
'status_field': 'billing_status', 'status_field': 'billing_status',
'keyword': 'Billed' 'keyword': 'Billed',
'overflow_type': 'billing'
}] }]
def validate(self): def validate(self):
@ -70,7 +75,7 @@ class SalesInvoice(SellingController):
self.set_against_income_account() self.set_against_income_account()
self.validate_c_form() self.validate_c_form()
self.validate_time_logs_are_submitted() self.validate_time_logs_are_submitted()
self.validate_recurring_invoice() validate_recurring_document(self)
self.validate_multiple_billing("Delivery Note", "dn_detail", "amount", self.validate_multiple_billing("Delivery Note", "dn_detail", "amount",
"delivery_note_details") "delivery_note_details")
@ -98,7 +103,7 @@ class SalesInvoice(SellingController):
self.update_c_form() self.update_c_form()
self.update_time_log_batch(self.name) self.update_time_log_batch(self.name)
self.convert_to_recurring() convert_to_recurring(self, "RECINV.#####", self.posting_date)
def before_cancel(self): def before_cancel(self):
self.update_time_log_batch(None) self.update_time_log_batch(None)
@ -116,7 +121,7 @@ class SalesInvoice(SellingController):
self.update_prevdoc_status() self.update_prevdoc_status()
self.update_billing_status_for_zero_amount_refdoc("Sales Order") 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): def update_status_updater_args(self):
if cint(self.update_stock): if cint(self.update_stock):
@ -134,12 +139,13 @@ class SalesInvoice(SellingController):
'keyword':'Delivered', 'keyword':'Delivered',
'second_source_dt': 'Delivery Note Item', 'second_source_dt': 'Delivery Note Item',
'second_source_field': 'qty', '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): def on_update_after_submit(self):
self.validate_recurring_invoice() validate_recurring_document(self)
self.convert_to_recurring() convert_to_recurring(self, "RECINV.#####", self.posting_date)
def get_portal_page(self): def get_portal_page(self):
return "invoice" if self.docstatus==1 else None return "invoice" if self.docstatus==1 else None
@ -262,11 +268,11 @@ class SalesInvoice(SellingController):
"""Validate Fixed Asset and whether Income Account Entered Exists""" """Validate Fixed Asset and whether Income Account Entered Exists"""
for d in self.get('entries'): for d in self.get('entries'):
item = frappe.db.sql("""select name,is_asset_item,is_sales_item from `tabItem` 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) where name = %s""", d.item_code)
acc = frappe.db.sql("""select account_type from `tabAccount` acc = frappe.db.sql("""select account_type from `tabAccount`
where name = %s and docstatus != 2""", d.income_account) where name = %s and docstatus != 2""", d.income_account)
if item and item[0][1] == 'Yes' and not acc[0][0] == 'Fixed Asset': 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(d.item_code), raise_exception=True) 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): def validate_with_previous_doc(self):
super(SalesInvoice, self).validate_with_previous_doc(self.tname, { super(SalesInvoice, self).validate_with_previous_doc(self.tname, {
@ -339,8 +345,8 @@ class SalesInvoice(SellingController):
def validate_pos(self): def validate_pos(self):
if not self.cash_bank_account and flt(self.paid_amount): if not self.cash_bank_account and flt(self.paid_amount):
msgprint(_("Cash or Bank Account is mandatory for making payment entry")) frappe.throw(_("Cash or Bank Account is mandatory for making payment entry"))
raise Exception
if flt(self.paid_amount) + flt(self.write_off_amount) \ if flt(self.paid_amount) + flt(self.write_off_amount) \
- flt(self.grand_total) > 1/(10**(self.precision("grand_total") + 1)): - 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""")) 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): def get_warehouse(self):
w = frappe.db.sql("""select warehouse from `tabPOS Setting` user_pos_setting = frappe.db.sql("""select name, warehouse from `tabPOS Setting`
where ifnull(user,'') = %s and company = %s""", where ifnull(user,'') = %s and company = %s""", (frappe.session['user'], self.company))
(frappe.session['user'], self.company)) warehouse = user_pos_setting[0][1] if user_pos_setting else None
w = w and w[0][0] or ''
if not w: if not warehouse:
ps = frappe.db.sql("""select name, warehouse from `tabPOS Setting` global_pos_setting = frappe.db.sql("""select name, warehouse from `tabPOS Setting`
where ifnull(user,'') = '' and company = %s""", self.company) 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) msgprint(_("POS Setting required to make POS Entry"), raise_exception=True)
elif not ps[0][1]:
msgprint(_("Warehouse required in POS Setting")) return warehouse
else:
w = ps[0][1]
return w
def on_update(self): def on_update(self):
if cint(self.update_stock) == 1: if cint(self.update_stock) == 1:
@ -431,8 +437,7 @@ class SalesInvoice(SellingController):
submitted = frappe.db.sql("""select name from `tabSales Order` submitted = frappe.db.sql("""select name from `tabSales Order`
where docstatus = 1 and name = %s""", d.sales_order) where docstatus = 1 and name = %s""", d.sales_order)
if not submitted: if not submitted:
msgprint(_("Sales Order {0} is not submitted").format(d.sales_order)) frappe.throw(_("Sales Order {0} is not submitted").format(d.sales_order))
raise Exception
if d.delivery_note: if d.delivery_note:
submitted = frappe.db.sql("""select name from `tabDelivery 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""", grand_total = %s where invoice_no = %s and parent = %s""",
(self.name, self.amended_from, self.c_form_no)) (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() @frappe.whitelist()
def get_bank_cash_account(mode_of_payment): def get_bank_cash_account(mode_of_payment):
val = frappe.db.get_value("Mode of Payment", mode_of_payment, "default_account") 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() @frappe.whitelist()
def make_delivery_note(source_name, target_doc=None): def make_delivery_note(source_name, target_doc=None):
def set_missing_values(source, target): def set_missing_values(source, target):
target.ignore_pricing_rule = 1
target.run_method("set_missing_values") target.run_method("set_missing_values")
target.run_method("calculate_taxes_and_totals") target.run_method("calculate_taxes_and_totals")

View File

@ -0,0 +1,45 @@
<div class="row" style="max-height: 30px;">
<div class="col-xs-9">
<div class="text-ellipsis">
{%= list.get_avatar_and_id(doc) %}
<span style="margin-right: 8px; display: inline-block">
<span class="filterable"
data-filter="customer,=,{%= doc.customer %}">
{%= doc.customer_name %}</span></span>
{% if(doc.outstanding_amount > 0 && doc.docstatus==1) { %}
{% if(frappe.datetime.get_diff(doc.due_date) < 0) { %}
<span class="label label-danger filterable"
title="{%= doc.get_formatted("due_date")%}"
data-filter="outstanding_amount,>,0|due_date,<,Today">
{%= __("Overdue: ") + comment_when(doc.due_date) %}
</span>
{% } else { %}
<span class="label label-warning filterable"
data-filter="outstanding_amount,>,0|due_date,>=,Today"
title="{%= __("Payment Pending") %}">
{%= doc.get_formatted("due_date") %}</span>
{% } %}
{% } %}
{% if(doc.outstanding_amount==0 && doc.docstatus==1) { %}
<span class="label label-success filterable"
title="{%= doc.get_formatted("due_date")%}"
data-filter="outstanding_amount,=,0">
<i class="icon-ok-sign"></i> {%= __("Paid") %}
</span>
{% } %}
{% if(doc.docstatus===0) { %}
<span class="label label-danger filterable"
data-filter="docstatus,=,0">{%= __("Draft") %}</span>
{% } %}
</div>
</div>
<div class="col-xs-1 text-right">
{% 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" %}
</div>
<div class="col-xs-2 text-right">
<div class="text-ellipsis" title="{%= doc.get_formatted("grand_total_export") %}">
{%= doc.get_formatted("grand_total_export") %}
</div>
</div>
</div>

View File

@ -3,12 +3,7 @@
// render // render
frappe.listview_settings['Sales Invoice'] = { frappe.listview_settings['Sales Invoice'] = {
add_fields: ["`tabSales Invoice`.grand_total", "`tabSales Invoice`.outstanding_amount"], add_fields: ["customer", "customer_name", "grand_total", "outstanding_amount", "due_date", "company",
add_columns: [{"content":"Percent Paid", width:"10%", type:"bar-graph", "currency"],
label: "Payment Received"}], filters: [["outstanding_amount", ">", "0"]]
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;
}
}; };

View File

@ -1,385 +1,390 @@
[ [
{ {
"company": "_Test Company", "company": "_Test Company",
"conversion_rate": 1.0, "conversion_rate": 1.0,
"currency": "INR", "currency": "INR",
"customer": "_Test Customer", "customer": "_Test Customer",
"customer_name": "_Test Customer", "customer_name": "_Test Customer",
"debit_to": "_Test Customer - _TC", "debit_to": "_Test Customer - _TC",
"doctype": "Sales Invoice", "doctype": "Sales Invoice",
"due_date": "2013-01-23", "due_date": "2013-01-23",
"entries": [ "entries": [
{ {
"amount": 500.0, "amount": 500.0,
"base_amount": 500.0, "base_amount": 500.0,
"base_rate": 500.0, "base_rate": 500.0,
"cost_center": "_Test Cost Center - _TC", "cost_center": "_Test Cost Center - _TC",
"description": "138-CMS Shoe", "description": "138-CMS Shoe",
"doctype": "Sales Invoice Item", "doctype": "Sales Invoice Item",
"income_account": "Sales - _TC", "income_account": "Sales - _TC",
"item_name": "138-CMS Shoe", "expense_account": "_Test Account Cost for Goods Sold - _TC",
"parentfield": "entries", "item_name": "138-CMS Shoe",
"qty": 1.0, "parentfield": "entries",
"qty": 1.0,
"rate": 500.0 "rate": 500.0
} }
], ],
"fiscal_year": "_Test Fiscal Year 2013", "fiscal_year": "_Test Fiscal Year 2013",
"grand_total": 561.8, "grand_total": 561.8,
"grand_total_export": 561.8, "grand_total_export": 561.8,
"is_pos": 0, "is_pos": 0,
"naming_series": "_T-Sales Invoice-", "naming_series": "_T-Sales Invoice-",
"net_total": 500.0, "net_total": 500.0,
"other_charges": [ "other_charges": [
{ {
"account_head": "_Test Account VAT - _TC", "account_head": "_Test Account VAT - _TC",
"charge_type": "On Net Total", "charge_type": "On Net Total",
"description": "VAT", "description": "VAT",
"doctype": "Sales Taxes and Charges", "doctype": "Sales Taxes and Charges",
"parentfield": "other_charges", "parentfield": "other_charges",
"rate": 6 "rate": 6
}, },
{ {
"account_head": "_Test Account Service Tax - _TC", "account_head": "_Test Account Service Tax - _TC",
"charge_type": "On Net Total", "charge_type": "On Net Total",
"description": "Service Tax", "description": "Service Tax",
"doctype": "Sales Taxes and Charges", "doctype": "Sales Taxes and Charges",
"parentfield": "other_charges", "parentfield": "other_charges",
"rate": 6.36 "rate": 6.36
} }
], ],
"plc_conversion_rate": 1.0, "plc_conversion_rate": 1.0,
"posting_date": "2013-01-23", "posting_date": "2013-01-23",
"price_list_currency": "INR", "price_list_currency": "INR",
"sales_team": [ "sales_team": [
{ {
"allocated_percentage": 65.5, "allocated_percentage": 65.5,
"doctype": "Sales Team", "doctype": "Sales Team",
"parentfield": "sales_team", "parentfield": "sales_team",
"sales_person": "_Test Sales Person 1" "sales_person": "_Test Sales Person 1"
}, },
{ {
"allocated_percentage": 34.5, "allocated_percentage": 34.5,
"doctype": "Sales Team", "doctype": "Sales Team",
"parentfield": "sales_team", "parentfield": "sales_team",
"sales_person": "_Test Sales Person 2" "sales_person": "_Test Sales Person 2"
} }
], ],
"selling_price_list": "_Test Price List", "selling_price_list": "_Test Price List",
"territory": "_Test Territory" "territory": "_Test Territory"
}, },
{ {
"company": "_Test Company", "company": "_Test Company",
"conversion_rate": 1.0, "conversion_rate": 1.0,
"currency": "INR", "currency": "INR",
"customer": "_Test Customer", "customer": "_Test Customer",
"customer_name": "_Test Customer", "customer_name": "_Test Customer",
"debit_to": "_Test Customer - _TC", "debit_to": "_Test Customer - _TC",
"doctype": "Sales Invoice", "doctype": "Sales Invoice",
"due_date": "2013-01-23", "due_date": "2013-03-07",
"entries": [ "entries": [
{ {
"amount": 500.0, "amount": 500.0,
"base_amount": 500.0, "base_amount": 500.0,
"base_rate": 500.0, "base_rate": 500.0,
"cost_center": "_Test Cost Center - _TC", "cost_center": "_Test Cost Center - _TC",
"description": "_Test Item", "description": "_Test Item",
"doctype": "Sales Invoice Item", "doctype": "Sales Invoice Item",
"expense_account": "_Test Account Cost for Goods Sold - _TC", "expense_account": "_Test Account Cost for Goods Sold - _TC",
"income_account": "Sales - _TC", "income_account": "Sales - _TC",
"item_code": "_Test Item", "item_code": "_Test Item",
"item_name": "_Test Item", "item_name": "_Test Item",
"parentfield": "entries", "parentfield": "entries",
"price_list_rate": 500.0, "price_list_rate": 500.0,
"qty": 1.0 "qty": 1.0
} }
], ],
"fiscal_year": "_Test Fiscal Year 2013", "fiscal_year": "_Test Fiscal Year 2013",
"grand_total": 630.0, "grand_total": 630.0,
"grand_total_export": 630.0, "grand_total_export": 630.0,
"is_pos": 0, "is_pos": 0,
"naming_series": "_T-Sales Invoice-", "naming_series": "_T-Sales Invoice-",
"net_total": 500.0, "net_total": 500.0,
"other_charges": [ "other_charges": [
{ {
"account_head": "_Test Account VAT - _TC", "account_head": "_Test Account VAT - _TC",
"charge_type": "On Net Total", "charge_type": "On Net Total",
"description": "VAT", "description": "VAT",
"doctype": "Sales Taxes and Charges", "doctype": "Sales Taxes and Charges",
"parentfield": "other_charges", "parentfield": "other_charges",
"rate": 16 "rate": 16
}, },
{ {
"account_head": "_Test Account Service Tax - _TC", "account_head": "_Test Account Service Tax - _TC",
"charge_type": "On Net Total", "charge_type": "On Net Total",
"description": "Service Tax", "description": "Service Tax",
"doctype": "Sales Taxes and Charges", "doctype": "Sales Taxes and Charges",
"parentfield": "other_charges", "parentfield": "other_charges",
"rate": 10 "rate": 10
} }
], ],
"plc_conversion_rate": 1.0, "plc_conversion_rate": 1.0,
"posting_date": "2013-03-07", "posting_date": "2013-03-07",
"price_list_currency": "INR", "price_list_currency": "INR",
"selling_price_list": "_Test Price List", "selling_price_list": "_Test Price List",
"territory": "_Test Territory" "territory": "_Test Territory"
}, },
{ {
"company": "_Test Company", "company": "_Test Company",
"conversion_rate": 1.0, "conversion_rate": 1.0,
"currency": "INR", "currency": "INR",
"customer": "_Test Customer", "customer": "_Test Customer",
"customer_name": "_Test Customer", "customer_name": "_Test Customer",
"debit_to": "_Test Customer - _TC", "debit_to": "_Test Customer - _TC",
"doctype": "Sales Invoice", "doctype": "Sales Invoice",
"due_date": "2013-01-23", "due_date": "2013-01-23",
"entries": [ "entries": [
{ {
"cost_center": "_Test Cost Center - _TC", "cost_center": "_Test Cost Center - _TC",
"doctype": "Sales Invoice Item", "doctype": "Sales Invoice Item",
"income_account": "Sales - _TC", "income_account": "Sales - _TC",
"item_code": "_Test Item Home Desktop 100", "expense_account": "_Test Account Cost for Goods Sold - _TC",
"item_name": "_Test Item Home Desktop 100", "item_code": "_Test Item Home Desktop 100",
"item_tax_rate": "{\"_Test Account Excise Duty - _TC\": 10}", "item_name": "_Test Item Home Desktop 100",
"parentfield": "entries", "item_tax_rate": "{\"_Test Account Excise Duty - _TC\": 10}",
"price_list_rate": 50, "parentfield": "entries",
"qty": 10, "price_list_rate": 50,
"rate": 50, "qty": 10,
"rate": 50,
"stock_uom": "_Test UOM" "stock_uom": "_Test UOM"
}, },
{ {
"cost_center": "_Test Cost Center - _TC", "cost_center": "_Test Cost Center - _TC",
"doctype": "Sales Invoice Item", "doctype": "Sales Invoice Item",
"income_account": "Sales - _TC", "income_account": "Sales - _TC",
"item_code": "_Test Item Home Desktop 200", "expense_account": "_Test Account Cost for Goods Sold - _TC",
"item_name": "_Test Item Home Desktop 200", "item_code": "_Test Item Home Desktop 200",
"parentfield": "entries", "item_name": "_Test Item Home Desktop 200",
"price_list_rate": 150, "parentfield": "entries",
"qty": 5, "price_list_rate": 150,
"rate": 150, "qty": 5,
"rate": 150,
"stock_uom": "_Test UOM" "stock_uom": "_Test UOM"
} }
], ],
"fiscal_year": "_Test Fiscal Year 2013", "fiscal_year": "_Test Fiscal Year 2013",
"grand_total_export": 0, "grand_total_export": 0,
"is_pos": 0, "is_pos": 0,
"naming_series": "_T-Sales Invoice-", "naming_series": "_T-Sales Invoice-",
"other_charges": [ "other_charges": [
{ {
"account_head": "_Test Account Shipping Charges - _TC", "account_head": "_Test Account Shipping Charges - _TC",
"charge_type": "Actual", "charge_type": "Actual",
"cost_center": "_Test Cost Center - _TC", "cost_center": "_Test Cost Center - _TC",
"description": "Shipping Charges", "description": "Shipping Charges",
"doctype": "Sales Taxes and Charges", "doctype": "Sales Taxes and Charges",
"parentfield": "other_charges", "parentfield": "other_charges",
"rate": 100 "rate": 100
}, },
{ {
"account_head": "_Test Account Customs Duty - _TC", "account_head": "_Test Account Customs Duty - _TC",
"charge_type": "On Net Total", "charge_type": "On Net Total",
"cost_center": "_Test Cost Center - _TC", "cost_center": "_Test Cost Center - _TC",
"description": "Customs Duty", "description": "Customs Duty",
"doctype": "Sales Taxes and Charges", "doctype": "Sales Taxes and Charges",
"parentfield": "other_charges", "parentfield": "other_charges",
"rate": 10 "rate": 10
}, },
{ {
"account_head": "_Test Account Excise Duty - _TC", "account_head": "_Test Account Excise Duty - _TC",
"charge_type": "On Net Total", "charge_type": "On Net Total",
"cost_center": "_Test Cost Center - _TC", "cost_center": "_Test Cost Center - _TC",
"description": "Excise Duty", "description": "Excise Duty",
"doctype": "Sales Taxes and Charges", "doctype": "Sales Taxes and Charges",
"parentfield": "other_charges", "parentfield": "other_charges",
"rate": 12 "rate": 12
}, },
{ {
"account_head": "_Test Account Education Cess - _TC", "account_head": "_Test Account Education Cess - _TC",
"charge_type": "On Previous Row Amount", "charge_type": "On Previous Row Amount",
"cost_center": "_Test Cost Center - _TC", "cost_center": "_Test Cost Center - _TC",
"description": "Education Cess", "description": "Education Cess",
"doctype": "Sales Taxes and Charges", "doctype": "Sales Taxes and Charges",
"parentfield": "other_charges", "parentfield": "other_charges",
"rate": 2, "rate": 2,
"row_id": 3 "row_id": 3
}, },
{ {
"account_head": "_Test Account S&H Education Cess - _TC", "account_head": "_Test Account S&H Education Cess - _TC",
"charge_type": "On Previous Row Amount", "charge_type": "On Previous Row Amount",
"cost_center": "_Test Cost Center - _TC", "cost_center": "_Test Cost Center - _TC",
"description": "S&H Education Cess", "description": "S&H Education Cess",
"doctype": "Sales Taxes and Charges", "doctype": "Sales Taxes and Charges",
"parentfield": "other_charges", "parentfield": "other_charges",
"rate": 1, "rate": 1,
"row_id": 3 "row_id": 3
}, },
{ {
"account_head": "_Test Account CST - _TC", "account_head": "_Test Account CST - _TC",
"charge_type": "On Previous Row Total", "charge_type": "On Previous Row Total",
"cost_center": "_Test Cost Center - _TC", "cost_center": "_Test Cost Center - _TC",
"description": "CST", "description": "CST",
"doctype": "Sales Taxes and Charges", "doctype": "Sales Taxes and Charges",
"parentfield": "other_charges", "parentfield": "other_charges",
"rate": 2, "rate": 2,
"row_id": 5 "row_id": 5
}, },
{ {
"account_head": "_Test Account VAT - _TC", "account_head": "_Test Account VAT - _TC",
"charge_type": "On Net Total", "charge_type": "On Net Total",
"cost_center": "_Test Cost Center - _TC", "cost_center": "_Test Cost Center - _TC",
"description": "VAT", "description": "VAT",
"doctype": "Sales Taxes and Charges", "doctype": "Sales Taxes and Charges",
"parentfield": "other_charges", "parentfield": "other_charges",
"rate": 12.5 "rate": 12.5
}, },
{ {
"account_head": "_Test Account Discount - _TC", "account_head": "_Test Account Discount - _TC",
"charge_type": "On Previous Row Total", "charge_type": "On Previous Row Total",
"cost_center": "_Test Cost Center - _TC", "cost_center": "_Test Cost Center - _TC",
"description": "Discount", "description": "Discount",
"doctype": "Sales Taxes and Charges", "doctype": "Sales Taxes and Charges",
"parentfield": "other_charges", "parentfield": "other_charges",
"rate": -10, "rate": -10,
"row_id": 7 "row_id": 7
} }
], ],
"plc_conversion_rate": 1.0, "plc_conversion_rate": 1.0,
"posting_date": "2013-01-23", "posting_date": "2013-01-23",
"price_list_currency": "INR", "price_list_currency": "INR",
"selling_price_list": "_Test Price List", "selling_price_list": "_Test Price List",
"territory": "_Test Territory" "territory": "_Test Territory"
}, },
{ {
"company": "_Test Company", "company": "_Test Company",
"conversion_rate": 1.0, "conversion_rate": 1.0,
"currency": "INR", "currency": "INR",
"customer": "_Test Customer", "customer": "_Test Customer",
"customer_name": "_Test Customer", "customer_name": "_Test Customer",
"debit_to": "_Test Customer - _TC", "debit_to": "_Test Customer - _TC",
"doctype": "Sales Invoice", "doctype": "Sales Invoice",
"due_date": "2013-01-23", "due_date": "2013-01-23",
"entries": [ "entries": [
{ {
"cost_center": "_Test Cost Center - _TC", "cost_center": "_Test Cost Center - _TC",
"doctype": "Sales Invoice Item", "doctype": "Sales Invoice Item",
"income_account": "Sales - _TC", "income_account": "Sales - _TC",
"item_code": "_Test Item Home Desktop 100", "expense_account": "_Test Account Cost for Goods Sold - _TC",
"item_name": "_Test Item Home Desktop 100", "item_code": "_Test Item Home Desktop 100",
"item_tax_rate": "{\"_Test Account Excise Duty - _TC\": 10}", "item_name": "_Test Item Home Desktop 100",
"parentfield": "entries", "item_tax_rate": "{\"_Test Account Excise Duty - _TC\": 10}",
"price_list_rate": 62.5, "parentfield": "entries",
"qty": 10, "price_list_rate": 62.5,
"qty": 10,
"stock_uom": "_Test UOM" "stock_uom": "_Test UOM"
}, },
{ {
"cost_center": "_Test Cost Center - _TC", "cost_center": "_Test Cost Center - _TC",
"doctype": "Sales Invoice Item", "doctype": "Sales Invoice Item",
"income_account": "Sales - _TC", "income_account": "Sales - _TC",
"item_code": "_Test Item Home Desktop 200", "expense_account": "_Test Account Cost for Goods Sold - _TC",
"item_name": "_Test Item Home Desktop 200", "item_code": "_Test Item Home Desktop 200",
"parentfield": "entries", "item_name": "_Test Item Home Desktop 200",
"price_list_rate": 190.66, "parentfield": "entries",
"qty": 5, "price_list_rate": 190.66,
"qty": 5,
"stock_uom": "_Test UOM" "stock_uom": "_Test UOM"
} }
], ],
"fiscal_year": "_Test Fiscal Year 2013", "fiscal_year": "_Test Fiscal Year 2013",
"grand_total_export": 0, "grand_total_export": 0,
"is_pos": 0, "is_pos": 0,
"naming_series": "_T-Sales Invoice-", "naming_series": "_T-Sales Invoice-",
"other_charges": [ "other_charges": [
{ {
"account_head": "_Test Account Excise Duty - _TC", "account_head": "_Test Account Excise Duty - _TC",
"charge_type": "On Net Total", "charge_type": "On Net Total",
"cost_center": "_Test Cost Center - _TC", "cost_center": "_Test Cost Center - _TC",
"description": "Excise Duty", "description": "Excise Duty",
"doctype": "Sales Taxes and Charges", "doctype": "Sales Taxes and Charges",
"idx": 1, "idx": 1,
"included_in_print_rate": 1, "included_in_print_rate": 1,
"parentfield": "other_charges", "parentfield": "other_charges",
"rate": 12 "rate": 12
}, },
{ {
"account_head": "_Test Account Education Cess - _TC", "account_head": "_Test Account Education Cess - _TC",
"charge_type": "On Previous Row Amount", "charge_type": "On Previous Row Amount",
"cost_center": "_Test Cost Center - _TC", "cost_center": "_Test Cost Center - _TC",
"description": "Education Cess", "description": "Education Cess",
"doctype": "Sales Taxes and Charges", "doctype": "Sales Taxes and Charges",
"idx": 2, "idx": 2,
"included_in_print_rate": 1, "included_in_print_rate": 1,
"parentfield": "other_charges", "parentfield": "other_charges",
"rate": 2, "rate": 2,
"row_id": 1 "row_id": 1
}, },
{ {
"account_head": "_Test Account S&H Education Cess - _TC", "account_head": "_Test Account S&H Education Cess - _TC",
"charge_type": "On Previous Row Amount", "charge_type": "On Previous Row Amount",
"cost_center": "_Test Cost Center - _TC", "cost_center": "_Test Cost Center - _TC",
"description": "S&H Education Cess", "description": "S&H Education Cess",
"doctype": "Sales Taxes and Charges", "doctype": "Sales Taxes and Charges",
"idx": 3, "idx": 3,
"included_in_print_rate": 1, "included_in_print_rate": 1,
"parentfield": "other_charges", "parentfield": "other_charges",
"rate": 1, "rate": 1,
"row_id": 1 "row_id": 1
}, },
{ {
"account_head": "_Test Account CST - _TC", "account_head": "_Test Account CST - _TC",
"charge_type": "On Previous Row Total", "charge_type": "On Previous Row Total",
"cost_center": "_Test Cost Center - _TC", "cost_center": "_Test Cost Center - _TC",
"description": "CST", "description": "CST",
"doctype": "Sales Taxes and Charges", "doctype": "Sales Taxes and Charges",
"idx": 4, "idx": 4,
"included_in_print_rate": 1, "included_in_print_rate": 1,
"parentfield": "other_charges", "parentfield": "other_charges",
"rate": 2, "rate": 2,
"row_id": 3 "row_id": 3
}, },
{ {
"account_head": "_Test Account VAT - _TC", "account_head": "_Test Account VAT - _TC",
"charge_type": "On Net Total", "charge_type": "On Net Total",
"cost_center": "_Test Cost Center - _TC", "cost_center": "_Test Cost Center - _TC",
"description": "VAT", "description": "VAT",
"doctype": "Sales Taxes and Charges", "doctype": "Sales Taxes and Charges",
"idx": 5, "idx": 5,
"included_in_print_rate": 1, "included_in_print_rate": 1,
"parentfield": "other_charges", "parentfield": "other_charges",
"rate": 12.5 "rate": 12.5
}, },
{ {
"account_head": "_Test Account Customs Duty - _TC", "account_head": "_Test Account Customs Duty - _TC",
"charge_type": "On Net Total", "charge_type": "On Net Total",
"cost_center": "_Test Cost Center - _TC", "cost_center": "_Test Cost Center - _TC",
"description": "Customs Duty", "description": "Customs Duty",
"doctype": "Sales Taxes and Charges", "doctype": "Sales Taxes and Charges",
"idx": 6, "idx": 6,
"parentfield": "other_charges", "parentfield": "other_charges",
"rate": 10 "rate": 10
}, },
{ {
"account_head": "_Test Account Shipping Charges - _TC", "account_head": "_Test Account Shipping Charges - _TC",
"charge_type": "Actual", "charge_type": "Actual",
"cost_center": "_Test Cost Center - _TC", "cost_center": "_Test Cost Center - _TC",
"description": "Shipping Charges", "description": "Shipping Charges",
"doctype": "Sales Taxes and Charges", "doctype": "Sales Taxes and Charges",
"idx": 7, "idx": 7,
"parentfield": "other_charges", "parentfield": "other_charges",
"rate": 100 "rate": 100
}, },
{ {
"account_head": "_Test Account Discount - _TC", "account_head": "_Test Account Discount - _TC",
"charge_type": "On Previous Row Total", "charge_type": "On Previous Row Total",
"cost_center": "_Test Cost Center - _TC", "cost_center": "_Test Cost Center - _TC",
"description": "Discount", "description": "Discount",
"doctype": "Sales Taxes and Charges", "doctype": "Sales Taxes and Charges",
"idx": 8, "idx": 8,
"parentfield": "other_charges", "parentfield": "other_charges",
"rate": -10, "rate": -10,
"row_id": 7 "row_id": 7
} }
], ],
"plc_conversion_rate": 1.0, "plc_conversion_rate": 1.0,
"posting_date": "2013-01-23", "posting_date": "2013-01-23",
"price_list_currency": "INR", "price_list_currency": "INR",
"selling_price_list": "_Test Price List", "selling_price_list": "_Test Price List",
"territory": "_Test Territory" "territory": "_Test Territory"
} }
] ]

View File

@ -502,7 +502,8 @@ class TestSalesInvoice(unittest.TestCase):
"warehouse": "_Test Warehouse - _TC" "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): def test_si_gl_entry_with_aii_and_update_stock_with_warehouse_but_no_account(self):
self.clear_stock_account_balance() self.clear_stock_account_balance()
@ -664,142 +665,9 @@ class TestSalesInvoice(unittest.TestCase):
where against_invoice=%s""", si.name)) where against_invoice=%s""", si.name))
def test_recurring_invoice(self): def test_recurring_invoice(self):
from frappe.utils import get_first_day, get_last_day, add_to_date, nowdate, getdate from erpnext.controllers.tests.test_recurring_document import test_recurring_document
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)
})
# monthly test_recurring_document(self, test_records)
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)
def clear_stock_account_balance(self): def clear_stock_account_balance(self):
frappe.db.sql("delete from `tabStock Ledger Entry`") frappe.db.sql("delete from `tabStock Ledger Entry`")

View File

@ -1,13 +1,12 @@
{ {
"autoname": "INVD.######", "autoname": "INVD.######",
"creation": "2013-06-04 11:02:19.000000", "creation": "2013-06-04 11:02:19",
"docstatus": 0, "docstatus": 0,
"doctype": "DocType", "doctype": "DocType",
"fields": [ "fields": [
{ {
"fieldname": "barcode", "fieldname": "barcode",
"fieldtype": "Data", "fieldtype": "Data",
"in_list_view": 0,
"label": "Barcode", "label": "Barcode",
"permlevel": 0, "permlevel": 0,
"print_hide": 1, "print_hide": 1,
@ -32,7 +31,7 @@
"fieldname": "item_name", "fieldname": "item_name",
"fieldtype": "Data", "fieldtype": "Data",
"in_filter": 0, "in_filter": 0,
"in_list_view": 0, "in_list_view": 1,
"label": "Item Name", "label": "Item Name",
"oldfieldname": "item_name", "oldfieldname": "item_name",
"oldfieldtype": "Data", "oldfieldtype": "Data",
@ -51,7 +50,6 @@
"fieldname": "customer_item_code", "fieldname": "customer_item_code",
"fieldtype": "Data", "fieldtype": "Data",
"hidden": 1, "hidden": 1,
"in_list_view": 0,
"label": "Customer's Item Code", "label": "Customer's Item Code",
"permlevel": 0, "permlevel": 0,
"print_hide": 1, "print_hide": 1,
@ -73,7 +71,6 @@
{ {
"fieldname": "quantity_and_rate", "fieldname": "quantity_and_rate",
"fieldtype": "Section Break", "fieldtype": "Section Break",
"in_list_view": 0,
"label": "Quantity and Rate", "label": "Quantity and Rate",
"permlevel": 0 "permlevel": 0
}, },
@ -91,7 +88,6 @@
{ {
"fieldname": "price_list_rate", "fieldname": "price_list_rate",
"fieldtype": "Currency", "fieldtype": "Currency",
"in_list_view": 0,
"label": "Price List Rate", "label": "Price List Rate",
"oldfieldname": "ref_rate", "oldfieldname": "ref_rate",
"oldfieldtype": "Currency", "oldfieldtype": "Currency",
@ -103,8 +99,8 @@
}, },
{ {
"fieldname": "discount_percentage", "fieldname": "discount_percentage",
"fieldtype": "Float", "fieldtype": "Percent",
"in_list_view": 0, "in_list_view": 1,
"label": "Discount (%)", "label": "Discount (%)",
"oldfieldname": "adj_rate", "oldfieldname": "adj_rate",
"oldfieldtype": "Float", "oldfieldtype": "Float",
@ -120,7 +116,7 @@
{ {
"fieldname": "stock_uom", "fieldname": "stock_uom",
"fieldtype": "Link", "fieldtype": "Link",
"in_list_view": 0, "in_list_view": 1,
"label": "UOM", "label": "UOM",
"options": "UOM", "options": "UOM",
"permlevel": 0, "permlevel": 0,
@ -129,7 +125,6 @@
{ {
"fieldname": "base_price_list_rate", "fieldname": "base_price_list_rate",
"fieldtype": "Currency", "fieldtype": "Currency",
"in_list_view": 0,
"label": "Price List Rate (Company Currency)", "label": "Price List Rate (Company Currency)",
"oldfieldname": "base_ref_rate", "oldfieldname": "base_ref_rate",
"oldfieldtype": "Currency", "oldfieldtype": "Currency",
@ -176,7 +171,6 @@
"fieldname": "base_rate", "fieldname": "base_rate",
"fieldtype": "Currency", "fieldtype": "Currency",
"in_filter": 0, "in_filter": 0,
"in_list_view": 0,
"label": "Rate (Company Currency)", "label": "Rate (Company Currency)",
"oldfieldname": "basic_rate", "oldfieldname": "basic_rate",
"oldfieldtype": "Currency", "oldfieldtype": "Currency",
@ -190,7 +184,6 @@
{ {
"fieldname": "base_amount", "fieldname": "base_amount",
"fieldtype": "Currency", "fieldtype": "Currency",
"in_list_view": 0,
"label": "Amount (Company Currency)", "label": "Amount (Company Currency)",
"oldfieldname": "amount", "oldfieldname": "amount",
"oldfieldtype": "Currency", "oldfieldtype": "Currency",
@ -201,17 +194,9 @@
"reqd": 1 "reqd": 1
}, },
{ {
"fieldname": "pricing_rule_for_price", "fieldname": "pricing_rule",
"fieldtype": "Link", "fieldtype": "Link",
"label": "Pricing Rule For Price", "label": "Pricing Rule",
"options": "Pricing Rule",
"permlevel": 0,
"read_only": 1
},
{
"fieldname": "pricing_rule_for_discount",
"fieldtype": "Link",
"label": "Pricing Rule For Discount",
"options": "Pricing Rule", "options": "Pricing Rule",
"permlevel": 0, "permlevel": 0,
"read_only": 1 "read_only": 1
@ -219,7 +204,6 @@
{ {
"fieldname": "accounting", "fieldname": "accounting",
"fieldtype": "Section Break", "fieldtype": "Section Break",
"in_list_view": 0,
"label": "Accounting", "label": "Accounting",
"permlevel": 0 "permlevel": 0
}, },
@ -227,7 +211,6 @@
"fieldname": "income_account", "fieldname": "income_account",
"fieldtype": "Link", "fieldtype": "Link",
"in_filter": 1, "in_filter": 1,
"in_list_view": 0,
"label": "Income Account", "label": "Income Account",
"oldfieldname": "income_account", "oldfieldname": "income_account",
"oldfieldtype": "Link", "oldfieldtype": "Link",
@ -244,7 +227,6 @@
"fieldtype": "Link", "fieldtype": "Link",
"hidden": 0, "hidden": 0,
"in_filter": 1, "in_filter": 1,
"in_list_view": 0,
"label": "Expense Account", "label": "Expense Account",
"options": "Account", "options": "Account",
"permlevel": 0, "permlevel": 0,
@ -262,7 +244,6 @@
"fieldname": "cost_center", "fieldname": "cost_center",
"fieldtype": "Link", "fieldtype": "Link",
"in_filter": 1, "in_filter": 1,
"in_list_view": 0,
"label": "Cost Center", "label": "Cost Center",
"oldfieldname": "cost_center", "oldfieldname": "cost_center",
"oldfieldtype": "Link", "oldfieldtype": "Link",
@ -271,13 +252,12 @@
"print_hide": 1, "print_hide": 1,
"print_width": "120px", "print_width": "120px",
"read_only": 0, "read_only": 0,
"reqd": 0, "reqd": 1,
"width": "120px" "width": "120px"
}, },
{ {
"fieldname": "warehouse_and_reference", "fieldname": "warehouse_and_reference",
"fieldtype": "Section Break", "fieldtype": "Section Break",
"in_list_view": 0,
"label": "Warehouse and Reference", "label": "Warehouse and Reference",
"permlevel": 0 "permlevel": 0
}, },
@ -285,7 +265,7 @@
"fieldname": "warehouse", "fieldname": "warehouse",
"fieldtype": "Link", "fieldtype": "Link",
"hidden": 0, "hidden": 0,
"in_list_view": 0, "in_list_view": 1,
"label": "Warehouse", "label": "Warehouse",
"oldfieldname": "warehouse", "oldfieldname": "warehouse",
"oldfieldtype": "Link", "oldfieldtype": "Link",
@ -310,6 +290,7 @@
{ {
"fieldname": "batch_no", "fieldname": "batch_no",
"fieldtype": "Link", "fieldtype": "Link",
"in_list_view": 1,
"label": "Batch No", "label": "Batch No",
"options": "Batch", "options": "Batch",
"permlevel": 0, "permlevel": 0,
@ -359,6 +340,7 @@
"permlevel": 0 "permlevel": 0
}, },
{ {
"allow_on_submit": 1,
"fieldname": "actual_qty", "fieldname": "actual_qty",
"fieldtype": "Float", "fieldtype": "Float",
"label": "Available Qty at Warehouse", "label": "Available Qty at Warehouse",
@ -380,6 +362,7 @@
"fieldname": "sales_order", "fieldname": "sales_order",
"fieldtype": "Link", "fieldtype": "Link",
"in_filter": 1, "in_filter": 1,
"in_list_view": 1,
"label": "Sales Order", "label": "Sales Order",
"no_copy": 1, "no_copy": 1,
"oldfieldname": "sales_order", "oldfieldname": "sales_order",
@ -456,9 +439,12 @@
], ],
"idx": 1, "idx": 1,
"istable": 1, "istable": 1,
"modified": "2014-02-28 11:04:19.000000", "modified": "2014-09-08 08:06:30.382092",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Accounts", "module": "Accounts",
"name": "Sales Invoice Item", "name": "Sales Invoice Item",
"owner": "Administrator" "owner": "Administrator",
"permissions": [],
"sort_field": "modified",
"sort_order": "DESC"
} }

View File

@ -1,431 +1,155 @@
{ {
"_last_update": null, "autoname": "INVTD.######",
"_user_tags": null, "creation": "2013-04-24 11:39:32",
"allow_attach": null, "docstatus": 0,
"allow_copy": null, "doctype": "DocType",
"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,
"fields": [ "fields": [
{ {
"allow_on_submit": null, "fieldname": "charge_type",
"default": null, "fieldtype": "Select",
"depends_on": null, "in_list_view": 1,
"description": null, "label": "Type",
"fieldname": "charge_type", "oldfieldname": "charge_type",
"fieldtype": "Select", "oldfieldtype": "Select",
"hidden": null, "options": "\nActual\nOn Net Total\nOn Previous Row Amount\nOn Previous Row Total",
"ignore_restrictions": null, "permlevel": 0,
"in_filter": null, "reqd": 1
"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
},
{ {
"allow_on_submit": null, "depends_on": "eval:[\"On Previous Row Amount\", \"On Previous Row Total\"].indexOf(doc.charge_type)!==-1",
"default": null, "fieldname": "row_id",
"depends_on": "eval:[\"On Previous Row Amount\", \"On Previous Row Total\"].indexOf(doc.charge_type)!==-1", "fieldtype": "Data",
"description": null, "hidden": 0,
"fieldname": "row_id", "label": "Reference Row #",
"fieldtype": "Data", "oldfieldname": "row_id",
"hidden": 0, "oldfieldtype": "Data",
"ignore_restrictions": null, "permlevel": 0
"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
},
{ {
"allow_on_submit": null, "fieldname": "description",
"default": null, "fieldtype": "Small Text",
"depends_on": null, "in_list_view": 1,
"description": null, "label": "Description",
"fieldname": "description", "oldfieldname": "description",
"fieldtype": "Small Text", "oldfieldtype": "Small Text",
"hidden": null, "permlevel": 0,
"ignore_restrictions": null, "print_width": "300px",
"in_filter": null, "reqd": 1,
"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,
"width": "300px" "width": "300px"
}, },
{ {
"allow_on_submit": null, "fieldname": "col_break_1",
"default": null, "fieldtype": "Column Break",
"depends_on": null, "permlevel": 0,
"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,
"width": "50%" "width": "50%"
}, },
{ {
"allow_on_submit": null, "fieldname": "account_head",
"default": null, "fieldtype": "Link",
"depends_on": null, "in_list_view": 0,
"description": null, "label": "Account Head",
"fieldname": "account_head", "oldfieldname": "account_head",
"fieldtype": "Link", "oldfieldtype": "Link",
"hidden": null, "options": "Account",
"ignore_restrictions": null, "permlevel": 0,
"in_filter": null, "reqd": 1,
"in_list_view": 0, "search_index": 1
"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
},
{ {
"allow_on_submit": null, "default": ":Company",
"default": ":Company", "fieldname": "cost_center",
"depends_on": null, "fieldtype": "Link",
"description": null, "in_list_view": 0,
"fieldname": "cost_center", "label": "Cost Center",
"fieldtype": "Link", "oldfieldname": "cost_center_other_charges",
"hidden": null, "oldfieldtype": "Link",
"ignore_restrictions": null, "options": "Cost Center",
"in_filter": null, "permlevel": 0
"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
},
{ {
"allow_on_submit": null, "fieldname": "rate",
"default": null, "fieldtype": "Float",
"depends_on": null, "in_list_view": 1,
"description": null, "label": "Rate",
"fieldname": "rate", "oldfieldname": "rate",
"fieldtype": "Float", "oldfieldtype": "Currency",
"hidden": null, "permlevel": 0,
"ignore_restrictions": null, "reqd": 1
"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
},
{ {
"allow_on_submit": null, "fieldname": "tax_amount",
"default": null, "fieldtype": "Currency",
"depends_on": null, "in_list_view": 1,
"description": null, "label": "Amount",
"fieldname": "tax_amount", "oldfieldname": "tax_amount",
"fieldtype": "Currency", "oldfieldtype": "Currency",
"hidden": null, "options": "Company:company:default_currency",
"ignore_restrictions": null, "permlevel": 0,
"in_filter": null, "read_only": 1,
"in_list_view": 1, "reqd": 0
"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
},
{ {
"allow_on_submit": null, "fieldname": "total",
"default": null, "fieldtype": "Currency",
"depends_on": null, "label": "Total",
"description": null, "oldfieldname": "total",
"fieldname": "total", "oldfieldtype": "Currency",
"fieldtype": "Currency", "options": "Company:company:default_currency",
"hidden": null, "permlevel": 0,
"ignore_restrictions": null, "read_only": 1
"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
},
{ {
"allow_on_submit": 0, "allow_on_submit": 0,
"default": null, "description": "If checked, the tax amount will be considered as already included in the Print Rate / Print Amount",
"depends_on": null, "fieldname": "included_in_print_rate",
"description": "If checked, the tax amount will be considered as already included in the Print Rate / Print Amount", "fieldtype": "Check",
"fieldname": "included_in_print_rate", "label": "Is this Tax included in Basic Rate?",
"fieldtype": "Check", "no_copy": 0,
"hidden": null, "permlevel": 0,
"ignore_restrictions": null, "print_hide": 1,
"in_filter": null, "print_width": "150px",
"in_list_view": null, "report_hide": 1,
"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,
"width": "150px" "width": "150px"
}, },
{ {
"allow_on_submit": null, "fieldname": "tax_amount_after_discount_amount",
"default": null, "fieldtype": "Currency",
"depends_on": null, "hidden": 1,
"description": null, "label": "Tax Amount After Discount Amount",
"fieldname": "tax_amount_after_discount_amount", "options": "Company:company:default_currency",
"fieldtype": "Currency", "permlevel": 0,
"hidden": 1, "read_only": 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
},
{ {
"allow_on_submit": null, "fieldname": "item_wise_tax_detail",
"default": null, "fieldtype": "Small Text",
"depends_on": null, "hidden": 1,
"description": null, "label": "Item Wise Tax Detail",
"fieldname": "item_wise_tax_detail", "oldfieldname": "item_wise_tax_detail",
"fieldtype": "Small Text", "oldfieldtype": "Small Text",
"hidden": 1, "permlevel": 0,
"ignore_restrictions": null, "read_only": 1
"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
},
{ {
"allow_on_submit": null, "fieldname": "parenttype",
"default": null, "fieldtype": "Data",
"depends_on": null, "hidden": 1,
"description": null, "in_filter": 1,
"fieldname": "parenttype", "label": "Parenttype",
"fieldtype": "Data", "oldfieldname": "parenttype",
"hidden": 1, "oldfieldtype": "Data",
"ignore_restrictions": null, "permlevel": 0,
"in_filter": 1, "print_hide": 1,
"in_list_view": null, "search_index": 1
"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
} }
], ],
"hide_heading": 1, "hide_heading": 1,
"hide_toolbar": null, "idx": 1,
"icon": null, "istable": 1,
"idx": 1, "modified": "2014-05-30 03:43:39.740638",
"in_create": null, "modified_by": "Administrator",
"in_dialog": null, "module": "Accounts",
"is_submittable": null, "name": "Sales Taxes and Charges",
"is_transaction_doc": null, "owner": "Administrator",
"issingle": null, "permissions": []
"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
}

View File

@ -2,7 +2,7 @@
"allow_import": 1, "allow_import": 1,
"allow_rename": 1, "allow_rename": 1,
"autoname": "field:title", "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.", "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, "docstatus": 0,
"doctype": "DocType", "doctype": "DocType",
@ -12,6 +12,7 @@
"fieldname": "title", "fieldname": "title",
"fieldtype": "Data", "fieldtype": "Data",
"in_filter": 1, "in_filter": 1,
"in_list_view": 1,
"label": "Title", "label": "Title",
"oldfieldname": "title", "oldfieldname": "title",
"oldfieldtype": "Data", "oldfieldtype": "Data",
@ -22,6 +23,7 @@
{ {
"fieldname": "is_default", "fieldname": "is_default",
"fieldtype": "Check", "fieldtype": "Check",
"in_list_view": 1,
"label": "Default", "label": "Default",
"permlevel": 0 "permlevel": 0
}, },
@ -34,6 +36,7 @@
"fieldname": "company", "fieldname": "company",
"fieldtype": "Link", "fieldtype": "Link",
"in_filter": 1, "in_filter": 1,
"in_list_view": 1,
"label": "Company", "label": "Company",
"oldfieldname": "company", "oldfieldname": "company",
"oldfieldtype": "Link", "oldfieldtype": "Link",
@ -69,7 +72,7 @@
], ],
"icon": "icon-money", "icon": "icon-money",
"idx": 1, "idx": 1,
"modified": "2014-01-28 12:28:27.000000", "modified": "2014-05-27 03:49:19.023941",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Accounts", "module": "Accounts",
"name": "Sales Taxes and Charges Master", "name": "Sales Taxes and Charges Master",
@ -77,7 +80,7 @@
"permissions": [ "permissions": [
{ {
"amend": 0, "amend": 0,
"cancel": 0, "apply_user_permissions": 1,
"create": 0, "create": 0,
"delete": 0, "delete": 0,
"email": 1, "email": 1,
@ -91,7 +94,6 @@
}, },
{ {
"amend": 0, "amend": 0,
"cancel": 0,
"create": 1, "create": 1,
"delete": 1, "delete": 1,
"email": 1, "email": 1,
@ -105,7 +107,6 @@
}, },
{ {
"amend": 0, "amend": 0,
"cancel": 0,
"create": 1, "create": 1,
"delete": 1, "delete": 1,
"email": 1, "email": 1,

View File

@ -1,6 +1,6 @@
{ {
"autoname": "Prompt", "autoname": "Prompt",
"creation": "2013-06-25 11:48:03.000000", "creation": "2013-06-25 11:48:03",
"description": "Specify conditions to calculate shipping amount", "description": "Specify conditions to calculate shipping amount",
"docstatus": 0, "docstatus": 0,
"doctype": "DocType", "doctype": "DocType",
@ -102,13 +102,14 @@
], ],
"icon": "icon-truck", "icon": "icon-truck",
"idx": 1, "idx": 1,
"modified": "2014-01-20 17:49:27.000000", "modified": "2014-05-27 03:49:19.387875",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Accounts", "module": "Accounts",
"name": "Shipping Rule", "name": "Shipping Rule",
"owner": "Administrator", "owner": "Administrator",
"permissions": [ "permissions": [
{ {
"apply_user_permissions": 1,
"delete": 0, "delete": 0,
"email": 1, "email": 1,
"permlevel": 0, "permlevel": 0,
@ -118,6 +119,7 @@
"role": "Accounts User" "role": "Accounts User"
}, },
{ {
"apply_user_permissions": 1,
"delete": 0, "delete": 0,
"email": 1, "email": 1,
"permlevel": 0, "permlevel": 0,
@ -127,7 +129,6 @@
"role": "Sales User" "role": "Sales User"
}, },
{ {
"cancel": 1,
"create": 1, "create": 1,
"delete": 1, "delete": 1,
"email": 1, "email": 1,
@ -139,7 +140,6 @@
"write": 1 "write": 1
}, },
{ {
"cancel": 1,
"create": 1, "create": 1,
"delete": 1, "delete": 1,
"email": 1, "email": 1,

View File

@ -15,7 +15,10 @@ def make_gl_entries(gl_map, cancel=False, adv_adj=False, merge_entries=True,
if gl_map: if gl_map:
if not cancel: if not cancel:
gl_map = process_gl_map(gl_map, merge_entries) 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: else:
delete_gl_entries(gl_map, adv_adj=adv_adj, update_outstanding=update_outstanding) delete_gl_entries(gl_map, adv_adj=adv_adj, update_outstanding=update_outstanding)

View File

@ -25,16 +25,16 @@ pscript['onload_Accounts Browser'] = function(wrapper){
'<li>'+__('To add child nodes, explore tree and click on the node under which you want to add more nodes.')+'</li>'+ '<li>'+__('To add child nodes, explore tree and click on the node under which you want to add more nodes.')+'</li>'+
'<li>'+ '<li>'+
__('Accounting Entries can be made against leaf nodes, called')+ __('Accounting Entries can be made against leaf nodes, called')+
'<b>' +__('Ledgers')+'</b>.'+ __('Entries against') + ' <b>' +__('Ledgers')+'</b>. '+ __('Entries against ') +
'<b>' +__('Groups') + '</b>'+ __('are not allowed.')+ '<b>' +__('Groups') + '</b> '+ __('are not allowed.')+
'</li>'+ '</li>'+
'<li>'+__('Please do NOT create Account (Ledgers) for Customers and Suppliers. They are created directly from the Customer / Supplier masters.')+'</li>'+ '<li>'+__('Please do NOT create Account (Ledgers) for Customers and Suppliers. They are created directly from the Customer / Supplier masters.')+'</li>'+
'<li>'+ '<li>'+
'<b>'+__('To create a Bank Account:')+'</b>'+ '<b>'+__('To create a Bank Account')+'</b>: '+
__('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"')+ __('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"')+
'</li>'+ '</li>'+
'<li>'+ '<li>'+
'<b>'+__('To create a Tax Account:')+'</b>'+ '<b>'+__('To create a Tax Account') +'</b>: '+
__('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.')+ __('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.')+
'</li>'+ '</li>'+
'</ol>'+ '</ol>'+
@ -66,7 +66,7 @@ pscript['onload_Accounts Browser'] = function(wrapper){
$.each(r.message, function(i, v) { $.each(r.message, function(i, v) {
$('<option>').html(v).attr('value', v).appendTo(wrapper.$company_select); $('<option>').html(v).attr('value', v).appendTo(wrapper.$company_select);
}); });
wrapper.$company_select.val(frappe.defaults.get_user_default("company") || r[0]).change(); wrapper.$company_select.val(frappe.defaults.get_user_default("company") || r.message[0]).change();
} }
}); });
} }
@ -238,6 +238,9 @@ erpnext.AccountsChart = Class.extend({
method: 'erpnext.accounts.utils.add_ac', method: 'erpnext.accounts.utils.add_ac',
callback: function(r) { callback: function(r) {
d.hide(); d.hide();
if(node.expanded) {
node.toggle_node();
}
node.reload(); node.reload();
} }
}); });
@ -281,6 +284,9 @@ erpnext.AccountsChart = Class.extend({
method: 'erpnext.accounts.utils.add_cc', method: 'erpnext.accounts.utils.add_cc',
callback: function(r) { callback: function(r) {
d.hide(); d.hide();
if(node.expanded) {
node.toggle_node();
}
node.reload(); node.reload();
} }
}); });

View File

@ -17,8 +17,9 @@ frappe.pages['financial-analytics'].onload = function(wrapper) {
erpnext.FinancialAnalytics = erpnext.AccountTreeGrid.extend({ erpnext.FinancialAnalytics = erpnext.AccountTreeGrid.extend({
filters: [ filters: [
{ {
fieldtype:"Select", label: __("PL or BS"), fieldtype:"Select", label: __("PL or BS"), fieldname: "pl_or_bs",
options:["Profit and Loss", "Balance Sheet"], options:[{"label": __("Profit and Loss"), "value": "Profit and Loss"},
{"label": __("Balance Sheet"), "value": "Balance Sheet"}],
filter: function(val, item, opts, me) { filter: function(val, item, opts, me) {
if(item._show) return true; if(item._show) return true;
@ -31,21 +32,23 @@ erpnext.FinancialAnalytics = erpnext.AccountTreeGrid.extend({
} }
}, },
{ {
fieldtype:"Select", label: __("Company"), fieldtype:"Select", label: __("Company"), fieldname: "company",
link:"Company", default_value: "Select Company...", link:"Company", default_value: __("Select Company..."),
filter: function(val, item, opts) { filter: function(val, item, opts) {
return item.company == val || val == opts.default_value || item._show; return item.company == val || val == opts.default_value || item._show;
} }
}, },
{fieldtype:"Select", label: __("Fiscal Year"), link:"Fiscal Year", {fieldtype:"Select", label: __("Fiscal Year"), link:"Fiscal Year", fieldname: "fiscal_year",
default_value: "Select Fiscal Year..."}, default_value: __("Select Fiscal Year...")},
{fieldtype:"Date", label: __("From Date")}, {fieldtype:"Date", label: __("From Date"), fieldname: "from_date"},
{fieldtype:"Label", label: __("To")}, {fieldtype:"Label", label: __("To")},
{fieldtype:"Date", label: __("To Date")}, {fieldtype:"Date", label: __("To Date"), fieldname: "to_date"},
{fieldtype:"Select", label: __("Range"), {fieldtype:"Select", label: __("Range"), fieldname: "range",
options:["Daily", "Weekly", "Monthly", "Quarterly", "Yearly"]}, options:[{label: __("Daily"), value: "Daily"}, {label: __("Weekly"), value: "Weekly"},
{label: __("Monthly"), value: "Monthly"}, {label: __("Quarterly"), value: "Quarterly"},
{label: __("Yearly"), value: "Yearly"}]},
{fieldtype:"Button", label: __("Refresh"), icon:"icon-refresh icon-white"}, {fieldtype:"Button", label: __("Refresh"), icon:"icon-refresh icon-white"},
{fieldtype:"Button", label: __("Reset Filters")} {fieldtype:"Button", label: __("Reset Filters"), icon: "icon-filter"}
], ],
setup_columns: function() { setup_columns: function() {
var std_columns = [ var std_columns = [
@ -203,11 +206,11 @@ erpnext.FinancialAnalytics = erpnext.AccountTreeGrid.extend({
if(me.pl_or_bs=='Balance Sheet') { if(me.pl_or_bs=='Balance Sheet') {
$.each(me.data, function(i, ac) { $.each(me.data, function(i, ac) {
if((ac.rgt - ac.lft)==1 && ac.report_type=='Balance Sheet') { if((ac.rgt - ac.lft)==1 && ac.report_type=='Balance Sheet') {
var opening = 0; var opening = flt(ac["opening_dr"]) - flt(ac["opening_cr"]);
//if(opening) throw opening; //if(opening) throw opening;
$.each(me.columns, function(i, col) { $.each(me.columns, function(i, col) {
if(col.formatter==me.currency_formatter) { if(col.formatter==me.currency_formatter) {
if(col.balance_type=="Dr") { if(col.balance_type=="Dr" && !in_list(["opening_dr", "opening_cr"], col.field)) {
opening = opening + flt(ac[col.date + "_dr"]) - opening = opening + flt(ac[col.date + "_dr"]) -
flt(ac[col.date + "_cr"]); flt(ac[col.date + "_cr"]);
me.set_debit_or_credit(ac, col.date, opening); me.set_debit_or_credit(ac, col.date, opening);
@ -229,7 +232,7 @@ erpnext.FinancialAnalytics = erpnext.AccountTreeGrid.extend({
indent: 0, indent: 0,
opening: 0, opening: 0,
checked: false, checked: false,
report_type: me.pl_or_bs, report_type: me.pl_or_bs=="Balance Sheet"? "Balance Sheet" : "Profit and Loss",
}; };
me.item_by_name[net_profit.name] = net_profit; me.item_by_name[net_profit.name] = net_profit;
@ -241,7 +244,7 @@ erpnext.FinancialAnalytics = erpnext.AccountTreeGrid.extend({
$.each(me.data, function(i, ac) { $.each(me.data, function(i, ac) {
if(!ac.parent_account && me.apply_filter(ac, "company") && if(!ac.parent_account && me.apply_filter(ac, "company") &&
ac.report_type==me.pl_or_bs) { ac.report_type==net_profit.report_type) {
$.each(me.columns, function(i, col) { $.each(me.columns, function(i, col) {
if(col.formatter==me.currency_formatter && col.balance_type=="Dr") { if(col.formatter==me.currency_formatter && col.balance_type=="Dr") {
var bal = net_profit[col.date+"_dr"] - var bal = net_profit[col.date+"_dr"] -
@ -253,9 +256,6 @@ erpnext.FinancialAnalytics = erpnext.AccountTreeGrid.extend({
} }
}); });
this.data.push(net_profit); this.data.push(net_profit);
// $.each(me.data, function(i, v) {
// if(v.report_type=="Profit and Loss") console.log(v)
// })
} }
}, },
add_balance: function(field, account, gl) { add_balance: function(field, account, gl) {

View File

View File

@ -0,0 +1,52 @@
frappe.pages['pos'].onload = function(wrapper) {
frappe.ui.make_app_page({
parent: wrapper,
title: 'Start POS',
single_column: true
});
wrapper.body.html('<div class="text-center" style="margin: 40px">\
<p>' + __("Select type of transaction") + '</p>\
<p class="select-type" style="margin: auto; max-width: 300px; margin-bottom: 15px;"></p>\
<p class="alert alert-warning pos-setting-message hide">'
+ __("Please setup your POS Preferences")
+ ': <a class="btn btn-default" onclick="newdoc(\'POS Setting\')">'
+ __("Make new POS Setting") + '</a></p>\
<p><button class="btn btn-primary">' + __("Start") + '</button></p>\
</div>');
var pos_type = frappe.ui.form.make_control({
parent: wrapper.body.find(".select-type"),
df: {
fieldtype: "Select",
options: [
{label: __("Billing (Sales Invoice)"), value:"Sales Invoice"},
{value:"Sales Order"},
{value:"Delivery Note"},
{value:"Quotation"},
{value:"Purchase Order"},
{value:"Purchase Receipt"},
{value:"Purchase Invoice"},
],
fieldname: "pos_type"
},
only_input: true
});
pos_type.refresh();
wrapper.body.find(".btn-primary").on("click", function() {
erpnext.open_as_pos = true;
new_doc(pos_type.get_value());
});
$.ajax({
url: "/api/resource/POS Setting",
success: function(data) {
if(!data.data.length) {
wrapper.body.find(".pos-setting-message").removeClass('hide');
}
}
})
}

View File

@ -0,0 +1,28 @@
{
"content": null,
"creation": "2014-08-08 02:45:55.931022",
"docstatus": 0,
"doctype": "Page",
"icon": "icon-th",
"modified": "2014-08-08 05:59:33.045012",
"modified_by": "Administrator",
"module": "Accounts",
"name": "pos",
"owner": "Administrator",
"page_name": "pos",
"roles": [
{
"role": "Sales User"
},
{
"role": "Purchase User"
},
{
"role": "Accounts User"
}
],
"script": null,
"standard": "Yes",
"style": null,
"title": "POS"
}

View File

@ -1 +0,0 @@
Period wise opening and closing balance of all transactions.

View File

@ -1 +0,0 @@
from __future__ import unicode_literals

View File

@ -1,51 +0,0 @@
// Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
// License: GNU General Public License v3. See license.txt
frappe.require("assets/erpnext/js/account_tree_grid.js");
frappe.pages['trial-balance'].onload = function(wrapper) {
frappe.ui.make_app_page({
parent: wrapper,
title: __('Trial Balance'),
single_column: true
});
var TrialBalance = erpnext.AccountTreeGrid.extend({
init: function(wrapper, title) {
var me = this;
this._super(wrapper, title);
// period closing entry checkbox
this.wrapper.bind("make", function() {
$('<div style="margin: 10px 0px; "\
class="with_period_closing_entry"><input type="checkbox" checked="checked">' +
__("With period closing entry") + '</div>')
.appendTo(me.wrapper)
.find("input").click(function() { me.refresh(); });
});
},
prepare_balances: function() {
// store value of with closing entry
this.with_period_closing_entry = this.wrapper
.find(".with_period_closing_entry input:checked").length;
this._super();
},
update_balances: function(account, posting_date, v) {
// for period closing voucher,
// only consider them when adding "With Closing Entry is checked"
if(v.voucher_type === "Period Closing Voucher") {
if(this.with_period_closing_entry) {
this._super(account, posting_date, v);
}
} else {
this._super(account, posting_date, v);
}
},
})
erpnext.trial_balance = new TrialBalance(wrapper, 'Trial Balance');
wrapper.appframe.add_module_icon("Accounts")
}

View File

@ -1,23 +0,0 @@
{
"creation": "2013-01-27 16:30:52.000000",
"docstatus": 0,
"doctype": "Page",
"icon": "icon-table",
"idx": 1,
"modified": "2013-07-11 14:44:49.000000",
"modified_by": "Administrator",
"module": "Accounts",
"name": "trial-balance",
"owner": "Administrator",
"page_name": "trial-balance",
"roles": [
{
"role": "Analytics"
},
{
"role": "Accounts Manager"
}
],
"standard": "Yes",
"title": "Trial Balance"
}

View File

@ -5,20 +5,21 @@ from __future__ import unicode_literals
import frappe import frappe
from frappe import _ from frappe import _
from frappe.defaults import get_restrictions from frappe.defaults import get_user_permissions
from frappe.utils import add_days from frappe.utils import add_days
from erpnext.utilities.doctype.address.address import get_address_display from erpnext.utilities.doctype.address.address import get_address_display
from erpnext.utilities.doctype.contact.contact import get_contact_details from erpnext.utilities.doctype.contact.contact import get_contact_details
@frappe.whitelist() @frappe.whitelist()
def get_party_details(party=None, account=None, party_type="Customer", company=None, def get_party_details(party=None, account=None, party_type="Customer", company=None,
posting_date=None, price_list=None, currency=None): posting_date=None, price_list=None, currency=None, doctype=None):
return _get_party_details(party, account, party_type, company, posting_date, price_list, currency) return _get_party_details(party, account, party_type,
company, posting_date, price_list, currency, doctype)
def _get_party_details(party=None, account=None, party_type="Customer", company=None, def _get_party_details(party=None, account=None, party_type="Customer", company=None,
posting_date=None, price_list=None, currency=None, ignore_permissions=False): posting_date=None, price_list=None, currency=None, doctype=None, ignore_permissions=False):
out = frappe._dict(set_account_and_due_date(party, account, party_type, company, posting_date)) out = frappe._dict(set_account_and_due_date(party, account, party_type, company, posting_date, doctype))
party = out[party_type.lower()] party = out[party_type.lower()]
@ -86,9 +87,9 @@ def set_other_values(out, party, party_type):
def set_price_list(out, party, party_type, given_price_list): def set_price_list(out, party, party_type, given_price_list):
# price list # price list
price_list = get_restrictions().get("Price List") price_list = filter(None, get_user_permissions().get("Price List", []))
if isinstance(price_list, list): if isinstance(price_list, list):
price_list = None price_list = price_list[0] if len(price_list)==1 else None
if not price_list: if not price_list:
price_list = party.default_price_list price_list = party.default_price_list
@ -106,8 +107,8 @@ def set_price_list(out, party, party_type, given_price_list):
out["selling_price_list" if party.doctype=="Customer" else "buying_price_list"] = price_list out["selling_price_list" if party.doctype=="Customer" else "buying_price_list"] = price_list
def set_account_and_due_date(party, account, party_type, company, posting_date): def set_account_and_due_date(party, account, party_type, company, posting_date, doctype):
if not posting_date: if doctype not in ["Sales Invoice", "Purchase Invoice"]:
# not an invoice # not an invoice
return { return {
party_type.lower(): party party_type.lower(): party

View File

@ -3,12 +3,13 @@
"doc_type": "Journal Voucher", "doc_type": "Journal Voucher",
"docstatus": 0, "docstatus": 0,
"doctype": "Print Format", "doctype": "Print Format",
"html": "<!-- p.big {line-height: 200%} .noborder td { border: 0px solid #fff; } -->\n<div style=\"position: relative;\">\n<h3><script>doc.company</script><br /> <br /> \n<hr />\nPAYMENT ADVICE</h3>\n<table class=\"noborder\" style=\"width: 100%;\">\n<tbody>\n<tr>\n<td style=\"vertical-align: top;\" width=\"50%\">To :<br />\n<script type=\"text/javascript\">// <![CDATA[\ndoc.pay_to_recd_from\n// ]]></script>\n</td>\n<td width=\"50%\">\n<table class=\"noborder\" width=\"100%\">\n<tbody>\n<tr>\n<td width=\"30%\">Voucher No :</td>\n<td width=\"70%\">\n<script type=\"text/javascript\">// <![CDATA[\ndoc.name\n// ]]></script>\n</td>\n</tr>\n<tr>\n<td width=\"30%\">Voucher Date :</td>\n<td width=\"70%\">\n<script type=\"text/javascript\">// <![CDATA[\ndate.str_to_user(doc.voucher_date)\n// ]]></script>\n</td>\n</tr>\n<tr>\n<td width=\"30%\">Cheque No :</td>\n<td width=\"70%\">\n<script type=\"text/javascript\">// <![CDATA[\ndate.str_to_user(doc.cheque_no)\n// ]]></script>\n</td>\n</tr>\n<tr>\n<td width=\"30%\">Cheque Date :</td>\n<td width=\"70%\">\n<script type=\"text/javascript\">// <![CDATA[\ndate.str_to_user(doc.cheque_date)\n// ]]></script>\n</td>\n</tr>\n</tbody>\n</table>\n</td>\n</tr>\n</tbody>\n</table>\n<br /> <strong>We are pleased to enclose our cheque in full/part Settlement of your under noted bills</strong> <br /> \n<hr />\n<table class=\"noborder\" width=\"100%\">\n<tbody>\n<tr>\n<td width=\"70%\">&nbsp;</td>\n<td width=\"15%\">Total :</td>\n<td class=\"pos_left\" width=\"15%\">\n<script type=\"text/javascript\">// <![CDATA[\ndoc.total_amount\n// ]]></script>\n</td>\n</tr>\n<tr>\n<td colspan=\"3\">Narration :\n<script type=\"text/javascript\">// <![CDATA[\nreplace_newlines(doc.remark)\n// ]]></script>\n<br /><br /><br /></td>\n</tr>\n</tbody>\n</table>\n<div style=\"position: absolute; top: 14cm; left: 0cm;\">Prepared By</div>\n<div style=\"position: absolute; top: 14cm; left: 5.5cm;\">Authorised Signatory</div>\n<div style=\"position: absolute; top: 14cm; left: 11cm;\">Received Payment as Above</div>\n<div style=\"position: absolute; top: 16.4cm; left: 5.9cm;\"><strong>_____________</strong></div>\n<div style=\"position: absolute; top: 16.7cm; left: 6cm;\"><strong>A/c Payee</strong></div>\n<div style=\"position: absolute; top: 16.7cm; left: 5.9cm;\"><strong>_____________</strong></div>\n<div style=\"position: absolute; top: 16.9cm; left: 12cm;\">\n<script type=\"text/javascript\">// <![CDATA[\ndate.str_to_user(doc.cheque_date)\n// ]]></script>\n</div>\n<div style=\"position: absolute; top: 17.9cm; left: 1cm;\">\n<script type=\"text/javascript\">// <![CDATA[\ndoc.pay_to_recd_from\n// ]]></script>\n</div>\n<div style=\"position: absolute; top: 18.6cm; left: 1cm; width: 7cm;\">\n<script type=\"text/javascript\">// <![CDATA[\ndoc.total_amount_in_words\n// ]]></script>\n</div>\n<div style=\"position: absolute; top: 19.7cm; left: 12cm;\">\n<script type=\"text/javascript\">// <![CDATA[\ndoc.total_amount\n// ]]></script>\n</div>\n</div>", "html": "<div style=\"position: relative\">\n\n\t{%- from \"templates/print_formats/standard_macros.html\" import add_header -%}\n<div class=\"page-break\">\n {%- if not doc.get(\"print_heading\") and not doc.get(\"select_print_heading\") \n and doc.set(\"select_print_heading\", _(\"Payment Advice\")) -%}{%- endif -%}\n {{ add_header(0, 1, doc, letter_head, no_letterhead) }}\n\n{%- for label, value in (\n (_(\"Voucher Date\"), frappe.utils.formatdate(doc.voucher_date)),\n (_(\"Reference / Cheque No.\"), doc.cheque_no),\n (_(\"Reference / Cheque Date\"), frappe.utils.formatdate(doc.cheque_date))\n ) -%}\n <div class=\"row\">\n <div class=\"col-sm-4\"><label class=\"text-right\">{{ label }}</label></div>\n <div class=\"col-sm-8\">{{ value }}</div>\n </div>\n{%- endfor -%}\n\t<hr>\n\t<p>{{ _(\"This amount is in full / part settlement of the listed bills\") }}:</p>\n{%- for label, value in (\n (_(\"Amount\"), \"<strong>\" + (doc.total_amount or \"\") + \"</strong><br>\" + (doc.total_amount_in_words or \"\") + \"<br>\"),\n (_(\"References\"), doc.remark)\n ) -%}\n <div class=\"row\">\n <div class=\"col-sm-4\"><label class=\"text-right\">{{ label }}</label></div>\n <div class=\"col-sm-8\">{{ value }}</div>\n </div>\n {%- endfor -%}\n <hr>\n\t<div style=\"position: absolute; top: 14cm; left: 0cm;\">\n\t\tPrepared By</div>\n\t<div style=\"position: absolute; top: 14cm; left: 5.5cm;\">\n\t\tAuthorised Signatory</div>\n\t<div style=\"position: absolute; top: 14cm; left: 11cm;\">\n\t\tReceived Payment as Above</div>\n\t<div style=\"position: absolute; top: 16.4cm; left: 5.9cm;\">\n\t\t<strong>_____________</strong></div>\n\t<div style=\"position: absolute; top: 16.7cm; left: 6cm;\">\n\t\t<strong>A/C Payee</strong></div>\n\t<div style=\"position: absolute; top: 16.7cm; left: 5.9cm;\">\n\t\t<strong>_____________</strong></div>\n\t<div style=\"position: absolute; top: 16.9cm; left: 12cm;\">\n\t\t{{ frappe.utils.formatdate(doc.cheque_date) }}</div>\n\t<div style=\"position: absolute; top: 17.9cm; left: 1cm;\">\n\t\t{{ doc.pay_to_recd_from }}</div>\n\t<div style=\"position: absolute; top: 18.6cm; left: 1cm; width: 7cm;\">\n\t\t{{ doc.total_amount_in_words }}</div>\n\t<div style=\"position: absolute; top: 19.7cm; left: 12cm;\">\n\t\t{{ doc.total_amount }}</div>\n</div>",
"idx": 1, "idx": 1,
"modified": "2014-05-13 16:07:18.792349", "modified": "2014-09-09 03:27:13.708596",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Accounts", "module": "Accounts",
"name": "Cheque Printing Format", "name": "Cheque Printing Format",
"owner": "Administrator", "owner": "Administrator",
"print_format_type": "Server",
"standard": "Yes" "standard": "Yes"
} }

View File

@ -0,0 +1,19 @@
{
"creation": "2014-08-28 11:11:39.796473",
"disabled": 0,
"doc_type": "Journal Voucher",
"docstatus": 0,
"doctype": "Print Format",
"html": "{%- from \"templates/print_formats/standard_macros.html\" import add_header -%}\n\n<div class=\"page-break\">\n {%- if not doc.get(\"print_heading\") and not doc.get(\"select_print_heading\") \n and doc.set(\"select_print_heading\", _(\"Credit Note\")) -%}{%- endif -%}\n {{ add_header(0, 1, doc, letter_head, no_letterhead) }}\n\n {%- for label, value in (\n (_(\"Credit To\"), doc.pay_to_recd_from),\n (_(\"Date\"), frappe.utils.formatdate(doc.voucher_date)),\n (_(\"Amount\"), \"<strong>\" + doc.total_amount + \"</strong><br>\" + (doc.total_amount_in_words or \"\") + \"<br>\"),\n (_(\"Remarks\"), doc.remark)\n ) -%}\n\n <div class=\"row\">\n <div class=\"col-sm-3\"><label class=\"text-right\">{{ label }}</label></div>\n <div class=\"col-sm-9\">{{ value }}</div>\n </div>\n\n {%- endfor -%}\n\n <hr>\n <br>\n <p class=\"strong\">\n {{ _(\"For\") }} {{ doc.company }},<br>\n <br>\n <br>\n <br>\n {{ _(\"Authorized Signatory\") }}\n </p>\n</div>\n\n\n",
"idx": 2,
"modified": "2014-08-29 13:20:15.789533",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Credit Note",
"owner": "Administrator",
"parent": "Journal Voucher",
"parentfield": "__print_formats",
"parenttype": "DocType",
"print_format_type": "Server",
"standard": "Yes"
}

View File

@ -3,12 +3,13 @@
"doc_type": "Journal Voucher", "doc_type": "Journal Voucher",
"docstatus": 0, "docstatus": 0,
"doctype": "Print Format", "doctype": "Print Format",
"html": "<h3 align=\"center\"><script>doc.select_print_heading || \"Payment Receipt Note\"</script></h3>\n\n<table class='simpletable'>\n<tr>\n<td><b> Receipt No.: </b></td>\n<td><script>doc.name</script></td>\n</tr>\n<tr>\n<td><b> Date : </b></td>\n<td><script>date.str_to_user(doc.voucher_date)</script></td>\n</tr> \n<tr>\n<td><b> Remark: </b></td>\n<td><script> doc.remark </script></td>\n</tr>\n<tr>\n<td><b> Received From: </b></td>\n<td><b><script> doc.pay_to_recd_from </script></b></td>\n</tr>\n</table>\n<br>\n\n<div><b><script>doc.total_amount</script></b> </td></div><br>\n<div style=\"text-align:left\"><b><script>doc.total_amount_in_words</script></b></div><br>\n<br>\n<table class=\"noborder\">\n<tr>\n<td style = \"text-align = right;\"><h3>For <script>doc.company</script>,</h3><br><div>(Authorised Signatory)</div></td>\n</tr>\n</table>", "html": "{%- from \"templates/print_formats/standard_macros.html\" import add_header -%}\n<div class=\"page-break\">\n {%- if not doc.get(\"print_heading\") and not doc.get(\"select_print_heading\") \n and doc.set(\"select_print_heading\", _(\"Payment Receipt Note\")) -%}{%- endif -%}\n {{ add_header(0, 1, doc, letter_head, no_letterhead) }}\n\n {%- for label, value in (\n (_(\"Received On\"), frappe.utils.formatdate(doc.voucher_date)),\n (_(\"Received From\"), doc.pay_to_recd_from),\n (_(\"Amount\"), \"<strong>\" + doc.total_amount + \"</strong><br>\" + (doc.total_amount_in_words or \"\") + \"<br>\"),\n (_(\"Remarks\"), doc.remark)\n ) -%}\n <div class=\"row\">\n <div class=\"col-sm-3\"><label class=\"text-right\">{{ label }}</label></div>\n <div class=\"col-sm-9\">{{ value }}</div>\n </div>\n\n {%- endfor -%}\n\n <hr>\n <br>\n <p class=\"strong\">\n {{ _(\"For\") }} {{ doc.company }},<br>\n <br>\n <br>\n <br>\n {{ _(\"Authorized Signatory\") }}\n </p>\n</div>\n\n",
"idx": 1, "idx": 1,
"modified": "2014-05-13 16:07:19.144006", "modified": "2014-08-29 15:55:34.248384",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Accounts", "module": "Accounts",
"name": "Payment Receipt Voucher", "name": "Payment Receipt Voucher",
"owner": "Administrator", "owner": "Administrator",
"print_format_type": "Server",
"standard": "Yes" "standard": "Yes"
} }

File diff suppressed because one or more lines are too long

View File

@ -1,135 +0,0 @@
{%- if doc.letter_head -%}
{{ frappe.db.get_value("Letter Head", doc.letter_head, "content") }}
{%- endif -%}
<!-- Page Layout Settings -->
<div class='common page-header'>
<table class='header-table' cellspacing=0 style="width: 100%">
<thead>
<tr><td colspan="2"><h1>{{ doc.select_print_heading or 'Invoice' }}</h1></td></tr>
<tr><td colspan="2"><h3>{{ doc.name }}</h3></td></tr>
</thead>
<tbody>
<tr>
<td width=60%><table width=100% cellspacing=0><tbody>
<tr>
<td width=39%><b>Name</b></td>
<td>{{ doc.customer_name }}</td>
</tr>
<tr>
<td><b>Address</b></td>
<td>{{ doc.address_display.replace("\n", "<br>") }}</td>
</tr>
<tr>
<td><b>Contact</b></td>
<td>{{ doc.contact_display }}</td>
</tr>
</tbody></table></td>
<td><table width=100% cellspacing=0><tbody>
<tr>
<td width=40%><b>Invoice Date</b></td>
<td>{{ utils.formatdate(doc.posting_date) }}</td>
</tr>
{%- if doc.convert_into_recurring_invoice and doc.recurring_id -%}
<tr>
<td width=40%><b>Invoice Period</b></td>
<td>{{ (utils.formatdate(doc.invoice_period_from_date)) +
' to ' + utils.formatdate(doc.invoice_period_to_date) }}</td>
</tr>
{%- endif -%}
<tr>
<td><b>Due Date</b></td>
<td>{{ utils.formatdate(doc.due_date) }}</td>
</tr>
</tbody></table></td>
</tr>
</tbody>
<tfoot>
</tfoot>
</table>
</div>
<div class='common page-body'>
<!--
Page Body will contain
+ table 2
- Sales Invoice Data
-->
<table class="table table-bordered">
<tbody>
<tr>
<th>Sr</th>
<th>Item Name</th>
<th>Description</th>
<th>Qty</th>
<th>UoM</th>
<th>Basic Rate</th>
<th>Amount</th>
</tr>
{%- for row in doc.get({"doctype":"Sales Invoice Item"}) %}
<tr>
<td style="width: 3%;">{{ row.idx }}</td>
<td style="width: 20%;">{{ row.item_name }}</td>
<td style="width: 37%;">{{ row.description }}</td>
<td style="width: 5%; text-align: right;">{{ row.qty }}</td>
<td style="width: 5%;">{{ row.stock_uom }}</td>
<td style="width: 15%; text-align: right;">{{ utils.fmt_money(row.rate, currency=doc.currency) }}</td>
<td style="width: 15%; text-align: right;">{{ utils.fmt_money(row.amount, currency=doc.currency) }}</td>
</tr>
{% endfor -%}
</tbody>
</table>
</div>
<div class='common page-footer'>
<!--
Page Footer will contain
+ table 3
- Terms and Conditions
- Total Rounded Amount Calculation
- Total Rounded Amount in Words
-->
<table class='footer-table' width=100% cellspacing=0>
<thead>
</thead>
<tbody>
<tr>
<td width=60% style='padding-right: 10px;'>
<b>Terms, Conditions &amp; Other Information:</b><br />
{{ doc.terms }}
</td>
<td>
<table cellspacing=0 width=100%>
<tbody>
<tr>
<td>Net Total</td>
<td width=40% style="text-align: right;">{{
utils.fmt_money(doc.net_total_export, currency=doc.currency)
}}</td>
</tr>
{%- for charge in doc.get({"doctype":"Sales Taxes and Charges"}) -%}
{%- if not charge.included_in_print_rate -%}
<tr>
<td>{{ charge.description }}</td>
<td style="text-align: right;">{{ utils.fmt_money(charge.tax_amount / doc.conversion_rate, currency=doc.currency) }}</td>
</tr>
{%- endif -%}
{%- endfor -%}
<tr>
<td>Grand Total</td>
<td style="text-align: right;">{{ utils.fmt_money(doc.grand_total_export, currency=doc.currency) }}</td>
</tr>
<tr style='font-weight: bold'>
<td>Rounded Total</td>
<td style="text-align: right;">{{ utils.fmt_money(doc.rounded_total_export, currency=doc.currency) }}</td>
</tr>
</tbody>
</table>
<br /><b>In Words</b><br />
<i>{{ doc.in_words_export }}</i>
</td>
</tr>
</tbody>
<tfoot>
</tfoot>
</table>
</div>

View File

@ -1,14 +0,0 @@
{
"creation": "2013-03-21 15:24:28",
"doc_type": "Sales Invoice",
"docstatus": 0,
"doctype": "Print Format",
"idx": 1,
"modified": "2014-05-13 17:51:43.245831",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Sales Invoice",
"owner": "Administrator",
"print_format_type": "Server",
"standard": "Yes"
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Some files were not shown because too many files have changed in this diff Show More