Merge branch 'stable' of github.com:webnotes/erpnext into stable
Conflicts:
erpnext/stock/DocType Mapper/Purchase Order-Purchase Receipt/Purchase Order-Purchase Receipt.txt
diff --git a/.gitignore b/.gitignore
index 7f90378..0818a02 100644
--- a/.gitignore
+++ b/.gitignore
@@ -5,3 +5,4 @@
patch.log
lib
versions-local.db
+*.sql*
diff --git a/data/master.sql.gz b/data/master.sql.gz
index f3eaf34..9f2ed7f 100644
--- a/data/master.sql.gz
+++ b/data/master.sql.gz
Binary files differ
diff --git a/erpnext/accounts/DocType Mapper/Purchase Order-Payable Voucher/Purchase Order-Payable Voucher.txt b/erpnext/accounts/DocType Mapper/Purchase Order-Payable Voucher/Purchase Order-Payable Voucher.txt
index 1949110..e58f738 100644
--- a/erpnext/accounts/DocType Mapper/Purchase Order-Payable Voucher/Purchase Order-Payable Voucher.txt
+++ b/erpnext/accounts/DocType Mapper/Purchase Order-Payable Voucher/Purchase Order-Payable Voucher.txt
@@ -5,7 +5,7 @@
{
'creation': '2010-08-08 17:09:35',
'docstatus': 0,
- 'modified': '2011-09-15 15:04:43',
+ 'modified': '2011-10-12 12:10:15',
'modified_by': 'Administrator',
'owner': 'Administrator'
},
@@ -107,6 +107,15 @@
'to_field': 'naming_series'
},
+ # Field Mapper Detail
+ {
+ 'doctype': 'Field Mapper Detail',
+ 'from_field': 'total_tax',
+ 'map': 'Yes',
+ 'match_id': 0,
+ 'to_field': 'total_tax'
+ },
+
# Table Mapper Detail
{
'doctype': 'Table Mapper Detail',
@@ -124,17 +133,6 @@
'match_id': 1,
'to_field': 'entries',
'to_table': 'PV Detail',
- 'validation_logic': 'ifnull(billed_qty,0) < qty'
- },
-
- # Table Mapper Detail
- {
- 'doctype': 'Table Mapper Detail',
- 'from_field': 'po_details',
- 'from_table': 'PO Detail',
- 'match_id': 1,
- 'to_field': 'entries',
- 'to_table': 'PV Detail',
'validation_logic': 'ifnull(billed_qty,0) < qty and docstatus = 1'
},
diff --git a/erpnext/accounts/DocType Mapper/Purchase Receipt-Payable Voucher/Purchase Receipt-Payable Voucher.txt b/erpnext/accounts/DocType Mapper/Purchase Receipt-Payable Voucher/Purchase Receipt-Payable Voucher.txt
index 94408e7..1744c4d 100644
--- a/erpnext/accounts/DocType Mapper/Purchase Receipt-Payable Voucher/Purchase Receipt-Payable Voucher.txt
+++ b/erpnext/accounts/DocType Mapper/Purchase Receipt-Payable Voucher/Purchase Receipt-Payable Voucher.txt
@@ -5,7 +5,7 @@
{
'creation': '2010-08-08 17:09:35',
'docstatus': 0,
- 'modified': '2011-09-15 15:04:44',
+ 'modified': '2011-10-12 10:49:26',
'modified_by': 'Administrator',
'owner': 'Administrator'
},
@@ -125,6 +125,33 @@
'to_field': 'naming_series'
},
+ # Field Mapper Detail
+ {
+ 'doctype': 'Field Mapper Detail',
+ 'from_field': 'net_total',
+ 'map': 'Yes',
+ 'match_id': 0,
+ 'to_field': 'net_total'
+ },
+
+ # Field Mapper Detail
+ {
+ 'doctype': 'Field Mapper Detail',
+ 'from_field': 'grand_total',
+ 'map': 'Yes',
+ 'match_id': 0,
+ 'to_field': 'grand_total'
+ },
+
+ # Field Mapper Detail
+ {
+ 'doctype': 'Field Mapper Detail',
+ 'from_field': 'total_tax',
+ 'map': 'Yes',
+ 'match_id': 0,
+ 'to_field': 'total_tax'
+ },
+
# Table Mapper Detail
{
'doctype': 'Table Mapper Detail',
diff --git a/erpnext/accounts/GL Mapper/Journal Voucher/Journal Voucher.txt b/erpnext/accounts/GL Mapper/Journal Voucher/Journal Voucher.txt
index b4a8cf6..fac3831 100644
--- a/erpnext/accounts/GL Mapper/Journal Voucher/Journal Voucher.txt
+++ b/erpnext/accounts/GL Mapper/Journal Voucher/Journal Voucher.txt
@@ -1 +1 @@
-[{'doc_type': 'Journal Voucher', 'modified_by': 'nabin@webnotestech.com', 'name': 'Journal Voucher', 'parent': None, 'creation': '2009-03-12 12:09:24', 'modified': '2010-04-30 17:56:41', 'module': 'Accounts', 'doctype': 'GL Mapper', 'idx': None, 'parenttype': None, 'owner': 'Administrator', 'docstatus': 0, 'parentfield': None}, {'creation': '2009-03-12 12:09:24', 'voucher_type': 'parent:doctype', 'doctype': 'GL Mapper Detail', 'owner': 'Administrator', 'cost_center': 'cost_center', 'voucher_no': 'parent:name', 'modified_by': 'nabin@webnotestech.com', 'against_voucher': "value:d.against_voucher or d.against_invoice or ''", 'table_field': 'entries', 'transaction_date': 'parent:voucher_date', 'debit': 'debit', 'docstatus': 0, 'parent': 'Journal Voucher', 'company': 'parent:company', 'aging_date': 'parent:aging_date', 'fiscal_year': 'parent:fiscal_year', 'is_advance': 'is_advance', 'remarks': 'parent:remark', 'account': 'account', 'name': 'GLMDetail00001', 'idx': 1, 'against_voucher_type': "value:(d.against_voucher and 'Payable Voucher') or (d.against_invoice and 'Receivable Voucher') or ''", 'modified': '2010-04-30 17:56:41', 'against': 'against_account', 'credit': 'credit', 'parenttype': 'GL Mapper', 'is_opening': 'parent:is_opening', 'posting_date': 'parent:posting_date', 'parentfield': 'fields'}, {'creation': '2009-06-11 11:09:11', 'voucher_type': 'doctype', 'doctype': 'GL Mapper Detail', 'owner': 'Administrator', 'cost_center': '', 'voucher_no': 'name', 'modified_by': 'nabin@webnotestech.com', 'against_voucher': '', 'table_field': '', 'transaction_date': 'voucher_date', 'debit': 'value:0', 'docstatus': 0, 'parent': 'Journal Voucher', 'company': 'company', 'aging_date': 'aging_date', 'fiscal_year': 'fiscal_year', 'is_advance': '', 'remarks': 'remark', 'account': 'tax_code', 'name': 'GLMDetail00009', 'idx': 2, 'against_voucher_type': None, 'modified': '2010-04-30 17:56:41', 'against': 'supplier_account', 'credit': 'ded_amount', 'parenttype': 'GL Mapper', 'is_opening': 'is_opening', 'posting_date': 'posting_date', 'parentfield': 'fields'}]
\ No newline at end of file
+[{'doc_type': 'Journal Voucher', 'modified_by': 'nabin@webnotestech.com', 'name': 'Journal Voucher', 'parent': None, 'creation': '2009-03-12 12:09:24', 'modified': '2010-04-30 17:56:41', 'module': 'Accounts', 'doctype': 'GL Mapper', 'idx': None, 'parenttype': None, 'owner': 'Administrator', 'docstatus': 0, 'parentfield': None}, {'creation': '2009-03-12 12:09:24', 'voucher_type': 'parent:doctype', 'doctype': 'GL Mapper Detail', 'owner': 'Administrator', 'cost_center': 'cost_center', 'voucher_no': 'parent:name', 'modified_by': 'nabin@webnotestech.com', 'against_voucher': "value:d.against_voucher or d.against_invoice or d.against_jv or ''", 'table_field': 'entries', 'transaction_date': 'parent:voucher_date', 'debit': 'debit', 'docstatus': 0, 'parent': 'Journal Voucher', 'company': 'parent:company', 'aging_date': 'parent:aging_date', 'fiscal_year': 'parent:fiscal_year', 'is_advance': 'is_advance', 'remarks': 'parent:remark', 'account': 'account', 'name': 'GLMDetail00001', 'idx': 1, 'against_voucher_type': "value:(d.against_voucher and 'Payable Voucher') or (d.against_invoice and 'Receivable Voucher') or (d.against_jv and 'Journal Voucher') or ''", 'modified': '2010-04-30 17:56:41', 'against': 'against_account', 'credit': 'credit', 'parenttype': 'GL Mapper', 'is_opening': 'parent:is_opening', 'posting_date': 'parent:posting_date', 'parentfield': 'fields'}, {'creation': '2009-06-11 11:09:11', 'voucher_type': 'doctype', 'doctype': 'GL Mapper Detail', 'owner': 'Administrator', 'cost_center': '', 'voucher_no': 'name', 'modified_by': 'nabin@webnotestech.com', 'against_voucher': '', 'table_field': '', 'transaction_date': 'voucher_date', 'debit': 'value:0', 'docstatus': 0, 'parent': 'Journal Voucher', 'company': 'company', 'aging_date': 'aging_date', 'fiscal_year': 'fiscal_year', 'is_advance': '', 'remarks': 'remark', 'account': 'tax_code', 'name': 'GLMDetail00009', 'idx': 2, 'against_voucher_type': None, 'modified': '2010-04-30 17:56:41', 'against': 'supplier_account', 'credit': 'ded_amount', 'parenttype': 'GL Mapper', 'is_opening': 'is_opening', 'posting_date': 'posting_date', 'parentfield': 'fields'}]
diff --git a/erpnext/accounts/Module Def/Accounts/Accounts.txt b/erpnext/accounts/Module Def/Accounts/Accounts.txt
index 0a6921a..f9c36c8 100644
--- a/erpnext/accounts/Module Def/Accounts/Accounts.txt
+++ b/erpnext/accounts/Module Def/Accounts/Accounts.txt
@@ -5,7 +5,7 @@
{
'creation': '2010-09-25 10:50:37',
'docstatus': 0,
- 'modified': '2011-09-27 12:44:04',
+ 'modified': '2011-12-07 16:18:28',
'modified_by': 'Administrator',
'owner': 'Administrator'
},
@@ -181,6 +181,15 @@
# Module Def Item
{
+ 'description': 'Track C-Form received from customers',
+ 'display_name': 'C-Form',
+ 'doc_name': 'C-Form',
+ 'doc_type': 'Setup Forms',
+ 'doctype': 'Module Def Item'
+ },
+
+ # Module Def Item
+ {
'display_name': 'General Ledger',
'doc_name': 'GL Entry',
'doc_type': 'Reports',
diff --git a/erpnext/accounts/Print Format/Cheque Printing Format/Cheque Printing Format.txt b/erpnext/accounts/Print Format/Cheque Printing Format/Cheque Printing Format.txt
index e0d2bce..aa90311 100755
--- a/erpnext/accounts/Print Format/Cheque Printing Format/Cheque Printing Format.txt
+++ b/erpnext/accounts/Print Format/Cheque Printing Format/Cheque Printing Format.txt
@@ -3,10 +3,10 @@
# These values are common in all dictionaries
{
- 'creation': '2011-03-25 15:26:02',
+ 'creation': '2011-03-28 15:17:25',
'docstatus': 0,
'modified': '2011-03-28 12:33:24',
- 'modified_by': 'Administrator',
+ 'modified_by': 'umair@iwebnotes.com',
'owner': 'Administrator'
},
diff --git a/erpnext/accounts/Print Format/Form 16A Print Format/Form 16A Print Format.txt b/erpnext/accounts/Print Format/Form 16A Print Format/Form 16A Print Format.txt
index 8316306..4da5443 100644
--- a/erpnext/accounts/Print Format/Form 16A Print Format/Form 16A Print Format.txt
+++ b/erpnext/accounts/Print Format/Form 16A Print Format/Form 16A Print Format.txt
@@ -5,7 +5,7 @@
{
'creation': '2010-09-27 17:30:34',
'docstatus': 0,
- 'modified': '2011-06-15 13:36:06',
+ 'modified': '2011-10-19 14:19:27',
'modified_by': 'Administrator',
'owner': 'Administrator'
},
@@ -13,7 +13,7 @@
# These values are common for all Print Format
{
'doctype': 'Print Format',
- 'html': '<html>\n \n<body>\n<table border = "1" style=\'border-collapse: collapse;\'>\n \n <tr>\n <td colspan = "3"><h1 align = "center"><b>FORM No. 16 A</b></h1>\n <p align="right">Certificate No:<script>doc.name</script></p>\n <p align = "center">[See rule 31 (1)(b)]</p>\n <h2 align = "center"><b>Certifiction of deduction of tax at source under section 203 of the Income-tax Act, 1961</b></h2>\n <p>[For interest on securities; dividends; interests other than \'interests on securities\';winnings from lottery or crossword puzzle;\n winnings from horse race; payments to contractors and sub-contractors;insurance comission;payments to\n \n non-resident sportsmen/ sports associations;payments in respect of deposits under National Savings Scheme:\n payments on account of repurchase of units by Mutual Fund or Unit Trust of India; commission, remuneration or prize\n \n on sale of lottery tickets; comission or brokerage;rent;fees for professional or technical services;royalty and any sum \n under section 28(va);income in respect of units; payment of compensation on acquisition of certain immovable property;\n\n other sums under section 195; income in respect of units of non-residents referred to in section 196A; income from units\n referred to in section 196B;income from foreign currency bonds or shares of an Indian Company referred to in section</p>\n 196C; income of Foreign Institutional Investors from securities referred to in section 196D]\n </td> \n </tr>\n\n <tr>\n <td width="30%">Name and address of person deducing tax</td>\n <td width="40%">Acknowledgement No.s of all quarterly statements of TDS under sub-section(3) of section 200 as provided by TIN Facilitation Centre or NSDL web-site</td>\n <td width="30%">Name and address of the person to whom payment is made or in whose account it is credited</td>\n </tr>\n \n <tr>\n <td>\n <table>\n <tr><script>doc.company</script></tr><br><br>\n <tr><script>replace_newlines(doc.company_address)</script></tr>\n </table>\n </td>\n <td>\n <script>print_table(\'Form 16A\', doc.name, \'form_16A_ack_details\',\'Form 16A Ack Detail\', [\'quarter\',\'ack_no\'], [\'Quarter\' , \'Acknowledgement No.\'] , [\'40%\',\'60%\']).innerHTML</script>\n </td>\n <td>\n <table>\n <tr><script>doc.party_name</script></tr><br><br>\n <tr><script>replace_newlines(doc.party_address)</script></tr>\n </table>\n </td>\n </tr>\n \n <tr>\n <td>\n <table>\n <tr><b>Registration Details OF THE DEDUCTOR</b></tr><br>\n <tr><script>replace_newlines(doc.registration_details)</script></tr>\n </table>\n </td>\n \n <td>\n <table>\n <tr><b><center>NATURE OF PAYMENT</center></b></tr><br><br>\n <tr><b><center><script>doc.tds_category</script></center></b></tr>\n \n </table>\n </td>\n \n <td>\n <table>\n <tr><b>PAN NO. OF THE PAYEE</b></tr><br>\n <tr><script>doc.pan_number</script></tr>\n \n </table>\n </td>\n </tr>\n \n <tr>\n <td align = "center" colspan ="3"><b>DETAILS OF PAYMENT, TAX DEDUCTION AND DEPOSIT OF TAX INTO CENTRAL GOVERNMENT ACCOUNT</b>\n <p align = "center">(The deductor is to provide transaction wise details of tax deducted and deposited)</p>\n </tr>\n \n <tr>\n <td colspan="3">\n <script>print_table(\'Form 16A\', doc.name, \'form_16A_tax_details\',\'Form 16A Tax Detail\', [\'SR\',\'amount_paid\', \'date_of_payment\',\'tds_main\',\'surcharge\',\'cess_on_tds\',\'total_tax_deposited\',\'cheque_no\',\'bsr_code\',\'tax_deposited_date\',\'challan_no\'], [\'S No.\' , \'Amount paid / credited\',\'Date of payment / credit\',\'TDS (Rs.)\',\'Surcharge (Rs.)\',\'Cess on TDS(Rs.)\',\'Total Tax Deposited (Rs.)\',\'Cheque/DD no.(if any)\',\'BSR code on bank branch\', \'Date on which tax deposited(dd/mm/yy)\',\'Transfer Voucher/Challan Identification no.\'] , [\'3%\', \'10%\',\'10%\', \'10%\',\'10%\',\'6%\',\'10%\' ,\'10%\',\'7%\' ,\'10%\',\'7%\',\'7%\'] ).innerHTML</script>\n </td>\n </tr>\n \n <tr>\n <td colspan="3">\n Certified that a sum of Rs. <script>doc.total_amount</script> has been deducted at source and paid to the credit of the Central Government as per details given above <br><br><br><br>\n <p align="right"> Signature of person responsible for deduction of tax \n </td>\n </tr>\n \n <tr>\n <td colspan="3">\n <table width="100%" border="0">\n <tr>\n <td width="50%">Place: <script>doc.place</script></td>\n <td width="50%" align="right">Full Name: <script>doc.full_name</script></td>\n </tr>\n <tr>\n <td width="50%">Date: <script>date.str_to_user(doc.dt)</script></td>\n <td width="50%" align="right">Designation: <script>doc.designation</script></td>\n </tr>\n </table>\n </td>\n </tr>\n \n</table>\n</body>\n</html>',
+ 'html': '<html>\n <script>\n function get_letter_head() {\n\t// add letter head\n\tvar cp = locals[\'Control Panel\'][\'Control Panel\'];\n\tif(doc.letter_head)\n\t\tvar lh= cstr(_p.letter_heads[doc.letter_head]);\n\telse if(cp.letter_head)\n\t\tvar lh= cp.letter_head;\n\telse \n\t\tvar lh= \'\';\n\t\t\n\treturn lh;\n}\n </script>\n<body>\n<table border = "1" style=\'border-collapse: collapse;\'>\n <tr>\n <td>\n <div style="border-bottom: 1px solid; padding-bottom: 5px; width:100%"><script>get_letter_head()</script></div>\n </td>\n </tr>\n <tr>\n <td colspan = "3"><h1 align = "center"><b>FORM No. 16 A</b></h1>\n <p align="right">Certificate No:<script>doc.name</script></p>\n <p align = "center">[See rule 31 (1)(b)]</p>\n <h2 align = "center"><b>Certifiction of deduction of tax at source under section 203 of the Income-tax Act, 1961</b></h2>\n <p>[For interest on securities; dividends; interests other than \'interests on securities\';winnings from lottery or crossword puzzle;\n winnings from horse race; payments to contractors and sub-contractors;insurance comission;payments to\n \n non-resident sportsmen/ sports associations;payments in respect of deposits under National Savings Scheme:\n payments on account of repurchase of units by Mutual Fund or Unit Trust of India; commission, remuneration or prize\n \n on sale of lottery tickets; comission or brokerage;rent;fees for professional or technical services;royalty and any sum \n under section 28(va);income in respect of units; payment of compensation on acquisition of certain immovable property;\n\n other sums under section 195; income in respect of units of non-residents referred to in section 196A; income from units\n referred to in section 196B;income from foreign currency bonds or shares of an Indian Company referred to in section</p>\n 196C; income of Foreign Institutional Investors from securities referred to in section 196D]\n </td> \n </tr>\n\n <tr>\n <td width="30%">Name and address of person deducing tax</td>\n <td width="40%">Acknowledgement No.s of all quarterly statements of TDS under sub-section(3) of section 200 as provided by TIN Facilitation Centre or NSDL web-site</td>\n <td width="30%">Name and address of the person to whom payment is made or in whose account it is credited</td>\n </tr>\n \n <tr>\n <td>\n <table>\n <tr><script>doc.company</script></tr><br><br>\n <tr><script>replace_newlines(doc.company_address)</script></tr>\n </table>\n </td>\n <td>\n <script>print_table(\'Form 16A\', doc.name, \'form_16A_ack_details\',\'Form 16A Ack Detail\', [\'quarter\',\'ack_no\'], [\'Quarter\' , \'Acknowledgement No.\'] , [\'40%\',\'60%\']).innerHTML</script>\n </td>\n <td>\n <table>\n <tr><script>doc.party_name</script></tr><br><br>\n <tr><script>replace_newlines(doc.party_address)</script></tr>\n </table>\n </td>\n </tr>\n \n <tr>\n <td>\n <table>\n <tr><b>Registration Details OF THE DEDUCTOR</b></tr><br>\n <tr><script>replace_newlines(doc.registration_details)</script></tr>\n </table>\n </td>\n \n <td>\n <table>\n <tr><b><center>NATURE OF PAYMENT</center></b></tr><br><br>\n <tr><b><center><script>doc.tds_category</script></center></b></tr>\n \n </table>\n </td>\n \n <td>\n <table>\n <tr><b>PAN NO. OF THE PAYEE</b></tr><br>\n <tr><script>doc.pan_number</script></tr>\n \n </table>\n </td>\n </tr>\n \n <tr>\n <td align = "center" colspan ="3"><b>DETAILS OF PAYMENT, TAX DEDUCTION AND DEPOSIT OF TAX INTO CENTRAL GOVERNMENT ACCOUNT</b>\n <p align = "center">(The deductor is to provide transaction wise details of tax deducted and deposited)</p>\n </tr>\n \n <tr>\n <td colspan="3">\n <script>print_table(\'Form 16A\', doc.name, \'form_16A_tax_details\',\'Form 16A Tax Detail\', [\'SR\',\'amount_paid\', \'date_of_payment\',\'tds_main\',\'surcharge\',\'cess_on_tds\',\'total_tax_deposited\',\'cheque_no\',\'bsr_code\',\'tax_deposited_date\',\'challan_no\'], [\'S No.\' , \'Amount paid / credited\',\'Date of payment / credit\',\'TDS (Rs.)\',\'Surcharge (Rs.)\',\'Cess on TDS(Rs.)\',\'Total Tax Deposited (Rs.)\',\'Cheque/DD no.(if any)\',\'BSR code on bank branch\', \'Date on which tax deposited(dd/mm/yy)\',\'Transfer Voucher/Challan Identification no.\'] , [\'3%\', \'10%\',\'10%\', \'10%\',\'10%\',\'6%\',\'10%\' ,\'10%\',\'7%\' ,\'10%\',\'7%\',\'7%\'] ).innerHTML</script>\n </td>\n </tr>\n \n <tr>\n <td colspan="3">\n Certified that a sum of Rs. <script>doc.total_amount</script> has been deducted at source and paid to the credit of the Central Government as per details given above <br><br><br><br>\n <p align="right"> Signature of person responsible for deduction of tax \n </td>\n </tr>\n \n <tr>\n <td colspan="3">\n <table width="100%" border="0">\n <tr>\n <td width="50%">Place: <script>doc.place</script></td>\n <td width="50%" align="right">Full Name: <script>doc.full_name</script></td>\n </tr>\n <tr>\n <td width="50%">Date: <script>date.str_to_user(doc.dt)</script></td>\n <td width="50%" align="right">Designation: <script>doc.designation</script></td>\n </tr>\n </table>\n </td>\n </tr>\n \n</table>\n</body>\n</html>',
'module': 'Accounts',
'name': '__common__',
'standard': 'Yes'
diff --git a/erpnext/accounts/Print Format/POS Invoice/POS Invoice.txt b/erpnext/accounts/Print Format/POS Invoice/POS Invoice.txt
new file mode 100644
index 0000000..6a7e835
--- /dev/null
+++ b/erpnext/accounts/Print Format/POS Invoice/POS Invoice.txt
@@ -0,0 +1,27 @@
+# Print Format, POS Invoice
+[
+
+ # These values are common in all dictionaries
+ {
+ 'creation': '2011-10-19 14:27:47',
+ 'docstatus': 0,
+ 'modified': '2011-10-19 14:29:45',
+ 'modified_by': 'Administrator',
+ 'owner': 'Administrator'
+ },
+
+ # These values are common for all Print Format
+ {
+ 'doctype': 'Print Format',
+ 'html': '<html>\n<head>\n<!--Other charges function-->\n<script>\n var make_row = function(title,val,bold){\n var bstart = \'<b>\'; var bend = \'</b>\';\n return \'<tr><td style="width:50%">\'+(bold?bstart:\'\')+title+(bold?bend:\'\')+\'</td>\'\n +\'<td style="width:20%">\'+doc.currency+\'</td>\'\n +\'<td style="width:30%;text-align:right">\'+(val?val:\'0.00\')+\'</td>\'\n +\'</tr>\'\n }\n var make_row1 = function(title,val,bold){\n var bstart = \'<b>\'; var bend = \'</b>\';\n \n return \'<tr style="font-family:courier new; line-height:150%"><td style="width:50%">\'+(bold?bstart:\'\')+title+(bold?bend:\'\')+\'</td>\'\n +\'<td style="width:50%;text-align:right">\'+(bold?bstart:\'\')+(val?val:\'0.00\')+(bold?bend:\'\')+\'</td>\'\n +\'</tr>\'\n }\n\nfunction get_letter_head() {\n\t// add letter head\n\tvar cp = locals[\'Control Panel\'][\'Control Panel\'];\n\tif(doc.letter_head)\n\t\tvar lh= cstr(_p.letter_heads[doc.letter_head]);\n\telse if(cp.letter_head)\n\t\tvar lh= cp.letter_head;\n\telse \n\t\tvar lh= \'\';\n\t\t\n\treturn lh;\n}\n\n function get_tax_details(){\n \n var cl = getchildren(\'RV Tax Detail\',doc.name,\'other_charges\');\n var out = \'\';\n\n// if(cl.length){\n out += \'<div><table style="float: right;">\';\n for(var i=0;i<cl.length;i++){\n out += make_row1(cl[i].description,fmt_money(convert_rate(cl[i].tax_amount)),0);\n }\n\n out += make_row1(\'TOTAL\',fmt_money(doc.grand_total),1);\n // }\n out +=\'</table></div>\';\n return out;\n }\n function get_other_charges(){\n var out =\'\';\n out += \'<div><table cssClass="noborder" style="width:100%">\';\n \n out += make_row(\'Net Total\',fmt_money(convert_rate(doc.net_total)),1)\n +make_row(\'Total Taxes\',fmt_money(convert_rate(doc.other_charges_total)),0)\n +make_row(\'Grand Total\',fmt_money(convert_rate(doc.grand_total)),1)\n +make_row(\'Rounded Total\',fmt_money(convert_rate(doc.rounded_total)),1)\n +make_row(\'Outstanding Amount\',fmt_money(convert_rate(doc.outstanding_amount)),1)\n out += \'</table></div>\';\n return out;\n }\n\n \n function convert_rate(val){ \n var new_val = flt(val)/flt(doc.conversion_rate);\n return new_val;\n }\n \n</script>\n</head>\n<body>\n\n<div><script>get_letter_head()</script></div>\n<table width="100%" style="font-family: courier new; line-height:200%">\n<tr>\n<td align="left">NO: <script>doc.name</script></td>\n<td align="right">DATE: <script>date.str_to_user(doc.voucher_date)</script></td>\n</tr>\n<tr>\n<td>M/s <script>doc.contact_display</script></td>\n</tr>\n</table>\n<!--Item Table-->\n<div>\n <script>\n var t = print_table(\'Receivable Voucher\', doc.name, \'entries\', \'RV Detail\', [\'description\',\'qty\',\'basic_rate\',\'amount\'], [\'ITEM\', \'QTY\',\'RATE\',\'AMOUNT\'], [\'35%\',\'20%\',\'20%\',\'25%\'])\n if(t.appendChild) {\n // single\n out = t.innerHTML.replace(/border: 1px/gi,\'border: 0px\').replace(/style="/gi,\'style="font-family:courier new;line-height:150%;\');\n }\n else {//multiple\n out = \'<table class="None" border="0px" width="100%" style="border:0px; font-family:courier-new">\';\n\n for(var i=0;i<t.length;i++) \n {\n\t\tif(i==0)\n\t\t{\n\t\t\tout+=\'<tr>\'+t[i].childNodes[0].childNodes[0].childNodes[0].innerHTML.replace(/style="border: 1px solid rgb\\(0, 0, 0\\);/gi,\'style="font-family:courier new;\')+\'</tr>\'\n\t\t}\n\t\tout+=\'<tr>\'+t[i].childNodes[0].childNodes[0].childNodes[1].innerHTML.replace(/style="border: 1px solid rgb\\(0, 0, 0\\);/gi,\'style="font-family:courier new;\')+\'</tr>\'\n }\n\tout += \'</table>\'\n }\n out;\n </script>\n\n</div>\n\n<!--Tax table-->\n<div><script>get_tax_details();</script>\n </table>\n</div>\n\n<br>\n<table style="font-family:courier new;">\n<tr><td><b><script>doc.terms</script></b></td></tr>\n<tr><td nowrap><b>For <script>doc.company</script></b></td></tr>\n<tr><td> </td></tr>\n<tr><td nowrap><b>Signatory</b></td></tr>\n</table>\n</body>\n</html>',
+ 'module': 'Accounts',
+ 'name': '__common__',
+ 'standard': 'Yes'
+ },
+
+ # Print Format, POS Invoice
+ {
+ 'doctype': 'Print Format',
+ 'name': 'POS Invoice'
+ }
+]
\ No newline at end of file
diff --git a/erpnext/accounts/Print Format/Payment Receipt Voucher/Payment Receipt Voucher.txt b/erpnext/accounts/Print Format/Payment Receipt Voucher/Payment Receipt Voucher.txt
index fa0145a..932df2e 100755
--- a/erpnext/accounts/Print Format/Payment Receipt Voucher/Payment Receipt Voucher.txt
+++ b/erpnext/accounts/Print Format/Payment Receipt Voucher/Payment Receipt Voucher.txt
@@ -3,17 +3,17 @@
# These values are common in all dictionaries
{
- 'creation': '2011-03-25 17:30:45',
+ 'creation': '2011-03-28 15:17:25',
'docstatus': 0,
- 'modified': '2011-04-27 11:44:30',
- 'modified_by': 'Administrator',
+ 'modified': '2011-03-28 12:31:40',
+ 'modified_by': 'umair@iwebnotes.com',
'owner': 'Administrator'
},
# These values are common for all Print Format
{
'doctype': 'Print Format',
- 'html': '<div style="position: relative;">\n<h3 align="center"><script>doc.company</script>\n</div>\n\n<font size="4">\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_rec_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<div>This receipt is issued subject to realization of the <script>if(doc.cheque_no){\'Cheque\'}else{\'Cash\'}</script></div>\n</font>\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': '<div style="position: relative;">\n<h3 align="center"><script>doc.company</script>\n</div>\n\n<font size="4">\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_rec_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<div>This receipt is issued subject to realization of the Cheque</div>\n</font>\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>',
'module': 'Accounts',
'name': '__common__',
'standard': 'Yes'
diff --git a/erpnext/accounts/Print Format/Sales Invoice Classic/Sales Invoice Classic.txt b/erpnext/accounts/Print Format/Sales Invoice Classic/Sales Invoice Classic.txt
new file mode 100644
index 0000000..d6255d7
--- /dev/null
+++ b/erpnext/accounts/Print Format/Sales Invoice Classic/Sales Invoice Classic.txt
@@ -0,0 +1,28 @@
+# Print Format, Sales Invoice Classic
+[
+
+ # These values are common in all dictionaries
+ {
+ 'creation': '2011-12-13 11:02:59',
+ 'docstatus': 0,
+ 'modified': '2011-12-13 13:31:22',
+ 'modified_by': 'Administrator',
+ 'owner': 'Administrator'
+ },
+
+ # These values are common for all Print Format
+ {
+ 'doc_type': 'Receivable Voucher',
+ 'doctype': 'Print Format',
+ 'html': '<!--\n\tSample Print Format for ERPNext\n\tPlease use at your own discretion\n\tFor suggestions and contributions:\n\t\thttps://github.com/webnotes/erpnext-print-templates\n\n\tFreely usable under MIT license\n-->\n\n<!-- Style Settings -->\n<style>\n\t/*\n\t\tcommon style for whole page\n\t\tThis should include:\n\t\t+ page size related settings\n\t\t+ font family settings\n\t\t+ line spacing settings\n\t*/\n\t@media screen {\n\t\tbody {\n\t\t\twidth: 8.3in;\n\t\t}\n\t}\n\n\thtml, body, div, span, td {\n\t\tfont-family: "Georgia", serif;\n\t\tfont-size: 12px;\n\t}\n\n\tbody {\n\t\tpadding: 10px;\n\t\tmargin: auto;\n\t\tfont-size: 12px;\n\t\tline-height: 150%;\n\t}\n\n\t.common {\n\t\tfont-family: "Georgia", serif !important;\n\t\tfont-size: 12px;\n\t\tpadding: 10px 0px;\n\t}\n\n\ttable {\n\t\tborder-collapse: collapse;\n\t\twidth: 100%;\n\t\tvertical-align: top;\n\t}\n\n\ttable td {\n\t\tpadding: 2px 0px;\n\t}\n\t\n\ttable h1, h2, h3, h4, h5, h6 {\n\t\tpadding: 0px;\n\t\tmargin: 0px;\n\t}\n\n\ttable.header-table td {\n\t\tvertical-align: top;\n\t}\n\n\ttable.header-table thead {\n\t\tborder-bottom: 1px solid black;\n\t}\n\n\ttable.header-table h3 {\n\t\tcolor: gray;\n\t}\n\n\ttable.header-table thead td {\n\t\tpadding: 5px 0px;\n\t}\n\n\tdiv.page-body table td:nth-child(6),\n\tdiv.page-body table td:nth-child(7) {\n\t\ttext-align: right;\n\t}\n\n\ttable.footer-table td {\n\t\tvertical-align: top;\n\t}\n\n\ttable.footer-table td table td:nth-child(2),\n\ttable.footer-table td table td:nth-child(3) {\n\t\ttext-align: right;\n\t}\n</style>\n\n\n<!-- Javascript -->\n<script>\n\tsi_std = {\n\t\tprint_item_table: function() {\n\t\t\tvar table = print_table(\n\t\t\t\t\'Receivable Voucher\',\n\t\t\t\tdoc.name,\n\t\t\t\t\'entries\',\n\t\t\t\t\'RV Detail\',\n\t\t\t\t[// Here specify the table columns to be displayed\n\t\t\t\t\t\'SR\', \'item_name\', \'description\', \'qty\', \'stock_uom\',\n\t\t\t\t\t\'export_rate\', \'export_amount\'\n\t\t\t\t],\n\t\t\t\t[// Here specify the labels of column headings\n\t\t\t\t\t\'Sr\', \'Item Name\', \'Description\', \'Qty\',\n\t\t\t\t\t\'UoM\', \'Basic Rate\', \'Amount\'\n\t\t\t\t],\n\t\t\t\t[// Here specify the column widths\n\t\t\t\t\t\'3%\', \'20%\', \'37%\', \'5%\',\n\t\t\t\t\t\'5%\', \'15%\', \'15%\'\n\t\t\t\t],\n\t\t\t\tnull,\n\t\t\t\tnull,\n\t\t\t\t{\n\t\t\t\t\t\'description\' : function(data_row) {\n\t\t\t\t\t\tif(data_row.adj_rate) {\n\t\t\t\t\t\t\tvar to_append = \'<div style="padding-left: 15px;"><i>Discount: \' + \n\t\t\t\t\t\t\t\tdata_row.adj_rate + \'%</i></div>\';\n\t\t\t\t\t\t\tif(data_row.description.indexOf(to_append)==-1) {\n\t\t\t\t\t\t\t\treturn data_row.description + to_append;\n\t\t\t\t\t\t\t} else { return data_row.description; }\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\treturn data_row.description;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t);\n\n\t\t\t// This code takes care of page breaks\n\t\t\tif(table.appendChild) {\n\t\t\t\tout = table.innerHTML;\n\t\t\t} else {\n\t\t\t\tout = \'\';\n\t\t\t\tfor(var i=0; i < (table.length-1); i++) {\n\t\t\t\t\tout += table[i].innerHTML + \n\t\t\t\t\t\t\'<div style = "page-break-after: always;" \\\n\t\t\t\t\t\tclass = "page_break"></div>\\\n\t\t\t\t\t\t<div class="page-settings"></div>\';\n\t\t\t\t}\n\t\t\t\tout += table[table.length-1].innerHTML;\n\t\t\t}\n\t\t\treturn out;\n\t\t},\n\n\n\t\tprint_other_charges: function(parent) {\n\t\t\tvar oc = getchildren(\'RV Tax Detail\', doc.name, \'other_charges\');\n\t\t\tvar rows = \'<table width=100%>\\n\';\n\t\t\tfor(var i=0; i<oc.length; i++) {\n\t\t\t\trows +=\n\t\t\t\t\t\'<tr>\\n\' +\n\t\t\t\t\t\t\'\\t<td>\' + oc[i].description + \'</td>\\n\' +\n\t\t\t\t\t\t\'\\t<td></td>\\n\' +\n\t\t\t\t\t\t\'\\t<td width=38%>\' + fmt_money(oc[i].tax_amount) + \'</td>\\n\' +\n\t\t\t\t\t\'</tr>\\n\';\n\t\t\t}\n\t\t\treturn rows + \'</table>\\n\';\n\t\t}\n\t};\n</script>\n\n\n<!-- Page Layout Settings -->\n<div class=\'common page-header\'>\n\t<!-- \n\t\tPage Header will contain\n\t\t\t+ table 1\n\t\t\t\t+ table 1a\n\t\t\t\t\t- Name\n\t\t\t\t\t- Address\n\t\t\t\t\t- Contact\n\t\t\t\t\t- Mobile No\n\t\t\t\t+ table 1b\n\t\t\t\t\t- Voucher Date\n\t\t\t\t\t- Due Date\n\t-->\n\t<table class=\'header-table\' cellspacing=0>\n\t\t<thead>\n\t\t\t<tr><td><script>\'<h1>\' + (doc.select_print_heading || \'Invoice\') + \'</h1>\'</script></td></tr>\n\t\t\t<tr><td><h3><script>cur_frm.docname</script></h3></td></tr>\n\t\t</thead>\n\t\t<tbody>\n\t\t\t<tr>\n\t\t\t\t<td width=60%><table width=100% cellspacing=0><tbody>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td width=39%><b>Name</b></td>\n\t\t\t\t\t\t<td><script>doc.customer_name</script></td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td><b>Address</b></td>\n\t\t\t\t\t\t<td><script>replace_newlines(doc.address_display)</script></td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td><b>Contact</b></td>\n\t\t\t\t\t\t<td><script>doc.contact_display</script></td>\n\t\t\t\t\t</tr>\n\t\t\t\t</tbody></table></td>\n\t\t\t\t<td><table width=100% cellspacing=0><tbody>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td width=40%><b>Invoice Date</b></td>\n\t\t\t\t\t\t<td><script>date.str_to_user(doc.voucher_date)</script></td>\n\t\t\t\t\t<tr>\t\t\t\t\t\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td><b>Due Date</b></td>\n\t\t\t\t\t\t<td><script>date.str_to_user(doc.due_date)</script></td>\n\t\t\t\t\t<tr>\t\t\t\t\t\n\t\t\t\t</tbody></table></td>\n\t\t\t</tr>\n\t\t</tbody>\n\t\t<tfoot>\n\t\t\n\t\t</tfoot>\n\t</table>\n</div>\n<div class=\'common page-body\'>\n\t<!-- \n\t\tPage Body will contain\n\t\t\t+ table 2\n\t\t\t\t- Sales Invoice Data\n\t-->\n\t<script>si_std.print_item_table()</script>\n</div>\n<div class=\'common page-footer\'>\n\t<!-- \n\t\tPage Footer will contain\n\t\t\t+ table 3\n\t\t\t\t- Terms and Conditions\n\t\t\t\t- Total Rounded Amount Calculation\n\t\t\t\t- Total Rounded Amount in Words\n\t-->\n\t<table class=\'footer-table\' width=100% cellspacing=0>\n\t\t<thead>\n\t\t\t\n\t\t</thead>\n\t\t<tbody>\n\t\t\t<tr>\n\t\t\t\t<td width=60% style=\'padding-right: 10px;\'>\n\t\t\t\t\t<b>Terms, Conditions & Other Information:</b><br />\n\t\t\t\t\t<script>doc.terms</script>\n\t\t\t\t</td>\n\t\t\t\t<td>\n\t\t\t\t\t<table cellspacing=0 width=100%><tbody>\n\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t<td>Net Total</td>\n\t\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t\t<td width=38%><script>\n\t\t\t\t\t\t\t\tfmt_money(doc.net_total/doc.conversion_rate)\n\t\t\t\t\t\t\t</script></td>\n\t\t\t\t\t\t</tr>\n\t\t\t\t\t\t<tr><td colspan=3><script>si_std.print_other_charges()</script></td></tr>\n\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t<td>Grand Total</td>\n\t\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t\t<td><script>\n\t\t\t\t\t\t\t\tfmt_money(doc.grand_total_export)\n\t\t\t\t\t\t\t</script></td>\n\t\t\t\t\t\t</tr>\n\t\t\t\t\t\t<tr style=\'font-weight: bold\'>\n\t\t\t\t\t\t\t<td>Rounded Total</td>\n\t\t\t\t\t\t\t<td><script>doc.currency</script></td>\n\t\t\t\t\t\t\t<td><script>\n\t\t\t\t\t\t\t\tfmt_money(doc.rounded_total_export)\n\t\t\t\t\t\t\t</script></td>\n\t\t\t\t\t\t</tr>\n\t\t\t\t\t</tbody></table>\n\t\t\t\t\t<br /><b>In Words</b><br />\n\t\t\t\t\t<i><script>doc.in_words_export</script></i>\n\t\t\t\t</td>\n\t\t\t</tr>\t\t\n\t\t</tbody>\n\t\t<tfoot>\n\t\t\n\t\t</tfoot>\n\t</table>\n</div>\n',
+ 'module': 'Accounts',
+ 'name': '__common__',
+ 'standard': 'Yes'
+ },
+
+ # Print Format, Sales Invoice Classic
+ {
+ 'doctype': 'Print Format',
+ 'name': 'Sales Invoice Classic'
+ }
+]
\ No newline at end of file
diff --git a/erpnext/accounts/Print Format/Sales Invoice Modern/Sales Invoice Modern.txt b/erpnext/accounts/Print Format/Sales Invoice Modern/Sales Invoice Modern.txt
new file mode 100644
index 0000000..f7d2c6b
--- /dev/null
+++ b/erpnext/accounts/Print Format/Sales Invoice Modern/Sales Invoice Modern.txt
@@ -0,0 +1,28 @@
+# Print Format, Sales Invoice Modern
+[
+
+ # These values are common in all dictionaries
+ {
+ 'creation': '2011-12-13 11:02:59',
+ 'docstatus': 0,
+ 'modified': '2011-12-13 13:37:39',
+ 'modified_by': 'Administrator',
+ 'owner': 'Administrator'
+ },
+
+ # These values are common for all Print Format
+ {
+ 'doc_type': 'Receivable Voucher',
+ 'doctype': 'Print Format',
+ 'html': '<!--\n\tSample Print Format for ERPNext\n\tPlease use at your own discretion\n\tFor suggestions and contributions:\n\t\thttps://github.com/webnotes/erpnext-print-templates\n\n\tFreely usable under MIT license\n-->\n\n<!-- Style Settings -->\n<style>\n\t/*\n\t\tcommon style for whole page\n\t\tThis should include:\n\t\t+ page size related settings\n\t\t+ font family settings\n\t\t+ line spacing settings\n\t*/\n\t@media screen {\n\t\tbody {\n\t\t\twidth: 8.3in;\n\t\t}\n\t}\n\n\thtml, body, div, span, td {\n\t\tfont-family: "Helvetica", "Arial", sans-serif;\n\t\tfont-size: 12px;\n\t}\n\n\tbody {\n\t\tpadding: 10px;\n\t\tmargin: auto;\n\t\tfont-size: 12px;\n\t\tline-height: 150%;\n\t}\n\n\t.common {\n\t\tfont-family: "Helvetica", "Arial", sans-serif !important;\n\t\tfont-size: 12px;\n\t\tpadding: 10px 0px;\n\t}\n\n\ttable {\n\t\tborder-collapse: collapse;\n\t\twidth: 100%;\n\t\tvertical-align: top;\n\t\tborder-style: none !important;\n\t}\n\n\ttable td {\n\t\tpadding: 2px 0px;\n\t\tborder-style: none !important;\n\t}\n\t\n\ttable h1, h2, h3, h4, h5, h6 {\n\t\tpadding: 0px;\n\t\tmargin: 0px;\n\t}\n\n\ttable.header-table td {\n\t\tvertical-align: top;\n\t}\n\n\ttable.header-table h1 {\n\t\ttext-transform: uppercase;\n\t\tcolor: white;\n\t\tfont-size: 55px;\n\t\tfont-style: italic;\n\t}\n\n\ttable.header-table thead tr:nth-child(1) div {\n\t\theight: 24px;\n\t\tbackground-color: #696969;\n\t\tvertical-align: middle;\n\t\tpadding: 12px 0px 0px 0px;\n\t\twidth: 100%;\n\t}\n\n\tdiv.page-body table td:nth-child(6),\n\tdiv.page-body table td:nth-child(7) {\n\t\ttext-align: right;\n\t}\n\n\tdiv.page-body table tr td {\n\t\tbackground-color: #DCDCDC !important;\n\t}\n\n\tdiv.page-body table tr:nth-child(1) td {\n\t\tbackground-color: #696969 !important;\n\t\tcolor: white !important;\n\t}\n\n\ttable.footer-table td {\n\t\tvertical-align: top;\n\t}\n\n\ttable.footer-table td table td:nth-child(2),\n\ttable.footer-table td table td:nth-child(3) {\n\t\ttext-align: right;\n\t}\n\n\ttable.footer-table tfoot td {\n\t\tbackground-color: #696969;\n\t\theight: 10px;\n\t}\n\n\t.imp-details {\n\t\tbackground-color: #DCDCDC;\n\t}\n</style>\n\n\n<!-- Javascript -->\n<script>\n\tsi_std = {\n\t\tprint_item_table: function() {\n\t\t\tvar table = print_table(\n\t\t\t\t\'Receivable Voucher\',\n\t\t\t\tdoc.name,\n\t\t\t\t\'entries\',\n\t\t\t\t\'RV Detail\',\n\t\t\t\t[// Here specify the table columns to be displayed\n\t\t\t\t\t\'SR\', \'item_name\', \'description\', \'qty\', \'stock_uom\',\n\t\t\t\t\t\'export_rate\', \'export_amount\'\n\t\t\t\t],\n\t\t\t\t[// Here specify the labels of column headings\n\t\t\t\t\t\'Sr\', \'Item Name\', \'Description\', \'Qty\',\n\t\t\t\t\t\'UoM\', \'Basic Rate\', \'Amount\'\n\t\t\t\t],\n\t\t\t\t[// Here specify the column widths\n\t\t\t\t\t\'3%\', \'20%\', \'37%\', \'5%\',\n\t\t\t\t\t\'5%\', \'15%\', \'15%\'\n\t\t\t\t],\n\t\t\t\tnull,\n\t\t\t\tnull,\n\t\t\t\t{\n\t\t\t\t\t\'description\' : function(data_row) {\n\t\t\t\t\t\tif(data_row.adj_rate) {\n\t\t\t\t\t\t\tvar to_append = \'<div style="padding-left: 15px;"><i>Discount: \' + \n\t\t\t\t\t\t\t\tdata_row.adj_rate + \'%</i></div>\';\n\t\t\t\t\t\t\tif(data_row.description.indexOf(to_append)==-1) {\n\t\t\t\t\t\t\t\treturn data_row.description + to_append;\n\t\t\t\t\t\t\t} else { return data_row.description; }\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\treturn data_row.description;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t);\n\n\t\t\t// This code takes care of page breaks\n\t\t\tif(table.appendChild) {\n\t\t\t\tout = table.innerHTML;\n\t\t\t} else {\n\t\t\t\tout = \'\';\n\t\t\t\tfor(var i=0; i < (table.length-1); i++) {\n\t\t\t\t\tout += table[i].innerHTML + \n\t\t\t\t\t\t\'<div style = "page-break-after: always;" \\\n\t\t\t\t\t\tclass = "page_break"></div>\\\n\t\t\t\t\t\t<div class="page-settings"></div>\';\n\t\t\t\t}\n\t\t\t\tout += table[table.length-1].innerHTML;\n\t\t\t}\n\t\t\treturn out;\n\t\t},\n\n\n\t\tprint_other_charges: function(parent) {\n\t\t\tvar oc = getchildren(\'RV Tax Detail\', doc.name, \'other_charges\');\n\t\t\tvar rows = \'<table width=100%>\\n\';\n\t\t\tfor(var i=0; i<oc.length; i++) {\n\t\t\t\trows +=\n\t\t\t\t\t\'<tr>\\n\' +\n\t\t\t\t\t\t\'\\t<td>\' + oc[i].description + \'</td>\\n\' +\n\t\t\t\t\t\t\'\\t<td></td>\\n\' +\n\t\t\t\t\t\t\'\\t<td width=38%>\' + fmt_money(oc[i].tax_amount) + \'</td>\\n\' +\n\t\t\t\t\t\'</tr>\\n\';\n\t\t\t}\n\t\t\treturn rows + \'</table>\\n\';\n\t\t}\n\t};\n</script>\n\n\n<!-- Page Layout Settings -->\n<div class=\'common page-header\'>\n\t<!-- \n\t\tPage Header will contain\n\t\t\t+ table 1\n\t\t\t\t+ table 1a\n\t\t\t\t\t- Name\n\t\t\t\t\t- Address\n\t\t\t\t\t- Contact\n\t\t\t\t\t- Mobile No\n\t\t\t\t+ table 1b\n\t\t\t\t\t- Voucher Date\n\t\t\t\t\t- Due Date\n\t-->\n\t<table class=\'header-table\' cellspacing=0>\n\t\t<thead>\n\t\t\t<tr><td colspan=2><div><script>\'<h1>\' + (doc.select_print_heading || \'Invoice\') + \'</h1>\'</script></div></td></tr>\n\t\t\t<tr><td colspan=2><div style="height:15px"></div></td></tr>\n\t\t</thead>\n\t\t<tbody>\n\t\t\t<tr>\n\t\t\t\t<td width=60%><table width=100% cellspacing=0><tbody>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td width=39%><b>Name</b></td>\n\t\t\t\t\t\t<td><script>doc.customer_name</script></td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td><b>Address</b></td>\n\t\t\t\t\t\t<td><script>replace_newlines(doc.address_display)</script></td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td><b>Contact</b></td>\n\t\t\t\t\t\t<td><script>doc.contact_display</script></td>\n\t\t\t\t\t</tr>\n\t\t\t\t</tbody></table></td>\n\t\t\t\t<td><table width=100% cellspacing=0><tbody>\n\t\t\t\t\t<tr class=\'imp-details\'>\n\t\t\t\t\t\t<td><b>Invoice No.</b></td>\n\t\t\t\t\t\t<td><script>cur_frm.docname</script></td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td width=40%><b>Invoice Date</b></td>\n\t\t\t\t\t\t<td><script>date.str_to_user(doc.voucher_date)</script></td>\n\t\t\t\t\t<tr>\t\t\t\t\t\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td><b>Due Date</b></td>\n\t\t\t\t\t\t<td><script>date.str_to_user(doc.due_date)</script></td>\n\t\t\t\t\t<tr>\t\t\t\t\t\n\t\t\t\t</tbody></table></td>\n\t\t\t</tr>\n\t\t</tbody>\n\t\t<tfoot>\n\t\t\n\t\t</tfoot>\n\t</table>\n</div>\n<div class=\'common page-body\'>\n\t<!-- \n\t\tPage Body will contain\n\t\t\t+ table 2\n\t\t\t\t- Sales Invoice Data\n\t-->\n\t<script>si_std.print_item_table()</script>\n</div>\n<div class=\'common page-footer\'>\n\t<!-- \n\t\tPage Footer will contain\n\t\t\t+ table 3\n\t\t\t\t- Terms and Conditions\n\t\t\t\t- Total Rounded Amount Calculation\n\t\t\t\t- Total Rounded Amount in Words\n\t-->\n\t<table class=\'footer-table\' width=100% cellspacing=0>\n\t\t<thead>\n\t\t\t\n\t\t</thead>\n\t\t<tbody>\n\t\t\t<tr>\n\t\t\t\t<td width=60% style=\'padding-right: 10px;\'>\n\t\t\t\t\t<b>Terms, Conditions & Other Information:</b><br />\n\t\t\t\t\t<script>doc.terms</script>\n\t\t\t\t</td>\n\t\t\t\t<td>\n\t\t\t\t\t<table cellspacing=0 width=100%><tbody>\n\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t<td>Net Total</td>\n\t\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t\t<td width=38%><script>\n\t\t\t\t\t\t\t\tfmt_money(doc.net_total/doc.conversion_rate)\n\t\t\t\t\t\t\t</script></td>\n\t\t\t\t\t\t</tr>\n\t\t\t\t\t\t<tr><td colspan=3><script>si_std.print_other_charges()</script></td></tr>\n\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t<td>Grand Total</td>\n\t\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t\t<td><script>\n\t\t\t\t\t\t\t\tfmt_money(doc.grand_total_export)\n\t\t\t\t\t\t\t</script></td>\n\t\t\t\t\t\t</tr>\n\t\t\t\t\t\t<tr style=\'font-weight: bold\' class=\'imp-details\'>\n\t\t\t\t\t\t\t<td>Rounded Total</td>\n\t\t\t\t\t\t\t<td><script>doc.currency</script></td>\n\t\t\t\t\t\t\t<td><script>\n\t\t\t\t\t\t\t\tfmt_money(doc.rounded_total_export)\n\t\t\t\t\t\t\t</script></td>\n\t\t\t\t\t\t</tr>\n\t\t\t\t\t</tbody></table>\n\t\t\t\t\t<br /><b>In Words</b><br />\n\t\t\t\t\t<i><script>doc.in_words_export</script></i>\n\t\t\t\t</td>\n\t\t\t</tr>\t\t\n\t\t</tbody>\n\t\t<tfoot>\n\t\t\t<tr><td colspan=2><div></div></td><tr>\n\t\t</tfoot>\n\t</table>\n</div>\n',
+ 'module': 'Accounts',
+ 'name': '__common__',
+ 'standard': 'Yes'
+ },
+
+ # Print Format, Sales Invoice Modern
+ {
+ 'doctype': 'Print Format',
+ 'name': 'Sales Invoice Modern'
+ }
+]
\ No newline at end of file
diff --git a/erpnext/accounts/Print Format/Sales Invoice Spartan/Sales Invoice Spartan.txt b/erpnext/accounts/Print Format/Sales Invoice Spartan/Sales Invoice Spartan.txt
new file mode 100644
index 0000000..c24cde5
--- /dev/null
+++ b/erpnext/accounts/Print Format/Sales Invoice Spartan/Sales Invoice Spartan.txt
@@ -0,0 +1,28 @@
+# Print Format, Sales Invoice Spartan
+[
+
+ # These values are common in all dictionaries
+ {
+ 'creation': '2011-12-13 11:02:59',
+ 'docstatus': 0,
+ 'modified': '2011-12-13 13:39:55',
+ 'modified_by': 'Administrator',
+ 'owner': 'Administrator'
+ },
+
+ # These values are common for all Print Format
+ {
+ 'doc_type': 'Receivable Voucher',
+ 'doctype': 'Print Format',
+ 'html': '<!--\n\tSample Print Format for ERPNext\n\tPlease use at your own discretion\n\tFor suggestions and contributions:\n\t\thttps://github.com/webnotes/erpnext-print-templates\n\n\tFreely usable under MIT license\n-->\n\n<!-- Style Settings -->\n<style>\n\t/*\n\t\tcommon style for whole page\n\t\tThis should include:\n\t\t+ page size related settings\n\t\t+ font family settings\n\t\t+ line spacing settings\n\t*/\n\t@media screen {\n\t\tbody {\n\t\t\twidth: 8.3in;\n\t\t}\n\t}\n\n\thtml, body, div, span, td {\n\t\tfont-family: "Arial", sans-serif;\n\t\tfont-size: 12px;\n\t}\n\n\tbody {\n\t\tpadding: 10px;\n\t\tmargin: auto;\n\t\tfont-size: 12px;\n\t\tline-height: 150%;\n\t}\n\n\t.common {\n\t\tfont-family: "Arial", sans-serif !important;\n\t\tfont-size: 12px;\n\t\tpadding: 0px;\n\t}\n\n\ttable {\n\t\twidth: 100% !important;\n\t\tvertical-align: top;\n\t}\n\n\ttable td {\n\t\tpadding: 2px 0px;\n\t}\n\n\ttable, td {\n\t\tborder-collapse: collapse !important;\n\t\tpadding: 0px;\n\t\tmargin: 0px !important;\n\t}\n\t\n\ttable h1, h2, h3, h4, h5, h6 {\n\t\tpadding: 0px;\n\t\tmargin: 0px;\n\t}\n\n\ttable.header-table td {\n\t\tvertical-align: top;\n\t}\n\n\ttable.header-table h3 {\n\t\tcolor: gray;\n\t}\n\n\ttable.header-table thead td {\n\t\tpadding: 5px;\n\t}\n\n\ttable.header-table > thead,\n\ttable.header-table > tbody > tr > td,\n\ttable.footer-table > tbody > tr > td {\n\t\tborder: 1px solid black;\n\t\tpadding: 5px;\n\t}\n\n\ttable.footer-table > tbody,\n\ttable.header-table > thead {\n\t\tborder-bottom: 3px solid black;\n\t}\n\n\ttable.header-table > thead {\n\t\tborder-top: 3px solid black;\n\t}\n\n\tdiv.page-body table td:nth-child(6),\n\tdiv.page-body table td:nth-child(7) {\n\t\ttext-align: right;\n\t}\n\n\tdiv.page-body td {\n\t\tbackground-color: white !important;\n\t\tborder: 1px solid black !important;\n\t}\n\n\ttable.footer-table td {\n\t\tvertical-align: top;\n\t}\n\n\ttable.footer-table td table td:nth-child(2),\n\ttable.footer-table td table td:nth-child(3) {\n\t\ttext-align: right;\n\t}\n</style>\n\n\n<!-- Javascript -->\n<script>\n\tsi_std = {\n\t\tprint_item_table: function() {\n\t\t\tvar table = print_table(\n\t\t\t\t\'Receivable Voucher\',\n\t\t\t\tdoc.name,\n\t\t\t\t\'entries\',\n\t\t\t\t\'RV Detail\',\n\t\t\t\t[// Here specify the table columns to be displayed\n\t\t\t\t\t\'SR\', \'item_name\', \'description\', \'qty\', \'stock_uom\',\n\t\t\t\t\t\'export_rate\', \'export_amount\'\n\t\t\t\t],\n\t\t\t\t[// Here specify the labels of column headings\n\t\t\t\t\t\'Sr\', \'Item Name\', \'Description\', \'Qty\',\n\t\t\t\t\t\'UoM\', \'Basic Rate\', \'Amount\'\n\t\t\t\t],\n\t\t\t\t[// Here specify the column widths\n\t\t\t\t\t\'3%\', \'20%\', \'37%\', \'5%\',\n\t\t\t\t\t\'5%\', \'15%\', \'15%\'\n\t\t\t\t],\n\t\t\t\tnull,\n\t\t\t\tnull,\n\t\t\t\t{\n\t\t\t\t\t\'description\' : function(data_row) {\n\t\t\t\t\t\tif(data_row.adj_rate) {\n\t\t\t\t\t\t\tvar to_append = \'<div style="padding-left: 15px;"><i>Discount: \' + \n\t\t\t\t\t\t\t\tdata_row.adj_rate + \'%</i></div>\';\n\t\t\t\t\t\t\tif(data_row.description.indexOf(to_append)==-1) {\n\t\t\t\t\t\t\t\treturn data_row.description + to_append;\n\t\t\t\t\t\t\t} else { return data_row.description; }\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\treturn data_row.description;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t);\n\n\t\t\t// This code takes care of page breaks\n\t\t\tif(table.appendChild) {\n\t\t\t\tout = table.innerHTML;\n\t\t\t} else {\n\t\t\t\tout = \'\';\n\t\t\t\tfor(var i=0; i < (table.length-1); i++) {\n\t\t\t\t\tout += table[i].innerHTML + \n\t\t\t\t\t\t\'<div style = "page-break-after: always;" \\\n\t\t\t\t\t\tclass = "page_break"></div>\\\n\t\t\t\t\t\t<div class="page-settings"></div>\';\n\t\t\t\t}\n\t\t\t\tout += table[table.length-1].innerHTML;\n\t\t\t}\n\t\t\treturn out;\n\t\t},\n\n\n\t\tprint_other_charges: function(parent) {\n\t\t\tvar oc = getchildren(\'RV Tax Detail\', doc.name, \'other_charges\');\n\t\t\tvar rows = \'<table width=100%>\\n\';\n\t\t\tfor(var i=0; i<oc.length; i++) {\n\t\t\t\trows +=\n\t\t\t\t\t\'<tr>\\n\' +\n\t\t\t\t\t\t\'\\t<td>\' + oc[i].description + \'</td>\\n\' +\n\t\t\t\t\t\t\'\\t<td></td>\\n\' +\n\t\t\t\t\t\t\'\\t<td width=38%>\' + fmt_money(oc[i].tax_amount) + \'</td>\\n\' +\n\t\t\t\t\t\'</tr>\\n\';\n\t\t\t}\n\t\t\treturn rows + \'</table>\\n\';\n\t\t}\n\t};\n</script>\n\n\n<!-- Page Layout Settings -->\n<div class=\'common page-header\'>\n\t<!-- \n\t\tPage Header will contain\n\t\t\t+ table 1\n\t\t\t\t+ table 1a\n\t\t\t\t\t- Name\n\t\t\t\t\t- Address\n\t\t\t\t\t- Contact\n\t\t\t\t\t- Mobile No\n\t\t\t\t+ table 1b\n\t\t\t\t\t- Voucher Date\n\t\t\t\t\t- Due Date\n\t-->\n\t<table class=\'header-table\' cellspacing=0>\n\t\t<thead>\n\t\t\t<tr><td colspan=2><script>\'<h1>\' + (doc.select_print_heading || \'Invoice\') + \'</h1>\'</script></td></tr>\n\t\t\t<tr><td colspan=2><h3><script>cur_frm.docname</script></h3></td></tr>\n\t\t</thead>\n\t\t<tbody>\n\t\t\t<tr>\n\t\t\t\t<td width=60%><table width=100% cellspacing=0><tbody>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td width=39%><b>Name</b></td>\n\t\t\t\t\t\t<td><script>doc.customer_name</script></td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td><b>Address</b></td>\n\t\t\t\t\t\t<td><script>replace_newlines(doc.address_display)</script></td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td><b>Contact</b></td>\n\t\t\t\t\t\t<td><script>doc.contact_display</script></td>\n\t\t\t\t\t</tr>\n\t\t\t\t</tbody></table></td>\n\t\t\t\t<td><table width=100% cellspacing=0><tbody>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td width=40%><b>Invoice Date</b></td>\n\t\t\t\t\t\t<td><script>date.str_to_user(doc.voucher_date)</script></td>\n\t\t\t\t\t<tr>\t\t\t\t\t\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td><b>Due Date</b></td>\n\t\t\t\t\t\t<td><script>date.str_to_user(doc.due_date)</script></td>\n\t\t\t\t\t<tr>\t\t\t\t\t\n\t\t\t\t</tbody></table></td>\n\t\t\t</tr>\n\t\t</tbody>\n\t\t<tfoot>\n\t\t\n\t\t</tfoot>\n\t</table>\n</div>\n<div class=\'common page-body\'>\n\t<!-- \n\t\tPage Body will contain\n\t\t\t+ table 2\n\t\t\t\t- Sales Invoice Data\n\t-->\n\t<script>si_std.print_item_table()</script>\n</div>\n<div class=\'common page-footer\'>\n\t<!-- \n\t\tPage Footer will contain\n\t\t\t+ table 3\n\t\t\t\t- Terms and Conditions\n\t\t\t\t- Total Rounded Amount Calculation\n\t\t\t\t- Total Rounded Amount in Words\n\t-->\n\t<table class=\'footer-table\' width=100% cellspacing=0>\n\t\t<thead>\n\t\t\t\n\t\t</thead>\n\t\t<tbody>\n\t\t\t<tr>\n\t\t\t\t<td width=60% style=\'padding-right: 10px;\'>\n\t\t\t\t\t<b>Terms, Conditions & Other Information:</b><br />\n\t\t\t\t\t<script>doc.terms</script>\n\t\t\t\t</td>\n\t\t\t\t<td>\n\t\t\t\t\t<table cellspacing=0 width=100%><tbody>\n\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t<td>Net Total</td>\n\t\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t\t<td width=38%><script>\n\t\t\t\t\t\t\t\tfmt_money(doc.net_total/doc.conversion_rate)\n\t\t\t\t\t\t\t</script></td>\n\t\t\t\t\t\t</tr>\n\t\t\t\t\t\t<tr><td colspan=3><script>si_std.print_other_charges()</script></td></tr>\n\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t<td>Grand Total</td>\n\t\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t\t<td><script>\n\t\t\t\t\t\t\t\tfmt_money(doc.grand_total_export)\n\t\t\t\t\t\t\t</script></td>\n\t\t\t\t\t\t</tr>\n\t\t\t\t\t\t<tr style=\'font-weight: bold\'>\n\t\t\t\t\t\t\t<td>Rounded Total</td>\n\t\t\t\t\t\t\t<td><script>doc.currency</script></td>\n\t\t\t\t\t\t\t<td><script>\n\t\t\t\t\t\t\t\tfmt_money(doc.rounded_total_export)\n\t\t\t\t\t\t\t</script></td>\n\t\t\t\t\t\t</tr>\n\t\t\t\t\t</tbody></table>\n\t\t\t\t\t<br /><b>In Words</b><br />\n\t\t\t\t\t<i><script>doc.in_words_export</script></i>\n\t\t\t\t</td>\n\t\t\t</tr>\t\t\n\t\t</tbody>\n\t\t<tfoot>\n\t\t\n\t\t</tfoot>\n\t</table>\n</div>\n',
+ 'module': 'Accounts',
+ 'name': '__common__',
+ 'standard': 'Yes'
+ },
+
+ # Print Format, Sales Invoice Spartan
+ {
+ 'doctype': 'Print Format',
+ 'name': 'Sales Invoice Spartan'
+ }
+]
\ No newline at end of file
diff --git a/erpnext/accounts/doctype/c_form/__init__.py b/erpnext/accounts/doctype/c_form/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/accounts/doctype/c_form/__init__.py
diff --git a/erpnext/accounts/doctype/c_form/c_form.js b/erpnext/accounts/doctype/c_form/c_form.js
new file mode 100644
index 0000000..6629de6
--- /dev/null
+++ b/erpnext/accounts/doctype/c_form/c_form.js
@@ -0,0 +1,10 @@
+//c-form js file
+// -----------------------------
+cur_frm.fields_dict.invoice_details.grid.get_field("invoice_no").get_query = function(doc) {
+ return 'SELECT `tabReceivable Voucher`.`name` FROM `tabReceivable Voucher` WHERE `tabReceivable Voucher`.`company` = "' +doc.company+'" AND `tabReceivable Voucher`.%(key)s LIKE "%s" AND `tabReceivable Voucher`.`customer` = "' + doc.customer + '" AND `tabReceivable Voucher`.`docstatus` = 1 and `tabReceivable Voucher`.`c_form_applicable` = "Yes" and ifnull(`tabReceivable Voucher`.c_form_no, "") = "" ORDER BY `tabReceivable Voucher`.`name` ASC LIMIT 50';
+}
+
+cur_frm.cscript.invoice_no = function(doc, cdt, cdn) {
+ var d = locals[cdt][cdn];
+ get_server_fields('get_invoice_details', d.invoice_no, 'invoice_details', doc, cdt, cdn, 1);
+}
diff --git a/erpnext/accounts/doctype/c_form/c_form.py b/erpnext/accounts/doctype/c_form/c_form.py
new file mode 100644
index 0000000..7228f11
--- /dev/null
+++ b/erpnext/accounts/doctype/c_form/c_form.py
@@ -0,0 +1,61 @@
+# Please edit this list and import only required elements
+import webnotes
+from webnotes.utils import add_days, cint, cstr, date_diff, default_fields, flt, getdate, now, nowdate
+from webnotes.model.doc import Document, addchild, removechild, getchildren, make_autoname, SuperDocType
+from webnotes.model.doclist import getlist, copy_doclist
+from webnotes.model.code import get_obj
+from webnotes import msgprint, errprint
+
+sql = webnotes.conn.sql
+# -----------------------------------------------------------------------------------------
+
+
+class DocType:
+ def __init__(self,d,dl):
+ self.doc, self.doclist = d,dl
+
+ def autoname(self):
+ self.doc.name = make_autoname(self.doc.naming_series + '.#####')
+
+
+ def on_update(self):
+ """ Update C-Form No on invoices"""
+
+ if len(getlist(self.doclist, 'invoice_details')):
+ inv = "'" + "', '".join([d.invoice_no for d in getlist(self.doclist, 'invoice_details')]) + "'"
+ sql("""update `tabReceivable Voucher` set c_form_no = '%s', modified ='%s'
+ where name in (%s)"""%(self.doc.name, self.doc.modified, inv))
+ sql("""update `tabReceivable Voucher` set c_form_no = '', modified = %s where name not
+ in (%s) and ifnull(c_form_no, '') = %s""", (self.doc.modified, self.doc.name, inv))
+ else:
+ msgprint("Please enter atleast 1 invoice in the table below", raise_exception=1)
+
+
+ def get_invoice_details(self, invoice_no):
+ """ Pull details from invoices for referrence """
+
+ inv = sql("""select posting_date, territory, net_total, grand_total from
+ `tabReceivable Voucher` where name = %s""", invoice_no)
+ ret = {
+ 'invoice_date' : inv and getdate(inv[0][0]).strftime('%Y-%m-%d') or '',
+ 'territory' : inv and inv[0][1] or '',
+ 'net_total' : inv and flt(inv[0][2]) or '',
+ 'grand_total' : inv and flt(inv[0][3]) or ''
+ }
+ return ret
+
+
+ def validate_invoice(self):
+ """Validate invoice that c-form is applicable and no other c-form is
+ received for that"""
+
+ for d in getlist(self.doclist, 'invoice_details'):
+ inv = sql("""select c_form_applicable, c_form_no from
+ `tabReceivable Voucher` where name = %s""", invoice_no)
+ if not inv:
+ msgprint("Invoice: %s is not exists in the system, please check." % d.invoice_no, raise_exception=1)
+ elif inv[0][0] != 'Yes':
+ msgprint("C-form is not applicable for Invoice: %s" % d.invoice_no, raise_exception=1)
+ elif inv[0][1] and inv[0][1] != self.doc.name:
+ msgprint("""Invoice %s is tagged in another C-form: %s. \nIf you want to change C-form no for this invoice,
+ please remove invoice no from the previous c-form and then try again""" % (d.invoice_no, inv[0][1]), raise_exception=1)
diff --git a/erpnext/accounts/doctype/c_form/c_form.txt b/erpnext/accounts/doctype/c_form/c_form.txt
new file mode 100644
index 0000000..987bc9a
--- /dev/null
+++ b/erpnext/accounts/doctype/c_form/c_form.txt
@@ -0,0 +1,190 @@
+# DocType, C-Form
+[
+
+ # These values are common in all dictionaries
+ {
+ 'creation': '2011-12-07 16:16:16',
+ 'docstatus': 0,
+ 'modified': '2011-12-07 17:50:17',
+ 'modified_by': 'Administrator',
+ 'owner': 'Administrator'
+ },
+
+ # These values are common for all DocType
+ {
+ '_last_update': '1323255350',
+ 'colour': 'White:FFF',
+ 'doctype': 'DocType',
+ 'module': 'Accounts',
+ 'name': '__common__',
+ 'section_style': 'Simple',
+ 'show_in_menu': 0,
+ 'version': 11
+ },
+
+ # These values are common for all DocField
+ {
+ 'doctype': 'DocField',
+ 'name': '__common__',
+ 'parent': 'C-Form',
+ 'parentfield': 'fields',
+ 'parenttype': 'DocType',
+ 'permlevel': 0
+ },
+
+ # These values are common for all DocPerm
+ {
+ 'doctype': 'DocPerm',
+ 'name': '__common__',
+ 'parent': 'C-Form',
+ 'parentfield': 'permissions',
+ 'parenttype': 'DocType',
+ 'read': 1
+ },
+
+ # DocType, C-Form
+ {
+ 'doctype': 'DocType',
+ 'name': 'C-Form'
+ },
+
+ # DocPerm
+ {
+ 'create': 1,
+ 'doctype': 'DocPerm',
+ 'permlevel': 0,
+ 'role': 'Accounts User',
+ 'write': 1
+ },
+
+ # DocPerm
+ {
+ 'create': 1,
+ 'doctype': 'DocPerm',
+ 'permlevel': 0,
+ 'role': 'Accounts Manager',
+ 'submit': 0,
+ 'write': 1
+ },
+
+ # DocPerm
+ {
+ 'doctype': 'DocPerm',
+ 'permlevel': 1,
+ 'role': 'All'
+ },
+
+ # DocField
+ {
+ 'doctype': 'DocField',
+ 'fieldtype': 'Column Break',
+ 'width': '50%'
+ },
+
+ # DocField
+ {
+ 'doctype': 'DocField',
+ 'fieldname': 'naming_series',
+ 'fieldtype': 'Select',
+ 'label': 'Series',
+ 'options': '\nC-FORM/',
+ 'reqd': 1
+ },
+
+ # DocField
+ {
+ 'doctype': 'DocField',
+ 'fieldname': 'c_form_no',
+ 'fieldtype': 'Data',
+ 'label': 'C-Form No',
+ 'reqd': 1
+ },
+
+ # DocField
+ {
+ 'doctype': 'DocField',
+ 'fieldname': 'received_date',
+ 'fieldtype': 'Date',
+ 'label': 'Received Date',
+ 'reqd': 1
+ },
+
+ # DocField
+ {
+ 'doctype': 'DocField',
+ 'fieldname': 'customer',
+ 'fieldtype': 'Link',
+ 'label': 'Customer',
+ 'options': 'Customer',
+ 'reqd': 1
+ },
+
+ # DocField
+ {
+ 'doctype': 'DocField',
+ 'fieldtype': 'Column Break',
+ 'width': '50%'
+ },
+
+ # DocField
+ {
+ 'doctype': 'DocField',
+ 'fieldname': 'company',
+ 'fieldtype': 'Select',
+ 'label': 'Company',
+ 'options': 'link:Company'
+ },
+
+ # DocField
+ {
+ 'doctype': 'DocField',
+ 'fieldname': 'fiscal_year',
+ 'fieldtype': 'Select',
+ 'label': 'Fiscal Year',
+ 'options': 'link:Fiscal Year',
+ 'reqd': 1
+ },
+
+ # DocField
+ {
+ 'doctype': 'DocField',
+ 'fieldname': 'quarter',
+ 'fieldtype': 'Select',
+ 'label': 'Quarter',
+ 'options': '\nI\nII\nIII\nIV'
+ },
+
+ # DocField
+ {
+ 'doctype': 'DocField',
+ 'fieldname': 'total_amount',
+ 'fieldtype': 'Currency',
+ 'label': 'Total Amount',
+ 'reqd': 1
+ },
+
+ # DocField
+ {
+ 'doctype': 'DocField',
+ 'fieldname': 'state',
+ 'fieldtype': 'Select',
+ 'label': 'State',
+ 'options': "link:State\ncountry='India'",
+ 'reqd': 1
+ },
+
+ # DocField
+ {
+ 'doctype': 'DocField',
+ 'fieldtype': 'Section Break'
+ },
+
+ # DocField
+ {
+ 'doctype': 'DocField',
+ 'fieldname': 'invoice_details',
+ 'fieldtype': 'Table',
+ 'label': 'Invoice Details',
+ 'options': 'C-Form Invoice Detail'
+ }
+]
\ No newline at end of file
diff --git a/erpnext/accounts/doctype/c_form_invoice_detail/__init__.py b/erpnext/accounts/doctype/c_form_invoice_detail/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/accounts/doctype/c_form_invoice_detail/__init__.py
diff --git a/erpnext/accounts/doctype/c_form_invoice_detail/c_form_invoice_detail.txt b/erpnext/accounts/doctype/c_form_invoice_detail/c_form_invoice_detail.txt
new file mode 100644
index 0000000..d6be6c0d
--- /dev/null
+++ b/erpnext/accounts/doctype/c_form_invoice_detail/c_form_invoice_detail.txt
@@ -0,0 +1,91 @@
+# DocType, C-Form Invoice Detail
+[
+
+ # These values are common in all dictionaries
+ {
+ 'creation': '2011-12-07 16:15:39',
+ 'docstatus': 0,
+ 'modified': '2011-12-07 16:21:55',
+ 'modified_by': 'Administrator',
+ 'owner': 'Administrator'
+ },
+
+ # These values are common for all DocType
+ {
+ 'colour': 'White:FFF',
+ 'doctype': 'DocType',
+ 'istable': 1,
+ 'module': 'Accounts',
+ 'name': '__common__',
+ 'section_style': 'Simple',
+ 'show_in_menu': 0,
+ 'version': 5
+ },
+
+ # These values are common for all DocField
+ {
+ 'doctype': 'DocField',
+ 'name': '__common__',
+ 'parent': 'C-Form Invoice Detail',
+ 'parentfield': 'fields',
+ 'parenttype': 'DocType'
+ },
+
+ # DocType, C-Form Invoice Detail
+ {
+ 'doctype': 'DocType',
+ 'name': 'C-Form Invoice Detail'
+ },
+
+ # DocField
+ {
+ 'doctype': 'DocField',
+ 'fieldname': 'invoice_no',
+ 'fieldtype': 'Link',
+ 'label': 'Invoice No',
+ 'options': 'Receivable Voucher',
+ 'permlevel': 0,
+ 'width': '160px'
+ },
+
+ # DocField
+ {
+ 'doctype': 'DocField',
+ 'fieldname': 'invoice_date',
+ 'fieldtype': 'Date',
+ 'label': 'Invoice Date',
+ 'permlevel': 1,
+ 'width': '120px'
+ },
+
+ # DocField
+ {
+ 'doctype': 'DocField',
+ 'fieldname': 'territory',
+ 'fieldtype': 'Link',
+ 'label': 'Territory',
+ 'options': 'Territory',
+ 'permlevel': 1,
+ 'width': '120px'
+ },
+
+ # DocField
+ {
+ 'doctype': 'DocField',
+ 'fieldname': 'net_total',
+ 'fieldtype': 'Currency',
+ 'label': 'Net Total',
+ 'permlevel': 1,
+ 'width': '120px'
+ },
+
+ # DocField
+ {
+ 'doctype': 'DocField',
+ 'fieldname': 'grand_total',
+ 'fieldtype': 'Currency',
+ 'label': 'Grand Total',
+ 'permlevel': 1,
+ 'width': '120px'
+ }
+]
\ No newline at end of file
diff --git a/erpnext/accounts/doctype/gl_control/gl_control.py b/erpnext/accounts/doctype/gl_control/gl_control.py
index 44a9e8d..bab8626 100644
--- a/erpnext/accounts/doctype/gl_control/gl_control.py
+++ b/erpnext/accounts/doctype/gl_control/gl_control.py
@@ -4,8 +4,8 @@
from webnotes.utils import add_days, add_months, add_years, cint, cstr, date_diff, default_fields, flt, fmt_money, formatdate, generate_hash, getTraceback, get_defaults, get_first_day, get_last_day, getdate, has_common, month_name, now, nowdate, replace_newlines, sendmail, set_default, str_esc_quote, user_format, validate_email_add
from webnotes.model import db_exists
from webnotes.model.doc import Document, addchild, removechild, getchildren, make_autoname, SuperDocType
-from webnotes.model.doclist import getlist, copy_doclist
-from webnotes.model.code import get_obj, get_server_obj, run_server_obj, updatedb, check_syntax
+from webnotes.model.doclist import getlist, copy_doclist, clone
+from webnotes.model.code import get_obj
from webnotes import session, form, is_testing, msgprint, errprint
sql = webnotes.conn.sql
@@ -24,14 +24,8 @@
# Get Company List
# ----------------
def get_companies(self,arg=''):
- #d = get_defaults()
ret = sql("select name, abbr from tabCompany where docstatus != 2")
- #pl = {}
- #for r in ret:
- # inc = get_value('Account','Income - '+r[1], 'balance')
- # exp = get_value('Account','Expenses - '+r[1], 'balance')
- # pl[r[0]] = flt(flt(inc) - flt(exp))
- return {'cl':[r[0] for r in ret]}#, 'pl':pl}
+ return {'cl':[r[0] for r in ret]}
def get_company_currency(self,arg=''):
dcc = TransactionBase().get_company_currency(arg)
@@ -506,3 +500,95 @@
for a in set(ac_list):
fy_obj.repost(a)
+
+def manage_recurring_invoices():
+ """
+ Create recurring invoices on specific date by copying the original one
+ and notify the concerned people
+ """
+ rv = sql("""select name, recurring_id from `tabReceivable Voucher` where ifnull(convert_into_recurring_invoice, 0) = 1
+ and next_date = %s and next_date <= end_date order by next_date desc""", nowdate())
+ for d in rv:
+ if not sql("""select name from `tabReceivable Voucher` where posting_date = %s and recurring_id = %s""", (nowdate(), d[1])):
+ prev_rv = get_obj('Receivable Voucher', d[0], with_children=1)
+ new_rv = create_new_invoice(prev_rv)
+
+ send_notification(new_rv)
+
+
+def create_new_invoice(prev_rv):
+ # clone rv
+ new_rv = clone(prev_rv)
+
+ # update new rv
+
+ new_rv.doc.voucher_date = new_rv.doc.next_date
+ new_rv.doc.posting_date = new_rv.doc.next_date
+ new_rv.doc.aging_date = new_rv.doc.next_date
+ new_rv.doc.due_date = add_days(new_rv.doc.next_date, cint(date_diff(prev_rv.doc.due_date, prev_rv.doc.posting_date)))
+ new_rv.doc.save()
+
+ # submit and after submit
+ new_rv.submit()
+ new_rv.update_after_submit()
+
+ return new_rv
+
+
+def send_notification(new_rv):
+ """Notify concerned persons about recurring invoice generation"""
+ subject = "Invoice : " + new_rv.doc.name
+
+ com = new_rv.doc.company # get_value('Control Panel', '', 'letter_head')
+
+ hd = '''<div><h2>%s</h2></div>
+ <div><h3>Invoice: %s</h3></div>
+ <table cellspacing= "5" cellpadding="5" width = "100%%">
+ <tr>
+ <td width = "50%%"><b>Customer</b><br>%s<br>%s</td>
+ <td width = "50%%">Invoice Date: %s<br>Due Date: %s</td>
+ </tr>
+ </table>
+ ''' % (com, new_rv.doc.name, new_rv.doc.customer, new_rv.doc.address_display, new_rv.doc.posting_date, new_rv.doc.due_date)
+
+
+ tbl = '''<table border="1px solid #CCC" width="100%%" cellpadding="0px" cellspacing="0px">
+ <tr>
+ <td width = "15%%" bgcolor="#CCC" align="left"><b>Item</b></td>
+ <td width = "40%%" bgcolor="#CCC" align="left"><b>Description</b></td>
+ <td width = "15%%" bgcolor="#CCC" align="center"><b>Qty</b></td>
+ <td width = "15%%" bgcolor="#CCC" align="center"><b>Rate</b></td>
+ <td width = "15%%" bgcolor="#CCC" align="center"><b>Amount</b></td>
+ </tr>
+ '''
+ for d in getlist(new_rv.doclist, 'entries'):
+ tbl += '<tr><td>' + d.item_code +'</td><td>' + d.description+'</td><td>' + cstr(d.qty) +'</td><td>' + cstr(d.basic_rate) +'</td><td>' + cstr(d.amount) +'</td></tr>'
+ tbl += '</table>'
+
+ totals =''' <table cellspacing= "5" cellpadding="5" width = "100%%">
+ <tr>
+ <td width = "50%%"></td>
+ <td width = "50%%">
+ <table width = "100%%">
+ <tr>
+ <td width = "50%%">Net Total: </td><td>%s </td>
+ </tr><tr>
+ <td width = "50%%">Total Tax: </td><td>%s </td>
+ </tr><tr>
+ <td width = "50%%">Grand Total: </td><td>%s</td>
+ </tr><tr>
+ <td width = "50%%">In Words: </td><td>%s</td>
+ </tr>
+ </table>
+ </td>
+ </tr>
+ <tr><td>Terms:</td></tr>
+ <tr><td>%s</td></tr>
+ </table>
+ ''' % (new_rv.doc.net_total, new_rv.doc.total_tax,new_rv.doc.grand_total, new_rv.doc.in_words,new_rv.doc.terms)
+
+
+ msg = hd + tbl + totals
+ from webnotes.utils.email_lib import sendmail
+ sendmail(recipients = [new_rv.doc.email_notification_address], \
+ sender=new_rv.doc.owner, subject=subject, parts=[['text/plain', msg]])
diff --git a/erpnext/accounts/doctype/gl_entry/gl_entry.txt b/erpnext/accounts/doctype/gl_entry/gl_entry.txt
index 776cbb3..1d84e1d 100644
--- a/erpnext/accounts/doctype/gl_entry/gl_entry.txt
+++ b/erpnext/accounts/doctype/gl_entry/gl_entry.txt
@@ -5,24 +5,26 @@
{
'creation': '2010-08-08 17:09:03',
'docstatus': 0,
- 'modified': '2010-12-29 12:59:45',
- 'modified_by': 'umair@iwebnotes.com',
+ 'modified': '2011-11-24 15:03:45',
+ 'modified_by': 'Administrator',
'owner': 'Administrator'
},
# These values are common for all DocType
{
- '_last_update': '1309508838',
+ '_last_update': '1319016431',
'autoname': 'GL.#######',
'colour': 'White:FFF',
+ 'default_print_format': 'Standard',
'doctype': 'DocType',
+ 'in_create': 1,
'module': 'Accounts',
'name': '__common__',
'search_fields': 'voucher_no,account,posting_date,against_voucher',
'section_style': 'Simple',
'server_code_error': ' ',
'show_in_menu': 0,
- 'version': 101
+ 'version': 103
},
# These values are common for all DocField
@@ -68,7 +70,6 @@
'cancel': 0,
'create': 0,
'doctype': 'DocPerm',
- 'idx': 1,
'permlevel': 0,
'role': 'Accounts Manager',
'submit': 0,
@@ -78,7 +79,6 @@
# DocPerm
{
'doctype': 'DocPerm',
- 'idx': 2,
'permlevel': 0,
'role': 'System Manager'
},
@@ -89,7 +89,6 @@
'doctype': 'DocField',
'fieldname': 'posting_date',
'fieldtype': 'Date',
- 'idx': 1,
'in_filter': 1,
'label': 'Posting Date',
'oldfieldname': 'posting_date',
@@ -103,7 +102,6 @@
'doctype': 'DocField',
'fieldname': 'transaction_date',
'fieldtype': 'Date',
- 'idx': 2,
'label': 'Transaction Date',
'oldfieldname': 'transaction_date',
'oldfieldtype': 'Date'
@@ -114,7 +112,6 @@
'doctype': 'DocField',
'fieldname': 'aging_date',
'fieldtype': 'Date',
- 'idx': 3,
'in_filter': 1,
'label': 'Aging Date',
'oldfieldname': 'aging_date',
@@ -127,7 +124,6 @@
'doctype': 'DocField',
'fieldname': 'account',
'fieldtype': 'Link',
- 'idx': 4,
'in_filter': 1,
'label': 'Account',
'oldfieldname': 'account',
@@ -141,7 +137,6 @@
'doctype': 'DocField',
'fieldname': 'cost_center',
'fieldtype': 'Link',
- 'idx': 5,
'in_filter': 1,
'label': 'Cost Center',
'oldfieldname': 'cost_center',
@@ -155,7 +150,6 @@
'doctype': 'DocField',
'fieldname': 'debit',
'fieldtype': 'Currency',
- 'idx': 6,
'label': 'Debit Amt',
'oldfieldname': 'debit',
'oldfieldtype': 'Currency'
@@ -166,7 +160,6 @@
'doctype': 'DocField',
'fieldname': 'credit',
'fieldtype': 'Currency',
- 'idx': 7,
'label': 'Credit Amt',
'oldfieldname': 'credit',
'oldfieldtype': 'Currency'
@@ -177,7 +170,6 @@
'doctype': 'DocField',
'fieldname': 'against',
'fieldtype': 'Text',
- 'idx': 8,
'in_filter': 1,
'label': 'Against',
'oldfieldname': 'against',
@@ -189,7 +181,6 @@
'doctype': 'DocField',
'fieldname': 'against_voucher',
'fieldtype': 'Data',
- 'idx': 9,
'in_filter': 1,
'label': 'Against Voucher',
'oldfieldname': 'against_voucher',
@@ -202,7 +193,6 @@
'doctype': 'DocField',
'fieldname': 'against_voucher_type',
'fieldtype': 'Data',
- 'idx': 10,
'in_filter': 0,
'label': 'Against Voucher Type',
'oldfieldname': 'against_voucher_type',
@@ -215,7 +205,6 @@
'doctype': 'DocField',
'fieldname': 'voucher_type',
'fieldtype': 'Select',
- 'idx': 11,
'in_filter': 1,
'label': 'Voucher Type',
'oldfieldname': 'voucher_type',
@@ -229,7 +218,6 @@
'doctype': 'DocField',
'fieldname': 'voucher_no',
'fieldtype': 'Data',
- 'idx': 12,
'in_filter': 1,
'label': 'Voucher No',
'oldfieldname': 'voucher_no',
@@ -242,7 +230,6 @@
'doctype': 'DocField',
'fieldname': 'remarks',
'fieldtype': 'Text',
- 'idx': 13,
'in_filter': 1,
'label': 'Remarks',
'no_copy': 1,
@@ -256,7 +243,6 @@
'doctype': 'DocField',
'fieldname': 'is_cancelled',
'fieldtype': 'Select',
- 'idx': 14,
'in_filter': 1,
'label': 'Is Cancelled',
'oldfieldname': 'is_cancelled',
@@ -270,7 +256,6 @@
'doctype': 'DocField',
'fieldname': 'is_opening',
'fieldtype': 'Select',
- 'idx': 15,
'in_filter': 1,
'label': 'Is Opening',
'oldfieldname': 'is_opening',
@@ -284,7 +269,6 @@
'doctype': 'DocField',
'fieldname': 'is_advance',
'fieldtype': 'Select',
- 'idx': 16,
'in_filter': 0,
'label': 'Is Advance',
'oldfieldname': 'is_advance',
@@ -298,7 +282,6 @@
'doctype': 'DocField',
'fieldname': 'fiscal_year',
'fieldtype': 'Select',
- 'idx': 17,
'in_filter': 1,
'label': 'Fiscal Year',
'oldfieldname': 'fiscal_year',
@@ -312,7 +295,6 @@
'doctype': 'DocField',
'fieldname': 'company',
'fieldtype': 'Link',
- 'idx': 18,
'in_filter': 1,
'label': 'Company',
'oldfieldname': 'company',
diff --git a/erpnext/accounts/doctype/internal_reconciliation/internal_reconciliation.js b/erpnext/accounts/doctype/internal_reconciliation/internal_reconciliation.js
index bcd5c44..a5ec2b6 100644
--- a/erpnext/accounts/doctype/internal_reconciliation/internal_reconciliation.js
+++ b/erpnext/accounts/doctype/internal_reconciliation/internal_reconciliation.js
@@ -2,7 +2,6 @@
// --------------------
cur_frm.fields_dict.voucher_no.get_query = function(doc) {
-
if (!doc.account) msgprint("Please select Account first");
else {
return repl("select voucher_no, posting_date \
diff --git a/erpnext/accounts/doctype/internal_reconciliation/internal_reconciliation.py b/erpnext/accounts/doctype/internal_reconciliation/internal_reconciliation.py
index 7c34546..24a7db5 100644
--- a/erpnext/accounts/doctype/internal_reconciliation/internal_reconciliation.py
+++ b/erpnext/accounts/doctype/internal_reconciliation/internal_reconciliation.py
@@ -81,7 +81,7 @@
and ifnull(t2.against_voucher, '')='' and ifnull(t2.against_invoice, '')='' and ifnull(t2.against_jv, '')=''
and t2.%s > 0
%s
- group by t1.name
+ group by t1.name, t2.name
"""% ('%s', dc, cond), self.doc.account, as_dict=1)
return gle
@@ -112,6 +112,9 @@
2. split into multiple rows if partially adjusted, assign against voucher
3. submit payment voucher
"""
+ if not self.doc.voucher_no or not sql("select name from `tab%s` where name = %s" %(self.dt[self.doc.voucher_type], '%s'), self.doc.voucher_no):
+ msgprint("Please select valid Voucher No to proceed", raise_exception=1)
+
lst = []
for d in getlist(self.doclist, 'ir_payment_details'):
if d.selected and flt(d.amt_to_be_reconciled) > 0:
@@ -129,8 +132,7 @@
lst.append(args)
- if not sql("select name from `tab%s` where name = %s" %(self.dt[self.doc.voucher_type], '%s'), self.doc.voucher_no):
- msgprint("Please select valid Voucher No to proceed", raise_exception=1)
+
if lst:
get_obj('GL Control').reconcile_against_document(lst)
msgprint("Successfully reconciled.")
diff --git a/erpnext/accounts/doctype/payable_voucher/payable_voucher.js b/erpnext/accounts/doctype/payable_voucher/payable_voucher.js
index 06c2947..ce26865 100644
--- a/erpnext/accounts/doctype/payable_voucher/payable_voucher.js
+++ b/erpnext/accounts/doctype/payable_voucher/payable_voucher.js
@@ -52,7 +52,6 @@
//Supplier
cur_frm.cscript.supplier = function(doc,dt,dn) {
-
var callback = function(r,rt) {
var doc = locals[cur_frm.doctype][cur_frm.docname];
get_server_fields('get_credit_to','','',doc, dt, dn, 0, callback2);
@@ -67,7 +66,7 @@
get_server_fields('get_default_values', args, 'entries', doc, el[i].doctype, el[i].name, 1);
}
}
- cur_frm.cscript.calc_total(doc);
+ cur_frm.cscript.calc_amount(doc, 1);
}
if(doc.supplier) get_server_fields('get_default_supplier_address', JSON.stringify({supplier: doc.supplier}),'', doc, dt, dn, 1,callback);
@@ -78,13 +77,6 @@
if(doc.supplier) get_server_fields('get_supplier_address', JSON.stringify({supplier: doc.supplier, address: doc.supplier_address, contact: doc.contact_person}),'', doc, dt, dn, 1);
}
-cur_frm.fields_dict['supplier_address'].get_query = function(doc, cdt, cdn) {
- return 'SELECT name,address_line1,city FROM tabAddress WHERE supplier = "'+ doc.supplier +'" AND docstatus != 2 AND name LIKE "%s" ORDER BY name ASC LIMIT 50';
-}
-
-cur_frm.fields_dict['contact_person'].get_query = function(doc, cdt, cdn) {
- return 'SELECT name,CONCAT(first_name," ",ifnull(last_name,"")) As FullName,department,designation FROM tabContact WHERE supplier = "'+ doc.supplier +'" AND docstatus != 2 AND name LIKE "%s" ORDER BY name ASC LIMIT 50';
-}
cur_frm.fields_dict.supplier_address.on_new = function(dn) {
@@ -112,12 +104,6 @@
-// Get Print Heading
-cur_frm.fields_dict['select_print_heading'].get_query = function(doc, cdt, cdn) {
- return 'SELECT `tabPrint Heading`.name FROM `tabPrint Heading` WHERE `tabPrint Heading`.docstatus !=2 AND `tabPrint Heading`.name LIKE "%s" ORDER BY `tabPrint Heading`.name ASC LIMIT 50';
-}
-
-
//Set expense_head and cost center on adding new row
//----------------------------------------------
cur_frm.fields_dict['entries'].grid.onrowadd = function(doc, cdt, cdn){
@@ -143,25 +129,10 @@
if (doc.is_opening == 'Yes') unhide_field('aging_date');
}
-/* ******************************** TRIGGERS **************************************** */
-/*
-// Supplier
-// ---------
-cur_frm.cscript.supplier = function(doc,cdt,cdn){
- get_server_fields('get_credit_to','','',doc,cdt,cdn);
-}
-*/
-
-// Conversion Rate
-// ----------------
-cur_frm.cscript.conversion_rate = function(doc,cdt,cdn) {
- cur_frm.cscript.calc_total(doc,cdt,cdn);
-}
-
// Recalculate Button
// -------------------
cur_frm.cscript['Recalculate'] = function(doc, dt, dn) {
- cur_frm.cscript.calc_total(doc, cdt, cdn);
+ cur_frm.cscript['Calculate Tax'](doc,cdt,cdn);
calc_total_advance(doc,cdt,cdn);
}
@@ -186,31 +157,16 @@
}
}
-// Quantity
-// ---------
-cur_frm.cscript.qty = function(doc,dt,dn) { cur_frm.cscript.calc_exp_row(doc,dt,dn); }
-
-// Import Rate
-// ------------
-cur_frm.cscript.import_rate = function(doc,dt,dn) {
- var d = locals[dt][dn];
- set_multiple('PV Detail', d.name, {'rate': flt(d.import_rate) * flt(doc.conversion_rate) }, 'entries');
- cur_frm.cscript.calc_exp_row(doc,dt,dn)
-}
-
-
-// ============== TDS ===============
-
// Rate in Deduct Taxes (TDS)
// --------------------------
cur_frm.cscript.rate = function(doc,dt,dn) {
//This is done as Purchase tax detail and PV detail both contain the same fieldname 'rate'
- if(dt != 'Purchase Tax Detail') cur_frm.cscript.calc_exp_row(doc,dt,dn);
+ if(dt != 'Purchase Tax Detail') cur_frm.cscript.calc_amount(doc, 2);
}
// Amount
// -------
-cur_frm.cscript.ded_amount = function(doc,dt,dn) { cur_frm.cscript.calc_total(doc); }
+cur_frm.cscript.ded_amount = function(doc,dt,dn) {calculate_outstanding(doc);}
// Get TDS Button
// ---------------
@@ -218,7 +174,7 @@
var callback = function(r,rt) {
cur_frm.refresh();
refresh_field('ded_amount');
- cur_frm.cscript.calc_total(locals[dt][dn]);
+ //cur_frm.cscript.calc_total(locals[dt][dn]);
}
$c_obj(make_doclist(dt,dn), 'get_tds', '', callback);
}
@@ -251,6 +207,15 @@
/* ***************************** GET QUERY Functions *************************** */
+
+cur_frm.fields_dict['supplier_address'].get_query = function(doc, cdt, cdn) {
+ return 'SELECT name,address_line1,city FROM tabAddress WHERE supplier = "'+ doc.supplier +'" AND docstatus != 2 AND name LIKE "%s" ORDER BY name ASC LIMIT 50';
+}
+
+cur_frm.fields_dict['contact_person'].get_query = function(doc, cdt, cdn) {
+ return 'SELECT name,CONCAT(first_name," ",ifnull(last_name,"")) As FullName,department,designation FROM tabContact WHERE supplier = "'+ doc.supplier +'" AND docstatus != 2 AND name LIKE "%s" ORDER BY name ASC LIMIT 50';
+}
+
// Item Code
// ----------
cur_frm.fields_dict['entries'].grid.get_field("item_code").get_query = function(doc, cdt, cdn) {
@@ -284,6 +249,12 @@
}
}
+// Get Print Heading
+cur_frm.fields_dict['select_print_heading'].get_query = function(doc, cdt, cdn) {
+ return 'SELECT `tabPrint Heading`.name FROM `tabPrint Heading` WHERE `tabPrint Heading`.docstatus !=2 AND `tabPrint Heading`.name LIKE "%s" ORDER BY `tabPrint Heading`.name ASC LIMIT 50';
+}
+
+
// ================== PV Details Table ===================
// Expense Head
// -------------
@@ -331,27 +302,6 @@
/* ***************************** UTILITY FUNCTIONS ************************ */
-// Calculate
-// ---------
-cur_frm.cscript.calc_total = function(doc) {
-
- // expense
- var t_exp = 0.0;
- var el = getchildren('PV Detail',doc.name,'entries');
- for(var i in el) {
- if (flt(el[i].import_rate) > 0){
- set_multiple('PV Detail', el[i].name, {'rate': flt(doc.conversion_rate) * flt(el[i].import_rate) }, 'entries');
- set_multiple('PV Detail', el[i].name, {'import_amount': flt(el[i].qty) * flt(el[i].import_rate) }, 'entries');
- }
- set_multiple('PV Detail', el[i].name, {'amount': flt(el[i].qty) * flt(el[i].rate) }, 'entries')
- t_exp += flt(el[i].amount);
- }
- doc.net_total = flt(t_exp);
- refresh_field('net_total');
- cur_frm.cscript.val_cal_charges(doc, cdt, cdn, cur_frm.cscript.tname, cur_frm.cscript.fname, cur_frm.cscript.other_fname);
-}
-
-
// Calculate Advance
// ------------------
var calc_total_advance = function(doc,cdt,cdn) {
@@ -372,30 +322,12 @@
refresh_many(['total_advance','outstanding_amount','tds_amount_on_advance', 'total_amount_to_pay']);
}
-
-cur_frm.cscript.calc_exp_row = function(doc,dt,dn) {
- var d = locals[dt][dn];
- d.amount = flt(d.qty * d.rate);
- refresh_field('amount',dn,'entries');
-
- if (!doc.conversion_rate){ doc.conversion_rate = 1; refresh_field('conversion_rate'); }
-
- set_multiple('PV Detail', dn, {'import_rate': flt(d.rate) / flt(doc.conversion_rate) }, 'entries');
- set_multiple('PV Detail', dn, {'import_amount': flt(d.qty) * flt(d.rate) / flt(doc.conversion_rate) }, 'entries');
-
- cur_frm.cscript.calc_total(doc)
-}
-
-
// Make JV
// --------
cur_frm.cscript.make_jv = function(doc, dt, dn, det) {
var jv = LocalDB.create('Journal Voucher');
jv = locals['Journal Voucher'][jv];
jv.voucher_type = 'Bank Voucher';
- //jv.voucher_series = det.def_bv_series;
- //jv.voucher_date = doc.voucher_date;
- //jv.posting_date = doc.posting_date;
jv.remark = repl('Payment against voucher %(vn)s for %(rem)s', {vn:doc.name, rem:doc.remarks});
jv.total_debit = doc.outstanding_amount;
jv.total_credit = doc.outstanding_amount;
@@ -406,20 +338,17 @@
var d1 = LocalDB.add_child(jv, 'Journal Voucher Detail', 'entries');
d1.account = doc.credit_to;
d1.debit = doc.outstanding_amount;
- //d1.balance = det.acc_balance;
d1.against_voucher = doc.name;
// credit to bank
var d1 = LocalDB.add_child(jv, 'Journal Voucher Detail', 'entries');
- //d1.account = det.def_bank_account;
- //d1.balance = det.bank_balance;
d1.credit = doc.outstanding_amount;
loaddoc('Journal Voucher', jv.name);
}
// ***************** Get project name *****************
-cur_frm.fields_dict['project_name'].get_query = function(doc, cdt, cdn) {
+cur_frm.fields_dict['entries'].grid.get_field('project_name').get_query = function(doc, cdt, cdn) {
return 'SELECT `tabProject`.name FROM `tabProject` WHERE `tabProject`.status = "Open" AND `tabProject`.name LIKE "%s" ORDER BY `tabProject`.name ASC LIMIT 50';
}
@@ -433,15 +362,6 @@
cur_frm.pformat.print_heading = "Purchase Invoice";
}
-/* *********************** Client Side Validation **************************** */
-// Validate
-// ---------
-cur_frm.cscript.validate = function(doc, cdt, cdn) {
- is_item_table(doc,cdt,cdn);
- cur_frm.cscript.calc_total(doc, cdt, cdn);
- calc_total_advance(doc, cdt, cdn);
-}
-
/****************** Get Accounting Entry *****************/
cur_frm.cscript['View Ledger Entry'] = function(){
var callback = function(report){
diff --git a/erpnext/accounts/doctype/payable_voucher/payable_voucher.py b/erpnext/accounts/doctype/payable_voucher/payable_voucher.py
index 178a0cb..a7e128b 100644
--- a/erpnext/accounts/doctype/payable_voucher/payable_voucher.py
+++ b/erpnext/accounts/doctype/payable_voucher/payable_voucher.py
@@ -232,15 +232,11 @@
# Validate Acc Head of Supplier and Credit To Account entered
# ------------------------------------------------------------
def check_for_acc_head_of_supplier(self):
- acc_head = sql("select name from `tabAccount` where name = %s", (cstr(self.doc.supplier) + " - " + self.get_company_abbr()))
- if self.doc.supplier:
- if acc_head and acc_head[0][0]:
- if not cstr(acc_head[0][0]) == cstr(self.doc.credit_to):
- msgprint("Credit To: %s do not match with Supplier: %s for Company: %s i.e. %s" %(self.doc.credit_to,self.doc.supplier,self.doc.company,cstr(acc_head[0][0])))
- raise Exception, "Validation Error "
- if not acc_head:
- msgprint("Supplier %s does not have an Account Head in %s. You must first create it from the Supplier Master" % (self.doc.supplier, self.doc.company))
- raise Exception, "Validation Error "
+ if self.doc.supplier and self.doc.credit_to:
+ acc_head = sql("select master_name from `tabAccount` where name = %s", self.doc.credit_to)
+
+ if (acc_head and cstr(acc_head[0][0]) != cstr(self.doc.supplier)) or (not acc_head and (self.doc.credit_to != cstr(self.doc.supplier) + " - " + self.get_company_abbr())):
+ msgprint("Credit To: %s do not match with Supplier: %s for Company: %s.\n If both correctly entered, please select Master Type and Master Name in account master." %(self.doc.credit_to,self.doc.supplier,self.doc.company), raise_exception=1)
# Check for Stopped PO
# ---------------------
diff --git a/erpnext/accounts/doctype/payable_voucher/payable_voucher.txt b/erpnext/accounts/doctype/payable_voucher/payable_voucher.txt
old mode 100644
new mode 100755
index c77db19..93014ec
--- a/erpnext/accounts/doctype/payable_voucher/payable_voucher.txt
+++ b/erpnext/accounts/doctype/payable_voucher/payable_voucher.txt
@@ -5,15 +5,16 @@
{
'creation': '2010-08-08 17:09:11',
'docstatus': 0,
- 'modified': '2011-06-21 17:01:01',
+ 'modified': '2011-11-24 15:17:14',
'modified_by': 'Administrator',
'owner': 'Administrator'
},
# These values are common for all DocType
{
- '_last_update': '1309508838',
+ '_last_update': '1321601347',
'colour': 'White:FFF',
+ 'default_print_format': 'Standard',
'doctype': 'DocType',
'module': 'Accounts',
'name': '__common__',
@@ -23,7 +24,7 @@
'server_code_error': ' ',
'show_in_menu': 0,
'subject': 'From %(supplier_name)s worth %(grand_total)s due on %(due_date)s | %(outstanding_amount)s outstanding',
- 'version': 518
+ 'version': 522
},
# These values are common for all DocField
@@ -57,7 +58,6 @@
'cancel': 0,
'create': 0,
'doctype': 'DocPerm',
- 'idx': 1,
'permlevel': 1,
'role': 'Accounts Manager',
'submit': 0,
@@ -70,7 +70,6 @@
'cancel': 1,
'create': 1,
'doctype': 'DocPerm',
- 'idx': 2,
'permlevel': 0,
'role': 'Accounts Manager',
'submit': 1,
@@ -83,7 +82,6 @@
'cancel': 0,
'create': 0,
'doctype': 'DocPerm',
- 'idx': 3,
'permlevel': 1,
'role': 'Accounts User',
'submit': 0,
@@ -93,7 +91,6 @@
# DocPerm
{
'doctype': 'DocPerm',
- 'idx': 4,
'permlevel': 1,
'role': 'Purchase User'
},
@@ -104,7 +101,6 @@
'cancel': 0,
'create': 1,
'doctype': 'DocPerm',
- 'idx': 5,
'permlevel': 0,
'role': 'Purchase User',
'submit': 0,
@@ -117,7 +113,6 @@
'cancel': 1,
'create': 1,
'doctype': 'DocPerm',
- 'idx': 6,
'permlevel': 0,
'role': 'Accounts User',
'submit': 1,
@@ -127,7 +122,6 @@
# DocPerm
{
'doctype': 'DocPerm',
- 'idx': 7,
'match': 'supplier',
'permlevel': 0,
'role': 'Supplier'
@@ -138,7 +132,6 @@
'allow_on_submit': 0,
'doctype': 'DocField',
'fieldtype': 'Section Break',
- 'idx': 1,
'label': 'Basic Info',
'oldfieldtype': 'Section Break',
'permlevel': 0
@@ -148,7 +141,6 @@
{
'doctype': 'DocField',
'fieldtype': 'Column Break',
- 'idx': 2,
'oldfieldtype': 'Column Break',
'permlevel': 0,
'width': '50%'
@@ -161,7 +153,6 @@
'doctype': 'DocField',
'fieldname': 'naming_series',
'fieldtype': 'Select',
- 'idx': 3,
'label': 'Series',
'no_copy': 1,
'oldfieldname': 'naming_series',
@@ -179,7 +170,6 @@
'doctype': 'DocField',
'fieldname': 'credit_to',
'fieldtype': 'Link',
- 'idx': 4,
'in_filter': 1,
'label': 'Credit To',
'oldfieldname': 'credit_to',
@@ -197,7 +187,6 @@
'doctype': 'DocField',
'fieldname': 'amended_from',
'fieldtype': 'Link',
- 'idx': 5,
'label': 'Amended From',
'no_copy': 1,
'oldfieldname': 'amended_from',
@@ -214,14 +203,12 @@
'fieldname': 'supplier',
'fieldtype': 'Link',
'hidden': 0,
- 'idx': 6,
'label': 'Supplier',
'oldfieldname': 'supplier',
'oldfieldtype': 'Link',
'options': 'Supplier',
'permlevel': 0,
'print_hide': 1,
- 'search_index': 1,
'trigger': 'Client'
},
@@ -230,11 +217,8 @@
'doctype': 'DocField',
'fieldname': 'supplier_address',
'fieldtype': 'Link',
- 'idx': 7,
'label': 'Supplier Address',
- 'options': 'Address',
- 'permlevel': 0,
- 'print_hide': 1
+ 'permlevel': 0
},
# DocField
@@ -242,7 +226,6 @@
'doctype': 'DocField',
'fieldname': 'contact_person',
'fieldtype': 'Link',
- 'idx': 8,
'label': 'Contact Person',
'options': 'Contact',
'permlevel': 0,
@@ -254,7 +237,6 @@
'doctype': 'DocField',
'fieldname': 'supplier_name',
'fieldtype': 'Text',
- 'idx': 9,
'label': 'Name',
'oldfieldname': 'supplier_name',
'oldfieldtype': 'Data',
@@ -266,7 +248,6 @@
'doctype': 'DocField',
'fieldname': 'address_display',
'fieldtype': 'Small Text',
- 'idx': 10,
'label': 'Address',
'permlevel': 1
},
@@ -276,7 +257,6 @@
'doctype': 'DocField',
'fieldname': 'contact_display',
'fieldtype': 'Small Text',
- 'idx': 11,
'label': 'Contact',
'permlevel': 1
},
@@ -286,7 +266,6 @@
'doctype': 'DocField',
'fieldname': 'contact_mobile',
'fieldtype': 'Text',
- 'idx': 12,
'label': 'Mobile No',
'permlevel': 1
},
@@ -296,7 +275,6 @@
'doctype': 'DocField',
'fieldname': 'contact_email',
'fieldtype': 'Text',
- 'idx': 13,
'label': 'Contact Email',
'permlevel': 1,
'print_hide': 1
@@ -306,7 +284,6 @@
{
'doctype': 'DocField',
'fieldtype': 'Column Break',
- 'idx': 14,
'oldfieldtype': 'Column Break',
'permlevel': 0,
'reqd': 0,
@@ -319,7 +296,6 @@
'doctype': 'DocField',
'fieldname': 'voucher_date',
'fieldtype': 'Date',
- 'idx': 15,
'in_filter': 1,
'label': 'Voucher Date',
'no_copy': 0,
@@ -327,7 +303,7 @@
'oldfieldtype': 'Date',
'permlevel': 0,
'reqd': 1,
- 'search_index': 0
+ 'search_index': 1
},
# DocField
@@ -335,7 +311,6 @@
'doctype': 'DocField',
'fieldname': 'due_date',
'fieldtype': 'Date',
- 'idx': 16,
'in_filter': 1,
'label': 'Due Date',
'no_copy': 0,
@@ -343,7 +318,7 @@
'oldfieldtype': 'Date',
'permlevel': 0,
'print_hide': 0,
- 'search_index': 0
+ 'search_index': 1
},
# DocField
@@ -353,7 +328,6 @@
'doctype': 'DocField',
'fieldname': 'posting_date',
'fieldtype': 'Date',
- 'idx': 17,
'in_filter': 1,
'label': 'Posting Date',
'no_copy': 0,
@@ -371,7 +345,6 @@
'doctype': 'DocField',
'fieldname': 'bill_no',
'fieldtype': 'Data',
- 'idx': 18,
'in_filter': 1,
'label': 'Bill No',
'oldfieldname': 'bill_no',
@@ -379,7 +352,7 @@
'permlevel': 0,
'print_hide': 1,
'reqd': 1,
- 'search_index': 0
+ 'search_index': 1
},
# DocField
@@ -387,7 +360,6 @@
'doctype': 'DocField',
'fieldname': 'bill_date',
'fieldtype': 'Date',
- 'idx': 19,
'in_filter': 1,
'label': 'Bill Date',
'oldfieldname': 'bill_date',
@@ -395,7 +367,7 @@
'permlevel': 0,
'print_hide': 1,
'reqd': 0,
- 'search_index': 0
+ 'search_index': 1
},
# DocField
@@ -404,7 +376,6 @@
'doctype': 'DocField',
'fieldname': 'amendment_date',
'fieldtype': 'Date',
- 'idx': 20,
'label': 'Amendment Date',
'no_copy': 1,
'oldfieldname': 'amendment_date',
@@ -418,7 +389,6 @@
'doctype': 'DocField',
'fieldname': 'mode_of_payment',
'fieldtype': 'Select',
- 'idx': 21,
'label': 'Mode of Payment',
'oldfieldname': 'mode_of_payment',
'oldfieldtype': 'Select',
@@ -430,7 +400,6 @@
{
'doctype': 'DocField',
'fieldtype': 'Section Break',
- 'idx': 22,
'label': 'Items',
'oldfieldtype': 'Section Break',
'permlevel': 0
@@ -443,7 +412,6 @@
'doctype': 'DocField',
'fieldname': 'purchase_order_main',
'fieldtype': 'Link',
- 'idx': 23,
'label': 'Purchase Order',
'oldfieldname': 'purchase_order_main',
'oldfieldtype': 'Link',
@@ -460,7 +428,6 @@
'doctype': 'DocField',
'fieldname': 'purchase_receipt_main',
'fieldtype': 'Link',
- 'idx': 24,
'label': 'Purchase Receipt',
'oldfieldname': 'purchase_receipt_main',
'oldfieldtype': 'Link',
@@ -475,7 +442,6 @@
'colour': 'White:FFF',
'doctype': 'DocField',
'fieldtype': 'Button',
- 'idx': 25,
'label': 'Get Items',
'oldfieldtype': 'Button',
'options': 'pull_details',
@@ -486,7 +452,6 @@
{
'doctype': 'DocField',
'fieldtype': 'Column Break',
- 'idx': 26,
'permlevel': 0
},
@@ -495,14 +460,12 @@
'doctype': 'DocField',
'fieldname': 'currency',
'fieldtype': 'Select',
- 'idx': 27,
'label': 'Bill Currency',
'oldfieldname': 'currency',
'oldfieldtype': 'Select',
'options': 'link:Currency',
'permlevel': 0,
- 'print_hide': 1,
- 'reqd': 1
+ 'print_hide': 1
},
# DocField
@@ -512,29 +475,26 @@
'doctype': 'DocField',
'fieldname': 'conversion_rate',
'fieldtype': 'Currency',
- 'idx': 28,
'label': 'Bill Conversion Rate',
'oldfieldname': 'conversion_rate',
'oldfieldtype': 'Currency',
'permlevel': 0,
- 'print_hide': 1,
- 'reqd': 1
+ 'print_hide': 1
},
# DocField
{
'doctype': 'DocField',
'fieldtype': 'Section Break',
- 'idx': 29,
'permlevel': 0
},
# DocField
{
+ 'allow_on_submit': 1,
'doctype': 'DocField',
'fieldname': 'entries',
'fieldtype': 'Table',
- 'idx': 30,
'label': 'Entries',
'oldfieldname': 'entries',
'oldfieldtype': 'Table',
@@ -546,7 +506,6 @@
{
'doctype': 'DocField',
'fieldtype': 'Button',
- 'idx': 31,
'label': 'Recalculate',
'oldfieldtype': 'Button',
'permlevel': 0,
@@ -559,7 +518,6 @@
'doctype': 'DocField',
'fieldname': 'net_total',
'fieldtype': 'Currency',
- 'idx': 32,
'label': 'Net Total',
'oldfieldname': 'net_total',
'oldfieldtype': 'Currency',
@@ -573,7 +531,6 @@
'description': 'Add / Edit taxes and other charges',
'doctype': 'DocField',
'fieldtype': 'Section Break',
- 'idx': 33,
'label': 'Taxes',
'oldfieldtype': 'Section Break',
'permlevel': 0
@@ -584,7 +541,6 @@
'doctype': 'DocField',
'fieldname': 'purchase_other_charges',
'fieldtype': 'Link',
- 'idx': 34,
'label': 'Purchase Other Charges',
'oldfieldname': 'purchase_other_charges',
'oldfieldtype': 'Link',
@@ -597,7 +553,6 @@
{
'doctype': 'DocField',
'fieldtype': 'Button',
- 'idx': 35,
'label': 'Get Tax Detail',
'oldfieldtype': 'Button',
'options': 'get_purchase_tax_details',
@@ -610,7 +565,6 @@
'doctype': 'DocField',
'fieldname': 'purchase_tax_details',
'fieldtype': 'Table',
- 'idx': 36,
'label': 'Purchase Tax Details',
'oldfieldname': 'purchase_tax_details',
'oldfieldtype': 'Table',
@@ -622,7 +576,6 @@
{
'doctype': 'DocField',
'fieldtype': 'Button',
- 'idx': 37,
'label': 'Calculate Tax',
'oldfieldtype': 'Button',
'permlevel': 0,
@@ -634,7 +587,6 @@
{
'doctype': 'DocField',
'fieldtype': 'HTML',
- 'idx': 38,
'label': 'Tax Calculation',
'oldfieldtype': 'HTML',
'permlevel': 0,
@@ -646,7 +598,6 @@
'doctype': 'DocField',
'fieldname': 'total_tax',
'fieldtype': 'Currency',
- 'idx': 39,
'label': 'Total Tax',
'oldfieldname': 'total_tax',
'oldfieldtype': 'Currency',
@@ -658,7 +609,6 @@
{
'doctype': 'DocField',
'fieldtype': 'Section Break',
- 'idx': 40,
'label': 'More Info',
'oldfieldtype': 'Section Break',
'permlevel': 0,
@@ -669,7 +619,6 @@
{
'doctype': 'DocField',
'fieldtype': 'Column Break',
- 'idx': 41,
'oldfieldtype': 'Column Break',
'permlevel': 0,
'print_hide': 0,
@@ -683,7 +632,6 @@
'doctype': 'DocField',
'fieldname': 'is_opening',
'fieldtype': 'Select',
- 'idx': 42,
'in_filter': 1,
'label': 'Is Opening',
'oldfieldname': 'is_opening',
@@ -691,33 +639,15 @@
'options': 'No\nYes',
'permlevel': 0,
'print_hide': 1,
- 'search_index': 0,
+ 'search_index': 1,
'trigger': 'Client'
},
# DocField
{
- 'colour': 'White:FFF',
- 'description': 'Track this Purchase Invoice against any Project',
- 'doctype': 'DocField',
- 'fieldname': 'project_name',
- 'fieldtype': 'Link',
- 'idx': 43,
- 'in_filter': 1,
- 'label': 'Project Name',
- 'oldfieldname': 'project_name',
- 'oldfieldtype': 'Link',
- 'options': 'Project',
- 'permlevel': 0,
- 'search_index': 1
- },
-
- # DocField
- {
'doctype': 'DocField',
'fieldname': 'aging_date',
'fieldtype': 'Date',
- 'idx': 44,
'label': 'Aging Date',
'oldfieldname': 'aging_date',
'oldfieldtype': 'Date',
@@ -733,7 +663,6 @@
'doctype': 'DocField',
'fieldname': 'select_print_heading',
'fieldtype': 'Link',
- 'idx': 45,
'label': 'Select Print Heading',
'no_copy': 1,
'oldfieldname': 'select_print_heading',
@@ -749,7 +678,6 @@
{
'doctype': 'DocField',
'fieldtype': 'Column Break',
- 'idx': 46,
'oldfieldtype': 'Column Break',
'permlevel': 0,
'width': '50%'
@@ -760,7 +688,6 @@
'doctype': 'DocField',
'fieldname': 'company',
'fieldtype': 'Link',
- 'idx': 47,
'in_filter': 1,
'label': 'Company',
'oldfieldname': 'company',
@@ -768,8 +695,7 @@
'options': 'Company',
'permlevel': 0,
'print_hide': 1,
- 'reqd': 1,
- 'search_index': 0
+ 'search_index': 1
},
# DocField
@@ -777,7 +703,6 @@
'doctype': 'DocField',
'fieldname': 'fiscal_year',
'fieldtype': 'Select',
- 'idx': 48,
'in_filter': 1,
'label': 'Fiscal Year',
'oldfieldname': 'fiscal_year',
@@ -785,8 +710,7 @@
'options': 'link:Fiscal Year',
'permlevel': 0,
'print_hide': 1,
- 'reqd': 1,
- 'search_index': 0
+ 'search_index': 1
},
# DocField
@@ -796,7 +720,6 @@
'doctype': 'DocField',
'fieldname': 'cancel_reason',
'fieldtype': 'Data',
- 'idx': 49,
'label': 'Cancel Reason',
'no_copy': 1,
'oldfieldname': 'cancel_reason',
@@ -810,7 +733,6 @@
'doctype': 'DocField',
'fieldname': 'remarks',
'fieldtype': 'Small Text',
- 'idx': 50,
'label': 'Remarks',
'no_copy': 1,
'oldfieldname': 'remarks',
@@ -824,7 +746,6 @@
{
'doctype': 'DocField',
'fieldtype': 'Section Break',
- 'idx': 51,
'label': 'Advances',
'oldfieldtype': 'Section Break',
'permlevel': 0,
@@ -835,7 +756,6 @@
{
'doctype': 'DocField',
'fieldtype': 'Button',
- 'idx': 52,
'label': 'Get Advances Paid',
'oldfieldtype': 'Button',
'options': 'get_advances',
@@ -849,7 +769,6 @@
'doctype': 'DocField',
'fieldname': 'advance_allocation_details',
'fieldtype': 'Table',
- 'idx': 53,
'label': 'Advance Allocation Details',
'no_copy': 1,
'oldfieldname': 'advance_allocation_details',
@@ -863,7 +782,6 @@
{
'doctype': 'DocField',
'fieldtype': 'Section Break',
- 'idx': 54,
'label': 'TDS',
'oldfieldtype': 'Section Break',
'permlevel': 0
@@ -873,7 +791,6 @@
{
'doctype': 'DocField',
'fieldtype': 'Column Break',
- 'idx': 55,
'permlevel': 0,
'width': '50%'
},
@@ -883,7 +800,6 @@
'doctype': 'DocField',
'fieldname': 'tds_applicable',
'fieldtype': 'Select',
- 'idx': 56,
'label': 'TDS Applicable',
'oldfieldname': 'tds_applicable',
'oldfieldtype': 'Select',
@@ -897,7 +813,6 @@
'doctype': 'DocField',
'fieldname': 'tds_category',
'fieldtype': 'Select',
- 'idx': 57,
'label': 'TDS Category',
'oldfieldname': 'tds_category',
'oldfieldtype': 'Select',
@@ -911,7 +826,6 @@
'colour': 'White:FFF',
'doctype': 'DocField',
'fieldtype': 'Button',
- 'idx': 58,
'label': 'Get TDS',
'oldfieldtype': 'Button',
'permlevel': 0,
@@ -923,7 +837,6 @@
{
'doctype': 'DocField',
'fieldtype': 'Column Break',
- 'idx': 59,
'permlevel': 0,
'width': '50%'
},
@@ -933,7 +846,6 @@
'doctype': 'DocField',
'fieldname': 'tax_code',
'fieldtype': 'Link',
- 'idx': 60,
'label': 'TDS Account Head',
'oldfieldname': 'tax_code',
'oldfieldtype': 'Link',
@@ -947,7 +859,6 @@
'doctype': 'DocField',
'fieldname': 'rate',
'fieldtype': 'Currency',
- 'idx': 61,
'label': 'Rate',
'oldfieldname': 'rate',
'oldfieldtype': 'Currency',
@@ -960,7 +871,6 @@
'doctype': 'DocField',
'fieldname': 'ded_amount',
'fieldtype': 'Currency',
- 'idx': 62,
'label': 'TDS Amount',
'oldfieldname': 'ded_amount',
'oldfieldtype': 'Currency',
@@ -972,7 +882,6 @@
{
'doctype': 'DocField',
'fieldtype': 'Section Break',
- 'idx': 63,
'label': 'Totals',
'oldfieldtype': 'Section Break',
'permlevel': 0
@@ -982,7 +891,6 @@
{
'doctype': 'DocField',
'fieldtype': 'Column Break',
- 'idx': 64,
'oldfieldtype': 'Column Break',
'permlevel': 0,
'width': '50%'
@@ -993,7 +901,6 @@
'doctype': 'DocField',
'fieldname': 'other_charges_added',
'fieldtype': 'Currency',
- 'idx': 65,
'label': 'Other Charges Added',
'oldfieldname': 'other_charges_added',
'oldfieldtype': 'Currency',
@@ -1006,7 +913,6 @@
'doctype': 'DocField',
'fieldname': 'other_charges_deducted',
'fieldtype': 'Currency',
- 'idx': 66,
'label': 'Other Charges Deducted',
'oldfieldname': 'other_charges_deducted',
'oldfieldtype': 'Currency',
@@ -1019,7 +925,6 @@
'doctype': 'DocField',
'fieldname': 'total_tds_on_voucher',
'fieldtype': 'Currency',
- 'idx': 67,
'label': 'Total TDS On Voucher',
'no_copy': 1,
'oldfieldname': 'total_tds_on_voucher',
@@ -1034,7 +939,6 @@
'doctype': 'DocField',
'fieldname': 'tds_amount_on_advance',
'fieldtype': 'Currency',
- 'idx': 68,
'label': 'TDS Amount On Advance',
'no_copy': 1,
'oldfieldname': 'tds_amount_on_advance',
@@ -1048,7 +952,6 @@
'doctype': 'DocField',
'fieldname': 'total_advance',
'fieldtype': 'Currency',
- 'idx': 69,
'label': 'Total Advance (Incl. TDS)',
'no_copy': 1,
'oldfieldname': 'total_advance',
@@ -1063,7 +966,6 @@
'fieldname': 'total_amount_to_pay',
'fieldtype': 'Currency',
'hidden': 0,
- 'idx': 70,
'label': 'Total Amount To Pay',
'no_copy': 1,
'oldfieldname': 'total_amount_to_pay',
@@ -1077,7 +979,6 @@
'doctype': 'DocField',
'fieldname': 'outstanding_amount',
'fieldtype': 'Currency',
- 'idx': 71,
'in_filter': 1,
'label': 'Outstanding Amount',
'no_copy': 1,
@@ -1085,14 +986,13 @@
'oldfieldtype': 'Currency',
'permlevel': 1,
'print_hide': 1,
- 'search_index': 0
+ 'search_index': 1
},
# DocField
{
'doctype': 'DocField',
'fieldtype': 'Column Break',
- 'idx': 72,
'oldfieldtype': 'Column Break',
'permlevel': 0,
'print_hide': 1,
@@ -1104,7 +1004,6 @@
'doctype': 'DocField',
'fieldname': 'grand_total',
'fieldtype': 'Currency',
- 'idx': 73,
'label': 'Grand Total',
'oldfieldname': 'grand_total',
'oldfieldtype': 'Currency',
@@ -1119,7 +1018,6 @@
'doctype': 'DocField',
'fieldname': 'in_words',
'fieldtype': 'Data',
- 'idx': 74,
'label': 'In Words',
'oldfieldname': 'in_words',
'oldfieldtype': 'Data',
@@ -1132,7 +1030,6 @@
'doctype': 'DocField',
'fieldname': 'net_total_import',
'fieldtype': 'Currency',
- 'idx': 75,
'label': 'Net Total (Import)',
'oldfieldname': 'net_total_import',
'oldfieldtype': 'Currency',
@@ -1145,7 +1042,6 @@
'doctype': 'DocField',
'fieldname': 'other_charges_added_import',
'fieldtype': 'Currency',
- 'idx': 76,
'label': 'Other Charges Added (Import)',
'oldfieldname': 'other_charges_added_import',
'oldfieldtype': 'Currency',
@@ -1158,7 +1054,6 @@
'doctype': 'DocField',
'fieldname': 'other_charges_deducted_import',
'fieldtype': 'Currency',
- 'idx': 77,
'label': 'Other Charges Deducted (Import)',
'oldfieldname': 'other_charges_deducted_import',
'oldfieldtype': 'Currency',
@@ -1171,7 +1066,6 @@
'doctype': 'DocField',
'fieldname': 'grand_total_import',
'fieldtype': 'Currency',
- 'idx': 78,
'label': 'Grand Total (Import)',
'oldfieldname': 'grand_total_import',
'oldfieldtype': 'Currency',
@@ -1186,7 +1080,6 @@
'doctype': 'DocField',
'fieldname': 'in_words_import',
'fieldtype': 'Data',
- 'idx': 79,
'label': 'In Words (Import)',
'oldfieldname': 'in_words_import',
'oldfieldtype': 'Data',
@@ -1200,7 +1093,6 @@
'depends_on': 'eval:!doc.__islocal',
'doctype': 'DocField',
'fieldtype': 'Section Break',
- 'idx': 80,
'label': 'Actions',
'oldfieldtype': 'Section Break',
'permlevel': 0,
@@ -1212,7 +1104,6 @@
'allow_on_submit': 1,
'doctype': 'DocField',
'fieldtype': 'Button',
- 'idx': 81,
'label': 'Repair Outstanding Amt',
'oldfieldtype': 'Button',
'options': 'repair_pv_outstanding',
@@ -1226,7 +1117,6 @@
'fieldname': 'against_expense_account',
'fieldtype': 'Small Text',
'hidden': 1,
- 'idx': 82,
'label': 'Against Expense Account',
'no_copy': 1,
'oldfieldname': 'against_expense_account',
diff --git a/erpnext/accounts/doctype/pos_setting/pos_setting.js b/erpnext/accounts/doctype/pos_setting/pos_setting.js
index 4eed7b6..2bbc08c 100755
--- a/erpnext/accounts/doctype/pos_setting/pos_setting.js
+++ b/erpnext/accounts/doctype/pos_setting/pos_setting.js
@@ -1,109 +1,38 @@
+cur_frm.cscript.onload = function(doc,cdt,cdn){
+ $c_obj(make_doclist(cdt,cdn),'get_series','',function(r,rt){
+ if(r.message) set_field_options('naming_series', r.message);
+ });
-
-//--------- ONLOAD -------------
-cur_frm.cscript.onload = function(doc, cdt, cdn) {
-
-}
-
-// Settings Module
-
-cur_frm.cscript.refresh = function(doc,cdt,cdn){
-
-
- if(doc.based_on == 'Grand Total' || doc.based_on == 'Average Discount' || doc.based_on == 'Total Claimed Amount' || doc.based_on == 'Not Applicable') hide_field('master_name');
- else unhide_field('master_name');
- if(doc.based_on == 'Not Applicable') hide_field('value');
- else unhide_field('value');
-
- if(doc.transaction == 'Expense Voucher' || doc.transaction == 'Appraisal'){
- hide_field(['master_name','system_role', 'system_user']);
- unhide_field(['to_emp','to_designation']);
- if(doc.transaction == 'Appraisal') hide_field('value');
- else unhide_field('value');
- }
- else {
- unhide_field(['master_name','system_role', 'system_user','value']);
- hide_field(['to_emp','to_designation']);
- }
}
-cur_frm.cscript.based_on = function(doc){
- if(doc.based_on == 'Grand Total' || doc.based_on == 'Average Discount' || doc.based_on == 'Total Claimed Amount' || doc.based_on == 'Not Applicable'){
- doc.master_name = '';
- refresh_field('master_name');
- hide_field('master_name');
- }
- else{
- unhide_field('master_name');
- }
-
- if(doc.based_on == 'Not Applicable') {
- doc.value =0;
- refresh_field('value');
- hide_field('value');
- }
- else unhide_field('value');
+//cash bank account
+//------------------------------------
+cur_frm.fields_dict['cash_bank_account'].get_query = function(doc,cdt,cdn) {
+ return 'SELECT tabAccount.name FROM tabAccount WHERE tabAccount.debit_or_credit="Debit" AND tabAccount.is_pl_account = "No" AND tabAccount.group_or_ledger="Ledger" AND tabAccount.docstatus!=2 AND tabAccount.company="'+doc.company+'" AND tabAccount.%(key)s LIKE "%s"'
}
-cur_frm.cscript.transaction = function(doc,cdt,cdn){
- if(doc.transaction == 'Expense Voucher' || doc.transaction == 'Appraisal'){
- doc.master_name = doc.system_role = doc.system_user = '';
- refresh_many(['master_name','system_role', 'system_user']);
- hide_field(['master_name','system_role', 'system_user']);
- unhide_field(['to_emp','to_designation']);
- if(doc.transaction == 'Appraisal') {
- doc.value =0;
- refresh_many('value');
- hide_field('value');
- }
- else unhide_field('value');
- }
- else {
- unhide_field(['master_name','system_role', 'system_user','value']);
- hide_field(['to_emp','to_designation']);
- }
-
- if(doc.transaction == 'Expense Voucher') doc.based_on = 'Total Claimed Amount';
- if(doc.transaction == 'Appraisal') doc.based_on == 'Not Applicable';
+// Income Account
+// --------------------------------
+cur_frm.fields_dict['income_account'].get_query = function(doc,cdt,cdn) {
+ return 'SELECT tabAccount.name FROM tabAccount WHERE tabAccount.debit_or_credit="Credit" AND tabAccount.group_or_ledger="Ledger" AND tabAccount.docstatus!=2 AND tabAccount.company="'+doc.company+'" AND tabAccount.account_type ="Income Account" AND tabAccount.%(key)s LIKE "%s"'
}
-// System User Trigger
-// -------------------
-cur_frm.fields_dict['system_user'].get_query = function(doc) {
- return 'SELECT tabProfile.name, tabProfile.first_name FROM tabProfile WHERE tabProfile.name not in ("Administrator","Guest") AND tabProfile.docstatus != 2 AND tabProfile.%(key)s LIKE "%s" LIMIT 50'
+// Cost Center
+// -----------------------------
+cur_frm.fields_dict['cost_center'].get_query = function(doc,cdt,cdn) {
+ return 'SELECT `tabCost Center`.`name` FROM `tabCost Center` WHERE `tabCost Center`.`company_name` = "' +doc.company+'" AND `tabCost Center`.%(key)s LIKE "%s" AND `tabCost Center`.`group_or_ledger` = "Ledger" AND `tabCost Center`.`docstatus`!= 2 ORDER BY `tabCost Center`.`name` ASC LIMIT 50';
+}
+
+//get query select Territory
+//=================================================================
+cur_frm.fields_dict['territory'].get_query = function(doc,cdt,cdn) {
+ return 'SELECT `tabTerritory`.`name`,`tabTerritory`.`parent_territory` FROM `tabTerritory` WHERE `tabTerritory`.`is_group` = "No" AND `tabTerritory`.`docstatus`!= 2 AND `tabTerritory`.%(key)s LIKE "%s" ORDER BY `tabTerritory`.`name` ASC LIMIT 50';
}
-// System Role Trigger
-// -----------------------
-cur_frm.fields_dict['system_role'].get_query = function(doc) {
- return 'SELECT tabRole.name FROM tabRole WHERE tabRole.name not in ("Administrator","Guest","All") AND tabRole.docstatus != 2 AND tabRole.%(key)s LIKE "%s" LIMIT 50'
-}
-
-
-// Approving User Trigger
-// -----------------------
-cur_frm.fields_dict['approving_user'].get_query = function(doc) {
- return 'SELECT tabProfile.name, tabProfile.first_name FROM tabProfile WHERE tabProfile.name not in ("Administrator","Guest") AND tabProfile.docstatus != 2 AND tabProfile.%(key)s LIKE "%s" LIMIT 50'
-}
-
-
-// Approving Role Trigger
-// -----------------------
-cur_frm.fields_dict['approving_role'].get_query = function(doc) {
- return 'SELECT tabRole.name FROM tabRole WHERE tabRole.name not in ("Administrator","Guest","All") AND tabRole.docstatus != 2 AND tabRole.%(key)s LIKE "%s" LIMIT 50'
-}
-
-
-// Master Name Trigger
-// --------------------
-cur_frm.fields_dict['master_name'].get_query = function(doc){
- if(doc.based_on == 'Customerwise Discount')
- return 'SELECT `tabCustomer`.`name` FROM `tabCustomer` WHERE `tabCustomer`.docstatus !=2 and `tabCustomer`.`name` LIKE "%s" ORDER BY `tabCustomer`.`name` DESC LIMIT 50';
- else if(doc.based_on == 'Itemwise Discount')
- return 'SELECT `tabItem`.`name` FROM `tabItem` WHERE (IFNULL(`tabItem`.`end_of_life`,"") = "" OR `tabItem`.`end_of_life` = "0000-00-00" OR `tabItem`.`end_of_life` > NOW()) and `tabItem`.is_sales_item = "Yes" and tabItem.%(key)s LIKE "%s" ORDER BY `tabItem`.`name` DESC LIMIT 50';
- else
- return 'SELECT `tabItem`.`name` FROM `tabItem` WHERE `tabItem`.`name` = "cheating done to avoid null" ORDER BY `tabItem`.`name` DESC LIMIT 50';
+// ------------------ Get Print Heading ------------------------------------
+cur_frm.fields_dict['select_print_heading'].get_query = function(doc, cdt, cdn) {
+ return 'SELECT `tabPrint Heading`.name FROM `tabPrint Heading` WHERE `tabPrint Heading`.docstatus !=2 AND `tabPrint Heading`.name LIKE "%s" ORDER BY `tabPrint Heading`.name ASC LIMIT 50';
}
diff --git a/erpnext/accounts/doctype/purchase_tax_detail/purchase_tax_detail.txt b/erpnext/accounts/doctype/purchase_tax_detail/purchase_tax_detail.txt
index ed67ba2..58f66c7 100644
--- a/erpnext/accounts/doctype/purchase_tax_detail/purchase_tax_detail.txt
+++ b/erpnext/accounts/doctype/purchase_tax_detail/purchase_tax_detail.txt
@@ -5,8 +5,8 @@
{
'creation': '2010-08-08 17:09:16',
'docstatus': 0,
- 'modified': '2010-09-20 14:06:57',
- 'modified_by': 'umair@iwebnotes.com',
+ 'modified': '2011-11-16 15:41:42',
+ 'modified_by': 'Administrator',
'owner': 'wasim@webnotestech.com'
},
@@ -14,6 +14,7 @@
{
'autoname': 'PVTD.######',
'colour': 'White:FFF',
+ 'default_print_format': 'Standard',
'doctype': 'DocType',
'hide_heading': 1,
'istable': 1,
@@ -22,7 +23,7 @@
'section_style': 'Tray',
'server_code_error': ' ',
'show_in_menu': 0,
- 'version': 10
+ 'version': 12
},
# These values are common for all DocField
@@ -45,7 +46,6 @@
'doctype': 'DocField',
'fieldname': 'category',
'fieldtype': 'Select',
- 'idx': 1,
'label': 'Category',
'oldfieldname': 'category',
'oldfieldtype': 'Select',
@@ -60,7 +60,6 @@
'doctype': 'DocField',
'fieldname': 'add_deduct_tax',
'fieldtype': 'Select',
- 'idx': 2,
'label': 'Add or Deduct',
'oldfieldname': 'add_deduct_tax',
'oldfieldtype': 'Select',
@@ -75,7 +74,6 @@
'doctype': 'DocField',
'fieldname': 'charge_type',
'fieldtype': 'Select',
- 'idx': 3,
'label': 'Type',
'oldfieldname': 'charge_type',
'oldfieldtype': 'Select',
@@ -91,7 +89,6 @@
'fieldname': 'row_id',
'fieldtype': 'Data',
'hidden': 0,
- 'idx': 4,
'label': 'Enter Row',
'oldfieldname': 'row_id',
'oldfieldtype': 'Data',
@@ -104,7 +101,6 @@
'doctype': 'DocField',
'fieldname': 'item_wise_tax_detail',
'fieldtype': 'Small Text',
- 'idx': 5,
'label': 'Item Wise Tax Detail ',
'oldfieldname': 'item_wise_tax_detail',
'oldfieldtype': 'Small Text',
@@ -116,7 +112,6 @@
'doctype': 'DocField',
'fieldname': 'description',
'fieldtype': 'Small Text',
- 'idx': 6,
'label': 'Description',
'oldfieldname': 'description',
'oldfieldtype': 'Small Text',
@@ -130,7 +125,6 @@
'doctype': 'DocField',
'fieldname': 'account_head',
'fieldtype': 'Link',
- 'idx': 7,
'label': 'Account Head',
'oldfieldname': 'account_head',
'oldfieldtype': 'Link',
@@ -145,13 +139,11 @@
'doctype': 'DocField',
'fieldname': 'cost_center',
'fieldtype': 'Link',
- 'idx': 8,
'label': 'Cost Center',
'oldfieldname': 'cost_center',
'oldfieldtype': 'Link',
'options': 'Cost Center',
'permlevel': 0,
- 'search_index': 0,
'trigger': 'Client'
},
@@ -160,7 +152,6 @@
'doctype': 'DocField',
'fieldname': 'rate',
'fieldtype': 'Currency',
- 'idx': 9,
'label': 'Rate',
'oldfieldname': 'rate',
'oldfieldtype': 'Currency',
@@ -174,7 +165,6 @@
'doctype': 'DocField',
'fieldname': 'tax_amount',
'fieldtype': 'Currency',
- 'idx': 10,
'label': 'Amount',
'oldfieldname': 'tax_amount',
'oldfieldtype': 'Currency',
@@ -188,7 +178,6 @@
'doctype': 'DocField',
'fieldname': 'total',
'fieldtype': 'Currency',
- 'idx': 11,
'label': 'Aggregate Total',
'oldfieldname': 'total',
'oldfieldtype': 'Currency',
@@ -201,7 +190,6 @@
'fieldname': 'parenttype',
'fieldtype': 'Data',
'hidden': 1,
- 'idx': 12,
'in_filter': 1,
'label': 'Parenttype',
'oldfieldname': 'parenttype',
@@ -218,7 +206,6 @@
'fieldname': 'total_tax_amount',
'fieldtype': 'Currency',
'hidden': 1,
- 'idx': 13,
'label': 'Total +Tax',
'no_copy': 1,
'oldfieldname': 'total_tax_amount',
@@ -235,7 +222,6 @@
'fieldname': 'total_amount',
'fieldtype': 'Currency',
'hidden': 1,
- 'idx': 14,
'label': 'Tax Amount',
'no_copy': 1,
'oldfieldname': 'total_amount',
diff --git a/erpnext/accounts/doctype/pv_detail/pv_detail.txt b/erpnext/accounts/doctype/pv_detail/pv_detail.txt
old mode 100644
new mode 100755
index 1e05160..e1181b0
--- a/erpnext/accounts/doctype/pv_detail/pv_detail.txt
+++ b/erpnext/accounts/doctype/pv_detail/pv_detail.txt
@@ -5,7 +5,7 @@
{
'creation': '2010-08-08 17:09:17',
'docstatus': 0,
- 'modified': '2011-03-30 11:23:38',
+ 'modified': '2011-12-14 10:44:21',
'modified_by': 'Administrator',
'owner': 'Administrator'
},
@@ -14,6 +14,7 @@
{
'autoname': 'EVD.######',
'colour': 'White:FFF',
+ 'default_print_format': 'Standard',
'doctype': 'DocType',
'istable': 1,
'module': 'Accounts',
@@ -21,7 +22,7 @@
'section_style': 'Tray',
'server_code_error': ' ',
'show_in_menu': 0,
- 'version': 26
+ 'version': 42
},
# These values are common for all DocField
@@ -44,7 +45,6 @@
'doctype': 'DocField',
'fieldname': 'item_code',
'fieldtype': 'Link',
- 'idx': 1,
'in_filter': 1,
'label': 'Item',
'oldfieldname': 'item_code',
@@ -62,7 +62,6 @@
'doctype': 'DocField',
'fieldname': 'item_name',
'fieldtype': 'Data',
- 'idx': 2,
'in_filter': 0,
'label': 'Item Name',
'oldfieldname': 'item_name',
@@ -75,22 +74,8 @@
# DocField
{
'doctype': 'DocField',
- 'fieldname': 'brand',
- 'fieldtype': 'Data',
- 'idx': 3,
- 'label': 'Brand',
- 'oldfieldname': 'brand',
- 'oldfieldtype': 'Data',
- 'permlevel': 0,
- 'print_hide': 1
- },
-
- # DocField
- {
- 'doctype': 'DocField',
'fieldname': 'description',
'fieldtype': 'Text',
- 'idx': 4,
'label': 'Description',
'oldfieldname': 'description',
'oldfieldtype': 'Text',
@@ -101,55 +86,8 @@
# DocField
{
'doctype': 'DocField',
- 'fieldname': 'item_group',
- 'fieldtype': 'Link',
- 'idx': 5,
- 'in_filter': 1,
- 'label': 'Item Group',
- 'oldfieldname': 'item_group',
- 'oldfieldtype': 'Link',
- 'options': 'Item Group',
- 'permlevel': 1,
- 'print_hide': 1,
- 'search_index': 0
- },
-
- # DocField
- {
- 'doctype': 'DocField',
- 'fieldname': 'rate',
- 'fieldtype': 'Currency',
- 'idx': 6,
- 'label': 'Rate (Default Curr.)',
- 'oldfieldname': 'rate',
- 'oldfieldtype': 'Currency',
- 'permlevel': 0,
- 'print_hide': 1,
- 'reqd': 1,
- 'trigger': 'Client'
- },
-
- # DocField
- {
- 'doctype': 'DocField',
- 'fieldname': 'import_rate',
- 'fieldtype': 'Currency',
- 'idx': 7,
- 'label': 'Rate',
- 'oldfieldname': 'import_rate',
- 'oldfieldtype': 'Currency',
- 'permlevel': 0,
- 'print_hide': 0,
- 'reqd': 1,
- 'trigger': 'Client'
- },
-
- # DocField
- {
- 'doctype': 'DocField',
'fieldname': 'qty',
'fieldtype': 'Currency',
- 'idx': 8,
'label': 'Qty',
'oldfieldname': 'qty',
'oldfieldtype': 'Currency',
@@ -162,9 +100,78 @@
# DocField
{
'doctype': 'DocField',
+ 'fieldname': 'import_ref_rate',
+ 'fieldtype': 'Currency',
+ 'label': 'Ref Rate ',
+ 'permlevel': 0,
+ 'trigger': 'Client'
+ },
+
+ # DocField
+ {
+ 'doctype': 'DocField',
+ 'fieldname': 'discount_rate',
+ 'fieldtype': 'Currency',
+ 'label': 'Discount %',
+ 'permlevel': 0,
+ 'trigger': 'Client'
+ },
+
+ # DocField
+ {
+ 'doctype': 'DocField',
+ 'fieldname': 'import_rate',
+ 'fieldtype': 'Currency',
+ 'label': 'Rate ',
+ 'oldfieldname': 'import_rate',
+ 'oldfieldtype': 'Currency',
+ 'permlevel': 0,
+ 'print_hide': 0,
+ 'reqd': 1,
+ 'trigger': 'Client'
+ },
+
+ # DocField
+ {
+ 'doctype': 'DocField',
+ 'fieldname': 'import_amount',
+ 'fieldtype': 'Currency',
+ 'label': 'Amount',
+ 'oldfieldname': 'import_amount',
+ 'oldfieldtype': 'Currency',
+ 'permlevel': 1,
+ 'reqd': 1
+ },
+
+ # DocField
+ {
+ 'doctype': 'DocField',
+ 'fieldname': 'purchase_ref_rate',
+ 'fieldtype': 'Currency',
+ 'label': 'Ref Rate *',
+ 'permlevel': 0,
+ 'trigger': 'Client'
+ },
+
+ # DocField
+ {
+ 'doctype': 'DocField',
+ 'fieldname': 'rate',
+ 'fieldtype': 'Currency',
+ 'label': 'Rate *(Default Curr.)',
+ 'oldfieldname': 'rate',
+ 'oldfieldtype': 'Currency',
+ 'permlevel': 0,
+ 'print_hide': 1,
+ 'reqd': 1,
+ 'trigger': 'Client'
+ },
+
+ # DocField
+ {
+ 'doctype': 'DocField',
'fieldname': 'amount',
'fieldtype': 'Currency',
- 'idx': 9,
'label': 'Amount (Default Curr.)',
'oldfieldname': 'amount',
'oldfieldtype': 'Currency',
@@ -175,24 +182,10 @@
# DocField
{
- 'doctype': 'DocField',
- 'fieldname': 'import_amount',
- 'fieldtype': 'Currency',
- 'idx': 10,
- 'label': 'Amount',
- 'oldfieldname': 'import_amount',
- 'oldfieldtype': 'Currency',
- 'permlevel': 1,
- 'reqd': 1
- },
-
- # DocField
- {
'colour': 'White:FFF',
'doctype': 'DocField',
'fieldname': 'expense_head',
'fieldtype': 'Link',
- 'idx': 11,
'label': 'Expense Head',
'oldfieldname': 'expense_head',
'oldfieldtype': 'Link',
@@ -210,7 +203,6 @@
'doctype': 'DocField',
'fieldname': 'cost_center',
'fieldtype': 'Link',
- 'idx': 12,
'label': 'Cost Center',
'oldfieldname': 'cost_center',
'oldfieldtype': 'Link',
@@ -223,10 +215,49 @@
# DocField
{
+ 'colour': 'White:FFF',
+ 'doctype': 'DocField',
+ 'fieldname': 'project_name',
+ 'fieldtype': 'Link',
+ 'in_filter': 1,
+ 'label': 'Project Name',
+ 'options': 'Project',
+ 'permlevel': 0,
+ 'print_hide': 1
+ },
+
+ # DocField
+ {
+ 'doctype': 'DocField',
+ 'fieldname': 'brand',
+ 'fieldtype': 'Data',
+ 'label': 'Brand',
+ 'oldfieldname': 'brand',
+ 'oldfieldtype': 'Data',
+ 'permlevel': 0,
+ 'print_hide': 1
+ },
+
+ # DocField
+ {
+ 'doctype': 'DocField',
+ 'fieldname': 'item_group',
+ 'fieldtype': 'Link',
+ 'in_filter': 1,
+ 'label': 'Item Group',
+ 'oldfieldname': 'item_group',
+ 'oldfieldtype': 'Link',
+ 'options': 'Item Group',
+ 'permlevel': 1,
+ 'print_hide': 1,
+ 'search_index': 1
+ },
+
+ # DocField
+ {
'doctype': 'DocField',
'fieldname': 'purchase_order',
'fieldtype': 'Link',
- 'idx': 13,
'in_filter': 1,
'label': 'Pur Order',
'oldfieldname': 'purchase_order',
@@ -243,7 +274,6 @@
'fieldname': 'po_detail',
'fieldtype': 'Data',
'hidden': 1,
- 'idx': 14,
'in_filter': 1,
'label': 'PO Detail',
'oldfieldname': 'po_detail',
@@ -258,7 +288,6 @@
'doctype': 'DocField',
'fieldname': 'purchase_receipt',
'fieldtype': 'Link',
- 'idx': 15,
'in_filter': 1,
'label': 'Pur Receipt',
'oldfieldname': 'purchase_receipt',
@@ -275,7 +304,6 @@
'fieldname': 'pr_detail',
'fieldtype': 'Data',
'hidden': 1,
- 'idx': 16,
'in_filter': 1,
'label': 'PR Detail',
'oldfieldname': 'pr_detail',
@@ -291,7 +319,6 @@
'doctype': 'DocField',
'fieldname': 'item_tax_rate',
'fieldtype': 'Small Text',
- 'idx': 17,
'label': 'Item Tax Rate',
'oldfieldname': 'item_tax_rate',
'oldfieldtype': 'Small Text',
@@ -306,7 +333,6 @@
'doctype': 'DocField',
'fieldname': 'page_break',
'fieldtype': 'Check',
- 'idx': 18,
'label': 'Page Break',
'no_copy': 1,
'permlevel': 0,
diff --git a/erpnext/accounts/doctype/receivable_voucher/receivable_voucher.js b/erpnext/accounts/doctype/receivable_voucher/receivable_voucher.js
index ec8f291..c2b478e 100644
--- a/erpnext/accounts/doctype/receivable_voucher/receivable_voucher.js
+++ b/erpnext/accounts/doctype/receivable_voucher/receivable_voucher.js
@@ -18,6 +18,8 @@
if(!doc.voucher_date) set_multiple(dt,dn,{voucher_date:get_today()});
if(!doc.due_date) set_multiple(dt,dn,{due_date:get_today()});
if(!doc.posting_date) set_multiple(dt,dn,{posting_date:get_today()});
+ if(!doc.currency && sys_defaults.currency) set_multiple(cdt,cdn,{currency:sys_defaults.currency});
+ if(!doc.price_list_currency) set_multiple(cdt, cdn, {price_list_currency: doc.currency, plc_conversion_rate: 1});
//for previously created sales invoice, set required field related to pos
if(doc.is_pos ==1) cur_frm.cscript.is_pos(doc, dt, dn);
@@ -48,9 +50,9 @@
// Hide Fields
// ------------
cur_frm.cscript.hide_fields = function(doc, cdt, cdn) {
- par_flds =['project_name', 'due_date', 'posting_time', 'sales_order_main', 'delivery_note_main', 'Get Items', 'company', 'is_opening', 'currency', 'conversion_rate', 'price_list_name', 'cash_bank_account', 'source', 'cancel_reason', 'total_advance', 'gross_profit', 'gross_profit_percent', 'Get Advances Received', 'advance_adjustment_details', 'sales_partner', 'commission_rate', 'total_commission', 'Repair Outstanding Amt'];
+ par_flds =['project_name', 'due_date', 'posting_time', 'sales_order_main', 'delivery_note_main', 'Get Items', 'is_opening', 'conversion_rate', 'source', 'cancel_reason', 'total_advance', 'gross_profit', 'gross_profit_percent', 'Get Advances Received', 'advance_adjustment_details', 'sales_partner', 'commission_rate', 'total_commission', 'Repair Outstanding Amt'];
- ch_flds = {'entries': ['income_account', 'warehouse', 'cost_center', 'sales_order', 'delivery_note']}
+ ch_flds = {'entries': ['sales_order', 'delivery_note']}
if(cint(doc.is_pos) == 1) {
hide_field(par_flds);
@@ -67,6 +69,12 @@
}
}
}
+
+ // India related fields
+ var cp = locals['Control Panel']['Control Panel'];
+ if (cp.country == 'India') unhide_field(['c_form_applicable', 'c_form_no']);
+ else hide_field(['c_form_applicable', 'c_form_no']);
+
}
@@ -74,6 +82,9 @@
// -------
cur_frm.cscript.refresh = function(doc, dt, dn) {
+ cur_frm.cscript.is_opening(doc, dt, dn);
+ cur_frm.cscript.hide_fields(doc, cdt, cdn);
+
// Show / Hide button
cur_frm.clear_custom_buttons();
@@ -90,8 +101,6 @@
}
else
hide_field('Repair Outstanding Amt');
- cur_frm.cscript.is_opening(doc, dt, dn);
- cur_frm.cscript.hide_fields(doc, cdt, cdn);
}
//fetch retail transaction related fields
@@ -227,13 +236,6 @@
/* **************************** TRIGGERS ********************************** */
-
-
-// Posting Date
-// ------------
-//cur_frm.cscript.posting_date = cur_frm.cscript.debit_to;
-
-
// Get Items based on SO or DN Selected
cur_frm.cscript['Get Items'] = function(doc, dt, dn) {
var callback = function(r,rt) {
@@ -432,3 +434,12 @@
}
loadreport('GL Entry','General Ledger', callback);
}
+
+// Default values for recurring invoices
+cur_frm.cscript.convert_into_recurring_invoice = function(doc) {
+ if (doc.convert_into_recurring_invoice) {
+ doc.repeat_on_day_of_month = doc.posting_date.split('-')[2];
+ doc.notification_email_address = doc.owner + ', ' + doc.contact_email;
+ refresh_field(['repeat_on_day_of_month', 'notification_email_address']);
+ }
+}
diff --git a/erpnext/accounts/doctype/receivable_voucher/receivable_voucher.py b/erpnext/accounts/doctype/receivable_voucher/receivable_voucher.py
index 6d1f80a..536bb6d 100644
--- a/erpnext/accounts/doctype/receivable_voucher/receivable_voucher.py
+++ b/erpnext/accounts/doctype/receivable_voucher/receivable_voucher.py
@@ -1,12 +1,13 @@
# Please edit this list and import only required elements
import webnotes
-from webnotes.utils import add_days, add_months, add_years, cint, cstr, date_diff, default_fields, flt, fmt_money, formatdate, generate_hash, getTraceback, get_defaults, get_first_day, get_last_day, getdate, has_common, month_name, now, nowdate, replace_newlines, sendmail, set_default, str_esc_quote, user_format, validate_email_add
+from webnotes.utils import add_days, add_months, add_years, cint, cstr,date_diff, default_fields, flt, fmt_money, formatdate, generate_hash,getTraceback, get_defaults, get_first_day, get_last_day, getdate, has_common,month_name, now, nowdate, replace_newlines, sendmail, set_default,str_esc_quote, user_format, validate_email_add
from webnotes.model import db_exists
from webnotes.model.doc import Document, addchild, removechild, getchildren, make_autoname, SuperDocType
from webnotes.model.doclist import getlist, copy_doclist
from webnotes.model.code import get_obj, get_server_obj, run_server_obj, updatedb, check_syntax
from webnotes import session, form, is_testing, msgprint, errprint
+from webnotes.utils.scheduler import set_event, cancel_event, Scheduler
set = webnotes.conn.set
sql = webnotes.conn.sql
@@ -163,6 +164,10 @@
ret['actual_qty']= actual_qty and flt(actual_qty[0][0]) or 0
return ret
+ # Fetch ref rate from item master as per selected price list
+ def get_adj_percent(self, arg=''):
+ get_obj('Sales Common').get_adj_percent(self)
+
# Get tax rate if account type is tax
# ------------------------------------
@@ -396,6 +401,14 @@
if flt(self.doc.write_off_amount) and not self.doc.write_off_account:
msgprint("Please enter Write Off Account", raise_exception=1)
+
+ def validate_c_form(self):
+ """ Blank C-form no if C-form applicable marked as 'No'"""
+ if self.doc.amended_from and self.doc.c_form_applicable == 'No' and self.doc.c_form_no:
+ sql("""delete from `tabC-Form Invoice Detail` where invoice_no = %s
+ and parent = %s""", (self.doc.amended_from, self.doc.c_form_no))
+
+ set(self.doc, 'c_form_no', '')
# VALIDATE
# ====================================================================================
@@ -431,6 +444,7 @@
self.clear_advances()
# Set against account
self.set_against_income_account()
+ self.validate_c_form()
# *************************************************** ON SUBMIT **********************************************
@@ -506,7 +520,7 @@
if stock_item[0]['is_stock_item'] == "Yes":
# Reduce actual qty from warehouse
self.make_sl_entry( d, d.warehouse, - flt(d.qty) , 0, update_stock)
- get_obj('Stock Ledger', 'Stock Ledger').update_stock(self.values)
+ get_obj('Stock Ledger', 'Stock Ledger').update_stock(self.values, self.doc.amended_from and 'Yes' or 'No')
#-------------------POS Stock Updatation Part----------------------------------------------
@@ -528,7 +542,6 @@
def make_gl_entries(self, is_cancel=0):
mapper = self.doc.is_pos and self.doc.write_off_account and 'POS with write off' or self.doc.is_pos and not self.doc.write_off_account and 'POS' or ''
update_outstanding = self.doc.is_pos and self.doc.write_off_account and 'No' or 'Yes'
-
get_obj(dt='GL Control').make_gl_entries(self.doc, self.doclist,cancel = is_cancel, use_mapper = mapper, update_outstanding = update_outstanding, merge_entries = cint(self.doc.is_pos) != 1 and 1 or 0)
@@ -546,17 +559,29 @@
get_obj("Sales Common").update_prevdoc_detail(1,self)
# Check for Approving Authority
- get_obj('Authorization Control').validate_approving_authority(self.doc.doctype, self.doc.company, self.doc.grand_total, self)
+ if not self.doc.recurring_id:
+ get_obj('Authorization Control').validate_approving_authority(self.doc.doctype, self.doc.company, self.doc.grand_total, self)
# this sequence because outstanding may get -ve
self.make_gl_entries()
if not cint(self.doc.is_pos) == 1:
self.update_against_document_in_jv()
-
+
+ self.update_c_form()
+
# on submit notification
# get_obj('Notification Control').notify_contact('Sales Invoice', self.doc.doctype,self.doc.name, self.doc.email_id, self.doc.contact_person)
-
+
+
+ def update_c_form(self):
+ """Update amended id in C-form"""
+ if self.doc.c_form_no and self.doc.amended_from:
+ sql("""update `tabC-Form Invoice Detail` set invoice_no = %s,
+ invoice_date = %s, territory = %s, net_total = %s,
+ grand_total = %s where invoice_no = %s and parent = %s""", (self.doc.name, self.doc.amended_from, self.doc.c_form_no))
+
+
# *************************************************** ON CANCEL **********************************************
# Check Next Document's docstatus
@@ -618,9 +643,67 @@
set(self.doc,'outstanding_amount',flt(self.doc.grand_total) - flt(self.doc.total_advance) - flt(self.doc.paid_amount) - flt(self.doc.write_off_amount))
-
########################################################################
# Repair Outstanding
-#######################################################################
+
def repair_rv_outstanding(self):
get_obj(dt = 'GL Control').repair_voucher_outstanding(self)
+
+
+ #-------------------------------------------------------------------------------------
+ def on_update_after_submit(self):
+ self.convert_into_recurring()
+
+
+ def convert_into_recurring(self):
+ if self.doc.convert_into_recurring_invoice:
+ self.set_next_date()
+ if not self.doc.recurring_id:
+ set(self.doc, 'recurring_id', make_autoname('RECINV/.#####'))
+ elif self.doc.recurring_id:
+ sql("""update `tabReceivable Voucher` set convert_into_recurring_invoice = 0 where recurring_id = %s""", self.doc.recurring_id)
+
+ self.manage_scheduler()
+
+ def manage_scheduler(self):
+ """ set/cancel event in scheduler """
+ event = 'accounts.doctype.gl_control.gl_control.manage_recurring_invoices'
+
+ if sql("select name from `tabReceivable Voucher` where ifnull(convert_into_recurring_invoice, 0) = 1 and next_date <= end_date"):
+ if not self.check_event_exists(event):
+ set_event(event, interval = 60*60, recurring = 1)
+ else:
+ cancel_event(event)
+
+
+ def check_event_exists(self, event):
+ try:
+ ev = Scheduler().get_events()
+ except:
+ msgprint("Scheduler database not exists. Please mail to support@erpnext.com", raise_exception=1)
+
+ if event in [d['event'] for d in ev]:
+ return 1
+
+
+ def set_next_date(self):
+ """ Set next date on which auto invoice will be created"""
+
+ if not self.doc.repeat_on_day_of_month:
+ msgprint("""Please enter 'Repeat on Day of Month' field value. \nThe day of the month on which auto invoice
+ will be generated e.g. 05, 28 etc.""", raise_exception=1)
+
+ import datetime
+ m = getdate(self.doc.posting_date).month + 1
+ y = getdate(self.doc.posting_date).year
+ if m > 12:
+ m, y = 1, y+1
+ try:
+ next_date = datetime.date(y, m, cint(self.doc.repeat_on_day_of_month))
+ except:
+ import calendar
+ last_day = calendar.monthrange(y, m)[1]
+ next_date = datetime.date(y, m, last_day)
+ next_date = next_date.strftime("%Y-%m-%d")
+
+ set(self.doc, 'next_date', next_date)
diff --git a/erpnext/accounts/doctype/receivable_voucher/receivable_voucher.txt b/erpnext/accounts/doctype/receivable_voucher/receivable_voucher.txt
index 2f3b48d..c194e7c 100644
--- a/erpnext/accounts/doctype/receivable_voucher/receivable_voucher.txt
+++ b/erpnext/accounts/doctype/receivable_voucher/receivable_voucher.txt
@@ -5,14 +5,23 @@
{
'creation': '2010-08-08 17:09:18',
'docstatus': 0,
- 'modified': '2011-10-10 12:29:26',
+ 'modified': '2011-12-22 19:04:07',
'modified_by': 'Administrator',
'owner': 'Administrator'
},
+ # These values are common for all DocField
+ {
+ 'doctype': 'DocField',
+ 'name': '__common__',
+ 'parent': 'Receivable Voucher',
+ 'parentfield': 'fields',
+ 'parenttype': 'DocType'
+ },
+
# These values are common for all DocType
{
- '_last_update': '1317986484',
+ '_last_update': '1324367593',
'change_log': '1. Change in pull_details method dt.-26-06-2009',
'colour': 'White:FFF',
'default_print_format': 'Standard',
@@ -25,15 +34,15 @@
'server_code_error': ' ',
'show_in_menu': 0,
'subject': 'To %(customer_name)s worth %(currency)s %(grand_total_export)s due on %(due_date)s | %(outstanding_amount)s outstanding',
- 'version': 359
+ 'version': 392
},
- # These values are common for all DocField
+ # These values are common for all DocFormat
{
- 'doctype': 'DocField',
+ 'doctype': 'DocFormat',
'name': '__common__',
'parent': 'Receivable Voucher',
- 'parentfield': 'fields',
+ 'parentfield': 'formats',
'parenttype': 'DocType'
},
@@ -114,6 +123,36 @@
'write': 0
},
+ # DocFormat
+ {
+ 'doctype': 'DocFormat',
+ 'format': 'POS Invoice'
+ },
+
+ # DocFormat
+ {
+ 'doctype': 'DocFormat',
+ 'format': 'POS Invoice'
+ },
+
+ # DocFormat
+ {
+ 'doctype': 'DocFormat',
+ 'format': 'Sales Invoice Classic'
+ },
+
+ # DocFormat
+ {
+ 'doctype': 'DocFormat',
+ 'format': 'Sales Invoice Modern'
+ },
+
+ # DocFormat
+ {
+ 'doctype': 'DocFormat',
+ 'format': 'Sales Invoice Spartan'
+ },
+
# DocField
{
'doctype': 'DocField',
@@ -455,42 +494,28 @@
# DocField
{
'colour': 'White:FFF',
- 'description': 'Select Items from Sales Order',
+ 'description': 'Select the currency in which price list is maintained',
'doctype': 'DocField',
- 'fieldname': 'sales_order_main',
- 'fieldtype': 'Link',
- 'label': 'Sales Order',
- 'oldfieldname': 'sales_order_main',
- 'oldfieldtype': 'Link',
- 'options': 'Sales Order',
+ 'fieldname': 'price_list_currency',
+ 'fieldtype': 'Select',
+ 'label': 'Price List Currency',
+ 'options': 'link:Currency',
'permlevel': 0,
- 'print_hide': 1
+ 'print_hide': 1,
+ 'reqd': 1
},
# DocField
{
'colour': 'White:FFF',
- 'description': 'Select Items from Delivery Note',
+ 'description': 'Rate at which Price list currency is converted to your currency',
'doctype': 'DocField',
- 'fieldname': 'delivery_note_main',
- 'fieldtype': 'Link',
- 'label': 'Delivery Note',
- 'oldfieldname': 'delivery_note_main',
- 'oldfieldtype': 'Link',
- 'options': 'Delivery Note',
- 'permlevel': 0,
- 'print_hide': 1
- },
-
- # DocField
- {
- 'doctype': 'DocField',
- 'fieldtype': 'Button',
- 'label': 'Get Items',
- 'oldfieldtype': 'Button',
+ 'fieldname': 'plc_conversion_rate',
+ 'fieldtype': 'Currency',
+ 'label': 'Price List Currency Conversion Rate',
'permlevel': 0,
'print_hide': 1,
- 'trigger': 'Client'
+ 'reqd': 1
},
# DocField
@@ -531,6 +556,47 @@
# DocField
{
+ 'colour': 'White:FFF',
+ 'description': 'Select Items from Sales Order',
+ 'doctype': 'DocField',
+ 'fieldname': 'sales_order_main',
+ 'fieldtype': 'Link',
+ 'label': 'Sales Order',
+ 'oldfieldname': 'sales_order_main',
+ 'oldfieldtype': 'Link',
+ 'options': 'Sales Order',
+ 'permlevel': 0,
+ 'print_hide': 1
+ },
+
+ # DocField
+ {
+ 'colour': 'White:FFF',
+ 'description': 'Select Items from Delivery Note',
+ 'doctype': 'DocField',
+ 'fieldname': 'delivery_note_main',
+ 'fieldtype': 'Link',
+ 'label': 'Delivery Note',
+ 'oldfieldname': 'delivery_note_main',
+ 'oldfieldtype': 'Link',
+ 'options': 'Delivery Note',
+ 'permlevel': 0,
+ 'print_hide': 1
+ },
+
+ # DocField
+ {
+ 'doctype': 'DocField',
+ 'fieldtype': 'Button',
+ 'label': 'Get Items',
+ 'oldfieldtype': 'Button',
+ 'permlevel': 0,
+ 'print_hide': 1,
+ 'trigger': 'Client'
+ },
+
+ # DocField
+ {
'doctype': 'DocField',
'fieldtype': 'Section Break',
'permlevel': 0
@@ -959,6 +1025,31 @@
# DocField
{
'doctype': 'DocField',
+ 'fieldname': 'c_form_applicable',
+ 'fieldtype': 'Select',
+ 'label': 'C-Form Applicable',
+ 'no_copy': 1,
+ 'options': 'No\nYes',
+ 'permlevel': 0,
+ 'print_hide': 1,
+ 'report_hide': 0
+ },
+
+ # DocField
+ {
+ 'doctype': 'DocField',
+ 'fieldname': 'c_form_no',
+ 'fieldtype': 'Link',
+ 'label': 'C-Form No',
+ 'no_copy': 1,
+ 'options': 'C-Form',
+ 'permlevel': 1,
+ 'print_hide': 1
+ },
+
+ # DocField
+ {
+ 'doctype': 'DocField',
'fieldname': 'company',
'fieldtype': 'Link',
'in_filter': 1,
@@ -1328,5 +1419,115 @@
'permlevel': 0,
'print_hide': 1,
'report_hide': 1
+ },
+
+ # DocField
+ {
+ 'depends_on': 'eval:doc.docstatus==1',
+ 'doctype': 'DocField',
+ 'fieldtype': 'Section Break',
+ 'label': 'Recurring Invoice',
+ 'permlevel': 0
+ },
+
+ # DocField
+ {
+ 'doctype': 'DocField',
+ 'fieldtype': 'Column Break',
+ 'permlevel': 0,
+ 'width': '50%'
+ },
+
+ # DocField
+ {
+ 'allow_on_submit': 1,
+ 'colour': 'White:FFF',
+ 'depends_on': 'eval:doc.docstatus==1',
+ 'description': 'Check if recurring invoice, uncheck to stop recurring or put proper End Date',
+ 'doctype': 'DocField',
+ 'fieldname': 'convert_into_recurring_invoice',
+ 'fieldtype': 'Check',
+ 'label': 'Convert into Recurring Invoice',
+ 'no_copy': 1,
+ 'permlevel': 0,
+ 'print_hide': 1,
+ 'trigger': 'Client'
+ },
+
+ # DocField
+ {
+ 'allow_on_submit': 1,
+ 'depends_on': 'eval:doc.convert_into_recurring_invoice==1',
+ 'description': 'The day of the month on which auto invoice will be generated e.g. 05, 28 etc ',
+ 'doctype': 'DocField',
+ 'fieldname': 'repeat_on_day_of_month',
+ 'fieldtype': 'Data',
+ 'label': 'Repeat on Day of Month',
+ 'no_copy': 1,
+ 'permlevel': 0,
+ 'print_hide': 1
+ },
+
+ # DocField
+ {
+ 'allow_on_submit': 1,
+ 'depends_on': 'eval:doc.convert_into_recurring_invoice==1',
+ 'description': 'The date on which recurring invoice will be stop',
+ 'doctype': 'DocField',
+ 'fieldname': 'end_date',
+ 'fieldtype': 'Date',
+ 'label': 'End Date',
+ 'no_copy': 1,
+ 'permlevel': 0,
+ 'print_hide': 1
+ },
+
+ # DocField
+ {
+ 'doctype': 'DocField',
+ 'fieldtype': 'Column Break',
+ 'no_copy': 0,
+ 'permlevel': 0,
+ 'width': '50%'
+ },
+
+ # DocField
+ {
+ 'allow_on_submit': 1,
+ 'depends_on': 'eval:doc.convert_into_recurring_invoice==1',
+ 'description': 'Enter email id separated by commas, invoice will be mailed automatically on particular date',
+ 'doctype': 'DocField',
+ 'fieldname': 'notification_email_address',
+ 'fieldtype': 'Small Text',
+ 'label': 'Notification Email Address',
+ 'no_copy': 1,
+ 'permlevel': 0,
+ 'print_hide': 1
+ },
+
+ # DocField
+ {
+ 'depends_on': 'eval:doc.convert_into_recurring_invoice==1',
+ 'description': 'The unique id for tracking all recurring invoices ',
+ 'doctype': 'DocField',
+ 'fieldname': 'recurring_id',
+ 'fieldtype': 'Data',
+ 'label': 'Recurring Id',
+ 'no_copy': 1,
+ 'permlevel': 1,
+ 'print_hide': 1
+ },
+
+ # DocField
+ {
+ 'depends_on': 'eval:doc.convert_into_recurring_invoice==1',
+ 'description': 'The date on which next invoice will be generated ',
+ 'doctype': 'DocField',
+ 'fieldname': 'next_date',
+ 'fieldtype': 'Date',
+ 'label': 'Next Date',
+ 'no_copy': 1,
+ 'permlevel': 1,
+ 'print_hide': 1
}
]
\ No newline at end of file
diff --git a/erpnext/accounts/doctype/rv_tax_detail/rv_tax_detail.txt b/erpnext/accounts/doctype/rv_tax_detail/rv_tax_detail.txt
index a9326a0..784c3b7 100644
--- a/erpnext/accounts/doctype/rv_tax_detail/rv_tax_detail.txt
+++ b/erpnext/accounts/doctype/rv_tax_detail/rv_tax_detail.txt
@@ -5,8 +5,8 @@
{
'creation': '2010-08-08 17:09:20',
'docstatus': 0,
- 'modified': '2010-09-20 14:06:57',
- 'modified_by': 'nabin@webnotestech.com',
+ 'modified': '2011-12-28 17:33:30',
+ 'modified_by': 'Administrator',
'owner': 'Administrator'
},
@@ -14,6 +14,7 @@
{
'autoname': 'INVTD.######',
'colour': 'White:FFF',
+ 'default_print_format': 'Standard',
'doctype': 'DocType',
'hide_heading': 1,
'istable': 1,
@@ -22,7 +23,7 @@
'section_style': 'Tray',
'server_code_error': ' ',
'show_in_menu': 0,
- 'version': 15
+ 'version': 18
},
# These values are common for all DocField
@@ -45,7 +46,6 @@
'doctype': 'DocField',
'fieldname': 'charge_type',
'fieldtype': 'Select',
- 'idx': 1,
'label': 'Type',
'oldfieldname': 'charge_type',
'oldfieldtype': 'Select',
@@ -60,7 +60,6 @@
'doctype': 'DocField',
'fieldname': 'account_head',
'fieldtype': 'Link',
- 'idx': 2,
'label': 'Account Head',
'oldfieldname': 'account_head',
'oldfieldtype': 'Link',
@@ -75,13 +74,11 @@
'doctype': 'DocField',
'fieldname': 'cost_center_other_charges',
'fieldtype': 'Link',
- 'idx': 3,
'label': 'Cost Center',
'oldfieldname': 'cost_center_other_charges',
'oldfieldtype': 'Link',
'options': 'Cost Center',
- 'permlevel': 0,
- 'search_index': 0
+ 'permlevel': 0
},
# DocField
@@ -89,7 +86,6 @@
'doctype': 'DocField',
'fieldname': 'description',
'fieldtype': 'Small Text',
- 'idx': 4,
'label': 'Description',
'oldfieldname': 'description',
'oldfieldtype': 'Small Text',
@@ -103,7 +99,6 @@
'doctype': 'DocField',
'fieldname': 'rate',
'fieldtype': 'Currency',
- 'idx': 5,
'label': 'Rate',
'oldfieldname': 'rate',
'oldfieldtype': 'Currency',
@@ -117,7 +112,6 @@
'doctype': 'DocField',
'fieldname': 'tax_amount',
'fieldtype': 'Currency',
- 'idx': 6,
'label': 'Amount*',
'oldfieldname': 'tax_amount',
'oldfieldtype': 'Currency',
@@ -131,7 +125,6 @@
'doctype': 'DocField',
'fieldname': 'total',
'fieldtype': 'Currency',
- 'idx': 7,
'label': 'Total*',
'oldfieldname': 'total',
'oldfieldtype': 'Currency',
@@ -144,7 +137,6 @@
'fieldname': 'row_id',
'fieldtype': 'Data',
'hidden': 0,
- 'idx': 8,
'label': 'Enter Row',
'oldfieldname': 'row_id',
'oldfieldtype': 'Data',
@@ -157,7 +149,6 @@
'doctype': 'DocField',
'fieldname': 'item_wise_tax_detail',
'fieldtype': 'Small Text',
- 'idx': 9,
'label': 'Item Wise Tax Detail ',
'oldfieldname': 'item_wise_tax_detail',
'oldfieldtype': 'Small Text',
@@ -170,7 +161,6 @@
'fieldname': 'parenttype',
'fieldtype': 'Data',
'hidden': 1,
- 'idx': 10,
'in_filter': 1,
'label': 'Parenttype',
'oldfieldname': 'parenttype',
@@ -188,7 +178,6 @@
'fieldname': 'total_tax_amount',
'fieldtype': 'Currency',
'hidden': 1,
- 'idx': 11,
'label': 'Total Tax Amount',
'no_copy': 1,
'oldfieldname': 'total_tax_amount',
@@ -205,7 +194,6 @@
'fieldname': 'total_amount',
'fieldtype': 'Currency',
'hidden': 1,
- 'idx': 12,
'label': 'Total Amount',
'no_copy': 1,
'oldfieldname': 'total_amount',
@@ -213,5 +201,20 @@
'permlevel': 0,
'print_hide': 1,
'report_hide': 1
+ },
+
+ # DocField
+ {
+ 'allow_on_submit': 0,
+ 'description': 'If checked, the tax amount will be considered as already included in the Print Rate / Print Amount',
+ 'doctype': 'DocField',
+ 'fieldname': 'included_in_print_rate',
+ 'fieldtype': 'Check',
+ 'label': 'Included in Print Rate',
+ 'no_column': 0,
+ 'no_copy': 1,
+ 'permlevel': 0,
+ 'print_hide': 1,
+ 'report_hide': 1
}
]
\ No newline at end of file
diff --git a/erpnext/accounts/page/accounts_browser/accounts_browser.js b/erpnext/accounts/page/accounts_browser/accounts_browser.js
index 38acfc9..61b36d2 100644
--- a/erpnext/accounts/page/accounts_browser/accounts_browser.js
+++ b/erpnext/accounts/page/accounts_browser/accounts_browser.js
@@ -31,7 +31,7 @@
var footer = $a($i('ab_body'),'div','',{backgroundColor: "#FFD", padding: "8px", color: "#444", fontSize: "12px", marginTop: "14px"});
var help1 = $a(footer,'span');
- help1.innerHTML = "<strong>Note:</strong> To create accounts for Customers and Suppliers, please create <a href='#Page/Selling'>Customer</a> and <a href='#Page/Buying'>Supplier</a>"
+ help1.innerHTML = "<strong>Note:</strong> To create accounts for Customers and Suppliers, please create <a href='#!List/Customer'>Customer</a> and <a href='#!List/Supplier'>Supplier</a>"
+ " Masters. This will ensure that the accounts are linked to your Selling and Buying Processes. The Account Heads for Customer and Supplier will automatically be created."
}
@@ -124,7 +124,7 @@
var imgsrc=null;
var has_children = true;
if(cl[i].group_or_ledger=='Ledger') {
- var imgsrc = 'images/icons/page.gif';
+ var imgsrc = 'lib/images/icons/page.gif';
has_children = false;
}
var t = tree.addNode(n, cl[i].account_name, imgsrc,tree.std_onclick, has_children ? tree.std_onexp : null);
@@ -137,7 +137,7 @@
var imgsrc=null;
var has_children = true;
if(cl[i].group_or_ledger=='Ledger') {
- var imgsrc = 'images/icons/page.gif';
+ var imgsrc = 'lib/images/icons/page.gif';
has_children = false;
}
var t = tree.addNode(n, cl[i].cost_center_name, imgsrc,tree.std_onclick, has_children ? tree.std_onexp : null);
@@ -254,7 +254,7 @@
// refresh
ref_btn = $a(pscript.group_area, 'div', '', {fontSize: '14px',marginBottom: '8px', marginTop: '24px', fontWeight: 'bold'});
- ref_btn.innerHTML = '<img src="images/icons/page_refresh.gif" style="margin-right: 8px"><span class="link_type">Refresh Tree</span>';
+ ref_btn.innerHTML = '<img src="lib/images/icons/page_refresh.gif" style="margin-right: 8px"><span class="link_type">Refresh Tree</span>';
ref_btn.onclick= function() {
pscript.cur_node.clear_child_nodes();
pscript.cur_node.expand();
@@ -312,7 +312,7 @@
//General ledger report link
pscript.gl_rep = $a(pscript.ledger_area, 'div','', {fontSize: '14px',marginBottom: '8px', fontWeight: 'bold'});
- pscript.gl_rep.innerHTML = '<img src="images/icons/report.png" style="margin-right: 8px"><span class="link_type">Open Ledger</span>';
+ pscript.gl_rep.innerHTML = '<img src="lib/images/icons/report.png" style="margin-right: 8px"><span class="link_type">Open Ledger</span>';
pscript.gl_rep.onclick = function(){ pscript.make_report('gl'); }
//Budget report link
diff --git a/erpnext/accounts/search_criteria/payment_receipt_report/payment_receipt_report.py b/erpnext/accounts/search_criteria/payment_receipt_report/payment_receipt_report.py
index 737e658..f92f72c 100644
--- a/erpnext/accounts/search_criteria/payment_receipt_report/payment_receipt_report.py
+++ b/erpnext/accounts/search_criteria/payment_receipt_report/payment_receipt_report.py
@@ -7,21 +7,18 @@
raise Exception
if not filter_values.get('company'):
- msgprint("Select Comapny.")
+ msgprint("Select Company to proceed.")
raise Exception
-#for r in res:
-# par_acc = sql("SELECT parent.name FROM `tabAccount` AS node,`tabAccount` AS parent WHERE node.lft BETWEEN parent.lft AND parent.rgt AND node.name = '%s' and parent.cash_flow_level = 'Yes' ORDER BY parent.lft DESC"% r[0])
-# r.append(par_acc and par_acc[0][0] or '')
col_list = [['Account', 'Link', '150px', 'Account']
,['Total', 'Currency', '150px', '']
-# ,['Parent Account', 'Link', '150px', 'Account']
]
+
for c in col_list:
colnames.append(c[0])
coltypes.append(c[1])
colwidths.append(c[2])
coloptions.append(c[3])
- col_idx[c[0]] = len(colnames) - 1
\ No newline at end of file
+ col_idx[c[0]] = len(colnames) - 1
diff --git a/erpnext/analysis/search_criteria/trend_analyzer/trend_analyzer.js b/erpnext/analysis/search_criteria/trend_analyzer/trend_analyzer.js
index 9a87abb..9426a23 100644
--- a/erpnext/analysis/search_criteria/trend_analyzer/trend_analyzer.js
+++ b/erpnext/analysis/search_criteria/trend_analyzer/trend_analyzer.js
@@ -5,7 +5,7 @@
this.add_filter({fieldname:'period', label:'Period', fieldtype:'Select', options:'Monthly'+NEWLINE+'Quarterly'+NEWLINE+'Half Yearly'+NEWLINE+'Annual',report_default:'Quarterly',ignore : 1, parent:'Profile',in_first_page:1,single_select:1});
- this.add_filter({fieldname:'based_on', label:'Based On', fieldtype:'Select', options:'Item'+NEWLINE+'Item Group'+NEWLINE+'Customer'+NEWLINE+'Customer Group'+NEWLINE+'Territory'+NEWLINE+'Supplier'+NEWLINE+'Supplier Type', ignore : 1, parent:'Profile', report_default:'Item', in_first_page : 1,single_select:1});
+ this.add_filter({fieldname:'based_on', label:'Based On', fieldtype:'Select', options:'Item'+NEWLINE+'Item Group'+NEWLINE+'Customer'+NEWLINE+'Customer Group'+NEWLINE+'Territory'+NEWLINE+'Supplier'+NEWLINE+'Supplier Type'+NEWLINE+'Project', ignore : 1, parent:'Profile', report_default:'Item', in_first_page : 1,single_select:1});
this.add_filter({fieldname:'group_by', label:'Group By', fieldtype:'Select', options:NEWLINE+'Item'+NEWLINE+'Customer'+NEWLINE+'Supplier', ignore : 1, parent:'Profile',single_select:1});
@@ -24,6 +24,7 @@
this.add_filter({fieldname:'territory', label:'Territory', fieldtype:'Link', options:'Territory', ignore : 1, parent:'Profile'});
this.add_filter({fieldname:'supplier', label:'Supplier', fieldtype:'Link', options:'Supplier', ignore : 1, parent:'Profile'});
this.add_filter({fieldname:'supplier_type', label:'Supplier Type', fieldtype:'Link', options:'Supplier Type', ignore : 1, parent:'Profile'});
+ this.add_filter({fieldname:'project', label:'Project', fieldtype:'Link', options:'Project', ignore : 1, parent:'Profile'});
}
@@ -99,6 +100,15 @@
add_cond += ' AND t1.supplier = t3.name';
if(supp_type) add_cond += ' AND t1.supplier_type = "'+supp_type+'"';
break;
+ case 'Project' : pro = this.get_filter('Profile', 'Project').get_value();
+ if (inList(['Purchase Order', 'Purchase Receipt', 'Payable Voucher'], trans)) {
+ col = 'DISTINCT t2.project_name';
+ if(pro) add_cond += ' AND t2.project_name = "'+pro+'"';
+ } else {
+ col = 'DISTINCT t1.project_name';
+ if(pro) add_cond += ' AND t1.project_name = "'+pro+'"';
+ }
+ break;
case 'Item Group' : ig = this.get_filter('Profile', 'Item Group').get_value();
if(ig) sp_cond += ' AND parent.name = "'+ig+'"';
break;
@@ -108,10 +118,11 @@
case 'Territory' : ter = this.get_filter('Profile', 'Territory').get_value();
if(ter) sp_cond += ' AND parent.name = "'+ter+'"';
break;
+
}
- if(based_on == 'Item' || based_on == 'Customer' || based_on == 'Supplier' || based_on == 'Supplier Type')
+ if(based_on == 'Item' || based_on == 'Customer' || based_on == 'Supplier' || based_on == 'Supplier Type' || based_on == 'Project')
var q ='SELECT '+col+' FROM `tab'+trans+'` t1, `tab'+trans_det+'` t2 '+add_tables+' WHERE t1.fiscal_year = "'+fiscal_year+'" and t1.company = "'+company+'" and t2.parent = t1.name '+add_cond;
else
var q = 'SELECT CONCAT(REPEAT(" ", COUNT(parent.name) - 1), node.name) AS "Name" FROM `tab'+based_on+'` node,`tab'+based_on+'` parent WHERE node.lft BETWEEN parent.lft and parent.rgt and node.docstatus !=2 '+sp_cond+' GROUP BY node.name ORDER BY node.lft';
diff --git a/erpnext/analysis/search_criteria/trend_analyzer/trend_analyzer.py b/erpnext/analysis/search_criteria/trend_analyzer/trend_analyzer.py
index 9edf045..42a7c5c 100644
--- a/erpnext/analysis/search_criteria/trend_analyzer/trend_analyzer.py
+++ b/erpnext/analysis/search_criteria/trend_analyzer/trend_analyzer.py
@@ -17,7 +17,7 @@
territory = filter_values.get('territory')
supplier = filter_values.get('supplier')
supplier_type = filter_values.get('supplier_type')
-
+project = filter_values.get('project')
# ********************************************* SET DEFAULTS **************************************************
@@ -41,41 +41,41 @@
# ********************************************* VALIDATIONS ***************************************************
if (based_on in ['Customer','Customer Group','Territory'] and group_by == 'Supplier') or (based_on in ['Supplier','Supplier Type'] and group_by == 'Customer'):
- msgprint("Sorry! You cannot group Trend Analyzer based on %s by %s" % (based_on,group_by))
- raise Exception
+ msgprint("Sorry! You cannot group Trend Analyzer based on %s by %s" % (based_on,group_by))
+ raise Exception
if based_on == group_by:
- msgprint("Based On and Group By value cannot be same for Trend Analyzer")
- raise Exception
+ msgprint("Based On and Group By value cannot be same for Trend Analyzer")
+ raise Exception
# ********************************************** ADD COLUMNS **********************************************
cols = [[based_on, 'Data', '300px', '']]
cr = 1
if based_on == 'Item':
- cols.append(['Item Name','Data','200px',''])
- cr = 2
+ cols.append(['Item Name','Data','200px',''])
+ cr = 2
elif based_on == 'Customer':
- cols.append(['Territory','Link','150px','Territory'])
- cr = 2
+ cols.append(['Territory','Link','150px','Territory'])
+ cr = 2
elif based_on == 'Supplier':
- cols.append(['Supplier Type','Link','150px','Supplier Type'])
- cr = 2
+ cols.append(['Supplier Type','Link','150px','Supplier Type'])
+ cr = 2
if group_by:
- cr += 1
+ cr += 1
if group_by:
- cols.append([group_by,'Data','150px',''])
+ cols.append([group_by,'Data','150px',''])
for c in col_names:
- cols.append([c,'Currency','150px',''])
+ cols.append([c,'Currency','150px',''])
for c in cols:
- colnames.append(c[0])
- coltypes.append(c[1])
- colwidths.append(c[2])
- coloptions.append(c[3])
- col_idx[c[0]] = len(colnames)-1
+ colnames.append(c[0])
+ coltypes.append(c[1])
+ colwidths.append(c[2])
+ coloptions.append(c[3])
+ col_idx[c[0]] = len(colnames)-1
# ******************************************* ADDITIONAL CONDITION ************************************************
@@ -86,75 +86,81 @@
# Item
if item or based_on == 'Item':
- add_cond += ' AND t2.item_code = "%s"' % (based_on != 'Item' and item or '%(value)s')
+ add_cond += ' AND t2.item_code = "%s"' % (based_on != 'Item' and item or '%(value)s')
# Item Group
if item_group or based_on == 'Item Group':
- add_tab += ' ,`tabItem` t3, `tabItem Group` t4 '
- add_cond += ' AND t3.name = t2.item_code AND t3.item_group = t4.name and (t4.name = "%s" or t4.name IN (SELECT t5.name FROM `tabItem Group` t5,`tabItem Group` t6 WHERE t5.lft BETWEEN t6.lft and t6.rgt and t5.docstatus !=2 and ifnull(t5.is_group,"No") = "No" and t6.name = "%s"))' % (based_on != 'Item Group' and item_group or '%(value)s', based_on != 'Item Group' and item_group or '%(value)s')
+ add_tab += ' ,`tabItem` t3, `tabItem Group` t4 '
+ add_cond += ' AND t3.name = t2.item_code AND t3.item_group = t4.name and (t4.name = "%s" or t4.name IN (SELECT t5.name FROM `tabItem Group` t5,`tabItem Group` t6 WHERE t5.lft BETWEEN t6.lft and t6.rgt and t5.docstatus !=2 and ifnull(t5.is_group,"No") = "No" and t6.name = "%s"))' % (based_on != 'Item Group' and item_group or '%(value)s', based_on != 'Item Group' and item_group or '%(value)s')
# Customer
if customer or based_on == 'Customer':
- add_cond += ' AND t1.customer = "%s"' % (based_on != 'Customer' and customer or '%(value)s')
+ add_cond += ' AND t1.customer = "%s"' % (based_on != 'Customer' and customer or '%(value)s')
# Customer Group
if customer_group or based_on == 'Customer Group':
- add_tab += ' ,`tabCustomer` t7, `tabCustomer Group` t8 '
- add_cond += ' AND t7.name = t1.customer AND t7.customer_group = t8.name and (t8.name = "%s" or t8.name IN (SELECT t9.name FROM `tabCustomer Group` t9,`tabCustomer Group` t10 WHERE t9.lft BETWEEN t10.lft and t10.rgt and t9.docstatus !=2 and ifnull(t9.is_group,"No") = "No" and t10.name = "%s"))' % (based_on != 'Customer Group' and customer_group or '%(value)s', based_on != 'Customer Group' and customer_group or '%(value)s')
-
+ add_tab += ' ,`tabCustomer` t7, `tabCustomer Group` t8 '
+ add_cond += ' AND t7.name = t1.customer AND t7.customer_group = t8.name and (t8.name = "%s" or t8.name IN (SELECT t9.name FROM `tabCustomer Group` t9,`tabCustomer Group` t10 WHERE t9.lft BETWEEN t10.lft and t10.rgt and t9.docstatus !=2 and ifnull(t9.is_group,"No") = "No" and t10.name = "%s"))' % (based_on != 'Customer Group' and customer_group or '%(value)s', based_on != 'Customer Group' and customer_group or '%(value)s')
+
# Territory
if territory or based_on == 'Territory':
- add_tab += ' ,`tabTerritory` t11 '
- add_cond += ' AND t1.territory = t11.name AND t1.territory = t11.name and (t11.name = "%s" or t11.name IN (SELECT t12.name FROM `tabTerritory` t12,`tabTerritory` t13 WHERE t12.lft BETWEEN t13.lft and t13.rgt and t12.docstatus !=2 and ifnull(t12.is_group,"No") = "No" and t13.name = "%s"))' % (based_on != 'Territory' and territory or '%(value)s', based_on != 'Territory' and territory or '%(value)s')
+ add_tab += ' ,`tabTerritory` t11 '
+ add_cond += ' AND t1.territory = t11.name AND t1.territory = t11.name and (t11.name = "%s" or t11.name IN (SELECT t12.name FROM `tabTerritory` t12,`tabTerritory` t13 WHERE t12.lft BETWEEN t13.lft and t13.rgt and t12.docstatus !=2 and ifnull(t12.is_group,"No") = "No" and t13.name = "%s"))' % (based_on != 'Territory' and territory or '%(value)s', based_on != 'Territory' and territory or '%(value)s')
# Supplier
if supplier or based_on == 'Supplier':
- add_cond += ' AND t1.supplier = "%s"' % (based_on != 'Supplier' and supplier or '%(value)s')
-
+ add_cond += ' AND t1.supplier = "%s"' % (based_on != 'Supplier' and supplier or '%(value)s')
+
# Supplier Type
if supplier_type or based_on == 'Supplier Type':
- add_tab += ' ,`tabSupplier` t14, `tabSupplier Type` t15 '
- add_cond += ' AND t14.name = t1.supplier AND t14.supplier_type = t15.name and t15.name = "%s"' % (based_on != 'Supplier Type' and supplier_type or '%(value)s')
+ add_tab += ' ,`tabSupplier` t14, `tabSupplier Type` t15 '
+ add_cond += ' AND t14.name = t1.supplier AND t14.supplier_type = t15.name and t15.name = "%s"' % (based_on != 'Supplier Type' and supplier_type or '%(value)s')
-
+# Project
+if project or based_on == 'Project':
+ if trans in ['Purchase Order', 'Purchase Receipt', 'Payable Voucher']:
+ add_cond += ' AND t2.project_name = "%s"' % (based_on != 'Project' and project or '%(value)s')
+ else:
+ add_cond += ' AND t1.project_name = "%s"' % (based_on != 'Project' and project or '%(value)s')
+
# Column to be seleted for group by condition
# ==============================================
sel_col = ''
if group_by == 'Item':
- sel_col = 't2.item_code'
+ sel_col = 't2.item_code'
elif group_by == 'Customer':
- sel_col = 't1.customer'
+ sel_col = 't1.customer'
elif group_by == 'Supplier':
- sel_col = 't1.supplier'
-
-
+ sel_col = 't1.supplier'
+
+
# ********************************************** Result Set ************************************************
for r in res:
- main_det = sql("SELECT %s FROM %s WHERE %s" % (query_val, add_tab, add_cond % {'value':cstr(r[col_idx[based_on]]).strip()}))
- if group_by:
- for col in range(cr,cr+1): # this would make all first row blank. just for look
- r.append('')
- if main_det[0][len(colnames) - cr - 1]:
- for d in range(len(colnames) - cr):
- r.append(flt(main_det[0][d]))
- out.append(r)
-
- if group_by:
- flag = 1
- # check for root nodes
- if based_on in ['Item Group','Customer Group','Territory']:
- is_grp = sql("select is_group from `tab%s` where name = '%s'" % (based_on, cstr(r[col_idx[based_on]]).strip()))
- is_grp = is_grp and cstr(is_grp[0][0]) or ''
- if is_grp != 'No':
- flag = 0
+ main_det = sql("SELECT %s FROM %s WHERE %s" % (query_val, add_tab, add_cond % {'value':cstr(r[col_idx[based_on]]).strip()}))
+ if group_by:
+ for col in range(cr,cr+1): # this would make all first row blank. just for look
+ r.append('')
+ if main_det[0][len(colnames) - cr - 1]:
+ for d in range(len(colnames) - cr):
+ r.append(flt(main_det[0][d]))
+ out.append(r)
+
+ if group_by:
+ flag = 1
+ # check for root nodes
+ if based_on in ['Item Group','Customer Group','Territory']:
+ is_grp = sql("select is_group from `tab%s` where name = '%s'" % (based_on, cstr(r[col_idx[based_on]]).strip()))
+ is_grp = is_grp and cstr(is_grp[0][0]) or ''
+ if is_grp != 'No':
+ flag = 0
- if flag == 1:
- det = [x[0] for x in sql("SELECT DISTINCT %s FROM %s where %s" % (sel_col, add_tab, add_cond % {'value':cstr(r[col_idx[based_on]]).strip()}))]
+ if flag == 1:
+ det = [x[0] for x in sql("SELECT DISTINCT %s FROM %s where %s" % (sel_col, add_tab, add_cond % {'value':cstr(r[col_idx[based_on]]).strip()}))]
- for des in range(len(det)):
- t_row = ['' for i in range(len(colnames))]
- t_row[col_idx[group_by]] = cstr(det[des])
- gr_det = sql("SELECT %s FROM %s WHERE %s = '%s' and %s" % (query_val, add_tab, sel_col, cstr(det[des]), add_cond % {'value':cstr(r[col_idx[based_on]]).strip()}))
- for d in range(len(col_names)):
- t_row[col_idx[col_names[d]]] = flt(gr_det[0][d])
- out.append(t_row)
\ No newline at end of file
+ for des in range(len(det)):
+ t_row = ['' for i in range(len(colnames))]
+ t_row[col_idx[group_by]] = cstr(det[des])
+ gr_det = sql("SELECT %s FROM %s WHERE %s = '%s' and %s" % (query_val, add_tab, sel_col, cstr(det[des]), add_cond % {'value':cstr(r[col_idx[based_on]]).strip()}))
+ for d in range(len(col_names)):
+ t_row[col_idx[col_names[d]]] = flt(gr_det[0][d])
+ out.append(t_row)
diff --git a/erpnext/buying/Print Format/Purchase Order Classic/Purchase Order Classic.txt b/erpnext/buying/Print Format/Purchase Order Classic/Purchase Order Classic.txt
new file mode 100644
index 0000000..604d2d8
--- /dev/null
+++ b/erpnext/buying/Print Format/Purchase Order Classic/Purchase Order Classic.txt
@@ -0,0 +1,28 @@
+# Print Format, Purchase Order Classic
+[
+
+ # These values are common in all dictionaries
+ {
+ 'creation': '2011-12-13 11:02:59',
+ 'docstatus': 0,
+ 'modified': '2011-12-13 13:51:41',
+ 'modified_by': 'Administrator',
+ 'owner': 'Administrator'
+ },
+
+ # These values are common for all Print Format
+ {
+ 'doc_type': 'Purchase Order',
+ 'doctype': 'Print Format',
+ 'html': '<!--\n\tSample Print Format for ERPNext\n\tPlease use at your own discretion\n\tFor suggestions and contributions:\n\t\thttps://github.com/webnotes/erpnext-print-templates\n\n\tFreely usable under MIT license\n-->\n\n<!-- Style Settings -->\n<style>\n\t/*\n\t\tcommon style for whole page\n\t\tThis should include:\n\t\t+ page size related settings\n\t\t+ font family settings\n\t\t+ line spacing settings\n\t*/\n\t@media screen {\n\t\tbody {\n\t\t\twidth: 8.3in;\n\t\t}\n\t}\n\n\thtml, body, div, span, td {\n\t\tfont-family: "Georgia", serif;\n\t\tfont-size: 12px;\n\t}\n\n\tbody {\n\t\tpadding: 10px;\n\t\tmargin: auto;\n\t\tfont-size: 12px;\n\t\tline-height: 150%;\n\t}\n\n\t.common {\n\t\tfont-family: "Georgia", serif !important;\n\t\tfont-size: 12px;\n\t\tpadding: 10px 0px;\n\t}\n\n\ttable {\n\t\tborder-collapse: collapse;\n\t\twidth: 100%;\n\t\tvertical-align: top;\n\t}\n\n\ttable td {\n\t\tpadding: 2px 0px;\n\t}\n\t\n\ttable h1, h2, h3, h4, h5, h6 {\n\t\tpadding: 0px;\n\t\tmargin: 0px;\n\t}\n\n\ttable.header-table td {\n\t\tvertical-align: top;\n\t}\n\n\ttable.header-table thead {\n\t\tborder-bottom: 1px solid black;\n\t}\n\n\ttable.header-table h3 {\n\t\tcolor: gray;\n\t}\n\n\ttable.header-table thead td {\n\t\tpadding: 5px 0px;\n\t}\n\n\tdiv.page-body table td:nth-child(6),\n\tdiv.page-body table td:nth-child(7) {\n\t\ttext-align: right;\n\t}\n\n\ttable.footer-table td {\n\t\tvertical-align: top;\n\t}\n\n\ttable.footer-table td table td:nth-child(2),\n\ttable.footer-table td table td:nth-child(3) {\n\t\ttext-align: right;\n\t}\n</style>\n\n\n<!-- Javascript -->\n<script>\n\tsi_std = {\n\t\tprint_item_table: function() {\n\t\t\tvar table = print_table(\n\t\t\t\t\'Purchase Order\',\n\t\t\t\tdoc.name,\n\t\t\t\t\'po_details\',\n\t\t\t\t\'PO Detail\',\n\t\t\t\t[// Here specify the table columns to be displayed\n\t\t\t\t\t\'SR\', \'item_code\', \'item_name\', \'description\', \'qty\', \'stock_uom\',\n\t\t\t\t\t\'import_rate\', \'import_amount\'\n\t\t\t\t],\n\t\t\t\t[// Here specify the labels of column headings\n\t\t\t\t\t\'Sr\', \'Item Code\', \'Item Name\', \'Description\', \'Qty\',\n\t\t\t\t\t\'UoM\', \'Basic Rate\', \'Amount\'\n\t\t\t\t],\n\t\t\t\t[// Here specify the column widths\n\t\t\t\t\t\'3%\', \'10%\', \'15%\', \'32%\', \'5%\',\n\t\t\t\t\t\'5%\', \'15%\', \'15%\'\n\t\t\t\t]\n\t\t\t);\n\n\t\t\t// This code takes care of page breaks\n\t\t\tif(table.appendChild) {\n\t\t\t\tout = table.innerHTML;\n\t\t\t} else {\n\t\t\t\tout = \'\';\n\t\t\t\tfor(var i=0; i < (table.length-1); i++) {\n\t\t\t\t\tout += table[i].innerHTML + \n\t\t\t\t\t\t\'<div style = "page-break-after: always;" \\\n\t\t\t\t\t\tclass = "page_break"></div>\\\n\t\t\t\t\t\t<div class="page-settings"></div>\';\n\t\t\t\t}\n\t\t\t\tout += table[table.length-1].innerHTML;\n\t\t\t}\n\t\t\treturn out;\n\t\t},\n\n\n\t\tprint_other_charges: function(parent) {\n\t\t\tvar oc = getchildren(\'Purchase Tax Detail\', doc.name, \'purchase_tax_details\');\n\t\t\tvar rows = \'<table width=100%>\\n\';\n\t\t\tfor(var i=0; i<oc.length; i++) {\n\t\t\t\trows +=\n\t\t\t\t\t\'<tr>\\n\' +\n\t\t\t\t\t\t\'\\t<td>\' + oc[i].description + \'</td>\\n\' +\n\t\t\t\t\t\t\'\\t<td></td>\\n\' +\n\t\t\t\t\t\t\'\\t<td width=38%>\' + fmt_money(oc[i].tax_amount / (doc.conversion_rate || 1)) + \'</td>\\n\' +\n\t\t\t\t\t\'</tr>\\n\';\n\t\t\t}\n\t\t\treturn rows + \'</table>\\n\';\n\t\t}\n\t};\n</script>\n\n\n<!-- Page Layout Settings -->\n<div class=\'common page-header\'>\n\t<!-- \n\t\tPage Header will contain\n\t\t\t+ table 1\n\t\t\t\t+ table 1a\n\t\t\t\t\t- Name\n\t\t\t\t\t- Address\n\t\t\t\t\t- Contact\n\t\t\t\t\t- Mobile No\n\t\t\t\t+ table 1b\n\t\t\t\t\t- Voucher Date\n\t\t\t\t\t- Due Date\n\t-->\n\t<table class=\'header-table\' cellspacing=0>\n\t\t<thead>\n\t\t\t<tr><td><script>\'<h1>\' + (doc.select_print_heading || \'Purchase Order\') + \'</h1>\'</script></td></tr>\n\t\t\t<tr><td><h3><script>cur_frm.docname</script></h3></td></tr>\n\t\t</thead>\n\t\t<tbody>\n\t\t\t<tr>\n\t\t\t\t<td width=60%><table width=100% cellspacing=0><tbody>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td width=22%><b>Name</b></td>\n\t\t\t\t\t\t<td><script>doc.supplier_name</script></td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td><b>Address</b></td>\n\t\t\t\t\t\t<td><script>replace_newlines(doc.address_display)</script></td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td><b>Contact</b></td>\n\t\t\t\t\t\t<td><script>doc.contact_display</script></td>\n\t\t\t\t\t</tr>\n\t\t\t\t</tbody></table></td>\n\t\t\t\t<td><table width=100% cellspacing=0><tbody>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td width=63%><b>Purchase Order Date</b></td>\n\t\t\t\t\t\t<td><script>date.str_to_user(doc.transaction_date)</script></td>\n\t\t\t\t\t<tr>\t\t\t\t\t\n\t\t\t\t</tbody></table></td>\n\t\t\t</tr>\n\t\t</tbody>\n\t\t<tfoot>\n\t\t\n\t\t</tfoot>\n\t</table>\n</div>\n<div class=\'common page-body\'>\n\t<!-- \n\t\tPage Body will contain\n\t\t\t+ table 2\n\t\t\t\t- Sales Invoice Data\n\t-->\n\t<script>si_std.print_item_table()</script>\n</div>\n<div class=\'common page-footer\'>\n\t<!-- \n\t\tPage Footer will contain\n\t\t\t+ table 3\n\t\t\t\t- Terms and Conditions\n\t\t\t\t- Total Rounded Amount Calculation\n\t\t\t\t- Total Rounded Amount in Words\n\t-->\n\t<table class=\'footer-table\' width=100% cellspacing=0>\n\t\t<thead>\n\t\t\t\n\t\t</thead>\n\t\t<tbody>\n\t\t\t<tr>\n\t\t\t\t<td width=60% style=\'padding-right: 10px;\'>\n\t\t\t\t\t<b>Terms, Conditions & Other Information:</b><br />\n\t\t\t\t\t<script>doc.terms</script>\n\t\t\t\t</td>\n\t\t\t\t<td>\n\t\t\t\t\t<table cellspacing=0 width=100%><tbody>\n\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t<td>Net Total</td>\n\t\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t\t<td width=38%><script>\n\t\t\t\t\t\t\t\tfmt_money(doc.net_total_import)\n\t\t\t\t\t\t\t</script></td>\n\t\t\t\t\t\t</tr>\n\t\t\t\t\t\t<tr><td colspan=3><script>si_std.print_other_charges()</script></td></tr>\n\t\t\t\t\t\t<tr style=\'font-weight: bold\'>\n\t\t\t\t\t\t\t<td>Grand Total</td>\n\t\t\t\t\t\t\t<td><script>doc.currency</script></td>\n\t\t\t\t\t\t\t<td><script>\n\t\t\t\t\t\t\t\tfmt_money(doc.grand_total_import)\n\t\t\t\t\t\t\t</script></td>\n\t\t\t\t\t\t</tr>\n\t\t\t\t\t</tbody></table>\n\t\t\t\t\t<br /><b>In Words</b><br />\n\t\t\t\t\t<i><script>doc.in_words_import</script></i>\n\t\t\t\t</td>\n\t\t\t</tr>\t\t\n\t\t</tbody>\n\t\t<tfoot>\n\t\t\n\t\t</tfoot>\n\t</table>\n</div>\n',
+ 'module': 'Buying',
+ 'name': '__common__',
+ 'standard': 'Yes'
+ },
+
+ # Print Format, Purchase Order Classic
+ {
+ 'doctype': 'Print Format',
+ 'name': 'Purchase Order Classic'
+ }
+]
\ No newline at end of file
diff --git a/erpnext/buying/Print Format/Purchase Order Modern/Purchase Order Modern.txt b/erpnext/buying/Print Format/Purchase Order Modern/Purchase Order Modern.txt
new file mode 100644
index 0000000..f5cafe4
--- /dev/null
+++ b/erpnext/buying/Print Format/Purchase Order Modern/Purchase Order Modern.txt
@@ -0,0 +1,28 @@
+# Print Format, Purchase Order Modern
+[
+
+ # These values are common in all dictionaries
+ {
+ 'creation': '2011-12-13 11:02:59',
+ 'docstatus': 0,
+ 'modified': '2011-12-13 13:53:52',
+ 'modified_by': 'Administrator',
+ 'owner': 'Administrator'
+ },
+
+ # These values are common for all Print Format
+ {
+ 'doc_type': 'Purchase Order',
+ 'doctype': 'Print Format',
+ 'html': '<!--\n\tSample Print Format for ERPNext\n\tPlease use at your own discretion\n\tFor suggestions and contributions:\n\t\thttps://github.com/webnotes/erpnext-print-templates\n\n\tFreely usable under MIT license\n-->\n\n<!-- Style Settings -->\n<style>\n\t/*\n\t\tcommon style for whole page\n\t\tThis should include:\n\t\t+ page size related settings\n\t\t+ font family settings\n\t\t+ line spacing settings\n\t*/\n\t@media screen {\n\t\tbody {\n\t\t\twidth: 8.3in;\n\t\t}\n\t}\n\n\thtml, body, div, span, td {\n\t\tfont-family: "Helvetica", "Arial", sans-serif;\n\t\tfont-size: 12px;\n\t}\n\n\tbody {\n\t\tpadding: 10px;\n\t\tmargin: auto;\n\t\tfont-size: 12px;\n\t\tline-height: 150%;\n\t}\n\n\t.common {\n\t\tfont-family: "Helvetica", "Arial", sans-serif !important;\n\t\tfont-size: 12px;\n\t\tpadding: 10px 0px;\n\t}\n\n\ttable {\n\t\tborder-collapse: collapse;\n\t\twidth: 100%;\n\t\tvertical-align: top;\n\t\tborder-style: none !important;\n\t}\n\n\ttable td {\n\t\tpadding: 2px 0px;\n\t\tborder-style: none !important;\n\t}\n\t\n\ttable h1, h2, h3, h4, h5, h6 {\n\t\tpadding: 0px;\n\t\tmargin: 0px;\n\t}\n\n\ttable.header-table td {\n\t\tvertical-align: top;\n\t}\n\n\ttable.header-table h1 {\n\t\ttext-transform: uppercase;\n\t\tcolor: white;\n\t\tfont-size: 55px;\n\t\tfont-style: italic;\n\t}\n\n\ttable.header-table thead tr:nth-child(1) div {\n\t\theight: 24px;\n\t\tbackground-color: #696969;\n\t\tvertical-align: middle;\n\t\tpadding: 12px 0px 0px 0px;\n\t\twidth: 100%;\n\t}\n\n\tdiv.page-body table td:nth-child(6),\n\tdiv.page-body table td:nth-child(7) {\n\t\ttext-align: right;\n\t}\n\n\tdiv.page-body table tr td {\n\t\tbackground-color: #DCDCDC !important;\n\t}\n\n\tdiv.page-body table tr:nth-child(1) td {\n\t\tbackground-color: #696969 !important;\n\t\tcolor: white !important;\n\t}\n\n\ttable.footer-table td {\n\t\tvertical-align: top;\n\t}\n\n\ttable.footer-table td table td:nth-child(2),\n\ttable.footer-table td table td:nth-child(3) {\n\t\ttext-align: right;\n\t}\n\n\ttable.footer-table tfoot td {\n\t\tbackground-color: #696969;\n\t\theight: 10px;\n\t}\n\n\t.imp-details {\n\t\tbackground-color: #DCDCDC;\n\t}\n</style>\n\n\n<!-- Javascript -->\n<script>\n\tsi_std = {\n\t\tprint_item_table: function() {\n\t\t\tvar table = print_table(\n\t\t\t\t\'Purchase Order\',\n\t\t\t\tdoc.name,\n\t\t\t\t\'po_details\',\n\t\t\t\t\'PO Detail\',\n\t\t\t\t[// Here specify the table columns to be displayed\n\t\t\t\t\t\'SR\', \'item_code\', \'item_name\', \'description\', \'qty\', \'stock_uom\',\n\t\t\t\t\t\'import_rate\', \'import_amount\'\n\t\t\t\t],\n\t\t\t\t[// Here specify the labels of column headings\n\t\t\t\t\t\'Sr\', \'Item Code\', \'Item Name\', \'Description\', \'Qty\',\n\t\t\t\t\t\'UoM\', \'Basic Rate\', \'Amount\'\n\t\t\t\t],\n\t\t\t\t[// Here specify the column widths\n\t\t\t\t\t\'3%\', \'10%\', \'15%\', \'32%\', \'5%\',\n\t\t\t\t\t\'5%\', \'15%\', \'15%\'\n\t\t\t\t]\n\t\t\t);\n\n\t\t\t// This code takes care of page breaks\n\t\t\tif(table.appendChild) {\n\t\t\t\tout = table.innerHTML;\n\t\t\t} else {\n\t\t\t\tout = \'\';\n\t\t\t\tfor(var i=0; i < (table.length-1); i++) {\n\t\t\t\t\tout += table[i].innerHTML + \n\t\t\t\t\t\t\'<div style = "page-break-after: always;" \\\n\t\t\t\t\t\tclass = "page_break"></div>\\\n\t\t\t\t\t\t<div class="page-settings"></div>\';\n\t\t\t\t}\n\t\t\t\tout += table[table.length-1].innerHTML;\n\t\t\t}\n\t\t\treturn out;\n\t\t},\n\n\n\t\tprint_other_charges: function(parent) {\n\t\t\tvar oc = getchildren(\'Purchase Tax Detail\', doc.name, \'purchase_tax_details\');\n\t\t\tvar rows = \'<table width=100%>\\n\';\n\t\t\tfor(var i=0; i<oc.length; i++) {\n\t\t\t\trows +=\n\t\t\t\t\t\'<tr>\\n\' +\n\t\t\t\t\t\t\'\\t<td>\' + oc[i].description + \'</td>\\n\' +\n\t\t\t\t\t\t\'\\t<td></td>\\n\' +\n\t\t\t\t\t\t\'\\t<td width=38%>\' + fmt_money(oc[i].tax_amount / (doc.conversion_rate || 1)) + \'</td>\\n\' +\n\t\t\t\t\t\'</tr>\\n\';\n\t\t\t}\n\t\t\treturn rows + \'</table>\\n\';\n\t\t}\n\t};\n</script>\n\n\n<!-- Page Layout Settings -->\n<div class=\'common page-header\'>\n\t<!-- \n\t\tPage Header will contain\n\t\t\t+ table 1\n\t\t\t\t+ table 1a\n\t\t\t\t\t- Name\n\t\t\t\t\t- Address\n\t\t\t\t\t- Contact\n\t\t\t\t\t- Mobile No\n\t\t\t\t+ table 1b\n\t\t\t\t\t- Voucher Date\n\t\t\t\t\t- Due Date\n\t-->\n\t<table class=\'header-table\' cellspacing=0>\n\t\t<thead>\n\t\t\t<tr><td colspan=2><div><script>\'<h1>\' + (doc.select_print_heading || \'Purchase Order\') + \'</h1>\'</script></div></td></tr>\n\t\t\t<tr><td colspan=2><div style="height:15px"></div></td></tr>\n\t\t</thead>\n\t\t<tbody>\n\t\t\t<tr>\n\t\t\t\t<td width=60%><table width=100% cellspacing=0><tbody>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td width=22%><b>Name</b></td>\n\t\t\t\t\t\t<td><script>doc.supplier_name</script></td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td><b>Address</b></td>\n\t\t\t\t\t\t<td><script>replace_newlines(doc.address_display)</script></td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td><b>Contact</b></td>\n\t\t\t\t\t\t<td><script>doc.contact_display</script></td>\n\t\t\t\t\t</tr>\n\t\t\t\t</tbody></table></td>\n\t\t\t\t<td><table width=100% cellspacing=0><tbody>\n\t\t\t\t\t<tr class=\'imp-details\'>\n\t\t\t\t\t\t<td><b>Purchase Order No.</b></td>\n\t\t\t\t\t\t<td><script>cur_frm.docname</script></td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td width=63%><b>Purchase Order Date</b></td>\n\t\t\t\t\t\t<td><script>date.str_to_user(doc.transaction_date)</script></td>\n\t\t\t\t\t<tr>\t\t\t\t\t\n\t\t\t\t</tbody></table></td>\n\t\t\t</tr>\n\t\t</tbody>\n\t\t<tfoot>\n\t\t\n\t\t</tfoot>\n\t</table>\n</div>\n<div class=\'common page-body\'>\n\t<!-- \n\t\tPage Body will contain\n\t\t\t+ table 2\n\t\t\t\t- Sales Invoice Data\n\t-->\n\t<script>si_std.print_item_table()</script>\n</div>\n<div class=\'common page-footer\'>\n\t<!-- \n\t\tPage Footer will contain\n\t\t\t+ table 3\n\t\t\t\t- Terms and Conditions\n\t\t\t\t- Total Rounded Amount Calculation\n\t\t\t\t- Total Rounded Amount in Words\n\t-->\n\t<table class=\'footer-table\' width=100% cellspacing=0>\n\t\t<thead>\n\t\t\t\n\t\t</thead>\n\t\t<tbody>\n\t\t\t<tr>\n\t\t\t\t<td width=60% style=\'padding-right: 10px;\'>\n\t\t\t\t\t<b>Terms, Conditions & Other Information:</b><br />\n\t\t\t\t\t<script>doc.terms</script>\n\t\t\t\t</td>\n\t\t\t\t<td>\n\t\t\t\t\t<table cellspacing=0 width=100%><tbody>\n\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t<td>Net Total</td>\n\t\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t\t<td width=38%><script>\n\t\t\t\t\t\t\t\tfmt_money(doc.net_total_import)\n\t\t\t\t\t\t\t</script></td>\n\t\t\t\t\t\t</tr>\n\t\t\t\t\t\t<tr><td colspan=3><script>si_std.print_other_charges()</script></td></tr>\n\t\t\t\t\t\t<tr style=\'font-weight: bold\' class=\'imp-details\'>\n\t\t\t\t\t\t\t<td>Grand Total</td>\n\t\t\t\t\t\t\t<td><script>doc.currency</script></td>\n\t\t\t\t\t\t\t<td><script>\n\t\t\t\t\t\t\t\tfmt_money(doc.grand_total_import)\n\t\t\t\t\t\t\t</script></td>\n\t\t\t\t\t\t</tr>\n\t\t\t\t\t</tbody></table>\n\t\t\t\t\t<br /><b>In Words</b><br />\n\t\t\t\t\t<i><script>doc.in_words_import</script></i>\n\t\t\t\t</td>\n\t\t\t</tr>\t\t\n\t\t</tbody>\n\t\t<tfoot>\n\t\t\t<tr><td colspan=2><div></div></td><tr>\n\t\t</tfoot>\n\t</table>\n</div>\n',
+ 'module': 'Buying',
+ 'name': '__common__',
+ 'standard': 'Yes'
+ },
+
+ # Print Format, Purchase Order Modern
+ {
+ 'doctype': 'Print Format',
+ 'name': 'Purchase Order Modern'
+ }
+]
\ No newline at end of file
diff --git a/erpnext/buying/Print Format/Purchase Order Spartan/Purchase Order Spartan.txt b/erpnext/buying/Print Format/Purchase Order Spartan/Purchase Order Spartan.txt
new file mode 100644
index 0000000..70d6961
--- /dev/null
+++ b/erpnext/buying/Print Format/Purchase Order Spartan/Purchase Order Spartan.txt
@@ -0,0 +1,28 @@
+# Print Format, Purchase Order Spartan
+[
+
+ # These values are common in all dictionaries
+ {
+ 'creation': '2011-12-13 11:02:59',
+ 'docstatus': 0,
+ 'modified': '2011-12-13 13:55:23',
+ 'modified_by': 'Administrator',
+ 'owner': 'Administrator'
+ },
+
+ # These values are common for all Print Format
+ {
+ 'doc_type': 'Purchase Order',
+ 'doctype': 'Print Format',
+ 'html': '<!--\n\tSample Print Format for ERPNext\n\tPlease use at your own discretion\n\tFor suggestions and contributions:\n\t\thttps://github.com/webnotes/erpnext-print-templates\n\n\tFreely usable under MIT license\n-->\n\n<!-- Style Settings -->\n<style>\n\t/*\n\t\tcommon style for whole page\n\t\tThis should include:\n\t\t+ page size related settings\n\t\t+ font family settings\n\t\t+ line spacing settings\n\t*/\n\t@media screen {\n\t\tbody {\n\t\t\twidth: 8.3in;\n\t\t}\n\t}\n\n\thtml, body, div, span, td {\n\t\tfont-family: "Arial", sans-serif;\n\t\tfont-size: 12px;\n\t}\n\n\tbody {\n\t\tpadding: 10px;\n\t\tmargin: auto;\n\t\tfont-size: 12px;\n\t\tline-height: 150%;\n\t}\n\n\t.common {\n\t\tfont-family: "Arial", sans-serif !important;\n\t\tfont-size: 12px;\n\t\tpadding: 0px;\n\t}\n\n\ttable {\n\t\twidth: 100% !important;\n\t\tvertical-align: top;\n\t}\n\n\ttable td {\n\t\tpadding: 2px 0px;\n\t}\n\n\ttable, td {\n\t\tborder-collapse: collapse !important;\n\t\tpadding: 0px;\n\t\tmargin: 0px !important;\n\t}\n\t\n\ttable h1, h2, h3, h4, h5, h6 {\n\t\tpadding: 0px;\n\t\tmargin: 0px;\n\t}\n\n\ttable.header-table td {\n\t\tvertical-align: top;\n\t}\n\n\ttable.header-table h3 {\n\t\tcolor: gray;\n\t}\n\n\ttable.header-table thead td {\n\t\tpadding: 5px;\n\t}\n\n\ttable.header-table > thead,\n\ttable.header-table > tbody > tr > td,\n\ttable.footer-table > tbody > tr > td {\n\t\tborder: 1px solid black;\n\t\tpadding: 5px;\n\t}\n\n\ttable.footer-table > tbody,\n\ttable.header-table > thead {\n\t\tborder-bottom: 3px solid black;\n\t}\n\n\ttable.header-table > thead {\n\t\tborder-top: 3px solid black;\n\t}\n\n\tdiv.page-body table td:nth-child(6),\n\tdiv.page-body table td:nth-child(7) {\n\t\ttext-align: right;\n\t}\n\n\tdiv.page-body td {\n\t\tbackground-color: white !important;\n\t\tborder: 1px solid black !important;\n\t}\n\n\ttable.footer-table td {\n\t\tvertical-align: top;\n\t}\n\n\ttable.footer-table td table td:nth-child(2),\n\ttable.footer-table td table td:nth-child(3) {\n\t\ttext-align: right;\n\t}\n</style>\n\n\n<!-- Javascript -->\n<script>\n\tsi_std = {\n\t\tprint_item_table: function() {\n\t\t\tvar table = print_table(\n\t\t\t\t\'Purchase Order\',\n\t\t\t\tdoc.name,\n\t\t\t\t\'po_details\',\n\t\t\t\t\'PO Detail\',\n\t\t\t\t[// Here specify the table columns to be displayed\n\t\t\t\t\t\'SR\', \'item_code\', \'item_name\', \'description\', \'qty\', \'stock_uom\',\n\t\t\t\t\t\'import_rate\', \'import_amount\'\n\t\t\t\t],\n\t\t\t\t[// Here specify the labels of column headings\n\t\t\t\t\t\'Sr\', \'Item Code\', \'Item Name\', \'Description\', \'Qty\',\n\t\t\t\t\t\'UoM\', \'Basic Rate\', \'Amount\'\n\t\t\t\t],\n\t\t\t\t[// Here specify the column widths\n\t\t\t\t\t\'3%\', \'10%\', \'15%\', \'32%\', \'5%\',\n\t\t\t\t\t\'5%\', \'15%\', \'15%\'\n\t\t\t\t]\n\t\t\t);\n\n\t\t\t// This code takes care of page breaks\n\t\t\tif(table.appendChild) {\n\t\t\t\tout = table.innerHTML;\n\t\t\t} else {\n\t\t\t\tout = \'\';\n\t\t\t\tfor(var i=0; i < (table.length-1); i++) {\n\t\t\t\t\tout += table[i].innerHTML + \n\t\t\t\t\t\t\'<div style = "page-break-after: always;" \\\n\t\t\t\t\t\tclass = "page_break"></div>\\\n\t\t\t\t\t\t<div class="page-settings"></div>\';\n\t\t\t\t}\n\t\t\t\tout += table[table.length-1].innerHTML;\n\t\t\t}\n\t\t\treturn out;\n\t\t},\n\n\n\t\tprint_other_charges: function(parent) {\n\t\t\tvar oc = getchildren(\'Purchase Tax Detail\', doc.name, \'purchase_tax_details\');\n\t\t\tvar rows = \'<table width=100%>\\n\';\n\t\t\tfor(var i=0; i<oc.length; i++) {\n\t\t\t\trows +=\n\t\t\t\t\t\'<tr>\\n\' +\n\t\t\t\t\t\t\'\\t<td>\' + oc[i].description + \'</td>\\n\' +\n\t\t\t\t\t\t\'\\t<td></td>\\n\' +\n\t\t\t\t\t\t\'\\t<td width=38%>\' + fmt_money(oc[i].tax_amount / (doc.conversion_rate || 1)) + \'</td>\\n\' +\n\t\t\t\t\t\'</tr>\\n\';\n\t\t\t}\n\t\t\treturn rows + \'</table>\\n\';\n\t\t}\n\t};\n</script>\n\n\n<!-- Page Layout Settings -->\n<div class=\'common page-header\'>\n\t<!-- \n\t\tPage Header will contain\n\t\t\t+ table 1\n\t\t\t\t+ table 1a\n\t\t\t\t\t- Name\n\t\t\t\t\t- Address\n\t\t\t\t\t- Contact\n\t\t\t\t\t- Mobile No\n\t\t\t\t+ table 1b\n\t\t\t\t\t- Voucher Date\n\t\t\t\t\t- Due Date\n\t-->\n\t<table class=\'header-table\' cellspacing=0>\n\t\t<thead>\n\t\t\t<tr><td colspan=2><script>\'<h1>\' + (doc.select_print_heading || \'Purchase Order\') + \'</h1>\'</script></td></tr>\n\t\t\t<tr><td colspan=2><h3><script>cur_frm.docname</script></h3></td></tr>\n\t\t</thead>\n\t\t<tbody>\n\t\t\t<tr>\n\t\t\t\t<td width=60%><table width=100% cellspacing=0><tbody>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td width=22%><b>Name</b></td>\n\t\t\t\t\t\t<td><script>doc.supplier_name</script></td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td><b>Address</b></td>\n\t\t\t\t\t\t<td><script>replace_newlines(doc.address_display)</script></td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td><b>Contact</b></td>\n\t\t\t\t\t\t<td><script>doc.contact_display</script></td>\n\t\t\t\t\t</tr>\n\t\t\t\t</tbody></table></td>\n\t\t\t\t<td><table width=100% cellspacing=0><tbody>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td width=63%><b>Purchase Order Date</b></td>\n\t\t\t\t\t\t<td><script>date.str_to_user(doc.transaction_date)</script></td>\n\t\t\t\t\t<tr>\t\t\t\t\t\n\t\t\t\t</tbody></table></td>\n\t\t\t</tr>\n\t\t</tbody>\n\t\t<tfoot>\n\t\t\n\t\t</tfoot>\n\t</table>\n</div>\n<div class=\'common page-body\'>\n\t<!-- \n\t\tPage Body will contain\n\t\t\t+ table 2\n\t\t\t\t- Sales Invoice Data\n\t-->\n\t<script>si_std.print_item_table()</script>\n</div>\n<div class=\'common page-footer\'>\n\t<!-- \n\t\tPage Footer will contain\n\t\t\t+ table 3\n\t\t\t\t- Terms and Conditions\n\t\t\t\t- Total Rounded Amount Calculation\n\t\t\t\t- Total Rounded Amount in Words\n\t-->\n\t<table class=\'footer-table\' width=100% cellspacing=0>\n\t\t<thead>\n\t\t\t\n\t\t</thead>\n\t\t<tbody>\n\t\t\t<tr>\n\t\t\t\t<td width=60% style=\'padding-right: 10px;\'>\n\t\t\t\t\t<b>Terms, Conditions & Other Information:</b><br />\n\t\t\t\t\t<script>doc.terms</script>\n\t\t\t\t</td>\n\t\t\t\t<td>\n\t\t\t\t\t<table cellspacing=0 width=100%><tbody>\n\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t<td>Net Total</td>\n\t\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t\t<td width=38%><script>\n\t\t\t\t\t\t\t\tfmt_money(doc.net_total_import)\n\t\t\t\t\t\t\t</script></td>\n\t\t\t\t\t\t</tr>\n\t\t\t\t\t\t<tr><td colspan=3><script>si_std.print_other_charges()</script></td></tr>\n\t\t\t\t\t\t<tr style=\'font-weight: bold\'>\n\t\t\t\t\t\t\t<td>Grand Total</td>\n\t\t\t\t\t\t\t<td><script>doc.currency</script></td>\n\t\t\t\t\t\t\t<td><script>\n\t\t\t\t\t\t\t\tfmt_money(doc.grand_total_import)\n\t\t\t\t\t\t\t</script></td>\n\t\t\t\t\t\t</tr>\n\t\t\t\t\t</tbody></table>\n\t\t\t\t\t<br /><b>In Words</b><br />\n\t\t\t\t\t<i><script>doc.in_words_import</script></i>\n\t\t\t\t</td>\n\t\t\t</tr>\t\t\n\t\t</tbody>\n\t\t<tfoot>\n\t\t\n\t\t</tfoot>\n\t</table>\n</div>\n',
+ 'module': 'Buying',
+ 'name': '__common__',
+ 'standard': 'Yes'
+ },
+
+ # Print Format, Purchase Order Spartan
+ {
+ 'doctype': 'Print Format',
+ 'name': 'Purchase Order Spartan'
+ }
+]
\ No newline at end of file
diff --git a/erpnext/buying/doctype/indent/indent.txt b/erpnext/buying/doctype/indent/indent.txt
index cd6c912..6d9f5f6 100644
--- a/erpnext/buying/doctype/indent/indent.txt
+++ b/erpnext/buying/doctype/indent/indent.txt
@@ -5,16 +5,17 @@
{
'creation': '2010-08-08 17:09:04',
'docstatus': 0,
- 'modified': '2011-05-04 14:53:17',
+ 'modified': '2011-10-12 13:09:38',
'modified_by': 'Administrator',
'owner': 'Administrator'
},
# These values are common for all DocType
{
- '_last_update': '1304500997',
+ '_last_update': '1318404775',
'allow_print': 0,
'colour': 'White:FFF',
+ 'default_print_format': 'Standard',
'doctype': 'DocType',
'module': 'Buying',
'name': '__common__',
@@ -24,7 +25,7 @@
'server_code_error': ' ',
'show_in_menu': 0,
'subject': '%(per_ordered)s% ordered',
- 'version': 186
+ 'version': 188
},
# These values are common for all DocField
@@ -54,11 +55,22 @@
# DocPerm
{
+ 'amend': 1,
+ 'cancel': 1,
+ 'create': 1,
+ 'doctype': 'DocPerm',
+ 'permlevel': 0,
+ 'role': 'Production Manager',
+ 'submit': 1,
+ 'write': 1
+ },
+
+ # DocPerm
+ {
'amend': 0,
'cancel': 0,
'create': 0,
'doctype': 'DocPerm',
- 'idx': 1,
'permlevel': 1,
'role': 'Purchase Manager',
'submit': 0,
@@ -71,7 +83,6 @@
'cancel': 1,
'create': 1,
'doctype': 'DocPerm',
- 'idx': 2,
'permlevel': 0,
'role': 'Purchase Manager',
'submit': 1,
@@ -84,7 +95,6 @@
'cancel': 0,
'create': 0,
'doctype': 'DocPerm',
- 'idx': 3,
'permlevel': 1,
'role': 'Material Manager',
'submit': 0,
@@ -97,7 +107,6 @@
'cancel': 1,
'create': 1,
'doctype': 'DocPerm',
- 'idx': 4,
'permlevel': 0,
'role': 'Material Manager',
'submit': 1,
@@ -110,7 +119,6 @@
'cancel': 0,
'create': 0,
'doctype': 'DocPerm',
- 'idx': 5,
'permlevel': 1,
'role': 'Material User',
'submit': 0,
@@ -123,7 +131,6 @@
'cancel': 1,
'create': 1,
'doctype': 'DocPerm',
- 'idx': 6,
'permlevel': 0,
'role': 'Material User',
'submit': 1,
@@ -136,7 +143,6 @@
'cancel': 1,
'create': 1,
'doctype': 'DocPerm',
- 'idx': 7,
'permlevel': 0,
'role': 'Purchase User',
'submit': 1,
@@ -145,10 +151,14 @@
# DocPerm
{
+ 'amend': 0,
+ 'cancel': 0,
+ 'create': 0,
'doctype': 'DocPerm',
- 'idx': 8,
'permlevel': 1,
- 'role': 'Purchase User'
+ 'role': 'Purchase User',
+ 'submit': 0,
+ 'write': 0
},
# DocField
@@ -158,7 +168,6 @@
'description': 'Enter items and their details for which you want your purchase department to raise a purchase order.',
'doctype': 'DocField',
'fieldtype': 'Section Break',
- 'idx': 1,
'label': 'Basic Info',
'oldfieldtype': 'Section Break',
'permlevel': 0,
@@ -169,7 +178,6 @@
{
'doctype': 'DocField',
'fieldtype': 'Column Break',
- 'idx': 2,
'oldfieldtype': 'Column Break',
'permlevel': 0,
'print_hide': 0,
@@ -183,7 +191,6 @@
'doctype': 'DocField',
'fieldname': 'naming_series',
'fieldtype': 'Select',
- 'idx': 3,
'label': 'Series',
'no_copy': 1,
'oldfieldname': 'naming_series',
@@ -199,7 +206,6 @@
'doctype': 'DocField',
'fieldname': 'status',
'fieldtype': 'Select',
- 'idx': 4,
'in_filter': 1,
'label': 'Status',
'no_copy': 1,
@@ -216,7 +222,6 @@
{
'doctype': 'DocField',
'fieldtype': 'Column Break',
- 'idx': 5,
'oldfieldtype': 'Column Break',
'permlevel': 0,
'width': '50%'
@@ -229,7 +234,6 @@
'doctype': 'DocField',
'fieldname': 'transaction_date',
'fieldtype': 'Date',
- 'idx': 6,
'in_filter': 1,
'label': 'Indent Date',
'no_copy': 1,
@@ -249,7 +253,6 @@
'doctype': 'DocField',
'fieldname': 'per_ordered',
'fieldtype': 'Currency',
- 'idx': 7,
'label': '% Ordered',
'no_copy': 1,
'oldfieldname': 'per_ordered',
@@ -262,7 +265,6 @@
'colour': 'White:FFF',
'doctype': 'DocField',
'fieldtype': 'Section Break',
- 'idx': 8,
'label': 'Items',
'oldfieldtype': 'Section Break',
'permlevel': 0
@@ -275,14 +277,12 @@
'doctype': 'DocField',
'fieldname': 'sales_order_no',
'fieldtype': 'Link',
- 'idx': 9,
'label': 'Sales Order No',
'no_copy': 1,
'oldfieldname': 'sales_order_no',
'oldfieldtype': 'Data',
'options': 'Sales Order',
'permlevel': 0,
- 'search_index': 0,
'width': '100px'
},
@@ -290,7 +290,6 @@
{
'doctype': 'DocField',
'fieldtype': 'Button',
- 'idx': 10,
'label': 'Pull Sales Order Details',
'options': 'pull_so_details',
'permlevel': 0
@@ -298,10 +297,11 @@
# DocField
{
+ 'allow_on_submit': 1,
+ 'colour': 'White:FFF',
'doctype': 'DocField',
'fieldname': 'indent_details',
'fieldtype': 'Table',
- 'idx': 11,
'label': 'Indent Details',
'no_copy': 0,
'oldfieldname': 'indent_details',
@@ -317,7 +317,6 @@
'description': 'Filing in Additional Information about the Indent will help you analyze your data better.',
'doctype': 'DocField',
'fieldtype': 'Section Break',
- 'idx': 12,
'label': 'More Info',
'oldfieldtype': 'Section Break',
'permlevel': 0
@@ -330,7 +329,6 @@
'doctype': 'DocField',
'fieldname': 'company',
'fieldtype': 'Link',
- 'idx': 13,
'in_filter': 1,
'label': 'Company',
'oldfieldname': 'company',
@@ -339,7 +337,7 @@
'permlevel': 0,
'print_hide': 1,
'reqd': 1,
- 'search_index': 0,
+ 'search_index': 1,
'width': '150px'
},
@@ -349,7 +347,6 @@
'doctype': 'DocField',
'fieldname': 'fiscal_year',
'fieldtype': 'Select',
- 'idx': 14,
'in_filter': 1,
'label': 'Fiscal Year',
'oldfieldname': 'fiscal_year',
@@ -358,7 +355,7 @@
'permlevel': 0,
'print_hide': 1,
'reqd': 1,
- 'search_index': 0,
+ 'search_index': 1,
'width': '150px'
},
@@ -369,7 +366,6 @@
'doctype': 'DocField',
'fieldname': 'requested_by',
'fieldtype': 'Data',
- 'idx': 15,
'label': 'Requested By',
'no_copy': 1,
'oldfieldname': 'requested_by',
@@ -382,7 +378,6 @@
{
'doctype': 'DocField',
'fieldtype': 'Column Break',
- 'idx': 16,
'oldfieldtype': 'Column Break',
'permlevel': 0,
'width': '50%'
@@ -393,7 +388,6 @@
'doctype': 'DocField',
'fieldname': 'remark',
'fieldtype': 'Small Text',
- 'idx': 17,
'label': 'Remarks',
'no_copy': 1,
'oldfieldname': 'remark',
@@ -410,7 +404,6 @@
'doctype': 'DocField',
'fieldname': 'cancel_reason',
'fieldtype': 'Data',
- 'idx': 18,
'label': 'Cancel Reason',
'no_copy': 1,
'oldfieldname': 'cancel_reason',
@@ -424,7 +417,6 @@
'doctype': 'DocField',
'fieldname': 'amended_from',
'fieldtype': 'Data',
- 'idx': 19,
'label': 'Amended From',
'no_copy': 1,
'oldfieldname': 'amended_from',
@@ -440,7 +432,6 @@
'doctype': 'DocField',
'fieldname': 'amendment_date',
'fieldtype': 'Date',
- 'idx': 20,
'label': 'Amendment Date',
'no_copy': 1,
'oldfieldname': 'amendment_date',
@@ -455,7 +446,6 @@
'description': 'Add Terms and Conditions for the Indent. You can also prepare a master Term Sheet and use the Template',
'doctype': 'DocField',
'fieldtype': 'Section Break',
- 'idx': 21,
'label': 'Terms',
'oldfieldtype': 'Section Break',
'permlevel': 0
@@ -467,7 +457,6 @@
'doctype': 'DocField',
'fieldname': 'letter_head',
'fieldtype': 'Select',
- 'idx': 22,
'label': 'Letter Head',
'oldfieldname': 'letter_head',
'oldfieldtype': 'Select',
@@ -481,22 +470,19 @@
'doctype': 'DocField',
'fieldname': 'tc_name',
'fieldtype': 'Link',
- 'idx': 23,
'label': 'Select Terms',
'oldfieldname': 'tc_name',
'oldfieldtype': 'Link',
'options': 'Term',
'permlevel': 0,
'print_hide': 1,
- 'report_hide': 1,
- 'search_index': 0
+ 'report_hide': 1
},
# DocField
{
'doctype': 'DocField',
'fieldtype': 'Button',
- 'idx': 24,
'label': 'Get Terms',
'oldfieldtype': 'Button',
'options': 'get_tc_details',
@@ -507,7 +493,6 @@
{
'doctype': 'DocField',
'fieldtype': 'HTML',
- 'idx': 25,
'label': 'Terms HTML',
'oldfieldtype': 'HTML',
'options': 'You can add Terms and Notes that will be printed in the Transaction',
@@ -520,7 +505,6 @@
'doctype': 'DocField',
'fieldname': 'terms',
'fieldtype': 'Text Editor',
- 'idx': 26,
'label': 'Terms1',
'oldfieldname': 'terms',
'oldfieldtype': 'Text Editor',
@@ -531,7 +515,6 @@
{
'doctype': 'DocField',
'fieldtype': 'Column Break',
- 'idx': 27,
'oldfieldtype': 'Column Break',
'permlevel': 0,
'print_hide': 1
@@ -543,7 +526,6 @@
'colour': 'White:FFF',
'doctype': 'DocField',
'fieldtype': 'Button',
- 'idx': 28,
'label': 'Repair Indent',
'oldfieldtype': 'Button',
'options': 'repair_indent',
diff --git a/erpnext/buying/doctype/indent_detail/indent_detail.txt b/erpnext/buying/doctype/indent_detail/indent_detail.txt
index c207266..136237a 100644
--- a/erpnext/buying/doctype/indent_detail/indent_detail.txt
+++ b/erpnext/buying/doctype/indent_detail/indent_detail.txt
@@ -5,7 +5,7 @@
{
'creation': '2010-08-08 17:09:04',
'docstatus': 0,
- 'modified': '2011-05-04 14:41:43',
+ 'modified': '2011-10-12 13:02:13',
'modified_by': 'Administrator',
'owner': 'Administrator'
},
@@ -14,6 +14,7 @@
{
'autoname': 'IDTD/.#####',
'colour': 'White:FFF',
+ 'default_print_format': 'Standard',
'doctype': 'DocType',
'istable': 1,
'module': 'Buying',
@@ -21,7 +22,7 @@
'section_style': 'Tray',
'server_code_error': ' ',
'show_in_menu': 0,
- 'version': 29
+ 'version': 34
},
# These values are common for all DocField
@@ -44,7 +45,6 @@
'doctype': 'DocField',
'fieldname': 'schedule_date',
'fieldtype': 'Date',
- 'idx': 1,
'label': 'Required Date',
'no_copy': 1,
'oldfieldname': 'schedule_date',
@@ -60,7 +60,6 @@
'doctype': 'DocField',
'fieldname': 'item_code',
'fieldtype': 'Link',
- 'idx': 2,
'in_filter': 1,
'label': 'Item Code',
'oldfieldname': 'item_code',
@@ -78,14 +77,13 @@
'doctype': 'DocField',
'fieldname': 'item_name',
'fieldtype': 'Data',
- 'idx': 3,
'in_filter': 1,
'label': 'Item Name',
'oldfieldname': 'item_name',
'oldfieldtype': 'Data',
'permlevel': 0,
'reqd': 1,
- 'search_index': 0,
+ 'search_index': 1,
'width': '100px'
},
@@ -94,7 +92,6 @@
'doctype': 'DocField',
'fieldname': 'description',
'fieldtype': 'Text',
- 'idx': 4,
'label': 'Description',
'oldfieldname': 'description',
'oldfieldtype': 'Text',
@@ -108,7 +105,6 @@
'doctype': 'DocField',
'fieldname': 'warehouse',
'fieldtype': 'Link',
- 'idx': 5,
'label': 'Warehouse',
'oldfieldname': 'warehouse',
'oldfieldtype': 'Link',
@@ -125,14 +121,12 @@
'doctype': 'DocField',
'fieldname': 'brand',
'fieldtype': 'Link',
- 'idx': 6,
'label': 'Brand',
'oldfieldname': 'brand',
'oldfieldtype': 'Link',
'options': 'Brand',
'permlevel': 1,
'print_hide': 1,
- 'search_index': 0,
'width': '100px'
},
@@ -142,7 +136,6 @@
'doctype': 'DocField',
'fieldname': 'item_group',
'fieldtype': 'Link',
- 'idx': 7,
'in_filter': 1,
'label': 'Item Group',
'no_copy': 0,
@@ -152,7 +145,7 @@
'permlevel': 1,
'print_hide': 1,
'reqd': 0,
- 'search_index': 0
+ 'search_index': 1
},
# DocField
@@ -162,7 +155,6 @@
'doctype': 'DocField',
'fieldname': 'qty',
'fieldtype': 'Currency',
- 'idx': 8,
'label': 'Quantity',
'no_copy': 0,
'oldfieldname': 'qty',
@@ -178,7 +170,6 @@
'doctype': 'DocField',
'fieldname': 'lead_time_date',
'fieldtype': 'Date',
- 'idx': 9,
'label': 'Lead Time Date',
'no_copy': 1,
'oldfieldname': 'lead_time_date',
@@ -192,7 +183,6 @@
'doctype': 'DocField',
'fieldname': 'uom',
'fieldtype': 'Link',
- 'idx': 10,
'label': 'Stock UOM',
'no_copy': 0,
'oldfieldname': 'uom',
@@ -200,7 +190,6 @@
'options': 'UOM',
'permlevel': 1,
'reqd': 1,
- 'search_index': 0,
'width': '50px'
},
@@ -209,7 +198,6 @@
'doctype': 'DocField',
'fieldname': 'min_order_qty',
'fieldtype': 'Currency',
- 'idx': 11,
'label': 'Min Order Qty',
'no_copy': 1,
'oldfieldname': 'min_order_qty',
@@ -225,7 +213,6 @@
'doctype': 'DocField',
'fieldname': 'projected_qty',
'fieldtype': 'Currency',
- 'idx': 12,
'label': 'Projected Qty',
'no_copy': 1,
'oldfieldname': 'projected_qty',
@@ -240,7 +227,6 @@
'doctype': 'DocField',
'fieldname': 'ordered_qty',
'fieldtype': 'Currency',
- 'idx': 13,
'label': 'Ordered Qty',
'no_copy': 1,
'oldfieldname': 'ordered_qty',
@@ -253,9 +239,9 @@
'doctype': 'DocField',
'fieldname': 'sales_order_no',
'fieldtype': 'Link',
- 'idx': 14,
'label': 'Sales Order No',
'no_copy': 1,
+ 'options': 'Sales Order',
'permlevel': 1,
'print_hide': 1
},
@@ -266,7 +252,6 @@
'doctype': 'DocField',
'fieldname': 'page_break',
'fieldtype': 'Check',
- 'idx': 15,
'label': 'Page Break',
'no_copy': 1,
'oldfieldname': 'page_break',
diff --git a/erpnext/buying/doctype/po_detail/po_detail.txt b/erpnext/buying/doctype/po_detail/po_detail.txt
old mode 100644
new mode 100755
index 71d78df..1512666
--- a/erpnext/buying/doctype/po_detail/po_detail.txt
+++ b/erpnext/buying/doctype/po_detail/po_detail.txt
@@ -5,8 +5,8 @@
{
'creation': '2010-08-08 17:09:12',
'docstatus': 0,
- 'modified': '2010-11-12 16:53:30',
- 'modified_by': 'sneha@webnotestech.com',
+ 'modified': '2011-12-14 10:49:46',
+ 'modified_by': 'Administrator',
'owner': 'Administrator'
},
@@ -14,6 +14,7 @@
{
'autoname': 'POD/.#####',
'colour': 'White:FFF',
+ 'default_print_format': 'Standard',
'doctype': 'DocType',
'istable': 1,
'module': 'Buying',
@@ -21,7 +22,7 @@
'section_style': 'Tray',
'server_code_error': ' ',
'show_in_menu': 0,
- 'version': 46
+ 'version': 60
},
# These values are common for all DocField
@@ -45,7 +46,6 @@
'fieldname': 'schedule_date',
'fieldtype': 'Date',
'hidden': 0,
- 'idx': 1,
'in_filter': 1,
'label': 'Reqd By Date',
'no_copy': 1,
@@ -54,7 +54,7 @@
'permlevel': 0,
'print_hide': 1,
'reqd': 1,
- 'search_index': 0
+ 'search_index': 1
},
# DocField
@@ -62,7 +62,6 @@
'doctype': 'DocField',
'fieldname': 'item_code',
'fieldtype': 'Link',
- 'idx': 2,
'in_filter': 1,
'label': 'Item Code',
'oldfieldname': 'item_code',
@@ -81,7 +80,6 @@
'fieldname': 'item_name',
'fieldtype': 'Data',
'hidden': 0,
- 'idx': 3,
'in_filter': 1,
'label': 'Item Name',
'oldfieldname': 'item_name',
@@ -89,7 +87,7 @@
'permlevel': 0,
'print_hide': 1,
'reqd': 1,
- 'search_index': 0
+ 'search_index': 1
},
# DocField
@@ -97,7 +95,6 @@
'doctype': 'DocField',
'fieldname': 'description',
'fieldtype': 'Small Text',
- 'idx': 4,
'label': 'Description',
'oldfieldname': 'description',
'oldfieldtype': 'Small Text',
@@ -110,10 +107,77 @@
{
'default': '0.00',
'doctype': 'DocField',
+ 'fieldname': 'qty',
+ 'fieldtype': 'Currency',
+ 'label': 'Quantity',
+ 'oldfieldname': 'qty',
+ 'oldfieldtype': 'Currency',
+ 'permlevel': 0,
+ 'reqd': 1,
+ 'trigger': 'Client',
+ 'width': '60px'
+ },
+
+ # DocField
+ {
+ 'doctype': 'DocField',
+ 'fieldname': 'import_ref_rate',
+ 'fieldtype': 'Currency',
+ 'label': 'Ref Rate ',
+ 'permlevel': 0
+ },
+
+ # DocField
+ {
+ 'doctype': 'DocField',
+ 'fieldname': 'discount_rate',
+ 'fieldtype': 'Currency',
+ 'label': 'Discount %',
+ 'permlevel': 0,
+ 'trigger': 'Client'
+ },
+
+ # DocField
+ {
+ 'doctype': 'DocField',
+ 'fieldname': 'import_rate',
+ 'fieldtype': 'Currency',
+ 'hidden': 0,
+ 'label': 'Rate ',
+ 'oldfieldname': 'import_rate',
+ 'oldfieldtype': 'Currency',
+ 'permlevel': 0,
+ 'print_hide': 0,
+ 'trigger': 'Client'
+ },
+
+ # DocField
+ {
+ 'doctype': 'DocField',
+ 'fieldname': 'import_amount',
+ 'fieldtype': 'Currency',
+ 'label': 'Amount',
+ 'oldfieldname': 'import_amount',
+ 'oldfieldtype': 'Currency',
+ 'permlevel': 1
+ },
+
+ # DocField
+ {
+ 'doctype': 'DocField',
+ 'fieldname': 'purchase_ref_rate',
+ 'fieldtype': 'Currency',
+ 'label': 'Ref Rate *',
+ 'permlevel': 0
+ },
+
+ # DocField
+ {
+ 'default': '0.00',
+ 'doctype': 'DocField',
'fieldname': 'purchase_rate',
'fieldtype': 'Currency',
- 'idx': 7,
- 'label': 'Rate (Default Curr.)',
+ 'label': 'Rate (Default Curr.) *',
'oldfieldname': 'purchase_rate',
'oldfieldtype': 'Currency',
'permlevel': 0,
@@ -129,7 +193,6 @@
'doctype': 'DocField',
'fieldname': 'amount',
'fieldtype': 'Currency',
- 'idx': 8,
'label': 'Amount (Default Curr.)',
'oldfieldname': 'amount',
'oldfieldtype': 'Currency',
@@ -140,72 +203,10 @@
# DocField
{
- 'default': '0.00',
- 'doctype': 'DocField',
- 'fieldname': 'qty',
- 'fieldtype': 'Currency',
- 'idx': 9,
- 'label': 'Quantity',
- 'oldfieldname': 'qty',
- 'oldfieldtype': 'Currency',
- 'permlevel': 0,
- 'reqd': 1,
- 'trigger': 'Client',
- 'width': '60px'
- },
-
- # DocField
- {
- 'doctype': 'DocField',
- 'fieldname': 'import_rate',
- 'fieldtype': 'Currency',
- 'hidden': 0,
- 'idx': 9,
- 'label': 'Rate',
- 'oldfieldname': 'import_rate',
- 'oldfieldtype': 'Currency',
- 'permlevel': 0,
- 'print_hide': 0,
- 'trigger': 'Client'
- },
-
- # DocField
- {
- 'doctype': 'DocField',
- 'fieldname': 'uom',
- 'fieldtype': 'Link',
- 'idx': 10,
- 'label': 'UOM',
- 'oldfieldname': 'uom',
- 'oldfieldtype': 'Link',
- 'options': 'UOM',
- 'permlevel': 0,
- 'print_hide': 0,
- 'reqd': 1,
- 'search_index': 0,
- 'trigger': 'Client',
- 'width': '100px'
- },
-
- # DocField
- {
- 'doctype': 'DocField',
- 'fieldname': 'import_amount',
- 'fieldtype': 'Currency',
- 'idx': 10,
- 'label': 'Amount',
- 'oldfieldname': 'import_amount',
- 'oldfieldtype': 'Currency',
- 'permlevel': 1
- },
-
- # DocField
- {
'doctype': 'DocField',
'fieldname': 'warehouse',
'fieldtype': 'Link',
'hidden': 0,
- 'idx': 11,
'label': 'Warehouse',
'oldfieldname': 'warehouse',
'oldfieldtype': 'Link',
@@ -218,12 +219,40 @@
# DocField
{
+ 'doctype': 'DocField',
+ 'fieldname': 'project_name',
+ 'fieldtype': 'Link',
+ 'in_filter': 1,
+ 'label': 'Project Name',
+ 'options': 'Project',
+ 'permlevel': 0,
+ 'print_hide': 1,
+ 'report_hide': 0
+ },
+
+ # DocField
+ {
+ 'doctype': 'DocField',
+ 'fieldname': 'uom',
+ 'fieldtype': 'Link',
+ 'label': 'UOM',
+ 'oldfieldname': 'uom',
+ 'oldfieldtype': 'Link',
+ 'options': 'UOM',
+ 'permlevel': 0,
+ 'print_hide': 0,
+ 'reqd': 1,
+ 'trigger': 'Client',
+ 'width': '100px'
+ },
+
+ # DocField
+ {
'colour': 'White:FFF',
'doctype': 'DocField',
'fieldname': 'conversion_factor',
'fieldtype': 'Currency',
'hidden': 0,
- 'idx': 11,
'label': 'Conversion Factor',
'oldfieldname': 'conversion_factor',
'oldfieldtype': 'Currency',
@@ -236,27 +265,10 @@
# DocField
{
- 'colour': 'White:FFF',
- 'doctype': 'DocField',
- 'fieldname': 'prevdoc_doctype',
- 'fieldtype': 'Data',
- 'hidden': 1,
- 'idx': 12,
- 'label': 'Prevdoc DocType',
- 'no_copy': 0,
- 'oldfieldname': 'prevdoc_doctype',
- 'oldfieldtype': 'Data',
- 'permlevel': 1,
- 'print_hide': 1
- },
-
- # DocField
- {
'doctype': 'DocField',
'fieldname': 'stock_uom',
'fieldtype': 'Data',
'hidden': 0,
- 'idx': 12,
'label': 'Stock UOM',
'oldfieldname': 'stock_uom',
'oldfieldtype': 'Data',
@@ -270,10 +282,24 @@
{
'colour': 'White:FFF',
'doctype': 'DocField',
+ 'fieldname': 'prevdoc_doctype',
+ 'fieldtype': 'Data',
+ 'hidden': 1,
+ 'label': 'Prevdoc DocType',
+ 'no_copy': 0,
+ 'oldfieldname': 'prevdoc_doctype',
+ 'oldfieldtype': 'Data',
+ 'permlevel': 1,
+ 'print_hide': 1
+ },
+
+ # DocField
+ {
+ 'colour': 'White:FFF',
+ 'doctype': 'DocField',
'fieldname': 'prevdoc_docname',
'fieldtype': 'Link',
'hidden': 0,
- 'idx': 13,
'in_filter': 1,
'label': 'Indent No',
'no_copy': 0,
@@ -292,7 +318,6 @@
'fieldname': 'prevdoc_date',
'fieldtype': 'Date',
'hidden': 0,
- 'idx': 14,
'in_filter': 1,
'label': 'Indent Date',
'oldfieldname': 'prevdoc_date',
@@ -309,7 +334,6 @@
'fieldname': 'prevdoc_detail_docname',
'fieldtype': 'Data',
'hidden': 1,
- 'idx': 15,
'in_filter': 1,
'label': 'Indent Detail No',
'no_copy': 0,
@@ -326,14 +350,12 @@
'fieldname': 'brand',
'fieldtype': 'Link',
'hidden': 0,
- 'idx': 16,
'label': 'Brand',
'oldfieldname': 'brand',
'oldfieldtype': 'Link',
'options': 'Brand',
'permlevel': 1,
- 'print_hide': 1,
- 'search_index': 0
+ 'print_hide': 1
},
# DocField
@@ -342,7 +364,6 @@
'fieldname': 'item_group',
'fieldtype': 'Link',
'hidden': 0,
- 'idx': 17,
'in_filter': 1,
'label': 'Item Group',
'oldfieldname': 'item_group',
@@ -350,21 +371,21 @@
'options': 'Item Group',
'permlevel': 1,
'print_hide': 1,
- 'search_index': 0
+ 'search_index': 1
},
# DocField
{
+ 'colour': 'White:FFF',
'doctype': 'DocField',
'fieldname': 'stock_qty',
'fieldtype': 'Currency',
'hidden': 0,
- 'idx': 20,
'label': 'Stock Qty',
'no_copy': 1,
'oldfieldname': 'stock_qty',
'oldfieldtype': 'Currency',
- 'permlevel': 0,
+ 'permlevel': 1,
'print_hide': 1,
'trigger': 'Client',
'width': '100px'
@@ -376,7 +397,6 @@
'fieldname': 'received_qty',
'fieldtype': 'Currency',
'hidden': 0,
- 'idx': 21,
'label': 'Received Qty',
'no_copy': 1,
'oldfieldname': 'received_qty',
@@ -392,7 +412,6 @@
'fieldname': 'billed_qty',
'fieldtype': 'Currency',
'hidden': 0,
- 'idx': 22,
'label': 'Billed Quantity',
'no_copy': 1,
'oldfieldname': 'billed_qty',
@@ -409,7 +428,6 @@
'fieldname': 'item_tax_rate',
'fieldtype': 'Small Text',
'hidden': 1,
- 'idx': 23,
'label': 'Item Tax Rate',
'oldfieldname': 'item_tax_rate',
'oldfieldtype': 'Small Text',
@@ -425,7 +443,6 @@
'fieldname': 'page_break',
'fieldtype': 'Check',
'hidden': 0,
- 'idx': 24,
'label': 'Page Break',
'no_copy': 1,
'oldfieldname': 'page_break',
diff --git a/erpnext/buying/doctype/purchase_common/purchase_common.js b/erpnext/buying/doctype/purchase_common/purchase_common.js
index f91b1d8..a429b68 100644
--- a/erpnext/buying/doctype/purchase_common/purchase_common.js
+++ b/erpnext/buying/doctype/purchase_common/purchase_common.js
@@ -13,14 +13,6 @@
}
}
-/*
-// ======================== Supplier =================================================
-cur_frm.cscript.supplier = function(doc, cdt, cdn) {
- if(doc.supplier) get_server_fields('get_supplier_details', doc.supplier,'', doc, cdt, cdn, 1);
-}
-
-*/
-
// ======================== Conversion Rate ==========================================
cur_frm.cscript.conversion_rate = function(doc,cdt,cdn) {
@@ -54,22 +46,11 @@
}
}
-//==================== Purchase UOM Get Query =======================================================
-//cur_frm.fields_dict[fname].grid.get_field("uom").get_query = function(doc, cdt, cdn) {
-// var d = locals[this.doctype][this.docname];
-// return 'SELECT `tabUOM Conversion Detail`.`uom` FROM `tabUOM Conversion Detail` WHERE `tabUOM Conversion Detail`.`parent` = "' + d.item_code + '" AND `tabUOM Conversion Detail`.uom LIKE "%s"'
-//}
-
-
//==================== UOM ======================================================================
cur_frm.cscript.uom = function(doc, cdt, cdn) {
var d = locals[cdt][cdn];
if (d.item_code && d.uom) {
call_back = function(doc, cdt, cdn){
- //refresh_field('purchase_rate', d.name, fname);
- //refresh_field('qty' , d.name, fname);
- //refresh_field('conversion_factor' , d.name, fname);
- //var doc = locals[cdt][cdn];
cur_frm.cscript.calc_amount(doc, 2);
}
str_arg = {'item_code':d.item_code, 'uom':d.uom, 'stock_qty':flt(d.stock_qty), 'qty': flt(d.qty)}
@@ -115,47 +96,26 @@
//=================== Purchase Rate ==============================================================
cur_frm.cscript.purchase_rate = function(doc, cdt, cdn) {
- // Calculate Amount
cur_frm.cscript.calc_amount(doc, 2);
}
//==================== Import Rate ================================================================
cur_frm.cscript.import_rate = function(doc, cdt, cdn) {
- // Calculate Amount
cur_frm.cscript.calc_amount(doc, 1);
}
-
-//====================== Calculate Amount ============================================================
-/*cur_frm.cscript.calc_amount = function(doc, n) {
- // Set defaults
- doc = locals[doc.doctype][doc.name]
- if (! doc.conversion_rate) doc.conversion_rate = 1;
- if(!n) n=0;
- var net_total = 0;
- var net_total_import = 0;
-
- var cl = getchildren(tname, doc.name, fname);
-
- for(var i=0;i<cl.length;i++)
- {
- if(n == 1){
- set_multiple(tname, cl[i].name, {'purchase_rate': flt(doc.conversion_rate) * flt(cl[i].import_rate) }, fname);
- set_multiple(tname, cl[i].name, {'amount': flt(flt(cl[i].qty) * flt(doc.conversion_rate) * flt(cl[i].import_rate))}, fname);
- set_multiple(tname, cl[i].name, {'import_amount': flt(flt(cl[i].qty) * flt(cl[i].import_rate))}, fname);
- }
- if(n == 2){
- set_multiple(tname, cl[i].name, {'amount': flt(flt(cl[i].qty) * flt(cl[i].purchase_rate)), 'import_rate': flt(flt(cl[i].purchase_rate) / flt(doc.conversion_rate)) }, fname);
- set_multiple(tname, cl[i].name, {'import_amount': flt(flt(cl[i].qty) * flt(cl[i].purchase_rate) / flt(doc.conversion_rate))}, fname);
- }
- net_total += flt(flt(cl[i].qty) * flt(cl[i].purchase_rate));
- net_total_import += flt(flt(cl[i].qty) * flt(cl[i].import_rate));
- }
- doc.net_total = flt(net_total) ;
- doc.net_total_import = flt(net_total_import) ;
- refresh_field('net_total');
- refresh_field('net_total_import');
-} */
+//==================== Discount Rate ================================================================
+cur_frm.cscript.discount_rate = function(doc, cdt, cdn) {
+ cur_frm.cscript.calc_amount(doc, 4);
+}
+//==================== Purchase Ref Rate ================================================================
+cur_frm.cscript.purchase_ref_rate = function(doc, cdt, cdn) {
+ cur_frm.cscript.calc_amount(doc, 4);
+}
+//==================== Import Ref Rate ================================================================
+cur_frm.cscript.import_ref_rate = function(doc, cdt, cdn) {
+ cur_frm.cscript.calc_amount(doc, 5);
+}
//==================== check if item table is blank ==============================================
var is_item_table = function(doc,cdt,cdn) {
@@ -173,18 +133,11 @@
is_item_table(doc,cdt,cdn);
// Step 2:=> Calculate Amount
cur_frm.cscript.calc_amount(doc, 1);
+
+ // calculate advances if pv
+ if(doc.doctype == 'Payable Voucher') calc_total_advance(doc, cdt, cdn);
}
-
-
-/*cur_frm.cscript.other_fname = "purchase_tax_details";
-other_charges ===> purchase_tax_details
-RV Tax Detail ===> Purchase Tax Detail
-cur_frm.cscript.recalc ===> cur_frm.cscript.calc_amount
-export ===> import
-other_charges_total ===> total_tax
-Other Charges Calculation ===> Tax Calculation*/
-
// **************** RE-CALCULATE VALUES ***************************
cur_frm.cscript['Re-Calculate Values'] = function(doc, cdt, cdn) {
@@ -205,8 +158,7 @@
validated = false;
}
}
- if(doc.doctype != 'Payable Voucher') cur_frm.cscript.calc_amount(doc, 1);
- else if(doc.doctype == 'Payable Voucher') cur_frm.cscript.calc_total(doc);
+ cur_frm.cscript.calc_amount(doc, 1);
}
@@ -218,10 +170,6 @@
return detail;
}
- //if(cur_frm.cscript.custom_recalc)cur_frm.cscript.custom_recalc(doc);
-
-
-
cur_frm.cscript.amount = function(doc, cdt, cdn) {
cur_frm.cscript.calc_amount(doc, 3);
}
@@ -241,25 +189,56 @@
for(var i=0;i<cl.length;i++)
{
+ var rate_fld = (doc.doctype != 'Payable Voucher') ? 'purchase_rate': 'rate';
+ var tmp = {};
+ if(!cl[i].discount_rate) cl[i].discount_rate = 0;
+
if(n == 1){
- set_multiple(tname, cl[i].name, {'purchase_rate': flt(doc.conversion_rate) * flt(cl[i].import_rate) }, fname);
+ set_multiple(tname, cl[i].name, {'purchase_ref_rate':flt(cl[i].import_ref_rate)*flt(doc.conversion_rate)}, fname);
+ set_multiple(tname, cl[i].name, {'discount_rate': flt(flt( flt( flt(cl[i].import_ref_rate) - flt(cl[i].import_rate) ) * 100 )/flt(cl[i].import_ref_rate)) }, fname);
+ tmp[rate_fld] = flt(doc.conversion_rate) * flt(cl[i].import_rate);
+ set_multiple(tname, cl[i].name, tmp, fname);
+
set_multiple(tname, cl[i].name, {'amount': flt(flt(cl[i].qty) * flt(doc.conversion_rate) * flt(cl[i].import_rate))}, fname);
set_multiple(tname, cl[i].name, {'import_amount': flt(flt(cl[i].qty) * flt(cl[i].import_rate))}, fname);
- }
- if(n == 2){
- set_multiple(tname, cl[i].name, {'amount': flt(flt(cl[i].qty) * flt(cl[i].purchase_rate)), 'import_rate': flt(flt(cl[i].purchase_rate) / flt(doc.conversion_rate)) }, fname);
- set_multiple(tname, cl[i].name, {'import_amount': flt(flt(cl[i].qty) * flt(cl[i].purchase_rate) / flt(doc.conversion_rate))}, fname);
- }
- if(n == 3){
- set_multiple(tname, cl[i].name, {'purchase_rate': flt(flt(cl[i].amount) / flt(cl[i].qty)) }, fname);
- set_multiple(tname, cl[i].name, {'import_rate': flt(flt(cl[i].purchase_rate) / flt(doc.conversion_rate))}, fname);
- set_multiple(tname, cl[i].name, {'import_amount': flt(flt(cl[i].qty) * flt(cl[i].purchase_rate) / flt(doc.conversion_rate))}, fname);
- }
+
+ }else if(n == 2){
+ set_multiple(tname, cl[i].name, {'purchase_ref_rate':flt(cl[i].import_ref_rate)*flt(doc.conversion_rate)}, fname);
+ set_multiple(tname, cl[i].name, {'discount_rate': flt(flt( flt( flt(cl[i].purchase_ref_rate) - flt(cl[i][rate_fld]) ) * 100 )/flt(cl[i].purchase_ref_rate)) }, fname);
+ set_multiple(tname, cl[i].name, {'amount': flt(flt(cl[i].qty) * flt(cl[i][rate_fld])),}, fname);
+ set_multiple(tname, cl[i].name, {'import_rate': flt(flt(cl[i][rate_fld]) / flt(doc.conversion_rate)) }, fname);
+ set_multiple(tname, cl[i].name, {'import_amount': flt(flt(cl[i].qty) * flt(cl[i][rate_fld]) / flt(doc.conversion_rate))}, fname);
+
+ }else if(n == 3){
+ tmp[rate_fld] = flt(flt(cl[i].amount) / flt(cl[i].qty));
+ set_multiple(tname, cl[i].name, tmp, fname);
+ set_multiple(tname, cl[i].name, {'import_rate': flt(flt(cl[i][rate_fld]) / flt(doc.conversion_rate))}, fname);
+ set_multiple(tname, cl[i].name, {'import_amount': flt(flt(cl[i].qty) * flt(cl[i][rate_fld]) / flt(doc.conversion_rate))}, fname);
+
+ }else if( n==4){
+
+ set_multiple(tname, cl[i].name, {'import_ref_rate': flt(flt(cl[i].purchase_ref_rate) / flt(doc.conversion_rate))}, fname);
+
+ tmp[rate_fld] = flt( flt(cl[i].purchase_ref_rate) - flt(flt(cl[i].purchase_ref_rate)*flt(cl[i].discount_rate)/100) )
+ set_multiple(tname, cl[i].name, tmp, fname);
+
+ set_multiple(tname, cl[i].name, {'import_rate': flt(flt(cl[i][rate_fld]) / flt(doc.conversion_rate))}, fname);
+ set_multiple(tname, cl[i].name, {'amount':flt(flt(cl[i].qty) * flt(cl[i][rate_fld]))}, fname);
+ set_multiple(tname, cl[i].name, {'import_amount': flt(flt(cl[i].qty) * flt(cl[i][rate_fld]) / flt(doc.conversion_rate))}, fname);
+
+ }else if( n==5){
+ tmp[rate_fld] = flt( flt(cl[i].import_ref_rate) - flt(flt(cl[i].import_ref_rate)*flt(cl[i].discount_rate)/100) ) * flt(doc.conversion_rate);
+ set_multiple(tname, cl[i].name, {'purchase_ref_rate': flt(flt(cl[i].import_ref_rate) * flt(doc.conversion_rate))}, fname);
+ set_multiple(tname, cl[i].name, tmp, fname);
+ set_multiple(tname, cl[i].name, {'import_rate': flt(flt(cl[i][rate_fld]) / flt(doc.conversion_rate))}, fname);
+ set_multiple(tname, cl[i].name, {'amount':flt(flt(cl[i].qty) * flt(cl[i][rate_fld]))}, fname);
+ set_multiple(tname, cl[i].name, {'import_amount': flt(flt(cl[i].qty) * flt(cl[i][rate_fld]) / flt(doc.conversion_rate))}, fname);
+ }
+
if (n != 3){
- net_total += flt(flt(cl[i].qty) * flt(cl[i].purchase_rate));
+ net_total += flt(flt(cl[i].qty) * flt(cl[i][rate_fld]));
net_total_import += flt(flt(cl[i].qty) * flt(cl[i].import_rate));
- }
- else if(n == 3){
+ } else if(n == 3){
net_total += flt(cl[i].amount);
net_total_import += flt(cl[i].amount) / flt(doc.conversion_rate);
}
@@ -296,7 +275,7 @@
}
cur_frm.cscript.calc_doc_values(doc, cdt, cdn, tname, fname, other_fname); // calculates total amounts
- refresh_many(['net_total','grand_total','rounded_total','grand_total_import','rounded_total_import','in_words','in_words_import','purchase_tax_details','total_tax','other_charges_added', 'other_charges_deducted','net_total_import','other_charges_added_import','other_charges_deducted_import']);
+ refresh_many(['net_total', 'grand_total', 'rounded_total', 'grand_total_import', 'rounded_total_import', 'in_words', 'in_words_import', 'purchase_tax_details', 'total_tax', 'other_charges_added', 'other_charges_deducted', 'net_total_import', 'other_charges_added_import', 'other_charges_deducted_import']);
}
@@ -451,21 +430,27 @@
doc.grand_total_import = flt(flt(doc.grand_total) / flt(doc.conversion_rate));
doc.rounded_total_import = Math.round(doc.grand_total_import);
+ refresh_many(['net_total','total_taxes','grand_total']);
+
+
if(doc.doctype == 'Payable Voucher'){
- var t_tds_tax = 0.0;
-
- doc.total_tds_on_voucher = flt(doc.ded_amount)
- // total amount to pay
-
- doc.total_amount_to_pay = flt(flt(net_total) + flt(other_charges_added) - flt(other_charges_deducted) - flt(doc.total_tds_on_voucher));
-
- // outstanding amount
- if(doc.docstatus==0) doc.outstanding_amount = flt(doc.net_total) + flt(other_charges_added) - flt(other_charges_deducted) - flt(doc.total_tds_on_voucher) - flt(doc.total_advance);
-
- refresh_many(['net_total','total_taxes','grand_total','total_tds_on_voucher','total_amount_to_pay', 'outstanding_amount']);
+ calculate_outstanding(doc);
}
}
+var calculate_outstanding = function(doc) {
+ var t_tds_tax = 0.0;
+ doc.total_tds_on_voucher = flt(doc.ded_amount);
+
+ // total amount to pay
+ doc.total_amount_to_pay = flt(flt(doc.net_total) + flt(doc.other_charges_added) - flt(doc.other_charges_deducted) - flt(doc.total_tds_on_voucher));
+
+ // outstanding amount
+ if(doc.docstatus==0) doc.outstanding_amount = flt(doc.net_total) + flt(doc.other_charges_added) - flt(doc.other_charges_deducted) - flt(doc.total_tds_on_voucher) - flt(doc.total_advance);
+
+ refresh_many(['total_tds_on_voucher','total_amount_to_pay', 'outstanding_amount']);
+}
+
cur_frm.cscript.check_charge_type_and_get_tax_amount = function(doc, tax, t, cl, rate, print_amt) {
doc = locals[doc.doctype][doc.name];
diff --git a/erpnext/buying/doctype/purchase_common/purchase_common.py b/erpnext/buying/doctype/purchase_common/purchase_common.py
index 29658cb..84bfffb 100644
--- a/erpnext/buying/doctype/purchase_common/purchase_common.py
+++ b/erpnext/buying/doctype/purchase_common/purchase_common.py
@@ -120,7 +120,8 @@
'conversion_factor' : '1',
'warehouse' : wh,
'item_tax_rate' : str(t),
- 'batch_no' : ''
+ 'batch_no' : '',
+ 'discount_rate' : 0
}
# get min_order_qty from item
@@ -139,6 +140,8 @@
# get last purchase rate as per stock uom and default currency for following list of doctypes
if obj.doc.doctype in ['Supplier Quotation', 'Purchase Order', 'Purchase Receipt']:
+ ret['purchase_ref_rate'] = item and flt(item[0]['last_purchase_rate']) or 0
+ ret['import_ref_rate'] = flt(item and flt(item[0]['last_purchase_rate']) or 0) / flt(obj.doc.fields.has_key('conversion_rate') and flt(obj.doc.conversion_rate) or 1)
ret['purchase_rate'] = item and flt(item[0]['last_purchase_rate']) or 0
ret['import_rate'] = flt(item and flt(item[0]['last_purchase_rate']) or 0) / flt(obj.doc.fields.has_key('conversion_rate') and flt(obj.doc.conversion_rate) or 1)
@@ -159,8 +162,11 @@
if uom:
ret = {
'conversion_factor' : flt(uom[0]['conversion_factor']),
- 'qty' : flt(arg['stock_qty']) / flt(uom[0]['conversion_factor']),
- 'purchase_rate' : (lpr and flt(lpr[0]['last_purchase_rate']) * flt(uom[0]['conversion_factor'])) or 0
+ 'qty' : flt(arg['stock_qty']) / flt(uom[0]['conversion_factor']),
+ 'purchase_ref_rate' : (lpr and flt(lpr[0]['last_purchase_rate']) * flt(uom[0]['conversion_factor'])) or 0,
+ 'purchase_rate' : (lpr and flt(lpr[0]['last_purchase_rate']) * flt(uom[0]['conversion_factor'])) or 0,
+ 'import_ref_rate' : (lpr and flt(lpr[0]['last_purchase_rate']) * flt(uom[0]['conversion_factor'])/flt(self.doc.conversion_rate)) or 0,
+ 'import_rate' : (lpr and flt(lpr[0]['last_purchase_rate']) * flt(uom[0]['conversion_factor'])/flt(self.doc.conversion_rate)) or 0
}
return ret
@@ -170,8 +176,7 @@
for d in getlist(obj.doclist, obj.fname):
if d.item_code:
rate = sql("select last_purchase_rate from `tabItem` where name = '%s' and (ifnull(end_of_life,'')='' or end_of_life = '0000-00-00' or end_of_life > now())"% cstr(d.item_code), as_dict = 1 )
- d.purchase_rate = rate and flt(rate[0]['last_purchase_rate']) * flt(d.conversion_factor) or 0
-
+ d.purchase_rate = rate and flt(rate[0]['last_purchase_rate']) * flt(d.conversion_factor) or 0
if not rate[0]['last_purchase_rate']:
msgprint("%s has no Last Purchase Rate."% d.item_code)
@@ -243,7 +248,7 @@
raise Exception
# list criteria that should not repeat if item is stock item
- e = [d.schedule_date, d.item_code, d.warehouse, d.uom, d.fields.has_key('prevdoc_docname') and d.prevdoc_docname or '', d.fields.has_key('prevdoc_detail_docname') and d.prevdoc_detail_docname or '', d.fields.has_key('batch_no') and d.batch_no or '']
+ e = [d.schedule_date, d.item_code, d.description, d.warehouse, d.uom, d.fields.has_key('prevdoc_docname') and d.prevdoc_docname or '', d.fields.has_key('prevdoc_detail_docname') and d.prevdoc_detail_docname or '', d.fields.has_key('batch_no') and d.batch_no or '']
# if is not stock item
f = [d.schedule_date, d.item_code, d.description]
@@ -253,16 +258,16 @@
if ch and ch[0][0] == 'Yes':
# check for same items
if e in check_list:
- msgprint("Item %s has been entered more than once with same schedule date, warehouse and uom." % d.item_code)
- raise Exception
+ msgprint("""Item %s has been entered more than once with same description, schedule date, warehouse and uom.\n
+ Please change any of the field value to enter the item twice""" % d.item_code, raise_exception = 1)
else:
check_list.append(e)
elif ch and ch[0][0] == 'No':
# check for same items
if f in chk_dupl_itm:
- msgprint("Item %s has been entered more than once." % d.item_code)
- raise Exception
+ msgprint("""Item %s has been entered more than once with same description, schedule date.\n
+ Please change any of the field value to enter the item twice.""" % d.item_code, raise_exception = 1)
else:
chk_dupl_itm.append(f)
diff --git a/erpnext/buying/doctype/purchase_order/purchase_order.js b/erpnext/buying/doctype/purchase_order/purchase_order.js
index 5714126..d3fa37b 100644
--- a/erpnext/buying/doctype/purchase_order/purchase_order.js
+++ b/erpnext/buying/doctype/purchase_order/purchase_order.js
@@ -111,11 +111,10 @@
// ---------------------- Get project name --------------------------
-cur_frm.fields_dict['project_name'].get_query = function(doc, cdt, cdn) {
+cur_frm.fields_dict['po_details'].grid.get_field('project_name').get_query = function(doc, cdt, cdn) {
return 'SELECT `tabProject`.name FROM `tabProject` WHERE `tabProject`.status = "Open" AND `tabProject`.name LIKE "%s" ORDER BY `tabProject`.name ASC LIMIT 50';
}
-
//==================== Indent No Get Query =======================================================
//===== Only those Indents status != 'Completed' and docstatus = 1 i.e. submitted=================
cur_frm.fields_dict['indent_no'].get_query = function(doc) {
diff --git a/erpnext/buying/doctype/purchase_other_charges/purchase_other_charges.js b/erpnext/buying/doctype/purchase_other_charges/purchase_other_charges.js
index 9222997..d9735b6 100644
--- a/erpnext/buying/doctype/purchase_other_charges/purchase_other_charges.js
+++ b/erpnext/buying/doctype/purchase_other_charges/purchase_other_charges.js
@@ -111,15 +111,14 @@
/*---------------------- Get rate if account_head has account_type as TAX or CHARGEABLE-------------------------------------*/
cur_frm.fields_dict['purchase_tax_details'].grid.get_field("account_head").get_query = function(doc,cdt,cdn) {
- return 'SELECT tabAccount.name FROM tabAccount WHERE tabAccount.group_or_ledger="Ledger" AND tabAccount.docstatus != 2 AND (tabAccount.account_type = "Tax" OR tabAccount.account_type = "Chargeable" or (tabAccount.is_pl_account = "Yes" and tabAccount.debit_or_credit = "Debit")) AND tabAccount.name LIKE "%s"'
+ return 'SELECT tabAccount.name FROM tabAccount WHERE tabAccount.group_or_ledger="Ledger" AND tabAccount.docstatus != 2 AND (tabAccount.account_type = "Tax" OR tabAccount.account_type = "Chargeable" or (tabAccount.is_pl_account = "Yes" and tabAccount.debit_or_credit = "Debit")) AND tabAccount.company = "' + doc.company + '" AND tabAccount.name LIKE "%s"'
}
-//--------------------filter other charges master company-wise-----------------------------------------
-/*
-cur_frm.fields_dict.charge.get_query = function(doc) {
- return 'SELECT DISTINCT `tabOther Charges`.name FROM `tabOther Charges` WHERE `tabOther Charges`.company = "'+doc.company+'" AND `tabOther Charges`.company is not NULL AND `tabOther Charges`.docstatus !=2 AND `tabOther Charges`.name LIKE "%s" ORDER BY `tabOther Charges`.name LIMIT 50';
+
+cur_frm.fields_dict['purchase_tax_details'].grid.get_field("cost_center").get_query = function(doc) {
+ return 'SELECT `tabCost Center`.`name` FROM `tabCost Center` WHERE `tabCost Center`.`company_name` = "' +doc.company+'" AND `tabCost Center`.%(key)s LIKE "%s" AND `tabCost Center`.`group_or_ledger` = "Ledger" AND `tabCost Center`.`docstatus`!= 2 ORDER BY `tabCost Center`.`name` ASC LIMIT 50';
}
-*/
+
cur_frm.cscript.account_head = function(doc, cdt, cdn) {
var d = locals[cdt][cdn];
diff --git a/erpnext/buying/doctype/supplier/supplier.txt b/erpnext/buying/doctype/supplier/supplier.txt
index a7a08c3..0834898 100644
--- a/erpnext/buying/doctype/supplier/supplier.txt
+++ b/erpnext/buying/doctype/supplier/supplier.txt
@@ -333,4 +333,4 @@
'oldfieldtype': 'Small Text',
'permlevel': 1
}
-]
\ No newline at end of file
+]
diff --git a/erpnext/home/doctype/home_control/home_control.py b/erpnext/home/doctype/home_control/home_control.py
index 8242e74..ce15bfd 100644
--- a/erpnext/home/doctype/home_control/home_control.py
+++ b/erpnext/home/doctype/home_control/home_control.py
@@ -31,6 +31,8 @@
def get_modules(self):
rl = webnotes.user.get_roles()
ml = sql("select distinct t1.name, t1.module_icon, t1.module_label, t1.module_desc, t1.module_page from `tabModule Def` t1, `tabModule Def Role` t2 where t2.role in ('%s') and t1.disabled !='Yes' and ifnull(t1.is_hidden, 'No') != 'Yes' and t1.name = t2.parent order by t1.module_seq asc" % "','".join(rl), as_dict=1)
+ webnotes.response['login_url'] = session['data'].get('login_from', '')
+
return ml
def get_module_details(self,m):
@@ -48,8 +50,6 @@
AND t2.role IN ("%s")
AND ifnull(standard,"No")="No"''' % (m, '", "'.join(webnotes.user.get_roles())), as_dict=1)
- ret['login_url'] = session['data'].get('login_from', '')
-
return ret
# ----------------------------------------------------------------------------------------------------------------
diff --git a/erpnext/home/page/dashboard/dashboard.js b/erpnext/home/page/dashboard/dashboard.js
index 08be0af..aac42a3 100644
--- a/erpnext/home/page/dashboard/dashboard.js
+++ b/erpnext/home/page/dashboard/dashboard.js
@@ -10,8 +10,20 @@
pscript.dashboard_settings = {
company: sys_defaults.company,
- start: dateutil.obj_to_str(dateutil.add_days(new Date(), -180)),
- end: dateutil.obj_to_str(new Date()),
+ start: (function() {
+ var start_date = dateutil.add_days(new Date(), -180);
+ var year_start_date = dateutil.str_to_obj(sys_defaults.year_start_date);
+ if (start_date < year_start_date) { start_date = year_start_date; }
+ console.log(start_date);
+ return dateutil.obj_to_str(start_date);
+ })(),
+ end: (function() {
+ var end_date = new Date();
+ var year_end_date = dateutil.str_to_obj(sys_defaults.year_end_date);
+ if (end_date > year_end_date) { end_date = year_end_date; }
+ console.log(end_date);
+ return dateutil.obj_to_str(end_date);
+ })(),
interval: 30
}
diff --git a/erpnext/home/page/dashboard/dashboard.py b/erpnext/home/page/dashboard/dashboard.py
index 9ead6d6..c2378d3 100644
--- a/erpnext/home/page/dashboard/dashboard.py
+++ b/erpnext/home/page/dashboard/dashboard.py
@@ -133,19 +133,27 @@
webnotes.msgprint('Wrongly defined account: ' + acc)
print acc
raise e
-
- return self.glc.get_as_on_balance(acc, self.get_fiscal_year(start), start, debit_or_credit, lft, rgt)
+
+ fiscal_year = self.get_fiscal_year(start)
+ if fiscal_year:
+ return self.glc.get_as_on_balance(acc, fiscal_year, start, debit_or_credit, lft, rgt)
+ else:
+ webnotes.msgprint('Please select the START DATE and END DATE such that\
+ they fall within <b>fiscal year(s)</b> as defined in\
+ Setup > System > Fiscal Year.', raise_exception=1)
+
def get_fiscal_year(self, dt):
"""
get fiscal year from date
"""
import webnotes
- return webnotes.conn.sql("""
+ fiscal_year = webnotes.conn.sql("""
select name from `tabFiscal Year`
where year_start_date <= %s and
DATE_ADD(year_start_date, INTERVAL 1 YEAR) >= %s
- """, (dt, dt))[0][0]
+ """, (dt, dt))
+ return fiscal_year and (fiscal_year[0] and fiscal_year[0][0]) or None
def get_creation_trend(self, doctype, start, end):
"""
@@ -257,4 +265,4 @@
"start": "2011-05-01",
"end": "2011-08-01",
"interval": "7"
- }""")
\ No newline at end of file
+ }""")
diff --git a/erpnext/home/page/my_company/my_company.js b/erpnext/home/page/my_company/my_company.js
index 40bf155..ccda765 100644
--- a/erpnext/home/page/my_company/my_company.js
+++ b/erpnext/home/page/my_company/my_company.js
@@ -42,13 +42,48 @@
// Add user dialog and server call
//
pscript.myc_add_user = function() {
+ var fields = [{
+ fieldtype: 'Data',
+ fieldname: 'user',
+ reqd: 1,
+ label: 'Email Id of the user to add'
+ }];
+ console.log(pscript.is_erpnext_saas);
+
+ if(pscript.is_erpnext_saas==0) {
+ fields = fields.concat([
+ {
+ fieldtype: 'Data',
+ fieldname: 'first_name',
+ reqd: 1,
+ label: 'First Name'
+ },
+ {
+ fieldtype: 'Data',
+ fieldname: 'last_name',
+ reqd: 1,
+ label: 'Last Name'
+ },
+ {
+ fieldtype: 'Data',
+ fieldname: 'password',
+ reqd: 1,
+ label: 'Password'
+ }]);
+ }
+
+ fields.push({
+ fieldtype: 'Button',
+ label: 'Add',
+ fieldname: 'add'
+ });
+
+ console.log(fields);
+
var d = new wn.widgets.Dialog({
title: 'Add User',
width: 400,
- fields: [
- {fieldtype:'Data', fieldname:'user',reqd:1,label:'Email Id of the user to add'},
- {fieldtype:'Button', label:'Add', fieldname:'add'}
- ]
+ fields: fields
});
d.make();
d.fields_dict.add.input.onclick = function() {
@@ -242,7 +277,7 @@
// working img
var div = $a($td(this.tab, 0, 1), 'div');
this.working_img = $a(div,'img','',{display:'none'});
- this.working_img.src = 'images/ui/button-load.gif';
+ this.working_img.src = 'lib/images/ui/button-load.gif';
this.refresh_name_link();
@@ -603,17 +638,17 @@
this.input_wrapper = $a(this.wrapper, 'div', 'my-company-input-wrapper');
var tab = make_table(this.input_wrapper, 1, 2, '100%', ['64%','36%'], {padding: '3px'})
this.input = $a($td(tab,0,0), 'textarea');
- $(this.input).add_default_text( 'Send a message to ' + fullname);
// button
var div = $a(this.input_wrapper, 'div');
this.post = $btn(div, 'Post'.bold(), function() { me.post_message(); }, {margin:'0px 13px 0px 3px'})
- this.post.set_disabled();
+ this.post.disabled = true;
+
this.input.onkeyup = this.input.onchange = function() {
if(this.value) {
- me.post.set_enabled();
+ me.post.disabled = false;
} else {
- me.post.set_disabled();
+ me.post.disabled = true;
}
}
@@ -731,7 +766,7 @@
this.make_role_body(profile_id);
this.make_help_body();
- this.body.innerHTML = '<span style="color:#888">Loading...</span> <img src="images/ui/button-load.gif">'
+ this.body.innerHTML = '<span style="color:#888">Loading...</span> <img src="lib/images/ui/button-load.gif">'
var me=this;
d.onshow = function() {
@@ -829,7 +864,7 @@
var t = make_table($td(tbl, ridx, cidx),1,2,null,['16px', null],{marginRight:'5px'});
var ic = $a($td(t,0,0), 'img','',{cursor:'pointer', marginRight:'5px'});
- ic.src= 'images/icons/help.gif';
+ ic.src= 'lib/images/icons/help.gif';
ic.role = role;
ic.onclick = function(){
@@ -942,8 +977,8 @@
for(var i=0; i<(head_lst.length-1);i++){
$td(perm_tbl,0,i).innerHTML= "<b>"+head_lst[i]+"</b>";
}
- var accept_img1 = 'images/icons/accept.gif';
- var cancel_img1 = 'images/icons/cancel.gif';
+ var accept_img1 = 'lib/images/icons/accept.gif';
+ var cancel_img1 = 'lib/images/icons/cancel.gif';
for(i=1; i<perm.length+1; i++){
$td(perm_tbl,i,0).innerHTML= get_doctype_label(perm[i-1][0]);
diff --git a/erpnext/home/page/my_company/my_company.py b/erpnext/home/page/my_company/my_company.py
index 3ff1482..4931ea9 100644
--- a/erpnext/home/page/my_company/my_company.py
+++ b/erpnext/home/page/my_company/my_company.py
@@ -34,6 +34,11 @@
return 'Cannot disable Administrator'
webnotes.conn.sql("update tabProfile set enabled=0 where name=%s", arg)
+ sid_list = webnotes.conn.sql("SELECT sid FROM `tabSessions` WHERE user=%s", arg)
+ from webnotes.auth import LoginManager
+ login_manager = LoginManager()
+ for sid in sid_list:
+ login_manager.logout(sid=sid)
return 0
#
@@ -57,14 +62,15 @@
from server_tools.gateway_utils import add_user_gateway
add_user_gateway(args['user'])
- add_profile(args['user'])
+ add_profile(args)
#
# add profile record
#
-def add_profile(email):
+def add_profile(args):
from webnotes.utils import validate_email_add
from webnotes.model.doc import Document
+ email = args['user']
sql = webnotes.conn.sql
@@ -83,9 +89,17 @@
pr = Document('Profile')
pr.name = email
pr.email = email
- pr.enabled=1
- pr.user_type='System User'
- pr.save(1)
+ pr.first_name = args.get('first_name')
+ pr.last_name = args.get('last_name')
+ pr.enabled = 1
+ pr.user_type = 'System User'
+ pr.save(1)
+
+ if args.get('password'):
+ sql("""
+ UPDATE tabProfile
+ SET password = PASSWORD(%s)
+ WHERE name = %s""", (args.get('password'), email))
#
# post comment
@@ -140,7 +154,9 @@
if 'new_password' in args:
if cint(webnotes.conn.get_value('Control Panel',None,'sync_with_gateway')):
import server_tools.gateway_utils
- webnotes.msgprint(server_tools.gateway_utils.change_password('', args['new_password'], args['user'], args['sys_admin_pwd'])['message'])
+ res = server_tools.gateway_utils.change_password('', args['new_password'], args['user'], args['sys_admin_pwd'])
+ if 'Traceback' not in res['message']:
+ webnotes.msgprint(res['message'])
else:
webnotes.conn.sql("update tabProfile set password=password(%s) where name=%s", (args['new_password'], args['user']))
- else: webnotes.msgprint('Settings Updated')
\ No newline at end of file
+ else: webnotes.msgprint('Settings Updated')
diff --git a/erpnext/home/page/profile_settings/profile_settings.js b/erpnext/home/page/profile_settings/profile_settings.js
index 425626b..bcb39b3 100644
--- a/erpnext/home/page/profile_settings/profile_settings.js
+++ b/erpnext/home/page/profile_settings/profile_settings.js
@@ -97,7 +97,12 @@
]);
var w = d.widgets['wrapper'];
- me.uploader = new Uploader(w, {cmd:'home.page.profile_settings.profile_settings.set_user_image'}, pscript.user_image_upload, 1)
+ me.uploader = new Uploader(w,
+ {
+ modulename:'home.page.profile_settings.profile_settings',
+ method: 'set_user_image'
+ },
+ pscript.user_image_upload, 1)
me.change_dialog = d;
}
me.change_dialog.show();
diff --git a/erpnext/home/page/profile_settings/profile_settings.py b/erpnext/home/page/profile_settings/profile_settings.py
index d1e091c..ffa0e7f 100644
--- a/erpnext/home/page/profile_settings/profile_settings.py
+++ b/erpnext/home/page/profile_settings/profile_settings.py
@@ -36,24 +36,10 @@
p.save()
webnotes.msgprint('Updated')
-def set_user_image(arg=None):
+def set_user_image(fid, fname):
"""
Set uploaded image as user image
"""
- from webnotes.utils.upload_handler import UploadHandler
-
- uh = UploadHandler()
- if not uh.file_name:
- # do nothing - no file found
- return
- else:
- # save the file
- from webnotes.utils.file_manager import FileAttachments
-
- fa = FileAttachments('Profile', webnotes.session['user'])
- fa.delete_all()
- fa.add(uh.file_name, uh.content)
- fa.save()
-
- uh.set_callback('window.parent.upload_callback("%s", "%s")' \
- % (webnotes.form_dict['uploader_id'], fa.get_fid(0)))
+ from webnotes.utils.file_manager import add_file_list, remove_all
+ remove_all('Profile', webnotes.session['user'])
+ add_file_list('Profile', webnotes.session['user'], fname, fid)
diff --git a/erpnext/hr/doctype/appraisal/appraisal.js b/erpnext/hr/doctype/appraisal/appraisal.js
index b2683d8..d040c53 100644
--- a/erpnext/hr/doctype/appraisal/appraisal.js
+++ b/erpnext/hr/doctype/appraisal/appraisal.js
@@ -1,13 +1,20 @@
cur_frm.add_fetch('employee', 'company', 'company');
cur_frm.cscript.onload = function(doc,cdt,cdn){
- if(!doc.status) set_multiple(dt,dn,{status:'Draft'});
- if(doc.employee) cur_frm.cscript.employee(doc,cdt,cdn);
- if(doc.amended_from && doc.__islocal) cur_frm.cscript.refresh_appraisal_details(doc, cdt, cdn);
+ if(!doc.status)
+ set_multiple(cdt,cdn,{status:'Draft'});
+ if(doc.amended_from && doc.__islocal)
+ cur_frm.cscript.refresh_appraisal_details(doc, cdt, cdn);
+}
+
+cur_frm.cscript.onload_post_render = function(doc,cdt,cdn){
+ if(doc.employee)
+ cur_frm.cscript.employee(doc,cdt,cdn);
}
cur_frm.cscript.refresh = function(doc,cdt,cdn){
- if(user == doc.kra_approver && doc.status == 'Submitted') unhide_field(['Update', 'Declare Completed', 'Calculate Total Score']);
+ if(user == doc.kra_approver && doc.status == 'Submitted')
+ unhide_field(['Update', 'Declare Completed', 'Calculate Total Score']);
else hide_field(['Update', 'Declare Completed', 'Calculate Total Score']);
if(!doc.docstatus) unhide_field('Fetch Template');
diff --git a/erpnext/hr/doctype/attendance/attendance.txt b/erpnext/hr/doctype/attendance/attendance.txt
index 4f189b1..9c795bb 100644
--- a/erpnext/hr/doctype/attendance/attendance.txt
+++ b/erpnext/hr/doctype/attendance/attendance.txt
@@ -5,15 +5,16 @@
{
'creation': '2010-09-23 10:26:03',
'docstatus': 0,
- 'modified': '2011-06-27 14:39:08',
+ 'modified': '2011-12-19 14:11:15',
'modified_by': 'Administrator',
'owner': 'ashwini@webnotestech.com'
},
# These values are common for all DocType
{
- '_last_update': '1308808105',
+ '_last_update': '1317365120',
'colour': 'White:FFF',
+ 'default_print_format': 'Standard',
'doctype': 'DocType',
'document_type': 'Master',
'module': 'HR',
@@ -22,7 +23,7 @@
'section_style': 'Simple',
'server_code_error': ' ',
'show_in_menu': 0,
- 'version': 74
+ 'version': 75
},
# These values are common for all DocField
@@ -72,7 +73,6 @@
{
'amend': 0,
'doctype': 'DocPerm',
- 'idx': 1,
'role': 'System Manager'
},
@@ -80,7 +80,6 @@
{
'doctype': 'DocField',
'fieldtype': 'Section Break',
- 'idx': 1,
'label': 'Attendance Details',
'oldfieldtype': 'Section Break',
'options': 'Simple'
@@ -91,7 +90,6 @@
'doctype': 'DocField',
'fieldname': 'naming_series',
'fieldtype': 'Select',
- 'idx': 2,
'label': 'Naming Series',
'no_copy': 1,
'oldfieldname': 'naming_series',
@@ -106,7 +104,6 @@
'doctype': 'DocField',
'fieldname': 'employee',
'fieldtype': 'Link',
- 'idx': 3,
'in_filter': 1,
'label': 'Employee',
'oldfieldname': 'employee',
@@ -122,7 +119,6 @@
'doctype': 'DocField',
'fieldname': 'employee_name',
'fieldtype': 'Data',
- 'idx': 4,
'label': 'Employee Name',
'oldfieldname': 'employee_name',
'oldfieldtype': 'Data'
@@ -134,27 +130,14 @@
'doctype': 'DocField',
'fieldname': 'status',
'fieldtype': 'Select',
- 'idx': 5,
'in_filter': 1,
'label': 'Status',
+ 'no_copy': 1,
'oldfieldname': 'status',
'oldfieldtype': 'Select',
'options': '\nPresent\nAbsent\nHalf Day',
'reqd': 1,
- 'search_index': 0
- },
-
- # DocField
- {
- 'doctype': 'DocField',
- 'fieldname': 'shifts',
- 'fieldtype': 'Select',
- 'idx': 6,
- 'label': 'Shifts',
- 'oldfieldname': 'shifts',
- 'oldfieldtype': 'Select',
- 'options': '\nDay\nNight',
- 'reqd': 0
+ 'search_index': 1
},
# DocField
@@ -164,7 +147,6 @@
'fieldname': 'leave_type',
'fieldtype': 'Link',
'hidden': 1,
- 'idx': 7,
'label': 'Leave Type',
'oldfieldname': 'leave_type',
'oldfieldtype': 'Link',
@@ -177,7 +159,6 @@
{
'doctype': 'DocField',
'fieldtype': 'Column Break',
- 'idx': 8,
'oldfieldtype': 'Column Break',
'width': '50%'
},
@@ -187,13 +168,12 @@
'doctype': 'DocField',
'fieldname': 'att_date',
'fieldtype': 'Date',
- 'idx': 9,
'in_filter': 1,
'label': 'Attendance Date',
'oldfieldname': 'att_date',
'oldfieldtype': 'Date',
'reqd': 1,
- 'search_index': 1
+ 'search_index': 0
},
# DocField
@@ -201,7 +181,6 @@
'doctype': 'DocField',
'fieldname': 'fiscal_year',
'fieldtype': 'Select',
- 'idx': 10,
'in_filter': 1,
'label': 'Fiscal Year',
'oldfieldname': 'fiscal_year',
@@ -215,7 +194,6 @@
'doctype': 'DocField',
'fieldname': 'company',
'fieldtype': 'Select',
- 'idx': 11,
'in_filter': 1,
'label': 'Company',
'oldfieldname': 'company',
diff --git a/erpnext/hr/doctype/leave_application/leave_application.py b/erpnext/hr/doctype/leave_application/leave_application.py
index 1756f2a..f688cae 100755
--- a/erpnext/hr/doctype/leave_application/leave_application.py
+++ b/erpnext/hr/doctype/leave_application/leave_application.py
@@ -17,108 +17,116 @@
# -----------------------------------------------------------------------------------------
class DocType:
- def __init__(self, doc, doclist):
- self.doc = doc
- self.doclist = doclist
+ def __init__(self, doc, doclist):
+ self.doc = doc
+ self.doclist = doclist
# ******************************************** client triggers ***********************************************
- # ------------------
- # get leave balance
- # ------------------
- def get_leave_balance(self):
- leave_all = sql("select total_leaves_allocated from `tabLeave Allocation` where employee = '%s' and leave_type = '%s' and fiscal_year = '%s' and docstatus = 1" % (self.doc.employee, self.doc.leave_type, self.doc.fiscal_year))
- leave_all = leave_all and flt(leave_all[0][0]) or 0
- leave_app = sql("select total_leave_days from `tabLeave Application` where employee = '%s' and leave_type = '%s' and fiscal_year = '%s' and docstatus = 1" % (self.doc.employee, self.doc.leave_type, self.doc.fiscal_year))
- leave_app = leave_app and flt(leave_app[0][0]) or 0
- ret = {'leave_balance':leave_all - leave_app}
- return ret
+ # ------------------
+ # get leave balance
+ # ------------------
+ def get_leave_balance(self):
+ leave_all = sql("select total_leaves_allocated from `tabLeave Allocation` where employee = '%s' and leave_type = '%s' and fiscal_year = '%s' and docstatus = 1" % (self.doc.employee, self.doc.leave_type, self.doc.fiscal_year))
+ leave_all = leave_all and flt(leave_all[0][0]) or 0
+ leave_app = sql("select total_leave_days from `tabLeave Application` where employee = '%s' and leave_type = '%s' and fiscal_year = '%s' and docstatus = 1" % (self.doc.employee, self.doc.leave_type, self.doc.fiscal_year))
+ leave_app = leave_app and flt(leave_app[0][0]) or 0
+ ret = {'leave_balance':leave_all - leave_app}
+ return ret
# ************************************************ utilities *************************************************
- # -------------------
- # get total holidays
- # -------------------
- def get_holidays(self):
- tot_hol = sql("select count(*) from `tabHoliday List Detail` h1, `tabHoliday List` h2, `tabEmployee` e1 where e1.name = '%s' and h1.parent = h2.name and e1.holiday_list = h2.name and h1.holiday_date between '%s' and '%s'"% (self.doc.employee, self.doc.from_date, self.doc.to_date))
- if not tot_hol:
- tot_hol = sql("select count(*) from `tabHoliday List Detail` h1, `tabHoliday List` h2 where h1.parent = h2.name and h1.holiday_date between '%s' and '%s' and ifnull(h2.is_default,0) = 1 and h2.fiscal_year = %s"% (self.doc.from_date, self.doc.to_date, self.doc.fiscal_year))
- return tot_hol and flt(tot_hol[0][0]) or 0
+ # -------------------
+ def get_holidays(self):
+ """
+ get total holidays
+ """
+ tot_hol = sql("select count(*) from `tabHoliday List Detail` h1, `tabHoliday List` h2, `tabEmployee` e1 where e1.name = '%s' and h1.parent = h2.name and e1.holiday_list = h2.name and h1.holiday_date between '%s' and '%s'"% (self.doc.employee, self.doc.from_date, self.doc.to_date))
+ if not tot_hol:
+ tot_hol = sql("select count(*) from `tabHoliday List Detail` h1, `tabHoliday List` h2 where h1.parent = h2.name and h1.holiday_date between '%s' and '%s' and ifnull(h2.is_default,0) = 1 and h2.fiscal_year = %s"% (self.doc.from_date, self.doc.to_date, self.doc.fiscal_year))
+ return tot_hol and flt(tot_hol[0][0]) or 0
-
- # ---------------------
- # get total leave days
- # ---------------------
- def get_total_leave_days(self):
- tot_days = date_diff(self.doc.to_date, self.doc.from_date) + 1
- holidays = self.get_holidays()
- ret = {'total_leave_days':flt(tot_days)-flt(holidays)}
- return ret
+
+ # ---------------------
+ # get total leave days
+ # ---------------------
+ def get_total_leave_days(self):
+ """
+ Calculates total leave days based on input and holidays
+ """
+ ret = {'total_leave_days' : 0.5}
+ if not self.doc.half_day:
+ tot_days = date_diff(self.doc.to_date, self.doc.from_date) + 1
+ holidays = self.get_holidays()
+ ret = {
+ 'total_leave_days' : flt(tot_days)-flt(holidays)
+ }
+ return ret
# ************************************************ validate *************************************************
- # -----------------
- # validate to date
- # -----------------
- def validate_to_date(self):
- if (getdate(self.doc.to_date) < getdate(self.doc.from_date)):
- msgprint("To date cannot be before from date")
- raise Exception
+ # -----------------
+ # validate to date
+ # -----------------
+ def validate_to_date(self):
+ if self.doc.from_date and self.doc.to_date and (getdate(self.doc.to_date) < getdate(self.doc.from_date)):
+ msgprint("To date cannot be before from date")
+ raise Exception
- # --------------------------------
- # check whether leave type is lwp
- # --------------------------------
- def is_lwp(self):
- lwp = sql("select is_lwp from `tabLeave Type` where name = %s", self.doc.leave_type)
- return lwp and cint(lwp[0][0]) or 0
+ # --------------------------------
+ # check whether leave type is lwp
+ # --------------------------------
+ def is_lwp(self):
+ lwp = sql("select is_lwp from `tabLeave Type` where name = %s", self.doc.leave_type)
+ return lwp and cint(lwp[0][0]) or 0
- # ------------------------
- # validate balance leaves
- # ------------------------
- def validate_balance_leaves(self):
- if not self.is_lwp():
- bal = self.get_leave_balance()
- tot_leaves = self.get_total_leave_days()
- bal, tot_leaves = bal, tot_leaves
- set(self.doc,'leave_balance',flt(bal['leave_balance']))
- set(self.doc,'total_leave_days',flt(tot_leaves['total_leave_days']))
- if flt(bal['leave_balance']) < flt(tot_leaves['total_leave_days']):
- msgprint("Employee : %s cannot apply for %s of more than %s days" % (self.doc.employee, self.doc.leave_type, flt(bal['leave_balance'])))
- raise Exception
+ # ------------------------
+ # validate balance leaves
+ # ------------------------
+ def validate_balance_leaves(self):
+ if self.doc.from_date and self.doc.to_date and not self.is_lwp():
+ bal = self.get_leave_balance()
+ tot_leaves = self.get_total_leave_days()
+ bal, tot_leaves = bal, tot_leaves
+ set(self.doc,'leave_balance',flt(bal['leave_balance']))
+ set(self.doc,'total_leave_days',flt(tot_leaves['total_leave_days']))
+ if flt(bal['leave_balance']) < flt(tot_leaves['total_leave_days']):
+ msgprint("Employee : %s cannot apply for %s of more than %s days" % (self.doc.employee, self.doc.leave_type, flt(bal['leave_balance'])))
+ raise Exception
- #
- # validate overlapping leaves
- #
- def validate_leave_overlap(self):
- for d in sql("""select name, leave_type, posting_date, from_date, to_date
- from `tabLeave Application`
- where
- (from_date <= %(to_date)s and to_date >= %(from_date)s)
- and employee = %(employee)s
- and docstatus = 1
- and name != %(name)s""", self.doc.fields, as_dict = 1):
+ #
+ # validate overlapping leaves
+ #
+ def validate_leave_overlap(self):
+ for d in sql("""select name, leave_type, posting_date, from_date, to_date
+ from `tabLeave Application`
+ where
+ (from_date <= %(to_date)s and to_date >= %(from_date)s)
+ and employee = %(employee)s
+ and docstatus = 1
+ and name != %(name)s""", self.doc.fields, as_dict = 1):
- msgprint("Employee : %s has already applied for %s between %s and %s on %s. Please refer Leave Application : %s" % (self.doc.employee, cstr(d['leave_type']), formatdate(d['from_date']), formatdate(d['to_date']), formatdate(d['posting_date']), d['name']), raise_exception = 1)
+ msgprint("Employee : %s has already applied for %s between %s and %s on %s. Please refer Leave Application : %s" % (self.doc.employee, cstr(d['leave_type']), formatdate(d['from_date']), formatdate(d['to_date']), formatdate(d['posting_date']), d['name']), raise_exception = 1)
- # ---------------------------------------------------------------------
- # validate max days for which leave can be applied for particular type
- # ---------------------------------------------------------------------
- def validate_max_days(self):
- max_days = sql("select max_days_allowed from `tabLeave Type` where name = '%s'" %(self.doc.leave_type))
- max_days = max_days and flt(max_days[0][0]) or 0
- if max_days and self.doc.total_leave_days > max_days:
- msgprint("Sorry ! You cannot apply for %s for more than %s days" % (self.doc.leave_type, max_days))
- raise Exception
+ # ---------------------------------------------------------------------
+ # validate max days for which leave can be applied for particular type
+ # ---------------------------------------------------------------------
+ def validate_max_days(self):
+ max_days = sql("select max_days_allowed from `tabLeave Type` where name = '%s'" %(self.doc.leave_type))
+ max_days = max_days and flt(max_days[0][0]) or 0
+ if max_days and self.doc.total_leave_days > max_days:
+ msgprint("Sorry ! You cannot apply for %s for more than %s days" % (self.doc.leave_type, max_days))
+ raise Exception
- # ---------
- # validate
- # ---------
- def validate(self):
- self.validate_to_date()
- self.validate_balance_leaves()
- self.validate_leave_overlap()
- self.validate_max_days()
+ # ---------
+ # validate
+ # ---------
+ def validate(self):
+ self.validate_to_date()
+ self.validate_balance_leaves()
+ self.validate_leave_overlap()
+ self.validate_max_days()
diff --git a/erpnext/hr/doctype/salary_manager/salary_manager.py b/erpnext/hr/doctype/salary_manager/salary_manager.py
index 5071056..badd69b 100644
--- a/erpnext/hr/doctype/salary_manager/salary_manager.py
+++ b/erpnext/hr/doctype/salary_manager/salary_manager.py
@@ -46,7 +46,7 @@
self.check_mandatory()
cond = ''
- for f in ['company', 'branch', 'department', 'designation', 'grade', 'employment_type']:
+ for f in ['company', 'branch', 'department', 'designation', 'grade']:
if self.doc.fields.get(f):
cond += " and t1." + f + " = '" + self.doc.fields.get(f) + "'"
diff --git a/erpnext/hr/doctype/salary_manager/salary_manager.txt b/erpnext/hr/doctype/salary_manager/salary_manager.txt
index 66a7282..c1ca4c6 100644
--- a/erpnext/hr/doctype/salary_manager/salary_manager.txt
+++ b/erpnext/hr/doctype/salary_manager/salary_manager.txt
@@ -5,18 +5,19 @@
{
'creation': '2011-08-11 16:40:04',
'docstatus': 0,
- 'modified': '2011-08-25 12:02:57',
+ 'modified': '2011-11-07 10:47:32',
'modified_by': 'Administrator',
'owner': 'Administrator'
},
# These values are common for all DocType
{
- '_last_update': '1314179318',
+ '_last_update': '1314253977',
'allow_copy': 1,
'allow_email': 1,
'allow_print': 1,
'colour': 'White:FFF',
+ 'default_print_format': 'Standard',
'doctype': 'DocType',
'document_type': 'Other',
'issingle': 1,
@@ -24,7 +25,7 @@
'name': '__common__',
'section_style': 'Simple',
'show_in_menu': 1,
- 'version': 29
+ 'version': 30
},
# These values are common for all DocField
@@ -59,21 +60,18 @@
# DocPerm
{
'doctype': 'DocPerm',
- 'idx': 1,
'role': 'System Manager'
},
# DocPerm
{
'doctype': 'DocPerm',
- 'idx': 2,
'role': 'HR User'
},
# DocPerm
{
'doctype': 'DocPerm',
- 'idx': 3,
'role': 'HR Manager'
},
@@ -82,7 +80,6 @@
'colour': 'White:FFF',
'doctype': 'DocField',
'fieldtype': 'HTML',
- 'idx': 1,
'label': 'Document Description',
'options': '<div class="field_description">You can generate multiple salary slips based on the selected criteria, submit and mail those to the employee directly from here</div>'
},
@@ -90,15 +87,13 @@
# DocField
{
'doctype': 'DocField',
- 'fieldtype': 'Section Break',
- 'idx': 2
+ 'fieldtype': 'Section Break'
},
# DocField
{
'doctype': 'DocField',
'fieldtype': 'Column Break',
- 'idx': 3,
'width': '50%'
},
@@ -107,7 +102,6 @@
'doctype': 'DocField',
'fieldname': 'company',
'fieldtype': 'Select',
- 'idx': 4,
'label': 'Company',
'options': 'link:Company',
'reqd': 1
@@ -118,7 +112,6 @@
'doctype': 'DocField',
'fieldname': 'branch',
'fieldtype': 'Link',
- 'idx': 5,
'label': 'Branch',
'options': 'Branch'
},
@@ -128,7 +121,6 @@
'doctype': 'DocField',
'fieldname': 'department',
'fieldtype': 'Link',
- 'idx': 6,
'label': 'Department',
'options': 'Department'
},
@@ -138,7 +130,6 @@
'doctype': 'DocField',
'fieldname': 'designation',
'fieldtype': 'Link',
- 'idx': 7,
'label': 'Designation',
'options': 'Designation'
},
@@ -147,7 +138,6 @@
{
'doctype': 'DocField',
'fieldtype': 'Column Break',
- 'idx': 8,
'width': '50%'
},
@@ -156,28 +146,16 @@
'doctype': 'DocField',
'fieldname': 'grade',
'fieldtype': 'Select',
- 'idx': 9,
'label': 'Grade',
'options': 'link:Grade'
},
# DocField
{
- 'doctype': 'DocField',
- 'fieldname': 'employment_type',
- 'fieldtype': 'Select',
- 'idx': 10,
- 'label': 'Employment Type',
- 'options': 'link:Employment Type'
- },
-
- # DocField
- {
'colour': 'White:FFF',
'doctype': 'DocField',
'fieldname': 'fiscal_year',
'fieldtype': 'Select',
- 'idx': 11,
'label': 'Fiscal Year',
'options': 'link:Fiscal Year',
'reqd': 1
@@ -189,7 +167,6 @@
'doctype': 'DocField',
'fieldname': 'month',
'fieldtype': 'Select',
- 'idx': 12,
'label': 'Month',
'options': '\n01\n02\n03\n04\n05\n06\n07\n08\n09\n10\n11\n12',
'reqd': 1
@@ -202,22 +179,19 @@
'doctype': 'DocField',
'fieldname': 'send_email',
'fieldtype': 'Check',
- 'idx': 13,
'label': 'Send Email'
},
# DocField
{
'doctype': 'DocField',
- 'fieldtype': 'Section Break',
- 'idx': 14
+ 'fieldtype': 'Section Break'
},
# DocField
{
'doctype': 'DocField',
'fieldtype': 'Column Break',
- 'idx': 15,
'width': '50%'
},
@@ -227,7 +201,6 @@
'description': 'Creates salary slip for above mentioned criteria.',
'doctype': 'DocField',
'fieldtype': 'Button',
- 'idx': 16,
'label': 'Create Salary Slip',
'trigger': 'Client'
},
@@ -236,7 +209,6 @@
{
'doctype': 'DocField',
'fieldtype': 'Column Break',
- 'idx': 17,
'width': '25%'
},
@@ -246,7 +218,6 @@
'description': 'Submit all salary slips for the above selected criteria',
'doctype': 'DocField',
'fieldtype': 'Button',
- 'idx': 18,
'label': 'Submit Salary Slip',
'trigger': 'Client'
},
@@ -255,7 +226,6 @@
{
'doctype': 'DocField',
'fieldtype': 'Column Break',
- 'idx': 19,
'width': '25%'
},
@@ -265,7 +235,6 @@
'description': 'Create Bank Voucher for the total salary paid for the above selected criteria',
'doctype': 'DocField',
'fieldtype': 'Button',
- 'idx': 20,
'label': 'Make Bank Voucher',
'trigger': 'Client'
},
@@ -273,15 +242,13 @@
# DocField
{
'doctype': 'DocField',
- 'fieldtype': 'Section Break',
- 'idx': 21
+ 'fieldtype': 'Section Break'
},
# DocField
{
'doctype': 'DocField',
'fieldtype': 'HTML',
- 'idx': 22,
'label': 'Activity Log'
}
]
\ No newline at end of file
diff --git a/erpnext/hr/search_criteria/employeewise_balance_leave_report/employeewise_balance_leave_report.js b/erpnext/hr/search_criteria/employeewise_balance_leave_report/employeewise_balance_leave_report.js
index 2439ffa..24d1774 100644
--- a/erpnext/hr/search_criteria/employeewise_balance_leave_report/employeewise_balance_leave_report.js
+++ b/erpnext/hr/search_criteria/employeewise_balance_leave_report/employeewise_balance_leave_report.js
@@ -1,3 +1,24 @@
this.mytabs.items['Select Columns'].hide();
-this.mytabs.tabs['More Filters'].hide();
\ No newline at end of file
+this.mytabs.tabs['More Filters'].hide();
+
+report.customize_filters = function() {
+ this.add_filter({
+ fieldname:'fiscal_year',
+ label:'Fiscal Year',
+ fieldtype:'Link',
+ ignore : 1,
+ options: 'Fiscal Year',
+ parent:'Leave Allocation',
+ in_first_page:1
+ });
+ this.add_filter({
+ fieldname:'employee_name',
+ label:'Employee Name',
+ fieldtype:'Data',
+ ignore : 1,
+ options: '',
+ parent:'Leave Allocation',
+ in_first_page:1
+ });
+}
\ No newline at end of file
diff --git a/erpnext/hr/search_criteria/employeewise_balance_leave_report/employeewise_balance_leave_report.py b/erpnext/hr/search_criteria/employeewise_balance_leave_report/employeewise_balance_leave_report.py
index c258d15..8c0c747 100644
--- a/erpnext/hr/search_criteria/employeewise_balance_leave_report/employeewise_balance_leave_report.py
+++ b/erpnext/hr/search_criteria/employeewise_balance_leave_report/employeewise_balance_leave_report.py
@@ -1,20 +1,55 @@
-leave_types = sql("select name from `tabLeave Type` where docstatus != 2 and name not in ('Compensatory Off','Leave Without Pay')")
-msgprint(leave_types)
+leave_types = sql("""
+ SELECT name FROM `tabLeave Type`
+ WHERE
+ docstatus!=2 AND
+ name NOT IN ('Compensatory Off', 'Leave Without Pay')""")
col=[]
+col.append(['Employee ID', 'Data', '150px', ''])
+col.append(['Employee Name', 'Data', '150px', ''])
+col.append(['Fiscal Year', 'Data', '150px', ''])
for e in leave_types:
- l = (len(e)*9)
- if l < 150 : col_width = '150px'
- else: col_width = '%spx'%(l)
-
- col.append([e,'Currency',col_width,''])
-
+ l = (len(e[0])*9)
+ if l < 150 : col_width = '150px'
+ else: col_width = '%spx'%(l)
+ col.append([e[0],'Currency',col_width,''])
col.append(['Total Balance','Currency','150px',''])
for c in col:
- colnames.append(c[0])
- coltypes.append(c[1])
- colwidths.append(c[2])
- coloptions.append(c[3])
- col_idx[c[0]] = len(colnames)
+ colnames.append(c[0])
+ coltypes.append(c[1])
+ colwidths.append(c[2])
+ coloptions.append(c[3])
+ col_idx[c[0]] = len(colnames)
+
+data = res
+res = []
+
+try:
+ for d in data:
+ exists = 0
+ ind = None
+
+ # Check if the employee record exists in list 'res'
+ for r in res:
+ if r[0] == d[0] and r[1] == d[1]:
+ exists = 1
+ ind = res.index(r)
+ break
+ if d[3] in colnames:
+ # If exists, then append the leave type data
+ if exists:
+ res[ind][colnames.index(d[3])] = d[4] - d[5]
+ res[ind][len(colnames)-1] = sum(res[ind][3:-1])
+ # Else create a new row in res
+ else:
+ new_row = [0.0 for c in colnames]
+ new_row[0] = d[0]
+ new_row[1] = d[1]
+ new_row[2] = d[2]
+ new_row[colnames.index(d[3])] = d[4] - d[5]
+ new_row[len(colnames)-1] = sum(new_row[3:-1])
+ res.append(new_row)
+except Exception, e:
+ msgprint(e)
\ No newline at end of file
diff --git a/erpnext/hr/search_criteria/employeewise_balance_leave_report/employeewise_balance_leave_report.sql b/erpnext/hr/search_criteria/employeewise_balance_leave_report/employeewise_balance_leave_report.sql
new file mode 100644
index 0000000..50811c0
--- /dev/null
+++ b/erpnext/hr/search_criteria/employeewise_balance_leave_report/employeewise_balance_leave_report.sql
@@ -0,0 +1,26 @@
+SELECT
+ leave_alloc.employee AS 'employee',
+ leave_alloc.employee_name AS 'employee_name',
+ leave_alloc.fiscal_year AS 'fiscal_year',
+ leave_alloc.leave_type AS 'leave_type',
+ leave_alloc.total_leaves_allocated AS 'total_leaves_allocated',
+ SUM(leave_app.total_leave_days) AS 'total_leaves_applied'
+FROM
+ `tabLeave Allocation` AS leave_alloc,
+ `tabLeave Application` AS leave_app
+WHERE
+ leave_alloc.employee=leave_app.employee AND
+ leave_alloc.leave_type=leave_app.leave_type AND
+ leave_alloc.fiscal_year=leave_app.fiscal_year AND
+ leave_alloc.docstatus=1 AND
+ leave_app.docstatus=1 AND
+ leave_alloc.fiscal_year LIKE '%(fiscal_year)s%%' AND
+ leave_alloc.employee_name LIKE '%(employee_name)s%%'
+GROUP BY
+ employee,
+ fiscal_year,
+ leave_type
+ORDER BY
+ employee,
+ fiscal_year,
+ leave_type
\ No newline at end of file
diff --git a/erpnext/hr/search_criteria/employeewise_balance_leave_report/employeewise_balance_leave_report.txt b/erpnext/hr/search_criteria/employeewise_balance_leave_report/employeewise_balance_leave_report.txt
index 48ef3bf..7a7f049 100644
--- a/erpnext/hr/search_criteria/employeewise_balance_leave_report/employeewise_balance_leave_report.txt
+++ b/erpnext/hr/search_criteria/employeewise_balance_leave_report/employeewise_balance_leave_report.txt
@@ -3,9 +3,9 @@
# These values are common in all dictionaries
{
- 'creation': '2010-12-14 10:23:25',
+ 'creation': '2010-12-14 10:33:09',
'docstatus': 0,
- 'modified': '2010-12-01 10:39:56',
+ 'modified': '2011-10-31 15:42:36',
'modified_by': 'Administrator',
'owner': 'harshada@webnotestech.com'
},
@@ -13,7 +13,8 @@
# These values are common for all Search Criteria
{
'columns': 'Employee\x01ID',
- 'criteria_name': 'Employeewise Balance Leave Report',
+ 'criteria_name': 'Employee Leave Balance Report',
+ 'description': 'Employeewise Balance Leave Report',
'doc_type': 'Employee',
'doctype': 'Search Criteria',
'filters': "{'Employee\x01Saved':1,'Employee\x01Submitted':1,'Employee\x01Gender':'','Employee\x01Month of Birth':'','Employee\x01Status':'Active'}",
diff --git a/erpnext/knowledge_base/page/kb_common/kb_common.js b/erpnext/knowledge_base/page/kb_common/kb_common.js
index 3e17b6f..433ea2e 100644
--- a/erpnext/knowledge_base/page/kb_common/kb_common.js
+++ b/erpnext/knowledge_base/page/kb_common/kb_common.js
@@ -71,8 +71,8 @@
// if user has not already voted
if(user!='Guest' && !in_list(voted, user) && user!=owner) {
- this.vote_up = $a(this.wrapper, 'img', 'images/ui/vote_up.gif', {margin:'0px 0px -2px 7px', cursor: 'pointer'});
- this.vote_down = $a(this.wrapper, 'img', 'images/ui/vote_down.gif', {margin:'0px 0px -3px 0px', cursor: 'pointer'});
+ this.vote_up = $a(this.wrapper, 'img', 'lib/images/ui/vote_up.gif', {margin:'0px 0px -2px 7px', cursor: 'pointer'});
+ this.vote_down = $a(this.wrapper, 'img', 'lib/images/ui/vote_down.gif', {margin:'0px 0px -3px 0px', cursor: 'pointer'});
this.vote_up.title = 'Vote Up'; this.vote_down.title = 'Vote Down';
diff --git a/erpnext/knowledge_base/page/questions/questions.js b/erpnext/knowledge_base/page/questions/questions.js
index f268d0b..a3dff13 100644
--- a/erpnext/knowledge_base/page/questions/questions.js
+++ b/erpnext/knowledge_base/page/questions/questions.js
@@ -35,8 +35,6 @@
this.make_search_bar = function() {
this.search = $a($a(w,'div','kb-search-wrapper'), 'textarea');
-
- $(this.search).add_default_text('Enter keywords or a new Question');
var div = $a(w,'div','kb-btn-wrapper');
$btn(div, 'Search', function() { me.run() }, {fontSize:'14px'});
diff --git a/erpnext/patches/Discount_purchase_cycle.py b/erpnext/patches/Discount_purchase_cycle.py
new file mode 100755
index 0000000..34fd498
--- /dev/null
+++ b/erpnext/patches/Discount_purchase_cycle.py
@@ -0,0 +1,14 @@
+def execute():
+ import webnotes
+ from webnotes.modules.module_manager import reload_doc
+
+ reload_doc('accounts', 'doctype', 'pv_detail')
+ reload_doc('buying', 'doctype', 'po_detail')
+ reload_doc('stock', 'doctype', 'purchase_receipt_detail')
+ if webnotes.conn.sql("select name from `tabDocField` where parent = 'PO Detail' and fieldname = 'discount'"):
+ webnotes.conn.sql("update `tabPO Detail` set discount_rate=discount")
+
+ # Features setup
+ reload_doc('setup', 'doctype', 'features_setup')
+ from webnotes.model.code import get_obj
+ get_obj('Features Setup').validate()
diff --git a/erpnext/patches/accounts_default_form.py b/erpnext/patches/accounts_default_form.py
new file mode 100644
index 0000000..dab6923
--- /dev/null
+++ b/erpnext/patches/accounts_default_form.py
@@ -0,0 +1,6 @@
+def execute():
+ import webnotes
+ from webnotes.modules.module_manager import reload_doc
+ reload_doc('setup', 'doctype', 'company')
+ reload_doc('setup', 'doctype', 'manage_account')
+
diff --git a/erpnext/patches/auto_indent.py b/erpnext/patches/auto_indent.py
new file mode 100644
index 0000000..a8488e7
--- /dev/null
+++ b/erpnext/patches/auto_indent.py
@@ -0,0 +1,8 @@
+def execute():
+ import webnotes
+ from webnotes.modules.module_manager import reload_doc
+ reload_doc('setup', 'doctype', 'manage_account')
+ reload_doc('stock', 'doctype', 'item')
+ webnotes.conn.sql("delete from `tabDocField` where fieldname='minimum_inventory_level' and parent='item'")
+ webnotes.conn.sql("update `tabItem` set re_order_level = minimum_inventory_level where ifnull(re_order_level,0) = 0 ")
+
diff --git a/erpnext/patches/c_form_patch.py b/erpnext/patches/c_form_patch.py
new file mode 100644
index 0000000..0f8fa22
--- /dev/null
+++ b/erpnext/patches/c_form_patch.py
@@ -0,0 +1,12 @@
+def execute():
+ import webnotes
+ from webnotes.modules.module_manager import reload_doc
+
+ reload_doc('accounts', 'doctype', 'receivable_voucher')
+ reload_doc('accounts', 'doctype', 'c_form')
+ reload_doc('accounts', 'doctype', 'c_form_invoice_detail')
+ reload_doc('accounts', 'Module Def', 'Accounts')
+
+ sql = webnotes.conn.sql
+ sql("update `tabReceivable Voucher` set c_form_applicable = 'Yes' where c_form_applicable = 'Y'")
+ sql("update `tabReceivable Voucher` set c_form_applicable = 'No' where c_form_applicable = 'N'")
diff --git a/erpnext/patches/delivery_billing_status_patch.py b/erpnext/patches/delivery_billing_status_patch.py
index 1fcd8bf..7de04b7 100644
--- a/erpnext/patches/delivery_billing_status_patch.py
+++ b/erpnext/patches/delivery_billing_status_patch.py
@@ -49,7 +49,7 @@
sql("""update `tabDelivery Note` set billing_status = if(ifnull(per_billed,0) < 0.001, 'Not Billed',
if(per_billed >= 99.99, 'Fully Billed', 'Partly Billed'))""")
-def run_patch():
+def execute():
update_delivered_billed_qty()
update_percent()
update_status()
diff --git a/erpnext/patches/deploy_email_digest.py b/erpnext/patches/deploy_email_digest.py
new file mode 100644
index 0000000..02f842c
--- /dev/null
+++ b/erpnext/patches/deploy_email_digest.py
@@ -0,0 +1,96 @@
+import webnotes
+
+def execute():
+ """
+ * Reload email_digest doctype
+ * Create default email digest
+ """
+ from webnotes.modules.module_manager import reload_doc
+
+ # Minor fix in print_format doctype
+ #reload_doc('core', 'doctype', 'print_format')
+
+ #reload_doc('setup', 'doctype', 'email_digest')
+
+ #global create_default_email_digest
+ #create_default_email_digest()
+
+ global enabled_default_email_digest
+ enabled_default_email_digest()
+
+
+def enabled_default_email_digest():
+ """
+ Enables the created email digest
+ """
+ from webnotes.model.doc import Document
+ from webnotes.model.code import get_obj
+ companies_list = webnotes.conn.sql("SELECT company_name FROM `tabCompany`", as_list=1)
+ for company in companies_list:
+ if company and company[0]:
+ edigest = Document('Email Digest', 'Default Weekly Digest - ' + company[0])
+ if edigest:
+ edigest.enabled = 1
+ edigest.save()
+ ed_obj = get_obj(doc=edigest)
+ ed_obj.on_update()
+
+
+
+def create_default_email_digest():
+ """
+ * Weekly Digest
+ * For all companies
+ * Recipients: System Managers
+ * Full content
+ * Disabled by default
+ """
+ from webnotes.model.doc import Document
+ companies_list = webnotes.conn.sql("SELECT company_name FROM `tabCompany`", as_list=1)
+ global get_system_managers
+ system_managers = get_system_managers()
+ for company in companies_list:
+ if company and company[0]:
+ edigest = Document('Email Digest')
+ edigest.name = "Default Weekly Digest - " + company[0]
+ edigest.company = company[0]
+ edigest.frequency = 'Weekly'
+ edigest.recipient_list = system_managers
+ edigest.new_leads = 1
+ edigest.new_enquiries = 1
+ edigest.new_quotations = 1
+ edigest.new_sales_orders = 1
+ edigest.new_purchase_orders = 1
+ edigest.new_transactions = 1
+ edigest.payables = 1
+ edigest.payments = 1
+ edigest.expenses_booked = 1
+ edigest.invoiced_amount = 1
+ edigest.collections = 1
+ edigest.income = 1
+ edigest.bank_balance = 1
+ exists = webnotes.conn.sql("""\
+ SELECT name FROM `tabEmail Digest`
+ WHERE name = %s""", edigest.name)
+ if (exists and exists[0]) and exists[0][0]:
+ continue
+ else:
+ edigest.save(1)
+
+
+def get_system_managers():
+ """
+ Returns a string of system managers' email addresses separated by \n
+ """
+ system_managers_list = webnotes.conn.sql("""\
+ SELECT DISTINCT p.name
+ FROM tabUserRole ur, tabProfile p
+ WHERE
+ ur.parent = p.name AND
+ ur.role='System Manager' AND
+ p.docstatus<2 AND
+ p.enabled=1 AND
+ p.name not in ('Administrator', 'Guest')""", as_list=1)
+
+ return "\n".join([sysman[0] for sysman in system_managers_list])
+
diff --git a/erpnext/patches/edigest_enable_income_year_to_date.py b/erpnext/patches/edigest_enable_income_year_to_date.py
new file mode 100644
index 0000000..380de83
--- /dev/null
+++ b/erpnext/patches/edigest_enable_income_year_to_date.py
@@ -0,0 +1,11 @@
+import webnotes
+from webnotes.model.doc import Document
+
+def execute():
+ companies_list = webnotes.conn.sql("SELECT company_name FROM `tabCompany`", as_list=1)
+ for company in companies_list:
+ if company and company[0]:
+ edigest = Document('Email Digest', "Default Weekly Digest - " + company[0])
+ if edigest:
+ edigest.income_year_to_date = 1
+ edigest.save()
diff --git a/erpnext/patches/employeewise_balance_leave_report.py b/erpnext/patches/employeewise_balance_leave_report.py
new file mode 100644
index 0000000..59c5940
--- /dev/null
+++ b/erpnext/patches/employeewise_balance_leave_report.py
@@ -0,0 +1,14 @@
+"""
+ This patch changes criteria name
+ of search criteria "employeewise_balance_leave_report"
+ from "Employeewise Balance Leave Report"
+ to "Employee Leave Balance Report"
+"""
+def execute():
+ from webnotes.model.doc import Document
+ from webnotes.modules.module_manager import reload_doc
+ reload_doc('hr', 'search_criteria', 'employeewise_balance_leave_report')
+ d = Document('Search Criteria', 'employeewise_balance_leave_report')
+ d.criteria_name = 'Employee Leave Balance Report'
+ d.description = 'Employeewise Balance Leave Report'
+ d.save()
diff --git a/erpnext/patches/index_patch.py b/erpnext/patches/index_patch.py
index 3ef8ec3..788b68d 100644
--- a/erpnext/patches/index_patch.py
+++ b/erpnext/patches/index_patch.py
@@ -293,3 +293,6 @@
sql("commit")
except:
continue
+
+def execute():
+ create_proper_index()
diff --git a/erpnext/patches/install_print_formats.py b/erpnext/patches/install_print_formats.py
new file mode 100644
index 0000000..40a008e
--- /dev/null
+++ b/erpnext/patches/install_print_formats.py
@@ -0,0 +1,108 @@
+import os, sys
+import webnotes
+
+path_to_file = os.sep.join(os.path.abspath(__file__).split(os.sep)[:-1] + ['print_formats'])
+
+def prepare_pf_dict(args_list):
+ """
+
+ """
+ pf_list = []
+ for a in args_list:
+ for pf_type in ['Classic', 'Modern', 'Spartan']:
+ pf = {}
+ pf['name'] = " ".join([a['name'], pf_type])
+ pf['file'] = os.sep.join([path_to_file, "".join(pf['name'].split(" ")) + ".html"])
+ pf['module'] = a['module']
+ pf['doc_type'] = a['doc_type']
+ pf['standard'] = 'Yes'
+ pf_list += [pf]
+ return pf_list
+
+
+pf_to_install = prepare_pf_dict([
+ {
+ 'name' : 'Sales Invoice',
+ 'doc_type' : 'Receivable Voucher',
+ 'module' : 'Accounts'
+ },
+ {
+ 'name' : 'Sales Order',
+ 'doc_type' : 'Sales Order',
+ 'module' : 'Selling'
+ },
+ {
+ 'name' : 'Quotation',
+ 'doc_type' : 'Quotation',
+ 'module' : 'Selling'
+ },
+ {
+ 'name' : 'Delivery Note',
+ 'doc_type' : 'Delivery Note',
+ 'module' : 'Stock'
+ },
+ {
+ 'name' : 'Purchase Order',
+ 'doc_type' : 'Purchase Order',
+ 'module' : 'Buying'
+ }
+])
+
+def execute():
+ """
+ Install print formats
+ """
+ from webnotes.modules.module_manager import reload_doc
+ reload_doc('core', 'doctype', 'print_format')
+
+ #copy_doctype_to_pfs()
+ global pf_to_install
+ for pf in pf_to_install:
+ # install_print_format(pf)
+ # print "Installed PF: " + pf['name']
+ reload_doc(pf['module'], 'Print Format', pf['name'])
+
+
+def copy_doctype_to_pfs():
+ """
+ Copy doctype to existing print formats
+ """
+ pf_dt_list = webnotes.conn.sql("""
+ SELECT format, parent
+ FROM `tabDocFormat`""", as_list=1)
+
+ from webnotes.model.doc import Document
+
+ for pf, dt in pf_dt_list:
+ try:
+ d = Document('Print Format', pf)
+ d.doc_type = dt
+ d.save()
+ except Exception, e:
+ print e.args
+ pass
+
+
+def install_print_format(args):
+ """
+ Installs print format
+ args is a dict consisting of following keys:
+ * name
+ * module
+ * doctype
+ * standard = "Yes"/"No"
+ * file
+ """
+ from webnotes.model.doc import Document
+ d = Document('Print Format')
+ d.name = args['name']
+ f = open(args['file'])
+ d.html = f.read()
+ f.close()
+ d.module = args['module']
+ d.doc_type = args['doc_type']
+ d.standard = args['standard']
+ d.save(1)
+ from webnotes.model.code import get_obj
+ obj = get_obj('Print Format', args['name'])
+ obj.on_update()
diff --git a/erpnext/patches/lcw_patch.py b/erpnext/patches/lcw_patch.py
new file mode 100644
index 0000000..66afafc
--- /dev/null
+++ b/erpnext/patches/lcw_patch.py
@@ -0,0 +1,9 @@
+def execute():
+ import webnotes
+ from webnotes.modules.module_manager import reload_doc
+
+
+ reload_doc('stock', 'doctype', 'landed_cost_wizard')
+ reload_doc('stock', 'doctype', 'lc_pr_detail')
+
+ webnotes.conn.sql("delete from `tabDocField` where parent ='LC PR Detail' and fieldname in ('purchase_receipt_no', 'include_in_landed_cost')")
diff --git a/erpnext/patches/p1.py b/erpnext/patches/p1.py
new file mode 100644
index 0000000..e2304c7
--- /dev/null
+++ b/erpnext/patches/p1.py
@@ -0,0 +1,4 @@
+def execute():
+ import webnotes
+ if not webnotes.conn.sql("select name from tabDocFormat where parent = 'Receivable Voucher' and format != 'POS Invoice'"):
+ webnotes.conn.sql("update tabDocType set default_print_format = 'Standard' where name = 'Receivable Voucher'")
diff --git a/erpnext/patches/packing_slip.py b/erpnext/patches/packing_slip.py
new file mode 100644
index 0000000..9285e8a
--- /dev/null
+++ b/erpnext/patches/packing_slip.py
@@ -0,0 +1,8 @@
+def execute():
+ import webnotes
+ from webnotes.modules.module_manager import reload_doc
+ reload_doc('stock', 'doctype', 'delivery_note_detail')
+ reload_doc('stock', 'Print Format', 'Delivery Note Packing List Wise')
+
+ webnotes.conn.sql("delete from `tabDocField` where fieldname in ('packed_by', 'packing_checked_by', 'pack_size') and parent = 'Delivery Note'")
+
diff --git a/erpnext/patches/patch.py b/erpnext/patches/patch.py
index 456e936..2563915 100644
--- a/erpnext/patches/patch.py
+++ b/erpnext/patches/patch.py
@@ -1,11 +1,12 @@
# REMEMBER to update this
# ========================
-last_patch = 385
+last_patch = 388
#-------------------------------------------
def execute(patch_no):
+ return
import webnotes
from webnotes.modules.module_manager import reload_doc
@@ -344,8 +345,7 @@
bin = sql("select name from tabBin")
for b in bin:
bobj = get_obj('Bin',b[0])
- prev_sle = bobj.get_prev_sle(posting_date = '2011-09-01', posting_time = '01:00')
- bobj.update_item_valuation(posting_date = '2011-09-01', posting_time = '01:00', prev_sle = prev_sle)
+ bobj.update_entries_after(posting_date = '2011-09-01', posting_time = '01:00')
elif patch_no == 368:
from webnotes.utils import nestedset
t = [
@@ -456,3 +456,9 @@
elif patch_no == 385:
# Patch for adding packing related columns (packed by, checked by, shipping mark etc)
reload_doc('stock','doctype','delivery_note')
+ elif patch_no == 386:
+ sql("update `tabDocField` set allow_on_submit = 1 where fieldname = 'page_break'")
+ elif patch_no == 387:
+ sql("update `tabDocField` set allow_on_submit = 1 where fieldname in ('indent_details', 'po_details', 'purchase_receipt_details', 'entries', 'sales_order_details', 'delivery_note_details', 'quotation_details') and fieldtype = 'Table'")
+ elif patch_no == 388:
+ pass
diff --git a/erpnext/patches/patch_list.py b/erpnext/patches/patch_list.py
new file mode 100644
index 0000000..80f1cc1
--- /dev/null
+++ b/erpnext/patches/patch_list.py
@@ -0,0 +1,11 @@
+patch_list = [
+ {
+ 'patch_file': 'reload_print_format',
+ 'description': 'Reload doctype print format'
+ },
+ {
+ 'patch_module': 'patches',
+ 'patch_file': 'reload_project_task',
+ 'description': 'Reload doctype task of project module'
+ }
+]
diff --git a/erpnext/patches/price_list_patch.py b/erpnext/patches/price_list_patch.py
new file mode 100644
index 0000000..0f485b3
--- /dev/null
+++ b/erpnext/patches/price_list_patch.py
@@ -0,0 +1,13 @@
+def execute():
+ import webnotes
+ from webnotes.modules.module_manager import reload_doc
+
+ reload_doc('accounts', 'doctype', 'receivable_voucher')
+ reload_doc('stock', 'doctype', 'delivery_note')
+ reload_doc('selling', 'doctype', 'sales_order')
+ reload_doc('selling', 'doctype', 'quotation')
+ reload_doc('setup', 'doctype', 'manage_account')
+
+
+ for d in ['Receivable Voucher', 'Delivery Note', 'Sales Order', 'Quotation']:
+ webnotes.conn.sql("update `tab%s` set price_list_currency = currency, plc_conversion_rate = conversion_rate" % d)
diff --git a/erpnext/patches/print_formats/DeliveryNoteClassic.html b/erpnext/patches/print_formats/DeliveryNoteClassic.html
new file mode 100644
index 0000000..64475d6
--- /dev/null
+++ b/erpnext/patches/print_formats/DeliveryNoteClassic.html
@@ -0,0 +1,288 @@
+<!--
+ Sample Print Format for ERPNext
+ Please use at your own discretion
+ For suggestions and contributions:
+ https://github.com/webnotes/erpnext-print-templates
+
+ Freely usable under MIT license
+-->
+
+<!-- Style Settings -->
+<style>
+ /*
+ common style for whole page
+ This should include:
+ + page size related settings
+ + font family settings
+ + line spacing settings
+ */
+ @media screen {
+ body {
+ width: 8.3in;
+ }
+ }
+
+ html, body, div, span, td {
+ font-family: "Georgia", serif;
+ font-size: 12px;
+ }
+
+ body {
+ padding: 10px;
+ margin: auto;
+ font-size: 12px;
+ line-height: 150%;
+ }
+
+ .common {
+ font-family: "Georgia", serif !important;
+ font-size: 12px;
+ padding: 10px 0px;
+ }
+
+ table {
+ border-collapse: collapse;
+ width: 100%;
+ vertical-align: top;
+ }
+
+ table td {
+ padding: 2px 0px;
+ }
+
+ table h1, h2, h3, h4, h5, h6 {
+ padding: 0px;
+ margin: 0px;
+ }
+
+ table.header-table td {
+ vertical-align: top;
+ }
+
+ table.header-table thead {
+ border-bottom: 1px solid black;
+ }
+
+ table.header-table h3 {
+ color: gray;
+ }
+
+ table.header-table thead td {
+ padding: 5px 0px;
+ }
+
+ div.page-body table td:nth-child(6),
+ div.page-body table td:nth-child(7) {
+ text-align: right;
+ }
+
+ table.footer-table td {
+ vertical-align: top;
+ }
+
+ table.footer-table td table td:nth-child(2),
+ table.footer-table td table td:nth-child(3) {
+ text-align: right;
+ }
+</style>
+
+
+<!-- Javascript -->
+<script>
+ si_std = {
+ print_item_table: function() {
+ var table = print_table(
+ 'Delivery Note',
+ doc.name,
+ 'delivery_note_details',
+ 'Delivery Note Detail',
+ [// Here specify the table columns to be displayed
+ 'SR', 'item_code', 'item_name', 'description', 'qty', 'stock_uom',
+ 'basic_rate', 'amount'
+ ],
+ [// Here specify the labels of column headings
+ 'Sr', 'Item Code', 'Item Name', 'Description', 'Qty',
+ 'UoM', 'Basic Rate', 'Amount'
+ ],
+ [// Here specify the column widths
+ '3%', '10%', '15%', '32%', '5%',
+ '5%', '15%', '15%'
+ ],
+ null,
+ null,
+ {
+ 'description' : function(data_row) {
+ var to_append = ''
+ if(data_row.adj_rate){
+ to_append = '<div style="padding-left: 15px;"><i>Discount: ' +
+ data_row.adj_rate + '%</i></div>';
+ if(data_row.description.indexOf(to_append)==-1) {
+ data_row.description = data_row.description + to_append;
+ }
+ }
+
+ if(data_row.serial_no) {
+ to_append = '<div style="padding-left: 15px;"><i>Serial No.:' +
+ ((data_row.serial_no.indexOf('\n')>-1)?'<br />':' ') +
+ data_row.serial_no + '</i></div>';
+ if(data_row.description.indexOf(to_append)==-1) {
+ data_row.description = data_row.description + to_append;
+ }
+ }
+
+ return data_row.description;
+ }
+ }
+ );
+
+ // This code takes care of page breaks
+ if(table.appendChild) {
+ out = table.innerHTML;
+ } else {
+ out = '';
+ for(var i=0; i < (table.length-1); i++) {
+ out += table[i].innerHTML +
+ '<div style = "page-break-after: always;" \
+ class = "page_break"></div>\
+ <div class="page-settings"></div>';
+ }
+ out += table[table.length-1].innerHTML;
+ }
+ return out;
+ },
+
+
+ print_other_charges: function(parent) {
+ var oc = getchildren('RV Tax Detail', doc.name, 'other_charges');
+ var rows = '<table width=100%>\n';
+ for(var i=0; i<oc.length; i++) {
+ rows +=
+ '<tr>\n' +
+ '\t<td>' + oc[i].description + '</td>\n' +
+ '\t<td></td>\n' +
+ '\t<td width=38%>' + fmt_money(oc[i].tax_amount) + '</td>\n' +
+ '</tr>\n';
+ }
+ return rows + '</table>\n';
+ }
+ };
+</script>
+
+
+<!-- Page Layout Settings -->
+<div class='common page-header'>
+ <!--
+ Page Header will contain
+ + table 1
+ + table 1a
+ - Name
+ - Address
+ - Contact
+ - Mobile No
+ + table 1b
+ - Voucher Date
+ - Due Date
+ -->
+ <table class='header-table' cellspacing=0>
+ <thead>
+ <tr><td><script>'<h1>' + (doc.select_print_heading || 'Delivery Note') + '</h1>'</script></td></tr>
+ <tr><td><h3><script>cur_frm.docname</script></h3></td></tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td width=60%><table width=100% cellspacing=0><tbody>
+ <tr>
+ <td width=22%><b>Name</b></td>
+ <td><script>doc.customer_name</script></td>
+ </tr>
+ <tr>
+ <td><b>Address</b></td>
+ <td><script>replace_newlines(doc.address_display)</script></td>
+ </tr>
+ <tr>
+ <td><b>Contact</b></td>
+ <td><script>doc.contact_display</script></td>
+ </tr>
+ </tbody></table></td>
+ <td><table width=100% cellspacing=0><tbody>
+ <tr>
+ <td width=63%><b>Delivery Note Date</b></td>
+ <td><script>date.str_to_user(doc.transaction_date)</script></td>
+ <tr>
+ <tr>
+ <td><b>Sales Order No.</b></td>
+ <td>
+ <script>doc.sales_order_no</script><br />
+ <i>(<script>date.str_to_user(doc.posting_date)</script>)</i>
+ </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
+ -->
+ <script>si_std.print_item_table()</script>
+</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 & Other Information:</b><br />
+ <script>doc.terms</script>
+ </td>
+ <td>
+ <table cellspacing=0 width=100%><tbody>
+ <tr>
+ <td>Net Total</td>
+ <td></td>
+ <td width=38%><script>
+ fmt_money(doc.net_total)
+ </script></td>
+ </tr>
+ <tr><td colspan=3><script>si_std.print_other_charges()</script></td></tr>
+ <tr>
+ <td>Grand Total</td>
+ <td></td>
+ <td><script>
+ fmt_money(doc.grand_total_export)
+ </script></td>
+ </tr>
+ <tr style='font-weight: bold'>
+ <td>Rounded Total</td>
+ <td><script>doc.currency</script></td>
+ <td><script>
+ fmt_money(doc.rounded_total_export)
+ </script></td>
+ </tr>
+ </tbody></table>
+ <br /><b>In Words</b><br />
+ <i><script>doc.in_words_export</script></i>
+ </td>
+ </tr>
+ </tbody>
+ <tfoot>
+
+ </tfoot>
+ </table>
+</div>
+
diff --git a/erpnext/patches/print_formats/DeliveryNoteModern.html b/erpnext/patches/print_formats/DeliveryNoteModern.html
new file mode 100644
index 0000000..375a8a6
--- /dev/null
+++ b/erpnext/patches/print_formats/DeliveryNoteModern.html
@@ -0,0 +1,314 @@
+<!--
+ Sample Print Format for ERPNext
+ Please use at your own discretion
+ For suggestions and contributions:
+ https://github.com/webnotes/erpnext-print-templates
+
+ Freely usable under MIT license
+-->
+
+<!-- Style Settings -->
+<style>
+ /*
+ common style for whole page
+ This should include:
+ + page size related settings
+ + font family settings
+ + line spacing settings
+ */
+ @media screen {
+ body {
+ width: 8.3in;
+ }
+ }
+
+ html, body, div, span, td {
+ font-family: "Helvetica", "Arial", sans-serif;
+ font-size: 12px;
+ }
+
+ body {
+ padding: 10px;
+ margin: auto;
+ font-size: 12px;
+ line-height: 150%;
+ }
+
+ .common {
+ font-family: "Helvetica", "Arial", sans-serif !important;
+ font-size: 12px;
+ padding: 10px 0px;
+ }
+
+ table {
+ border-collapse: collapse;
+ width: 100%;
+ vertical-align: top;
+ border-style: none !important;
+ }
+
+ table td {
+ padding: 2px 0px;
+ border-style: none !important;
+ }
+
+ table h1, h2, h3, h4, h5, h6 {
+ padding: 0px;
+ margin: 0px;
+ }
+
+ table.header-table td {
+ vertical-align: top;
+ }
+
+ table.header-table h1 {
+ text-transform: uppercase;
+ color: white;
+ font-size: 55px;
+ font-style: italic;
+ }
+
+ table.header-table thead tr:nth-child(1) div {
+ height: 24px;
+ background-color: #696969;
+ vertical-align: middle;
+ padding: 12px 0px 0px 0px;
+ width: 100%;
+ }
+
+ div.page-body table td:nth-child(6),
+ div.page-body table td:nth-child(7) {
+ text-align: right;
+ }
+
+ div.page-body table tr td {
+ background-color: #DCDCDC !important;
+ }
+
+ div.page-body table tr:nth-child(1) td {
+ background-color: #696969 !important;
+ color: white !important;
+ }
+
+ table.footer-table td {
+ vertical-align: top;
+ }
+
+ table.footer-table td table td:nth-child(2),
+ table.footer-table td table td:nth-child(3) {
+ text-align: right;
+ }
+
+ table.footer-table tfoot td {
+ background-color: #696969;
+ height: 10px;
+ }
+
+ .imp-details {
+ background-color: #DCDCDC;
+ }
+</style>
+
+
+<!-- Javascript -->
+<script>
+ si_std = {
+ print_item_table: function() {
+ var table = print_table(
+ 'Delivery Note',
+ doc.name,
+ 'delivery_note_details',
+ 'Delivery Note Detail',
+ [// Here specify the table columns to be displayed
+ 'SR', 'item_code', 'item_name', 'description', 'qty', 'stock_uom',
+ 'basic_rate', 'amount'
+ ],
+ [// Here specify the labels of column headings
+ 'Sr', 'Item Code', 'Item Name', 'Description', 'Qty',
+ 'UoM', 'Basic Rate', 'Amount'
+ ],
+ [// Here specify the column widths
+ '3%', '10%', '15%', '32%', '5%',
+ '5%', '15%', '15%'
+ ],
+ null,
+ null,
+ {
+ 'description' : function(data_row) {
+ var to_append = ''
+ if(data_row.adj_rate){
+ to_append = '<div style="padding-left: 15px;"><i>Discount: ' +
+ data_row.adj_rate + '%</i></div>';
+ if(data_row.description.indexOf(to_append)==-1) {
+ data_row.description = data_row.description + to_append;
+ }
+ }
+
+ if(data_row.serial_no) {
+ to_append = '<div style="padding-left: 15px;"><i>Serial No.:' +
+ ((data_row.serial_no.indexOf('\n')>-1)?'<br />':' ') +
+ data_row.serial_no + '</i></div>';
+ if(data_row.description.indexOf(to_append)==-1) {
+ data_row.description = data_row.description + to_append;
+ }
+ }
+
+ return data_row.description;
+ }
+ }
+ );
+
+ // This code takes care of page breaks
+ if(table.appendChild) {
+ out = table.innerHTML;
+ } else {
+ out = '';
+ for(var i=0; i < (table.length-1); i++) {
+ out += table[i].innerHTML +
+ '<div style = "page-break-after: always;" \
+ class = "page_break"></div>\
+ <div class="page-settings"></div>';
+ }
+ out += table[table.length-1].innerHTML;
+ }
+ return out;
+ },
+
+
+ print_other_charges: function(parent) {
+ var oc = getchildren('RV Tax Detail', doc.name, 'other_charges');
+ var rows = '<table width=100%>\n';
+ for(var i=0; i<oc.length; i++) {
+ rows +=
+ '<tr>\n' +
+ '\t<td>' + oc[i].description + '</td>\n' +
+ '\t<td></td>\n' +
+ '\t<td width=38%>' + fmt_money(oc[i].tax_amount) + '</td>\n' +
+ '</tr>\n';
+ }
+ return rows + '</table>\n';
+ }
+ };
+</script>
+
+
+<!-- Page Layout Settings -->
+<div class='common page-header'>
+ <!--
+ Page Header will contain
+ + table 1
+ + table 1a
+ - Name
+ - Address
+ - Contact
+ - Mobile No
+ + table 1b
+ - Voucher Date
+ - Due Date
+ -->
+ <table class='header-table' cellspacing=0>
+ <thead>
+ <tr><td colspan=2><div><script>'<h1>' + (doc.select_print_heading || 'Delivery Note') + '</h1>'</script></div></td></tr>
+ <tr><td colspan=2><div style="height:15px"></div></td></tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td width=60%><table width=100% cellspacing=0><tbody>
+ <tr>
+ <td width=22%><b>Name</b></td>
+ <td><script>doc.customer_name</script></td>
+ </tr>
+ <tr>
+ <td><b>Address</b></td>
+ <td><script>replace_newlines(doc.address_display)</script></td>
+ </tr>
+ <tr>
+ <td><b>Contact</b></td>
+ <td><script>doc.contact_display</script></td>
+ </tr>
+ </tbody></table></td>
+ <td><table width=100% cellspacing=0><tbody>
+ <tr class='imp-details'>
+ <td><b>Delivery Note No.</b></td>
+ <td><script>cur_frm.docname</script></td>
+ </tr>
+ <tr>
+ <td width=63%><b>Delivery Note Date</b></td>
+ <td><script>date.str_to_user(doc.transaction_date)</script></td>
+ <tr>
+ <tr>
+ <td><b>Sales Order No.</b></td>
+ <td>
+ <script>doc.sales_order_no</script><br />
+ <i>(<script>date.str_to_user(doc.posting_date)</script>)</i>
+ </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
+ -->
+ <script>si_std.print_item_table()</script>
+</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 & Other Information:</b><br />
+ <script>doc.terms</script>
+ </td>
+ <td>
+ <table cellspacing=0 width=100%><tbody>
+ <tr>
+ <td>Net Total</td>
+ <td></td>
+ <td width=38%><script>
+ fmt_money(doc.net_total)
+ </script></td>
+ </tr>
+ <tr><td colspan=3><script>si_std.print_other_charges()</script></td></tr>
+ <tr>
+ <td>Grand Total</td>
+ <td></td>
+ <td><script>
+ fmt_money(doc.grand_total_export)
+ </script></td>
+ </tr>
+ <tr style='font-weight: bold' class='imp-details'>
+ <td>Rounded Total</td>
+ <td><script>doc.currency</script></td>
+ <td><script>
+ fmt_money(doc.rounded_total_export)
+ </script></td>
+ </tr>
+ </tbody></table>
+ <br /><b>In Words</b><br />
+ <i><script>doc.in_words_export</script></i>
+ </td>
+ </tr>
+ </tbody>
+ <tfoot>
+ <tr><td colspan=2><div></div></td><tr>
+ </tfoot>
+ </table>
+</div>
diff --git a/erpnext/patches/print_formats/DeliveryNoteSpartan.html b/erpnext/patches/print_formats/DeliveryNoteSpartan.html
new file mode 100644
index 0000000..5426f13
--- /dev/null
+++ b/erpnext/patches/print_formats/DeliveryNoteSpartan.html
@@ -0,0 +1,309 @@
+<!--
+ Sample Print Format for ERPNext
+ Please use at your own discretion
+ For suggestions and contributions:
+ https://github.com/webnotes/erpnext-print-templates
+
+ Freely usable under MIT license
+-->
+
+<!-- Style Settings -->
+<style>
+ /*
+ common style for whole page
+ This should include:
+ + page size related settings
+ + font family settings
+ + line spacing settings
+ */
+ @media screen {
+ body {
+ width: 8.3in;
+ }
+ }
+
+ html, body, div, span, td {
+ font-family: "Arial", sans-serif;
+ font-size: 12px;
+ }
+
+ body {
+ padding: 10px;
+ margin: auto;
+ font-size: 12px;
+ line-height: 150%;
+ }
+
+ .common {
+ font-family: "Arial", sans-serif !important;
+ font-size: 12px;
+ padding: 0px;
+ }
+
+ table {
+ width: 100% !important;
+ vertical-align: top;
+ }
+
+ table td {
+ padding: 2px 0px;
+ }
+
+ table, td {
+ border-collapse: collapse !important;
+ padding: 0px;
+ margin: 0px !important;
+ }
+
+ table h1, h2, h3, h4, h5, h6 {
+ padding: 0px;
+ margin: 0px;
+ }
+
+ table.header-table td {
+ vertical-align: top;
+ }
+
+ table.header-table h3 {
+ color: gray;
+ }
+
+ table.header-table thead td {
+ padding: 5px;
+ }
+
+ table.header-table > thead,
+ table.header-table > tbody > tr > td,
+ table.footer-table > tbody > tr > td {
+ border: 1px solid black;
+ padding: 5px;
+ }
+
+ table.footer-table > tbody,
+ table.header-table > thead {
+ border-bottom: 3px solid black;
+ }
+
+ table.header-table > thead {
+ border-top: 3px solid black;
+ }
+
+ div.page-body table td:nth-child(6),
+ div.page-body table td:nth-child(7) {
+ text-align: right;
+ }
+
+ div.page-body td {
+ background-color: white !important;
+ border: 1px solid black !important;
+ }
+
+ table.footer-table td {
+ vertical-align: top;
+ }
+
+ table.footer-table td table td:nth-child(2),
+ table.footer-table td table td:nth-child(3) {
+ text-align: right;
+ }
+</style>
+
+
+<!-- Javascript -->
+<script>
+ si_std = {
+ print_item_table: function() {
+ var table = print_table(
+ 'Delivery Note',
+ doc.name,
+ 'delivery_note_details',
+ 'Delivery Note Detail',
+ [// Here specify the table columns to be displayed
+ 'SR', 'item_code', 'item_name', 'description', 'qty', 'stock_uom',
+ 'basic_rate', 'amount'
+ ],
+ [// Here specify the labels of column headings
+ 'Sr', 'Item Code', 'Item Name', 'Description', 'Qty',
+ 'UoM', 'Basic Rate', 'Amount'
+ ],
+ [// Here specify the column widths
+ '3%', '10%', '15%', '32%', '5%',
+ '5%', '15%', '15%'
+ ],
+ null,
+ null,
+ {
+ 'description' : function(data_row) {
+ var to_append = ''
+ if(data_row.adj_rate){
+ to_append = '<div style="padding-left: 15px;"><i>Discount: ' +
+ data_row.adj_rate + '%</i></div>';
+ if(data_row.description.indexOf(to_append)==-1) {
+ data_row.description = data_row.description + to_append;
+ }
+ }
+
+ if(data_row.serial_no) {
+ to_append = '<div style="padding-left: 15px;"><i>Serial No.:' +
+ ((data_row.serial_no.indexOf('\n')>-1)?'<br />':' ') +
+ data_row.serial_no + '</i></div>';
+ if(data_row.description.indexOf(to_append)==-1) {
+ data_row.description = data_row.description + to_append;
+ }
+ }
+
+ return data_row.description;
+ }
+ }
+ );
+
+ // This code takes care of page breaks
+ if(table.appendChild) {
+ out = table.innerHTML;
+ } else {
+ out = '';
+ for(var i=0; i < (table.length-1); i++) {
+ out += table[i].innerHTML +
+ '<div style = "page-break-after: always;" \
+ class = "page_break"></div>\
+ <div class="page-settings"></div>';
+ }
+ out += table[table.length-1].innerHTML;
+ }
+ return out;
+ },
+
+
+ print_other_charges: function(parent) {
+ var oc = getchildren('RV Tax Detail', doc.name, 'other_charges');
+ var rows = '<table width=100%>\n';
+ for(var i=0; i<oc.length; i++) {
+ rows +=
+ '<tr>\n' +
+ '\t<td>' + oc[i].description + '</td>\n' +
+ '\t<td></td>\n' +
+ '\t<td width=38%>' + fmt_money(oc[i].tax_amount) + '</td>\n' +
+ '</tr>\n';
+ }
+ return rows + '</table>\n';
+ }
+ };
+</script>
+
+
+<!-- Page Layout Settings -->
+<div class='common page-header'>
+ <!--
+ Page Header will contain
+ + table 1
+ + table 1a
+ - Name
+ - Address
+ - Contact
+ - Mobile No
+ + table 1b
+ - Voucher Date
+ - Due Date
+ -->
+ <table class='header-table' cellspacing=0>
+ <thead>
+ <tr><td colspan=2><script>'<h1>' + (doc.select_print_heading || 'Delivery Note') + '</h1>'</script></td></tr>
+ <tr><td colspan=2><h3><script>cur_frm.docname</script></h3></td></tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td width=60%><table width=100% cellspacing=0><tbody>
+ <tr>
+ <td width=22%><b>Name</b></td>
+ <td><script>doc.customer_name</script></td>
+ </tr>
+ <tr>
+ <td><b>Address</b></td>
+ <td><script>replace_newlines(doc.address_display)</script></td>
+ </tr>
+ <tr>
+ <td><b>Contact</b></td>
+ <td><script>doc.contact_display</script></td>
+ </tr>
+ </tbody></table></td>
+ <td><table width=100% cellspacing=0><tbody>
+ <tr>
+ <td width=63%><b>Delivery Note Date</b></td>
+ <td><script>date.str_to_user(doc.transaction_date)</script></td>
+ <tr>
+ <tr>
+ <td><b>Sales Order No.</b></td>
+ <td>
+ <script>doc.sales_order_no</script><br />
+ <i>(<script>date.str_to_user(doc.posting_date)</script>)</i>
+ </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
+ -->
+ <script>si_std.print_item_table()</script>
+</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 & Other Information:</b><br />
+ <script>doc.terms</script>
+ </td>
+ <td>
+ <table cellspacing=0 width=100%><tbody>
+ <tr>
+ <td>Net Total</td>
+ <td></td>
+ <td width=38%><script>
+ fmt_money(doc.net_total)
+ </script></td>
+ </tr>
+ <tr><td colspan=3><script>si_std.print_other_charges()</script></td></tr>
+ <tr>
+ <td>Grand Total</td>
+ <td></td>
+ <td><script>
+ fmt_money(doc.grand_total_export)
+ </script></td>
+ </tr>
+ <tr style='font-weight: bold'>
+ <td>Rounded Total</td>
+ <td><script>doc.currency</script></td>
+ <td><script>
+ fmt_money(doc.rounded_total_export)
+ </script></td>
+ </tr>
+ </tbody></table>
+ <br /><b>In Words</b><br />
+ <i><script>doc.in_words_export</script></i>
+ </td>
+ </tr>
+ </tbody>
+ <tfoot>
+
+ </tfoot>
+ </table>
+</div>
diff --git a/erpnext/patches/print_formats/PurchaseOrderClassic.html b/erpnext/patches/print_formats/PurchaseOrderClassic.html
new file mode 100644
index 0000000..e9a9ff8
--- /dev/null
+++ b/erpnext/patches/print_formats/PurchaseOrderClassic.html
@@ -0,0 +1,248 @@
+<!--
+ Sample Print Format for ERPNext
+ Please use at your own discretion
+ For suggestions and contributions:
+ https://github.com/webnotes/erpnext-print-templates
+
+ Freely usable under MIT license
+-->
+
+<!-- Style Settings -->
+<style>
+ /*
+ common style for whole page
+ This should include:
+ + page size related settings
+ + font family settings
+ + line spacing settings
+ */
+ @media screen {
+ body {
+ width: 8.3in;
+ }
+ }
+
+ html, body, div, span, td {
+ font-family: "Georgia", serif;
+ font-size: 12px;
+ }
+
+ body {
+ padding: 10px;
+ margin: auto;
+ font-size: 12px;
+ line-height: 150%;
+ }
+
+ .common {
+ font-family: "Georgia", serif !important;
+ font-size: 12px;
+ padding: 10px 0px;
+ }
+
+ table {
+ border-collapse: collapse;
+ width: 100%;
+ vertical-align: top;
+ }
+
+ table td {
+ padding: 2px 0px;
+ }
+
+ table h1, h2, h3, h4, h5, h6 {
+ padding: 0px;
+ margin: 0px;
+ }
+
+ table.header-table td {
+ vertical-align: top;
+ }
+
+ table.header-table thead {
+ border-bottom: 1px solid black;
+ }
+
+ table.header-table h3 {
+ color: gray;
+ }
+
+ table.header-table thead td {
+ padding: 5px 0px;
+ }
+
+ div.page-body table td:nth-child(6),
+ div.page-body table td:nth-child(7) {
+ text-align: right;
+ }
+
+ table.footer-table td {
+ vertical-align: top;
+ }
+
+ table.footer-table td table td:nth-child(2),
+ table.footer-table td table td:nth-child(3) {
+ text-align: right;
+ }
+</style>
+
+
+<!-- Javascript -->
+<script>
+ si_std = {
+ print_item_table: function() {
+ var table = print_table(
+ 'Purchase Order',
+ doc.name,
+ 'po_details',
+ 'PO Detail',
+ [// Here specify the table columns to be displayed
+ 'SR', 'item_code', 'item_name', 'description', 'qty', 'stock_uom',
+ 'import_rate', 'import_amount'
+ ],
+ [// Here specify the labels of column headings
+ 'Sr', 'Item Code', 'Item Name', 'Description', 'Qty',
+ 'UoM', 'Basic Rate', 'Amount'
+ ],
+ [// Here specify the column widths
+ '3%', '10%', '15%', '32%', '5%',
+ '5%', '15%', '15%'
+ ]
+ );
+
+ // This code takes care of page breaks
+ if(table.appendChild) {
+ out = table.innerHTML;
+ } else {
+ out = '';
+ for(var i=0; i < (table.length-1); i++) {
+ out += table[i].innerHTML +
+ '<div style = "page-break-after: always;" \
+ class = "page_break"></div>\
+ <div class="page-settings"></div>';
+ }
+ out += table[table.length-1].innerHTML;
+ }
+ return out;
+ },
+
+
+ print_other_charges: function(parent) {
+ var oc = getchildren('Purchase Tax Detail', doc.name, 'purchase_tax_details');
+ var rows = '<table width=100%>\n';
+ for(var i=0; i<oc.length; i++) {
+ rows +=
+ '<tr>\n' +
+ '\t<td>' + oc[i].description + '</td>\n' +
+ '\t<td></td>\n' +
+ '\t<td width=38%>' + fmt_money(oc[i].tax_amount / (doc.conversion_rate || 1)) + '</td>\n' +
+ '</tr>\n';
+ }
+ return rows + '</table>\n';
+ }
+ };
+</script>
+
+
+<!-- Page Layout Settings -->
+<div class='common page-header'>
+ <!--
+ Page Header will contain
+ + table 1
+ + table 1a
+ - Name
+ - Address
+ - Contact
+ - Mobile No
+ + table 1b
+ - Voucher Date
+ - Due Date
+ -->
+ <table class='header-table' cellspacing=0>
+ <thead>
+ <tr><td><script>'<h1>' + (doc.select_print_heading || 'Purchase Order') + '</h1>'</script></td></tr>
+ <tr><td><h3><script>cur_frm.docname</script></h3></td></tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td width=60%><table width=100% cellspacing=0><tbody>
+ <tr>
+ <td width=22%><b>Name</b></td>
+ <td><script>doc.supplier_name</script></td>
+ </tr>
+ <tr>
+ <td><b>Address</b></td>
+ <td><script>replace_newlines(doc.address_display)</script></td>
+ </tr>
+ <tr>
+ <td><b>Contact</b></td>
+ <td><script>doc.contact_display</script></td>
+ </tr>
+ </tbody></table></td>
+ <td><table width=100% cellspacing=0><tbody>
+ <tr>
+ <td width=63%><b>Purchase Order Date</b></td>
+ <td><script>date.str_to_user(doc.transaction_date)</script></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
+ -->
+ <script>si_std.print_item_table()</script>
+</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 & Other Information:</b><br />
+ <script>doc.terms</script>
+ </td>
+ <td>
+ <table cellspacing=0 width=100%><tbody>
+ <tr>
+ <td>Net Total</td>
+ <td></td>
+ <td width=38%><script>
+ fmt_money(doc.net_total_import)
+ </script></td>
+ </tr>
+ <tr><td colspan=3><script>si_std.print_other_charges()</script></td></tr>
+ <tr style='font-weight: bold'>
+ <td>Grand Total</td>
+ <td><script>doc.currency</script></td>
+ <td><script>
+ fmt_money(doc.grand_total_import)
+ </script></td>
+ </tr>
+ </tbody></table>
+ <br /><b>In Words</b><br />
+ <i><script>doc.in_words_import</script></i>
+ </td>
+ </tr>
+ </tbody>
+ <tfoot>
+
+ </tfoot>
+ </table>
+</div>
diff --git a/erpnext/patches/print_formats/PurchaseOrderModern.html b/erpnext/patches/print_formats/PurchaseOrderModern.html
new file mode 100644
index 0000000..73b607b
--- /dev/null
+++ b/erpnext/patches/print_formats/PurchaseOrderModern.html
@@ -0,0 +1,275 @@
+<!--
+ Sample Print Format for ERPNext
+ Please use at your own discretion
+ For suggestions and contributions:
+ https://github.com/webnotes/erpnext-print-templates
+
+ Freely usable under MIT license
+-->
+
+<!-- Style Settings -->
+<style>
+ /*
+ common style for whole page
+ This should include:
+ + page size related settings
+ + font family settings
+ + line spacing settings
+ */
+ @media screen {
+ body {
+ width: 8.3in;
+ }
+ }
+
+ html, body, div, span, td {
+ font-family: "Helvetica", "Arial", sans-serif;
+ font-size: 12px;
+ }
+
+ body {
+ padding: 10px;
+ margin: auto;
+ font-size: 12px;
+ line-height: 150%;
+ }
+
+ .common {
+ font-family: "Helvetica", "Arial", sans-serif !important;
+ font-size: 12px;
+ padding: 10px 0px;
+ }
+
+ table {
+ border-collapse: collapse;
+ width: 100%;
+ vertical-align: top;
+ border-style: none !important;
+ }
+
+ table td {
+ padding: 2px 0px;
+ border-style: none !important;
+ }
+
+ table h1, h2, h3, h4, h5, h6 {
+ padding: 0px;
+ margin: 0px;
+ }
+
+ table.header-table td {
+ vertical-align: top;
+ }
+
+ table.header-table h1 {
+ text-transform: uppercase;
+ color: white;
+ font-size: 55px;
+ font-style: italic;
+ }
+
+ table.header-table thead tr:nth-child(1) div {
+ height: 24px;
+ background-color: #696969;
+ vertical-align: middle;
+ padding: 12px 0px 0px 0px;
+ width: 100%;
+ }
+
+ div.page-body table td:nth-child(6),
+ div.page-body table td:nth-child(7) {
+ text-align: right;
+ }
+
+ div.page-body table tr td {
+ background-color: #DCDCDC !important;
+ }
+
+ div.page-body table tr:nth-child(1) td {
+ background-color: #696969 !important;
+ color: white !important;
+ }
+
+ table.footer-table td {
+ vertical-align: top;
+ }
+
+ table.footer-table td table td:nth-child(2),
+ table.footer-table td table td:nth-child(3) {
+ text-align: right;
+ }
+
+ table.footer-table tfoot td {
+ background-color: #696969;
+ height: 10px;
+ }
+
+ .imp-details {
+ background-color: #DCDCDC;
+ }
+</style>
+
+
+<!-- Javascript -->
+<script>
+ si_std = {
+ print_item_table: function() {
+ var table = print_table(
+ 'Purchase Order',
+ doc.name,
+ 'po_details',
+ 'PO Detail',
+ [// Here specify the table columns to be displayed
+ 'SR', 'item_code', 'item_name', 'description', 'qty', 'stock_uom',
+ 'import_rate', 'import_amount'
+ ],
+ [// Here specify the labels of column headings
+ 'Sr', 'Item Code', 'Item Name', 'Description', 'Qty',
+ 'UoM', 'Basic Rate', 'Amount'
+ ],
+ [// Here specify the column widths
+ '3%', '10%', '15%', '32%', '5%',
+ '5%', '15%', '15%'
+ ]
+ );
+
+ // This code takes care of page breaks
+ if(table.appendChild) {
+ out = table.innerHTML;
+ } else {
+ out = '';
+ for(var i=0; i < (table.length-1); i++) {
+ out += table[i].innerHTML +
+ '<div style = "page-break-after: always;" \
+ class = "page_break"></div>\
+ <div class="page-settings"></div>';
+ }
+ out += table[table.length-1].innerHTML;
+ }
+ return out;
+ },
+
+
+ print_other_charges: function(parent) {
+ var oc = getchildren('Purchase Tax Detail', doc.name, 'purchase_tax_details');
+ var rows = '<table width=100%>\n';
+ for(var i=0; i<oc.length; i++) {
+ rows +=
+ '<tr>\n' +
+ '\t<td>' + oc[i].description + '</td>\n' +
+ '\t<td></td>\n' +
+ '\t<td width=38%>' + fmt_money(oc[i].tax_amount / (doc.conversion_rate || 1)) + '</td>\n' +
+ '</tr>\n';
+ }
+ return rows + '</table>\n';
+ }
+ };
+</script>
+
+
+<!-- Page Layout Settings -->
+<div class='common page-header'>
+ <!--
+ Page Header will contain
+ + table 1
+ + table 1a
+ - Name
+ - Address
+ - Contact
+ - Mobile No
+ + table 1b
+ - Voucher Date
+ - Due Date
+ -->
+ <table class='header-table' cellspacing=0>
+ <thead>
+ <tr><td colspan=2><div><script>'<h1>' + (doc.select_print_heading || 'Purchase Order') + '</h1>'</script></div></td></tr>
+ <tr><td colspan=2><div style="height:15px"></div></td></tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td width=60%><table width=100% cellspacing=0><tbody>
+ <tr>
+ <td width=22%><b>Name</b></td>
+ <td><script>doc.supplier_name</script></td>
+ </tr>
+ <tr>
+ <td><b>Address</b></td>
+ <td><script>replace_newlines(doc.address_display)</script></td>
+ </tr>
+ <tr>
+ <td><b>Contact</b></td>
+ <td><script>doc.contact_display</script></td>
+ </tr>
+ </tbody></table></td>
+ <td><table width=100% cellspacing=0><tbody>
+ <tr class='imp-details'>
+ <td><b>Purchase Order No.</b></td>
+ <td><script>cur_frm.docname</script></td>
+ </tr>
+ <tr>
+ <td width=63%><b>Purchase Order Date</b></td>
+ <td><script>date.str_to_user(doc.transaction_date)</script></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
+ -->
+ <script>si_std.print_item_table()</script>
+</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 & Other Information:</b><br />
+ <script>doc.terms</script>
+ </td>
+ <td>
+ <table cellspacing=0 width=100%><tbody>
+ <tr>
+ <td>Net Total</td>
+ <td></td>
+ <td width=38%><script>
+ fmt_money(doc.net_total_import)
+ </script></td>
+ </tr>
+ <tr><td colspan=3><script>si_std.print_other_charges()</script></td></tr>
+ <tr style='font-weight: bold' class='imp-details'>
+ <td>Grand Total</td>
+ <td><script>doc.currency</script></td>
+ <td><script>
+ fmt_money(doc.grand_total_import)
+ </script></td>
+ </tr>
+ </tbody></table>
+ <br /><b>In Words</b><br />
+ <i><script>doc.in_words_import</script></i>
+ </td>
+ </tr>
+ </tbody>
+ <tfoot>
+ <tr><td colspan=2><div></div></td><tr>
+ </tfoot>
+ </table>
+</div>
diff --git a/erpnext/patches/print_formats/PurchaseOrderSpartan.html b/erpnext/patches/print_formats/PurchaseOrderSpartan.html
new file mode 100644
index 0000000..9058e0c
--- /dev/null
+++ b/erpnext/patches/print_formats/PurchaseOrderSpartan.html
@@ -0,0 +1,270 @@
+<!--
+ Sample Print Format for ERPNext
+ Please use at your own discretion
+ For suggestions and contributions:
+ https://github.com/webnotes/erpnext-print-templates
+
+ Freely usable under MIT license
+-->
+
+<!-- Style Settings -->
+<style>
+ /*
+ common style for whole page
+ This should include:
+ + page size related settings
+ + font family settings
+ + line spacing settings
+ */
+ @media screen {
+ body {
+ width: 8.3in;
+ }
+ }
+
+ html, body, div, span, td {
+ font-family: "Arial", sans-serif;
+ font-size: 12px;
+ }
+
+ body {
+ padding: 10px;
+ margin: auto;
+ font-size: 12px;
+ line-height: 150%;
+ }
+
+ .common {
+ font-family: "Arial", sans-serif !important;
+ font-size: 12px;
+ padding: 0px;
+ }
+
+ table {
+ width: 100% !important;
+ vertical-align: top;
+ }
+
+ table td {
+ padding: 2px 0px;
+ }
+
+ table, td {
+ border-collapse: collapse !important;
+ padding: 0px;
+ margin: 0px !important;
+ }
+
+ table h1, h2, h3, h4, h5, h6 {
+ padding: 0px;
+ margin: 0px;
+ }
+
+ table.header-table td {
+ vertical-align: top;
+ }
+
+ table.header-table h3 {
+ color: gray;
+ }
+
+ table.header-table thead td {
+ padding: 5px;
+ }
+
+ table.header-table > thead,
+ table.header-table > tbody > tr > td,
+ table.footer-table > tbody > tr > td {
+ border: 1px solid black;
+ padding: 5px;
+ }
+
+ table.footer-table > tbody,
+ table.header-table > thead {
+ border-bottom: 3px solid black;
+ }
+
+ table.header-table > thead {
+ border-top: 3px solid black;
+ }
+
+ div.page-body table td:nth-child(6),
+ div.page-body table td:nth-child(7) {
+ text-align: right;
+ }
+
+ div.page-body td {
+ background-color: white !important;
+ border: 1px solid black !important;
+ }
+
+ table.footer-table td {
+ vertical-align: top;
+ }
+
+ table.footer-table td table td:nth-child(2),
+ table.footer-table td table td:nth-child(3) {
+ text-align: right;
+ }
+</style>
+
+
+<!-- Javascript -->
+<script>
+ si_std = {
+ print_item_table: function() {
+ var table = print_table(
+ 'Purchase Order',
+ doc.name,
+ 'po_details',
+ 'PO Detail',
+ [// Here specify the table columns to be displayed
+ 'SR', 'item_code', 'item_name', 'description', 'qty', 'stock_uom',
+ 'import_rate', 'import_amount'
+ ],
+ [// Here specify the labels of column headings
+ 'Sr', 'Item Code', 'Item Name', 'Description', 'Qty',
+ 'UoM', 'Basic Rate', 'Amount'
+ ],
+ [// Here specify the column widths
+ '3%', '10%', '15%', '32%', '5%',
+ '5%', '15%', '15%'
+ ]
+ );
+
+ // This code takes care of page breaks
+ if(table.appendChild) {
+ out = table.innerHTML;
+ } else {
+ out = '';
+ for(var i=0; i < (table.length-1); i++) {
+ out += table[i].innerHTML +
+ '<div style = "page-break-after: always;" \
+ class = "page_break"></div>\
+ <div class="page-settings"></div>';
+ }
+ out += table[table.length-1].innerHTML;
+ }
+ return out;
+ },
+
+
+ print_other_charges: function(parent) {
+ var oc = getchildren('Purchase Tax Detail', doc.name, 'purchase_tax_details');
+ var rows = '<table width=100%>\n';
+ for(var i=0; i<oc.length; i++) {
+ rows +=
+ '<tr>\n' +
+ '\t<td>' + oc[i].description + '</td>\n' +
+ '\t<td></td>\n' +
+ '\t<td width=38%>' + fmt_money(oc[i].tax_amount / (doc.conversion_rate || 1)) + '</td>\n' +
+ '</tr>\n';
+ }
+ return rows + '</table>\n';
+ }
+ };
+</script>
+
+
+<!-- Page Layout Settings -->
+<div class='common page-header'>
+ <!--
+ Page Header will contain
+ + table 1
+ + table 1a
+ - Name
+ - Address
+ - Contact
+ - Mobile No
+ + table 1b
+ - Voucher Date
+ - Due Date
+ -->
+ <table class='header-table' cellspacing=0>
+ <thead>
+ <tr><td colspan=2><script>'<h1>' + (doc.select_print_heading || 'Purchase Order') + '</h1>'</script></td></tr>
+ <tr><td colspan=2><h3><script>cur_frm.docname</script></h3></td></tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td width=60%><table width=100% cellspacing=0><tbody>
+ <tr>
+ <td width=22%><b>Name</b></td>
+ <td><script>doc.supplier_name</script></td>
+ </tr>
+ <tr>
+ <td><b>Address</b></td>
+ <td><script>replace_newlines(doc.address_display)</script></td>
+ </tr>
+ <tr>
+ <td><b>Contact</b></td>
+ <td><script>doc.contact_display</script></td>
+ </tr>
+ </tbody></table></td>
+ <td><table width=100% cellspacing=0><tbody>
+ <tr>
+ <td width=63%><b>Purchase Order Date</b></td>
+ <td><script>date.str_to_user(doc.transaction_date)</script></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
+ -->
+ <script>si_std.print_item_table()</script>
+</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 & Other Information:</b><br />
+ <script>doc.terms</script>
+ </td>
+ <td>
+ <table cellspacing=0 width=100%><tbody>
+ <tr>
+ <td>Net Total</td>
+ <td></td>
+ <td width=38%><script>
+ fmt_money(doc.net_total_import)
+ </script></td>
+ </tr>
+ <tr><td colspan=3><script>si_std.print_other_charges()</script></td></tr>
+ <tr style='font-weight: bold'>
+ <td>Grand Total</td>
+ <td><script>doc.currency</script></td>
+ <td><script>
+ fmt_money(doc.grand_total_import)
+ </script></td>
+ </tr>
+ </tbody></table>
+ <br /><b>In Words</b><br />
+ <i><script>doc.in_words_import</script></i>
+ </td>
+ </tr>
+ </tbody>
+ <tfoot>
+
+ </tfoot>
+ </table>
+</div>
diff --git a/erpnext/patches/print_formats/QuotationClassic.html b/erpnext/patches/print_formats/QuotationClassic.html
new file mode 100644
index 0000000..a522ec6
--- /dev/null
+++ b/erpnext/patches/print_formats/QuotationClassic.html
@@ -0,0 +1,272 @@
+<!--
+ Sample Print Format for ERPNext
+ Please use at your own discretion
+ For suggestions and contributions:
+ https://github.com/webnotes/erpnext-print-templates
+
+ Freely usable under MIT license
+-->
+
+<!-- Style Settings -->
+<style>
+ /*
+ common style for whole page
+ This should include:
+ + page size related settings
+ + font family settings
+ + line spacing settings
+ */
+ @media screen {
+ body {
+ width: 8.3in;
+ }
+ }
+
+ html, body, div, span, td {
+ font-family: "Georgia", serif;
+ font-size: 12px;
+ }
+
+ body {
+ padding: 10px;
+ margin: auto;
+ font-size: 12px;
+ line-height: 150%;
+ }
+
+ .common {
+ font-family: "Georgia", serif !important;
+ font-size: 12px;
+ padding: 10px 0px;
+ }
+
+ table {
+ border-collapse: collapse;
+ width: 100%;
+ vertical-align: top;
+ }
+
+ table td {
+ padding: 2px 0px;
+ }
+
+ table h1, h2, h3, h4, h5, h6 {
+ padding: 0px;
+ margin: 0px;
+ }
+
+ table.header-table td {
+ vertical-align: top;
+ }
+
+ table.header-table thead {
+ border-bottom: 1px solid black;
+ }
+
+ table.header-table h3 {
+ color: gray;
+ }
+
+ table.header-table thead td {
+ padding: 5px 0px;
+ }
+
+ div.page-body table td:nth-child(6),
+ div.page-body table td:nth-child(7) {
+ text-align: right;
+ }
+
+ table.footer-table td {
+ vertical-align: top;
+ }
+
+ table.footer-table td table td:nth-child(2),
+ table.footer-table td table td:nth-child(3) {
+ text-align: right;
+ }
+</style>
+
+
+<!-- Javascript -->
+<script>
+ si_std = {
+ print_item_table: function() {
+ var table = print_table(
+ 'Quotation',
+ doc.name,
+ 'quotation_details',
+ 'Quotation Detail',
+ [// Here specify the table columns to be displayed
+ 'SR', 'item_code', 'item_name', 'description', 'qty', 'stock_uom',
+ 'export_rate', 'export_amount'
+ ],
+ [// Here specify the labels of column headings
+ 'Sr', 'Item Code', 'Item Name', 'Description', 'Qty',
+ 'UoM', 'Basic Rate', 'Amount'
+ ],
+ [// Here specify the column widths
+ '3%', '10%', '15%', '32%', '5%',
+ '5%', '15%', '15%'
+ ],
+ null,
+ null,
+ {
+ 'description' : function(data_row) {
+ if(data_row.adj_rate) {
+ var to_append = '<div style="padding-left: 15px;"><i>Discount: ' +
+ data_row.adj_rate + '%</i></div>';
+ if(data_row.description.indexOf(to_append)==-1) {
+ return data_row.description + to_append;
+ } else { return data_row.description; }
+ } else {
+ return data_row.description;
+ }
+ }
+ }
+ );
+
+ // This code takes care of page breaks
+ if(table.appendChild) {
+ out = table.innerHTML;
+ } else {
+ out = '';
+ for(var i=0; i < (table.length-1); i++) {
+ out += table[i].innerHTML +
+ '<div style = "page-break-after: always;" \
+ class = "page_break"></div>\
+ <div class="page-settings"></div>';
+ }
+ out += table[table.length-1].innerHTML;
+ }
+ return out;
+ },
+
+
+ print_other_charges: function(parent) {
+ var oc = getchildren('RV Tax Detail', doc.name, 'other_charges');
+ var rows = '<table width=100%>\n';
+ for(var i=0; i<oc.length; i++) {
+ rows +=
+ '<tr>\n' +
+ '\t<td>' + oc[i].description + '</td>\n' +
+ '\t<td></td>\n' +
+ '\t<td width=38%>' + fmt_money(oc[i].tax_amount) + '</td>\n' +
+ '</tr>\n';
+ }
+ return rows + '</table>\n';
+ }
+ };
+</script>
+
+
+<!-- Page Layout Settings -->
+<div class='common page-header'>
+ <!--
+ Page Header will contain
+ + table 1
+ + table 1a
+ - Name
+ - Address
+ - Contact
+ - Mobile No
+ + table 1b
+ - Voucher Date
+ - Due Date
+ -->
+ <table class='header-table' cellspacing=0>
+ <thead>
+ <tr><td>
+ <script>'<h1>' + (doc.select_print_heading || 'Quotation') + '</h1>'</script>
+ </td></tr>
+ <tr><td><h3><script>cur_frm.docname</script></h3></td></tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td width=60%><table width=100% cellspacing=0><tbody>
+ <tr>
+ <td width=39%><b>Name</b></td>
+ <td><script>doc.customer?doc.customer:doc.lead_name</script></td>
+ </tr>
+ <tr>
+ <td><b>Address</b></td>
+ <td><script>replace_newlines(doc.address_display)</script></td>
+ </tr>
+ <tr>
+ <td><b>Contact</b></td>
+ <td><script>doc.contact_display</script></td>
+ </tr>
+ </tbody></table></td>
+ <td><table width=100% cellspacing=0><tbody>
+ <tr>
+ <td width=63%><b>Quotation Date</b></td>
+ <td><script>date.str_to_user(doc.transaction_date)</script></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
+ -->
+ <script>si_std.print_item_table()</script>
+</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 & Other Information:</b><br />
+ <script>doc.terms</script>
+ </td>
+ <td>
+ <table cellspacing=0 width=100%><tbody>
+ <tr>
+ <td>Net Total</td>
+ <td></td>
+ <td width=38%><script>
+ fmt_money(doc.net_total/doc.conversion_rate)
+ </script></td>
+ </tr>
+ <tr><td colspan=3><script>si_std.print_other_charges()</script></td></tr>
+ <tr>
+ <td>Grand Total</td>
+ <td></td>
+ <td><script>
+ fmt_money(doc.grand_total_export)
+ </script></td>
+ </tr>
+ <tr style='font-weight: bold'>
+ <td>Rounded Total</td>
+ <td><script>doc.currency</script></td>
+ <td><script>
+ fmt_money(doc.rounded_total_export)
+ </script></td>
+ </tr>
+ </tbody></table>
+ <br /><b>In Words</b><br />
+ <i><script>doc.in_words_export</script></i>
+ </td>
+ </tr>
+ </tbody>
+ <tfoot>
+
+ </tfoot>
+ </table>
+</div>
diff --git a/erpnext/patches/print_formats/QuotationModern.html b/erpnext/patches/print_formats/QuotationModern.html
new file mode 100644
index 0000000..33db0aa
--- /dev/null
+++ b/erpnext/patches/print_formats/QuotationModern.html
@@ -0,0 +1,297 @@
+<!--
+ Sample Print Format for ERPNext
+ Please use at your own discretion
+ For suggestions and contributions:
+ https://github.com/webnotes/erpnext-print-templates
+
+ Freely usable under MIT license
+-->
+
+<!-- Style Settings -->
+<style>
+ /*
+ common style for whole page
+ This should include:
+ + page size related settings
+ + font family settings
+ + line spacing settings
+ */
+ @media screen {
+ body {
+ width: 8.3in;
+ }
+ }
+
+ html, body, div, span, td {
+ font-family: "Helvetica", "Arial", sans-serif;
+ font-size: 12px;
+ }
+
+ body {
+ padding: 10px;
+ margin: auto;
+ font-size: 12px;
+ line-height: 150%;
+ }
+
+ .common {
+ font-family: "Helvetica", "Arial", sans-serif !important;
+ font-size: 12px;
+ padding: 10px 0px;
+ }
+
+ table {
+ border-collapse: collapse;
+ width: 100%;
+ vertical-align: top;
+ border-style: none !important;
+ }
+
+ table td {
+ padding: 2px 0px;
+ border-style: none !important;
+ }
+
+ table h1, h2, h3, h4, h5, h6 {
+ padding: 0px;
+ margin: 0px;
+ }
+
+ table.header-table td {
+ vertical-align: top;
+ }
+
+ table.header-table h1 {
+ text-transform: uppercase;
+ color: white;
+ font-size: 55px;
+ font-style: italic;
+ }
+
+ table.header-table thead tr:nth-child(1) div {
+ height: 24px;
+ background-color: #696969;
+ vertical-align: middle;
+ padding: 12px 0px 0px 0px;
+ width: 100%;
+ }
+
+ div.page-body table td:nth-child(6),
+ div.page-body table td:nth-child(7) {
+ text-align: right;
+ }
+
+ div.page-body table tr td {
+ background-color: #DCDCDC !important;
+ }
+
+ div.page-body table tr:nth-child(1) td {
+ background-color: #696969 !important;
+ color: white !important;
+ }
+
+ table.footer-table td {
+ vertical-align: top;
+ }
+
+ table.footer-table td table td:nth-child(2),
+ table.footer-table td table td:nth-child(3) {
+ text-align: right;
+ }
+
+ table.footer-table tfoot td {
+ background-color: #696969;
+ height: 10px;
+ }
+
+ .imp-details {
+ background-color: #DCDCDC;
+ }
+</style>
+
+
+<!-- Javascript -->
+<script>
+ si_std = {
+ print_item_table: function() {
+ var table = print_table(
+ 'Quotation',
+ doc.name,
+ 'quotation_details',
+ 'Quotation Detail',
+ [// Here specify the table columns to be displayed
+ 'SR', 'item_code', 'item_name', 'description', 'qty', 'stock_uom',
+ 'export_rate', 'export_amount'
+ ],
+ [// Here specify the labels of column headings
+ 'Sr', 'Item Code', 'Item Name', 'Description', 'Qty',
+ 'UoM', 'Basic Rate', 'Amount'
+ ],
+ [// Here specify the column widths
+ '3%', '10%', '15%', '32%', '5%',
+ '5%', '15%', '15%'
+ ],
+ null,
+ null,
+ {
+ 'description' : function(data_row) {
+ if(data_row.adj_rate) {
+ var to_append = '<div style="padding-left: 15px;"><i>Discount: ' +
+ data_row.adj_rate + '%</i></div>';
+ if(data_row.description.indexOf(to_append)==-1) {
+ return data_row.description + to_append;
+ } else { return data_row.description; }
+ } else {
+ return data_row.description;
+ }
+ }
+ }
+ );
+
+ // This code takes care of page breaks
+ if(table.appendChild) {
+ out = table.innerHTML;
+ } else {
+ out = '';
+ for(var i=0; i < (table.length-1); i++) {
+ out += table[i].innerHTML +
+ '<div style = "page-break-after: always;" \
+ class = "page_break"></div>\
+ <div class="page-settings"></div>';
+ }
+ out += table[table.length-1].innerHTML;
+ }
+ return out;
+ },
+
+
+ print_other_charges: function(parent) {
+ var oc = getchildren('RV Tax Detail', doc.name, 'other_charges');
+ var rows = '<table width=100%>\n';
+ for(var i=0; i<oc.length; i++) {
+ rows +=
+ '<tr>\n' +
+ '\t<td>' + oc[i].description + '</td>\n' +
+ '\t<td></td>\n' +
+ '\t<td width=38%>' + fmt_money(oc[i].tax_amount) + '</td>\n' +
+ '</tr>\n';
+ }
+ return rows + '</table>\n';
+ }
+ };
+</script>
+
+
+<!-- Page Layout Settings -->
+<div class='common page-header'>
+ <!--
+ Page Header will contain
+ + table 1
+ + table 1a
+ - Name
+ - Address
+ - Contact
+ - Mobile No
+ + table 1b
+ - Voucher Date
+ - Due Date
+ -->
+ <table class='header-table' cellspacing=0>
+ <thead>
+ <tr><td colspan=2><div><script>'<h1>' + (doc.select_print_heading || 'Quotation') + '</h1>'</script></div></td></tr>
+ <tr><td colspan=2><div style="height:15px"></div></td></tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td width=60%><table width=100% cellspacing=0><tbody>
+ <tr>
+ <td width=39%><b>Name</b></td>
+ <td><script>doc.customer?doc.customer:doc.lead_name</script></td>
+ </tr>
+ <tr>
+ <td><b>Address</b></td>
+ <td><script>replace_newlines(doc.address_display)</script></td>
+ </tr>
+ <tr>
+ <td><b>Contact</b></td>
+ <td><script>doc.contact_display</script></td>
+ </tr>
+ </tbody></table></td>
+ <td><table width=100% cellspacing=0><tbody>
+ <tr class='imp-details'>
+ <td><b>Quotation No.</b></td>
+ <td><script>cur_frm.docname</script></td>
+ </tr>
+ <tr>
+ <td width=63%><b>Quotation Date</b></td>
+ <td><script>date.str_to_user(doc.transaction_date)</script></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
+ -->
+ <script>si_std.print_item_table()</script>
+</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 & Other Information:</b><br />
+ <script>doc.terms</script>
+ </td>
+ <td>
+ <table cellspacing=0 width=100%><tbody>
+ <tr>
+ <td>Net Total</td>
+ <td></td>
+ <td width=38%><script>
+ fmt_money(doc.net_total/doc.conversion_rate)
+ </script></td>
+ </tr>
+ <tr><td colspan=3><script>si_std.print_other_charges()</script></td></tr>
+ <tr>
+ <td>Grand Total</td>
+ <td></td>
+ <td><script>
+ fmt_money(doc.grand_total_export)
+ </script></td>
+ </tr>
+ <tr style='font-weight: bold' class='imp-details'>
+ <td>Rounded Total</td>
+ <td><script>doc.currency</script></td>
+ <td><script>
+ fmt_money(doc.rounded_total_export)
+ </script></td>
+ </tr>
+ </tbody></table>
+ <br /><b>In Words</b><br />
+ <i><script>doc.in_words_export</script></i>
+ </td>
+ </tr>
+ </tbody>
+ <tfoot>
+ <tr><td colspan=2><div></div></td><tr>
+ </tfoot>
+ </table>
+</div>
diff --git a/erpnext/patches/print_formats/QuotationSpartan.html b/erpnext/patches/print_formats/QuotationSpartan.html
new file mode 100644
index 0000000..72ed0f7
--- /dev/null
+++ b/erpnext/patches/print_formats/QuotationSpartan.html
@@ -0,0 +1,292 @@
+<!--
+ Sample Print Format for ERPNext
+ Please use at your own discretion
+ For suggestions and contributions:
+ https://github.com/webnotes/erpnext-print-templates
+
+ Freely usable under MIT license
+-->
+
+<!-- Style Settings -->
+<style>
+ /*
+ common style for whole page
+ This should include:
+ + page size related settings
+ + font family settings
+ + line spacing settings
+ */
+ @media screen {
+ body {
+ width: 8.3in;
+ }
+ }
+
+ html, body, div, span, td {
+ font-family: "Arial", sans-serif;
+ font-size: 12px;
+ }
+
+ body {
+ padding: 10px;
+ margin: auto;
+ font-size: 12px;
+ line-height: 150%;
+ }
+
+ .common {
+ font-family: "Arial", sans-serif !important;
+ font-size: 12px;
+ padding: 0px;
+ }
+
+ table {
+ width: 100% !important;
+ vertical-align: top;
+ }
+
+ table td {
+ padding: 2px 0px;
+ }
+
+ table, td {
+ border-collapse: collapse !important;
+ padding: 0px;
+ margin: 0px !important;
+ }
+
+ table h1, h2, h3, h4, h5, h6 {
+ padding: 0px;
+ margin: 0px;
+ }
+
+ table.header-table td {
+ vertical-align: top;
+ }
+
+ table.header-table h3 {
+ color: gray;
+ }
+
+ table.header-table thead td {
+ padding: 5px;
+ }
+
+ table.header-table > thead,
+ table.header-table > tbody > tr > td,
+ table.footer-table > tbody > tr > td {
+ border: 1px solid black;
+ padding: 5px;
+ }
+
+ table.footer-table > tbody,
+ table.header-table > thead {
+ border-bottom: 3px solid black;
+ }
+
+ table.header-table > thead {
+ border-top: 3px solid black;
+ }
+
+ div.page-body table td:nth-child(6),
+ div.page-body table td:nth-child(7) {
+ text-align: right;
+ }
+
+ div.page-body td {
+ background-color: white !important;
+ border: 1px solid black !important;
+ }
+
+ table.footer-table td {
+ vertical-align: top;
+ }
+
+ table.footer-table td table td:nth-child(2),
+ table.footer-table td table td:nth-child(3) {
+ text-align: right;
+ }
+</style>
+
+
+<!-- Javascript -->
+<script>
+ si_std = {
+ print_item_table: function() {
+ var table = print_table(
+ 'Quotation',
+ doc.name,
+ 'quotation_details',
+ 'Quotation Detail',
+ [// Here specify the table columns to be displayed
+ 'SR', 'item_code', 'item_name', 'description', 'qty', 'stock_uom',
+ 'export_rate', 'export_amount'
+ ],
+ [// Here specify the labels of column headings
+ 'Sr', 'Item Code', 'Item Name', 'Description', 'Qty',
+ 'UoM', 'Basic Rate', 'Amount'
+ ],
+ [// Here specify the column widths
+ '3%', '10%', '15%', '32%', '5%',
+ '5%', '15%', '15%'
+ ],
+ null,
+ null,
+ {
+ 'description' : function(data_row) {
+ if(data_row.adj_rate) {
+ var to_append = '<div style="padding-left: 15px;"><i>Discount: ' +
+ data_row.adj_rate + '%</i></div>';
+ if(data_row.description.indexOf(to_append)==-1) {
+ return data_row.description + to_append;
+ } else { return data_row.description; }
+ } else {
+ return data_row.description;
+ }
+ }
+ }
+ );
+
+ // This code takes care of page breaks
+ if(table.appendChild) {
+ out = table.innerHTML;
+ } else {
+ out = '';
+ for(var i=0; i < (table.length-1); i++) {
+ out += table[i].innerHTML +
+ '<div style = "page-break-after: always;" \
+ class = "page_break"></div>\
+ <div class="page-settings"></div>';
+ }
+ out += table[table.length-1].innerHTML;
+ }
+ return out;
+ },
+
+
+ print_other_charges: function(parent) {
+ var oc = getchildren('RV Tax Detail', doc.name, 'other_charges');
+ var rows = '<table width=100%>\n';
+ for(var i=0; i<oc.length; i++) {
+ rows +=
+ '<tr>\n' +
+ '\t<td>' + oc[i].description + '</td>\n' +
+ '\t<td></td>\n' +
+ '\t<td width=38%>' + fmt_money(oc[i].tax_amount) + '</td>\n' +
+ '</tr>\n';
+ }
+ return rows + '</table>\n';
+ }
+ };
+</script>
+
+
+<!-- Page Layout Settings -->
+<div class='common page-header'>
+ <!--
+ Page Header will contain
+ + table 1
+ + table 1a
+ - Name
+ - Address
+ - Contact
+ - Mobile No
+ + table 1b
+ - Voucher Date
+ - Due Date
+ -->
+ <table class='header-table' cellspacing=0>
+ <thead>
+ <tr><td colspan=2><script>'<h1>' + (doc.select_print_heading || 'Quotation') + '</h1>'</script></td></tr>
+ <tr><td colspan=2><h3><script>cur_frm.docname</script></h3></td></tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td width=60%><table width=100% cellspacing=0><tbody>
+ <tr>
+ <td width=39%><b>Name</b></td>
+ <td><script>doc.customer?doc.customer:doc.lead_name</script></td>
+ </tr>
+ <tr>
+ <td><b>Address</b></td>
+ <td><script>replace_newlines(doc.address_display)</script></td>
+ </tr>
+ <tr>
+ <td><b>Contact</b></td>
+ <td><script>doc.contact_display</script></td>
+ </tr>
+ </tbody></table></td>
+ <td><table width=100% cellspacing=0><tbody>
+ <tr>
+ <td width=63%><b>Quotation Date</b></td>
+ <td><script>date.str_to_user(doc.transaction_date)</script></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
+ -->
+ <script>si_std.print_item_table()</script>
+</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 & Other Information:</b><br />
+ <script>doc.terms</script>
+ </td>
+ <td>
+ <table cellspacing=0 width=100%><tbody>
+ <tr>
+ <td>Net Total</td>
+ <td></td>
+ <td width=38%><script>
+ fmt_money(doc.net_total/doc.conversion_rate)
+ </script></td>
+ </tr>
+ <tr><td colspan=3><script>si_std.print_other_charges()</script></td></tr>
+ <tr>
+ <td>Grand Total</td>
+ <td></td>
+ <td><script>
+ fmt_money(doc.grand_total_export)
+ </script></td>
+ </tr>
+ <tr style='font-weight: bold'>
+ <td>Rounded Total</td>
+ <td><script>doc.currency</script></td>
+ <td><script>
+ fmt_money(doc.rounded_total_export)
+ </script></td>
+ </tr>
+ </tbody></table>
+ <br /><b>In Words</b><br />
+ <i><script>doc.in_words_export</script></i>
+ </td>
+ </tr>
+ </tbody>
+ <tfoot>
+
+ </tfoot>
+ </table>
+</div>
diff --git a/erpnext/patches/print_formats/SalesInvoiceClassic.html b/erpnext/patches/print_formats/SalesInvoiceClassic.html
new file mode 100644
index 0000000..79da643
--- /dev/null
+++ b/erpnext/patches/print_formats/SalesInvoiceClassic.html
@@ -0,0 +1,274 @@
+<!--
+ Sample Print Format for ERPNext
+ Please use at your own discretion
+ For suggestions and contributions:
+ https://github.com/webnotes/erpnext-print-templates
+
+ Freely usable under MIT license
+-->
+
+<!-- Style Settings -->
+<style>
+ /*
+ common style for whole page
+ This should include:
+ + page size related settings
+ + font family settings
+ + line spacing settings
+ */
+ @media screen {
+ body {
+ width: 8.3in;
+ }
+ }
+
+ html, body, div, span, td {
+ font-family: "Georgia", serif;
+ font-size: 12px;
+ }
+
+ body {
+ padding: 10px;
+ margin: auto;
+ font-size: 12px;
+ line-height: 150%;
+ }
+
+ .common {
+ font-family: "Georgia", serif !important;
+ font-size: 12px;
+ padding: 10px 0px;
+ }
+
+ table {
+ border-collapse: collapse;
+ width: 100%;
+ vertical-align: top;
+ }
+
+ table td {
+ padding: 2px 0px;
+ }
+
+ table h1, h2, h3, h4, h5, h6 {
+ padding: 0px;
+ margin: 0px;
+ }
+
+ table.header-table td {
+ vertical-align: top;
+ }
+
+ table.header-table thead {
+ border-bottom: 1px solid black;
+ }
+
+ table.header-table h3 {
+ color: gray;
+ }
+
+ table.header-table thead td {
+ padding: 5px 0px;
+ }
+
+ div.page-body table td:nth-child(6),
+ div.page-body table td:nth-child(7) {
+ text-align: right;
+ }
+
+ table.footer-table td {
+ vertical-align: top;
+ }
+
+ table.footer-table td table td:nth-child(2),
+ table.footer-table td table td:nth-child(3) {
+ text-align: right;
+ }
+</style>
+
+
+<!-- Javascript -->
+<script>
+ si_std = {
+ print_item_table: function() {
+ var table = print_table(
+ 'Receivable Voucher',
+ doc.name,
+ 'entries',
+ 'RV Detail',
+ [// Here specify the table columns to be displayed
+ 'SR', 'item_name', 'description', 'qty', 'stock_uom',
+ 'export_rate', 'export_amount'
+ ],
+ [// Here specify the labels of column headings
+ 'Sr', 'Item Name', 'Description', 'Qty',
+ 'UoM', 'Basic Rate', 'Amount'
+ ],
+ [// Here specify the column widths
+ '3%', '20%', '37%', '5%',
+ '5%', '15%', '15%'
+ ],
+ null,
+ null,
+ {
+ 'description' : function(data_row) {
+ if(data_row.adj_rate) {
+ var to_append = '<div style="padding-left: 15px;"><i>Discount: ' +
+ data_row.adj_rate + '%</i></div>';
+ if(data_row.description.indexOf(to_append)==-1) {
+ return data_row.description + to_append;
+ } else { return data_row.description; }
+ } else {
+ return data_row.description;
+ }
+ }
+ }
+ );
+
+ // This code takes care of page breaks
+ if(table.appendChild) {
+ out = table.innerHTML;
+ } else {
+ out = '';
+ for(var i=0; i < (table.length-1); i++) {
+ out += table[i].innerHTML +
+ '<div style = "page-break-after: always;" \
+ class = "page_break"></div>\
+ <div class="page-settings"></div>';
+ }
+ out += table[table.length-1].innerHTML;
+ }
+ return out;
+ },
+
+
+ print_other_charges: function(parent) {
+ var oc = getchildren('RV Tax Detail', doc.name, 'other_charges');
+ var rows = '<table width=100%>\n';
+ for(var i=0; i<oc.length; i++) {
+ rows +=
+ '<tr>\n' +
+ '\t<td>' + oc[i].description + '</td>\n' +
+ '\t<td></td>\n' +
+ '\t<td width=38%>' + fmt_money(oc[i].tax_amount) + '</td>\n' +
+ '</tr>\n';
+ }
+ return rows + '</table>\n';
+ }
+ };
+</script>
+
+
+<!-- Page Layout Settings -->
+<div class='common page-header'>
+ <!--
+ Page Header will contain
+ + table 1
+ + table 1a
+ - Name
+ - Address
+ - Contact
+ - Mobile No
+ + table 1b
+ - Voucher Date
+ - Due Date
+ -->
+ <table class='header-table' cellspacing=0>
+ <thead>
+ <tr><td><script>'<h1>' + (doc.select_print_heading || 'Invoice') + '</h1>'</script></td></tr>
+ <tr><td><h3><script>cur_frm.docname</script></h3></td></tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td width=60%><table width=100% cellspacing=0><tbody>
+ <tr>
+ <td width=39%><b>Name</b></td>
+ <td><script>doc.customer_name</script></td>
+ </tr>
+ <tr>
+ <td><b>Address</b></td>
+ <td><script>replace_newlines(doc.address_display)</script></td>
+ </tr>
+ <tr>
+ <td><b>Contact</b></td>
+ <td><script>doc.contact_display</script></td>
+ </tr>
+ </tbody></table></td>
+ <td><table width=100% cellspacing=0><tbody>
+ <tr>
+ <td width=40%><b>Invoice Date</b></td>
+ <td><script>date.str_to_user(doc.voucher_date)</script></td>
+ <tr>
+ <tr>
+ <td><b>Due Date</b></td>
+ <td><script>date.str_to_user(doc.due_date)</script></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
+ -->
+ <script>si_std.print_item_table()</script>
+</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 & Other Information:</b><br />
+ <script>doc.terms</script>
+ </td>
+ <td>
+ <table cellspacing=0 width=100%><tbody>
+ <tr>
+ <td>Net Total</td>
+ <td></td>
+ <td width=38%><script>
+ fmt_money(doc.net_total/doc.conversion_rate)
+ </script></td>
+ </tr>
+ <tr><td colspan=3><script>si_std.print_other_charges()</script></td></tr>
+ <tr>
+ <td>Grand Total</td>
+ <td></td>
+ <td><script>
+ fmt_money(doc.grand_total_export)
+ </script></td>
+ </tr>
+ <tr style='font-weight: bold'>
+ <td>Rounded Total</td>
+ <td><script>doc.currency</script></td>
+ <td><script>
+ fmt_money(doc.rounded_total_export)
+ </script></td>
+ </tr>
+ </tbody></table>
+ <br /><b>In Words</b><br />
+ <i><script>doc.in_words_export</script></i>
+ </td>
+ </tr>
+ </tbody>
+ <tfoot>
+
+ </tfoot>
+ </table>
+</div>
diff --git a/erpnext/patches/print_formats/SalesInvoiceModern.html b/erpnext/patches/print_formats/SalesInvoiceModern.html
new file mode 100644
index 0000000..3173c55
--- /dev/null
+++ b/erpnext/patches/print_formats/SalesInvoiceModern.html
@@ -0,0 +1,301 @@
+<!--
+ Sample Print Format for ERPNext
+ Please use at your own discretion
+ For suggestions and contributions:
+ https://github.com/webnotes/erpnext-print-templates
+
+ Freely usable under MIT license
+-->
+
+<!-- Style Settings -->
+<style>
+ /*
+ common style for whole page
+ This should include:
+ + page size related settings
+ + font family settings
+ + line spacing settings
+ */
+ @media screen {
+ body {
+ width: 8.3in;
+ }
+ }
+
+ html, body, div, span, td {
+ font-family: "Helvetica", "Arial", sans-serif;
+ font-size: 12px;
+ }
+
+ body {
+ padding: 10px;
+ margin: auto;
+ font-size: 12px;
+ line-height: 150%;
+ }
+
+ .common {
+ font-family: "Helvetica", "Arial", sans-serif !important;
+ font-size: 12px;
+ padding: 10px 0px;
+ }
+
+ table {
+ border-collapse: collapse;
+ width: 100%;
+ vertical-align: top;
+ border-style: none !important;
+ }
+
+ table td {
+ padding: 2px 0px;
+ border-style: none !important;
+ }
+
+ table h1, h2, h3, h4, h5, h6 {
+ padding: 0px;
+ margin: 0px;
+ }
+
+ table.header-table td {
+ vertical-align: top;
+ }
+
+ table.header-table h1 {
+ text-transform: uppercase;
+ color: white;
+ font-size: 55px;
+ font-style: italic;
+ }
+
+ table.header-table thead tr:nth-child(1) div {
+ height: 24px;
+ background-color: #696969;
+ vertical-align: middle;
+ padding: 12px 0px 0px 0px;
+ width: 100%;
+ }
+
+ div.page-body table td:nth-child(6),
+ div.page-body table td:nth-child(7) {
+ text-align: right;
+ }
+
+ div.page-body table tr td {
+ background-color: #DCDCDC !important;
+ }
+
+ div.page-body table tr:nth-child(1) td {
+ background-color: #696969 !important;
+ color: white !important;
+ }
+
+ table.footer-table td {
+ vertical-align: top;
+ }
+
+ table.footer-table td table td:nth-child(2),
+ table.footer-table td table td:nth-child(3) {
+ text-align: right;
+ }
+
+ table.footer-table tfoot td {
+ background-color: #696969;
+ height: 10px;
+ }
+
+ .imp-details {
+ background-color: #DCDCDC;
+ }
+</style>
+
+
+<!-- Javascript -->
+<script>
+ si_std = {
+ print_item_table: function() {
+ var table = print_table(
+ 'Receivable Voucher',
+ doc.name,
+ 'entries',
+ 'RV Detail',
+ [// Here specify the table columns to be displayed
+ 'SR', 'item_name', 'description', 'qty', 'stock_uom',
+ 'export_rate', 'export_amount'
+ ],
+ [// Here specify the labels of column headings
+ 'Sr', 'Item Name', 'Description', 'Qty',
+ 'UoM', 'Basic Rate', 'Amount'
+ ],
+ [// Here specify the column widths
+ '3%', '20%', '37%', '5%',
+ '5%', '15%', '15%'
+ ],
+ null,
+ null,
+ {
+ 'description' : function(data_row) {
+ if(data_row.adj_rate) {
+ var to_append = '<div style="padding-left: 15px;"><i>Discount: ' +
+ data_row.adj_rate + '%</i></div>';
+ if(data_row.description.indexOf(to_append)==-1) {
+ return data_row.description + to_append;
+ } else { return data_row.description; }
+ } else {
+ return data_row.description;
+ }
+ }
+ }
+ );
+
+ // This code takes care of page breaks
+ if(table.appendChild) {
+ out = table.innerHTML;
+ } else {
+ out = '';
+ for(var i=0; i < (table.length-1); i++) {
+ out += table[i].innerHTML +
+ '<div style = "page-break-after: always;" \
+ class = "page_break"></div>\
+ <div class="page-settings"></div>';
+ }
+ out += table[table.length-1].innerHTML;
+ }
+ return out;
+ },
+
+
+ print_other_charges: function(parent) {
+ var oc = getchildren('RV Tax Detail', doc.name, 'other_charges');
+ var rows = '<table width=100%>\n';
+ for(var i=0; i<oc.length; i++) {
+ rows +=
+ '<tr>\n' +
+ '\t<td>' + oc[i].description + '</td>\n' +
+ '\t<td></td>\n' +
+ '\t<td width=38%>' + fmt_money(oc[i].tax_amount) + '</td>\n' +
+ '</tr>\n';
+ }
+ return rows + '</table>\n';
+ }
+ };
+</script>
+
+
+<!-- Page Layout Settings -->
+<div class='common page-header'>
+ <!--
+ Page Header will contain
+ + table 1
+ + table 1a
+ - Name
+ - Address
+ - Contact
+ - Mobile No
+ + table 1b
+ - Voucher Date
+ - Due Date
+ -->
+ <table class='header-table' cellspacing=0>
+ <thead>
+ <tr><td colspan=2><div><script>'<h1>' + (doc.select_print_heading || 'Invoice') + '</h1>'</script></div></td></tr>
+ <tr><td colspan=2><div style="height:15px"></div></td></tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td width=60%><table width=100% cellspacing=0><tbody>
+ <tr>
+ <td width=39%><b>Name</b></td>
+ <td><script>doc.customer_name</script></td>
+ </tr>
+ <tr>
+ <td><b>Address</b></td>
+ <td><script>replace_newlines(doc.address_display)</script></td>
+ </tr>
+ <tr>
+ <td><b>Contact</b></td>
+ <td><script>doc.contact_display</script></td>
+ </tr>
+ </tbody></table></td>
+ <td><table width=100% cellspacing=0><tbody>
+ <tr class='imp-details'>
+ <td><b>Invoice No.</b></td>
+ <td><script>cur_frm.docname</script></td>
+ </tr>
+ <tr>
+ <td width=40%><b>Invoice Date</b></td>
+ <td><script>date.str_to_user(doc.voucher_date)</script></td>
+ <tr>
+ <tr>
+ <td><b>Due Date</b></td>
+ <td><script>date.str_to_user(doc.due_date)</script></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
+ -->
+ <script>si_std.print_item_table()</script>
+</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 & Other Information:</b><br />
+ <script>doc.terms</script>
+ </td>
+ <td>
+ <table cellspacing=0 width=100%><tbody>
+ <tr>
+ <td>Net Total</td>
+ <td></td>
+ <td width=38%><script>
+ fmt_money(doc.net_total/doc.conversion_rate)
+ </script></td>
+ </tr>
+ <tr><td colspan=3><script>si_std.print_other_charges()</script></td></tr>
+ <tr>
+ <td>Grand Total</td>
+ <td></td>
+ <td><script>
+ fmt_money(doc.grand_total_export)
+ </script></td>
+ </tr>
+ <tr style='font-weight: bold' class='imp-details'>
+ <td>Rounded Total</td>
+ <td><script>doc.currency</script></td>
+ <td><script>
+ fmt_money(doc.rounded_total_export)
+ </script></td>
+ </tr>
+ </tbody></table>
+ <br /><b>In Words</b><br />
+ <i><script>doc.in_words_export</script></i>
+ </td>
+ </tr>
+ </tbody>
+ <tfoot>
+ <tr><td colspan=2><div></div></td><tr>
+ </tfoot>
+ </table>
+</div>
diff --git a/erpnext/patches/print_formats/SalesInvoiceSpartan.html b/erpnext/patches/print_formats/SalesInvoiceSpartan.html
new file mode 100644
index 0000000..b76c49e
--- /dev/null
+++ b/erpnext/patches/print_formats/SalesInvoiceSpartan.html
@@ -0,0 +1,296 @@
+<!--
+ Sample Print Format for ERPNext
+ Please use at your own discretion
+ For suggestions and contributions:
+ https://github.com/webnotes/erpnext-print-templates
+
+ Freely usable under MIT license
+-->
+
+<!-- Style Settings -->
+<style>
+ /*
+ common style for whole page
+ This should include:
+ + page size related settings
+ + font family settings
+ + line spacing settings
+ */
+ @media screen {
+ body {
+ width: 8.3in;
+ }
+ }
+
+ html, body, div, span, td {
+ font-family: "Arial", sans-serif;
+ font-size: 12px;
+ }
+
+ body {
+ padding: 10px;
+ margin: auto;
+ font-size: 12px;
+ line-height: 150%;
+ }
+
+ .common {
+ font-family: "Arial", sans-serif !important;
+ font-size: 12px;
+ padding: 0px;
+ }
+
+ table {
+ width: 100% !important;
+ vertical-align: top;
+ }
+
+ table td {
+ padding: 2px 0px;
+ }
+
+ table, td {
+ border-collapse: collapse !important;
+ padding: 0px;
+ margin: 0px !important;
+ }
+
+ table h1, h2, h3, h4, h5, h6 {
+ padding: 0px;
+ margin: 0px;
+ }
+
+ table.header-table td {
+ vertical-align: top;
+ }
+
+ table.header-table h3 {
+ color: gray;
+ }
+
+ table.header-table thead td {
+ padding: 5px;
+ }
+
+ table.header-table > thead,
+ table.header-table > tbody > tr > td,
+ table.footer-table > tbody > tr > td {
+ border: 1px solid black;
+ padding: 5px;
+ }
+
+ table.footer-table > tbody,
+ table.header-table > thead {
+ border-bottom: 3px solid black;
+ }
+
+ table.header-table > thead {
+ border-top: 3px solid black;
+ }
+
+ div.page-body table td:nth-child(6),
+ div.page-body table td:nth-child(7) {
+ text-align: right;
+ }
+
+ div.page-body td {
+ background-color: white !important;
+ border: 1px solid black !important;
+ }
+
+ table.footer-table td {
+ vertical-align: top;
+ }
+
+ table.footer-table td table td:nth-child(2),
+ table.footer-table td table td:nth-child(3) {
+ text-align: right;
+ }
+</style>
+
+
+<!-- Javascript -->
+<script>
+ si_std = {
+ print_item_table: function() {
+ var table = print_table(
+ 'Receivable Voucher',
+ doc.name,
+ 'entries',
+ 'RV Detail',
+ [// Here specify the table columns to be displayed
+ 'SR', 'item_name', 'description', 'qty', 'stock_uom',
+ 'export_rate', 'export_amount'
+ ],
+ [// Here specify the labels of column headings
+ 'Sr', 'Item Name', 'Description', 'Qty',
+ 'UoM', 'Basic Rate', 'Amount'
+ ],
+ [// Here specify the column widths
+ '3%', '20%', '37%', '5%',
+ '5%', '15%', '15%'
+ ],
+ null,
+ null,
+ {
+ 'description' : function(data_row) {
+ if(data_row.adj_rate) {
+ var to_append = '<div style="padding-left: 15px;"><i>Discount: ' +
+ data_row.adj_rate + '%</i></div>';
+ if(data_row.description.indexOf(to_append)==-1) {
+ return data_row.description + to_append;
+ } else { return data_row.description; }
+ } else {
+ return data_row.description;
+ }
+ }
+ }
+ );
+
+ // This code takes care of page breaks
+ if(table.appendChild) {
+ out = table.innerHTML;
+ } else {
+ out = '';
+ for(var i=0; i < (table.length-1); i++) {
+ out += table[i].innerHTML +
+ '<div style = "page-break-after: always;" \
+ class = "page_break"></div>\
+ <div class="page-settings"></div>';
+ }
+ out += table[table.length-1].innerHTML;
+ }
+ return out;
+ },
+
+
+ print_other_charges: function(parent) {
+ var oc = getchildren('RV Tax Detail', doc.name, 'other_charges');
+ var rows = '<table width=100%>\n';
+ for(var i=0; i<oc.length; i++) {
+ rows +=
+ '<tr>\n' +
+ '\t<td>' + oc[i].description + '</td>\n' +
+ '\t<td></td>\n' +
+ '\t<td width=38%>' + fmt_money(oc[i].tax_amount) + '</td>\n' +
+ '</tr>\n';
+ }
+ return rows + '</table>\n';
+ }
+ };
+</script>
+
+
+<!-- Page Layout Settings -->
+<div class='common page-header'>
+ <!--
+ Page Header will contain
+ + table 1
+ + table 1a
+ - Name
+ - Address
+ - Contact
+ - Mobile No
+ + table 1b
+ - Voucher Date
+ - Due Date
+ -->
+ <table class='header-table' cellspacing=0>
+ <thead>
+ <tr><td colspan=2><script>'<h1>' + (doc.select_print_heading || 'Invoice') + '</h1>'</script></td></tr>
+ <tr><td colspan=2><h3><script>cur_frm.docname</script></h3></td></tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td width=60%><table width=100% cellspacing=0><tbody>
+ <tr>
+ <td width=39%><b>Name</b></td>
+ <td><script>doc.customer_name</script></td>
+ </tr>
+ <tr>
+ <td><b>Address</b></td>
+ <td><script>replace_newlines(doc.address_display)</script></td>
+ </tr>
+ <tr>
+ <td><b>Contact</b></td>
+ <td><script>doc.contact_display</script></td>
+ </tr>
+ </tbody></table></td>
+ <td><table width=100% cellspacing=0><tbody>
+ <tr>
+ <td width=40%><b>Invoice Date</b></td>
+ <td><script>date.str_to_user(doc.voucher_date)</script></td>
+ <tr>
+ <tr>
+ <td><b>Due Date</b></td>
+ <td><script>date.str_to_user(doc.due_date)</script></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
+ -->
+ <script>si_std.print_item_table()</script>
+</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 & Other Information:</b><br />
+ <script>doc.terms</script>
+ </td>
+ <td>
+ <table cellspacing=0 width=100%><tbody>
+ <tr>
+ <td>Net Total</td>
+ <td></td>
+ <td width=38%><script>
+ fmt_money(doc.net_total/doc.conversion_rate)
+ </script></td>
+ </tr>
+ <tr><td colspan=3><script>si_std.print_other_charges()</script></td></tr>
+ <tr>
+ <td>Grand Total</td>
+ <td></td>
+ <td><script>
+ fmt_money(doc.grand_total_export)
+ </script></td>
+ </tr>
+ <tr style='font-weight: bold'>
+ <td>Rounded Total</td>
+ <td><script>doc.currency</script></td>
+ <td><script>
+ fmt_money(doc.rounded_total_export)
+ </script></td>
+ </tr>
+ </tbody></table>
+ <br /><b>In Words</b><br />
+ <i><script>doc.in_words_export</script></i>
+ </td>
+ </tr>
+ </tbody>
+ <tfoot>
+
+ </tfoot>
+ </table>
+</div>
diff --git a/erpnext/patches/print_formats/SalesOrderClassic.html b/erpnext/patches/print_formats/SalesOrderClassic.html
new file mode 100644
index 0000000..21d8d46
--- /dev/null
+++ b/erpnext/patches/print_formats/SalesOrderClassic.html
@@ -0,0 +1,274 @@
+<!--
+ Sample Print Format for ERPNext
+ Please use at your own discretion
+ For suggestions and contributions:
+ https://github.com/webnotes/erpnext-print-templates
+
+ Freely usable under MIT license
+-->
+
+<!-- Style Settings -->
+<style>
+ /*
+ common style for whole page
+ This should include:
+ + page size related settings
+ + font family settings
+ + line spacing settings
+ */
+ @media screen {
+ body {
+ width: 8.3in;
+ }
+ }
+
+ html, body, div, span, td {
+ font-family: "Georgia", serif;
+ font-size: 12px;
+ }
+
+ body {
+ padding: 10px;
+ margin: auto;
+ font-size: 12px;
+ line-height: 150%;
+ }
+
+ .common {
+ font-family: "Georgia", serif !important;
+ font-size: 12px;
+ padding: 10px 0px;
+ }
+
+ table {
+ border-collapse: collapse;
+ width: 100%;
+ vertical-align: top;
+ }
+
+ table td {
+ padding: 2px 0px;
+ }
+
+ table h1, h2, h3, h4, h5, h6 {
+ padding: 0px;
+ margin: 0px;
+ }
+
+ table.header-table td {
+ vertical-align: top;
+ }
+
+ table.header-table thead {
+ border-bottom: 1px solid black;
+ }
+
+ table.header-table h3 {
+ color: gray;
+ }
+
+ table.header-table thead td {
+ padding: 5px 0px;
+ }
+
+ div.page-body table td:nth-child(6),
+ div.page-body table td:nth-child(7) {
+ text-align: right;
+ }
+
+ table.footer-table td {
+ vertical-align: top;
+ }
+
+ table.footer-table td table td:nth-child(2),
+ table.footer-table td table td:nth-child(3) {
+ text-align: right;
+ }
+</style>
+
+
+<!-- Javascript -->
+<script>
+ si_std = {
+ print_item_table: function() {
+ var table = print_table(
+ 'Sales Order',
+ doc.name,
+ 'sales_order_details',
+ 'Sales Order Detail',
+ [// Here specify the table columns to be displayed
+ 'SR', 'item_code', 'description', 'qty', 'stock_uom',
+ 'basic_rate', 'amount'
+ ],
+ [// Here specify the labels of column headings
+ 'Sr', 'Item Code', 'Description', 'Qty',
+ 'UoM', 'Basic Rate', 'Amount'
+ ],
+ [// Here specify the column widths
+ '3%', '20%', '37%', '5%',
+ '5%', '15%', '15%'
+ ],
+ null,
+ null,
+ {
+ 'description' : function(data_row) {
+ if(data_row.adj_rate) {
+ var to_append = '<div style="padding-left: 15px;"><i>Discount: ' +
+ data_row.adj_rate + '%</i></div>';
+ if(data_row.description.indexOf(to_append)==-1) {
+ return data_row.description + to_append;
+ } else { return data_row.description; }
+ } else {
+ return data_row.description;
+ }
+ }
+ }
+ );
+
+ // This code takes care of page breaks
+ if(table.appendChild) {
+ out = table.innerHTML;
+ } else {
+ out = '';
+ for(var i=0; i < (table.length-1); i++) {
+ out += table[i].innerHTML +
+ '<div style = "page-break-after: always;" \
+ class = "page_break"></div>\
+ <div class="page-settings"></div>';
+ }
+ out += table[table.length-1].innerHTML;
+ }
+ return out;
+ },
+
+
+ print_other_charges: function(parent) {
+ var oc = getchildren('RV Tax Detail', doc.name, 'other_charges');
+ var rows = '<table width=100%>\n';
+ for(var i=0; i<oc.length; i++) {
+ rows +=
+ '<tr>\n' +
+ '\t<td>' + oc[i].description + '</td>\n' +
+ '\t<td></td>\n' +
+ '\t<td width=38%>' + fmt_money(oc[i].tax_amount) + '</td>\n' +
+ '</tr>\n';
+ }
+ return rows + '</table>\n';
+ }
+ };
+</script>
+
+
+<!-- Page Layout Settings -->
+<div class='common page-header'>
+ <!--
+ Page Header will contain
+ + table 1
+ + table 1a
+ - Name
+ - Address
+ - Contact
+ - Mobile No
+ + table 1b
+ - Voucher Date
+ - Due Date
+ -->
+ <table class='header-table' cellspacing=0>
+ <thead>
+ <tr><td><script>'<h1>' + (doc.select_print_heading || 'Sales Order') + '</h1>'</script></td></tr>
+ <tr><td><h3><script>cur_frm.docname</script></h3></td></tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td width=60%><table width=100% cellspacing=0><tbody>
+ <tr>
+ <td width=39%><b>Name</b></td>
+ <td><script>doc.customer_name</script></td>
+ </tr>
+ <tr>
+ <td><b>Address</b></td>
+ <td><script>replace_newlines(doc.address_display)</script></td>
+ </tr>
+ <tr>
+ <td><b>Contact</b></td>
+ <td><script>doc.contact_display</script></td>
+ </tr>
+ </tbody></table></td>
+ <td><table width=100% cellspacing=0><tbody>
+ <tr>
+ <td width=63%><b>Sales Order Date</b></td>
+ <td><script>date.str_to_user(doc.transaction_date)</script></td>
+ <tr>
+ <tr>
+ <td><b>Delivery Date</b></td>
+ <td><script>date.str_to_user(doc.delivery_date)</script></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
+ -->
+ <script>si_std.print_item_table()</script>
+</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 & Other Information:</b><br />
+ <script>doc.terms</script>
+ </td>
+ <td>
+ <table cellspacing=0 width=100%><tbody>
+ <tr>
+ <td>Net Total</td>
+ <td></td>
+ <td width=38%><script>
+ fmt_money(doc.net_total)
+ </script></td>
+ </tr>
+ <tr><td colspan=3><script>si_std.print_other_charges()</script></td></tr>
+ <tr>
+ <td>Grand Total</td>
+ <td></td>
+ <td><script>
+ fmt_money(doc.grand_total_export)
+ </script></td>
+ </tr>
+ <tr style='font-weight: bold'>
+ <td>Rounded Total</td>
+ <td><script>doc.currency</script></td>
+ <td><script>
+ fmt_money(doc.rounded_total_export)
+ </script></td>
+ </tr>
+ </tbody></table>
+ <br /><b>In Words</b><br />
+ <i><script>doc.in_words_export</script></i>
+ </td>
+ </tr>
+ </tbody>
+ <tfoot>
+
+ </tfoot>
+ </table>
+</div>
diff --git a/erpnext/patches/print_formats/SalesOrderModern.html b/erpnext/patches/print_formats/SalesOrderModern.html
new file mode 100644
index 0000000..48b60f7
--- /dev/null
+++ b/erpnext/patches/print_formats/SalesOrderModern.html
@@ -0,0 +1,301 @@
+<!--
+ Sample Print Format for ERPNext
+ Please use at your own discretion
+ For suggestions and contributions:
+ https://github.com/webnotes/erpnext-print-templates
+
+ Freely usable under MIT license
+-->
+
+<!-- Style Settings -->
+<style>
+ /*
+ common style for whole page
+ This should include:
+ + page size related settings
+ + font family settings
+ + line spacing settings
+ */
+ @media screen {
+ body {
+ width: 8.3in;
+ }
+ }
+
+ html, body, div, span, td {
+ font-family: "Helvetica", "Arial", sans-serif;
+ font-size: 12px;
+ }
+
+ body {
+ padding: 10px;
+ margin: auto;
+ font-size: 12px;
+ line-height: 150%;
+ }
+
+ .common {
+ font-family: "Helvetica", "Arial", sans-serif !important;
+ font-size: 12px;
+ padding: 10px 0px;
+ }
+
+ table {
+ border-collapse: collapse;
+ width: 100%;
+ vertical-align: top;
+ border-style: none !important;
+ }
+
+ table td {
+ padding: 2px 0px;
+ border-style: none !important;
+ }
+
+ table h1, h2, h3, h4, h5, h6 {
+ padding: 0px;
+ margin: 0px;
+ }
+
+ table.header-table td {
+ vertical-align: top;
+ }
+
+ table.header-table h1 {
+ text-transform: uppercase;
+ color: white;
+ font-size: 55px;
+ font-style: italic;
+ }
+
+ table.header-table thead tr:nth-child(1) div {
+ height: 24px;
+ background-color: #696969;
+ vertical-align: middle;
+ padding: 12px 0px 0px 0px;
+ width: 100%;
+ }
+
+ div.page-body table td:nth-child(6),
+ div.page-body table td:nth-child(7) {
+ text-align: right;
+ }
+
+ div.page-body table tr td {
+ background-color: #DCDCDC !important;
+ }
+
+ div.page-body table tr:nth-child(1) td {
+ background-color: #696969 !important;
+ color: white !important;
+ }
+
+ table.footer-table td {
+ vertical-align: top;
+ }
+
+ table.footer-table td table td:nth-child(2),
+ table.footer-table td table td:nth-child(3) {
+ text-align: right;
+ }
+
+ table.footer-table tfoot td {
+ background-color: #696969;
+ height: 10px;
+ }
+
+ .imp-details {
+ background-color: #DCDCDC;
+ }
+</style>
+
+
+<!-- Javascript -->
+<script>
+ si_std = {
+ print_item_table: function() {
+ var table = print_table(
+ 'Sales Order',
+ doc.name,
+ 'sales_order_details',
+ 'Sales Order Detail',
+ [// Here specify the table columns to be displayed
+ 'SR', 'item_code', 'description', 'qty', 'stock_uom',
+ 'basic_rate', 'amount'
+ ],
+ [// Here specify the labels of column headings
+ 'Sr', 'Item Code', 'Description', 'Qty',
+ 'UoM', 'Basic Rate', 'Amount'
+ ],
+ [// Here specify the column widths
+ '3%', '20%', '37%', '5%',
+ '5%', '15%', '15%'
+ ],
+ null,
+ null,
+ {
+ 'description' : function(data_row) {
+ if(data_row.adj_rate) {
+ var to_append = '<div style="padding-left: 15px;"><i>Discount: ' +
+ data_row.adj_rate + '%</i></div>';
+ if(data_row.description.indexOf(to_append)==-1) {
+ return data_row.description + to_append;
+ } else { return data_row.description; }
+ } else {
+ return data_row.description;
+ }
+ }
+ }
+ );
+
+ // This code takes care of page breaks
+ if(table.appendChild) {
+ out = table.innerHTML;
+ } else {
+ out = '';
+ for(var i=0; i < (table.length-1); i++) {
+ out += table[i].innerHTML +
+ '<div style = "page-break-after: always;" \
+ class = "page_break"></div>\
+ <div class="page-settings"></div>';
+ }
+ out += table[table.length-1].innerHTML;
+ }
+ return out;
+ },
+
+
+ print_other_charges: function(parent) {
+ var oc = getchildren('RV Tax Detail', doc.name, 'other_charges');
+ var rows = '<table width=100%>\n';
+ for(var i=0; i<oc.length; i++) {
+ rows +=
+ '<tr>\n' +
+ '\t<td>' + oc[i].description + '</td>\n' +
+ '\t<td></td>\n' +
+ '\t<td width=38%>' + fmt_money(oc[i].tax_amount) + '</td>\n' +
+ '</tr>\n';
+ }
+ return rows + '</table>\n';
+ }
+ };
+</script>
+
+
+<!-- Page Layout Settings -->
+<div class='common page-header'>
+ <!--
+ Page Header will contain
+ + table 1
+ + table 1a
+ - Name
+ - Address
+ - Contact
+ - Mobile No
+ + table 1b
+ - Voucher Date
+ - Due Date
+ -->
+ <table class='header-table' cellspacing=0>
+ <thead>
+ <tr><td colspan=2><div><script>'<h1>' + (doc.select_print_heading || 'Sales Order') + '</h1>'</script></div></td></tr>
+ <tr><td colspan=2><div style="height:15px"></div></td></tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td width=60%><table width=100% cellspacing=0><tbody>
+ <tr>
+ <td width=39%><b>Name</b></td>
+ <td><script>doc.customer_name</script></td>
+ </tr>
+ <tr>
+ <td><b>Address</b></td>
+ <td><script>replace_newlines(doc.address_display)</script></td>
+ </tr>
+ <tr>
+ <td><b>Contact</b></td>
+ <td><script>doc.contact_display</script></td>
+ </tr>
+ </tbody></table></td>
+ <td><table width=100% cellspacing=0><tbody>
+ <tr class='imp-details'>
+ <td><b>Sales Order No.</b></td>
+ <td><script>cur_frm.docname</script></td>
+ </tr>
+ <tr>
+ <td width=63%><b>Sales Order Date</b></td>
+ <td><script>date.str_to_user(doc.transaction_date)</script></td>
+ <tr>
+ <tr>
+ <td><b>Delivery Date</b></td>
+ <td><script>date.str_to_user(doc.delivery_date)</script></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
+ -->
+ <script>si_std.print_item_table()</script>
+</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 & Other Information:</b><br />
+ <script>doc.terms</script>
+ </td>
+ <td>
+ <table cellspacing=0 width=100%><tbody>
+ <tr>
+ <td>Net Total</td>
+ <td></td>
+ <td width=38%><script>
+ fmt_money(doc.net_total)
+ </script></td>
+ </tr>
+ <tr><td colspan=3><script>si_std.print_other_charges()</script></td></tr>
+ <tr>
+ <td>Grand Total</td>
+ <td></td>
+ <td><script>
+ fmt_money(doc.grand_total_export)
+ </script></td>
+ </tr>
+ <tr style='font-weight: bold' class='imp-details'>
+ <td>Rounded Total</td>
+ <td><script>doc.currency</script></td>
+ <td><script>
+ fmt_money(doc.rounded_total_export)
+ </script></td>
+ </tr>
+ </tbody></table>
+ <br /><b>In Words</b><br />
+ <i><script>doc.in_words_export</script></i>
+ </td>
+ </tr>
+ </tbody>
+ <tfoot>
+ <tr><td colspan=2><div></div></td><tr>
+ </tfoot>
+ </table>
+</div>
diff --git a/erpnext/patches/print_formats/SalesOrderSpartan.html b/erpnext/patches/print_formats/SalesOrderSpartan.html
new file mode 100644
index 0000000..b3fce74
--- /dev/null
+++ b/erpnext/patches/print_formats/SalesOrderSpartan.html
@@ -0,0 +1,296 @@
+<!--
+ Sample Print Format for ERPNext
+ Please use at your own discretion
+ For suggestions and contributions:
+ https://github.com/webnotes/erpnext-print-templates
+
+ Freely usable under MIT license
+-->
+
+<!-- Style Settings -->
+<style>
+ /*
+ common style for whole page
+ This should include:
+ + page size related settings
+ + font family settings
+ + line spacing settings
+ */
+ @media screen {
+ body {
+ width: 8.3in;
+ }
+ }
+
+ html, body, div, span, td {
+ font-family: "Arial", sans-serif;
+ font-size: 12px;
+ }
+
+ body {
+ padding: 10px;
+ margin: auto;
+ font-size: 12px;
+ line-height: 150%;
+ }
+
+ .common {
+ font-family: "Arial", sans-serif !important;
+ font-size: 12px;
+ padding: 0px;
+ }
+
+ table {
+ width: 100% !important;
+ vertical-align: top;
+ }
+
+ table td {
+ padding: 2px 0px;
+ }
+
+ table, td {
+ border-collapse: collapse !important;
+ padding: 0px;
+ margin: 0px !important;
+ }
+
+ table h1, h2, h3, h4, h5, h6 {
+ padding: 0px;
+ margin: 0px;
+ }
+
+ table.header-table td {
+ vertical-align: top;
+ }
+
+ table.header-table h3 {
+ color: gray;
+ }
+
+ table.header-table thead td {
+ padding: 5px;
+ }
+
+ table.header-table > thead,
+ table.header-table > tbody > tr > td,
+ table.footer-table > tbody > tr > td {
+ border: 1px solid black;
+ padding: 5px;
+ }
+
+ table.footer-table > tbody,
+ table.header-table > thead {
+ border-bottom: 3px solid black;
+ }
+
+ table.header-table > thead {
+ border-top: 3px solid black;
+ }
+
+ div.page-body table td:nth-child(6),
+ div.page-body table td:nth-child(7) {
+ text-align: right;
+ }
+
+ div.page-body td {
+ background-color: white !important;
+ border: 1px solid black !important;
+ }
+
+ table.footer-table td {
+ vertical-align: top;
+ }
+
+ table.footer-table td table td:nth-child(2),
+ table.footer-table td table td:nth-child(3) {
+ text-align: right;
+ }
+</style>
+
+
+<!-- Javascript -->
+<script>
+ si_std = {
+ print_item_table: function() {
+ var table = print_table(
+ 'Sales Order',
+ doc.name,
+ 'sales_order_details',
+ 'Sales Order Detail',
+ [// Here specify the table columns to be displayed
+ 'SR', 'item_code', 'description', 'qty', 'stock_uom',
+ 'basic_rate', 'amount'
+ ],
+ [// Here specify the labels of column headings
+ 'Sr', 'Item Code', 'Description', 'Qty',
+ 'UoM', 'Basic Rate', 'Amount'
+ ],
+ [// Here specify the column widths
+ '3%', '20%', '37%', '5%',
+ '5%', '15%', '15%'
+ ],
+ null,
+ null,
+ {
+ 'description' : function(data_row) {
+ if(data_row.adj_rate) {
+ var to_append = '<div style="padding-left: 15px;"><i>Discount: ' +
+ data_row.adj_rate + '%</i></div>';
+ if(data_row.description.indexOf(to_append)==-1) {
+ return data_row.description + to_append;
+ } else { return data_row.description; }
+ } else {
+ return data_row.description;
+ }
+ }
+ }
+ );
+
+ // This code takes care of page breaks
+ if(table.appendChild) {
+ out = table.innerHTML;
+ } else {
+ out = '';
+ for(var i=0; i < (table.length-1); i++) {
+ out += table[i].innerHTML +
+ '<div style = "page-break-after: always;" \
+ class = "page_break"></div>\
+ <div class="page-settings"></div>';
+ }
+ out += table[table.length-1].innerHTML;
+ }
+ return out;
+ },
+
+
+ print_other_charges: function(parent) {
+ var oc = getchildren('RV Tax Detail', doc.name, 'other_charges');
+ var rows = '<table width=100%>\n';
+ for(var i=0; i<oc.length; i++) {
+ rows +=
+ '<tr>\n' +
+ '\t<td>' + oc[i].description + '</td>\n' +
+ '\t<td></td>\n' +
+ '\t<td width=38%>' + fmt_money(oc[i].tax_amount) + '</td>\n' +
+ '</tr>\n';
+ }
+ return rows + '</table>\n';
+ }
+ };
+</script>
+
+
+<!-- Page Layout Settings -->
+<div class='common page-header'>
+ <!--
+ Page Header will contain
+ + table 1
+ + table 1a
+ - Name
+ - Address
+ - Contact
+ - Mobile No
+ + table 1b
+ - Voucher Date
+ - Due Date
+ -->
+ <table class='header-table' cellspacing=0>
+ <thead>
+ <tr><td colspan=2><script>'<h1>' + (doc.select_print_heading || 'Sales Order') + '</h1>'</script></td></tr>
+ <tr><td colspan=2><h3><script>cur_frm.docname</script></h3></td></tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td width=60%><table width=100% cellspacing=0><tbody>
+ <tr>
+ <td width=39%><b>Name</b></td>
+ <td><script>doc.customer_name</script></td>
+ </tr>
+ <tr>
+ <td><b>Address</b></td>
+ <td><script>replace_newlines(doc.address_display)</script></td>
+ </tr>
+ <tr>
+ <td><b>Contact</b></td>
+ <td><script>doc.contact_display</script></td>
+ </tr>
+ </tbody></table></td>
+ <td><table width=100% cellspacing=0><tbody>
+ <tr>
+ <td width=63%><b>Sales Order Date</b></td>
+ <td><script>date.str_to_user(doc.transaction_date)</script></td>
+ <tr>
+ <tr>
+ <td><b>Delivery Date</b></td>
+ <td><script>date.str_to_user(doc.delivery_date)</script></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
+ -->
+ <script>si_std.print_item_table()</script>
+</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 & Other Information:</b><br />
+ <script>doc.terms</script>
+ </td>
+ <td>
+ <table cellspacing=0 width=100%><tbody>
+ <tr>
+ <td>Net Total</td>
+ <td></td>
+ <td width=38%><script>
+ fmt_money(doc.net_total)
+ </script></td>
+ </tr>
+ <tr><td colspan=3><script>si_std.print_other_charges()</script></td></tr>
+ <tr>
+ <td>Grand Total</td>
+ <td></td>
+ <td><script>
+ fmt_money(doc.grand_total_export)
+ </script></td>
+ </tr>
+ <tr style='font-weight: bold'>
+ <td>Rounded Total</td>
+ <td><script>doc.currency</script></td>
+ <td><script>
+ fmt_money(doc.rounded_total_export)
+ </script></td>
+ </tr>
+ </tbody></table>
+ <br /><b>In Words</b><br />
+ <i><script>doc.in_words_export</script></i>
+ </td>
+ </tr>
+ </tbody>
+ <tfoot>
+
+ </tfoot>
+ </table>
+</div>
diff --git a/erpnext/patches/print_hide_price_list.py b/erpnext/patches/print_hide_price_list.py
new file mode 100644
index 0000000..833ab98
--- /dev/null
+++ b/erpnext/patches/print_hide_price_list.py
@@ -0,0 +1,3 @@
+def execute():
+ import webnotes
+ webnotes.conn.sql("update `tabDocField` set print_hide = 1 where fieldname in ('price_list_currency', 'plc_conversion_rate')")
diff --git a/erpnext/patches/profile_mark_not_in_create.py b/erpnext/patches/profile_mark_not_in_create.py
new file mode 100644
index 0000000..8d25047
--- /dev/null
+++ b/erpnext/patches/profile_mark_not_in_create.py
@@ -0,0 +1,10 @@
+import webnotes
+def execute():
+ """
+ Mark DocType Profile as 'not_in_create'
+ """
+ webnotes.conn.sql("""
+ UPDATE `tabDocType`
+ SET in_create=1
+ WHERE name='Profile'
+ """)
diff --git a/erpnext/patches/project_patch.py b/erpnext/patches/project_patch.py
new file mode 100644
index 0000000..c5473a0
--- /dev/null
+++ b/erpnext/patches/project_patch.py
@@ -0,0 +1,18 @@
+def execute():
+ import webnotes
+ from webnotes.modules.module_manager import reload_doc
+ sql = webnotes.conn.sql
+
+ # Reload item table
+ reload_doc('accounts', 'doctype', 'pv_detail')
+ reload_doc('buying', 'doctype', 'po_detail')
+ reload_doc('stock', 'doctype', 'purchase_receipt_detail')
+
+ # copy project value from parent to child
+ sql("update `tabPO Detail` t1, `tabPurchase Order` t2 set t1.project_name = t2.project_name where t1.parent = t2.name and ifnull(t1.project_name, '') = ''")
+ sql("update `tabPV Detail` t1, `tabPayable Voucher` t2 set t1.project_name = t2.project_name where t1.parent = t2.name and ifnull(t1.project_name, '') = ''")
+ sql("update `tabPurchase Receipt Detail` t1, `tabPurchase Receipt` t2 set t1.project_name = t2.project_name where t1.parent = t2.name and ifnull(t1.project_name, '') = ''")
+
+ # delete project from parent
+ sql("delete from `tabDocField` where fieldname = 'project_name' and parent in ('Purchase Order', 'Purchase Receipt', 'Payable Voucher')")
+
diff --git a/erpnext/patches/reload_address.py b/erpnext/patches/reload_address.py
new file mode 100644
index 0000000..252339b
--- /dev/null
+++ b/erpnext/patches/reload_address.py
@@ -0,0 +1,5 @@
+def execute():
+ import webnotes
+ from webnotes.modules.module_manager import reload_doc
+
+ reload_doc('utilities', 'doctype', 'address')
diff --git a/erpnext/patches/reload_bom.py b/erpnext/patches/reload_bom.py
new file mode 100644
index 0000000..f050f3c
--- /dev/null
+++ b/erpnext/patches/reload_bom.py
@@ -0,0 +1,5 @@
+def execute():
+ import webnotes
+ from webnotes.modules.module_manager import reload_doc
+
+ reload_doc('production', 'doctype', 'bill_of_materials')
diff --git a/erpnext/patches/reload_doclayer.py b/erpnext/patches/reload_doclayer.py
new file mode 100644
index 0000000..8ee4919
--- /dev/null
+++ b/erpnext/patches/reload_doclayer.py
@@ -0,0 +1,16 @@
+"""
+ Reload DocLayer, DocLayerField and Print Format doctypes
+"""
+def execute():
+ from webnotes.modules.module_manager import reload_doc
+ reload_doc('core', 'doctype', 'print_format')
+ reload_doc('core', 'doctype', 'doclayer')
+ reload_doc('core', 'doctype', 'doclayerfield')
+ reload_doc('accounts', 'doctype', 'gl_entry')
+ from webnotes.model.doc import Document
+ d = Document('DocType Label')
+ d.dt = "DocLayer"
+ d.dt_label = "Customize Form View"
+ d.save(1)
+ from webnotes.session_cache import clear
+ clear()
diff --git a/erpnext/patches/reload_email_digest.py b/erpnext/patches/reload_email_digest.py
new file mode 100644
index 0000000..2890254
--- /dev/null
+++ b/erpnext/patches/reload_email_digest.py
@@ -0,0 +1,3 @@
+def execute():
+ from webnotes.modules.module_manager import reload_doc
+ reload_doc('Setup', 'DocType', 'Email Digest')
diff --git a/erpnext/patches/reload_employeewise_balance_leave_report.py b/erpnext/patches/reload_employeewise_balance_leave_report.py
new file mode 100644
index 0000000..b03b44b
--- /dev/null
+++ b/erpnext/patches/reload_employeewise_balance_leave_report.py
@@ -0,0 +1,4 @@
+def execute():
+ import webnotes
+ from webnotes.modules.module_manager import reload_doc
+ reload_doc('hr', 'search_criteria', 'employeewise_balance_leave_report')
diff --git a/erpnext/patches/reload_flat_bom.py b/erpnext/patches/reload_flat_bom.py
new file mode 100644
index 0000000..b493610
--- /dev/null
+++ b/erpnext/patches/reload_flat_bom.py
@@ -0,0 +1,6 @@
+def execute():
+ from webnotes.modules import webnotes
+ from webnotes.modules.module_manager import reload_doc
+
+ reload_doc('production', 'doctype', 'flat_bom_detail')
+ reload_doc('production', 'doctype', 'bom_material')
diff --git a/erpnext/patches/reload_gl_mapper.py b/erpnext/patches/reload_gl_mapper.py
new file mode 100644
index 0000000..edb00bc
--- /dev/null
+++ b/erpnext/patches/reload_gl_mapper.py
@@ -0,0 +1,6 @@
+def execute():
+ import webnotes
+ from webnotes.modules.module_manager import reload_doc
+
+ # reload jv gl mapper
+ reload_doc('accounts', 'GL Mapper', 'Journal Voucher')
diff --git a/erpnext/patches/reload_lc_wizard.py b/erpnext/patches/reload_lc_wizard.py
new file mode 100644
index 0000000..6b8565e
--- /dev/null
+++ b/erpnext/patches/reload_lc_wizard.py
@@ -0,0 +1,9 @@
+def execute():
+ import webnotes
+ from webnotes.modules.module_manager import reload_doc
+ from webnotes.model import delete_doc
+
+ delete_doc('DocType', 'Landed Cost Wizard')
+ delete_doc('DocType', 'LC PR Detail')
+ reload_doc('stock', 'doctype', 'landed_cost_wizard')
+ reload_doc('stock', 'doctype', 'lc_pr_detail')
diff --git a/erpnext/patches/reload_print_format.py b/erpnext/patches/reload_print_format.py
new file mode 100644
index 0000000..e3c6adf
--- /dev/null
+++ b/erpnext/patches/reload_print_format.py
@@ -0,0 +1,17 @@
+def execute():
+ import webnotes
+ from webnotes.modules.module_manager import reload_doc
+ from webnotes.model.doc import addchild
+ from webnotes.model.code import get_obj
+ reload_doc('stock', 'Print Format', 'Delivery Note Packing List Wise')
+ reload_doc('stock', 'Print Format', 'Purchase Receipt Format')
+ reload_doc('accounts', 'Print Format', 'Payment Receipt Voucher')
+ reload_doc('accounts', 'Print Format', 'POS Invoice')
+ reload_doc('accounts', 'Print Format', 'Form 16A Print Format')
+ reload_doc('accounts', 'Print Format', 'Cheque Printing Format')
+
+ if not webnotes.conn.sql("select format from `tabDocFormat` where name = 'POS Invoice' and parent = 'Receivable Voucher'"):
+ dt_obj = get_obj('DocType', 'Receivable Voucher', with_children = 1)
+ ch = addchild(dt_obj.doc, 'formats', 'DocFormat', 1)
+ ch.format = 'POS Invoice'
+ ch.save(1)
diff --git a/erpnext/patches/reload_project_task.py b/erpnext/patches/reload_project_task.py
new file mode 100644
index 0000000..019a177
--- /dev/null
+++ b/erpnext/patches/reload_project_task.py
@@ -0,0 +1,7 @@
+"""
+ Reload Task Doctype of Project Module
+"""
+def execute():
+ from webnotes.modules.module_manager import reload_doc
+ reload_doc('Projects', 'DocType', 'Ticket')
+
diff --git a/erpnext/patches/reload_reco.py b/erpnext/patches/reload_reco.py
new file mode 100644
index 0000000..6b9ecc4
--- /dev/null
+++ b/erpnext/patches/reload_reco.py
@@ -0,0 +1,6 @@
+def execute():
+ import webnotes
+ from webnotes.modules.module_manager import reload_doc
+
+ reload_doc('stock', 'doctype', 'stock_reconciliation')
+ webnotes.conn.sql("delete from `tabDocField` where (label in ('Validate Data', 'Attachment HTML', 'Attachment') or fieldname in ('next_step', 'company', 'fiscal_year', 'amendment_date')) and parent = 'Stock Reconciliation'")
diff --git a/erpnext/patches/reload_rv.py b/erpnext/patches/reload_rv.py
new file mode 100644
index 0000000..7b47b4c
--- /dev/null
+++ b/erpnext/patches/reload_rv.py
@@ -0,0 +1,9 @@
+def execute():
+ import webnotes
+ from webnotes.modules.module_manager import reload_doc
+ from webnotes.model.code import get_obj
+
+ reload_doc('accounts', 'doctype', 'receivable_voucher')
+
+ reload_doc('setup', 'doctype', 'features_setup')
+ get_obj('Features setup').validate()
diff --git a/erpnext/patches/reload_support_ticket.py b/erpnext/patches/reload_support_ticket.py
new file mode 100644
index 0000000..85145bd
--- /dev/null
+++ b/erpnext/patches/reload_support_ticket.py
@@ -0,0 +1,6 @@
+def execute():
+ import webnotes
+ from webnotes.modules.module_manager import reload_doc
+ reload_doc('Support', 'DocType', 'Support Ticket')
+ from webnotes.model.code import get_obj
+ get_obj('DocType', 'Support Ticket').validate()
diff --git a/erpnext/patches/remove_duplicate_table_mapper_detail.py b/erpnext/patches/remove_duplicate_table_mapper_detail.py
new file mode 100644
index 0000000..aaddd99
--- /dev/null
+++ b/erpnext/patches/remove_duplicate_table_mapper_detail.py
@@ -0,0 +1,22 @@
+"""
+ Removes duplicate entries created in
+"""
+import webnotes
+def execute():
+ res = webnotes.conn.sql("""\
+ SELECT a.name
+ FROM
+ `tabTable Mapper Detail` a,
+ `tabTable Mapper Detail` b
+ WHERE
+ a.parent = b.parent AND
+ a.from_table = b.from_table AND
+ a.to_table = b.to_table AND
+ a.from_field = b.from_field AND
+ a.to_field = b.to_field AND
+ a.name < b.name""")
+ if res and len(res)>0:
+ name_string = ", ".join(["'" + str(r[0]) + "'" for r in res])
+ res = webnotes.conn.sql("""\
+ DELETE FROM `tabTable Mapper Detail`
+ WHERE name IN (%s)""" % name_string)
diff --git a/erpnext/patches/remove_extra_button_from_email_digest.py b/erpnext/patches/remove_extra_button_from_email_digest.py
new file mode 100644
index 0000000..7005db9
--- /dev/null
+++ b/erpnext/patches/remove_extra_button_from_email_digest.py
@@ -0,0 +1,8 @@
+def execute():
+ import webnotes
+ webnotes.conn.sql("""
+ DELETE FROM tabDocField
+ WHERE parent = 'Email Digest'
+ AND label = 'Add Recipients'
+ AND fieldtype = 'Button'""")
+
diff --git a/erpnext/patches/remove_old_cp_email_settings.py b/erpnext/patches/remove_old_cp_email_settings.py
new file mode 100644
index 0000000..5736c9c
--- /dev/null
+++ b/erpnext/patches/remove_old_cp_email_settings.py
@@ -0,0 +1,15 @@
+def execute():
+ """
+ remove control panel email settings if automail.webnotestech.com
+ """
+ from webnotes.model.doc import Document
+ cp = Document('Control Panel', 'Control Panel')
+ if cp:
+ if cp.outgoing_mail_server == 'mail.webnotestech.com':
+ cp.outgoing_mail_server = None;
+ cp.mail_login = None;
+ cp.mail_password = None;
+ cp.mail_port = None;
+ cp.auto_email_id = 'automail@erpnext.com'
+ cp.save()
+
diff --git a/erpnext/patches/remove_page_break_from_defaults.py b/erpnext/patches/remove_page_break_from_defaults.py
new file mode 100644
index 0000000..8d842e3
--- /dev/null
+++ b/erpnext/patches/remove_page_break_from_defaults.py
@@ -0,0 +1,3 @@
+def execute():
+ import webnotes
+ webnotes.conn.sql("""delete from `tabDefaultValue` where defkey in ('page_break', 'projects', 'packing_details', 'discounts', 'brands', 'item_batch_nos', 'after_sales_installations', 'item_searial_nos', 'item_group_in_details', 'exports', 'imports', 'item_advanced', 'sales_extras', 'more_info', 'quality', 'manufacturing', 'pos', 'item_serial_nos', 'purchase_discounts', 'recurring_invoice') and parent = 'Control Panel'""")
diff --git a/erpnext/patches/remove_previous_field_property_setter.py b/erpnext/patches/remove_previous_field_property_setter.py
new file mode 100644
index 0000000..677188e
--- /dev/null
+++ b/erpnext/patches/remove_previous_field_property_setter.py
@@ -0,0 +1,6 @@
+import webnotes
+def execute():
+ webnotes.conn.sql("""\
+ DELETE FROM `tabProperty Setter`
+ WHERE property='previous_field'
+ """)
diff --git a/erpnext/patches/repost_account_bal.py b/erpnext/patches/repost_account_bal.py
new file mode 100644
index 0000000..34edc04
--- /dev/null
+++ b/erpnext/patches/repost_account_bal.py
@@ -0,0 +1,31 @@
+
+def execute():
+ import webnotes
+ sql = webnotes.conn.sql
+ from webnotes.model.code import get_obj
+
+ # stop session
+ webnotes.conn.set_global('__session_status', 'stop')
+ webnotes.conn.set_global('__session_status_message', 'Patch is running in background. \nPlease wait until it completed...\n')
+
+ webnotes.conn.commit()
+ webnotes.conn.begin()
+
+ # repost
+ comp = sql("select name from tabCompany where docstatus!=2")
+ fy = sql("select name from `tabFiscal Year` order by year_start_date asc")
+ for c in comp:
+ prev_fy = ''
+ for f in fy:
+ fy_obj = get_obj('Fiscal Year', f[0])
+ fy_obj.doc.past_year = prev_fy
+ fy_obj.doc.company = c[0]
+ fy_obj.doc.save()
+ fy_obj.repost()
+ prev_fy = f[0]
+ sql("commit")
+ sql("start transaction")
+
+ # free session
+ webnotes.conn.set_global('__session_status', '')
+ webnotes.conn.set_global('__session_status_message', '')
diff --git a/erpnext/patches/repost_stock.py b/erpnext/patches/repost_stock.py
new file mode 100644
index 0000000..a19494c
--- /dev/null
+++ b/erpnext/patches/repost_stock.py
@@ -0,0 +1,23 @@
+def execute():
+ import webnotes
+ sql = webnotes.conn.sql
+ from webnotes.model.code import get_obj
+ from webnotes.utils import flt
+
+ # update incoming rate in serial nos
+ sr = sql("""select name, item_code, purchase_document_no from `tabSerial No`
+ where docstatus = 1 and purchase_document_type = 'Purchase Receipt'""")
+ for d in sr:
+ val_rate = sql("""select valuation_rate from `tabPurchase Receipt Detail`
+ where item_code = %s and parent = %s""", (d[1], d[2]))
+ sql("""update `tabSerial No` set purchase_rate = %s where name = %s""",
+ (val_rate and flt(val_rate[0][0]) or 0, d[0]))
+
+
+ # repost for all serialized item
+ bin = sql("""select t1.name from `tabBin` t1, tabItem t2 where t1.item_code = t2.name and ifnull(has_serial_no, 'No') = 'Yes'""")
+ for d in bin:
+ get_obj('Bin', d[0]).update_entries_after(posting_date = '2000-01-01', posting_time = '12:00')
+ sql("commit")
+ sql("start transaction")
+
diff --git a/erpnext/patches/sal_man_patch.py b/erpnext/patches/sal_man_patch.py
new file mode 100644
index 0000000..aef6251
--- /dev/null
+++ b/erpnext/patches/sal_man_patch.py
@@ -0,0 +1,8 @@
+
+def execute():
+ import webnotes
+ from webnotes.modules.module_manager import reload_doc
+ sql = webnotes.conn.sql
+
+ reload_doc('hr', 'doctype', 'salary_manager')
+ sql("delete from `tabDocField` where parent = 'Salary Manager' and fieldname = 'employment_type'")
diff --git a/erpnext/patches/task_email_notification.py b/erpnext/patches/task_email_notification.py
new file mode 100644
index 0000000..e6a7afa
--- /dev/null
+++ b/erpnext/patches/task_email_notification.py
@@ -0,0 +1,4 @@
+def execute():
+ import webnotes
+ from webnotes.modules.module_manager import reload_doc
+ reload_doc('projects', 'doctype', 'ticket')
diff --git a/erpnext/patches/update_0_idx.py b/erpnext/patches/update_0_idx.py
new file mode 100644
index 0000000..9c31f1d
--- /dev/null
+++ b/erpnext/patches/update_0_idx.py
@@ -0,0 +1,9 @@
+import webnotes
+def execute():
+ doc_type_list = webnotes.conn.sql("""SELECT DISTINCT parent FROM `tabDocField` where idx=0""")
+ for doc_type in doc_type_list:
+ if doc_type and doc_type[0]:
+ webnotes.conn.sql("""\
+ UPDATE `tabDocField` SET idx=idx+1
+ WHERE parent=%s
+ """, doc_type[0])
diff --git a/erpnext/patches/update_gle_against_voucher_for_jv.py b/erpnext/patches/update_gle_against_voucher_for_jv.py
new file mode 100644
index 0000000..5a03ec7
--- /dev/null
+++ b/erpnext/patches/update_gle_against_voucher_for_jv.py
@@ -0,0 +1,15 @@
+def execute():
+ import webnotes
+ from webnotes.model.code import get_obj
+
+ # select jv where against_jv exists
+ jv = webnotes.conn.sql("select distinct parent from `tabJournal Voucher Detail` where docstatus = 1 and ifnull(against_jv, '') != ''")
+
+ for d in jv:
+ jv_obj = get_obj('Journal Voucher', d[0], with_children=1)
+
+ # cancel
+ get_obj(dt='GL Control').make_gl_entries(jv_obj.doc, jv_obj.doclist, cancel =1, adv_adj = 1)
+
+ #re-submit
+ get_obj(dt='GL Control').make_gl_entries(jv_obj.doc, jv_obj.doclist, cancel =0, adv_adj = 1)
diff --git a/erpnext/production/doctype/bill_of_materials/bill_of_materials.py b/erpnext/production/doctype/bill_of_materials/bill_of_materials.py
index 9fcfb81..a62e4f2 100644
--- a/erpnext/production/doctype/bill_of_materials/bill_of_materials.py
+++ b/erpnext/production/doctype/bill_of_materials/bill_of_materials.py
@@ -32,9 +32,10 @@
#----------- Client Trigger function ----------
def get_item_detail(self, item_code):
- item = sql("select description from `tabItem` where (ifnull(end_of_life,'')='' or end_of_life = '0000-00-00' or end_of_life > now()) and name = %s",item_code , as_dict =1)
+ item = sql("select description, stock_uom from `tabItem` where (ifnull(end_of_life,'')='' or end_of_life = '0000-00-00' or end_of_life > now()) and name = %s",item_code , as_dict =1)
ret={
- 'description' : item and item[0]['description'] or ''
+ 'description' : item and item[0]['description'] or '',
+ 'uom' : item and item[0]['stock_uom'] or ''
}
return ret
@@ -411,8 +412,8 @@
if val_method == 'FIFO':
if warehouse:
bin_obj = get_obj('Warehouse',warehouse).get_bin(item_code)
- prev_sle = bin_obj.get_prev_sle('',nowdate(), (now().split(' ')[1])[:-3])
- fcfs_stack = prev_sle and (prev_sle[0][3] and eval(prev_sle[0][3]) or []) or []
+ prev_sle = bin_obj.get_prev_sle(nowdate(), (now().split(' ')[1])[:-3])
+ fcfs_stack = prev_sle and prev_sle['fcfs_stack'] and eval(prev_sle['fcfs_stack']) or []
else:
prev_sle = sql("select fcfs_stack from `tabStock Ledger Entry` where item_code = '%s' and posting_date <= '%s' order by posting_date DESC, posting_time DESC, name DESC limit 1" % (item_code, nowdate()))
fcfs_stack = prev_sle and (prev_sle[0][0] and eval(prev_sle[0][0]) or []) or []
@@ -499,20 +500,11 @@
def get_child_flat_bom_items(self, item, d):
child_flat_bom_items=[]
-# if item and (item[0]['is_sub_contracted_item'] == 'Yes' or item[0]['is_pro_applicable'] == 'Yes'):
child_flat_bom_items = sql("select fbom.item_code, fbom.description, fbom.qty_consumed_per_unit, fbom.stock_uom, fbom.moving_avg_rate, fbom.last_purchase_rate, fbom.standard_rate, '%s' as parent_bom, fbom.bom_mat_no, 'No' as is_pro_applicable from `tabFlat BOM Detail` fbom,`tabBill Of Materials` bom where fbom.parent=bom.name and fbom.parent = '%s' and fbom.is_pro_applicable = 'No' and bom.docstatus = 1" % ( d.bom_no, cstr(d.bom_no)))
self.cur_flat_bom_items.append([d.item_code, d.description, flt(d.qty), d.stock_uom, flt(d.moving_avg_rate), flt(d.amount_as_per_mar), flt(d.last_purchase_rate), flt(d.amount_as_per_lpr), flt(d.standard_rate), flt(d.amount_as_per_sr), flt(d.qty_consumed_per_unit), (item[0]['is_sub_contracted_item'] == 'Yes') and d.parent or d.bom_no, d.name, (item[0]['is_sub_contracted_item'] == 'Yes') and 'No' or 'Yes'])
return child_flat_bom_items
-# else:
-# child_flat_bom_items = sql("select item_code, description, qty_consumed_per_unit, stock_uom, moving_avg_rate, last_purchase_rate, standard_rate, if(parent_bom = '%s', '%s', parent_bom) as parent_bom, bom_mat_no, is_pro_applicable from `tabFlat BOM Detail` where parent = '%s' and docstatus = 1" % ( d.bom_no, d.parent, cstr(d.bom_no)))
-
-# if not child_flat_bom_items:
-# msgprint("Please Submit Child BOM := %s first." % cstr(d.bom_no))
-# raise Exception
-# else:"""
-
# Get Current Flat BOM Items
# -----------------------------
diff --git a/erpnext/production/doctype/bill_of_materials/bill_of_materials.txt b/erpnext/production/doctype/bill_of_materials/bill_of_materials.txt
index 2590817..3713667 100644
--- a/erpnext/production/doctype/bill_of_materials/bill_of_materials.txt
+++ b/erpnext/production/doctype/bill_of_materials/bill_of_materials.txt
@@ -5,14 +5,14 @@
{
'creation': '2010-08-08 17:08:52',
'docstatus': 0,
- 'modified': '2010-12-20 17:27:58',
- 'modified_by': 'umair@iwebnotes.com',
+ 'modified': '2011-11-09 12:47:50',
+ 'modified_by': 'Administrator',
'owner': 'Administrator'
},
# These values are common for all DocType
{
- '_last_update': '1309508837',
+ '_last_update': '1319016431',
'allow_attach': 0,
'allow_copy': 0,
'allow_email': 0,
@@ -20,6 +20,7 @@
'allow_rename': 0,
'allow_trash': 1,
'colour': 'White:FFF',
+ 'default_print_format': 'Standard',
'doctype': 'DocType',
'document_type': 'Master',
'hide_heading': 0,
@@ -35,7 +36,7 @@
'server_code_error': ' ',
'show_in_menu': 0,
'subject': '%(item)s',
- 'version': 170
+ 'version': 171
},
# These values are common for all DocField
@@ -49,6 +50,7 @@
# These values are common for all DocPerm
{
+ 'amend': 0,
'doctype': 'DocPerm',
'name': '__common__',
'parent': 'Bill Of Materials',
@@ -68,7 +70,6 @@
'cancel': 1,
'create': 1,
'doctype': 'DocPerm',
- 'idx': 1,
'permlevel': 0,
'role': 'System Manager',
'submit': 1,
@@ -77,10 +78,13 @@
# DocPerm
{
+ 'cancel': 0,
+ 'create': 0,
'doctype': 'DocPerm',
- 'idx': 2,
'permlevel': 1,
- 'role': 'System Manager'
+ 'role': 'System Manager',
+ 'submit': 0,
+ 'write': 0
},
# DocPerm
@@ -88,7 +92,6 @@
'cancel': 1,
'create': 1,
'doctype': 'DocPerm',
- 'idx': 3,
'permlevel': 0,
'role': 'Production Manager',
'submit': 1,
@@ -97,10 +100,13 @@
# DocPerm
{
+ 'cancel': 0,
+ 'create': 0,
'doctype': 'DocPerm',
- 'idx': 4,
'permlevel': 1,
- 'role': 'Production Manager'
+ 'role': 'Production Manager',
+ 'submit': 0,
+ 'write': 0
},
# DocPerm
@@ -108,7 +114,6 @@
'cancel': 1,
'create': 1,
'doctype': 'DocPerm',
- 'idx': 5,
'permlevel': 0,
'role': 'Production User',
'submit': 1,
@@ -117,10 +122,13 @@
# DocPerm
{
+ 'cancel': 0,
+ 'create': 0,
'doctype': 'DocPerm',
- 'idx': 6,
'permlevel': 1,
- 'role': 'Production User'
+ 'role': 'Production User',
+ 'submit': 0,
+ 'write': 0
},
# DocField
@@ -128,7 +136,6 @@
'doctype': 'DocField',
'fieldname': 'trash_reason',
'fieldtype': 'Small Text',
- 'idx': 1,
'label': 'Trash Reason',
'oldfieldname': 'trash_reason',
'oldfieldtype': 'Small Text',
@@ -139,7 +146,6 @@
{
'doctype': 'DocField',
'fieldtype': 'HTML',
- 'idx': 2,
'label': 'TreeView1',
'oldfieldtype': 'HTML',
'options': '<div style=\'border: 1px solid #CCF; padding: 8px;margin-bottom: 8px;\'><div class=\'link_type\' onclick=\'loadpage("Bill of Materials"); \'>Go To BOM Tree View</div></div>',
@@ -150,7 +156,6 @@
{
'doctype': 'DocField',
'fieldtype': 'Section Break',
- 'idx': 3,
'oldfieldtype': 'Section Break',
'options': 'Simple',
'permlevel': 0
@@ -162,7 +167,6 @@
'colour': 'White:FFF',
'doctype': 'DocField',
'fieldtype': 'Button',
- 'idx': 4,
'label': 'Set as Default BOM',
'oldfieldtype': 'Button',
'permlevel': 0,
@@ -173,7 +177,6 @@
{
'doctype': 'DocField',
'fieldtype': 'Column Break',
- 'idx': 5,
'oldfieldtype': 'Column Break',
'permlevel': 0
},
@@ -185,7 +188,6 @@
'doctype': 'DocField',
'fieldtype': 'Button',
'hidden': 1,
- 'idx': 6,
'label': 'Activate BOM',
'oldfieldtype': 'Button',
'permlevel': 0,
@@ -199,7 +201,6 @@
'doctype': 'DocField',
'fieldtype': 'Button',
'hidden': 1,
- 'idx': 7,
'label': 'Inactivate BOM',
'oldfieldtype': 'Button',
'permlevel': 0,
@@ -210,7 +211,6 @@
{
'doctype': 'DocField',
'fieldtype': 'Section Break',
- 'idx': 8,
'label': 'Details',
'oldfieldtype': 'Section Break',
'permlevel': 0
@@ -223,7 +223,6 @@
'doctype': 'DocField',
'fieldname': 'item',
'fieldtype': 'Link',
- 'idx': 9,
'in_filter': 1,
'label': 'Item',
'oldfieldname': 'item',
@@ -240,7 +239,6 @@
'doctype': 'DocField',
'fieldname': 'description',
'fieldtype': 'Text',
- 'idx': 10,
'label': 'Description',
'oldfieldname': 'description',
'oldfieldtype': 'Text',
@@ -255,7 +253,6 @@
'doctype': 'DocField',
'fieldname': 'quantity',
'fieldtype': 'Currency',
- 'idx': 11,
'label': 'Quantity',
'oldfieldname': 'quantity',
'oldfieldtype': 'Currency',
@@ -265,11 +262,20 @@
# DocField
{
+ 'doctype': 'DocField',
+ 'fieldname': 'uom',
+ 'fieldtype': 'Select',
+ 'label': 'UOM',
+ 'options': 'link:UOM',
+ 'permlevel': 1
+ },
+
+ # DocField
+ {
'colour': 'White:FFF',
'doctype': 'DocField',
'fieldname': 'is_active',
'fieldtype': 'Select',
- 'idx': 12,
'label': 'Is Active',
'no_copy': 1,
'oldfieldname': 'is_active',
@@ -285,7 +291,6 @@
'doctype': 'DocField',
'fieldname': 'is_default',
'fieldtype': 'Check',
- 'idx': 13,
'label': 'Is Default',
'no_copy': 1,
'oldfieldname': 'is_default',
@@ -299,7 +304,6 @@
'doctype': 'DocField',
'fieldname': 'project_name',
'fieldtype': 'Link',
- 'idx': 14,
'in_filter': 1,
'label': 'Project Name',
'oldfieldname': 'project_name',
@@ -313,7 +317,6 @@
{
'doctype': 'DocField',
'fieldtype': 'Section Break',
- 'idx': 15,
'label': 'Operations',
'oldfieldtype': 'Section Break',
'permlevel': 0
@@ -326,7 +329,6 @@
'doctype': 'DocField',
'fieldname': 'bom_operations',
'fieldtype': 'Table',
- 'idx': 16,
'label': 'BOM Operations',
'oldfieldname': 'bom_operations',
'oldfieldtype': 'Table',
@@ -338,7 +340,6 @@
{
'doctype': 'DocField',
'fieldtype': 'Section Break',
- 'idx': 17,
'label': 'Materials',
'oldfieldtype': 'Section Break',
'permlevel': 0
@@ -351,7 +352,6 @@
'doctype': 'DocField',
'fieldname': 'bom_materials',
'fieldtype': 'Table',
- 'idx': 18,
'label': 'BOM Material',
'oldfieldname': 'bom_materials',
'oldfieldtype': 'Table',
@@ -363,7 +363,6 @@
{
'doctype': 'DocField',
'fieldtype': 'Section Break',
- 'idx': 19,
'label': 'Costing',
'oldfieldtype': 'Section Break',
'permlevel': 0
@@ -375,7 +374,6 @@
'doctype': 'DocField',
'fieldname': 'remarks',
'fieldtype': 'Text',
- 'idx': 20,
'label': 'Remarks',
'no_copy': 1,
'oldfieldname': 'remarks',
@@ -388,7 +386,6 @@
'doctype': 'DocField',
'fieldname': 'cost_as_per_mar',
'fieldtype': 'Currency',
- 'idx': 21,
'label': 'Cost As Per Valuation Rate',
'oldfieldname': 'cost_as_per_mar',
'oldfieldtype': 'Currency',
@@ -400,7 +397,6 @@
'doctype': 'DocField',
'fieldname': 'cost_as_per_lpr',
'fieldtype': 'Currency',
- 'idx': 22,
'label': 'Cost As Per LPR',
'oldfieldname': 'cost_as_per_lpr',
'oldfieldtype': 'Currency',
@@ -412,7 +408,6 @@
'doctype': 'DocField',
'fieldname': 'cost_as_per_sr',
'fieldtype': 'Currency',
- 'idx': 23,
'label': 'Cost As Per SR',
'oldfieldname': 'cost_as_per_sr',
'oldfieldtype': 'Currency',
@@ -425,7 +420,6 @@
'doctype': 'DocField',
'fieldname': 'cost_as_on',
'fieldtype': 'Data',
- 'idx': 24,
'label': 'Cost as on',
'oldfieldname': 'cost_as_on',
'oldfieldtype': 'Data',
@@ -437,7 +431,6 @@
'doctype': 'DocField',
'fieldname': 'dir_mat_as_per_mar',
'fieldtype': 'Currency',
- 'idx': 25,
'label': 'Direct Material As Per Valuation',
'oldfieldname': 'dir_mat_as_per_mar',
'oldfieldtype': 'Currency',
@@ -449,7 +442,6 @@
'doctype': 'DocField',
'fieldname': 'dir_mat_as_per_lpr',
'fieldtype': 'Currency',
- 'idx': 26,
'label': 'Direct Material As Per LPR',
'oldfieldname': 'dir_mat_as_per_lpr',
'oldfieldtype': 'Currency',
@@ -461,7 +453,6 @@
'doctype': 'DocField',
'fieldname': 'dir_mat_as_per_sr',
'fieldtype': 'Currency',
- 'idx': 27,
'label': 'Direct Material As Per SR',
'oldfieldname': 'dir_mat_as_per_sr',
'oldfieldtype': 'Currency',
@@ -473,7 +464,6 @@
'doctype': 'DocField',
'fieldname': 'operating_cost',
'fieldtype': 'Currency',
- 'idx': 28,
'label': 'Operating Cost',
'oldfieldname': 'operating_cost',
'oldfieldtype': 'Currency',
@@ -485,7 +475,6 @@
'doctype': 'DocField',
'fieldname': 'maintained_by',
'fieldtype': 'Data',
- 'idx': 29,
'label': 'Maintained By',
'oldfieldname': 'maintained_by',
'oldfieldtype': 'Data',
@@ -497,7 +486,6 @@
'doctype': 'DocField',
'fieldtype': 'Section Break',
'hidden': 1,
- 'idx': 30,
'label': 'BOM Report',
'oldfieldtype': 'Section Break',
'permlevel': 0
@@ -508,7 +496,6 @@
'doctype': 'DocField',
'fieldtype': 'Section Break',
'hidden': 0,
- 'idx': 31,
'label': 'Flat BOM',
'oldfieldtype': 'Section Break',
'permlevel': 0
@@ -522,7 +509,6 @@
'fieldname': 'flat_bom_details',
'fieldtype': 'Table',
'hidden': 0,
- 'idx': 32,
'label': 'Flat BOM Detail',
'no_copy': 1,
'oldfieldname': 'flat_bom_details',
diff --git a/erpnext/production/doctype/bom_material/bom_material.txt b/erpnext/production/doctype/bom_material/bom_material.txt
index 1ce35a2..436519e 100644
--- a/erpnext/production/doctype/bom_material/bom_material.txt
+++ b/erpnext/production/doctype/bom_material/bom_material.txt
@@ -329,11 +329,11 @@
{
'doctype': 'DocField',
'fieldname': 'qty_consumed_per_unit',
- 'fieldtype': 'Currency',
+ 'fieldtype': 'Float',
'idx': 21,
'label': 'Qty Consumed Per Unit',
'oldfieldname': 'qty_consumed_per_unit',
- 'oldfieldtype': 'Currency',
+ 'oldfieldtype': 'Float',
'permlevel': 1
}
-]
\ No newline at end of file
+]
diff --git a/erpnext/production/doctype/flat_bom_detail/flat_bom_detail.txt b/erpnext/production/doctype/flat_bom_detail/flat_bom_detail.txt
index 7339300..f0d5d58 100644
--- a/erpnext/production/doctype/flat_bom_detail/flat_bom_detail.txt
+++ b/erpnext/production/doctype/flat_bom_detail/flat_bom_detail.txt
@@ -5,8 +5,8 @@
{
'creation': '2010-08-08 17:09:02',
'docstatus': 0,
- 'modified': '2010-09-20 14:06:57',
- 'modified_by': 'umair@iwebnotes.com',
+ 'modified': '2011-11-10 14:21:40',
+ 'modified_by': 'Administrator',
'owner': 'jai@webnotestech.com'
},
@@ -14,6 +14,7 @@
{
'autoname': 'FBD/.######',
'colour': 'White:FFF',
+ 'default_print_format': 'Standard',
'doctype': 'DocType',
'istable': 1,
'module': 'Production',
@@ -22,7 +23,7 @@
'section_style': 'Simple',
'server_code_error': ' ',
'show_in_menu': 0,
- 'version': 15
+ 'version': 18
},
# These values are common for all DocField
@@ -46,7 +47,6 @@
'doctype': 'DocField',
'fieldname': 'item_code',
'fieldtype': 'Link',
- 'idx': 1,
'label': 'Item Code',
'oldfieldname': 'item_code',
'oldfieldtype': 'Link',
@@ -58,7 +58,6 @@
'doctype': 'DocField',
'fieldname': 'description',
'fieldtype': 'Text',
- 'idx': 2,
'label': 'Description',
'oldfieldname': 'description',
'oldfieldtype': 'Text',
@@ -70,7 +69,6 @@
'doctype': 'DocField',
'fieldname': 'moving_avg_rate',
'fieldtype': 'Currency',
- 'idx': 5,
'label': 'Valuation Rate',
'oldfieldname': 'moving_avg_rate',
'oldfieldtype': 'Currency'
@@ -81,7 +79,6 @@
'doctype': 'DocField',
'fieldname': 'amount_as_per_mar',
'fieldtype': 'Currency',
- 'idx': 6,
'label': 'Amount As Per Valuation Rate',
'oldfieldname': 'amount_as_per_mar',
'oldfieldtype': 'Currency'
@@ -92,7 +89,6 @@
'doctype': 'DocField',
'fieldname': 'last_purchase_rate',
'fieldtype': 'Currency',
- 'idx': 7,
'label': 'Last Purchase Rate',
'oldfieldname': 'last_purchase_rate',
'oldfieldtype': 'Currency'
@@ -103,7 +99,6 @@
'doctype': 'DocField',
'fieldname': 'amount_as_per_lpr',
'fieldtype': 'Currency',
- 'idx': 8,
'label': 'Amount As Per LPR',
'oldfieldname': 'amount_as_per_lpr',
'oldfieldtype': 'Currency'
@@ -114,7 +109,6 @@
'doctype': 'DocField',
'fieldname': 'qty',
'fieldtype': 'Currency',
- 'idx': 9,
'label': 'Qty',
'oldfieldname': 'qty',
'oldfieldtype': 'Currency'
@@ -125,7 +119,6 @@
'doctype': 'DocField',
'fieldname': 'standard_rate',
'fieldtype': 'Currency',
- 'idx': 9,
'label': 'Standard Rate',
'oldfieldname': 'standard_rate',
'oldfieldtype': 'Currency'
@@ -136,7 +129,6 @@
'doctype': 'DocField',
'fieldname': 'amount_as_per_sr',
'fieldtype': 'Currency',
- 'idx': 10,
'label': 'Amount As Per SR',
'oldfieldname': 'amount_as_per_sr',
'oldfieldtype': 'Currency'
@@ -146,11 +138,10 @@
{
'doctype': 'DocField',
'fieldname': 'qty_consumed_per_unit',
- 'fieldtype': 'Currency',
- 'idx': 11,
+ 'fieldtype': 'Float',
'label': 'Qty Consumed Per Unit',
'oldfieldname': 'qty_consumed_per_unit',
- 'oldfieldtype': 'Currency'
+ 'oldfieldtype': 'Float'
},
# DocField
@@ -158,12 +149,10 @@
'doctype': 'DocField',
'fieldname': 'stock_uom',
'fieldtype': 'Link',
- 'idx': 12,
'label': 'Stock UOM',
'oldfieldname': 'stock_uom',
'oldfieldtype': 'Link',
- 'options': 'UOM',
- 'search_index': 0
+ 'options': 'UOM'
},
# DocField
@@ -172,7 +161,6 @@
'fieldname': 'flat_bom_no',
'fieldtype': 'Data',
'hidden': 1,
- 'idx': 12,
'label': 'Flat BOM No',
'oldfieldname': 'flat_bom_no',
'oldfieldtype': 'Data'
@@ -184,7 +172,6 @@
'fieldname': 'bom_mat_no',
'fieldtype': 'Data',
'hidden': 0,
- 'idx': 13,
'label': 'BOM Mat No',
'oldfieldname': 'bom_mat_no',
'oldfieldtype': 'Data'
@@ -196,7 +183,6 @@
'fieldname': 'parent_bom',
'fieldtype': 'Link',
'hidden': 0,
- 'idx': 14,
'label': 'Parent BOM',
'oldfieldname': 'parent_bom',
'oldfieldtype': 'Link'
@@ -207,11 +193,10 @@
'doctype': 'DocField',
'fieldname': 'is_pro_applicable',
'fieldtype': 'Select',
- 'idx': 15,
'label': 'Is PRO Applicable',
'oldfieldname': 'is_pro_applicable',
'oldfieldtype': 'Select',
'options': '\nYes\nNo',
'reqd': 0
}
-]
\ No newline at end of file
+]
diff --git a/erpnext/production/doctype/workstation/workstation.txt b/erpnext/production/doctype/workstation/workstation.txt
index bb7cc21..dd0868d 100644
--- a/erpnext/production/doctype/workstation/workstation.txt
+++ b/erpnext/production/doctype/workstation/workstation.txt
@@ -5,16 +5,19 @@
{
'creation': '2010-08-08 17:09:31',
'docstatus': 0,
- 'modified': '2011-01-04 13:40:42',
- 'modified_by': 'rahul@webnotestech.com',
+ 'modified': '2011-11-24 14:34:41',
+ 'modified_by': 'Administrator',
'owner': 'Administrator'
},
# These values are common for all DocType
{
+ '_last_update': '1322125389',
+ 'allow_email': 0,
'allow_trash': 1,
'autoname': 'field:workstation_name',
'colour': 'White:FFF',
+ 'default_print_format': 'Standard',
'doctype': 'DocType',
'document_type': 'Master',
'module': 'Production',
@@ -22,7 +25,7 @@
'section_style': 'Simple',
'server_code_error': ' ',
'show_in_menu': 0,
- 'version': 11
+ 'version': 13
},
# These values are common for all DocField
@@ -55,7 +58,6 @@
'cancel': 1,
'create': 1,
'doctype': 'DocPerm',
- 'idx': 1,
'permlevel': 0,
'role': 'System Manager',
'write': 1
@@ -64,7 +66,6 @@
# DocPerm
{
'doctype': 'DocPerm',
- 'idx': 2,
'permlevel': 1,
'role': 'System Manager'
},
@@ -74,7 +75,6 @@
'cancel': 1,
'create': 1,
'doctype': 'DocPerm',
- 'idx': 3,
'permlevel': 0,
'role': 'Production User',
'write': 1
@@ -85,7 +85,6 @@
'cancel': 1,
'create': 1,
'doctype': 'DocPerm',
- 'idx': 4,
'permlevel': 0,
'role': 'Production User',
'write': 1
@@ -94,7 +93,6 @@
# DocPerm
{
'doctype': 'DocPerm',
- 'idx': 5,
'permlevel': 1,
'role': 'Production Manager'
},
@@ -102,7 +100,6 @@
# DocPerm
{
'doctype': 'DocPerm',
- 'idx': 6,
'permlevel': 1,
'role': 'Production User'
},
@@ -112,7 +109,6 @@
'doctype': 'DocField',
'fieldname': 'trash_reason',
'fieldtype': 'Small Text',
- 'idx': 1,
'label': 'Trash Reason',
'oldfieldname': 'trash_reason',
'oldfieldtype': 'Small Text',
@@ -124,7 +120,6 @@
'doctype': 'DocField',
'fieldname': 'workstation_name',
'fieldtype': 'Data',
- 'idx': 2,
'label': 'Workstation Name',
'oldfieldname': 'workstation_name',
'oldfieldtype': 'Data',
@@ -137,7 +132,6 @@
'doctype': 'DocField',
'fieldname': 'warehouse',
'fieldtype': 'Link',
- 'idx': 3,
'label': 'Warehouse',
'oldfieldname': 'warehouse',
'oldfieldtype': 'Link',
@@ -151,7 +145,6 @@
'doctype': 'DocField',
'fieldname': 'description',
'fieldtype': 'Text',
- 'idx': 4,
'label': 'Description',
'oldfieldname': 'description',
'oldfieldtype': 'Text',
@@ -165,7 +158,6 @@
'fieldname': 'capacity',
'fieldtype': 'Data',
'hidden': 1,
- 'idx': 5,
'label': 'Capacity',
'oldfieldname': 'capacity',
'oldfieldtype': 'Data',
@@ -179,7 +171,6 @@
'fieldname': 'capacity_units',
'fieldtype': 'Select',
'hidden': 1,
- 'idx': 6,
'label': 'Capacity Units',
'oldfieldname': 'capacity_units',
'oldfieldtype': 'Select',
@@ -194,7 +185,6 @@
'doctype': 'DocField',
'fieldname': 'hour_rate_labour',
'fieldtype': 'Currency',
- 'idx': 7,
'label': 'Hour Rate Labour',
'oldfieldname': 'hour_rate_labour',
'oldfieldtype': 'Currency',
@@ -206,7 +196,6 @@
{
'doctype': 'DocField',
'fieldtype': 'Section Break',
- 'idx': 8,
'label': 'Over Heads',
'oldfieldtype': 'Section Break',
'permlevel': 0
@@ -217,7 +206,6 @@
'doctype': 'DocField',
'fieldname': 'hour_rate_electricity',
'fieldtype': 'Currency',
- 'idx': 9,
'label': 'Hour Rate Electricity',
'oldfieldname': 'hour_rate_electricity',
'oldfieldtype': 'Currency',
@@ -229,7 +217,6 @@
'doctype': 'DocField',
'fieldname': 'hour_rate_consumable',
'fieldtype': 'Currency',
- 'idx': 10,
'label': 'Hour Rate Consumable',
'oldfieldname': 'hour_rate_consumable',
'oldfieldtype': 'Currency',
@@ -241,7 +228,6 @@
'doctype': 'DocField',
'fieldname': 'hour_rate_rent',
'fieldtype': 'Currency',
- 'idx': 11,
'label': 'Hour Rate Rent',
'oldfieldname': 'hour_rate_rent',
'oldfieldtype': 'Currency',
@@ -253,7 +239,6 @@
'doctype': 'DocField',
'fieldname': 'overhead',
'fieldtype': 'Currency',
- 'idx': 12,
'label': 'Overhead',
'oldfieldname': 'overhead',
'oldfieldtype': 'Currency',
@@ -264,7 +249,6 @@
{
'doctype': 'DocField',
'fieldtype': 'Section Break',
- 'idx': 13,
'label': 'Hour Rate',
'oldfieldtype': 'Section Break',
'permlevel': 0
@@ -275,7 +259,6 @@
'doctype': 'DocField',
'fieldname': 'hour_rate',
'fieldtype': 'Currency',
- 'idx': 14,
'label': 'Hour Rate',
'oldfieldname': 'hour_rate',
'oldfieldtype': 'Currency',
diff --git a/erpnext/projects/doctype/project/project.py b/erpnext/projects/doctype/project/project.py
index 9930bf4..4504191 100644
--- a/erpnext/projects/doctype/project/project.py
+++ b/erpnext/projects/doctype/project/project.py
@@ -34,9 +34,9 @@
'customer_name' : details and details[0]['customer_name'] or ''
}
#get primary contact details(this is done separately coz. , if join query used & no primary contact thn it would not be able to fetch customer details)
- contact_det = sql("select contact_name, contact_no, email_id from `tabContact` where customer_name='%s' and is_customer=1 and is_primary_contact='Yes' and docstatus!=2" %(self.doc.customer), as_dict = 1)
+ contact_det = sql("select contact_name, phone, email_id from `tabContact` where customer_name='%s' and is_customer=1 and is_primary_contact=1 and docstatus!=2" %(self.doc.customer), as_dict = 1)
ret['contact_person'] = contact_det and contact_det[0]['contact_name'] or ''
- ret['contact_no'] = contact_det and contact_det[0]['contact_no'] or ''
+ ret['contact_no'] = contact_det and contact_det[0]['phone'] or ''
ret['email_id'] = contact_det and contact_det[0]['email_id'] or ''
return ret
else:
diff --git a/erpnext/projects/doctype/project_control/project_control.py b/erpnext/projects/doctype/project_control/project_control.py
index 82cb1c7..4b382a5 100644
--- a/erpnext/projects/doctype/project_control/project_control.py
+++ b/erpnext/projects/doctype/project_control/project_control.py
@@ -1,13 +1,13 @@
# Please edit this list and import only required elements
import webnotes
-from webnotes.utils import add_days, add_months, add_years, cint, cstr, date_diff, default_fields, flt, fmt_money, formatdate, generate_hash, getTraceback, get_defaults, get_first_day, get_last_day, getdate, has_common, month_name, now, nowdate, replace_newlines, sendmail, set_default, str_esc_quote, user_format, validate_email_add
+from webnotes.utils import add_days, add_months, add_years, cint, cstr, date_diff, default_fields, flt, fmt_money, formatdate, generate_hash, getTraceback, get_defaults, get_first_day, get_last_day, getdate, has_common, month_name, now, nowdate, replace_newlines, set_default, str_esc_quote, user_format, validate_email_add, add_days
from webnotes.model import db_exists
from webnotes.model.doc import Document, addchild, removechild, getchildren, make_autoname, SuperDocType
from webnotes.model.doclist import getlist, copy_doclist
from webnotes.model.code import get_obj, get_server_obj, run_server_obj, updatedb, check_syntax
from webnotes import session, form, is_testing, msgprint, errprint
-
+from webnotes.utils.email_lib import sendmail
set = webnotes.conn.set
sql = webnotes.conn.sql
get_value = webnotes.conn.get_value
@@ -18,99 +18,127 @@
class DocType:
- def __init__(self,d,dl):
- self.doc, self.doclist = d,dl
-
- def get_projects(self, arg):
- # project list
- pl=[]
- status={}
- if arg == 'Open':
- pl = [p[0] for p in sql("select name from `tabProject` where status = 'Open' order by creation desc limit 20")]
- for p1 in pl:
- status[p1] = 'Open'
- elif arg == 'Completed':
- pl = [p[0] for p in sql("select name from `tabProject` where status = 'Completed' order by creation desc limit 20")]
- for p2 in pl:
- status[p2] = 'Completed'
- elif arg == 'Cancelled':
- pl = [p[0] for p in sql("select name from `tabProject` where status = 'Cancelled' order by creation desc limit 20")]
- for p3 in pl:
- status[p3] = 'Cancelled'
- else:
- #pl = [p[0] for p in sql("select name from `tabProject` order by creation desc limit 20")]
- pl1 = sql("select name, status from `tabProject` order by creation desc limit 20", as_dict=1)
- for p4 in pl1:
- status[p4['name']] = p4['status']
- pl.append(p4['name'])
-
- # milestones in the next 7 days for active projects
- ml = convert_to_lists(sql("select t1.milestone_date, t1.milestone, t1.parent from `tabProject Milestone` t1, tabProject t2 where t1.parent = t2.name and t2.status='Open' and DATEDIFF(t1.milestone_date, CURDATE()) BETWEEN 0 AND 7 ORDER BY t1.milestone_date ASC"))
+ def __init__(self,d,dl):
+ self.doc, self.doclist = d,dl
+
+ def get_projects(self, arg):
+ # project list
+ pl=[]
+ status={}
+ if arg == 'Open':
+ pl = [p[0] for p in sql("select name from `tabProject` where status = 'Open' order by creation desc limit 20")]
+ for p1 in pl:
+ status[p1] = 'Open'
+ elif arg == 'Completed':
+ pl = [p[0] for p in sql("select name from `tabProject` where status = 'Completed' order by creation desc limit 20")]
+ for p2 in pl:
+ status[p2] = 'Completed'
+ elif arg == 'Cancelled':
+ pl = [p[0] for p in sql("select name from `tabProject` where status = 'Cancelled' order by creation desc limit 20")]
+ for p3 in pl:
+ status[p3] = 'Cancelled'
+ else:
+ #pl = [p[0] for p in sql("select name from `tabProject` order by creation desc limit 20")]
+ pl1 = sql("select name, status from `tabProject` order by creation desc limit 20", as_dict=1)
+ for p4 in pl1:
+ status[p4['name']] = p4['status']
+ pl.append(p4['name'])
+
+ # milestones in the next 7 days for active projects
+ ml = convert_to_lists(sql("select t1.milestone_date, t1.milestone, t1.parent from `tabProject Milestone` t1, tabProject t2 where t1.parent = t2.name and t2.status='Open' and DATEDIFF(t1.milestone_date, CURDATE()) BETWEEN 0 AND 7 ORDER BY t1.milestone_date ASC"))
- # percent of activity completed per project
- comp = {}
- n_tasks = {}
-
- for p in pl:
- t1 = sql('select count(*) from tabTicket where project=%s and docstatus!=2', p)[0][0]
- n_tasks[p] = t1 or 0
- if t1:
- t2 = sql('select count(*) from tabTicket where project=%s and docstatus!=2 and status="Closed"', p)[0][0]
- comp[p] = cint(flt(t2)*100/t1)
-
- return {'pl':pl, 'ml':ml, 'comp':comp, 'n_tasks':n_tasks, 'status':status}
-
- def get_resources(self):
- ret = {}
+ # percent of activity completed per project
+ comp = {}
+ n_tasks = {}
+
+ for p in pl:
+ t1 = sql('select count(*) from tabTicket where project=%s and docstatus!=2', p)[0][0]
+ n_tasks[p] = t1 or 0
+ if t1:
+ t2 = sql('select count(*) from tabTicket where project=%s and docstatus!=2 and status="Closed"', p)[0][0]
+ comp[p] = cint(flt(t2)*100/t1)
+
+ return {'pl':pl, 'ml':ml, 'comp':comp, 'n_tasks':n_tasks, 'status':status}
+
+ def get_resources(self):
+ ret = {}
- # resource list
- rl = sql("select distinct allocated_to, assignee_email from tabTicket")
+ # resource list
+ rl = sql("select distinct allocated_to, assignee_email from tabTicket")
- # get open & closed tickets
- for r in rl:
- if r[0]:
- ret[r[1]] = {}
- ret[r[1]]['id'] = r[0]
- ret[r[1]]['Total'] = sql("select count(*) from tabTicket where allocated_to=%s and docstatus!=2", r[0])[0][0]
- ret[r[1]]['Closed'] = sql("select count(*) from tabTicket where allocated_to=%s and status='Closed' and docstatus!=2", r[0])[0][0]
- ret[r[1]]['percent'] = cint(flt(ret[r[1]]['Closed']) * 100 / ret[r[1]]['Total'])
+ # get open & closed tickets
+ for r in rl:
+ if r[0]:
+ ret[r[1]] = {}
+ ret[r[1]]['id'] = r[0]
+ ret[r[1]]['Total'] = sql("select count(*) from tabTicket where allocated_to=%s and docstatus!=2", r[0])[0][0]
+ ret[r[1]]['Closed'] = sql("select count(*) from tabTicket where allocated_to=%s and status='Closed' and docstatus!=2", r[0])[0][0]
+ ret[r[1]]['percent'] = cint(flt(ret[r[1]]['Closed']) * 100 / ret[r[1]]['Total'])
- return ret
+ return ret
- # --------------------------------------------------------------
- # for Gantt Chart
+ # --------------------------------------------------------------
+ # for Gantt Chart
- def get_init_data(self, arg=''):
- pl = [p[0] for p in sql('select name from tabProject where docstatus != 2')]
- rl = [p[0] for p in sql('select distinct allocated_to from tabTicket where docstatus != 2 and ifnull(allocated_to,"") != ""')]
- return {'pl':pl, 'rl':rl}
+ def get_init_data(self, arg=''):
+ pl = [p[0] for p in sql('select name from tabProject where docstatus != 2')]
+ rl = [p[0] for p in sql('select distinct allocated_to from tabTicket where docstatus != 2 and ifnull(allocated_to,"") != ""')]
+ return {'pl':pl, 'rl':rl}
- def get_tasks(self, arg):
- start_date, end_date, project, resource = arg.split('~~~')
+ def get_tasks(self, arg):
+ start_date, end_date, project, resource = arg.split('~~~')
- cl = ''
- if project and project != 'All':
- cl = " and ifnull(project,'') = '%s'" % project
+ cl = ''
+ if project and project != 'All':
+ cl = " and ifnull(project,'') = '%s'" % project
- if resource and resource != 'All':
- cl = " and ifnull(allocated_to,'') = '%s'" % resource
+ if resource and resource != 'All':
+ cl = " and ifnull(allocated_to,'') = '%s'" % resource
- tl = sql("""
- select subject, allocated_to, project, exp_start_date, exp_end_date, priority, status, name
- from tabTicket
- where
- ((exp_start_date between '%(st)s' and '%(end)s') or
- (exp_end_date between '%(st)s' and '%(end)s') or
- (exp_start_date < '%(st)s' and exp_end_date > '%(end)s')) %(cond)s order by exp_start_date limit 100""" % {'st': start_date, 'end': end_date, 'cond':cl})
+ tl = sql("""
+ select subject, allocated_to, project, exp_start_date, exp_end_date, priority, status, name
+ from tabTicket
+ where
+ ((exp_start_date between '%(st)s' and '%(end)s') or
+ (exp_end_date between '%(st)s' and '%(end)s') or
+ (exp_start_date < '%(st)s' and exp_end_date > '%(end)s')) %(cond)s order by exp_start_date limit 100""" % {'st': start_date, 'end': end_date, 'cond':cl})
- return convert_to_lists(tl)
-
- def declare_proj_completed(self, arg):
- chk = sql("select name from `tabTicket` where project=%s and status='Open'", arg)
- if chk:
- chk_lst = [x[0] for x in chk]
- msgprint("Task(s) "+','.join(chk_lst)+" has staus 'Open'. Please submit all tasks against this project before closing the project.")
- return cstr('false')
- else:
- sql("update `tabProject` set status = 'Completed' where name = %s", arg)
- return cstr('true')
\ No newline at end of file
+ return convert_to_lists(tl)
+
+ def declare_proj_completed(self, arg):
+ chk = sql("select name from `tabTicket` where project=%s and status='Open'", arg)
+ if chk:
+ chk_lst = [x[0] for x in chk]
+ msgprint("Task(s) "+','.join(chk_lst)+" has staus 'Open'. Please submit all tasks against this project before closing the project.")
+ return cstr('false')
+ else:
+ sql("update `tabProject` set status = 'Completed' where name = %s", arg)
+ return cstr('true')
+
+
+def sent_reminder_task():
+ task_list = sql("""
+ select subject, allocated_to, project, exp_start_date, exp_end_date,
+ priority, status, name, senders_name, opening_date, review_date, description
+ from tabTicket
+ where task_email_notify=1
+ and sent_reminder=0
+ and status='Open'
+ and exp_start_date is not null""",as_dict=1)
+ for i in task_list:
+ if date_diff(i['exp_start_date'],nowdate()) ==2:
+ msg2="""<h2>Two days to complete: %(name)s</h2>
+ <p>This is a reminder for the task %(name)s has been assigned to you
+ by %(senders_name)s on %(opening_date)s</p>
+ <p><b>Project:</b> %(project)s</p>
+ <p><b>Expected Start Date:</b> %(exp_start_date)s</p>
+ <p><b>Expected End Date:</b> %(exp_end_date)s</p>
+ <p><b>Review Date:</b> %(review_date)s</p>
+ <p><b>Details:</b> %(description)s</p>
+ <p>If you have already completed this task, please update the system</p>
+ <p>Good Luck!</p>
+ <p>(This notification is autogenerated)</p>""" % i
+ sendmail(i['allocated_to'], sender='automail@webnotestech.com', msg=msg2,send_now=1, \
+ subject='A task has been assigned')
+ sql("update `tabTicket` set sent_reminder='1' where name='%(name)s' and allocated_to= '%(allocated_to)s'" % i)
+
diff --git a/erpnext/projects/doctype/project_milestone/project_milestone.txt b/erpnext/projects/doctype/project_milestone/project_milestone.txt
index eab533b..6d45a7c 100644
--- a/erpnext/projects/doctype/project_milestone/project_milestone.txt
+++ b/erpnext/projects/doctype/project_milestone/project_milestone.txt
@@ -5,21 +5,22 @@
{
'creation': '2010-08-08 17:09:15',
'docstatus': 0,
- 'modified': '2011-01-05 15:24:43',
- 'modified_by': 'sneha@webnotestech.com',
+ 'modified': '2011-12-19 14:11:40',
+ 'modified_by': 'Administrator',
'owner': 'Administrator'
},
# These values are common for all DocType
{
'colour': 'White:FFF',
+ 'default_print_format': 'Standard',
'doctype': 'DocType',
'istable': 1,
'module': 'Projects',
'name': '__common__',
'section_style': 'Simple',
'server_code_error': ' ',
- 'version': 2
+ 'version': 4
},
# These values are common for all DocField
@@ -43,7 +44,6 @@
'doctype': 'DocField',
'fieldname': 'milestone_date',
'fieldtype': 'Date',
- 'idx': 1,
'label': 'Milestone Date',
'oldfieldname': 'milestone_date',
'oldfieldtype': 'Date'
@@ -52,18 +52,8 @@
# DocField
{
'doctype': 'DocField',
- 'fieldname': 'actual_completion_date_',
- 'fieldtype': 'Date',
- 'idx': 2,
- 'label': 'Actual Completion Date '
- },
-
- # DocField
- {
- 'doctype': 'DocField',
'fieldname': 'milestone',
'fieldtype': 'Text',
- 'idx': 3,
'label': 'Milestone',
'oldfieldname': 'milestone',
'oldfieldtype': 'Text',
@@ -75,8 +65,8 @@
'doctype': 'DocField',
'fieldname': 'status',
'fieldtype': 'Select',
- 'idx': 4,
'label': 'Status',
+ 'no_copy': 1,
'oldfieldname': 'status',
'oldfieldtype': 'Select',
'options': 'Pending\nCompleted'
diff --git a/erpnext/projects/doctype/ticket/ticket.py b/erpnext/projects/doctype/ticket/ticket.py
index 0f18b21..4dbcfe7 100644
--- a/erpnext/projects/doctype/ticket/ticket.py
+++ b/erpnext/projects/doctype/ticket/ticket.py
@@ -1,7 +1,8 @@
# Please edit this list and import only required elements
import webnotes
-from webnotes.utils import add_days, add_months, add_years, cint, cstr, date_diff, default_fields, flt, fmt_money, formatdate, generate_hash, getTraceback, get_defaults, get_first_day, get_last_day, getdate, has_common, month_name, now, nowdate, replace_newlines, sendmail, set_default, str_esc_quote, user_format, validate_email_add
+from webnotes.utils import add_days, add_months, add_years, cint, cstr, date_diff, default_fields, flt, fmt_money, formatdate, generate_hash, getTraceback, get_defaults, get_first_day, get_last_day, getdate, has_common, month_name, now, nowdate, replace_newlines, set_default, str_esc_quote, user_format, validate_email_add
+from webnotes.utils.email_lib import sendmail
from webnotes.model import db_exists
from webnotes.model.doc import Document, addchild, removechild, getchildren, make_autoname, SuperDocType
from webnotes.model.doclist import getlist, copy_doclist
@@ -9,159 +10,217 @@
from webnotes import session, form, is_testing, msgprint, errprint
sql = webnotes.conn.sql
+set = webnotes.conn.set
+get_value = webnotes.conn.get_value
# -----------------------------------------------------------------------------------------
class DocType:
- def __init__(self,doc,doclist=[]):
- self.doc = doc
- self.doclist = doclist
-
- def get_project_details(self):
- cust = sql("select customer, customer_name from `tabProject` where name = %s", self.doc.project)
- if cust:
- ret = {'customer': cust and cust[0][0] or '', 'customer_name': cust and cust[0][1] or ''}
- return ret
-
- def get_customer_details(self):
- cust = sql("select customer_name from `tabCustomer` where name=%s", self.doc.customer)
- if cust:
- ret = {'customer_name': cust and cust[0][0] or ''}
- return ret
-
- def get_allocated_to_name(self):
- as_em = sql("select first_name, last_name from `tabProfile` where name=%s",self.doc.allocated_to)
- ret = { 'allocated_to_name' : as_em and (as_em[0][0] + ' ' + as_em[0][1]) or ''}
- return ret
+ def __init__(self,doc,doclist=[]):
+ self.doc = doc
+ self.doclist = doclist
+
+ def get_project_details(self):
+ cust = sql("select customer, customer_name from `tabProject` where name = %s", self.doc.project)
+ if cust:
+ ret = {'customer': cust and cust[0][0] or '', 'customer_name': cust and cust[0][1] or ''}
+ return ret
+
+ def get_customer_details(self):
+ cust = sql("select customer_name from `tabCustomer` where name=%s", self.doc.customer)
+ if cust:
+ ret = {'customer_name': cust and cust[0][0] or ''}
+ return ret
+
+ def get_allocated_to_name(self):
+ as_em = sql("select first_name, last_name from `tabProfile` where name=%s",str(self.doc.allocated_to))
+ ret = { 'allocated_to_name' : as_em and (as_em[0][0] + ' ' + as_em[0][1]) or ''}
+ return ret
- # validate
- #--------------------------------------------
+ # validate
+ #--------------------------------------------
- def validate(self):
- if not self.doc.opening_date:
- msgprint("Please enter Opening Date.")
- raise Exception
- elif getdate(self.doc.opening_date) > getdate(nowdate()):
- msgprint("Opening date can not be future date")
- raise Exception
-
- if self.doc.exp_start_date and self.doc.exp_end_date and getdate(self.doc.exp_start_date) > getdate(self.doc.exp_end_date):
- msgprint("'Expected Start Date' can not be greater than 'Expected End Date'")
- raise Exception
-
- if self.doc.act_start_date and self.doc.act_end_date and getdate(self.doc.act_start_date) > getdate(self.doc.act_end_date):
- msgprint("'Actual Start Date' can not be greater than 'Actual End Date'")
- raise Exception
-
- if self.doc.opening_date and self.doc.review_date and getdate(self.doc.opening_date) > getdate(self.doc.review_date):
- msgprint("Review Date should be greater than or equal to Opening Date ")
- raise Exception
-
- if self.doc.closing_date and self.doc.review_date and getdate(self.doc.closing_date) < getdate(self.doc.review_date):
- msgprint("Closing Date should be greater than or equal to Review Date ")
- raise Exception
+ def validate(self):
+ if not self.doc.opening_date:
+ msgprint("Please enter Opening Date.")
+ raise Exception
+ elif getdate(self.doc.opening_date) > getdate(nowdate()):
+ msgprint("Opening date can not be future date")
+ raise Exception
+
+ if self.doc.exp_start_date and self.doc.exp_end_date and getdate(self.doc.exp_start_date) > getdate(self.doc.exp_end_date):
+ msgprint("'Expected Start Date' can not be greater than 'Expected End Date'")
+ raise Exception
+
+ if self.doc.act_start_date and self.doc.act_end_date and getdate(self.doc.act_start_date) > getdate(self.doc.act_end_date):
+ msgprint("'Actual Start Date' can not be greater than 'Actual End Date'")
+ raise Exception
+
+ if self.doc.opening_date and self.doc.review_date and getdate(self.doc.opening_date) > getdate(self.doc.review_date):
+ msgprint("Review Date should be greater than or equal to Opening Date ")
+ raise Exception
+
+ if self.doc.closing_date and self.doc.review_date and getdate(self.doc.closing_date) < getdate(self.doc.review_date):
+ msgprint("Closing Date should be greater than or equal to Review Date ")
+ raise Exception
- # on update
- #--------------------------------------------
-
- def on_update(self):
- pass
-
- #validate before sending for approval
- def validate_for_pending_review(self):
- if not self.doc.allocated_to:
- msgprint("Please enter allocated_to.")
- raise Exception
- self.validate_with_timesheet_dates()
-
- #validate before closing task
- def validate_for_closed(self):
- self.check_non_submitted_timesheets()
- self.get_actual_total_hrs()
-
- def check_non_submitted_timesheets(self):
- chk = sql("select t1.name from `tabTimesheet` t1, `tabTimesheet Detail` t2 where t2.parent=t1.name and t2.task_id=%s and t1.status='Draft'", self.doc.name)
- if chk:
- chk_lst = [x[0] for x in chk]
- msgprint("Please submit timesheet(s) : "+','.join(chk_lst)+" before declaring this task as completed. As details of this task present in timesheet(s)")
- raise Exception
-
- #calculate actual total hours taken to complete task from timesheets
- def get_actual_total_hrs(self):
- import datetime
- import time
- chk = sql("select t2.act_total_hrs from `tabTimesheet` t1, `tabTimesheet Detail` t2 where t2.parent = t1.name and t2.task_id = %s and t1.status = 'Submitted' and ifnull(t2.act_total_hrs, '')!='' order by t1.timesheet_date asc", self.doc.name)
- if chk:
- chk_lst = [x[0] for x in chk]
- actual_total = total =0
-
- for m in chk_lst:
- m1, m2=[], 0
- m1 = m.split(":")
- m2 = (datetime.timedelta(minutes=cint(m1[1]), hours=cint(m1[0]))).seconds
- total = total + m2
-
- actual_total = time.strftime("%H:%M", time.gmtime(total))
- set(self.doc, 'act_total_hrs', actual_total)
-
- # validate and fetch actual start and end date
- def validate_with_timesheet_dates(self):
- chk = sql("select t1.name, t1.timesheet_date from `tabTimesheet` t1, `tabTimesheet Detail` t2 where t2.parent = t1.name and t2.task_id = %s and t1.status = 'Submitted' order by t1.timesheet_date asc", self.doc.name, as_dict=1)
- if chk:
- if self.doc.act_start_date:
- if chk[0]['timesheet_date'] > getdate(self.doc.act_start_date) or chk[0]['timesheet_date'] < getdate(self.doc.act_start_date):
- msgprint("Actual start date of this task is "+cstr(chk[0]['timesheet_date'])+" as per timesheet "+cstr(chk[0]['name']))
- raise Exception
- else:
- self.doc.act_start_date = chk[0]['timesheet_date']
-
- if self.doc.act_end_date:
- if chk[len(chk)-1]['timesheet_date'] < getdate(self.doc.act_end_date) or chk[len(chk)-1]['timesheet_date'] > getdate(self.doc.act_end_date):
- msgprint("Actual end date of this task is "+cstr(chk[len(chk)-1]['timesheet_date'])+" as per timesheet "+cstr(chk[len(chk)-1]['name']))
- raise Exception
- else:
- self.doc.act_end_date = chk[len(chk)-1]['timesheet_date']
-
- def set_for_review(self):
- self.check_non_submitted_timesheets()
- self.validate_for_pending_review()
- self.get_actual_total_hrs()
- self.doc.review_date = nowdate()
- set(self.doc, 'status', 'Pending Review')
- self.doc.save()
- return cstr('true')
-
- def reopen_task(self):
- set(self.doc, 'status', 'Open')
- self.doc.save()
- return cstr('true')
-
- def declare_completed(self):
- if self.doc.status == 'Open':
- self.validate_for_pending_review()
- self.doc.review_date = nowdate()
- else:
- self.validate_with_timesheet_dates()
- self.validate_for_closed()
- self.doc.closing_date = nowdate()
- set(self.doc, 'status', 'Closed')
- set(self.doc, 'docstatus', 1)
- self.doc.save()
- return cstr('true')
-
- def cancel_task(self):
- chk = sql("select distinct t1.name from `tabTimesheet` t1, `tabTimesheet Detail` t2 where t2.parent = t1.name and t2.task_id = %s and t1.status!='Cancelled'", self.doc.name)
- if chk:
- chk_lst = [x[0] for x in chk]
- msgprint("Timesheet(s) "+','.join(chk_lst)+" created against this task. Thus can not be cancelled")
- raise Exception
- else:
- set(self.doc, 'status', 'Cancelled')
- set(self.doc, 'docstatus', 2)
- self.doc.save()
- return cstr('true')
-
- def on_cancel(self):
- self.cancel_task()
\ No newline at end of file
+ # on update
+ #--------------------------------------------
+
+ def on_update(self):
+ if self.doc.status =='Open' and self.doc.allocated_to:
+ if self.doc.task_email_notify and (self.doc.allocated_to != self.doc.allocated_to_old):
+ self.doc.sent_reminder = 0
+ self.doc.allocated_to_old = self.doc.allocated_to
+ self.sent_notification()
+ if self.doc.exp_start_date:
+ sql("delete from tabEvent where ref_type='Task' and ref_name=%s", self.doc.name)
+ self.add_calendar_event()
+ else:
+ msgprint("An Expeted start date has not been set for this task.Please set a, 'Expected Start date'\
+ to add an event to allocated persons calender.You can save a task without this also.")
+
+
+ def validate_for_pending_review(self):
+ if not self.doc.allocated_to:
+ msgprint("Please enter allocated_to.")
+ raise Exception
+ self.validate_with_timesheet_dates()
+
+ #Sent Notification
+ def sent_notification(self):
+ i = {
+ 'name' : self.doc.name,
+ 'senders_name': self.doc.allocated_to,
+ 'opening_date': self.doc.opening_date,
+ 'exp_start_date': self.doc.exp_start_date,
+ 'exp_end_date' : self.doc.exp_end_date,
+ 'project': self.doc.project,
+ 'review_date': self.doc.review_date,
+ 'description': self.doc.description
+ }
+
+ msg2="""<h2>%(name)s</h2>
+ <p>This is a Notification for the task %(name)s that has been assigned to you
+ by %(senders_name)s on %(opening_date)s</p>
+ <p><b>Project:</b> %(project)s</p>
+ <p><b>Review Date:</b> %(review_date)s</p>
+ <p><b>Expected Start Date:</b> %(exp_start_date)s</p>
+ <p><b>Expected End Date:</b> %(exp_end_date)s</p>
+ <p><b>Details:</b> %(description)s</p>
+ <p>You will also recieve another reminder 2 days before the commencement of the task</p>
+ <p>Good Luck!</p>
+ <p>(This notification is autogenerated)</p>""" % i
+ sendmail(self.doc.allocated_to, sender='automail@webnotestech.com', msg=msg2,send_now=1,\
+ subject='A task has been assigned')
+
+
+
+ #validate before closing task
+ def validate_for_closed(self):
+ self.check_non_submitted_timesheets()
+ self.get_actual_total_hrs()
+
+ def check_non_submitted_timesheets(self):
+ chk = sql("select t1.name from `tabTimesheet` t1, `tabTimesheet Detail` t2 where t2.parent=t1.name and t2.task_id=%s and t1.status='Draft'", self.doc.name)
+ if chk:
+ chk_lst = [x[0] for x in chk]
+ msgprint("Please submit timesheet(s) : "+','.join(chk_lst)+" before declaring this task as completed. As details of this task present in timesheet(s)")
+ raise Exception
+
+ #calculate actual total hours taken to complete task from timesheets
+ def get_actual_total_hrs(self):
+ import datetime
+ import time
+ chk = sql("select t2.act_total_hrs from `tabTimesheet` t1, `tabTimesheet Detail` t2 where t2.parent = t1.name and t2.task_id = %s and t1.status = 'Submitted' and ifnull(t2.act_total_hrs, '')!='' order by t1.timesheet_date asc", self.doc.name)
+ if chk:
+ chk_lst = [x[0] for x in chk]
+ actual_total = total =0
+
+ for m in chk_lst:
+ m1, m2=[], 0
+ m1 = m.split(":")
+ m2 = (datetime.timedelta(minutes=cint(m1[1]), hours=cint(m1[0]))).seconds
+ total = total + m2
+
+ actual_total = time.strftime("%H:%M", time.gmtime(total))
+ set(self.doc, 'act_total_hrs', actual_total)
+
+ # validate and fetch actual start and end date
+ def validate_with_timesheet_dates(self):
+ chk = sql("select t1.name, t1.timesheet_date from `tabTimesheet` t1, `tabTimesheet Detail` t2 where t2.parent = t1.name and t2.task_id = %s and t1.status = 'Submitted' order by t1.timesheet_date asc", self.doc.name, as_dict=1)
+ if chk:
+ if self.doc.act_start_date:
+ if chk[0]['timesheet_date'] > getdate(self.doc.act_start_date) or chk[0]['timesheet_date'] < getdate(self.doc.act_start_date):
+ msgprint("Actual start date of this task is "+cstr(chk[0]['timesheet_date'])+" as per timesheet "+cstr(chk[0]['name']))
+ raise Exception
+ else:
+ self.doc.act_start_date = chk[0]['timesheet_date']
+
+ if self.doc.act_end_date:
+ if chk[len(chk)-1]['timesheet_date'] < getdate(self.doc.act_end_date) or chk[len(chk)-1]['timesheet_date'] > getdate(self.doc.act_end_date):
+ msgprint("Actual end date of this task is "+cstr(chk[len(chk)-1]['timesheet_date'])+" as per timesheet "+cstr(chk[len(chk)-1]['name']))
+ raise Exception
+ else:
+ self.doc.act_end_date = chk[len(chk)-1]['timesheet_date']
+
+ def set_for_review(self):
+ self.check_non_submitted_timesheets()
+ self.validate_for_pending_review()
+ self.get_actual_total_hrs()
+ self.doc.review_date = nowdate()
+ self.doc.status = 'Pending Review'
+ self.doc.save()
+ return cstr('true')
+
+ def reopen_task(self):
+ self.doc.status = 'Open'
+ self.doc.save()
+ return cstr('true')
+
+ def declare_completed(self):
+ if self.doc.status == 'Open':
+ self.validate_for_pending_review()
+ self.doc.review_date = nowdate()
+ else:
+ self.validate_with_timesheet_dates()
+ self.validate_for_closed()
+
+ self.doc.closing_date = nowdate()
+ self.doc.status = 'Closed'
+ self.doc.docstatus = 1
+ self.doc.save()
+
+ self.remove_event_from_calender()
+ return cstr('true')
+
+ def remove_event_from_calender(self):
+ sql("delete from tabEvent where ref_type='Task' and ref_name=%s", self.doc.name)
+
+ def cancel_task(self):
+ chk = sql("select distinct t1.name from `tabTimesheet` t1, `tabTimesheet Detail` t2 where t2.parent = t1.name and t2.task_id = %s and t1.status!='Cancelled'", self.doc.name)
+ if chk:
+ chk_lst = [x[0] for x in chk]
+ msgprint("Timesheet(s) "+','.join(chk_lst)+" created against this task. Thus can not be cancelled")
+ raise Exception
+ else:
+ self.doc.status = 'Cancelled'
+ self.doc.docstatus = 2
+ self.remove_event_from_calender()
+ self.doc.save()
+ return cstr('true')
+
+
+ def add_calendar_event(self):
+ """ Add calendar event for task in calendar of Allocated person"""
+ event = Document('Event')
+ event.owner = self.doc.allocated_to
+ event.description = self.doc.name
+ event.event_date = self.doc.exp_start_date and self.doc.exp_start_date or ''
+ event.event_hour = self.doc.event_hour and self.doc.event_hour or '10:00'
+ event.event_type = 'Private'
+ event.ref_type = 'Task'
+ event.ref_name = self.doc.name
+ event.save(1)
diff --git a/erpnext/projects/doctype/ticket/ticket.txt b/erpnext/projects/doctype/ticket/ticket.txt
index e9d5ff0..5b8da14 100644
--- a/erpnext/projects/doctype/ticket/ticket.txt
+++ b/erpnext/projects/doctype/ticket/ticket.txt
@@ -5,17 +5,18 @@
{
'creation': '2011-01-28 17:52:35',
'docstatus': 0,
- 'modified': '2010-12-03 10:04:58',
+ 'modified': '2011-12-26 11:56:35',
'modified_by': 'Administrator',
'owner': 'Administrator'
},
# These values are common for all DocType
{
- '_last_update': '1307707462',
+ '_last_update': '1324880734',
'allow_trash': 1,
'autoname': 'TIC/.####',
'colour': 'White:FFF',
+ 'default_print_format': 'Standard',
'doctype': 'DocType',
'document_type': 'Master',
'module': 'Projects',
@@ -25,7 +26,7 @@
'show_in_menu': 0,
'subject': '%(subject)s',
'tag_fields': 'status',
- 'version': 245
+ 'version': 254
},
# These values are common for all DocField
@@ -44,7 +45,8 @@
'parent': 'Ticket',
'parentfield': 'permissions',
'parenttype': 'DocType',
- 'read': 1
+ 'read': 1,
+ 'submit': 0
},
# DocType, Ticket
@@ -55,11 +57,21 @@
# DocPerm
{
+ 'amend': 0,
+ 'cancel': 0,
+ 'create': 0,
+ 'doctype': 'DocPerm',
+ 'permlevel': 1,
+ 'role': 'Projects User',
+ 'write': 0
+ },
+
+ # DocPerm
+ {
'amend': 1,
'cancel': 1,
'create': 1,
'doctype': 'DocPerm',
- 'idx': 1,
'permlevel': 0,
'role': 'All',
'write': 1
@@ -67,8 +79,10 @@
# DocPerm
{
+ 'amend': 0,
+ 'cancel': 0,
+ 'create': 0,
'doctype': 'DocPerm',
- 'idx': 2,
'permlevel': 1,
'role': 'All',
'write': 0
@@ -80,25 +94,15 @@
'cancel': 1,
'create': 1,
'doctype': 'DocPerm',
- 'idx': 3,
'permlevel': 0,
'role': 'Projects User',
'write': 1
},
- # DocPerm
- {
- 'doctype': 'DocPerm',
- 'idx': 4,
- 'permlevel': 1,
- 'role': 'Projects User'
- },
-
# DocField
{
'doctype': 'DocField',
'fieldtype': 'Section Break',
- 'idx': 1,
'label': 'Task Details',
'oldfieldtype': 'Section Break',
'permlevel': 0,
@@ -111,7 +115,6 @@
'doctype': 'DocField',
'fieldname': 'subject',
'fieldtype': 'Data',
- 'idx': 2,
'in_filter': 1,
'label': 'Subject',
'oldfieldname': 'subject',
@@ -125,8 +128,8 @@
'doctype': 'DocField',
'fieldname': 'status',
'fieldtype': 'Select',
- 'idx': 3,
'label': 'Status',
+ 'no_copy': 1,
'oldfieldname': 'status',
'oldfieldtype': 'Select',
'options': 'Open\nPending Review\nClosed\nCancelled',
@@ -139,7 +142,6 @@
'doctype': 'DocField',
'fieldname': 'opening_date',
'fieldtype': 'Date',
- 'idx': 4,
'label': 'Creation Date',
'oldfieldname': 'opening_date',
'oldfieldtype': 'Date',
@@ -155,7 +157,6 @@
'fieldname': 'review_date',
'fieldtype': 'Date',
'hidden': 1,
- 'idx': 5,
'label': 'Review Date',
'oldfieldname': 'review_date',
'oldfieldtype': 'Date',
@@ -170,7 +171,6 @@
'fieldname': 'closing_date',
'fieldtype': 'Date',
'hidden': 1,
- 'idx': 6,
'label': 'Closing Date',
'oldfieldname': 'closing_date',
'oldfieldtype': 'Date',
@@ -182,7 +182,6 @@
'doctype': 'DocField',
'fieldname': 'priority',
'fieldtype': 'Select',
- 'idx': 7,
'in_filter': 1,
'label': 'Priority',
'oldfieldname': 'priority',
@@ -199,7 +198,6 @@
'doctype': 'DocField',
'fieldname': 'project',
'fieldtype': 'Link',
- 'idx': 8,
'label': 'Project',
'oldfieldname': 'project',
'oldfieldtype': 'Link',
@@ -214,7 +212,6 @@
'doctype': 'DocField',
'fieldname': 'customer',
'fieldtype': 'Link',
- 'idx': 9,
'label': 'Customer',
'oldfieldname': 'customer',
'oldfieldtype': 'Link',
@@ -228,7 +225,6 @@
'doctype': 'DocField',
'fieldname': 'customer_name',
'fieldtype': 'Data',
- 'idx': 10,
'label': 'Customer Name',
'oldfieldname': 'customer_name',
'oldfieldtype': 'Data',
@@ -239,7 +235,6 @@
{
'doctype': 'DocField',
'fieldtype': 'Column Break',
- 'idx': 11,
'oldfieldtype': 'Column Break',
'permlevel': 0,
'width': '50%'
@@ -247,11 +242,21 @@
# DocField
{
+ 'doctype': 'DocField',
+ 'fieldname': 'allocated_to_old',
+ 'fieldtype': 'Link',
+ 'hidden': 1,
+ 'label': 'Allocated To Old',
+ 'no_copy': 1,
+ 'permlevel': 0
+ },
+
+ # DocField
+ {
'colour': 'White:FFF',
'doctype': 'DocField',
'fieldname': 'allocated_to',
'fieldtype': 'Link',
- 'idx': 12,
'label': 'Allocated To',
'oldfieldname': 'allocated_to',
'oldfieldtype': 'Link',
@@ -263,10 +268,18 @@
# DocField
{
'doctype': 'DocField',
+ 'fieldname': 'task_email_notify',
+ 'fieldtype': 'Check',
+ 'label': 'Sent Mail Notification',
+ 'permlevel': 0
+ },
+
+ # DocField
+ {
+ 'doctype': 'DocField',
'fieldname': 'allocated_to_name',
'fieldtype': 'Data',
'hidden': 1,
- 'idx': 13,
'label': 'Allocated To Name',
'oldfieldname': 'allocated_to_name',
'oldfieldtype': 'Data',
@@ -276,9 +289,19 @@
# DocField
{
'doctype': 'DocField',
+ 'fieldname': 'sent_reminder',
+ 'fieldtype': 'Data',
+ 'hidden': 1,
+ 'label': 'Sent Reminder',
+ 'no_copy': 1,
+ 'permlevel': 0
+ },
+
+ # DocField
+ {
+ 'doctype': 'DocField',
'fieldname': 'senders_name',
'fieldtype': 'Data',
- 'idx': 14,
'in_filter': 1,
'label': 'Raised By',
'oldfieldname': 'senders_name',
@@ -293,7 +316,6 @@
'doctype': 'DocField',
'fieldname': 'senders_email',
'fieldtype': 'Data',
- 'idx': 15,
'label': 'Email',
'oldfieldname': 'senders_email',
'oldfieldtype': 'Data',
@@ -306,7 +328,6 @@
'doctype': 'DocField',
'fieldname': 'senders_contact_no',
'fieldtype': 'Data',
- 'idx': 16,
'label': 'Senders Contact No',
'oldfieldname': 'senders_contact_no',
'oldfieldtype': 'Data',
@@ -318,7 +339,6 @@
'doctype': 'DocField',
'fieldname': 'senders_company',
'fieldtype': 'Data',
- 'idx': 17,
'label': 'Senders Company',
'oldfieldname': 'senders_company',
'oldfieldtype': 'Data',
@@ -330,7 +350,6 @@
'doctype': 'DocField',
'fieldname': 'category',
'fieldtype': 'Link',
- 'idx': 18,
'label': 'Category',
'oldfieldname': 'category',
'oldfieldtype': 'Link',
@@ -343,7 +362,6 @@
'doctype': 'DocField',
'fieldname': 'external_or_internal',
'fieldtype': 'Select',
- 'idx': 19,
'label': 'External or Internal',
'oldfieldname': 'external_or_internal',
'oldfieldtype': 'Select',
@@ -357,7 +375,6 @@
'fieldname': 'amended_from',
'fieldtype': 'Data',
'hidden': 1,
- 'idx': 20,
'label': 'Amended From',
'no_copy': 1,
'oldfieldname': 'amended_from',
@@ -373,7 +390,6 @@
'fieldname': 'amendment_date',
'fieldtype': 'Date',
'hidden': 1,
- 'idx': 21,
'label': 'Amendment Date',
'no_copy': 1,
'oldfieldname': 'amendment_date',
@@ -387,7 +403,6 @@
{
'doctype': 'DocField',
'fieldtype': 'Section Break',
- 'idx': 22,
'oldfieldtype': 'Section Break',
'options': 'Simple',
'permlevel': 0
@@ -398,7 +413,6 @@
'doctype': 'DocField',
'fieldname': 'description',
'fieldtype': 'Text Editor',
- 'idx': 23,
'label': 'Details',
'oldfieldname': 'description',
'oldfieldtype': 'Text Editor',
@@ -414,7 +428,6 @@
'fieldname': 'first_creation_flag',
'fieldtype': 'Int',
'hidden': 1,
- 'idx': 24,
'in_filter': 0,
'label': 'First Creation Flag',
'no_copy': 1,
@@ -431,7 +444,6 @@
'fieldname': 'second_creation_flag',
'fieldtype': 'Int',
'hidden': 1,
- 'idx': 25,
'label': 'Second Creation Flag',
'no_copy': 1,
'oldfieldname': 'second_creation_flag',
@@ -444,7 +456,6 @@
{
'doctype': 'DocField',
'fieldtype': 'Section Break',
- 'idx': 26,
'label': 'Time and Budget',
'oldfieldtype': 'Section Break',
'permlevel': 0
@@ -454,7 +465,6 @@
{
'doctype': 'DocField',
'fieldtype': 'Column Break',
- 'idx': 27,
'label': 'Expected',
'oldfieldtype': 'Column Break',
'permlevel': 0,
@@ -466,7 +476,6 @@
'doctype': 'DocField',
'fieldname': 'exp_start_date',
'fieldtype': 'Date',
- 'idx': 28,
'label': 'Expected Start Date',
'oldfieldname': 'exp_start_date',
'oldfieldtype': 'Date',
@@ -479,7 +488,6 @@
'doctype': 'DocField',
'fieldname': 'exp_end_date',
'fieldtype': 'Date',
- 'idx': 29,
'in_filter': 1,
'label': 'Expected End Date',
'oldfieldname': 'exp_end_date',
@@ -494,7 +502,6 @@
'doctype': 'DocField',
'fieldname': 'exp_total_hrs',
'fieldtype': 'Data',
- 'idx': 30,
'label': 'Total Hours (Expected)',
'oldfieldname': 'exp_total_hrs',
'oldfieldtype': 'Data',
@@ -507,7 +514,6 @@
'doctype': 'DocField',
'fieldname': 'allocated_budget',
'fieldtype': 'Currency',
- 'idx': 31,
'label': 'Allocated Budget',
'oldfieldname': 'allocated_budget',
'oldfieldtype': 'Currency',
@@ -518,7 +524,6 @@
{
'doctype': 'DocField',
'fieldtype': 'Column Break',
- 'idx': 32,
'label': 'Actual',
'oldfieldtype': 'Column Break',
'permlevel': 0,
@@ -530,7 +535,6 @@
'doctype': 'DocField',
'fieldname': 'act_start_date',
'fieldtype': 'Date',
- 'idx': 33,
'label': 'Actual Start Date',
'oldfieldname': 'act_start_date',
'oldfieldtype': 'Date',
@@ -542,7 +546,6 @@
'doctype': 'DocField',
'fieldname': 'act_end_date',
'fieldtype': 'Date',
- 'idx': 34,
'label': 'Actual End Date',
'oldfieldname': 'act_end_date',
'oldfieldtype': 'Date',
@@ -554,7 +557,6 @@
'doctype': 'DocField',
'fieldname': 'act_total_hrs',
'fieldtype': 'Data',
- 'idx': 35,
'label': 'Total Hours (Actual)',
'oldfieldname': 'act_total_hrs',
'oldfieldtype': 'Data',
@@ -566,7 +568,6 @@
'doctype': 'DocField',
'fieldname': 'actual_budget',
'fieldtype': 'Currency',
- 'idx': 36,
'label': 'Actual Budget',
'oldfieldname': 'actual_budget',
'oldfieldtype': 'Currency',
diff --git a/erpnext/sandbox/test_leave.py b/erpnext/sandbox/test_leave.py
new file mode 100644
index 0000000..cc2149f
--- /dev/null
+++ b/erpnext/sandbox/test_leave.py
@@ -0,0 +1,55 @@
+import unittest
+
+import webnotes
+import webnotes.profile
+webnotes.user = webnotes.profile.Profile()
+
+
+from webnotes.model.doc import Document
+from webnotes.model.code import get_obj
+from webnotes.utils import cstr, flt
+from webnotes.model.doclist import getlist
+sql = webnotes.conn.sql
+
+from sandbox.testdata import leaves
+#----------------------------------------------------------
+
+
+class TestStockEntry(unittest.TestCase):
+ #===========================================================================
+ def setUp(self):
+ webnotes.conn.begin()
+ leaves.emp.save(new = 1, make_autoname = 0)
+
+ def test_leave_bal(self):
+ leaves.l_all.save(1)
+ leaves.l_app1.save(1)
+ leaves.l_app2.save(1)
+
+ la1 = get_obj('Leave Application', leaves.l_app1.name, with_children=1)
+ la1.validate()
+ la1.doc.docstatus = 1
+ la1.doc.save()
+
+ self.assertTrue(la1.doc.total_leave_days == 2)
+
+ la1.doc.half_day = 1
+ la1.validate()
+ la1.doc.save()
+
+ self.assertTrue(la1.doc.total_leave_days == .5)
+
+ print "Test case for leave applied no of days"
+
+
+ la2 = get_obj('Leave Application', leaves.l_app2.name, with_children=1)
+ la2.validate()
+ bal = la2.get_leave_balance()
+ self.assertTrue(bal, 18)
+ print "Test case for leave balance"
+
+
+
+
+ def tearDown(self):
+ webnotes.conn.rollback()
diff --git a/erpnext/sandbox/test_stock_entry.py b/erpnext/sandbox/test_stock_entry.py
index f1035bc..d1e0097 100644
--- a/erpnext/sandbox/test_stock_entry.py
+++ b/erpnext/sandbox/test_stock_entry.py
@@ -101,7 +101,7 @@
self.save_stock_entry('Material Transfer')
mtn = get_obj('Stock Entry', stock_entry.mtn[0].name, with_children=1)
- tn = self.submit_stock_entry(mtn)
+ mtn = self.submit_stock_entry(mtn)
# stock ledger entry
print "Checking stock ledger entry........."
@@ -202,8 +202,54 @@
[{'doctype': 'Serial No', 'item_code': 'it', 'warehouse': 'wh1', 'status': 'In Store', 'docstatus': 0}, 10]
])
+ #===========================================================================
+ def test_entries_on_same_datetime(self):
+ print "Test Case: Multiple entries on same datetime, cancel first one"
+ # submitted 1st MR
+ self.save_stock_entry('Material Receipt')
+ mr = get_obj('Stock Entry', stock_entry.mr[0].name, with_children=1)
+ mr = self.submit_stock_entry(mr)
+
+ # submitted 2nd MR
+ for each in stock_entry.mr1:
+ each.save(1)
+ for t in stock_entry.mr1[1:]:
+ sql("update `tabStock Entry Detail` set parent = '%s' where name = '%s'" % (stock_entry.mr1[0].name, t.name))
+
+ mr1 = get_obj('Stock Entry', stock_entry.mr1[0].name, with_children=1)
+ mr1 = self.submit_stock_entry(mr1)
+
+ # submitted MTN
+ self.save_stock_entry('Material Transfer')
+ mtn = get_obj('Stock Entry', stock_entry.mtn[0].name, with_children=1)
+ mtn = self.submit_stock_entry(mtn)
+
+ # cancel prev MR
+ mr.on_cancel()
+ mr.doc.cancel_reason = "testing"
+ mr.doc.docstatus = 2
+ mr.doc.save()
+
+
+ # stock ledger entry
+ print "Checking stock ledger entry........."
+ self.assertDoc(self.get_expected_sle('entries_on_same_datetime'))
+
+ # bin qty
+ print "Checking Bin qty........."
+ self.assertDoc([
+ {'doctype':'Bin', 'actual_qty':0, 'item_code':'it', 'warehouse':'wh1'},
+ {'doctype':'Bin', 'actual_qty':5, 'item_code':'it', 'warehouse':'wh2'}
+ ])
+
+ # serial no
+ self.assertCount([
+ [{'doctype': 'Serial No', 'item_code': 'it', 'warehouse': 'wh1', 'status': 'In Store', 'docstatus': 0}, 0],
+ [{'doctype': 'Serial No', 'item_code': 'it', 'warehouse': 'wh2', 'status': 'In Store', 'docstatus': 0}, 5]
+ ])
+
#===========================================================================
def save_stock_entry(self, t):
if t == 'Material Receipt':
@@ -373,8 +419,58 @@
'ifnull(bin_aqat, 0)': 0,
'ifnull(valuation_rate, 0)': 0,
"ifnull(is_cancelled, 'No')": 'Yes'
+ }],
+ 'entries_on_same_datetime': [{
+ 'doctype': 'Stock Ledger Entry',
+ 'item_code':'it',
+ 'warehouse':'wh1',
+ 'voucher_type': 'Stock Entry',
+ 'voucher_no': stock_entry.mr[0].name,
+ 'actual_qty': 10,
+ 'bin_aqat': 10,
+ 'valuation_rate': 100,
+ 'is_cancelled': 'Yes'
+ }, {
+ 'doctype': 'Stock Ledger Entry',
+ 'item_code':'it',
+ 'warehouse':'wh1',
+ 'voucher_type': 'Stock Entry',
+ 'voucher_no': stock_entry.mr[0].name,
+ 'actual_qty': -10,
+ 'ifnull(bin_aqat, 0)': 0,
+ 'ifnull(valuation_rate, 0)': 0,
+ "ifnull(is_cancelled, 'No')": 'Yes'
+ }, {
+ 'doctype': 'Stock Ledger Entry',
+ 'item_code':'it',
+ 'warehouse':'wh1',
+ 'voucher_type': 'Stock Entry',
+ 'voucher_no': stock_entry.mr1[0].name,
+ 'actual_qty': 5,
+ 'bin_aqat': 5,
+ 'valuation_rate': 400,
+ 'is_cancelled': 'No'
+ }, {
+ 'doctype': 'Stock Ledger Entry',
+ 'item_code':'it',
+ 'warehouse':'wh1',
+ 'voucher_type': 'Stock Entry',
+ 'voucher_no': stock_entry.mtn[0].name,
+ 'actual_qty': -5,
+ 'bin_aqat': 0,
+ 'valuation_rate': 400,
+ 'is_cancelled': 'No'
+ }, {
+ 'doctype': 'Stock Ledger Entry',
+ 'item_code':'it',
+ 'warehouse':'wh2',
+ 'voucher_type': 'Stock Entry',
+ 'voucher_no': stock_entry.mtn[0].name,
+ 'actual_qty': 5,
+ 'bin_aqat': 5,
+ 'valuation_rate': 100,
+ 'is_cancelled': 'No'
}]
-
}
return expected_sle[action]
diff --git a/erpnext/sandbox/test_stock_reco.py b/erpnext/sandbox/test_stock_reco.py
new file mode 100644
index 0000000..bcde49e
--- /dev/null
+++ b/erpnext/sandbox/test_stock_reco.py
@@ -0,0 +1,94 @@
+import unittest
+
+import webnotes
+import webnotes.profile
+webnotes.user = webnotes.profile.Profile()
+
+
+from webnotes.model.doc import Document
+from webnotes.model.code import get_obj
+from webnotes.utils import cstr, flt
+from webnotes.model.doclist import getlist
+sql = webnotes.conn.sql
+
+from sandbox.testdata.masters import *
+from sandbox.testdata.sle_data import sle, bin
+from sandbox.testdata.stock_reco import *
+#----------------------------------------------------------
+
+
+class TestStockEntry(unittest.TestCase):
+ def assertDoc(self, lst):
+ """assert all values"""
+ for d in lst:
+ cl, vl = [], []
+ for k in d.keys():
+ if k!='doctype':
+ cl.append('%s=%s' % (k, '%s'))
+ vl.append(d[k])
+
+ self.assertTrue(sql("select name from `tab%s` where %s limit 1" % (d['doctype'], ' and '.join(cl)), vl))
+
+ #===========================================================================
+ def setUp(self):
+ print "====================================="
+ webnotes.conn.begin()
+ create_master_records()
+ print 'Master Data Created'
+
+ for d in sle:
+ d.save(1)
+ print "Existing SLE created"
+
+ bin.save(1)
+
+ sreco.save(1)
+ print "Stock Reco saved"
+
+ #===========================================================================
+ def test_diff_in_both(self):
+ reco = get_obj('Stock Reconciliation', sreco.name)
+ reco.doc.docstatus = 1
+ reco.doc.save()
+ reco.validate()
+ reco.on_submit()
+ print "Stock Reco submitted"
+
+ print "Checking stock ledger entry........."
+ self.assertDoc(self.get_expected_sle('diff_in_both'))
+
+ #===========================================================================
+ def tearDown(self):
+ webnotes.conn.rollback()
+
+ # Expected Result Set
+ #===================================================================================================
+ def get_expected_sle(self, action):
+ expected_sle = {
+ 'diff_in_both': [{
+ 'doctype': 'Stock Ledger Entry',
+ 'item_code':'it',
+ 'warehouse':'wh1',
+ 'voucher_type': 'Stock Reconciliation',
+ 'voucher_no': sreco.name,
+ 'actual_qty': 15,
+ 'bin_aqat': 20,
+ 'valuation_rate': 150,
+ #'stock_value': 3000,
+ 'is_cancelled': 'No'
+ },{
+ 'doctype': 'Stock Ledger Entry',
+ 'posting_date': '2011-09-10',
+ 'posting_time': '15:00',
+ 'item_code': 'it',
+ 'warehouse': 'wh1',
+ 'actual_qty': 20,
+ 'incoming_rate': 200,
+ 'bin_aqat': 40,
+ 'valuation_rate': 175,
+ #'stock_value': 4500,
+ 'is_cancelled': 'No'
+ }
+ ]
+ }
+ return expected_sle[action]
diff --git a/erpnext/sandbox/testdata/leaves.py b/erpnext/sandbox/testdata/leaves.py
new file mode 100644
index 0000000..8d44ffb
--- /dev/null
+++ b/erpnext/sandbox/testdata/leaves.py
@@ -0,0 +1,54 @@
+from webnotes.model.doc import Document
+
+emp = Document(
+ fielddata = {
+ 'doctype': 'Employee',
+ 'name': 'emp1',
+ 'employee_name': 'Nijil',
+ 'status': 'Active',
+ 'date_of_joining': '2011-01-01'
+ }
+)
+
+
+
+l_all = Document(
+ fielddata = {
+ 'doctype' : 'Leave Allocation',
+ 'name': 'l_all',
+ 'employee' : 'emp1',
+ 'leave_type' : 'Casual Leave',
+ 'posting_date': '2011-03-01',
+ 'fiscal_year': '2011-2012',
+ 'total_leaves_allocated': 20,
+ 'docstatus': 1
+ }
+)
+
+l_app1 = Document(
+ fielddata = {
+ 'doctype' : 'Leave Application',
+ 'name': 'l_app1',
+ 'employee' : 'emp1',
+ 'leave_type' : 'Casual Leave',
+ 'posting_date': '2011-03-01',
+ 'fiscal_year': '2011-2012',
+ 'from_date': '2011-08-01',
+ 'to_date': '2011-08-02',
+ 'total_leave_days': 2
+ }
+)
+
+l_app2 = Document(
+ fielddata = {
+ 'doctype' : 'Leave Application',
+ 'name': 'l_app2',
+ 'employee' : 'emp1',
+ 'leave_type' : 'Casual Leave',
+ 'posting_date': '2011-03-01',
+ 'fiscal_year': '2011-2012',
+ 'from_date': '2011-08-15',
+ 'to_date': '2011-08-17',
+ 'total_leave_days': 3
+ }
+)
diff --git a/erpnext/sandbox/testdata/sle_data.py b/erpnext/sandbox/testdata/sle_data.py
new file mode 100644
index 0000000..eab0376
--- /dev/null
+++ b/erpnext/sandbox/testdata/sle_data.py
@@ -0,0 +1,85 @@
+from webnotes.model.doc import Document
+
+# Existing SLE data
+#---------------------------
+
+sle = [
+ Document(
+ fielddata = {
+ 'doctype': 'Stock Ledger Entry',
+ 'name': 'sle1',
+ 'posting_date': '2011-09-01',
+ 'posting_time': '12:00',
+ 'item_code': 'it',
+ 'warehouse': 'wh1',
+ 'actual_qty': 10,
+ 'incoming_rate': 100,
+ 'bin_aqat': 10,
+ 'valuation_rate': 100,
+ 'fcfs_stack': '',
+ 'stock_value': 1000,
+ 'is_cancelled': 'No'
+ }
+ ),
+ Document(
+ fielddata = {
+ 'doctype': 'Stock Ledger Entry',
+ 'name': 'sle2',
+ 'posting_date': '2011-09-01',
+ 'posting_time': '12:00',
+ 'item_code': 'it',
+ 'warehouse': 'wh1',
+ 'actual_qty': -5,
+ 'incoming_rate': 100,
+ 'bin_aqat': 5,
+ 'valuation_rate': 100,
+ 'fcfs_stack': '',
+ 'stock_value': 500,
+ 'is_cancelled': 'No'
+ }
+ ),
+ Document(
+ fielddata = {
+ 'doctype': 'Stock Ledger Entry',
+ 'name': 'sle3',
+ 'posting_date': '2011-09-10',
+ 'posting_time': '15:00',
+ 'item_code': 'it',
+ 'warehouse': 'wh1',
+ 'actual_qty': 20,
+ 'incoming_rate': 200,
+ 'bin_aqat': 25,
+ 'valuation_rate': 180,
+ 'fcfs_stack': '',
+ 'stock_value': 4500,
+ 'is_cancelled': 'No'
+ }
+ ),
+ Document(
+ fielddata = {
+ 'doctype': 'Stock Ledger Entry',
+ 'name': 'sle4',
+ 'posting_date': '2011-09-15',
+ 'posting_time': '09:30',
+ 'item_code': 'it',
+ 'warehouse': 'wh1',
+ 'actual_qty': -5,
+ 'incoming_rate': 180,
+ 'bin_aqat': 20,
+ 'valuation_rate': 180,
+ 'fcfs_stack': '',
+ 'stock_value': 3600,
+ 'is_cancelled': 'No'
+ }
+ )
+]
+
+bin = Document(
+ fielddata = {
+ 'doctype': 'Bin',
+ 'name': 'bin01',
+ 'item_code': 'it',
+ 'warehouse': 'wh1',
+ 'actual_qty': 20,
+ }
+)
diff --git a/erpnext/sandbox/testdata/stock_entry.py b/erpnext/sandbox/testdata/stock_entry.py
index 8f2a30c..3316016 100644
--- a/erpnext/sandbox/testdata/stock_entry.py
+++ b/erpnext/sandbox/testdata/stock_entry.py
@@ -34,6 +34,38 @@
)
]
+mr1 = [
+ Document(
+ fielddata = {
+ 'doctype': 'Stock Entry',
+ 'posting_date': '2011-09-01',
+ 'transfer_date': '2011-09-01',
+ 'posting_time': '12:00',
+ 'company': 'comp',
+ 'fiscal_year' : '2011-2012',
+ 'purpose': 'Material Receipt',
+ 'name': 'mr1'
+ }
+ ),
+ Document(
+ fielddata ={
+ 'doctype': 'Stock Entry Detail',
+ 'parenttype': 'Stock Entry',
+ 'parentfield' : 'mtn_details',
+ 'parent' : 'mr1',
+ 'item_code' : 'it',
+ 't_warehouse' : 'wh1',
+ 'qty' : 5,
+ 'transfer_qty' : 5,
+ 'incoming_rate': 400,
+ 'stock_uom': 'Nos',
+ 'conversion_factor': 1,
+ 'serial_no': 'srno11, srno12, srno13, srno14, srno15'
+ }
+ )
+]
+
+
# Material Transfer
#--------------------
@@ -43,7 +75,7 @@
'doctype': 'Stock Entry',
'posting_date': '2011-09-01',
'transfer_date': '2011-09-01',
- 'posting_time': '13:00',
+ 'posting_time': '12:00',
'company': 'comp',
'fiscal_year' : '2011-2012',
'purpose': 'Material Transfer',
diff --git a/erpnext/sandbox/testdata/stock_reco.py b/erpnext/sandbox/testdata/stock_reco.py
new file mode 100644
index 0000000..efcbbc5
--- /dev/null
+++ b/erpnext/sandbox/testdata/stock_reco.py
@@ -0,0 +1,43 @@
+from webnotes.model.doc import Document
+
+# Stock Reconciliation
+#---------------------------
+
+sreco = Document(
+ fielddata = {
+ 'doctype': 'Stock Reconciliation',
+ 'name': 'sreco',
+ 'reconciliation_date': '2011-09-08',
+ 'reconciliation_time': '20:00',
+ }
+ )
+
+# diff in both
+csv_data1 = [
+ ['Item', 'Warehouse', 'Quantity', 'Rate'],
+ ['it', 'wh1', 20, 150]
+]
+
+# diff in qty, no rate
+csv_data2 = [
+ ['Item', 'Warehouse', 'Quantity'],
+ ['it', 'wh1', 20]
+]
+
+# diff in rate, no qty
+csv_data3 = [
+ ['Item', 'Warehouse', 'Rate'],
+ ['it', 'wh1', 200]
+]
+
+# diff in rate, same qty
+csv_data4 = [
+ ['Item', 'Warehouse', 'Quantity', 'Rate'],
+ ['it', 'wh1', 5, 200]
+]
+
+# no diff
+csv_data1 = [
+ ['Item', 'Warehouse', 'Quantity', 'Rate'],
+ ['it', 'wh1', 5, 100]
+]
diff --git a/erpnext/selling/Print Format/Quotation Classic/Quotation Classic.txt b/erpnext/selling/Print Format/Quotation Classic/Quotation Classic.txt
new file mode 100644
index 0000000..0650f30
--- /dev/null
+++ b/erpnext/selling/Print Format/Quotation Classic/Quotation Classic.txt
@@ -0,0 +1,28 @@
+# Print Format, Quotation Classic
+[
+
+ # These values are common in all dictionaries
+ {
+ 'creation': '2011-12-13 11:02:59',
+ 'docstatus': 0,
+ 'modified': '2011-12-13 12:12:22',
+ 'modified_by': 'Administrator',
+ 'owner': 'Administrator'
+ },
+
+ # These values are common for all Print Format
+ {
+ 'doc_type': 'Quotation',
+ 'doctype': 'Print Format',
+ 'html': '<!--\n\tSample Print Format for ERPNext\n\tPlease use at your own discretion\n\tFor suggestions and contributions:\n\t\thttps://github.com/webnotes/erpnext-print-templates\n\n\tFreely usable under MIT license\n-->\n\n<!-- Style Settings -->\n<style>\n\t/*\n\t\tcommon style for whole page\n\t\tThis should include:\n\t\t+ page size related settings\n\t\t+ font family settings\n\t\t+ line spacing settings\n\t*/\n\t@media screen {\n\t\tbody {\n\t\t\twidth: 8.3in;\n\t\t}\n\t}\n\n\thtml, body, div, span, td {\n\t\tfont-family: "Georgia", serif;\n\t\tfont-size: 12px;\n\t}\n\n\tbody {\n\t\tpadding: 10px;\n\t\tmargin: auto;\n\t\tfont-size: 12px;\n\t\tline-height: 150%;\n\t}\n\n\t.common {\n\t\tfont-family: "Georgia", serif !important;\n\t\tfont-size: 12px;\n\t\tpadding: 10px 0px;\n\t}\n\n\ttable {\n\t\tborder-collapse: collapse;\n\t\twidth: 100%;\n\t\tvertical-align: top;\n\t}\n\n\ttable td {\n\t\tpadding: 2px 0px;\n\t}\n\t\n\ttable h1, h2, h3, h4, h5, h6 {\n\t\tpadding: 0px;\n\t\tmargin: 0px;\n\t}\n\n\ttable.header-table td {\n\t\tvertical-align: top;\n\t}\n\n\ttable.header-table thead {\n\t\tborder-bottom: 1px solid black;\n\t}\n\n\ttable.header-table h3 {\n\t\tcolor: gray;\n\t}\n\n\ttable.header-table thead td {\n\t\tpadding: 5px 0px;\n\t}\n\n\tdiv.page-body table td:nth-child(6),\n\tdiv.page-body table td:nth-child(7) {\n\t\ttext-align: right;\n\t}\n\n\ttable.footer-table td {\n\t\tvertical-align: top;\n\t}\n\n\ttable.footer-table td table td:nth-child(2),\n\ttable.footer-table td table td:nth-child(3) {\n\t\ttext-align: right;\n\t}\n</style>\n\n\n<!-- Javascript -->\n<script>\n\tsi_std = {\n\t\tprint_item_table: function() {\n\t\t\tvar table = print_table(\n\t\t\t\t\'Quotation\',\n\t\t\t\tdoc.name,\n\t\t\t\t\'quotation_details\',\n\t\t\t\t\'Quotation Detail\',\n\t\t\t\t[// Here specify the table columns to be displayed\n\t\t\t\t\t\'SR\', \'item_code\', \'item_name\', \'description\', \'qty\', \'stock_uom\',\n\t\t\t\t\t\'export_rate\', \'export_amount\'\n\t\t\t\t],\n\t\t\t\t[// Here specify the labels of column headings\n\t\t\t\t\t\'Sr\', \'Item Code\', \'Item Name\', \'Description\', \'Qty\',\n\t\t\t\t\t\'UoM\', \'Basic Rate\', \'Amount\'\n\t\t\t\t],\n\t\t\t\t[// Here specify the column widths\n\t\t\t\t\t\'3%\', \'10%\', \'15%\', \'32%\', \'5%\',\n\t\t\t\t\t\'5%\', \'15%\', \'15%\'\n\t\t\t\t],\n\t\t\t\tnull,\n\t\t\t\tnull,\n\t\t\t\t{\n\t\t\t\t\t\'description\' : function(data_row) {\n\t\t\t\t\t\tif(data_row.adj_rate) {\n\t\t\t\t\t\t\tvar to_append = \'<div style="padding-left: 15px;"><i>Discount: \' + \n\t\t\t\t\t\t\t\tdata_row.adj_rate + \'%</i></div>\';\n\t\t\t\t\t\t\tif(data_row.description.indexOf(to_append)==-1) {\n\t\t\t\t\t\t\t\treturn data_row.description + to_append;\n\t\t\t\t\t\t\t} else { return data_row.description; }\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\treturn data_row.description;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t);\n\n\t\t\t// This code takes care of page breaks\n\t\t\tif(table.appendChild) {\n\t\t\t\tout = table.innerHTML;\n\t\t\t} else {\n\t\t\t\tout = \'\';\n\t\t\t\tfor(var i=0; i < (table.length-1); i++) {\n\t\t\t\t\tout += table[i].innerHTML + \n\t\t\t\t\t\t\'<div style = "page-break-after: always;" \\\n\t\t\t\t\t\tclass = "page_break"></div>\\\n\t\t\t\t\t\t<div class="page-settings"></div>\';\n\t\t\t\t}\n\t\t\t\tout += table[table.length-1].innerHTML;\n\t\t\t}\n\t\t\treturn out;\n\t\t},\n\n\n\t\tprint_other_charges: function(parent) {\n\t\t\tvar oc = getchildren(\'RV Tax Detail\', doc.name, \'other_charges\');\n\t\t\tvar rows = \'<table width=100%>\\n\';\n\t\t\tfor(var i=0; i<oc.length; i++) {\n\t\t\t\trows +=\n\t\t\t\t\t\'<tr>\\n\' +\n\t\t\t\t\t\t\'\\t<td>\' + oc[i].description + \'</td>\\n\' +\n\t\t\t\t\t\t\'\\t<td></td>\\n\' +\n\t\t\t\t\t\t\'\\t<td width=38%>\' + fmt_money(oc[i].tax_amount) + \'</td>\\n\' +\n\t\t\t\t\t\'</tr>\\n\';\n\t\t\t}\n\t\t\treturn rows + \'</table>\\n\';\n\t\t}\n\t};\n</script>\n\n\n<!-- Page Layout Settings -->\n<div class=\'common page-header\'>\n\t<!-- \n\t\tPage Header will contain\n\t\t\t+ table 1\n\t\t\t\t+ table 1a\n\t\t\t\t\t- Name\n\t\t\t\t\t- Address\n\t\t\t\t\t- Contact\n\t\t\t\t\t- Mobile No\n\t\t\t\t+ table 1b\n\t\t\t\t\t- Voucher Date\n\t\t\t\t\t- Due Date\n\t-->\n\t<table class=\'header-table\' cellspacing=0>\n\t\t<thead>\n\t\t\t<tr><td>\n\t\t\t\t\t<script>\'<h1>\' + (doc.select_print_heading || \'Quotation\') + \'</h1>\'</script>\n\t\t\t</td></tr>\n\t\t\t<tr><td><h3><script>cur_frm.docname</script></h3></td></tr>\n\t\t</thead>\n\t\t<tbody>\n\t\t\t<tr>\n\t\t\t\t<td width=60%><table width=100% cellspacing=0><tbody>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td width=39%><b>Name</b></td>\n\t\t\t\t\t\t<td><script>doc.customer?doc.customer:doc.lead_name</script></td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td><b>Address</b></td>\n\t\t\t\t\t\t<td><script>replace_newlines(doc.address_display)</script></td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td><b>Contact</b></td>\n\t\t\t\t\t\t<td><script>doc.contact_display</script></td>\n\t\t\t\t\t</tr>\n\t\t\t\t</tbody></table></td>\n\t\t\t\t<td><table width=100% cellspacing=0><tbody>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td width=63%><b>Quotation Date</b></td>\n\t\t\t\t\t\t<td><script>date.str_to_user(doc.transaction_date)</script></td>\n\t\t\t\t\t<tr>\t\t\t\t\t\n\t\t\t\t</tbody></table></td>\n\t\t\t</tr>\n\t\t</tbody>\n\t\t<tfoot>\n\t\t\n\t\t</tfoot>\n\t</table>\n</div>\n<div class=\'common page-body\'>\n\t<!-- \n\t\tPage Body will contain\n\t\t\t+ table 2\n\t\t\t\t- Sales Invoice Data\n\t-->\n\t<script>si_std.print_item_table()</script>\n</div>\n<div class=\'common page-footer\'>\n\t<!-- \n\t\tPage Footer will contain\n\t\t\t+ table 3\n\t\t\t\t- Terms and Conditions\n\t\t\t\t- Total Rounded Amount Calculation\n\t\t\t\t- Total Rounded Amount in Words\n\t-->\n\t<table class=\'footer-table\' width=100% cellspacing=0>\n\t\t<thead>\n\t\t\t\n\t\t</thead>\n\t\t<tbody>\n\t\t\t<tr>\n\t\t\t\t<td width=60% style=\'padding-right: 10px;\'>\n\t\t\t\t\t<b>Terms, Conditions & Other Information:</b><br />\n\t\t\t\t\t<script>doc.terms</script>\n\t\t\t\t</td>\n\t\t\t\t<td>\n\t\t\t\t\t<table cellspacing=0 width=100%><tbody>\n\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t<td>Net Total</td>\n\t\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t\t<td width=38%><script>\n\t\t\t\t\t\t\t\tfmt_money(doc.net_total/doc.conversion_rate)\n\t\t\t\t\t\t\t</script></td>\n\t\t\t\t\t\t</tr>\n\t\t\t\t\t\t<tr><td colspan=3><script>si_std.print_other_charges()</script></td></tr>\n\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t<td>Grand Total</td>\n\t\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t\t<td><script>\n\t\t\t\t\t\t\t\tfmt_money(doc.grand_total_export)\n\t\t\t\t\t\t\t</script></td>\n\t\t\t\t\t\t</tr>\n\t\t\t\t\t\t<tr style=\'font-weight: bold\'>\n\t\t\t\t\t\t\t<td>Rounded Total</td>\n\t\t\t\t\t\t\t<td><script>doc.currency</script></td>\n\t\t\t\t\t\t\t<td><script>\n\t\t\t\t\t\t\t\tfmt_money(doc.rounded_total_export)\n\t\t\t\t\t\t\t</script></td>\n\t\t\t\t\t\t</tr>\n\t\t\t\t\t</tbody></table>\n\t\t\t\t\t<br /><b>In Words</b><br />\n\t\t\t\t\t<i><script>doc.in_words_export</script></i>\n\t\t\t\t</td>\n\t\t\t</tr>\t\t\n\t\t</tbody>\n\t\t<tfoot>\n\t\t\n\t\t</tfoot>\n\t</table>\n</div>\n',
+ 'module': 'Selling',
+ 'name': '__common__',
+ 'standard': 'Yes'
+ },
+
+ # Print Format, Quotation Classic
+ {
+ 'doctype': 'Print Format',
+ 'name': 'Quotation Classic'
+ }
+]
\ No newline at end of file
diff --git a/erpnext/selling/Print Format/Quotation Modern/Quotation Modern.txt b/erpnext/selling/Print Format/Quotation Modern/Quotation Modern.txt
new file mode 100644
index 0000000..89d2e20
--- /dev/null
+++ b/erpnext/selling/Print Format/Quotation Modern/Quotation Modern.txt
@@ -0,0 +1,28 @@
+# Print Format, Quotation Modern
+[
+
+ # These values are common in all dictionaries
+ {
+ 'creation': '2011-12-13 11:02:59',
+ 'docstatus': 0,
+ 'modified': '2011-12-13 12:20:42',
+ 'modified_by': 'Administrator',
+ 'owner': 'Administrator'
+ },
+
+ # These values are common for all Print Format
+ {
+ 'doc_type': 'Quotation',
+ 'doctype': 'Print Format',
+ 'html': '<!--\n\tSample Print Format for ERPNext\n\tPlease use at your own discretion\n\tFor suggestions and contributions:\n\t\thttps://github.com/webnotes/erpnext-print-templates\n\n\tFreely usable under MIT license\n-->\n\n<!-- Style Settings -->\n<style>\n\t/*\n\t\tcommon style for whole page\n\t\tThis should include:\n\t\t+ page size related settings\n\t\t+ font family settings\n\t\t+ line spacing settings\n\t*/\n\t@media screen {\n\t\tbody {\n\t\t\twidth: 8.3in;\n\t\t}\n\t}\n\n\thtml, body, div, span, td {\n\t\tfont-family: "Helvetica", "Arial", sans-serif;\n\t\tfont-size: 12px;\n\t}\n\n\tbody {\n\t\tpadding: 10px;\n\t\tmargin: auto;\n\t\tfont-size: 12px;\n\t\tline-height: 150%;\n\t}\n\n\t.common {\n\t\tfont-family: "Helvetica", "Arial", sans-serif !important;\n\t\tfont-size: 12px;\n\t\tpadding: 10px 0px;\n\t}\n\n\ttable {\n\t\tborder-collapse: collapse;\n\t\twidth: 100%;\n\t\tvertical-align: top;\n\t\tborder-style: none !important;\n\t}\n\n\ttable td {\n\t\tpadding: 2px 0px;\n\t\tborder-style: none !important;\n\t}\n\t\n\ttable h1, h2, h3, h4, h5, h6 {\n\t\tpadding: 0px;\n\t\tmargin: 0px;\n\t}\n\n\ttable.header-table td {\n\t\tvertical-align: top;\n\t}\n\n\ttable.header-table h1 {\n\t\ttext-transform: uppercase;\n\t\tcolor: white;\n\t\tfont-size: 55px;\n\t\tfont-style: italic;\n\t}\n\n\ttable.header-table thead tr:nth-child(1) div {\n\t\theight: 24px;\n\t\tbackground-color: #696969;\n\t\tvertical-align: middle;\n\t\tpadding: 12px 0px 0px 0px;\n\t\twidth: 100%;\n\t}\n\n\tdiv.page-body table td:nth-child(6),\n\tdiv.page-body table td:nth-child(7) {\n\t\ttext-align: right;\n\t}\n\n\tdiv.page-body table tr td {\n\t\tbackground-color: #DCDCDC !important;\n\t}\n\n\tdiv.page-body table tr:nth-child(1) td {\n\t\tbackground-color: #696969 !important;\n\t\tcolor: white !important;\n\t}\n\n\ttable.footer-table td {\n\t\tvertical-align: top;\n\t}\n\n\ttable.footer-table td table td:nth-child(2),\n\ttable.footer-table td table td:nth-child(3) {\n\t\ttext-align: right;\n\t}\n\n\ttable.footer-table tfoot td {\n\t\tbackground-color: #696969;\n\t\theight: 10px;\n\t}\n\n\t.imp-details {\n\t\tbackground-color: #DCDCDC;\n\t}\n</style>\n\n\n<!-- Javascript -->\n<script>\n\tsi_std = {\n\t\tprint_item_table: function() {\n\t\t\tvar table = print_table(\n\t\t\t\t\'Quotation\',\n\t\t\t\tdoc.name,\n\t\t\t\t\'quotation_details\',\n\t\t\t\t\'Quotation Detail\',\n\t\t\t\t[// Here specify the table columns to be displayed\n\t\t\t\t\t\'SR\', \'item_code\', \'item_name\', \'description\', \'qty\', \'stock_uom\',\n\t\t\t\t\t\'export_rate\', \'export_amount\'\n\t\t\t\t],\n\t\t\t\t[// Here specify the labels of column headings\n\t\t\t\t\t\'Sr\', \'Item Code\', \'Item Name\', \'Description\', \'Qty\',\n\t\t\t\t\t\'UoM\', \'Basic Rate\', \'Amount\'\n\t\t\t\t],\n\t\t\t\t[// Here specify the column widths\n\t\t\t\t\t\'3%\', \'10%\', \'15%\', \'32%\', \'5%\',\n\t\t\t\t\t\'5%\', \'15%\', \'15%\'\n\t\t\t\t],\n\t\t\t\tnull,\n\t\t\t\tnull,\n\t\t\t\t{\n\t\t\t\t\t\'description\' : function(data_row) {\n\t\t\t\t\t\tif(data_row.adj_rate) {\n\t\t\t\t\t\t\tvar to_append = \'<div style="padding-left: 15px;"><i>Discount: \' + \n\t\t\t\t\t\t\t\tdata_row.adj_rate + \'%</i></div>\';\n\t\t\t\t\t\t\tif(data_row.description.indexOf(to_append)==-1) {\n\t\t\t\t\t\t\t\treturn data_row.description + to_append;\n\t\t\t\t\t\t\t} else { return data_row.description; }\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\treturn data_row.description;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t);\n\n\t\t\t// This code takes care of page breaks\n\t\t\tif(table.appendChild) {\n\t\t\t\tout = table.innerHTML;\n\t\t\t} else {\n\t\t\t\tout = \'\';\n\t\t\t\tfor(var i=0; i < (table.length-1); i++) {\n\t\t\t\t\tout += table[i].innerHTML + \n\t\t\t\t\t\t\'<div style = "page-break-after: always;" \\\n\t\t\t\t\t\tclass = "page_break"></div>\\\n\t\t\t\t\t\t<div class="page-settings"></div>\';\n\t\t\t\t}\n\t\t\t\tout += table[table.length-1].innerHTML;\n\t\t\t}\n\t\t\treturn out;\n\t\t},\n\n\n\t\tprint_other_charges: function(parent) {\n\t\t\tvar oc = getchildren(\'RV Tax Detail\', doc.name, \'other_charges\');\n\t\t\tvar rows = \'<table width=100%>\\n\';\n\t\t\tfor(var i=0; i<oc.length; i++) {\n\t\t\t\trows +=\n\t\t\t\t\t\'<tr>\\n\' +\n\t\t\t\t\t\t\'\\t<td>\' + oc[i].description + \'</td>\\n\' +\n\t\t\t\t\t\t\'\\t<td></td>\\n\' +\n\t\t\t\t\t\t\'\\t<td width=38%>\' + fmt_money(oc[i].tax_amount) + \'</td>\\n\' +\n\t\t\t\t\t\'</tr>\\n\';\n\t\t\t}\n\t\t\treturn rows + \'</table>\\n\';\n\t\t}\n\t};\n</script>\n\n\n<!-- Page Layout Settings -->\n<div class=\'common page-header\'>\n\t<!-- \n\t\tPage Header will contain\n\t\t\t+ table 1\n\t\t\t\t+ table 1a\n\t\t\t\t\t- Name\n\t\t\t\t\t- Address\n\t\t\t\t\t- Contact\n\t\t\t\t\t- Mobile No\n\t\t\t\t+ table 1b\n\t\t\t\t\t- Voucher Date\n\t\t\t\t\t- Due Date\n\t-->\n\t<table class=\'header-table\' cellspacing=0>\n\t\t<thead>\n\t\t\t<tr><td colspan=2><div><script>\'<h1>\' + (doc.select_print_heading || \'Quotation\') + \'</h1>\'</script></div></td></tr>\n\t\t\t<tr><td colspan=2><div style="height:15px"></div></td></tr>\n\t\t</thead>\n\t\t<tbody>\n\t\t\t<tr>\n\t\t\t\t<td width=60%><table width=100% cellspacing=0><tbody>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td width=39%><b>Name</b></td>\n\t\t\t\t\t\t<td><script>doc.customer?doc.customer:doc.lead_name</script></td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td><b>Address</b></td>\n\t\t\t\t\t\t<td><script>replace_newlines(doc.address_display)</script></td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td><b>Contact</b></td>\n\t\t\t\t\t\t<td><script>doc.contact_display</script></td>\n\t\t\t\t\t</tr>\n\t\t\t\t</tbody></table></td>\n\t\t\t\t<td><table width=100% cellspacing=0><tbody>\n\t\t\t\t\t<tr class=\'imp-details\'>\n\t\t\t\t\t\t<td><b>Quotation No.</b></td>\n\t\t\t\t\t\t<td><script>cur_frm.docname</script></td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td width=63%><b>Quotation Date</b></td>\n\t\t\t\t\t\t<td><script>date.str_to_user(doc.transaction_date)</script></td>\n\t\t\t\t\t<tr>\t\t\t\t\t\n\t\t\t\t</tbody></table></td>\n\t\t\t</tr>\n\t\t</tbody>\n\t\t<tfoot>\n\t\t\n\t\t</tfoot>\n\t</table>\n</div>\n<div class=\'common page-body\'>\n\t<!-- \n\t\tPage Body will contain\n\t\t\t+ table 2\n\t\t\t\t- Sales Invoice Data\n\t-->\n\t<script>si_std.print_item_table()</script>\n</div>\n<div class=\'common page-footer\'>\n\t<!-- \n\t\tPage Footer will contain\n\t\t\t+ table 3\n\t\t\t\t- Terms and Conditions\n\t\t\t\t- Total Rounded Amount Calculation\n\t\t\t\t- Total Rounded Amount in Words\n\t-->\n\t<table class=\'footer-table\' width=100% cellspacing=0>\n\t\t<thead>\n\t\t\t\n\t\t</thead>\n\t\t<tbody>\n\t\t\t<tr>\n\t\t\t\t<td width=60% style=\'padding-right: 10px;\'>\n\t\t\t\t\t<b>Terms, Conditions & Other Information:</b><br />\n\t\t\t\t\t<script>doc.terms</script>\n\t\t\t\t</td>\n\t\t\t\t<td>\n\t\t\t\t\t<table cellspacing=0 width=100%><tbody>\n\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t<td>Net Total</td>\n\t\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t\t<td width=38%><script>\n\t\t\t\t\t\t\t\tfmt_money(doc.net_total/doc.conversion_rate)\n\t\t\t\t\t\t\t</script></td>\n\t\t\t\t\t\t</tr>\n\t\t\t\t\t\t<tr><td colspan=3><script>si_std.print_other_charges()</script></td></tr>\n\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t<td>Grand Total</td>\n\t\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t\t<td><script>\n\t\t\t\t\t\t\t\tfmt_money(doc.grand_total_export)\n\t\t\t\t\t\t\t</script></td>\n\t\t\t\t\t\t</tr>\n\t\t\t\t\t\t<tr style=\'font-weight: bold\' class=\'imp-details\'>\n\t\t\t\t\t\t\t<td>Rounded Total</td>\n\t\t\t\t\t\t\t<td><script>doc.currency</script></td>\n\t\t\t\t\t\t\t<td><script>\n\t\t\t\t\t\t\t\tfmt_money(doc.rounded_total_export)\n\t\t\t\t\t\t\t</script></td>\n\t\t\t\t\t\t</tr>\n\t\t\t\t\t</tbody></table>\n\t\t\t\t\t<br /><b>In Words</b><br />\n\t\t\t\t\t<i><script>doc.in_words_export</script></i>\n\t\t\t\t</td>\n\t\t\t</tr>\t\t\n\t\t</tbody>\n\t\t<tfoot>\n\t\t\t<tr><td colspan=2><div></div></td><tr>\n\t\t</tfoot>\n\t</table>\n</div>\n',
+ 'module': 'Selling',
+ 'name': '__common__',
+ 'standard': 'Yes'
+ },
+
+ # Print Format, Quotation Modern
+ {
+ 'doctype': 'Print Format',
+ 'name': 'Quotation Modern'
+ }
+]
\ No newline at end of file
diff --git a/erpnext/selling/Print Format/Quotation Spartan/Quotation Spartan.txt b/erpnext/selling/Print Format/Quotation Spartan/Quotation Spartan.txt
new file mode 100644
index 0000000..258060e
--- /dev/null
+++ b/erpnext/selling/Print Format/Quotation Spartan/Quotation Spartan.txt
@@ -0,0 +1,28 @@
+# Print Format, Quotation Spartan
+[
+
+ # These values are common in all dictionaries
+ {
+ 'creation': '2011-12-13 11:02:59',
+ 'docstatus': 0,
+ 'modified': '2011-12-13 12:24:23',
+ 'modified_by': 'Administrator',
+ 'owner': 'Administrator'
+ },
+
+ # These values are common for all Print Format
+ {
+ 'doc_type': 'Quotation',
+ 'doctype': 'Print Format',
+ 'html': '<!--\n\tSample Print Format for ERPNext\n\tPlease use at your own discretion\n\tFor suggestions and contributions:\n\t\thttps://github.com/webnotes/erpnext-print-templates\n\n\tFreely usable under MIT license\n-->\n\n<!-- Style Settings -->\n<style>\n\t/*\n\t\tcommon style for whole page\n\t\tThis should include:\n\t\t+ page size related settings\n\t\t+ font family settings\n\t\t+ line spacing settings\n\t*/\n\t@media screen {\n\t\tbody {\n\t\t\twidth: 8.3in;\n\t\t}\n\t}\n\n\thtml, body, div, span, td {\n\t\tfont-family: "Arial", sans-serif;\n\t\tfont-size: 12px;\n\t}\n\n\tbody {\n\t\tpadding: 10px;\n\t\tmargin: auto;\n\t\tfont-size: 12px;\n\t\tline-height: 150%;\n\t}\n\n\t.common {\n\t\tfont-family: "Arial", sans-serif !important;\n\t\tfont-size: 12px;\n\t\tpadding: 0px;\n\t}\n\n\ttable {\n\t\twidth: 100% !important;\n\t\tvertical-align: top;\n\t}\n\n\ttable td {\n\t\tpadding: 2px 0px;\n\t}\n\n\ttable, td {\n\t\tborder-collapse: collapse !important;\n\t\tpadding: 0px;\n\t\tmargin: 0px !important;\n\t}\n\t\n\ttable h1, h2, h3, h4, h5, h6 {\n\t\tpadding: 0px;\n\t\tmargin: 0px;\n\t}\n\n\ttable.header-table td {\n\t\tvertical-align: top;\n\t}\n\n\ttable.header-table h3 {\n\t\tcolor: gray;\n\t}\n\n\ttable.header-table thead td {\n\t\tpadding: 5px;\n\t}\n\n\ttable.header-table > thead,\n\ttable.header-table > tbody > tr > td,\n\ttable.footer-table > tbody > tr > td {\n\t\tborder: 1px solid black;\n\t\tpadding: 5px;\n\t}\n\n\ttable.footer-table > tbody,\n\ttable.header-table > thead {\n\t\tborder-bottom: 3px solid black;\n\t}\n\n\ttable.header-table > thead {\n\t\tborder-top: 3px solid black;\n\t}\n\n\tdiv.page-body table td:nth-child(6),\n\tdiv.page-body table td:nth-child(7) {\n\t\ttext-align: right;\n\t}\n\n\tdiv.page-body td {\n\t\tbackground-color: white !important;\n\t\tborder: 1px solid black !important;\n\t}\n\n\ttable.footer-table td {\n\t\tvertical-align: top;\n\t}\n\n\ttable.footer-table td table td:nth-child(2),\n\ttable.footer-table td table td:nth-child(3) {\n\t\ttext-align: right;\n\t}\n</style>\n\n\n<!-- Javascript -->\n<script>\n\tsi_std = {\n\t\tprint_item_table: function() {\n\t\t\tvar table = print_table(\n\t\t\t\t\'Quotation\',\n\t\t\t\tdoc.name,\n\t\t\t\t\'quotation_details\',\n\t\t\t\t\'Quotation Detail\',\n\t\t\t\t[// Here specify the table columns to be displayed\n\t\t\t\t\t\'SR\', \'item_code\', \'item_name\', \'description\', \'qty\', \'stock_uom\',\n\t\t\t\t\t\'export_rate\', \'export_amount\'\n\t\t\t\t],\n\t\t\t\t[// Here specify the labels of column headings\n\t\t\t\t\t\'Sr\', \'Item Code\', \'Item Name\', \'Description\', \'Qty\',\n\t\t\t\t\t\'UoM\', \'Basic Rate\', \'Amount\'\n\t\t\t\t],\n\t\t\t\t[// Here specify the column widths\n\t\t\t\t\t\'3%\', \'10%\', \'15%\', \'32%\', \'5%\',\n\t\t\t\t\t\'5%\', \'15%\', \'15%\'\n\t\t\t\t],\n\t\t\t\tnull,\n\t\t\t\tnull,\n\t\t\t\t{\n\t\t\t\t\t\'description\' : function(data_row) {\n\t\t\t\t\t\tif(data_row.adj_rate) {\n\t\t\t\t\t\t\tvar to_append = \'<div style="padding-left: 15px;"><i>Discount: \' + \n\t\t\t\t\t\t\t\tdata_row.adj_rate + \'%</i></div>\';\n\t\t\t\t\t\t\tif(data_row.description.indexOf(to_append)==-1) {\n\t\t\t\t\t\t\t\treturn data_row.description + to_append;\n\t\t\t\t\t\t\t} else { return data_row.description; }\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\treturn data_row.description;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t);\n\n\t\t\t// This code takes care of page breaks\n\t\t\tif(table.appendChild) {\n\t\t\t\tout = table.innerHTML;\n\t\t\t} else {\n\t\t\t\tout = \'\';\n\t\t\t\tfor(var i=0; i < (table.length-1); i++) {\n\t\t\t\t\tout += table[i].innerHTML + \n\t\t\t\t\t\t\'<div style = "page-break-after: always;" \\\n\t\t\t\t\t\tclass = "page_break"></div>\\\n\t\t\t\t\t\t<div class="page-settings"></div>\';\n\t\t\t\t}\n\t\t\t\tout += table[table.length-1].innerHTML;\n\t\t\t}\n\t\t\treturn out;\n\t\t},\n\n\n\t\tprint_other_charges: function(parent) {\n\t\t\tvar oc = getchildren(\'RV Tax Detail\', doc.name, \'other_charges\');\n\t\t\tvar rows = \'<table width=100%>\\n\';\n\t\t\tfor(var i=0; i<oc.length; i++) {\n\t\t\t\trows +=\n\t\t\t\t\t\'<tr>\\n\' +\n\t\t\t\t\t\t\'\\t<td>\' + oc[i].description + \'</td>\\n\' +\n\t\t\t\t\t\t\'\\t<td></td>\\n\' +\n\t\t\t\t\t\t\'\\t<td width=38%>\' + fmt_money(oc[i].tax_amount) + \'</td>\\n\' +\n\t\t\t\t\t\'</tr>\\n\';\n\t\t\t}\n\t\t\treturn rows + \'</table>\\n\';\n\t\t}\n\t};\n</script>\n\n\n<!-- Page Layout Settings -->\n<div class=\'common page-header\'>\n\t<!-- \n\t\tPage Header will contain\n\t\t\t+ table 1\n\t\t\t\t+ table 1a\n\t\t\t\t\t- Name\n\t\t\t\t\t- Address\n\t\t\t\t\t- Contact\n\t\t\t\t\t- Mobile No\n\t\t\t\t+ table 1b\n\t\t\t\t\t- Voucher Date\n\t\t\t\t\t- Due Date\n\t-->\n\t<table class=\'header-table\' cellspacing=0>\n\t\t<thead>\n\t\t\t<tr><td colspan=2><script>\'<h1>\' + (doc.select_print_heading || \'Quotation\') + \'</h1>\'</script></td></tr>\n\t\t\t<tr><td colspan=2><h3><script>cur_frm.docname</script></h3></td></tr>\n\t\t</thead>\n\t\t<tbody>\n\t\t\t<tr>\n\t\t\t\t<td width=60%><table width=100% cellspacing=0><tbody>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td width=39%><b>Name</b></td>\n\t\t\t\t\t\t<td><script>doc.customer?doc.customer:doc.lead_name</script></td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td><b>Address</b></td>\n\t\t\t\t\t\t<td><script>replace_newlines(doc.address_display)</script></td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td><b>Contact</b></td>\n\t\t\t\t\t\t<td><script>doc.contact_display</script></td>\n\t\t\t\t\t</tr>\n\t\t\t\t</tbody></table></td>\n\t\t\t\t<td><table width=100% cellspacing=0><tbody>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td width=63%><b>Quotation Date</b></td>\n\t\t\t\t\t\t<td><script>date.str_to_user(doc.transaction_date)</script></td>\n\t\t\t\t\t<tr>\t\t\t\t\t\n\t\t\t\t</tbody></table></td>\n\t\t\t</tr>\n\t\t</tbody>\n\t\t<tfoot>\n\t\t\n\t\t</tfoot>\n\t</table>\n</div>\n<div class=\'common page-body\'>\n\t<!-- \n\t\tPage Body will contain\n\t\t\t+ table 2\n\t\t\t\t- Sales Invoice Data\n\t-->\n\t<script>si_std.print_item_table()</script>\n</div>\n<div class=\'common page-footer\'>\n\t<!-- \n\t\tPage Footer will contain\n\t\t\t+ table 3\n\t\t\t\t- Terms and Conditions\n\t\t\t\t- Total Rounded Amount Calculation\n\t\t\t\t- Total Rounded Amount in Words\n\t-->\n\t<table class=\'footer-table\' width=100% cellspacing=0>\n\t\t<thead>\n\t\t\t\n\t\t</thead>\n\t\t<tbody>\n\t\t\t<tr>\n\t\t\t\t<td width=60% style=\'padding-right: 10px;\'>\n\t\t\t\t\t<b>Terms, Conditions & Other Information:</b><br />\n\t\t\t\t\t<script>doc.terms</script>\n\t\t\t\t</td>\n\t\t\t\t<td>\n\t\t\t\t\t<table cellspacing=0 width=100%><tbody>\n\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t<td>Net Total</td>\n\t\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t\t<td width=38%><script>\n\t\t\t\t\t\t\t\tfmt_money(doc.net_total/doc.conversion_rate)\n\t\t\t\t\t\t\t</script></td>\n\t\t\t\t\t\t</tr>\n\t\t\t\t\t\t<tr><td colspan=3><script>si_std.print_other_charges()</script></td></tr>\n\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t<td>Grand Total</td>\n\t\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t\t<td><script>\n\t\t\t\t\t\t\t\tfmt_money(doc.grand_total_export)\n\t\t\t\t\t\t\t</script></td>\n\t\t\t\t\t\t</tr>\n\t\t\t\t\t\t<tr style=\'font-weight: bold\'>\n\t\t\t\t\t\t\t<td>Rounded Total</td>\n\t\t\t\t\t\t\t<td><script>doc.currency</script></td>\n\t\t\t\t\t\t\t<td><script>\n\t\t\t\t\t\t\t\tfmt_money(doc.rounded_total_export)\n\t\t\t\t\t\t\t</script></td>\n\t\t\t\t\t\t</tr>\n\t\t\t\t\t</tbody></table>\n\t\t\t\t\t<br /><b>In Words</b><br />\n\t\t\t\t\t<i><script>doc.in_words_export</script></i>\n\t\t\t\t</td>\n\t\t\t</tr>\t\t\n\t\t</tbody>\n\t\t<tfoot>\n\t\t\n\t\t</tfoot>\n\t</table>\n</div>\n',
+ 'module': 'Selling',
+ 'name': '__common__',
+ 'standard': 'Yes'
+ },
+
+ # Print Format, Quotation Spartan
+ {
+ 'doctype': 'Print Format',
+ 'name': 'Quotation Spartan'
+ }
+]
\ No newline at end of file
diff --git a/erpnext/selling/Print Format/Sales Order Classic/Sales Order Classic.txt b/erpnext/selling/Print Format/Sales Order Classic/Sales Order Classic.txt
new file mode 100644
index 0000000..7d99371
--- /dev/null
+++ b/erpnext/selling/Print Format/Sales Order Classic/Sales Order Classic.txt
@@ -0,0 +1,28 @@
+# Print Format, Sales Order Classic
+[
+
+ # These values are common in all dictionaries
+ {
+ 'creation': '2011-12-13 11:02:59',
+ 'docstatus': 0,
+ 'modified': '2011-12-13 12:30:15',
+ 'modified_by': 'Administrator',
+ 'owner': 'Administrator'
+ },
+
+ # These values are common for all Print Format
+ {
+ 'doc_type': 'Sales Order',
+ 'doctype': 'Print Format',
+ 'html': '<!--\n\tSample Print Format for ERPNext\n\tPlease use at your own discretion\n\tFor suggestions and contributions:\n\t\thttps://github.com/webnotes/erpnext-print-templates\n\n\tFreely usable under MIT license\n-->\n\n<!-- Style Settings -->\n<style>\n\t/*\n\t\tcommon style for whole page\n\t\tThis should include:\n\t\t+ page size related settings\n\t\t+ font family settings\n\t\t+ line spacing settings\n\t*/\n\t@media screen {\n\t\tbody {\n\t\t\twidth: 8.3in;\n\t\t}\n\t}\n\n\thtml, body, div, span, td {\n\t\tfont-family: "Georgia", serif;\n\t\tfont-size: 12px;\n\t}\n\n\tbody {\n\t\tpadding: 10px;\n\t\tmargin: auto;\n\t\tfont-size: 12px;\n\t\tline-height: 150%;\n\t}\n\n\t.common {\n\t\tfont-family: "Georgia", serif !important;\n\t\tfont-size: 12px;\n\t\tpadding: 10px 0px;\n\t}\n\n\ttable {\n\t\tborder-collapse: collapse;\n\t\twidth: 100%;\n\t\tvertical-align: top;\n\t}\n\n\ttable td {\n\t\tpadding: 2px 0px;\n\t}\n\t\n\ttable h1, h2, h3, h4, h5, h6 {\n\t\tpadding: 0px;\n\t\tmargin: 0px;\n\t}\n\n\ttable.header-table td {\n\t\tvertical-align: top;\n\t}\n\n\ttable.header-table thead {\n\t\tborder-bottom: 1px solid black;\n\t}\n\n\ttable.header-table h3 {\n\t\tcolor: gray;\n\t}\n\n\ttable.header-table thead td {\n\t\tpadding: 5px 0px;\n\t}\n\n\tdiv.page-body table td:nth-child(6),\n\tdiv.page-body table td:nth-child(7) {\n\t\ttext-align: right;\n\t}\n\n\ttable.footer-table td {\n\t\tvertical-align: top;\n\t}\n\n\ttable.footer-table td table td:nth-child(2),\n\ttable.footer-table td table td:nth-child(3) {\n\t\ttext-align: right;\n\t}\n</style>\n\n\n<!-- Javascript -->\n<script>\n\tsi_std = {\n\t\tprint_item_table: function() {\n\t\t\tvar table = print_table(\n\t\t\t\t\'Sales Order\',\n\t\t\t\tdoc.name,\n\t\t\t\t\'sales_order_details\',\n\t\t\t\t\'Sales Order Detail\',\n\t\t\t\t[// Here specify the table columns to be displayed\n\t\t\t\t\t\'SR\', \'item_code\', \'description\', \'qty\', \'stock_uom\',\n\t\t\t\t\t\'basic_rate\', \'amount\'\n\t\t\t\t],\n\t\t\t\t[// Here specify the labels of column headings\n\t\t\t\t\t\'Sr\', \'Item Code\', \'Description\', \'Qty\',\n\t\t\t\t\t\'UoM\', \'Basic Rate\', \'Amount\'\n\t\t\t\t],\n\t\t\t\t[// Here specify the column widths\n\t\t\t\t\t\'3%\', \'20%\', \'37%\', \'5%\',\n\t\t\t\t\t\'5%\', \'15%\', \'15%\'\n\t\t\t\t],\n\t\t\t\tnull,\n\t\t\t\tnull,\n\t\t\t\t{\n\t\t\t\t\t\'description\' : function(data_row) {\n\t\t\t\t\t\tif(data_row.adj_rate) {\n\t\t\t\t\t\t\tvar to_append = \'<div style="padding-left: 15px;"><i>Discount: \' + \n\t\t\t\t\t\t\t\tdata_row.adj_rate + \'%</i></div>\';\n\t\t\t\t\t\t\tif(data_row.description.indexOf(to_append)==-1) {\n\t\t\t\t\t\t\t\treturn data_row.description + to_append;\n\t\t\t\t\t\t\t} else { return data_row.description; }\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\treturn data_row.description;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t);\n\n\t\t\t// This code takes care of page breaks\n\t\t\tif(table.appendChild) {\n\t\t\t\tout = table.innerHTML;\n\t\t\t} else {\n\t\t\t\tout = \'\';\n\t\t\t\tfor(var i=0; i < (table.length-1); i++) {\n\t\t\t\t\tout += table[i].innerHTML + \n\t\t\t\t\t\t\'<div style = "page-break-after: always;" \\\n\t\t\t\t\t\tclass = "page_break"></div>\\\n\t\t\t\t\t\t<div class="page-settings"></div>\';\n\t\t\t\t}\n\t\t\t\tout += table[table.length-1].innerHTML;\n\t\t\t}\n\t\t\treturn out;\n\t\t},\n\n\n\t\tprint_other_charges: function(parent) {\n\t\t\tvar oc = getchildren(\'RV Tax Detail\', doc.name, \'other_charges\');\n\t\t\tvar rows = \'<table width=100%>\\n\';\n\t\t\tfor(var i=0; i<oc.length; i++) {\n\t\t\t\trows +=\n\t\t\t\t\t\'<tr>\\n\' +\n\t\t\t\t\t\t\'\\t<td>\' + oc[i].description + \'</td>\\n\' +\n\t\t\t\t\t\t\'\\t<td></td>\\n\' +\n\t\t\t\t\t\t\'\\t<td width=38%>\' + fmt_money(oc[i].tax_amount) + \'</td>\\n\' +\n\t\t\t\t\t\'</tr>\\n\';\n\t\t\t}\n\t\t\treturn rows + \'</table>\\n\';\n\t\t}\n\t};\n</script>\n\n\n<!-- Page Layout Settings -->\n<div class=\'common page-header\'>\n\t<!-- \n\t\tPage Header will contain\n\t\t\t+ table 1\n\t\t\t\t+ table 1a\n\t\t\t\t\t- Name\n\t\t\t\t\t- Address\n\t\t\t\t\t- Contact\n\t\t\t\t\t- Mobile No\n\t\t\t\t+ table 1b\n\t\t\t\t\t- Voucher Date\n\t\t\t\t\t- Due Date\n\t-->\n\t<table class=\'header-table\' cellspacing=0>\n\t\t<thead>\n\t\t\t<tr><td><script>\'<h1>\' + (doc.select_print_heading || \'Sales Order\') + \'</h1>\'</script></td></tr>\n\t\t\t<tr><td><h3><script>cur_frm.docname</script></h3></td></tr>\n\t\t</thead>\n\t\t<tbody>\n\t\t\t<tr>\n\t\t\t\t<td width=60%><table width=100% cellspacing=0><tbody>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td width=39%><b>Name</b></td>\n\t\t\t\t\t\t<td><script>doc.customer_name</script></td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td><b>Address</b></td>\n\t\t\t\t\t\t<td><script>replace_newlines(doc.address_display)</script></td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td><b>Contact</b></td>\n\t\t\t\t\t\t<td><script>doc.contact_display</script></td>\n\t\t\t\t\t</tr>\n\t\t\t\t</tbody></table></td>\n\t\t\t\t<td><table width=100% cellspacing=0><tbody>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td width=63%><b>Sales Order Date</b></td>\n\t\t\t\t\t\t<td><script>date.str_to_user(doc.transaction_date)</script></td>\n\t\t\t\t\t<tr>\t\t\t\t\t\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td><b>Delivery Date</b></td>\n\t\t\t\t\t\t<td><script>date.str_to_user(doc.delivery_date)</script></td>\n\t\t\t\t\t<tr>\t\t\t\t\t\n\t\t\t\t</tbody></table></td>\n\t\t\t</tr>\n\t\t</tbody>\n\t\t<tfoot>\n\t\t\n\t\t</tfoot>\n\t</table>\n</div>\n<div class=\'common page-body\'>\n\t<!-- \n\t\tPage Body will contain\n\t\t\t+ table 2\n\t\t\t\t- Sales Invoice Data\n\t-->\n\t<script>si_std.print_item_table()</script>\n</div>\n<div class=\'common page-footer\'>\n\t<!-- \n\t\tPage Footer will contain\n\t\t\t+ table 3\n\t\t\t\t- Terms and Conditions\n\t\t\t\t- Total Rounded Amount Calculation\n\t\t\t\t- Total Rounded Amount in Words\n\t-->\n\t<table class=\'footer-table\' width=100% cellspacing=0>\n\t\t<thead>\n\t\t\t\n\t\t</thead>\n\t\t<tbody>\n\t\t\t<tr>\n\t\t\t\t<td width=60% style=\'padding-right: 10px;\'>\n\t\t\t\t\t<b>Terms, Conditions & Other Information:</b><br />\n\t\t\t\t\t<script>doc.terms</script>\n\t\t\t\t</td>\n\t\t\t\t<td>\n\t\t\t\t\t<table cellspacing=0 width=100%><tbody>\n\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t<td>Net Total</td>\n\t\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t\t<td width=38%><script>\n\t\t\t\t\t\t\t\tfmt_money(doc.net_total)\n\t\t\t\t\t\t\t</script></td>\n\t\t\t\t\t\t</tr>\n\t\t\t\t\t\t<tr><td colspan=3><script>si_std.print_other_charges()</script></td></tr>\n\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t<td>Grand Total</td>\n\t\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t\t<td><script>\n\t\t\t\t\t\t\t\tfmt_money(doc.grand_total_export)\n\t\t\t\t\t\t\t</script></td>\n\t\t\t\t\t\t</tr>\n\t\t\t\t\t\t<tr style=\'font-weight: bold\'>\n\t\t\t\t\t\t\t<td>Rounded Total</td>\n\t\t\t\t\t\t\t<td><script>doc.currency</script></td>\n\t\t\t\t\t\t\t<td><script>\n\t\t\t\t\t\t\t\tfmt_money(doc.rounded_total_export)\n\t\t\t\t\t\t\t</script></td>\n\t\t\t\t\t\t</tr>\n\t\t\t\t\t</tbody></table>\n\t\t\t\t\t<br /><b>In Words</b><br />\n\t\t\t\t\t<i><script>doc.in_words_export</script></i>\n\t\t\t\t</td>\n\t\t\t</tr>\t\t\n\t\t</tbody>\n\t\t<tfoot>\n\t\t\n\t\t</tfoot>\n\t</table>\n</div>\n',
+ 'module': 'Selling',
+ 'name': '__common__',
+ 'standard': 'Yes'
+ },
+
+ # Print Format, Sales Order Classic
+ {
+ 'doctype': 'Print Format',
+ 'name': 'Sales Order Classic'
+ }
+]
\ No newline at end of file
diff --git a/erpnext/selling/Print Format/Sales Order Modern/Sales Order Modern.txt b/erpnext/selling/Print Format/Sales Order Modern/Sales Order Modern.txt
new file mode 100644
index 0000000..aaf8c19
--- /dev/null
+++ b/erpnext/selling/Print Format/Sales Order Modern/Sales Order Modern.txt
@@ -0,0 +1,28 @@
+# Print Format, Sales Order Modern
+[
+
+ # These values are common in all dictionaries
+ {
+ 'creation': '2011-12-13 11:02:59',
+ 'docstatus': 0,
+ 'modified': '2011-12-13 12:36:06',
+ 'modified_by': 'Administrator',
+ 'owner': 'Administrator'
+ },
+
+ # These values are common for all Print Format
+ {
+ 'doc_type': 'Sales Order',
+ 'doctype': 'Print Format',
+ 'html': '<!--\n\tSample Print Format for ERPNext\n\tPlease use at your own discretion\n\tFor suggestions and contributions:\n\t\thttps://github.com/webnotes/erpnext-print-templates\n\n\tFreely usable under MIT license\n-->\n\n<!-- Style Settings -->\n<style>\n\t/*\n\t\tcommon style for whole page\n\t\tThis should include:\n\t\t+ page size related settings\n\t\t+ font family settings\n\t\t+ line spacing settings\n\t*/\n\t@media screen {\n\t\tbody {\n\t\t\twidth: 8.3in;\n\t\t}\n\t}\n\n\thtml, body, div, span, td {\n\t\tfont-family: "Helvetica", "Arial", sans-serif;\n\t\tfont-size: 12px;\n\t}\n\n\tbody {\n\t\tpadding: 10px;\n\t\tmargin: auto;\n\t\tfont-size: 12px;\n\t\tline-height: 150%;\n\t}\n\n\t.common {\n\t\tfont-family: "Helvetica", "Arial", sans-serif !important;\n\t\tfont-size: 12px;\n\t\tpadding: 10px 0px;\n\t}\n\n\ttable {\n\t\tborder-collapse: collapse;\n\t\twidth: 100%;\n\t\tvertical-align: top;\n\t\tborder-style: none !important;\n\t}\n\n\ttable td {\n\t\tpadding: 2px 0px;\n\t\tborder-style: none !important;\n\t}\n\t\n\ttable h1, h2, h3, h4, h5, h6 {\n\t\tpadding: 0px;\n\t\tmargin: 0px;\n\t}\n\n\ttable.header-table td {\n\t\tvertical-align: top;\n\t}\n\n\ttable.header-table h1 {\n\t\ttext-transform: uppercase;\n\t\tcolor: white;\n\t\tfont-size: 55px;\n\t\tfont-style: italic;\n\t}\n\n\ttable.header-table thead tr:nth-child(1) div {\n\t\theight: 24px;\n\t\tbackground-color: #696969;\n\t\tvertical-align: middle;\n\t\tpadding: 12px 0px 0px 0px;\n\t\twidth: 100%;\n\t}\n\n\tdiv.page-body table td:nth-child(6),\n\tdiv.page-body table td:nth-child(7) {\n\t\ttext-align: right;\n\t}\n\n\tdiv.page-body table tr td {\n\t\tbackground-color: #DCDCDC !important;\n\t}\n\n\tdiv.page-body table tr:nth-child(1) td {\n\t\tbackground-color: #696969 !important;\n\t\tcolor: white !important;\n\t}\n\n\ttable.footer-table td {\n\t\tvertical-align: top;\n\t}\n\n\ttable.footer-table td table td:nth-child(2),\n\ttable.footer-table td table td:nth-child(3) {\n\t\ttext-align: right;\n\t}\n\n\ttable.footer-table tfoot td {\n\t\tbackground-color: #696969;\n\t\theight: 10px;\n\t}\n\n\t.imp-details {\n\t\tbackground-color: #DCDCDC;\n\t}\n</style>\n\n\n<!-- Javascript -->\n<script>\n\tsi_std = {\n\t\tprint_item_table: function() {\n\t\t\tvar table = print_table(\n\t\t\t\t\'Sales Order\',\n\t\t\t\tdoc.name,\n\t\t\t\t\'sales_order_details\',\n\t\t\t\t\'Sales Order Detail\',\n\t\t\t\t[// Here specify the table columns to be displayed\n\t\t\t\t\t\'SR\', \'item_code\', \'description\', \'qty\', \'stock_uom\',\n\t\t\t\t\t\'basic_rate\', \'amount\'\n\t\t\t\t],\n\t\t\t\t[// Here specify the labels of column headings\n\t\t\t\t\t\'Sr\', \'Item Code\', \'Description\', \'Qty\',\n\t\t\t\t\t\'UoM\', \'Basic Rate\', \'Amount\'\n\t\t\t\t],\n\t\t\t\t[// Here specify the column widths\n\t\t\t\t\t\'3%\', \'20%\', \'37%\', \'5%\',\n\t\t\t\t\t\'5%\', \'15%\', \'15%\'\n\t\t\t\t],\n\t\t\t\tnull,\n\t\t\t\tnull,\n\t\t\t\t{\n\t\t\t\t\t\'description\' : function(data_row) {\n\t\t\t\t\t\tif(data_row.adj_rate) {\n\t\t\t\t\t\t\tvar to_append = \'<div style="padding-left: 15px;"><i>Discount: \' + \n\t\t\t\t\t\t\t\tdata_row.adj_rate + \'%</i></div>\';\n\t\t\t\t\t\t\tif(data_row.description.indexOf(to_append)==-1) {\n\t\t\t\t\t\t\t\treturn data_row.description + to_append;\n\t\t\t\t\t\t\t} else { return data_row.description; }\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\treturn data_row.description;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t);\n\n\t\t\t// This code takes care of page breaks\n\t\t\tif(table.appendChild) {\n\t\t\t\tout = table.innerHTML;\n\t\t\t} else {\n\t\t\t\tout = \'\';\n\t\t\t\tfor(var i=0; i < (table.length-1); i++) {\n\t\t\t\t\tout += table[i].innerHTML + \n\t\t\t\t\t\t\'<div style = "page-break-after: always;" \\\n\t\t\t\t\t\tclass = "page_break"></div>\\\n\t\t\t\t\t\t<div class="page-settings"></div>\';\n\t\t\t\t}\n\t\t\t\tout += table[table.length-1].innerHTML;\n\t\t\t}\n\t\t\treturn out;\n\t\t},\n\n\n\t\tprint_other_charges: function(parent) {\n\t\t\tvar oc = getchildren(\'RV Tax Detail\', doc.name, \'other_charges\');\n\t\t\tvar rows = \'<table width=100%>\\n\';\n\t\t\tfor(var i=0; i<oc.length; i++) {\n\t\t\t\trows +=\n\t\t\t\t\t\'<tr>\\n\' +\n\t\t\t\t\t\t\'\\t<td>\' + oc[i].description + \'</td>\\n\' +\n\t\t\t\t\t\t\'\\t<td></td>\\n\' +\n\t\t\t\t\t\t\'\\t<td width=38%>\' + fmt_money(oc[i].tax_amount) + \'</td>\\n\' +\n\t\t\t\t\t\'</tr>\\n\';\n\t\t\t}\n\t\t\treturn rows + \'</table>\\n\';\n\t\t}\n\t};\n</script>\n\n\n<!-- Page Layout Settings -->\n<div class=\'common page-header\'>\n\t<!-- \n\t\tPage Header will contain\n\t\t\t+ table 1\n\t\t\t\t+ table 1a\n\t\t\t\t\t- Name\n\t\t\t\t\t- Address\n\t\t\t\t\t- Contact\n\t\t\t\t\t- Mobile No\n\t\t\t\t+ table 1b\n\t\t\t\t\t- Voucher Date\n\t\t\t\t\t- Due Date\n\t-->\n\t<table class=\'header-table\' cellspacing=0>\n\t\t<thead>\n\t\t\t<tr><td colspan=2><div><script>\'<h1>\' + (doc.select_print_heading || \'Sales Order\') + \'</h1>\'</script></div></td></tr>\n\t\t\t<tr><td colspan=2><div style="height:15px"></div></td></tr>\n\t\t</thead>\n\t\t<tbody>\n\t\t\t<tr>\n\t\t\t\t<td width=60%><table width=100% cellspacing=0><tbody>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td width=39%><b>Name</b></td>\n\t\t\t\t\t\t<td><script>doc.customer_name</script></td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td><b>Address</b></td>\n\t\t\t\t\t\t<td><script>replace_newlines(doc.address_display)</script></td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td><b>Contact</b></td>\n\t\t\t\t\t\t<td><script>doc.contact_display</script></td>\n\t\t\t\t\t</tr>\n\t\t\t\t</tbody></table></td>\n\t\t\t\t<td><table width=100% cellspacing=0><tbody>\n\t\t\t\t\t<tr class=\'imp-details\'>\n\t\t\t\t\t\t<td><b>Sales Order No.</b></td>\n\t\t\t\t\t\t<td><script>cur_frm.docname</script></td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td width=63%><b>Sales Order Date</b></td>\n\t\t\t\t\t\t<td><script>date.str_to_user(doc.transaction_date)</script></td>\n\t\t\t\t\t<tr>\t\t\t\t\t\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td><b>Delivery Date</b></td>\n\t\t\t\t\t\t<td><script>date.str_to_user(doc.delivery_date)</script></td>\n\t\t\t\t\t<tr>\t\t\t\t\t\n\t\t\t\t</tbody></table></td>\n\t\t\t</tr>\n\t\t</tbody>\n\t\t<tfoot>\n\t\t\n\t\t</tfoot>\n\t</table>\n</div>\n<div class=\'common page-body\'>\n\t<!-- \n\t\tPage Body will contain\n\t\t\t+ table 2\n\t\t\t\t- Sales Invoice Data\n\t-->\n\t<script>si_std.print_item_table()</script>\n</div>\n<div class=\'common page-footer\'>\n\t<!-- \n\t\tPage Footer will contain\n\t\t\t+ table 3\n\t\t\t\t- Terms and Conditions\n\t\t\t\t- Total Rounded Amount Calculation\n\t\t\t\t- Total Rounded Amount in Words\n\t-->\n\t<table class=\'footer-table\' width=100% cellspacing=0>\n\t\t<thead>\n\t\t\t\n\t\t</thead>\n\t\t<tbody>\n\t\t\t<tr>\n\t\t\t\t<td width=60% style=\'padding-right: 10px;\'>\n\t\t\t\t\t<b>Terms, Conditions & Other Information:</b><br />\n\t\t\t\t\t<script>doc.terms</script>\n\t\t\t\t</td>\n\t\t\t\t<td>\n\t\t\t\t\t<table cellspacing=0 width=100%><tbody>\n\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t<td>Net Total</td>\n\t\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t\t<td width=38%><script>\n\t\t\t\t\t\t\t\tfmt_money(doc.net_total)\n\t\t\t\t\t\t\t</script></td>\n\t\t\t\t\t\t</tr>\n\t\t\t\t\t\t<tr><td colspan=3><script>si_std.print_other_charges()</script></td></tr>\n\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t<td>Grand Total</td>\n\t\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t\t<td><script>\n\t\t\t\t\t\t\t\tfmt_money(doc.grand_total_export)\n\t\t\t\t\t\t\t</script></td>\n\t\t\t\t\t\t</tr>\n\t\t\t\t\t\t<tr style=\'font-weight: bold\' class=\'imp-details\'>\n\t\t\t\t\t\t\t<td>Rounded Total</td>\n\t\t\t\t\t\t\t<td><script>doc.currency</script></td>\n\t\t\t\t\t\t\t<td><script>\n\t\t\t\t\t\t\t\tfmt_money(doc.rounded_total_export)\n\t\t\t\t\t\t\t</script></td>\n\t\t\t\t\t\t</tr>\n\t\t\t\t\t</tbody></table>\n\t\t\t\t\t<br /><b>In Words</b><br />\n\t\t\t\t\t<i><script>doc.in_words_export</script></i>\n\t\t\t\t</td>\n\t\t\t</tr>\t\t\n\t\t</tbody>\n\t\t<tfoot>\n\t\t\t<tr><td colspan=2><div></div></td><tr>\n\t\t</tfoot>\n\t</table>\n</div>\n',
+ 'module': 'Selling',
+ 'name': '__common__',
+ 'standard': 'Yes'
+ },
+
+ # Print Format, Sales Order Modern
+ {
+ 'doctype': 'Print Format',
+ 'name': 'Sales Order Modern'
+ }
+]
\ No newline at end of file
diff --git a/erpnext/selling/Print Format/Sales Order Spartan/Sales Order Spartan.txt b/erpnext/selling/Print Format/Sales Order Spartan/Sales Order Spartan.txt
new file mode 100644
index 0000000..14df2e7
--- /dev/null
+++ b/erpnext/selling/Print Format/Sales Order Spartan/Sales Order Spartan.txt
@@ -0,0 +1,28 @@
+# Print Format, Sales Order Spartan
+[
+
+ # These values are common in all dictionaries
+ {
+ 'creation': '2011-12-13 11:02:59',
+ 'docstatus': 0,
+ 'modified': '2011-12-13 12:42:52',
+ 'modified_by': 'Administrator',
+ 'owner': 'Administrator'
+ },
+
+ # These values are common for all Print Format
+ {
+ 'doc_type': 'Sales Order',
+ 'doctype': 'Print Format',
+ 'html': '<!--\n\tSample Print Format for ERPNext\n\tPlease use at your own discretion\n\tFor suggestions and contributions:\n\t\thttps://github.com/webnotes/erpnext-print-templates\n\n\tFreely usable under MIT license\n-->\n\n<!-- Style Settings -->\n<style>\n\t/*\n\t\tcommon style for whole page\n\t\tThis should include:\n\t\t+ page size related settings\n\t\t+ font family settings\n\t\t+ line spacing settings\n\t*/\n\t@media screen {\n\t\tbody {\n\t\t\twidth: 8.3in;\n\t\t}\n\t}\n\n\thtml, body, div, span, td {\n\t\tfont-family: "Arial", sans-serif;\n\t\tfont-size: 12px;\n\t}\n\n\tbody {\n\t\tpadding: 10px;\n\t\tmargin: auto;\n\t\tfont-size: 12px;\n\t\tline-height: 150%;\n\t}\n\n\t.common {\n\t\tfont-family: "Arial", sans-serif !important;\n\t\tfont-size: 12px;\n\t\tpadding: 0px;\n\t}\n\n\ttable {\n\t\twidth: 100% !important;\n\t\tvertical-align: top;\n\t}\n\n\ttable td {\n\t\tpadding: 2px 0px;\n\t}\n\n\ttable, td {\n\t\tborder-collapse: collapse !important;\n\t\tpadding: 0px;\n\t\tmargin: 0px !important;\n\t}\n\t\n\ttable h1, h2, h3, h4, h5, h6 {\n\t\tpadding: 0px;\n\t\tmargin: 0px;\n\t}\n\n\ttable.header-table td {\n\t\tvertical-align: top;\n\t}\n\n\ttable.header-table h3 {\n\t\tcolor: gray;\n\t}\n\n\ttable.header-table thead td {\n\t\tpadding: 5px;\n\t}\n\n\ttable.header-table > thead,\n\ttable.header-table > tbody > tr > td,\n\ttable.footer-table > tbody > tr > td {\n\t\tborder: 1px solid black;\n\t\tpadding: 5px;\n\t}\n\n\ttable.footer-table > tbody,\n\ttable.header-table > thead {\n\t\tborder-bottom: 3px solid black;\n\t}\n\n\ttable.header-table > thead {\n\t\tborder-top: 3px solid black;\n\t}\n\n\tdiv.page-body table td:nth-child(6),\n\tdiv.page-body table td:nth-child(7) {\n\t\ttext-align: right;\n\t}\n\n\tdiv.page-body td {\n\t\tbackground-color: white !important;\n\t\tborder: 1px solid black !important;\n\t}\n\n\ttable.footer-table td {\n\t\tvertical-align: top;\n\t}\n\n\ttable.footer-table td table td:nth-child(2),\n\ttable.footer-table td table td:nth-child(3) {\n\t\ttext-align: right;\n\t}\n</style>\n\n\n<!-- Javascript -->\n<script>\n\tsi_std = {\n\t\tprint_item_table: function() {\n\t\t\tvar table = print_table(\n\t\t\t\t\'Sales Order\',\n\t\t\t\tdoc.name,\n\t\t\t\t\'sales_order_details\',\n\t\t\t\t\'Sales Order Detail\',\n\t\t\t\t[// Here specify the table columns to be displayed\n\t\t\t\t\t\'SR\', \'item_code\', \'description\', \'qty\', \'stock_uom\',\n\t\t\t\t\t\'basic_rate\', \'amount\'\n\t\t\t\t],\n\t\t\t\t[// Here specify the labels of column headings\n\t\t\t\t\t\'Sr\', \'Item Code\', \'Description\', \'Qty\',\n\t\t\t\t\t\'UoM\', \'Basic Rate\', \'Amount\'\n\t\t\t\t],\n\t\t\t\t[// Here specify the column widths\n\t\t\t\t\t\'3%\', \'20%\', \'37%\', \'5%\',\n\t\t\t\t\t\'5%\', \'15%\', \'15%\'\n\t\t\t\t],\n\t\t\t\tnull,\n\t\t\t\tnull,\n\t\t\t\t{\n\t\t\t\t\t\'description\' : function(data_row) {\n\t\t\t\t\t\tif(data_row.adj_rate) {\n\t\t\t\t\t\t\tvar to_append = \'<div style="padding-left: 15px;"><i>Discount: \' + \n\t\t\t\t\t\t\t\tdata_row.adj_rate + \'%</i></div>\';\n\t\t\t\t\t\t\tif(data_row.description.indexOf(to_append)==-1) {\n\t\t\t\t\t\t\t\treturn data_row.description + to_append;\n\t\t\t\t\t\t\t} else { return data_row.description; }\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\treturn data_row.description;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t);\n\n\t\t\t// This code takes care of page breaks\n\t\t\tif(table.appendChild) {\n\t\t\t\tout = table.innerHTML;\n\t\t\t} else {\n\t\t\t\tout = \'\';\n\t\t\t\tfor(var i=0; i < (table.length-1); i++) {\n\t\t\t\t\tout += table[i].innerHTML + \n\t\t\t\t\t\t\'<div style = "page-break-after: always;" \\\n\t\t\t\t\t\tclass = "page_break"></div>\\\n\t\t\t\t\t\t<div class="page-settings"></div>\';\n\t\t\t\t}\n\t\t\t\tout += table[table.length-1].innerHTML;\n\t\t\t}\n\t\t\treturn out;\n\t\t},\n\n\n\t\tprint_other_charges: function(parent) {\n\t\t\tvar oc = getchildren(\'RV Tax Detail\', doc.name, \'other_charges\');\n\t\t\tvar rows = \'<table width=100%>\\n\';\n\t\t\tfor(var i=0; i<oc.length; i++) {\n\t\t\t\trows +=\n\t\t\t\t\t\'<tr>\\n\' +\n\t\t\t\t\t\t\'\\t<td>\' + oc[i].description + \'</td>\\n\' +\n\t\t\t\t\t\t\'\\t<td></td>\\n\' +\n\t\t\t\t\t\t\'\\t<td width=38%>\' + fmt_money(oc[i].tax_amount) + \'</td>\\n\' +\n\t\t\t\t\t\'</tr>\\n\';\n\t\t\t}\n\t\t\treturn rows + \'</table>\\n\';\n\t\t}\n\t};\n</script>\n\n\n<!-- Page Layout Settings -->\n<div class=\'common page-header\'>\n\t<!-- \n\t\tPage Header will contain\n\t\t\t+ table 1\n\t\t\t\t+ table 1a\n\t\t\t\t\t- Name\n\t\t\t\t\t- Address\n\t\t\t\t\t- Contact\n\t\t\t\t\t- Mobile No\n\t\t\t\t+ table 1b\n\t\t\t\t\t- Voucher Date\n\t\t\t\t\t- Due Date\n\t-->\n\t<table class=\'header-table\' cellspacing=0>\n\t\t<thead>\n\t\t\t<tr><td colspan=2><script>\'<h1>\' + (doc.select_print_heading || \'Sales Order\') + \'</h1>\'</script></td></tr>\n\t\t\t<tr><td colspan=2><h3><script>cur_frm.docname</script></h3></td></tr>\n\t\t</thead>\n\t\t<tbody>\n\t\t\t<tr>\n\t\t\t\t<td width=60%><table width=100% cellspacing=0><tbody>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td width=39%><b>Name</b></td>\n\t\t\t\t\t\t<td><script>doc.customer_name</script></td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td><b>Address</b></td>\n\t\t\t\t\t\t<td><script>replace_newlines(doc.address_display)</script></td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td><b>Contact</b></td>\n\t\t\t\t\t\t<td><script>doc.contact_display</script></td>\n\t\t\t\t\t</tr>\n\t\t\t\t</tbody></table></td>\n\t\t\t\t<td><table width=100% cellspacing=0><tbody>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td width=63%><b>Sales Order Date</b></td>\n\t\t\t\t\t\t<td><script>date.str_to_user(doc.transaction_date)</script></td>\n\t\t\t\t\t<tr>\t\t\t\t\t\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td><b>Delivery Date</b></td>\n\t\t\t\t\t\t<td><script>date.str_to_user(doc.delivery_date)</script></td>\n\t\t\t\t\t<tr>\t\t\t\t\t\n\t\t\t\t</tbody></table></td>\n\t\t\t</tr>\n\t\t</tbody>\n\t\t<tfoot>\n\t\t\n\t\t</tfoot>\n\t</table>\n</div>\n<div class=\'common page-body\'>\n\t<!-- \n\t\tPage Body will contain\n\t\t\t+ table 2\n\t\t\t\t- Sales Invoice Data\n\t-->\n\t<script>si_std.print_item_table()</script>\n</div>\n<div class=\'common page-footer\'>\n\t<!-- \n\t\tPage Footer will contain\n\t\t\t+ table 3\n\t\t\t\t- Terms and Conditions\n\t\t\t\t- Total Rounded Amount Calculation\n\t\t\t\t- Total Rounded Amount in Words\n\t-->\n\t<table class=\'footer-table\' width=100% cellspacing=0>\n\t\t<thead>\n\t\t\t\n\t\t</thead>\n\t\t<tbody>\n\t\t\t<tr>\n\t\t\t\t<td width=60% style=\'padding-right: 10px;\'>\n\t\t\t\t\t<b>Terms, Conditions & Other Information:</b><br />\n\t\t\t\t\t<script>doc.terms</script>\n\t\t\t\t</td>\n\t\t\t\t<td>\n\t\t\t\t\t<table cellspacing=0 width=100%><tbody>\n\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t<td>Net Total</td>\n\t\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t\t<td width=38%><script>\n\t\t\t\t\t\t\t\tfmt_money(doc.net_total)\n\t\t\t\t\t\t\t</script></td>\n\t\t\t\t\t\t</tr>\n\t\t\t\t\t\t<tr><td colspan=3><script>si_std.print_other_charges()</script></td></tr>\n\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t<td>Grand Total</td>\n\t\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t\t<td><script>\n\t\t\t\t\t\t\t\tfmt_money(doc.grand_total_export)\n\t\t\t\t\t\t\t</script></td>\n\t\t\t\t\t\t</tr>\n\t\t\t\t\t\t<tr style=\'font-weight: bold\'>\n\t\t\t\t\t\t\t<td>Rounded Total</td>\n\t\t\t\t\t\t\t<td><script>doc.currency</script></td>\n\t\t\t\t\t\t\t<td><script>\n\t\t\t\t\t\t\t\tfmt_money(doc.rounded_total_export)\n\t\t\t\t\t\t\t</script></td>\n\t\t\t\t\t\t</tr>\n\t\t\t\t\t</tbody></table>\n\t\t\t\t\t<br /><b>In Words</b><br />\n\t\t\t\t\t<i><script>doc.in_words_export</script></i>\n\t\t\t\t</td>\n\t\t\t</tr>\t\t\n\t\t</tbody>\n\t\t<tfoot>\n\t\t\n\t\t</tfoot>\n\t</table>\n</div>\n',
+ 'module': 'Selling',
+ 'name': '__common__',
+ 'standard': 'Yes'
+ },
+
+ # Print Format, Sales Order Spartan
+ {
+ 'doctype': 'Print Format',
+ 'name': 'Sales Order Spartan'
+ }
+]
\ No newline at end of file
diff --git a/erpnext/selling/doctype/enquiry/enquiry.txt b/erpnext/selling/doctype/enquiry/enquiry.txt
index 260e077..0bf3b7f 100644
--- a/erpnext/selling/doctype/enquiry/enquiry.txt
+++ b/erpnext/selling/doctype/enquiry/enquiry.txt
@@ -5,15 +5,16 @@
{
'creation': '2010-08-08 17:09:00',
'docstatus': 0,
- 'modified': '2011-05-12 18:27:46',
+ 'modified': '2011-12-19 14:11:27',
'modified_by': 'Administrator',
'owner': 'Administrator'
},
# These values are common for all DocType
{
- '_last_update': '1305205067',
+ '_last_update': '1316075905',
'colour': 'White:FFF',
+ 'default_print_format': 'Standard',
'doctype': 'DocType',
'document_type': 'Transaction',
'module': 'Selling',
@@ -23,7 +24,7 @@
'server_code_error': ' ',
'show_in_menu': 0,
'subject': 'To %(customer_name)s%(lead_name)s on %(transaction_date)s',
- 'version': 586
+ 'version': 587
},
# These values are common for all DocField
@@ -57,7 +58,6 @@
'cancel': 0,
'create': 0,
'doctype': 'DocPerm',
- 'idx': 1,
'permlevel': 1,
'role': 'Sales Manager',
'submit': 0,
@@ -70,7 +70,6 @@
'cancel': 1,
'create': 1,
'doctype': 'DocPerm',
- 'idx': 2,
'permlevel': 0,
'role': 'System Manager',
'submit': 1,
@@ -80,7 +79,6 @@
# DocPerm
{
'doctype': 'DocPerm',
- 'idx': 3,
'permlevel': 1,
'role': 'System Manager'
},
@@ -91,7 +89,6 @@
'cancel': 1,
'create': 1,
'doctype': 'DocPerm',
- 'idx': 4,
'permlevel': 0,
'role': 'Sales User',
'submit': 1,
@@ -104,7 +101,6 @@
'cancel': 0,
'create': 0,
'doctype': 'DocPerm',
- 'idx': 5,
'permlevel': 1,
'role': 'Sales User',
'submit': 0,
@@ -117,7 +113,6 @@
'cancel': 1,
'create': 1,
'doctype': 'DocPerm',
- 'idx': 6,
'permlevel': 0,
'role': 'Sales Manager',
'submit': 1,
@@ -130,7 +125,6 @@
'description': 'Enter customer enquiry for which you might raise a quotation in future',
'doctype': 'DocField',
'fieldtype': 'Section Break',
- 'idx': 1,
'label': 'Basic Info',
'oldfieldtype': 'Section Break',
'permlevel': 0
@@ -143,7 +137,6 @@
'doctype': 'DocField',
'fieldname': 'naming_series',
'fieldtype': 'Select',
- 'idx': 2,
'label': 'Series',
'no_copy': 1,
'oldfieldname': 'naming_series',
@@ -159,7 +152,6 @@
'doctype': 'DocField',
'fieldname': 'enquiry_from',
'fieldtype': 'Select',
- 'idx': 3,
'label': 'Enquiry From',
'oldfieldname': 'enquiry_from',
'oldfieldtype': 'Select',
@@ -178,7 +170,6 @@
'fieldname': 'customer',
'fieldtype': 'Link',
'hidden': 0,
- 'idx': 4,
'in_filter': 1,
'label': 'Customer',
'oldfieldname': 'customer',
@@ -187,7 +178,7 @@
'permlevel': 0,
'print_hide': 1,
'reqd': 0,
- 'search_index': 1,
+ 'search_index': 0,
'trigger': 'Client'
},
@@ -196,7 +187,6 @@
'doctype': 'DocField',
'fieldname': 'customer_address',
'fieldtype': 'Link',
- 'idx': 5,
'in_filter': 1,
'label': 'Customer Address',
'options': 'Address',
@@ -210,7 +200,6 @@
'doctype': 'DocField',
'fieldname': 'contact_person',
'fieldtype': 'Link',
- 'idx': 6,
'in_filter': 1,
'label': 'Contact Person',
'options': 'Contact',
@@ -224,7 +213,6 @@
'doctype': 'DocField',
'fieldname': 'customer_name',
'fieldtype': 'Data',
- 'idx': 7,
'label': 'Customer Name',
'permlevel': 1,
'print_hide': 0
@@ -236,7 +224,6 @@
'fieldname': 'lead',
'fieldtype': 'Link',
'hidden': 0,
- 'idx': 8,
'in_filter': 1,
'label': 'Lead',
'oldfieldname': 'lead',
@@ -244,7 +231,6 @@
'options': 'Lead',
'permlevel': 0,
'print_hide': 1,
- 'search_index': 1,
'trigger': 'Client'
},
@@ -254,7 +240,6 @@
'fieldname': 'lead_name',
'fieldtype': 'Data',
'hidden': 0,
- 'idx': 9,
'label': 'Name',
'oldfieldname': 'lead_name',
'oldfieldtype': 'Data',
@@ -267,7 +252,6 @@
'fieldname': 'address_display',
'fieldtype': 'Small Text',
'hidden': 0,
- 'idx': 10,
'label': 'Address',
'oldfieldname': 'address',
'oldfieldtype': 'Small Text',
@@ -279,7 +263,6 @@
'doctype': 'DocField',
'fieldname': 'contact_display',
'fieldtype': 'Small Text',
- 'idx': 11,
'label': 'Contact',
'permlevel': 1
},
@@ -289,7 +272,6 @@
'doctype': 'DocField',
'fieldname': 'contact_mobile',
'fieldtype': 'Text',
- 'idx': 12,
'label': 'Contact Mobile No',
'permlevel': 1
},
@@ -299,7 +281,6 @@
'doctype': 'DocField',
'fieldname': 'contact_email',
'fieldtype': 'Text',
- 'idx': 13,
'label': 'Contact Email',
'permlevel': 1
},
@@ -308,7 +289,6 @@
{
'doctype': 'DocField',
'fieldtype': 'Column Break',
- 'idx': 14,
'oldfieldtype': 'Column Break',
'permlevel': 0,
'width': '50%'
@@ -321,13 +301,11 @@
'doctype': 'DocField',
'fieldname': 'transaction_date',
'fieldtype': 'Date',
- 'idx': 15,
'label': 'Enquiry Date',
'oldfieldname': 'transaction_date',
'oldfieldtype': 'Date',
'permlevel': 0,
'reqd': 1,
- 'search_index': 1,
'width': '50px'
},
@@ -337,7 +315,6 @@
'doctype': 'DocField',
'fieldname': 'enquiry_type',
'fieldtype': 'Select',
- 'idx': 16,
'label': 'Enquiry Type',
'oldfieldname': 'enquiry_type',
'oldfieldtype': 'Select',
@@ -353,7 +330,6 @@
'doctype': 'DocField',
'fieldname': 'status',
'fieldtype': 'Select',
- 'idx': 17,
'label': 'Status',
'no_copy': 1,
'oldfieldname': 'status',
@@ -368,7 +344,6 @@
'doctype': 'DocField',
'fieldname': 'amended_from',
'fieldtype': 'Data',
- 'idx': 18,
'label': 'Amended From',
'no_copy': 1,
'oldfieldname': 'amended_from',
@@ -383,7 +358,6 @@
'doctype': 'DocField',
'fieldname': 'amendment_date',
'fieldtype': 'Date',
- 'idx': 19,
'label': 'Amendment Date',
'no_copy': 1,
'oldfieldname': 'amendment_date',
@@ -400,26 +374,25 @@
'doctype': 'DocField',
'fieldname': 'territory',
'fieldtype': 'Link',
- 'idx': 20,
'in_filter': 1,
'label': 'Territory',
'options': 'Territory',
'permlevel': 0,
'print_hide': 1,
'reqd': 1,
- 'search_index': 0,
+ 'search_index': 1,
'trigger': 'Client'
},
# DocField
{
'colour': 'White:FFF',
+ 'depends_on': 'eval:doc.enquiry_from=="Customer"',
'description': '<a href="javascript:cur_frm.cscript.CGHelp();">To Manage Customer Groups, click here</a>',
'doctype': 'DocField',
'fieldname': 'customer_group',
'fieldtype': 'Link',
'hidden': 0,
- 'idx': 21,
'in_filter': 1,
'label': 'Customer Group',
'oldfieldname': 'customer_group',
@@ -428,7 +401,7 @@
'permlevel': 0,
'print_hide': 1,
'reqd': 0,
- 'search_index': 0,
+ 'search_index': 1,
'trigger': 'Client'
},
@@ -437,7 +410,6 @@
'colour': 'White:FFF',
'doctype': 'DocField',
'fieldtype': 'Section Break',
- 'idx': 22,
'label': 'Items',
'oldfieldtype': 'Section Break',
'permlevel': 0
@@ -450,7 +422,6 @@
'doctype': 'DocField',
'fieldname': 'enquiry_details',
'fieldtype': 'Table',
- 'idx': 23,
'label': 'Enquiry Details',
'oldfieldname': 'enquiry_details',
'oldfieldtype': 'Table',
@@ -464,7 +435,6 @@
'description': 'Filing in Additional Information about the Enquiry will help you analyze your data better.',
'doctype': 'DocField',
'fieldtype': 'Section Break',
- 'idx': 24,
'label': 'More Info',
'oldfieldtype': 'Section Break',
'permlevel': 0
@@ -474,7 +444,6 @@
{
'doctype': 'DocField',
'fieldtype': 'Column Break',
- 'idx': 25,
'oldfieldtype': 'Column Break',
'permlevel': 0,
'width': '50%'
@@ -485,7 +454,6 @@
'doctype': 'DocField',
'fieldname': 'company',
'fieldtype': 'Link',
- 'idx': 26,
'in_filter': 1,
'label': 'Company',
'oldfieldname': 'company',
@@ -494,7 +462,7 @@
'permlevel': 0,
'print_hide': 1,
'reqd': 1,
- 'search_index': 0
+ 'search_index': 1
},
# DocField
@@ -502,7 +470,6 @@
'doctype': 'DocField',
'fieldname': 'fiscal_year',
'fieldtype': 'Select',
- 'idx': 27,
'in_filter': 1,
'label': 'Fiscal Year',
'oldfieldname': 'fiscal_year',
@@ -511,7 +478,7 @@
'permlevel': 0,
'print_hide': 1,
'reqd': 1,
- 'search_index': 0
+ 'search_index': 1
},
# DocField
@@ -519,7 +486,6 @@
'doctype': 'DocField',
'fieldname': 'source',
'fieldtype': 'Select',
- 'idx': 28,
'label': 'Source',
'oldfieldname': 'source',
'oldfieldtype': 'Select',
@@ -534,7 +500,6 @@
'doctype': 'DocField',
'fieldname': 'campaign',
'fieldtype': 'Link',
- 'idx': 29,
'label': 'Campaign',
'oldfieldname': 'campaign',
'oldfieldtype': 'Link',
@@ -549,7 +514,6 @@
'doctype': 'DocField',
'fieldname': 'order_lost_reason',
'fieldtype': 'Small Text',
- 'idx': 30,
'label': 'Order Lost Reason',
'no_copy': 1,
'oldfieldname': 'order_lost_reason',
@@ -562,7 +526,6 @@
{
'doctype': 'DocField',
'fieldtype': 'Column Break',
- 'idx': 31,
'oldfieldtype': 'Column Break',
'permlevel': 0,
'width': '50%'
@@ -575,7 +538,6 @@
'doctype': 'DocField',
'fieldname': 'contact_by',
'fieldtype': 'Link',
- 'idx': 32,
'in_filter': 1,
'label': 'Next Contact By',
'oldfieldname': 'contact_by',
@@ -592,7 +554,6 @@
'doctype': 'DocField',
'fieldname': 'contact_date',
'fieldtype': 'Date',
- 'idx': 33,
'label': 'Next Contact Date',
'oldfieldname': 'contact_date',
'oldfieldtype': 'Date',
@@ -608,7 +569,6 @@
'doctype': 'DocField',
'fieldname': 'last_contact_date',
'fieldtype': 'Date',
- 'idx': 34,
'label': 'Last Contact Date',
'no_copy': 1,
'oldfieldname': 'last_contact_date',
@@ -622,7 +582,6 @@
'doctype': 'DocField',
'fieldname': 'to_discuss',
'fieldtype': 'Small Text',
- 'idx': 35,
'label': 'To Discuss',
'no_copy': 1,
'oldfieldname': 'to_discuss',
@@ -636,7 +595,6 @@
'description': 'Keep a track of communication related to this enquiry which will help for future reference.',
'doctype': 'DocField',
'fieldtype': 'Section Break',
- 'idx': 36,
'label': 'Communication History',
'oldfieldtype': 'Section Break',
'permlevel': 0
@@ -649,7 +607,6 @@
'doctype': 'DocField',
'fieldname': 'follow_up',
'fieldtype': 'Table',
- 'idx': 37,
'label': 'Follow Up',
'oldfieldname': 'follow_up',
'oldfieldtype': 'Table',
diff --git a/erpnext/selling/doctype/quotation/quotation.js b/erpnext/selling/doctype/quotation/quotation.js
index 21eceb9..4c205a9 100644
--- a/erpnext/selling/doctype/quotation/quotation.js
+++ b/erpnext/selling/doctype/quotation/quotation.js
@@ -18,7 +18,8 @@
if(!doc.transaction_date) set_multiple(cdt,cdn,{transaction_date:get_today()});
if(!doc.conversion_rate) set_multiple(cdt,cdn,{conversion_rate:'1.00'});
if(!doc.currency && sys_defaults.currency) set_multiple(cdt,cdn,{currency:sys_defaults.currency});
- //if(!doc.price_list_name && sys_defaults.price_list_name) set_multiple(cdt,cdn,{price_list_name:sys_defaults.price_list_name});
+ if(!doc.price_list_currency) set_multiple(cdt, cdn, {price_list_currency: doc.currency, plc_conversion_rate: 1});
+
if(!doc.company && sys_defaults.company) set_multiple(cdt,cdn,{company:sys_defaults.company});
if(!doc.fiscal_year && sys_defaults.fiscal_year) set_multiple(cdt,cdn,{fiscal_year:sys_defaults.fiscal_year});
@@ -51,7 +52,6 @@
hide_field(['lead','lead_name','address_display','contact_display','contact_mobile','contact_email','territory']);
doc.lead = doc.lead_name = doc.customer = doc.customer_address = doc.contact_person = doc.address_display = doc.contact_display = doc.contact_mobile = doc.contact_email = doc.territory = doc.customer_group = "";
}
- //refresh_many(['lead','customer']);
}
@@ -59,10 +59,6 @@
//================ hide - unhide fields on basis of quotation to either lead or customer ===============================
cur_frm.cscript.quotation_to = function(doc,cdt,cdn){
cur_frm.cscript.lead_cust_show(doc,cdt,cdn);
- //doc.customer_address = doc.territory = doc.contact_no = doc.email_id = "";
- //refresh_many(['territory','customer_address','contact_no','email_id']);
- //doc.address_display = doc.contact_display = "";
- //refresh_many(['address_display','contact_display']);
}
@@ -80,31 +76,8 @@
if (!doc.docstatus) hide_field(['Update Follow up']);
else unhide_field(['Update Follow up']);
- //cur_frm.cscript.lead_cust_show(doc,cdt,cdn);
}
-// ============== Lead and its Details ============================
-
-/*
-//================ create new contact ============================================================================
-cur_frm.cscript.new_contact = function(){
- tn = createLocal('Contact');
- locals['Contact'][tn].is_customer = 1;
- if(doc.customer) locals['Contact'][tn].customer = doc.customer;
- loaddoc('Contact', tn);
-}
-*/
-
-
-// DOCTYPE TRIGGERS
-// ====================================================================================
-
-/*
-// ***************** Get Contact Person based on customer selected *****************
-cur_frm.fields_dict['contact_person'].get_query = function(doc, cdt, cdn) {
- return 'SELECT `tabContact`.contact_name, `tabContact`.email_id FROM `tabContact` WHERE `tabContact`.is_customer = 1 AND `tabContact`.docstatus != 2 AND `tabContact`.customer = "'+ doc.customer +'" AND `tabContact`.docstatus != 2 AND `tabContact`.contact_name LIKE "%s" ORDER BY `tabContact`.contact_name ASC LIMIT 50';
-}
-*/
//customer
cur_frm.cscript.customer = function(doc,dt,dn) {
@@ -274,14 +247,6 @@
}
-
-
-/*
-//get query select Territory
-cur_frm.fields_dict['territory'].get_query = function(doc,cdt,cdn) {
- return 'SELECT `tabTerritory`.`name`,`tabTerritory`.`parent_territory` FROM `tabTerritory` WHERE `tabTerritory`.`is_group` = "No" AND `tabTerritory`.`docstatus`!= 2 AND `tabTerritory`.%(key)s LIKE "%s" ORDER BY `tabTerritory`.`name` ASC LIMIT 50';}
-*/
-
//===================== Quotation to validation - either customer or lead mandatory ====================
cur_frm.cscript.quot_to_validate = function(doc,cdt,cdn){
@@ -293,14 +258,11 @@
}
}
else if(doc.quotation_to == 'Customer'){
-
if(!doc.customer){
alert("Customer is mandatory.");
validated = false;
}
-
}
-
}
//===================validation function =================================
diff --git a/erpnext/selling/doctype/quotation/quotation.py b/erpnext/selling/doctype/quotation/quotation.py
index 1175540..10bccaf 100644
--- a/erpnext/selling/doctype/quotation/quotation.py
+++ b/erpnext/selling/doctype/quotation/quotation.py
@@ -133,24 +133,13 @@
# Does not allow same item code to be entered twice
# -------------------------------------------------
def validate_for_items(self):
- check_list=[]
chk_dupl_itm = []
for d in getlist(self.doclist,'quotation_details'):
- ch = sql("select is_stock_item from `tabItem` where name = '%s'"%d.item_code)
- if ch and ch[0][0]=='Yes':
- if cstr(d.item_code) in check_list:
- msgprint("Item %s has been entered twice." % d.item_code)
- raise Exception
- else:
- check_list.append(cstr(d.item_code))
-
- if ch and ch[0][0]=='No':
- f = [cstr(d.item_code),cstr(d.description)]
- if f in chk_dupl_itm:
- msgprint("Item %s has been entered twice." % d.item_code)
- raise Exception
- else:
- chk_dupl_itm.append(f)
+ if [cstr(d.item_code),cstr(d.description)] in chk_dupl_itm:
+ msgprint("Item %s has been entered twice. Please change description atleast to continue" % d.item_code)
+ raise Exception
+ else:
+ chk_dupl_itm.append([cstr(d.item_code),cstr(d.description)])
#do not allow sales item in maintenance quotation and service item in sales quotation
diff --git a/erpnext/selling/doctype/quotation/quotation.txt b/erpnext/selling/doctype/quotation/quotation.txt
index 6763c2d..ac58dc4 100644
--- a/erpnext/selling/doctype/quotation/quotation.txt
+++ b/erpnext/selling/doctype/quotation/quotation.txt
@@ -5,18 +5,28 @@
{
'creation': '2010-08-08 17:09:17',
'docstatus': 0,
- 'modified': '2011-06-21 17:17:07',
+ 'modified': '2011-12-22 19:03:04',
'modified_by': 'Administrator',
'owner': 'Administrator'
},
+ # These values are common for all DocField
+ {
+ 'doctype': 'DocField',
+ 'name': '__common__',
+ 'parent': 'Quotation',
+ 'parentfield': 'fields',
+ 'parenttype': 'DocType'
+ },
+
# These values are common for all DocType
{
- '_last_update': '1308741898',
+ '_last_update': '1322549700',
'allow_attach': 1,
'allow_email': 0,
'allow_trash': 1,
'colour': 'White:FFF',
+ 'default_print_format': 'Standard',
'doctype': 'DocType',
'document_type': 'Transaction',
'hide_toolbar': 0,
@@ -31,15 +41,15 @@
'show_in_menu': 0,
'subject': 'To %(customer_name)s on %(transaction_date)s worth %(currency)s %(grand_total_export)s',
'tag_fields': 'status',
- 'version': 596
+ 'version': 598
},
- # These values are common for all DocField
+ # These values are common for all DocFormat
{
- 'doctype': 'DocField',
+ 'doctype': 'DocFormat',
'name': '__common__',
'parent': 'Quotation',
- 'parentfield': 'fields',
+ 'parentfield': 'formats',
'parenttype': 'DocType'
},
@@ -49,8 +59,7 @@
'name': '__common__',
'parent': 'Quotation',
'parentfield': 'permissions',
- 'parenttype': 'DocType',
- 'read': 1
+ 'parenttype': 'DocType'
},
# DocType, Quotation
@@ -61,12 +70,19 @@
# DocPerm
{
+ 'doctype': 'DocPerm',
+ 'permlevel': 0,
+ 'role': 'user print'
+ },
+
+ # DocPerm
+ {
'amend': 0,
'cancel': 0,
'create': 0,
'doctype': 'DocPerm',
- 'idx': 1,
'permlevel': 1,
+ 'read': 1,
'role': 'Sales Manager',
'submit': 0,
'write': 0
@@ -78,8 +94,8 @@
'cancel': 1,
'create': 1,
'doctype': 'DocPerm',
- 'idx': 2,
'permlevel': 0,
+ 'read': 1,
'role': 'Sales Manager',
'submit': 1,
'write': 1
@@ -91,8 +107,8 @@
'cancel': 1,
'create': 1,
'doctype': 'DocPerm',
- 'idx': 3,
'permlevel': 0,
+ 'read': 1,
'role': 'Sales User',
'submit': 1,
'write': 1
@@ -104,8 +120,8 @@
'cancel': 0,
'create': 0,
'doctype': 'DocPerm',
- 'idx': 4,
'permlevel': 1,
+ 'read': 1,
'role': 'Sales User',
'submit': 0,
'write': 0
@@ -114,9 +130,9 @@
# DocPerm
{
'doctype': 'DocPerm',
- 'idx': 5,
'match': 'customer_name',
'permlevel': 0,
+ 'read': 1,
'role': 'Customer'
},
@@ -126,8 +142,8 @@
'cancel': 1,
'create': 1,
'doctype': 'DocPerm',
- 'idx': 6,
'permlevel': 0,
+ 'read': 1,
'role': 'Maintenance Manager',
'submit': 1,
'write': 1
@@ -136,8 +152,8 @@
# DocPerm
{
'doctype': 'DocPerm',
- 'idx': 7,
'permlevel': 1,
+ 'read': 1,
'role': 'Maintenance Manager'
},
@@ -147,8 +163,8 @@
'cancel': 1,
'create': 1,
'doctype': 'DocPerm',
- 'idx': 8,
'permlevel': 0,
+ 'read': 1,
'role': 'Maintenance User',
'submit': 1,
'write': 1
@@ -157,17 +173,34 @@
# DocPerm
{
'doctype': 'DocPerm',
- 'idx': 9,
'permlevel': 1,
+ 'read': 1,
'role': 'Maintenance User'
},
+ # DocFormat
+ {
+ 'doctype': 'DocFormat',
+ 'format': 'Quotation Classic'
+ },
+
+ # DocFormat
+ {
+ 'doctype': 'DocFormat',
+ 'format': 'Quotation Modern'
+ },
+
+ # DocFormat
+ {
+ 'doctype': 'DocFormat',
+ 'format': 'Quotation Spartan'
+ },
+
# DocField
{
'colour': 'White:FFF',
'doctype': 'DocField',
'fieldtype': 'Section Break',
- 'idx': 1,
'label': 'Basic Info',
'oldfieldtype': 'Section Break',
'permlevel': 0,
@@ -178,7 +211,6 @@
{
'doctype': 'DocField',
'fieldtype': 'Column Break',
- 'idx': 2,
'permlevel': 0,
'width': '50%'
},
@@ -190,7 +222,6 @@
'doctype': 'DocField',
'fieldname': 'naming_series',
'fieldtype': 'Select',
- 'idx': 3,
'label': 'Series',
'no_copy': 1,
'oldfieldname': 'naming_series',
@@ -207,7 +238,6 @@
'doctype': 'DocField',
'fieldname': 'quotation_to',
'fieldtype': 'Select',
- 'idx': 4,
'in_filter': 1,
'label': 'Quotation To',
'oldfieldname': 'quotation_to',
@@ -227,7 +257,6 @@
'fieldname': 'customer',
'fieldtype': 'Link',
'hidden': 0,
- 'idx': 5,
'in_filter': 1,
'label': 'Customer',
'oldfieldname': 'customer',
@@ -246,7 +275,6 @@
'fieldname': 'customer_address',
'fieldtype': 'Link',
'hidden': 0,
- 'idx': 6,
'in_filter': 1,
'label': 'Customer Address',
'options': 'Address',
@@ -262,7 +290,6 @@
'fieldname': 'contact_person',
'fieldtype': 'Link',
'hidden': 0,
- 'idx': 7,
'in_filter': 1,
'label': 'Contact Person',
'oldfieldname': 'contact_person',
@@ -279,7 +306,6 @@
'doctype': 'DocField',
'fieldname': 'customer_name',
'fieldtype': 'Data',
- 'idx': 8,
'label': 'Name',
'permlevel': 1
},
@@ -291,7 +317,6 @@
'fieldname': 'lead',
'fieldtype': 'Link',
'hidden': 0,
- 'idx': 9,
'in_filter': 1,
'label': 'Lead',
'oldfieldname': 'lead',
@@ -308,7 +333,6 @@
'doctype': 'DocField',
'fieldname': 'lead_name',
'fieldtype': 'Text',
- 'idx': 10,
'label': 'Name',
'permlevel': 1
},
@@ -320,7 +344,6 @@
'fieldname': 'address_display',
'fieldtype': 'Small Text',
'hidden': 0,
- 'idx': 11,
'in_filter': 0,
'label': 'Address',
'oldfieldname': 'customer_address',
@@ -337,7 +360,6 @@
'doctype': 'DocField',
'fieldname': 'contact_display',
'fieldtype': 'Small Text',
- 'idx': 12,
'in_filter': 0,
'label': 'Contact',
'permlevel': 1,
@@ -351,7 +373,6 @@
'fieldname': 'contact_mobile',
'fieldtype': 'Text',
'hidden': 0,
- 'idx': 13,
'label': 'Mobile No',
'permlevel': 1,
'print_hide': 0
@@ -363,7 +384,6 @@
'doctype': 'DocField',
'fieldname': 'contact_email',
'fieldtype': 'Text',
- 'idx': 14,
'label': 'Contact Email',
'permlevel': 1,
'print_hide': 1
@@ -374,7 +394,6 @@
'colour': 'White:FFF',
'doctype': 'DocField',
'fieldtype': 'Column Break',
- 'idx': 15,
'oldfieldtype': 'Column Break',
'permlevel': 0,
'width': '50%'
@@ -387,7 +406,6 @@
'doctype': 'DocField',
'fieldname': 'transaction_date',
'fieldtype': 'Date',
- 'idx': 16,
'in_filter': 1,
'label': 'Quotation Date',
'no_copy': 1,
@@ -405,7 +423,6 @@
'doctype': 'DocField',
'fieldname': 'order_type',
'fieldtype': 'Select',
- 'idx': 17,
'in_filter': 1,
'label': 'Order Type',
'oldfieldname': 'order_type',
@@ -425,7 +442,6 @@
'doctype': 'DocField',
'fieldname': 'status',
'fieldtype': 'Select',
- 'idx': 18,
'in_filter': 1,
'label': 'Status',
'no_copy': 1,
@@ -443,7 +459,6 @@
'doctype': 'DocField',
'fieldname': 'amended_from',
'fieldtype': 'Data',
- 'idx': 19,
'label': 'Amended From',
'no_copy': 1,
'oldfieldname': 'amended_from',
@@ -459,7 +474,6 @@
'doctype': 'DocField',
'fieldname': 'amendment_date',
'fieldtype': 'Date',
- 'idx': 20,
'label': 'Amendment Date',
'no_copy': 1,
'oldfieldname': 'amendment_date',
@@ -477,7 +491,6 @@
'fieldname': 'enq_no',
'fieldtype': 'Link',
'hidden': 0,
- 'idx': 21,
'in_filter': 1,
'label': 'Enquiry No',
'no_copy': 0,
@@ -495,7 +508,6 @@
'doctype': 'DocField',
'fieldtype': 'Button',
'hidden': 0,
- 'idx': 22,
'label': 'Pull Enquiry Detail',
'no_copy': 0,
'oldfieldtype': 'Button',
@@ -513,7 +525,6 @@
'fieldname': 'territory',
'fieldtype': 'Link',
'hidden': 0,
- 'idx': 23,
'in_filter': 1,
'label': 'Territory',
'options': 'Territory',
@@ -530,7 +541,6 @@
'doctype': 'DocField',
'fieldname': 'customer_group',
'fieldtype': 'Link',
- 'idx': 24,
'in_filter': 1,
'label': 'Customer Group',
'oldfieldname': 'customer_group',
@@ -548,7 +558,6 @@
'colour': 'White:FFF',
'doctype': 'DocField',
'fieldtype': 'Section Break',
- 'idx': 25,
'label': 'Items',
'oldfieldtype': 'Section Break',
'permlevel': 0,
@@ -558,24 +567,11 @@
# DocField
{
- 'doctype': 'DocField',
- 'fieldtype': 'Button',
- 'idx': 26,
- 'label': 'Clear Table',
- 'oldfieldtype': 'Button',
- 'options': 'clear_quotation_details',
- 'permlevel': 0,
- 'print_hide': 1
- },
-
- # DocField
- {
'colour': 'White:FFF',
'description': 'Select the price list as entered in "Price List" master. This will pull the reference rates of items against this price list as specified in "Item" master.',
'doctype': 'DocField',
'fieldname': 'price_list_name',
'fieldtype': 'Select',
- 'idx': 27,
'in_filter': 1,
'label': 'Price List',
'oldfieldname': 'price_list_name',
@@ -591,9 +587,35 @@
# DocField
{
+ 'colour': 'White:FFF',
+ 'description': 'Select the currency in which price list is maintained',
+ 'doctype': 'DocField',
+ 'fieldname': 'price_list_currency',
+ 'fieldtype': 'Select',
+ 'label': 'Price List Currency',
+ 'options': 'link:Currency',
+ 'permlevel': 0,
+ 'print_hide': 1,
+ 'reqd': 1
+ },
+
+ # DocField
+ {
+ 'colour': 'White:FFF',
+ 'description': 'Rate at which Price list currency is converted to your currency',
+ 'doctype': 'DocField',
+ 'fieldname': 'plc_conversion_rate',
+ 'fieldtype': 'Currency',
+ 'label': 'Price List Currency Conversion Rate',
+ 'permlevel': 0,
+ 'print_hide': 1,
+ 'reqd': 1
+ },
+
+ # DocField
+ {
'doctype': 'DocField',
'fieldtype': 'Column Break',
- 'idx': 28,
'permlevel': 0,
'width': '50%'
},
@@ -605,7 +627,6 @@
'doctype': 'DocField',
'fieldname': 'currency',
'fieldtype': 'Select',
- 'idx': 29,
'in_filter': 1,
'label': 'Currency',
'oldfieldname': 'currency',
@@ -627,7 +648,6 @@
'doctype': 'DocField',
'fieldname': 'conversion_rate',
'fieldtype': 'Currency',
- 'idx': 30,
'label': 'Currency Conversion Rate',
'oldfieldname': 'conversion_rate',
'oldfieldtype': 'Currency',
@@ -641,8 +661,18 @@
# DocField
{
'doctype': 'DocField',
+ 'fieldtype': 'Button',
+ 'label': 'Clear Table',
+ 'oldfieldtype': 'Button',
+ 'options': 'clear_quotation_details',
+ 'permlevel': 0,
+ 'print_hide': 1
+ },
+
+ # DocField
+ {
+ 'doctype': 'DocField',
'fieldtype': 'Section Break',
- 'idx': 31,
'options': 'Simple',
'permlevel': 0
},
@@ -655,7 +685,6 @@
'doctype': 'DocField',
'fieldname': 'quotation_details',
'fieldtype': 'Table',
- 'idx': 32,
'label': 'Quotation Details',
'oldfieldname': 'quotation_details',
'oldfieldtype': 'Table',
@@ -669,7 +698,6 @@
'doctype': 'DocField',
'fieldname': 'net_total',
'fieldtype': 'Currency',
- 'idx': 33,
'label': 'Net Total*',
'no_copy': 0,
'oldfieldname': 'net_total',
@@ -684,7 +712,6 @@
{
'doctype': 'DocField',
'fieldtype': 'Button',
- 'idx': 34,
'label': 'Re-Calculate Values',
'oldfieldtype': 'Button',
'permlevel': 0,
@@ -697,7 +724,6 @@
'colour': 'White:FFF',
'doctype': 'DocField',
'fieldtype': 'HTML',
- 'idx': 35,
'label': 'Note HTML',
'oldfieldtype': 'HTML',
'options': '<div style="margin-top:16px"><b>Note :</b> * In Base Currency\n</div>',
@@ -710,7 +736,6 @@
'colour': 'White:FFF',
'doctype': 'DocField',
'fieldtype': 'Section Break',
- 'idx': 36,
'label': 'Taxes',
'oldfieldtype': 'Section Break',
'permlevel': 0
@@ -722,7 +747,6 @@
'fieldname': 'charge',
'fieldtype': 'Link',
'hidden': 0,
- 'idx': 37,
'label': 'Select Charges Master',
'oldfieldname': 'charge',
'oldfieldtype': 'Link',
@@ -737,7 +761,6 @@
'doctype': 'DocField',
'fieldtype': 'Button',
'hidden': 0,
- 'idx': 38,
'label': 'Get Charges',
'oldfieldtype': 'Button',
'permlevel': 0,
@@ -750,7 +773,6 @@
'doctype': 'DocField',
'fieldname': 'other_charges',
'fieldtype': 'Table',
- 'idx': 39,
'label': 'Other Charges',
'oldfieldname': 'other_charges',
'oldfieldtype': 'Table',
@@ -763,7 +785,6 @@
'colour': 'White:FFF',
'doctype': 'DocField',
'fieldtype': 'Button',
- 'idx': 40,
'label': 'Calculate Charges',
'oldfieldtype': 'Button',
'permlevel': 0,
@@ -776,7 +797,6 @@
'doctype': 'DocField',
'fieldname': 'other_charges_total',
'fieldtype': 'Currency',
- 'idx': 41,
'label': 'Charges Total*',
'oldfieldname': 'other_charges_total',
'oldfieldtype': 'Currency',
@@ -789,7 +809,6 @@
'doctype': 'DocField',
'fieldname': 'grand_total',
'fieldtype': 'Currency',
- 'idx': 42,
'label': 'Grand Total*',
'no_copy': 0,
'oldfieldname': 'grand_total',
@@ -804,7 +823,6 @@
{
'doctype': 'DocField',
'fieldtype': 'HTML',
- 'idx': 43,
'label': 'Other Charges Calculation',
'oldfieldtype': 'HTML',
'permlevel': 0,
@@ -815,7 +833,6 @@
{
'doctype': 'DocField',
'fieldtype': 'HTML',
- 'idx': 44,
'label': 'OT Notes',
'oldfieldtype': 'HTML',
'options': '<div style="margin-top:16px"><b>Note :</b> * In Base Currency\n</div>',
@@ -828,7 +845,6 @@
'colour': 'White:FFF',
'doctype': 'DocField',
'fieldtype': 'Section Break',
- 'idx': 45,
'label': 'Totals',
'oldfieldtype': 'Section Break',
'permlevel': 0,
@@ -840,7 +856,6 @@
'doctype': 'DocField',
'fieldname': 'rounded_total',
'fieldtype': 'Currency',
- 'idx': 46,
'label': 'Rounded Total',
'no_copy': 0,
'oldfieldname': 'rounded_total',
@@ -858,7 +873,6 @@
'doctype': 'DocField',
'fieldname': 'in_words',
'fieldtype': 'Data',
- 'idx': 47,
'label': 'In Words',
'no_copy': 0,
'oldfieldname': 'in_words',
@@ -872,7 +886,6 @@
{
'doctype': 'DocField',
'fieldtype': 'Column Break',
- 'idx': 48,
'oldfieldtype': 'Column Break',
'permlevel': 0,
'print_hide': 1,
@@ -884,7 +897,6 @@
'doctype': 'DocField',
'fieldname': 'grand_total_export',
'fieldtype': 'Currency',
- 'idx': 49,
'label': 'Grand Total (Export)',
'no_copy': 0,
'oldfieldname': 'grand_total_export',
@@ -900,7 +912,6 @@
'doctype': 'DocField',
'fieldname': 'rounded_total_export',
'fieldtype': 'Currency',
- 'idx': 50,
'label': 'Rounded Total (Export)',
'no_copy': 0,
'oldfieldname': 'rounded_total_export',
@@ -918,7 +929,6 @@
'doctype': 'DocField',
'fieldname': 'in_words_export',
'fieldtype': 'Data',
- 'idx': 51,
'label': 'In Words (Export)',
'no_copy': 0,
'oldfieldname': 'in_words_export',
@@ -934,7 +944,6 @@
'description': 'Add Terms and Conditions for the Quotation like Payment Terms, Validity of Offer etc. You can also prepare a master Term Sheet and use the Template',
'doctype': 'DocField',
'fieldtype': 'Section Break',
- 'idx': 52,
'label': 'Terms',
'oldfieldtype': 'Section Break',
'permlevel': 0,
@@ -947,7 +956,6 @@
'doctype': 'DocField',
'fieldname': 'letter_head',
'fieldtype': 'Select',
- 'idx': 53,
'label': 'Letter Head',
'oldfieldname': 'letter_head',
'oldfieldtype': 'Select',
@@ -961,7 +969,6 @@
'doctype': 'DocField',
'fieldname': 'tc_name',
'fieldtype': 'Link',
- 'idx': 54,
'label': 'Select Terms',
'oldfieldname': 'tc_name',
'oldfieldtype': 'Link',
@@ -975,7 +982,6 @@
{
'doctype': 'DocField',
'fieldtype': 'Button',
- 'idx': 55,
'label': 'Get Terms',
'oldfieldtype': 'Button',
'options': 'get_tc_details',
@@ -986,7 +992,6 @@
{
'doctype': 'DocField',
'fieldtype': 'HTML',
- 'idx': 56,
'label': 'Terms HTML',
'oldfieldtype': 'HTML',
'options': 'You can add Terms and Notes that will be printed in the Transaction',
@@ -999,7 +1004,6 @@
'doctype': 'DocField',
'fieldname': 'terms',
'fieldtype': 'Text Editor',
- 'idx': 57,
'label': 'Term Details',
'oldfieldname': 'terms',
'oldfieldtype': 'Text Editor',
@@ -1012,7 +1016,6 @@
'description': 'Filling in additional information about the Quotation will help you analyze your data better.',
'doctype': 'DocField',
'fieldtype': 'Section Break',
- 'idx': 58,
'label': 'More Info',
'oldfieldtype': 'Section Break',
'permlevel': 0,
@@ -1026,7 +1029,6 @@
'doctype': 'DocField',
'fieldname': 'company',
'fieldtype': 'Link',
- 'idx': 59,
'in_filter': 1,
'label': 'Company',
'oldfieldname': 'company',
@@ -1046,7 +1048,6 @@
'doctype': 'DocField',
'fieldname': 'fiscal_year',
'fieldtype': 'Select',
- 'idx': 60,
'in_filter': 1,
'label': 'Fiscal Year',
'oldfieldname': 'fiscal_year',
@@ -1065,7 +1066,6 @@
'fieldname': 'enq_det',
'fieldtype': 'Text',
'hidden': 1,
- 'idx': 61,
'label': 'Enquiry Detail',
'no_copy': 0,
'oldfieldname': 'enq_det',
@@ -1082,7 +1082,6 @@
'fieldname': 'source',
'fieldtype': 'Select',
'hidden': 0,
- 'idx': 62,
'label': 'Source',
'no_copy': 0,
'oldfieldname': 'source',
@@ -1100,7 +1099,6 @@
'fieldname': 'campaign',
'fieldtype': 'Link',
'hidden': 0,
- 'idx': 63,
'label': 'Campaign',
'no_copy': 0,
'oldfieldname': 'campaign',
@@ -1117,7 +1115,6 @@
'doctype': 'DocField',
'fieldname': 'select_print_heading',
'fieldtype': 'Link',
- 'idx': 64,
'label': 'Select Print Heading',
'no_copy': 1,
'oldfieldname': 'select_print_heading',
@@ -1134,7 +1131,6 @@
'doctype': 'DocField',
'fieldname': 'cancel_reason',
'fieldtype': 'Data',
- 'idx': 65,
'label': 'Cancel Reason',
'no_copy': 1,
'oldfieldname': 'cancel_reason',
@@ -1150,7 +1146,6 @@
'doctype': 'DocField',
'fieldname': 'order_lost_reason',
'fieldtype': 'Small Text',
- 'idx': 66,
'label': 'Order Lost Reason',
'no_copy': 1,
'oldfieldname': 'order_lost_reason',
@@ -1163,7 +1158,6 @@
{
'doctype': 'DocField',
'fieldtype': 'Column Break',
- 'idx': 67,
'oldfieldtype': 'Column Break',
'permlevel': 0,
'print_hide': 1,
@@ -1176,7 +1170,6 @@
'doctype': 'DocField',
'fieldname': 'contact_by',
'fieldtype': 'Link',
- 'idx': 68,
'label': 'Next Contact By',
'oldfieldname': 'contact_by',
'oldfieldtype': 'Link',
@@ -1191,7 +1184,6 @@
'doctype': 'DocField',
'fieldname': 'contact_date',
'fieldtype': 'Date',
- 'idx': 69,
'label': 'Next Contact Date',
'oldfieldname': 'contact_date',
'oldfieldtype': 'Date',
@@ -1206,7 +1198,6 @@
'doctype': 'DocField',
'fieldname': 'last_contact_date',
'fieldtype': 'Date',
- 'idx': 70,
'label': 'Last Contact Date',
'no_copy': 1,
'oldfieldname': 'last_contact_date',
@@ -1220,7 +1211,6 @@
'doctype': 'DocField',
'fieldname': 'to_discuss',
'fieldtype': 'Small Text',
- 'idx': 71,
'label': 'To Discuss',
'oldfieldname': 'to_discuss',
'oldfieldtype': 'Small Text',
@@ -1234,7 +1224,6 @@
'description': 'Keep a track on communications regarding this Quotation. This will help you remember earlier communications in case the Customer comes back again',
'doctype': 'DocField',
'fieldtype': 'Section Break',
- 'idx': 72,
'label': 'Communication History',
'oldfieldtype': 'Section Break',
'permlevel': 0,
@@ -1248,7 +1237,6 @@
'doctype': 'DocField',
'fieldname': 'follow_up',
'fieldtype': 'Table',
- 'idx': 73,
'label': 'Follow up',
'oldfieldname': 'follow_up',
'oldfieldtype': 'Table',
@@ -1265,7 +1253,6 @@
'fieldname': 'file_list',
'fieldtype': 'Small Text',
'hidden': 1,
- 'idx': 74,
'label': 'File List',
'no_copy': 1,
'permlevel': 0,
diff --git a/erpnext/selling/doctype/sales_common/sales_common.js b/erpnext/selling/doctype/sales_common/sales_common.js
index f4b3f02..0cc8868 100644
--- a/erpnext/selling/doctype/sales_common/sales_common.js
+++ b/erpnext/selling/doctype/sales_common/sales_common.js
@@ -19,9 +19,10 @@
// -----------------
// Shipping Address
// -----------------
-//cur_frm.add_fetch('ship_det_no', 'shipping_address', 'shipping_address');
-//cur_frm.add_fetch('ship_det_no', 'ship_to', 'ship_to');
+
cur_frm.add_fetch('company', 'default_currency', 'currency');
+cur_frm.add_fetch('company', 'default_currency', 'price_list_currency');
+
// ============== Customer and its primary contact Details ============================
@@ -59,15 +60,6 @@
loadpage('Sales Browser',call_back);
}
-/*
-// ============= Customer's Contact Person Details =====================================
-cur_frm.cscript.contact_person = function(doc, cdt, cdn) {
- var callback = function(){
- refresh_many(['contact_no','email_id','customer_mobile_no','customer_address']);
- }
- get_server_fields('get_contact_details','','',doc, cdt, cdn, 1, callback);
-}
-*/
// TRIGGERS FOR CALCULATIONS
// =====================================================================================================
@@ -77,10 +69,17 @@
cur_frm.cscript.price_list_name(doc, cdt, cdn);
}
+cur_frm.cscript.price_list_currency = cur_frm.cscript.currency;
+cur_frm.cscript.conversion_rate = cur_frm.cscript.currency;
+cur_frm.cscript.plc_conversion_rate = cur_frm.cscript.currency;
+
+
+
// ******************** PRICE LIST ******************************
cur_frm.cscript.price_list_name = function(doc, cdt, cdn) {
var fname = cur_frm.cscript.fname;
- if(doc.price_list_name && doc.currency) {
+ var cl = getchildren(cur_frm.cscript.tname, doc.name, cur_frm.cscript.fname);
+ if(doc.price_list_name && doc.currency && doc.price_list_currency && doc.conversion_rate && doc.plc_conversion_rate && cl.length) {
$c_obj(make_doclist(doc.doctype, doc.name), 'get_adj_percent', '',
function(r, rt) {
refresh_field(fname);
@@ -92,8 +91,6 @@
}
-// ******************* CONVERSION RATE ***************************
-cur_frm.cscript.conversion_rate = function(doc, cdt, cdn) { cur_frm.cscript.recalc(doc, 3);/*cur_frm.cscript.price_list_name(doc, cdt, cdn);*/ }
// ******************** ITEM CODE ********************************
cur_frm.fields_dict[cur_frm.cscript.fname].grid.get_field("item_code").get_query = function(doc, cdt, cdn) {
@@ -104,7 +101,6 @@
}
-
cur_frm.cscript.item_code = function(doc, cdt, cdn) {
var fname = cur_frm.cscript.fname;
var d = locals[cdt][cdn];
@@ -125,6 +121,7 @@
}
}
+
// *********************** QUANTITY ***************************
cur_frm.cscript.qty = function(doc, cdt, cdn) { cur_frm.cscript.recalc(doc, 1); }
@@ -133,26 +130,49 @@
// ************************ REF RATE ****************************
cur_frm.cscript.ref_rate = function(doc, cdt, cdn){
- var d = locals[cdt][cdn];
- set_multiple(cur_frm.cscript.tname, d.name, {'export_rate': flt(d.ref_rate) * (100 - flt(d.adj_rate)) / 100}, cur_frm.cscript.fname);
- cur_frm.cscript.recalc(doc, 3);
+ var d = locals[cdt][cdn];
+ var consider_incl_rate = cur_frm.cscript.consider_incl_rate(doc, cur_frm.cscript.other_fname);
+ if(!consider_incl_rate) {
+ set_multiple(cur_frm.cscript.tname, d.name, {'export_rate': flt(d.ref_rate) * (100 - flt(d.adj_rate)) / 100}, cur_frm.cscript.fname);
+ }
+ cur_frm.cscript.recalc(doc, 1);
}
// *********************** BASIC RATE **************************
cur_frm.cscript.basic_rate = function(doc, cdt, cdn) {
- var fname = cur_frm.cscript.fname;
- var d = locals[cdt][cdn];;
- if(!d.qty)
- {
- d.qty = 1;
- refresh_field('qty', d.name, fname);
-
- }
- cur_frm.cscript.recalc(doc, 2);
+ var fname = cur_frm.cscript.fname;
+ var d = locals[cdt][cdn];
+ if(!d.qty) {
+ d.qty = 1;
+ refresh_field('qty', d.name, fname);
+ }
+ var consider_incl_rate = cur_frm.cscript.consider_incl_rate(doc, cur_frm.cscript.other_fname);
+ if(!consider_incl_rate) {
+ cur_frm.cscript.recalc(doc, 2);
+ } else {
+ var basic_rate = cur_frm.cscript.back_calc_basic_rate(
+ doc, cur_frm.cscript.tname, fname, d, cur_frm.cscript.other_fname
+ );
+ if (d.basic_rate != basic_rate.toFixed(2)) {
+ d.basic_rate = basic_rate;
+ refresh_field('basic_rate', d.name, fname);
+ msgprint("You cannot change Basic Rate* (Base Currency) when \
+ considering rates inclusive of taxes.<br /> \
+ Please either <br /> \
+ * Specify Basic Rate (i.e. Rate which will be displayed in print) <br /> \
+ -- or -- <br />\
+ * Uncheck 'Included in Print Rate' in the tax entries of Taxes section.");
+ }
+ }
}
// ************************ EXPORT RATE *************************
-cur_frm.cscript.export_rate = function(doc,cdt,cdn) { cur_frm.cscript.recalc(doc, 3);}
+cur_frm.cscript.export_rate = function(doc,cdt,cdn) {
+ doc = locals[doc.doctype][doc.name];
+ cur_frm.cscript.recalc(doc, 1);
+}
+
+
// ************* GET OTHER CHARGES BASED ON COMPANY *************
cur_frm.fields_dict.charge.get_query = function(doc) {
@@ -176,8 +196,9 @@
var other_fname = cur_frm.cscript.other_fname;
if(!flt(doc.conversion_rate)) { doc.conversion_rate = 1; refresh_field('conversion_rate'); }
+ if(!flt(doc.plc_conversion_rate)) { doc.plc_conversion_rate = 1; refresh_field('plc_conversion_rate'); }
- if(n > 0) cur_frm.cscript.update_fname_table(doc , tname , fname , n); // updates all values in table (i.e. amount, export amount, net total etc.)
+ if(n > 0) cur_frm.cscript.update_fname_table(doc , tname , fname , n, other_fname); // updates all values in table (i.e. amount, export amount, net total etc.)
if(flt(doc.net_total) > 0) {
var cl = getchildren('RV Tax Detail', doc.name, other_fname,doc.doctype);
@@ -218,11 +239,18 @@
for(var i = 0; i<cl.length; i++){
net_total += flt(cl[i].amount);
}
+ net_total_incl = net_total
var d = getchildren('RV Tax Detail', doc.name, other_fname,doc.doctype);
for(var j = 0; j<d.length; j++){
other_charges_total += flt(d[j].amount);
+ if(d[j].included_in_print_rate) {
+ net_total_incl += flt(d[j].amount);
+ }
}
- doc.net_total = flt(net_total);
+ console.log("Net Total: " + net_total);
+ console.log("Net Total Incl: " + net_total_incl);
+ console.log("Other Charges: " + other_charges_total);
+ doc.net_total = net_total_incl > net_total ? flt(net_total_incl) : flt(net_total);
doc.other_charges_total = flt(other_charges_total);
doc.grand_total = flt(flt(net_total) + flt(other_charges_total));
doc.rounded_total = Math.round(doc.grand_total);
@@ -278,9 +306,12 @@
// this is calculation part for all types
if(tax[t].charge_type != "Actual") tax[t].item_wise_tax_detail += item_wise_tax_detail;
- tax[t].total_amount = flt(tax_amount.toFixed(2)); //stores actual tax amount in virtual field
- tax[t].total_tax_amount = flt(prev_total.toFixed(2)); //stores total amount in virtual field
- tax[t].tax_amount += flt(tax_amount.toFixed(2));
+ //tax[t].total_amount = flt(tax_amount.toFixed(2)); //stores actual tax amount in virtual field
+ //tax[t].total_tax_amount = flt(prev_total.toFixed(2)); //stores total amount in virtual field
+ //tax[t].tax_amount += flt(tax_amount.toFixed(2));
+ tax[t].total_amount = flt(tax_amount); //stores actual tax amount in virtual field
+ tax[t].total_tax_amount = flt(prev_total); //stores total amount in virtual field
+ tax[t].tax_amount += flt(tax_amount);
var total_amount = flt(tax[t].tax_amount);
total_tax_amount = flt(tax[t].total_tax_amount) + flt(total_amount);
set_multiple('RV Tax Detail', tax[t].name, { 'item_wise_tax_detail':tax[t].item_wise_tax_detail, 'amount':total_amount, 'total':flt(total)+flt(tax[t].tax_amount)/*_tax_amount)*/}, other_fname);
@@ -311,7 +342,8 @@
refresh_field('total_excise_rate');
return
}
- return tax_amount = (flt(rate) * flt(cl.amount) / 100);
+
+ return tax_amount = (flt(rate) * flt(cl.amount) / 100);
}
else if(tax[t].charge_type == 'On Previous Row Amount'){
if(flt(print_amt) == 1) {
@@ -347,28 +379,150 @@
}
}
+// ********************** Functions for inclusive value calc ******************************
+cur_frm.cscript.consider_incl_rate = function(doc, other_fname) {
+ var tax_list = getchildren('RV Tax Detail', doc.name, other_fname, doc.doctype);
+ for(var i=0; i<tax_list.length; i++) {
+ if(tax_list[i].included_in_print_rate) {
+ console.log('consider incl rate');
+ return true;
+ }
+ }
+ console.log('do not consider incl rate');
+ return false;
+}
+
+cur_frm.cscript.back_calc_basic_rate = function(doc, tname, fname, child, other_fname) {
+
+ var get_item_tax_rate = function(item, tax) {
+ if(item.item_tax_rate) {
+ // Should to replace eval with JSON.parse when item_tax_rate is converted to json string notation
+ var item_tax = eval('var a='+item.item_tax_rate+';a');
+ if(item_tax[tax.account_head]!=null) {
+ return flt(item_tax[tax.account_head]);
+ }
+ }
+ };
+
+ var tax_list = getchildren('RV Tax Detail', doc.name, other_fname, doc.doctype);
+ var total = 1;
+ var temp_tax_list = [];
+ var amt = 0;
+ var item_tax_rate = 0;
+ var rate = 0;
+ for(var i=0; i<tax_list.length; i++) {
+ amt = 0;
+ item_tax_rate = get_item_tax_rate(child, tax_list[i]);
+ rate = item_tax_rate ? item_tax_rate : flt(tax_list[i].rate);
+ if(tax_list[i].included_in_print_rate) {
+ if(tax_list[i].charge_type=='On Net Total') {
+ amt = flt(rate / 100);
+ } else if(tax_list[i].charge_type=='On Previous Row Total') {
+ amt = flt((rate * temp_tax_list[tax_list[i].row_id-1]['total']) / 100);
+ } else if(tax_list[i].charge_type=='On Previous Row Amount') {
+ amt = flt((rate * temp_tax_list[tax_list[i].row_id-1]['amt']) / 100);
+ }
+ }
+ total += flt(amt);
+ temp_tax_list[i] = {
+ amt: amt,
+ total: total
+ };
+ }
+ var basic_rate = flt((child.export_rate * flt(doc.conversion_rate)) / total);
+ console.log(temp_tax_list);
+ console.log('in basic rate back calc');
+ console.log(basic_rate);
+ return basic_rate;
+}
+
+cur_frm.cscript.included_in_print_rate = function(doc, cdt, cdn) {
+ var tax = locals[cdt][cdn];
+ if(tax.included_in_print_rate==1) {
+ if(!inList(['On Net Total', 'On Previous Row Total', 'On Previous Row Amount'], tax.charge_type)) {
+ msgprint("Included in Print Rate (i.e. Inclusive Price) is only valid for charges of type: <br /> \
+ * On Net Total <br /> \
+ * On Previous Row Amount <br /> \
+ * On Previous Row Total");
+ tax.included_in_print_rate = 0;
+ refresh_field('included_in_print_rate', tax.name, cur_frm.cscript.other_fname);
+ } else if(inList(['On Previous Row Total', 'On Previous Row Amount'], tax.charge_type)){
+ if(tax.row_id) {
+ var tax_list = getchildren('RV Tax Detail', doc.name, cur_frm.cscript.other_fname, doc.doctype);
+ if(tax_list[tax.row_id-1].charge_type=='Actual') {
+ msgprint("Row of type 'Actual' cannot be depended on for type '" + tax.charge_type + "'\
+ when using tax inclusive prices.<br />\
+ This will lead to incorrect values.<br /><br /> \
+ <b>Please specify correct value in 'Enter Row' column of <span style='color:red'>Row: "
+ + tax.idx + "</span> in Taxes table</b>");
+ validated = false;
+ tax.included_in_print_rate = 0;
+ refresh_field('included_in_print_rate', tax.name, cur_frm.cscript.other_fname);
+ }
+ }
+ }
+ }
+}
+
// ********************** Update values in table ******************************
-cur_frm.cscript.update_fname_table = function(doc , tname , fname , n) {
+cur_frm.cscript.update_fname_table = function(doc , tname , fname , n, other_fname) {
doc = locals[doc.doctype][doc.name]
var net_total = 0
var cl = getchildren(tname, doc.name, fname);
+ var consider_incl_rate = cur_frm.cscript.consider_incl_rate(doc, other_fname);
for(var i=0;i<cl.length;i++) {
if(n == 1){
- if(flt(cl[i].ref_rate) > 0)
- set_multiple(tname, cl[i].name, {'export_rate': flt(flt(cl[i].ref_rate) * (100 - flt(cl[i].adj_rate)) / 100)}, fname);
- set_multiple(tname, cl[i].name, {'export_amount': flt(flt(cl[i].qty) * flt(cl[i].export_rate)), 'basic_rate': flt(flt(cl[i].export_rate) * flt(doc.conversion_rate)), 'amount': flt((flt(cl[i].export_rate) * flt(doc.conversion_rate)) * flt(cl[i].qty)) }, fname);
+ if(!consider_incl_rate && (flt(cl[i].ref_rate) > 0)) {
+ set_multiple(tname, cl[i].name, {
+ 'export_rate': flt(flt(cl[i].ref_rate) * (100 - flt(cl[i].adj_rate)) / 100)
+ }, fname);
+
+ set_multiple(tname, cl[i].name, {
+ 'export_amount': flt(flt(cl[i].qty) * flt(cl[i].export_rate)),
+ 'basic_rate': flt(flt(cl[i].export_rate) * flt(doc.conversion_rate)),
+ 'amount': flt((flt(cl[i].export_rate) * flt(doc.conversion_rate)) * flt(cl[i].qty))
+ }, fname);
+
+ var base_ref_rate = flt(cl[i].basic_rate) + flt(flt(cl[i].basic_rate) * flt(cl[i].adj_rate) / 100);
+ set_multiple(tname, cl[i].name, {
+ 'base_ref_rate': flt(base_ref_rate)
+ }, fname);
+
+ } else if(consider_incl_rate) {
+ if(flt(cl[i].export_rate) > 0) {
+ // calculate basic rate based on taxes
+ // then calculate and set basic_rate, base_ref_rate, ref_rate, amount, export_amount
+ var ref_rate = flt(cl[i].adj_rate)!=flt(100) ?
+ flt((100 * flt(cl[i].export_rate))/flt(100 - flt(cl[i].adj_rate))) :
+ flt(0)
+ set_multiple(tname, cl[i].name, { 'ref_rate': ref_rate }, fname);
+ } else if((flt(cl[i].ref_rate) > 0) && (flt(cl[i].adj_rate) > 0)) {
+ var export_rate = flt(cl[i].ref_rate) * flt(1 - flt(cl[i].adj_rate / 100));
+ set_multiple(tname, cl[i].name, { 'export_rate': flt(export_rate) }, fname);
+ }
+ console.log("export_rate: " + cl[i].export_rate);
+
+ var basic_rate = cur_frm.cscript.back_calc_basic_rate(doc, tname, fname, cl[i], other_fname);
+ var base_ref_rate = basic_rate + flt(basic_rate * flt(cl[i].adj_rate) / 100);
+ set_multiple(tname, cl[i].name, {
+ 'basic_rate': flt(basic_rate),
+ 'amount': flt(basic_rate * flt(cl[i].qty)),
+ 'export_amount': flt(flt(cl[i].qty) * flt(cl[i].export_rate)),
+ 'base_ref_rate': flt(base_ref_rate)
+ }, fname);
+ }
}
else if(n == 2){
if(flt(cl[i].ref_rate) > 0)
set_multiple(tname, cl[i].name, {'adj_rate': 100 - flt(flt(cl[i].basic_rate) * 100 / (flt(cl[i].ref_rate) * flt(doc.conversion_rate)))}, fname);
set_multiple(tname, cl[i].name, {'amount': flt(flt(cl[i].qty) * flt(cl[i].basic_rate)), 'export_rate': flt(flt(cl[i].basic_rate) / flt(doc.conversion_rate)), 'export_amount': flt((flt(cl[i].basic_rate) / flt(doc.conversion_rate)) * flt(cl[i].qty)) }, fname);
}
- else if(n == 3){
+ /*else if(n == 3){
set_multiple(tname, cl[i].name, {'basic_rate': flt(flt(cl[i].export_rate) * flt(doc.conversion_rate))}, fname);
set_multiple(tname, cl[i].name, {'amount' : flt(flt(cl[i].basic_rate) * flt(cl[i].qty)), 'export_amount': flt(flt(cl[i].export_rate) * flt(cl[i].qty))}, fname);
if(cl[i].ref_rate > 0)
- set_multiple(tname, cl[i].name, {'adj_rate': 100 - flt(flt(cl[i].export_rate) * 100 / flt(cl[i].ref_rate)), 'base_ref_rate': flt(flt(cl[i].ref_rate) * flt(doc.conversion_rate)) }, fname);
- }
+ set_multiple(tname, cl[i].name, {'adj_rate': 100 - flt(flt(cl[i].export_rate) * 100 / flt(cl[i].ref_rate)), 'base_ref_rate': flt(flt(cl[i].ref_rate) * flt(doc.conversion_rate)) }, fname);
+ }*/
net_total += flt(flt(cl[i].qty) * flt(cl[i].basic_rate));
}
doc.net_total = net_total;
@@ -389,20 +543,31 @@
}
cur_frm.cscript['Calculate Charges'] = function(doc, cdt, cdn) {
- var other_fname = cur_frm.cscript.other_fname;
+ var other_fname = cur_frm.cscript.other_fname;
- var cl = getchildren('RV Tax Detail', doc.name, other_fname, doc.doctype);
- for(var i = 0; i<cl.length; i++){
- cl[i].total_tax_amount = 0;
- cl[i].total_amount = 0;
- cl[i].tax_amount = 0; // this is done to calculate other charges
- cl[i].total = 0;
- if(in_list(['On Previous Row Amount','On Previous Row Total'],cl[i].charge_type) && !cl[i].row_id){
- alert("Please Enter Row on which amount needs to be calculated for row : "+cl[i].idx);
- validated = false;
- }
- }
- cur_frm.cscript.recalc(doc, 1);
+ var cl = getchildren('RV Tax Detail', doc.name, other_fname, doc.doctype);
+ for(var i = 0; i<cl.length; i++){
+ cl[i].total_tax_amount = 0;
+ cl[i].total_amount = 0;
+ cl[i].tax_amount = 0; // this is done to calculate other charges
+ cl[i].total = 0;
+ if(in_list(['On Previous Row Amount','On Previous Row Total'], cl[i].charge_type)) {
+ if(!cl[i].row_id){
+ alert("Please Enter Row on which amount needs to be calculated for row : "+cl[i].idx);
+ validated = false;
+ } else if(cl[cl[i].row_id-1].charge_type=='Actual') {
+ msgprint("Row of type 'Actual' cannot be depended on for type '" + cl[i].charge_type + "'\
+ when using tax inclusive prices.<br />\
+ This will lead to incorrect values.<br /><br /> \
+ <b>Please specify correct value in 'Enter Row' column of <span style='color:red'>Row: "
+ + cl[i].idx + "</span> in Taxes table</b>");
+ validated = false;
+ cl[i].included_in_print_rate = 0;
+ refresh_field('included_in_print_rate', cl[i].name, other_fname);
+ }
+ }
+ }
+ cur_frm.cscript.recalc(doc, 1);
}
// Get Sales Partner Commission
diff --git a/erpnext/selling/doctype/sales_common/sales_common.py b/erpnext/selling/doctype/sales_common/sales_common.py
index 78454ee..ea9ffe9 100644
--- a/erpnext/selling/doctype/sales_common/sales_common.py
+++ b/erpnext/selling/doctype/sales_common/sales_common.py
@@ -135,32 +135,31 @@
'batch_no' : ''
}
if(obj.doc.price_list_name and item): #this is done to fetch the changed BASIC RATE and REF RATE based on PRICE LIST
- ref_rate = self.get_ref_rate(item_code, obj.doc.price_list_name, obj.doc.currency)
- ret['ref_rate'] = flt(ref_rate)
- ret['export_rate'] = flt(ref_rate)
- ret['base_ref_rate'] = flt(ref_rate) * flt(obj.doc.conversion_rate)
- ret['basic_rate'] = flt(ref_rate) * flt(obj.doc.conversion_rate)
-
- if obj.doc.doctype == 'Receivable Voucher':
- return ret
-
+ base_ref_rate = self.get_ref_rate(item_code, obj.doc.price_list_name, obj.doc.price_list_currency, obj.doc.plc_conversion_rate)
+ ret['ref_rate'] = flt(base_ref_rate)/flt(obj.doc.conversion_rate)
+ ret['export_rate'] = flt(base_ref_rate)/flt(obj.doc.conversion_rate)
+ ret['base_ref_rate'] = flt(base_ref_rate)
+ ret['basic_rate'] = flt(base_ref_rate)
+
return ret
# ***************** Get Ref rate as entered in Item Master ********************
- def get_ref_rate(self, item_code, price_list_name, currency):
- ref_rate = sql("select ref_rate from `tabRef Rate Detail` where parent = %s and price_list_name = %s and ref_currency = %s", (item_code, price_list_name, currency))
- return ref_rate and ref_rate[0][0] or 0
+ def get_ref_rate(self, item_code, price_list_name, price_list_currency, plc_conv_rate):
+ ref_rate = sql("select ref_rate from `tabRef Rate Detail` where parent = %s and price_list_name = %s and ref_currency = %s", (item_code, price_list_name, price_list_currency))
+ base_ref_rate = ref_rate and flt(ref_rate[0][0]) * flt(plc_conv_rate) or 0
+ return base_ref_rate
- # ****** Re-calculates Basic Rate & amount based on Price List Selected ******
+ # ****** Re-cancellculates Basic Rate & amount based on Price List Selected ******
def get_adj_percent(self, obj):
for d in getlist(obj.doclist, obj.fname):
- ref_rate = self.get_ref_rate(d.item_code,obj.doc.price_list_name,obj.doc.currency)
+ base_ref_rate = self.get_ref_rate(d.item_code, obj.doc.price_list_name, obj.doc.price_list_currency, obj.doc.plc_conversion_rate)
d.adj_rate = 0
- d.ref_rate = flt(ref_rate)
- d.basic_rate = flt(ref_rate) * flt(obj.doc.conversion_rate)
- d.base_ref_rate = flt(ref_rate) * flt(obj.doc.conversion_rate)
- d.export_rate = flt(ref_rate)
+ d.ref_rate = flt(base_ref_rate)/flt(obj.doc.conversion_rate)
+ d.basic_rate = flt(base_ref_rate)
+ d.base_ref_rate = flt(base_ref_rate)
+ d.export_rate = flt(base_ref_rate)/flt(obj.doc.conversion_rate)
+
# Load Default Taxes
# ====================
@@ -268,9 +267,12 @@
msgprint('Message: Please enter default currency in Company Master')
raise Exception
if (obj.doc.currency == default_currency and flt(obj.doc.conversion_rate) != 1.00) or not obj.doc.conversion_rate or (obj.doc.currency != default_currency and flt(obj.doc.conversion_rate) == 1.00):
- msgprint("Please Enter Appropriate Conversion Rate.")
- raise Exception
+ msgprint("Please Enter Appropriate Conversion Rate for Customer's Currency to Base Currency (%s --> %s)" % (obj.doc.currency, default_currency), raise_exception = 1)
+ if (obj.doc.price_list_currency == default_currency and flt(obj.doc.plc_conversion_rate) != 1.00) or not obj.doc.plc_conversion_rate or (obj.doc.price_list_currency != default_currency and flt(obj.doc.plc_conversion_rate) == 1.00):
+ msgprint("Please Enter Appropriate Conversion Rate for Price List Currency to Base Currency ( (%s --> %s)" % (obj.doc.price_list_currency, default_currency), raise_exception = 1)
+
+
# Get Tax rate if account type is TAX
# =========================================================================
diff --git a/erpnext/selling/doctype/sales_order/sales_order.js b/erpnext/selling/doctype/sales_order/sales_order.js
index e684bed..949abcd 100644
--- a/erpnext/selling/doctype/sales_order/sales_order.js
+++ b/erpnext/selling/doctype/sales_order/sales_order.js
@@ -16,6 +16,7 @@
cur_frm.cscript.onload = function(doc, cdt, cdn) {
if(!doc.status) set_multiple(cdt,cdn,{status:'Draft'});
if(!doc.transaction_date) set_multiple(cdt,cdn,{transaction_date:get_today()});
+ if(!doc.price_list_currency) set_multiple(cdt, cdn, {price_list_currency: doc.currency, plc_conversion_rate: 1});
// load default charges
if(doc.__islocal){
diff --git a/erpnext/selling/doctype/sales_order/sales_order.py b/erpnext/selling/doctype/sales_order/sales_order.py
index ca5af7a..72245eb 100644
--- a/erpnext/selling/doctype/sales_order/sales_order.py
+++ b/erpnext/selling/doctype/sales_order/sales_order.py
@@ -446,7 +446,7 @@
if not d[0]:
msgprint("Message: Please enter Reserved Warehouse for item %s as it is stock item."% d[1])
raise Exception
- bin = get_obj('Warehouse', d[0]).update_bin( 0, flt(update_stock) * flt(d[2]), 0, 0, 0, d[1], self.doc.transaction_date)
+ bin = get_obj('Warehouse', d[0]).update_bin( 0, flt(update_stock) * flt(d[2]), 0, 0, 0, d[1], self.doc.transaction_date,doc_type=self.doc.doctype,doc_name=self.doc.name, is_amended = (self.doc.amended_from and 'Yes' or 'No'))
# Gets Items from packing list
#=================================
diff --git a/erpnext/selling/doctype/sales_order/sales_order.txt b/erpnext/selling/doctype/sales_order/sales_order.txt
index 98833d1..2e6ea99 100644
--- a/erpnext/selling/doctype/sales_order/sales_order.txt
+++ b/erpnext/selling/doctype/sales_order/sales_order.txt
@@ -5,15 +5,26 @@
{
'creation': '2010-08-08 17:09:21',
'docstatus': 0,
- 'modified': '2011-08-09 17:06:09',
+ 'modified': '2011-12-22 19:03:25',
'modified_by': 'Administrator',
'owner': 'Administrator'
},
+ # These values are common for all DocField
+ {
+ 'doctype': 'DocField',
+ 'name': '__common__',
+ 'parent': 'Sales Order',
+ 'parentfield': 'fields',
+ 'parenttype': 'DocType'
+ },
+
# These values are common for all DocType
{
- '_last_update': '1311621379',
+ '_last_update': '1324295218',
+ 'allow_attach': 0,
'colour': 'White:FFF',
+ 'default_print_format': 'Standard',
'doctype': 'DocType',
'document_type': 'Transaction',
'is_transaction_doc': 1,
@@ -27,15 +38,15 @@
'show_in_menu': 0,
'subject': 'From %(customer_name)s on %(transaction_date)s worth %(currency)s %(grand_total_export)s | %(per_delivered)s% delivered | %(per_billed)s% billed',
'tag_fields': 'delivery_status,billing_status',
- 'version': 597
+ 'version': 609
},
- # These values are common for all DocField
+ # These values are common for all DocFormat
{
- 'doctype': 'DocField',
+ 'doctype': 'DocFormat',
'name': '__common__',
'parent': 'Sales Order',
- 'parentfield': 'fields',
+ 'parentfield': 'formats',
'parenttype': 'DocType'
},
@@ -58,7 +69,6 @@
# DocPerm
{
'doctype': 'DocPerm',
- 'idx': 1,
'permlevel': 0,
'role': 'Production Manager'
},
@@ -69,7 +79,6 @@
'cancel': 0,
'create': 0,
'doctype': 'DocPerm',
- 'idx': 2,
'permlevel': 1,
'role': 'Sales Manager',
'submit': 0,
@@ -82,7 +91,6 @@
'cancel': 1,
'create': 1,
'doctype': 'DocPerm',
- 'idx': 3,
'permlevel': 0,
'role': 'Sales Manager',
'submit': 1,
@@ -95,7 +103,6 @@
'cancel': 1,
'create': 1,
'doctype': 'DocPerm',
- 'idx': 4,
'permlevel': 0,
'role': 'Sales User',
'submit': 1,
@@ -108,7 +115,6 @@
'cancel': 0,
'create': 0,
'doctype': 'DocPerm',
- 'idx': 5,
'permlevel': 1,
'role': 'Sales User',
'submit': 0,
@@ -118,7 +124,6 @@
# DocPerm
{
'doctype': 'DocPerm',
- 'idx': 6,
'match': 'customer_name',
'permlevel': 0,
'role': 'Customer'
@@ -127,7 +132,6 @@
# DocPerm
{
'doctype': 'DocPerm',
- 'idx': 7,
'permlevel': 2,
'role': 'Accounts User',
'write': 1
@@ -139,7 +143,6 @@
'cancel': 1,
'create': 1,
'doctype': 'DocPerm',
- 'idx': 8,
'permlevel': 0,
'role': 'Maintenance Manager',
'submit': 1,
@@ -149,7 +152,6 @@
# DocPerm
{
'doctype': 'DocPerm',
- 'idx': 9,
'permlevel': 1,
'role': 'Maintenance Manager'
},
@@ -160,7 +162,6 @@
'cancel': 1,
'create': 1,
'doctype': 'DocPerm',
- 'idx': 10,
'permlevel': 0,
'role': 'Maintenance User',
'submit': 1,
@@ -170,17 +171,33 @@
# DocPerm
{
'doctype': 'DocPerm',
- 'idx': 11,
'permlevel': 1,
'role': 'Maintenance User'
},
+ # DocFormat
+ {
+ 'doctype': 'DocFormat',
+ 'format': 'Sales Order Classic'
+ },
+
+ # DocFormat
+ {
+ 'doctype': 'DocFormat',
+ 'format': 'Sales Order Modern'
+ },
+
+ # DocFormat
+ {
+ 'doctype': 'DocFormat',
+ 'format': 'Sales Order Spartan'
+ },
+
# DocField
{
'colour': 'White:FFF',
'doctype': 'DocField',
'fieldtype': 'Section Break',
- 'idx': 1,
'label': 'Basic Info',
'oldfieldtype': 'Section Break',
'permlevel': 0,
@@ -191,7 +208,6 @@
{
'doctype': 'DocField',
'fieldtype': 'Column Break',
- 'idx': 2,
'in_filter': 0,
'oldfieldtype': 'Column Break',
'permlevel': 0,
@@ -206,7 +222,6 @@
'doctype': 'DocField',
'fieldname': 'naming_series',
'fieldtype': 'Select',
- 'idx': 3,
'label': 'Series',
'no_copy': 1,
'oldfieldname': 'naming_series',
@@ -224,7 +239,6 @@
'doctype': 'DocField',
'fieldname': 'customer',
'fieldtype': 'Link',
- 'idx': 4,
'in_filter': 1,
'label': 'Customer',
'oldfieldname': 'customer',
@@ -243,7 +257,6 @@
'fieldname': 'customer_address',
'fieldtype': 'Link',
'hidden': 0,
- 'idx': 5,
'in_filter': 1,
'label': 'Customer Address',
'options': 'Address',
@@ -256,7 +269,6 @@
'doctype': 'DocField',
'fieldname': 'contact_person',
'fieldtype': 'Link',
- 'idx': 6,
'in_filter': 1,
'label': 'Contact Person',
'options': 'Contact',
@@ -269,7 +281,6 @@
'doctype': 'DocField',
'fieldname': 'customer_name',
'fieldtype': 'Data',
- 'idx': 7,
'label': 'Name',
'permlevel': 1
},
@@ -279,7 +290,6 @@
'doctype': 'DocField',
'fieldname': 'address_display',
'fieldtype': 'Small Text',
- 'idx': 8,
'label': 'Address',
'permlevel': 1
},
@@ -289,7 +299,6 @@
'doctype': 'DocField',
'fieldname': 'contact_display',
'fieldtype': 'Small Text',
- 'idx': 9,
'label': 'Contact',
'permlevel': 1
},
@@ -299,7 +308,6 @@
'doctype': 'DocField',
'fieldname': 'contact_mobile',
'fieldtype': 'Text',
- 'idx': 10,
'label': 'Mobile No',
'permlevel': 1
},
@@ -309,7 +317,6 @@
'doctype': 'DocField',
'fieldname': 'contact_email',
'fieldtype': 'Text',
- 'idx': 11,
'label': 'Contact Email',
'permlevel': 1,
'print_hide': 1
@@ -320,7 +327,6 @@
'doctype': 'DocField',
'fieldname': 'territory',
'fieldtype': 'Link',
- 'idx': 12,
'in_filter': 1,
'label': 'Territory',
'options': 'Territory',
@@ -336,7 +342,6 @@
'doctype': 'DocField',
'fieldname': 'customer_group',
'fieldtype': 'Link',
- 'idx': 13,
'in_filter': 1,
'label': 'Customer Group',
'options': 'Customer Group',
@@ -354,7 +359,6 @@
'fieldname': 'po_no',
'fieldtype': 'Data',
'hidden': 0,
- 'idx': 14,
'label': 'P.O. No',
'oldfieldname': 'po_no',
'oldfieldtype': 'Data',
@@ -370,7 +374,6 @@
'fieldname': 'po_date',
'fieldtype': 'Date',
'hidden': 0,
- 'idx': 15,
'label': 'P.O. Date',
'oldfieldname': 'po_date',
'oldfieldtype': 'Date',
@@ -384,7 +387,6 @@
{
'doctype': 'DocField',
'fieldtype': 'Column Break',
- 'idx': 16,
'oldfieldtype': 'Column Break',
'permlevel': 0,
'width': '50%'
@@ -397,7 +399,6 @@
'doctype': 'DocField',
'fieldname': 'transaction_date',
'fieldtype': 'Date',
- 'idx': 17,
'in_filter': 1,
'label': 'Sales Order Date',
'no_copy': 1,
@@ -416,7 +417,6 @@
'doctype': 'DocField',
'fieldname': 'order_type',
'fieldtype': 'Select',
- 'idx': 18,
'label': 'Order Type',
'oldfieldname': 'order_type',
'oldfieldtype': 'Select',
@@ -431,7 +431,6 @@
'doctype': 'DocField',
'fieldname': 'status',
'fieldtype': 'Select',
- 'idx': 19,
'in_filter': 1,
'label': 'Status',
'no_copy': 1,
@@ -452,7 +451,6 @@
'fieldname': 'delivery_date',
'fieldtype': 'Date',
'hidden': 0,
- 'idx': 20,
'in_filter': 1,
'label': 'Expected Delivery Date',
'oldfieldname': 'delivery_date',
@@ -471,7 +469,6 @@
'doctype': 'DocField',
'fieldname': 'project_name',
'fieldtype': 'Link',
- 'idx': 21,
'in_filter': 1,
'label': 'Project Name',
'oldfieldname': 'project_name',
@@ -490,7 +487,6 @@
'doctype': 'DocField',
'fieldname': 'per_delivered',
'fieldtype': 'Currency',
- 'idx': 22,
'in_filter': 1,
'label': '% Delivered',
'no_copy': 1,
@@ -509,7 +505,6 @@
'doctype': 'DocField',
'fieldname': 'per_billed',
'fieldtype': 'Currency',
- 'idx': 23,
'in_filter': 1,
'label': '% Amount Billed',
'no_copy': 1,
@@ -526,7 +521,6 @@
'fieldname': 'amended_from',
'fieldtype': 'Data',
'hidden': 1,
- 'idx': 24,
'label': 'Amended From',
'no_copy': 1,
'oldfieldname': 'amended_from',
@@ -544,7 +538,6 @@
'fieldname': 'amendment_date',
'fieldtype': 'Date',
'hidden': 1,
- 'idx': 25,
'label': 'Amendment Date',
'no_copy': 1,
'oldfieldname': 'amendment_date',
@@ -560,7 +553,6 @@
'fieldname': 'shipping_address_name',
'fieldtype': 'Data',
'hidden': 1,
- 'idx': 26,
'in_filter': 1,
'label': 'Shipping Address Name',
'options': 'Address',
@@ -573,7 +565,6 @@
'doctype': 'DocField',
'fieldname': 'shipping_address',
'fieldtype': 'Small Text',
- 'idx': 27,
'in_filter': 0,
'label': 'Shipping Address',
'permlevel': 1,
@@ -585,7 +576,6 @@
'colour': 'White:FFF',
'doctype': 'DocField',
'fieldtype': 'Section Break',
- 'idx': 28,
'label': 'Items',
'oldfieldtype': 'Section Break',
'permlevel': 0
@@ -594,72 +584,10 @@
# DocField
{
'colour': 'White:FFF',
- 'description': 'Quotation no against which this Sales Order is made ',
- 'doctype': 'DocField',
- 'fieldname': 'quotation_no',
- 'fieldtype': 'Link',
- 'idx': 29,
- 'in_filter': 1,
- 'label': 'Quotation No',
- 'no_copy': 0,
- 'oldfieldname': 'quotation_no',
- 'oldfieldtype': 'Link',
- 'options': 'Quotation',
- 'permlevel': 0,
- 'print_hide': 1,
- 'search_index': 1,
- 'trigger': 'Client',
- 'width': '150px'
- },
-
- # DocField
- {
- 'doctype': 'DocField',
- 'fieldname': 'vehicle_detail',
- 'fieldtype': 'Small Text',
- 'idx': 30,
- 'label': 'Vehicle Detail',
- 'permlevel': 0
- },
-
- # DocField
- {
- 'colour': 'White:FFF',
- 'doctype': 'DocField',
- 'fieldname': 'quotation_date',
- 'fieldtype': 'Date',
- 'hidden': 1,
- 'idx': 31,
- 'label': 'Quotation Date',
- 'no_copy': 0,
- 'oldfieldname': 'quotation_date',
- 'oldfieldtype': 'Date',
- 'permlevel': 1,
- 'print_hide': 1,
- 'reqd': 0,
- 'width': '100px'
- },
-
- # DocField
- {
- 'doctype': 'DocField',
- 'fieldtype': 'Button',
- 'idx': 32,
- 'label': 'Pull Quotation Details',
- 'oldfieldtype': 'Button',
- 'options': 'pull_quotation_details',
- 'permlevel': 0,
- 'print_hide': 1
- },
-
- # DocField
- {
- 'colour': 'White:FFF',
'description': 'Select the price list as entered in "Price List" master. This will pull the reference rates of items against this price list as specified in "Item" master.',
'doctype': 'DocField',
'fieldname': 'price_list_name',
'fieldtype': 'Select',
- 'idx': 33,
'label': 'Price List',
'oldfieldname': 'price_list_name',
'oldfieldtype': 'Select',
@@ -673,9 +601,34 @@
# DocField
{
+ 'description': 'Select the currency in which price list is maintained',
+ 'doctype': 'DocField',
+ 'fieldname': 'price_list_currency',
+ 'fieldtype': 'Select',
+ 'label': 'Price List Currency',
+ 'options': 'link:Currency',
+ 'permlevel': 0,
+ 'print_hide': 1,
+ 'reqd': 1
+ },
+
+ # DocField
+ {
+ 'colour': 'White:FFF',
+ 'description': 'Rate at which Price list currency is converted to your currency',
+ 'doctype': 'DocField',
+ 'fieldname': 'plc_conversion_rate',
+ 'fieldtype': 'Currency',
+ 'label': 'Price List Currency Conversion Rate',
+ 'permlevel': 0,
+ 'print_hide': 1,
+ 'reqd': 1
+ },
+
+ # DocField
+ {
'doctype': 'DocField',
'fieldtype': 'Column Break',
- 'idx': 34,
'permlevel': 0,
'width': '50%'
},
@@ -687,8 +640,7 @@
'doctype': 'DocField',
'fieldname': 'currency',
'fieldtype': 'Select',
- 'idx': 35,
- 'label': 'Currency',
+ 'label': "Customer's Currency",
'oldfieldname': 'currency',
'oldfieldtype': 'Select',
'options': 'link:Currency',
@@ -706,7 +658,6 @@
'doctype': 'DocField',
'fieldname': 'conversion_rate',
'fieldtype': 'Currency',
- 'idx': 36,
'label': 'Conversion Rate',
'oldfieldname': 'conversion_rate',
'oldfieldtype': 'Currency',
@@ -719,9 +670,56 @@
# DocField
{
+ 'colour': 'White:FFF',
+ 'description': 'Quotation no against which this Sales Order is made ',
+ 'doctype': 'DocField',
+ 'fieldname': 'quotation_no',
+ 'fieldtype': 'Link',
+ 'in_filter': 1,
+ 'label': 'Quotation No',
+ 'no_copy': 0,
+ 'oldfieldname': 'quotation_no',
+ 'oldfieldtype': 'Link',
+ 'options': 'Quotation',
+ 'permlevel': 0,
+ 'print_hide': 1,
+ 'search_index': 1,
+ 'trigger': 'Client',
+ 'width': '150px'
+ },
+
+ # DocField
+ {
+ 'colour': 'White:FFF',
+ 'doctype': 'DocField',
+ 'fieldname': 'quotation_date',
+ 'fieldtype': 'Date',
+ 'hidden': 1,
+ 'label': 'Quotation Date',
+ 'no_copy': 0,
+ 'oldfieldname': 'quotation_date',
+ 'oldfieldtype': 'Date',
+ 'permlevel': 1,
+ 'print_hide': 1,
+ 'reqd': 0,
+ 'width': '100px'
+ },
+
+ # DocField
+ {
+ 'doctype': 'DocField',
+ 'fieldtype': 'Button',
+ 'label': 'Pull Quotation Details',
+ 'oldfieldtype': 'Button',
+ 'options': 'pull_quotation_details',
+ 'permlevel': 0,
+ 'print_hide': 1
+ },
+
+ # DocField
+ {
'doctype': 'DocField',
'fieldtype': 'Section Break',
- 'idx': 37,
'permlevel': 0
},
@@ -732,7 +730,6 @@
'doctype': 'DocField',
'fieldname': 'sales_order_details',
'fieldtype': 'Table',
- 'idx': 38,
'label': 'Sales Order Details',
'oldfieldname': 'sales_order_details',
'oldfieldtype': 'Table',
@@ -746,7 +743,6 @@
{
'doctype': 'DocField',
'fieldtype': 'Button',
- 'idx': 39,
'label': 'Clear Table',
'oldfieldtype': 'Button',
'options': 'clear_sales_order_details',
@@ -758,7 +754,6 @@
{
'doctype': 'DocField',
'fieldtype': 'Button',
- 'idx': 40,
'label': 'Re-Calculate Values',
'oldfieldtype': 'Button',
'permlevel': 0,
@@ -772,7 +767,6 @@
'doctype': 'DocField',
'fieldname': 'net_total',
'fieldtype': 'Currency',
- 'idx': 41,
'label': 'Net Total*',
'oldfieldname': 'net_total',
'oldfieldtype': 'Currency',
@@ -787,7 +781,6 @@
'colour': 'White:FFF',
'doctype': 'DocField',
'fieldtype': 'HTML',
- 'idx': 42,
'label': 'Note1',
'oldfieldtype': 'HTML',
'options': '<b>NOTE :</b> * In Base Currency',
@@ -800,7 +793,6 @@
'colour': 'White:FFF',
'doctype': 'DocField',
'fieldtype': 'Section Break',
- 'idx': 43,
'label': 'Taxes',
'oldfieldtype': 'Section Break',
'permlevel': 0,
@@ -812,7 +804,6 @@
'doctype': 'DocField',
'fieldname': 'charge',
'fieldtype': 'Link',
- 'idx': 44,
'label': 'Select Charges Master',
'oldfieldname': 'charge',
'oldfieldtype': 'Link',
@@ -825,7 +816,6 @@
{
'doctype': 'DocField',
'fieldtype': 'Button',
- 'idx': 45,
'label': 'Get Charges',
'oldfieldtype': 'Button',
'permlevel': 0,
@@ -837,7 +827,6 @@
'doctype': 'DocField',
'fieldname': 'other_charges',
'fieldtype': 'Table',
- 'idx': 46,
'label': 'Other Charges',
'oldfieldname': 'other_charges',
'oldfieldtype': 'Table',
@@ -849,7 +838,6 @@
{
'doctype': 'DocField',
'fieldtype': 'Button',
- 'idx': 47,
'label': 'Calculate Charges',
'oldfieldtype': 'Button',
'permlevel': 0,
@@ -862,7 +850,6 @@
'doctype': 'DocField',
'fieldname': 'other_charges_total',
'fieldtype': 'Currency',
- 'idx': 48,
'label': 'Charges Total*',
'oldfieldname': 'other_charges_total',
'oldfieldtype': 'Currency',
@@ -876,7 +863,6 @@
'doctype': 'DocField',
'fieldname': 'grand_total',
'fieldtype': 'Currency',
- 'idx': 49,
'label': 'Grand Total*',
'oldfieldname': 'grand_total',
'oldfieldtype': 'Currency',
@@ -890,7 +876,6 @@
{
'doctype': 'DocField',
'fieldtype': 'HTML',
- 'idx': 50,
'label': 'OT Notes',
'oldfieldtype': 'HTML',
'options': '<b>NOTE :</b> * In Base Currency',
@@ -902,7 +887,6 @@
{
'doctype': 'DocField',
'fieldtype': 'HTML',
- 'idx': 51,
'label': 'Other Charges Calculation',
'oldfieldtype': 'HTML',
'permlevel': 0,
@@ -914,7 +898,6 @@
'colour': 'White:FFF',
'doctype': 'DocField',
'fieldtype': 'Section Break',
- 'idx': 52,
'label': 'Totals',
'oldfieldtype': 'Section Break',
'permlevel': 0,
@@ -926,7 +909,6 @@
'doctype': 'DocField',
'fieldname': 'rounded_total',
'fieldtype': 'Currency',
- 'idx': 53,
'label': 'Rounded Total',
'oldfieldname': 'rounded_total',
'oldfieldtype': 'Currency',
@@ -942,7 +924,6 @@
'doctype': 'DocField',
'fieldname': 'in_words',
'fieldtype': 'Data',
- 'idx': 54,
'label': 'In Words',
'oldfieldname': 'in_words',
'oldfieldtype': 'Data',
@@ -955,7 +936,6 @@
{
'doctype': 'DocField',
'fieldtype': 'Column Break',
- 'idx': 55,
'oldfieldtype': 'Column Break',
'permlevel': 0,
'print_hide': 1,
@@ -967,7 +947,6 @@
'doctype': 'DocField',
'fieldname': 'grand_total_export',
'fieldtype': 'Currency',
- 'idx': 56,
'label': 'Grand Total (Export)',
'oldfieldname': 'grand_total_export',
'oldfieldtype': 'Currency',
@@ -982,7 +961,6 @@
'doctype': 'DocField',
'fieldname': 'rounded_total_export',
'fieldtype': 'Currency',
- 'idx': 57,
'label': 'Rounded Total (Export)',
'oldfieldname': 'rounded_total_export',
'oldfieldtype': 'Currency',
@@ -998,7 +976,6 @@
'doctype': 'DocField',
'fieldname': 'in_words_export',
'fieldtype': 'Data',
- 'idx': 58,
'label': 'In Words (Export)',
'oldfieldname': 'in_words_export',
'oldfieldtype': 'Data',
@@ -1012,7 +989,6 @@
'colour': 'White:FFF',
'doctype': 'DocField',
'fieldtype': 'Section Break',
- 'idx': 59,
'label': 'Terms',
'oldfieldtype': 'Section Break',
'permlevel': 0,
@@ -1024,7 +1000,6 @@
'doctype': 'DocField',
'fieldname': 'tc_name',
'fieldtype': 'Link',
- 'idx': 60,
'label': 'Select Terms',
'oldfieldname': 'tc_name',
'oldfieldtype': 'Link',
@@ -1038,7 +1013,6 @@
{
'doctype': 'DocField',
'fieldtype': 'Button',
- 'idx': 61,
'label': 'Get Terms',
'oldfieldtype': 'Button',
'options': 'get_tc_details',
@@ -1050,7 +1024,6 @@
{
'doctype': 'DocField',
'fieldtype': 'HTML',
- 'idx': 62,
'label': 'Terms HTML',
'oldfieldtype': 'HTML',
'options': 'You can add Terms and Notes that will be printed in the Transaction',
@@ -1063,7 +1036,6 @@
'doctype': 'DocField',
'fieldname': 'terms',
'fieldtype': 'Text Editor',
- 'idx': 63,
'label': 'Term Details',
'oldfieldname': 'terms',
'oldfieldtype': 'Text Editor',
@@ -1077,7 +1049,6 @@
'description': 'Filling in additional information about the Sales Order will help you analyze your data better.',
'doctype': 'DocField',
'fieldtype': 'Section Break',
- 'idx': 64,
'label': 'More Info',
'oldfieldtype': 'Section Break',
'permlevel': 0,
@@ -1088,7 +1059,6 @@
{
'doctype': 'DocField',
'fieldtype': 'Column Break',
- 'idx': 65,
'oldfieldtype': 'Column Break',
'permlevel': 0,
'print_hide': 1,
@@ -1101,7 +1071,6 @@
'doctype': 'DocField',
'fieldname': 'letter_head',
'fieldtype': 'Select',
- 'idx': 66,
'label': 'Letter Head',
'oldfieldname': 'letter_head',
'oldfieldtype': 'Select',
@@ -1117,7 +1086,6 @@
'doctype': 'DocField',
'fieldname': 'company',
'fieldtype': 'Link',
- 'idx': 67,
'in_filter': 1,
'label': 'Company',
'oldfieldname': 'company',
@@ -1136,7 +1104,6 @@
'doctype': 'DocField',
'fieldname': 'fiscal_year',
'fieldtype': 'Select',
- 'idx': 68,
'in_filter': 1,
'label': 'Fiscal Year',
'oldfieldname': 'fiscal_year',
@@ -1156,7 +1123,6 @@
'doctype': 'DocField',
'fieldname': 'select_print_heading',
'fieldtype': 'Link',
- 'idx': 69,
'label': 'Select Print Heading',
'no_copy': 1,
'oldfieldname': 'select_print_heading',
@@ -1171,7 +1137,6 @@
{
'doctype': 'DocField',
'fieldtype': 'Column Break',
- 'idx': 70,
'oldfieldtype': 'Column Break',
'permlevel': 0,
'print_hide': 1,
@@ -1184,7 +1149,6 @@
'doctype': 'DocField',
'fieldname': 'source',
'fieldtype': 'Select',
- 'idx': 71,
'label': 'Source',
'oldfieldname': 'source',
'oldfieldtype': 'Select',
@@ -1200,7 +1164,6 @@
'doctype': 'DocField',
'fieldname': 'campaign',
'fieldtype': 'Link',
- 'idx': 72,
'label': 'Campaign',
'oldfieldname': 'campaign',
'oldfieldtype': 'Link',
@@ -1215,7 +1178,6 @@
'doctype': 'DocField',
'fieldname': 'note',
'fieldtype': 'Text',
- 'idx': 73,
'label': 'Note',
'oldfieldname': 'note',
'oldfieldtype': 'Text',
@@ -1230,7 +1192,6 @@
'doctype': 'DocField',
'fieldname': 'cancel_reason',
'fieldtype': 'Data',
- 'idx': 74,
'label': 'Cancel Reason',
'no_column': 0,
'no_copy': 1,
@@ -1246,7 +1207,6 @@
'fieldname': 'delivery_status',
'fieldtype': 'Select',
'hidden': 1,
- 'idx': 75,
'label': 'Delivery Status',
'no_column': 0,
'no_copy': 1,
@@ -1261,7 +1221,6 @@
'fieldname': 'billing_status',
'fieldtype': 'Select',
'hidden': 1,
- 'idx': 76,
'label': 'Billing Status',
'no_column': 0,
'no_copy': 1,
@@ -1277,7 +1236,6 @@
'doctype': 'DocField',
'fieldtype': 'Section Break',
'hidden': 0,
- 'idx': 77,
'label': 'Packing List',
'oldfieldtype': 'Section Break',
'permlevel': 0,
@@ -1290,7 +1248,6 @@
'doctype': 'DocField',
'fieldname': 'packing_details',
'fieldtype': 'Table',
- 'idx': 78,
'label': 'Packing Details',
'oldfieldname': 'packing_details',
'oldfieldtype': 'Table',
@@ -1303,7 +1260,6 @@
{
'doctype': 'DocField',
'fieldtype': 'Section Break',
- 'idx': 79,
'label': 'Sales Team',
'oldfieldtype': 'Section Break',
'permlevel': 0,
@@ -1317,7 +1273,6 @@
'doctype': 'DocField',
'fieldname': 'sales_partner',
'fieldtype': 'Link',
- 'idx': 80,
'in_filter': 1,
'label': 'Sales Partner',
'oldfieldname': 'sales_partner',
@@ -1335,7 +1290,6 @@
'doctype': 'DocField',
'fieldname': 'commission_rate',
'fieldtype': 'Currency',
- 'idx': 81,
'label': 'Commission Rate',
'oldfieldname': 'commission_rate',
'oldfieldtype': 'Currency',
@@ -1350,7 +1304,6 @@
'doctype': 'DocField',
'fieldname': 'total_commission',
'fieldtype': 'Currency',
- 'idx': 82,
'label': 'Total Commission',
'oldfieldname': 'total_commission',
'oldfieldtype': 'Currency',
@@ -1364,7 +1317,6 @@
'doctype': 'DocField',
'fieldname': 'sales_team',
'fieldtype': 'Table',
- 'idx': 83,
'label': 'Sales Team1',
'oldfieldname': 'sales_team',
'oldfieldtype': 'Table',
@@ -1378,7 +1330,6 @@
'allow_on_submit': 1,
'doctype': 'DocField',
'fieldtype': 'Button',
- 'idx': 84,
'label': 'Repair Sales Order',
'oldfieldtype': 'Button',
'options': 'repair_sales_order',
diff --git a/erpnext/selling/page/sales_browser/sales_browser.js b/erpnext/selling/page/sales_browser/sales_browser.js
index a24c942..c0c4542 100644
--- a/erpnext/selling/page/sales_browser/sales_browser.js
+++ b/erpnext/selling/page/sales_browser/sales_browser.js
@@ -139,7 +139,7 @@
var has_children = true;
if(cl[i].is_group=='No') {
- var imgsrc = 'images/icons/page.gif';
+ var imgsrc = 'lib/images/icons/page.gif';
has_children = false;
}
var t = me.tree.addNode(n, cl[i].name, imgsrc,me.tree.std_onclick, has_children ? me.tree.std_onexp : null);
@@ -219,7 +219,7 @@
var has_children = true;
if(cl[i].is_group=='No') {
- var imgsrc = 'images/icons/page.gif';
+ var imgsrc = 'lib/images/icons/page.gif';
has_children = false;
}
me.tree_area.innerHTML = '';
@@ -418,4 +418,4 @@
else if(this.cls_obj.sel == 'Sales Person')
return {'node_title':nt,'sales_person_name':nm,'parent_sales_person':pnm,'is_group':grp,'old_parent':old_prt}
-}
\ No newline at end of file
+}
diff --git a/erpnext/setup/doctype/company/company.txt b/erpnext/setup/doctype/company/company.txt
index 15ba781..11ad19c 100644
--- a/erpnext/setup/doctype/company/company.txt
+++ b/erpnext/setup/doctype/company/company.txt
@@ -5,14 +5,14 @@
{
'creation': '2010-08-08 17:08:55',
'docstatus': 0,
- 'modified': '2011-07-01 17:43:29',
+ 'modified': '2011-12-14 15:12:28',
'modified_by': 'Administrator',
'owner': 'Administrator'
},
# These values are common for all DocType
{
- '_last_update': '1309506817',
+ '_last_update': '1323855292',
'allow_trash': 1,
'autoname': 'field:company_name',
'colour': 'White:FFF',
@@ -23,7 +23,7 @@
'section_style': 'Tabbed',
'server_code_error': ' ',
'show_in_menu': 0,
- 'version': 93
+ 'version': 96
},
# These values are common for all DocField
@@ -37,7 +37,6 @@
# These values are common for all DocPerm
{
- 'cancel': 0,
'doctype': 'DocPerm',
'name': '__common__',
'parent': 'Company',
@@ -55,9 +54,9 @@
# DocPerm
{
'amend': 0,
+ 'cancel': 1,
'create': 1,
'doctype': 'DocPerm',
- 'idx': 1,
'permlevel': 0,
'role': 'System Manager',
'submit': 0,
@@ -67,9 +66,9 @@
# DocPerm
{
'amend': 0,
+ 'cancel': 1,
'create': 1,
'doctype': 'DocPerm',
- 'idx': 2,
'permlevel': 0,
'role': 'System Manager',
'submit': 0,
@@ -78,8 +77,8 @@
# DocPerm
{
+ 'cancel': 0,
'doctype': 'DocPerm',
- 'idx': 3,
'permlevel': 1,
'role': 'All'
},
@@ -89,7 +88,6 @@
'description': 'Please Enter Company Name and Abbr and save the document. Once saved Accounting Settings will be populated automatically',
'doctype': 'DocField',
'fieldtype': 'Section Break',
- 'idx': 1,
'label': 'Details',
'oldfieldtype': 'Section Break',
'permlevel': 0
@@ -101,7 +99,6 @@
'doctype': 'DocField',
'fieldname': 'company_name',
'fieldtype': 'Data',
- 'idx': 2,
'label': 'Company',
'no_copy': 0,
'oldfieldname': 'company_name',
@@ -117,7 +114,6 @@
'doctype': 'DocField',
'fieldname': 'abbr',
'fieldtype': 'Data',
- 'idx': 3,
'label': 'Abbr',
'no_copy': 0,
'oldfieldname': 'abbr',
@@ -128,13 +124,11 @@
# DocField
{
+ 'depends_on': 'eval:!doc.__islocal',
'doctype': 'DocField',
- 'fieldname': 'address',
- 'fieldtype': 'Small Text',
- 'idx': 4,
- 'label': 'Address',
- 'oldfieldname': 'address',
- 'oldfieldtype': 'Small Text',
+ 'fieldtype': 'Section Break',
+ 'label': 'Default Settings',
+ 'oldfieldtype': 'Section Break',
'permlevel': 0
},
@@ -143,7 +137,6 @@
'doctype': 'DocField',
'fieldname': 'default_currency',
'fieldtype': 'Select',
- 'idx': 5,
'label': 'Default Currency',
'options': 'link:Currency',
'permlevel': 0,
@@ -152,110 +145,10 @@
# DocField
{
- 'doctype': 'DocField',
- 'fieldtype': 'Column Break',
- 'idx': 6,
- 'oldfieldtype': 'Column Break',
- 'permlevel': 0,
- 'width': '50%'
- },
-
- # DocField
- {
- 'doctype': 'DocField',
- 'fieldname': 'phone_no',
- 'fieldtype': 'Data',
- 'idx': 7,
- 'label': 'Phone No',
- 'oldfieldname': 'phone_no',
- 'oldfieldtype': 'Data',
- 'options': 'Phone',
- 'permlevel': 0
- },
-
- # DocField
- {
- 'doctype': 'DocField',
- 'fieldname': 'email',
- 'fieldtype': 'Data',
- 'idx': 8,
- 'label': 'Email',
- 'oldfieldname': 'email',
- 'oldfieldtype': 'Data',
- 'options': 'Email',
- 'permlevel': 0
- },
-
- # DocField
- {
- 'doctype': 'DocField',
- 'fieldname': 'fax',
- 'fieldtype': 'Data',
- 'idx': 9,
- 'label': 'Fax',
- 'oldfieldname': 'fax',
- 'oldfieldtype': 'Data',
- 'options': 'Phone',
- 'permlevel': 0
- },
-
- # DocField
- {
- 'doctype': 'DocField',
- 'fieldname': 'website',
- 'fieldtype': 'Data',
- 'idx': 10,
- 'label': 'Website',
- 'oldfieldname': 'website',
- 'oldfieldtype': 'Data',
- 'permlevel': 0
- },
-
- # DocField
- {
- 'colour': 'White:FFF',
- 'description': 'Company registration numbers for your reference. Example: VAT Registration Numbers etc.',
- 'doctype': 'DocField',
- 'fieldtype': 'Section Break',
- 'idx': 11,
- 'label': 'Registration Info',
- 'oldfieldtype': 'Section Break',
- 'permlevel': 0,
- 'width': '50%'
- },
-
- # DocField
- {
- 'colour': 'White:FFF',
- 'description': 'Company registration numbers for your reference. Tax numbers etc.',
- 'doctype': 'DocField',
- 'fieldname': 'registration_details',
- 'fieldtype': 'Code',
- 'idx': 12,
- 'label': 'Registration Details',
- 'oldfieldname': 'registration_details',
- 'oldfieldtype': 'Code',
- 'permlevel': 0
- },
-
- # DocField
- {
- 'depends_on': 'eval:!doc.__islocal',
- 'doctype': 'DocField',
- 'fieldtype': 'Section Break',
- 'idx': 13,
- 'label': 'Accounting Settings',
- 'oldfieldtype': 'Section Break',
- 'permlevel': 0
- },
-
- # DocField
- {
'depends_on': 'eval:!doc.__islocal',
'doctype': 'DocField',
'fieldname': 'default_bank_account',
'fieldtype': 'Link',
- 'idx': 14,
'label': 'Default Bank Account',
'no_copy': 1,
'oldfieldname': 'default_bank_account',
@@ -271,7 +164,6 @@
'doctype': 'DocField',
'fieldname': 'receivables_group',
'fieldtype': 'Link',
- 'idx': 15,
'label': 'Receivables Group',
'no_copy': 1,
'oldfieldname': 'receivables_group',
@@ -287,7 +179,6 @@
'doctype': 'DocField',
'fieldname': 'payables_group',
'fieldtype': 'Link',
- 'idx': 16,
'label': 'Payables Group',
'no_copy': 1,
'oldfieldname': 'payables_group',
@@ -301,7 +192,6 @@
{
'doctype': 'DocField',
'fieldtype': 'Column Break',
- 'idx': 17,
'oldfieldtype': 'Column Break',
'permlevel': 0,
'width': '50%'
@@ -309,12 +199,35 @@
# DocField
{
+ 'depends_on': 'eval:!doc.__islocal',
+ 'doctype': 'DocField',
+ 'fieldname': 'credit_days',
+ 'fieldtype': 'Int',
+ 'label': 'Credit Days',
+ 'oldfieldname': 'credit_days',
+ 'oldfieldtype': 'Int',
+ 'permlevel': 0
+ },
+
+ # DocField
+ {
+ 'depends_on': 'eval:!doc.__islocal',
+ 'doctype': 'DocField',
+ 'fieldname': 'credit_limit',
+ 'fieldtype': 'Currency',
+ 'label': 'Credit Limit',
+ 'oldfieldname': 'credit_limit',
+ 'oldfieldtype': 'Currency',
+ 'permlevel': 0
+ },
+
+ # DocField
+ {
'colour': 'White:FFF',
'depends_on': 'eval:!doc.__islocal',
'doctype': 'DocField',
'fieldname': 'yearly_bgt_flag',
'fieldtype': 'Select',
- 'idx': 18,
'label': 'If Yearly Budget Exceeded',
'oldfieldname': 'yearly_bgt_flag',
'oldfieldtype': 'Select',
@@ -328,7 +241,6 @@
'doctype': 'DocField',
'fieldname': 'monthly_bgt_flag',
'fieldtype': 'Select',
- 'idx': 19,
'label': 'If Monthly Budget Exceeded',
'oldfieldname': 'monthly_bgt_flag',
'oldfieldtype': 'Select',
@@ -338,27 +250,101 @@
# DocField
{
- 'depends_on': 'eval:!doc.__islocal',
'doctype': 'DocField',
- 'fieldname': 'credit_days',
- 'fieldtype': 'Int',
- 'idx': 20,
- 'label': 'Credit Days',
- 'oldfieldname': 'credit_days',
- 'oldfieldtype': 'Int',
+ 'fieldtype': 'Section Break',
+ 'label': 'Company Info',
'permlevel': 0
},
# DocField
{
- 'depends_on': 'eval:!doc.__islocal',
'doctype': 'DocField',
- 'fieldname': 'credit_limit',
- 'fieldtype': 'Currency',
- 'idx': 21,
- 'label': 'Credit Limit',
- 'oldfieldname': 'credit_limit',
- 'oldfieldtype': 'Currency',
+ 'fieldname': 'address',
+ 'fieldtype': 'Small Text',
+ 'label': 'Address',
+ 'oldfieldname': 'address',
+ 'oldfieldtype': 'Small Text',
+ 'permlevel': 0
+ },
+
+ # DocField
+ {
+ 'doctype': 'DocField',
+ 'fieldtype': 'Column Break',
+ 'oldfieldtype': 'Column Break',
+ 'permlevel': 0,
+ 'width': '50%'
+ },
+
+ # DocField
+ {
+ 'doctype': 'DocField',
+ 'fieldname': 'phone_no',
+ 'fieldtype': 'Data',
+ 'label': 'Phone No',
+ 'oldfieldname': 'phone_no',
+ 'oldfieldtype': 'Data',
+ 'options': 'Phone',
+ 'permlevel': 0
+ },
+
+ # DocField
+ {
+ 'doctype': 'DocField',
+ 'fieldname': 'fax',
+ 'fieldtype': 'Data',
+ 'label': 'Fax',
+ 'oldfieldname': 'fax',
+ 'oldfieldtype': 'Data',
+ 'options': 'Phone',
+ 'permlevel': 0
+ },
+
+ # DocField
+ {
+ 'doctype': 'DocField',
+ 'fieldname': 'email',
+ 'fieldtype': 'Data',
+ 'label': 'Email',
+ 'oldfieldname': 'email',
+ 'oldfieldtype': 'Data',
+ 'options': 'Email',
+ 'permlevel': 0
+ },
+
+ # DocField
+ {
+ 'doctype': 'DocField',
+ 'fieldname': 'website',
+ 'fieldtype': 'Data',
+ 'label': 'Website',
+ 'oldfieldname': 'website',
+ 'oldfieldtype': 'Data',
+ 'permlevel': 0
+ },
+
+ # DocField
+ {
+ 'colour': 'White:FFF',
+ 'description': 'Company registration numbers for your reference. Example: VAT Registration Numbers etc.',
+ 'doctype': 'DocField',
+ 'fieldtype': 'Section Break',
+ 'label': 'Registration Info',
+ 'oldfieldtype': 'Section Break',
+ 'permlevel': 0,
+ 'width': '50%'
+ },
+
+ # DocField
+ {
+ 'colour': 'White:FFF',
+ 'description': 'Company registration numbers for your reference. Tax numbers etc.',
+ 'doctype': 'DocField',
+ 'fieldname': 'registration_details',
+ 'fieldtype': 'Code',
+ 'label': 'Registration Details',
+ 'oldfieldname': 'registration_details',
+ 'oldfieldtype': 'Code',
'permlevel': 0
},
@@ -367,7 +353,6 @@
'doctype': 'DocField',
'fieldname': 'trash_reason',
'fieldtype': 'Small Text',
- 'idx': 22,
'label': 'Trash Reason',
'no_copy': 1,
'oldfieldname': 'trash_reason',
diff --git a/erpnext/setup/doctype/customer_group/customer_group.py b/erpnext/setup/doctype/customer_group/customer_group.py
index ae74797..4537876 100644
--- a/erpnext/setup/doctype/customer_group/customer_group.py
+++ b/erpnext/setup/doctype/customer_group/customer_group.py
@@ -39,7 +39,5 @@
def validate(self):
- r = sql("select name from `tabCustomer Group` where name = '%s' and docstatus = 2"%(self.doc.customer_group_name))
- if r:
- msgprint("%s record is trashed. To untrash please go to Setup & click on Trash."%(self.doc.customer_group_name))
- raise Exception
\ No newline at end of file
+ if sql("select name from `tabCustomer Group` where name = %s and docstatus = 2", (self.doc.customer_group_name)):
+ msgprint("%s record is trashed. To untrash please go to Setup & click on Trash."%(self.doc.customer_group_name), raise_exception = 1)
diff --git a/erpnext/setup/doctype/email_digest/email_digest.coffee b/erpnext/setup/doctype/email_digest/email_digest.coffee
deleted file mode 100644
index 1b17d5b..0000000
--- a/erpnext/setup/doctype/email_digest/email_digest.coffee
+++ /dev/null
@@ -1,101 +0,0 @@
-content_items = ['Sales','Expenses','Bank Balance','Activity']
-
-# make a grid with items and columns of checkboxes
-# Parameters:
-# parent
-# label (main heading)
-# items = [] (rows)
-# columns = [] (columns of checks)
-# widths
-# description
-
-class CheckGrid
- constructor: (@args) ->
- $.extend @, args
- @wrapper = $a @parent, 'div', 'check-grid round'
- @render()
-
- render: ->
- $a @wrapper, 'h3', 'check-grid-title', null, @label
-
- if @description
- $a @wrapper, 'div', 'help-box', null, @description
-
- @tab = make_table @wrapper, @items.length + 1, @columns.length, '100%', @widths
- @checks = {}
-
- # render heads
- for i in [0..@columns.length-1]
- $($td(@tab, 0, i))
- .addClass('check-grid-head gradient')
- .html @columns[i]
-
- @render_rows()
-
- render_rows: ->
- # render rows
- for i in [0..@items.length-1]
- $td(@tab, i+1, 0).innerHTML = @items[i]
-
- # render checkboxes for this row
- @checks[@items[i]] = {}
- for c in [1..@columns.length-1]
- check = $a_input $td(@tab, i+1, c), 'checkbox'
-
- # tag keys to checkbox
- check.item = @items[i]
- check.column = @columns[c]
-
- # add in my checks
- @checks[@items[i]][@columns[c]] = check
-
- # get the values of the checkbox in a double dict
- get: =>
- val = {}
- for item in keys @checks
- for column in keys @checks[item]
- check = @checks[item][column]
- val[check.item] or= {}
- val[check.item][check.column] = if check.checked then 1 else 0
- val
-
- # set the values of the grid
- set: (val) =>
- for item in keys @checks
- for column in keys @checks[item]
- if val[item][column]
- @checks[item][column] .checked = val[item][column]
- return
-
-# attach it to onload
-cx = cur_frm.cscript
-cx.onload = (doc, dt, dn) ->
-
- # make the content grid
- cx.content_grid = new CheckGrid
- parent: cur_frm.fields_dict.Body.wrapper
- label: 'Email Settings'
- items: content_items
- columns: ['Item','Daily','Weekly']
- widths: ['60%', '20%', '20%']
- description: 'Select items to be compiled for Email Digest'
-
- # make the email grid
- cx.email_grid = new CheckGrid
- parent: cur_frm.fields_dict.Body.wrapper
- label: 'Send To'
- items: ['test1@erpnext', 'test2@erpnext']
- columns: ['Email','Daily','Weekly']
- widths: ['60%', '20%', '20%']
- description: 'Select who gets daily and weekly mails'
-
- cx.content_grid.set JSON.parse doc.content_config if doc.content_config
- cx.email_grid.set JSON.parse doc.email_config if doc.email_config
-
- return
-
-# update the data before sending
-cx.validate = (doc, dt, dn) ->
- doc.content_config = JSON.stringify cx.content_grid.get()
- doc.email_config = JSON.stringify cx.email_grid.get()
-
\ No newline at end of file
diff --git a/erpnext/setup/doctype/email_digest/email_digest.css b/erpnext/setup/doctype/email_digest/email_digest.css
index f61dacc..0654dec 100644
--- a/erpnext/setup/doctype/email_digest/email_digest.css
+++ b/erpnext/setup/doctype/email_digest/email_digest.css
@@ -1,18 +1,10 @@
-
-div.check-grid {
- margin: 17px;
+table.profile-list {
+ text-align: left;
+ margin: auto;
+ line-height: 250%;
}
-div.check-grid table {
- border-collapse: collapse;
+div.dialog-div {
+ text-align: 'center';
+ width: 100%;
}
-
-div.check-grid table td {
- padding: 3px;
- border: 1px solid #aaa;
-}
-
-td.check-grid-head {
- font-weight: bold;
- text-align: center;
-}
\ No newline at end of file
diff --git a/erpnext/setup/doctype/email_digest/email_digest.js b/erpnext/setup/doctype/email_digest/email_digest.js
index ddb13f4..81b37e4 100644
--- a/erpnext/setup/doctype/email_digest/email_digest.js
+++ b/erpnext/setup/doctype/email_digest/email_digest.js
@@ -1,108 +1,106 @@
-(function() {
- var CheckGrid, content_items, cx;
- var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
- content_items = ['Sales', 'Expenses', 'Bank Balance', 'Activity'];
- CheckGrid = (function() {
- function CheckGrid(args) {
- this.args = args;
- this.set = __bind(this.set, this);
- this.get = __bind(this.get, this);
- $.extend(this, args);
- this.wrapper = $a(this.parent, 'div', 'check-grid round');
- this.render();
- }
- CheckGrid.prototype.render = function() {
- var i, _ref;
- $a(this.wrapper, 'h3', 'check-grid-title', null, this.label);
- if (this.description) {
- $a(this.wrapper, 'div', 'help-box', null, this.description);
- }
- this.tab = make_table(this.wrapper, this.items.length + 1, this.columns.length, '100%', this.widths);
- this.checks = {};
- for (i = 0, _ref = this.columns.length - 1; 0 <= _ref ? i <= _ref : i >= _ref; 0 <= _ref ? i++ : i--) {
- $($td(this.tab, 0, i)).addClass('check-grid-head gradient').html(this.columns[i]);
- }
- return this.render_rows();
- };
- CheckGrid.prototype.render_rows = function() {
- var c, check, i, _ref, _results;
- _results = [];
- for (i = 0, _ref = this.items.length - 1; 0 <= _ref ? i <= _ref : i >= _ref; 0 <= _ref ? i++ : i--) {
- $td(this.tab, i + 1, 0).innerHTML = this.items[i];
- this.checks[this.items[i]] = {};
- _results.push((function() {
- var _ref2, _results2;
- _results2 = [];
- for (c = 1, _ref2 = this.columns.length - 1; 1 <= _ref2 ? c <= _ref2 : c >= _ref2; 1 <= _ref2 ? c++ : c--) {
- check = $a_input($td(this.tab, i + 1, c), 'checkbox');
- check.item = this.items[i];
- check.column = this.columns[c];
- _results2.push(this.checks[this.items[i]][this.columns[c]] = check);
- }
- return _results2;
- }).call(this));
- }
- return _results;
- };
- CheckGrid.prototype.get = function() {
- var check, column, item, val, _i, _j, _len, _len2, _name, _ref, _ref2;
- val = {};
- _ref = keys(this.checks);
- for (_i = 0, _len = _ref.length; _i < _len; _i++) {
- item = _ref[_i];
- _ref2 = keys(this.checks[item]);
- for (_j = 0, _len2 = _ref2.length; _j < _len2; _j++) {
- column = _ref2[_j];
- check = this.checks[item][column];
- val[_name = check.item] || (val[_name] = {});
- val[check.item][check.column] = check.checked ? 1 : 0;
- }
- }
- return val;
- };
- CheckGrid.prototype.set = function(val) {
- var column, item, _i, _j, _len, _len2, _ref, _ref2;
- _ref = keys(this.checks);
- for (_i = 0, _len = _ref.length; _i < _len; _i++) {
- item = _ref[_i];
- _ref2 = keys(this.checks[item]);
- for (_j = 0, _len2 = _ref2.length; _j < _len2; _j++) {
- column = _ref2[_j];
- if (val[item][column]) {
- this.checks[item][column].checked = val[item][column];
- }
- }
- }
- };
- return CheckGrid;
- })();
- cx = cur_frm.cscript;
- cx.onload = function(doc, dt, dn) {
- cx.content_grid = new CheckGrid({
- parent: cur_frm.fields_dict.Body.wrapper,
- label: 'Email Settings',
- items: content_items,
- columns: ['Item', 'Daily', 'Weekly'],
- widths: ['60%', '20%', '20%'],
- description: 'Select items to be compiled for Email Digest'
- });
- cx.email_grid = new CheckGrid({
- parent: cur_frm.fields_dict.Body.wrapper,
- label: 'Send To',
- items: ['test1@erpnext', 'test2@erpnext'],
- columns: ['Email', 'Daily', 'Weekly'],
- widths: ['60%', '20%', '20%'],
- description: 'Select who gets daily and weekly mails'
- });
- if (doc.content_config) {
- cx.content_grid.set(JSON.parse(doc.content_config));
- }
- if (doc.email_config) {
- cx.email_grid.set(JSON.parse(doc.email_config));
- }
- };
- cx.validate = function(doc, dt, dn) {
- doc.content_config = JSON.stringify(cx.content_grid.get());
- return doc.email_config = JSON.stringify(cx.email_grid.get());
- };
-}).call(this);
+cur_frm.cscript.refresh = function(doc, dt, dn) {
+ doc = locals[dt][dn];
+ var save_msg = "You must <b>Save</b> the form before proceeding";
+ var err_msg = "There was an error. One probable reason could be that you haven't saved the form. Please contact support@erpnext.com if the problem persists."
+
+ cur_frm.add_custom_button('View Now', function() {
+ doc = locals[dt][dn];
+ if(doc.__unsaved != 1) {
+ $c_obj(make_doclist(dt, dn), 'get', '', function(r, rt) {
+ if(r.exc) {
+ msgprint(err_msg);
+ console.log(r.exc);
+ } else {
+ //console.log(arguments);
+ var d = new wn.widgets.Dialog({
+ title: 'Email Digest: ' + dn,
+ width: 800
+ });
+
+ $a(d.body, 'div', '', '', r['message'][1]);
+
+ d.show();
+ }
+ });
+ } else {
+ msgprint(save_msg);
+ }
+ }, 1);
+ cur_frm.add_custom_button('Send Now', function() {
+ doc = locals[dt][dn];
+ if(doc.__unsaved != 1) {
+ $c_obj(make_doclist(dt, dn), 'send', '', function(r, rt) {
+ if(r.exc) {
+ msgprint(err_msg);
+ console.log(r.exc);
+ } else {
+ //console.log(arguments);
+ msgprint('Message Sent');
+ }
+ });
+ } else {
+ msgprint(save_msg);
+ }
+ }, 1);
+}
+
+cur_frm.cscript['Add/Remove Recipients'] = function(doc, dt, dn) {
+ // Get profile list
+ $c_obj(make_doclist(dt, dn), 'get_profiles', '', function(r, rt) {
+ if(r.exc) {
+ msgprint(r.exc);
+ } else {
+ // Open a dialog and display checkboxes against email addresses
+ doc = locals[dt][dn];
+ var d = new wn.widgets.Dialog({
+ title: 'Add/Remove Recipients',
+ width: 400
+ });
+ var dialog_div = $a(d.body, 'div', 'dialog-div', '', '');
+ var tab = make_table(dialog_div, r.profile_list.length+2, 2, '', ['15%', '85%']);
+ tab.className = 'profile-list';
+ var add_or_update = 'Add';
+ $.each(r.profile_list, function(i, v) {
+ var check = $a_input($td(tab, i+1, 0), 'checkbox');
+ check.value = v.name;
+ if(v.checked==1) {
+ check.checked = 1;
+ add_or_update = 'Update';
+ }
+ if(v.enabled==0) {
+ v.name = "<span style='color: red'>" + v.name + " (disabled user)</span>"
+ }
+ var profile = $a($td(tab, i+1, 1), 'span', '', '', v.name);
+ //profile.onclick = function() { check.checked = !check.checked; }
+ });
+
+ // Display add recipients button
+ if(r.profile_list.length>15) {
+ $btn($td(tab, 0, 1), add_or_update + ' Recipients', function() {
+ cur_frm.cscript.add_to_rec_list(doc, tab, r.profile_list.length);
+ });
+ }
+ $btn($td(tab, r.profile_list.length+1, 1), add_or_update + ' Recipients', function() {
+ cur_frm.cscript.add_to_rec_list(doc, tab, r.profile_list.length);
+ });
+
+ cur_frm.rec_dialog = d;
+ d.show();
+ }
+ });
+}
+
+cur_frm.cscript.add_to_rec_list = function(doc, tab, length) {
+ // add checked profiles to list of recipients
+ var rec_list = [];
+ for(var i = 1; i <= length; i++) {
+ var input = $($td(tab, i, 0)).find('input');
+ if(input.is(':checked')) {
+ rec_list.push(input.attr('value'));
+ }
+ }
+ doc.recipient_list = rec_list.join('\n');
+ //console.log(doc.recipient_list);
+ cur_frm.rec_dialog.hide();
+ cur_frm.refresh_fields();
+}
diff --git a/erpnext/setup/doctype/email_digest/email_digest.py b/erpnext/setup/doctype/email_digest/email_digest.py
new file mode 100644
index 0000000..73c3a1e
--- /dev/null
+++ b/erpnext/setup/doctype/email_digest/email_digest.py
@@ -0,0 +1,786 @@
+import webnotes
+import webnotes.utils
+
+class DocType:
+ def __init__(self, doc, doclist=[]):
+ self.doc, self.doclist = doc, doclist
+ self.sending = False
+
+
+ def get_profiles(self):
+ """
+ Get a list of profiles
+ """
+ import webnotes
+ profile_list = webnotes.conn.sql("""
+ SELECT name, enabled FROM tabProfile
+ WHERE docstatus=0 AND name NOT IN ('Administrator', 'Guest')
+ ORDER BY enabled DESC, name ASC""", as_dict=1)
+ if self.doc.recipient_list:
+ recipient_list = self.doc.recipient_list.split("\n")
+ else:
+ recipient_list = []
+ for p in profile_list:
+ if p['name'] in recipient_list: p['checked'] = 1
+ else: p['checked'] = 0
+ webnotes.response['profile_list'] = profile_list
+
+
+ def get_standard_data(self):
+ """
+ Executes standard queries
+ """
+ res = {}
+ query_dict = {
+
+ 'invoiced_amount': self.generate_gle_query({
+ 'type': 'invoiced_amount',
+ 'field': 'debit',
+ 'master_type': 'Customer',
+ }),
+
+ 'payables': self.generate_gle_query({
+ 'type': 'payables',
+ 'field': 'credit',
+ 'master_type': 'Supplier',
+ }),
+
+ 'collections': self.generate_gle_query({
+ 'type': 'collections',
+ 'field': 'credit',
+ 'master_type': 'Customer',
+ }),
+
+ 'payments': self.generate_gle_query({
+ 'type': 'payments',
+ 'field': 'debit',
+ 'master_type': 'Supplier',
+ }),
+
+ 'income': self.generate_gle_query({
+ 'type': 'income',
+ 'debit_or_credit': 'Credit'
+ }),
+
+ 'income_year_to_date': self.generate_gle_query({
+ 'type': 'income_year_to_date',
+ 'debit_or_credit': 'Credit'
+ }),
+
+ 'expenses_booked': self.generate_gle_query({
+ 'type': 'expenses_booked',
+ 'debit_or_credit': 'Debit'
+ }),
+
+ 'bank_balance': self.generate_gle_query({
+ 'type': 'bank_balance'
+ }),
+
+ 'new_leads': self.generate_new_type_query({
+ 'type': 'new_leads',
+ 'doctype': 'Lead'
+ }),
+
+ 'new_enquiries': self.generate_new_type_query({
+ 'type': 'new_enquiries',
+ 'doctype': 'Enquiry'
+ }),
+
+ 'new_quotations': self.generate_new_type_query({
+ 'type': 'new_quotations',
+ 'doctype': 'Quotation',
+ 'sum_col': 'grand_total'
+ }),
+
+ 'new_sales_orders': self.generate_new_type_query({
+ 'type': 'new_sales_orders',
+ 'doctype': 'Receivable Voucher',
+ 'sum_col': 'grand_total'
+ }),
+
+ 'new_purchase_orders': self.generate_new_type_query({
+ 'type': 'new_purchase_orders',
+ 'doctype': 'Purchase Order',
+ 'sum_col': 'grand_total'
+ }),
+
+ 'new_transactions': self.generate_new_type_query({
+ 'type': 'new_transactions',
+ 'doctype': 'Feed'
+ }),
+
+ 'stock_below_rl': ""
+ }
+
+ result = {}
+
+ for query in query_dict.keys():
+ if self.doc.fields[query] and query_dict[query]:
+ #webnotes.msgprint(query)
+ res = webnotes.conn.sql(query_dict[query], as_dict=1)
+ if query in ['income', 'income_year_to_date']:
+ for r in res:
+ r['value'] = float(r['credit'] - r['debit'])
+ elif query in ['expenses_booked', 'bank_balance']:
+ for r in res:
+ r['value'] = float(r['debit'] - r['credit'])
+ #webnotes.msgprint(query)
+ #webnotes.msgprint(res)
+ result[query] = (res and len(res)==1) and res[0] or (res and res or None)
+ if result[query] is None:
+ del result[query]
+
+ return result
+
+
+ def generate_gle_query(self, args):
+ """
+ Returns generated query string based 'tabGL Entry' and 'tabAccount'
+ """
+ self.process_args(args)
+
+ query = None
+
+ if args['type'] in ['invoiced_amount', 'payables']:
+ query = """
+ SELECT
+ IFNULL(SUM(IFNULL(gle.%(field)s, 0)), 0) AS '%(field)s',
+ %(common_select)s
+ FROM
+ %(common_from)s
+ WHERE
+ %(common_where)s AND
+ ac.master_type = '%(master_type)s' AND
+ %(start_date_condition)s AND
+ %(end_date_condition)s""" % args
+
+ elif args['type'] in ['collections', 'payments']:
+ args['bc_accounts_regex'] = self.get_bc_accounts_regex()
+ if args['bc_accounts_regex']:
+ query = """
+ SELECT
+ IFNULL(SUM(IFNULL(gle.%(field)s, 0)), 0) AS '%(field)s',
+ %(common_select)s
+ FROM
+ %(common_from)s
+ WHERE
+ %(common_where)s AND
+ ac.master_type = '%(master_type)s' AND
+ gle.against REGEXP '%(bc_accounts_regex)s' AND
+ %(start_date_condition)s AND
+ %(end_date_condition)s""" % args
+
+ elif args['type'] in ['income', 'expenses_booked']:
+ query = """
+ SELECT
+ IFNULL(SUM(IFNULL(gle.debit, 0)), 0) AS 'debit',
+ IFNULL(SUM(IFNULL(gle.credit, 0)), 0) AS 'credit',
+ %(common_select)s
+ FROM
+ %(common_from)s
+ WHERE
+ %(common_where)s AND
+ ac.is_pl_account = 'Yes' AND
+ ac.debit_or_credit = '%(debit_or_credit)s' AND
+ %(start_date_condition)s AND
+ %(end_date_condition)s""" % args
+
+ elif args['type'] == 'income_year_to_date':
+ query = """
+ SELECT
+ IFNULL(SUM(IFNULL(gle.debit, 0)), 0) AS 'debit',
+ IFNULL(SUM(IFNULL(gle.credit, 0)), 0) AS 'credit',
+ %(common_select)s
+ FROM
+ %(common_from)s
+ WHERE
+ %(common_where)s AND
+ ac.is_pl_account = 'Yes' AND
+ ac.debit_or_credit = '%(debit_or_credit)s' AND
+ %(fiscal_start_date_condition)s AND
+ %(end_date_condition)s""" % args
+
+ elif args['type'] == 'bank_balance':
+ query = """
+ SELECT
+ ac.account_name AS 'name',
+ IFNULL(SUM(IFNULL(gle.debit, 0)), 0) AS 'debit',
+ IFNULL(SUM(IFNULL(gle.credit, 0)), 0) AS 'credit',
+ %(common_select)s
+ FROM
+ %(common_from)s
+ WHERE
+ %(common_where)s AND
+ ac.account_type = 'Bank or Cash' AND
+ %(end_date_condition)s
+ GROUP BY
+ ac.account_name""" % args
+
+ return query
+
+
+ def process_args(self, args):
+ """
+ Adds common conditions in dictionary "args"
+ """
+ start_date, end_date = self.get_start_end_dates()
+ fiscal_start_date = webnotes.utils.get_defaults()['year_start_date']
+
+ if 'new' in args['type']:
+ args.update({
+ 'company': self.doc.company,
+ 'start_date': start_date,
+ 'end_date': end_date,
+ 'sum_if_reqd': ''
+ })
+ if args['type'] in ['new_quotations', 'new_sales_orders', 'new_purchase_orders']:
+ args['sum_if_reqd'] = "IFNULL(SUM(IFNULL(%(sum_col)s, 0)), 0) AS '%(sum_col)s'," % args
+
+ if args['type'] == 'new_transactions':
+ args['company_condition'] = ''
+ else:
+ args['company_condition'] = "company = '%(company)s' AND" % args
+
+ else:
+ args.update({
+ 'common_select': "COUNT(*) AS 'count'",
+
+ 'common_from': "`tabGL Entry` gle, `tabAccount` ac",
+
+ 'common_where': """
+ gle.company = '%s' AND
+ gle.account = ac.name AND
+ ac.docstatus < 2 AND
+ IFNULL(gle.is_cancelled, 'No') = 'No'""" % self.doc.company,
+
+ 'start_date_condition': "gle.posting_date >= '%s'" % start_date,
+
+ 'end_date_condition': "gle.posting_date <= '%s'" % end_date,
+
+ 'fiscal_start_date_condition': "gle.posting_date >= '%s'" % fiscal_start_date
+ })
+
+
+ def get_start_end_dates(self):
+ """
+ Returns start and end date depending on the frequency of email digest
+ """
+ from datetime import datetime, date, timedelta
+ today = datetime.now().date()
+ year, month, day = today.year, today.month, today.day
+
+ if self.doc.frequency == 'Daily':
+ if self.sending:
+ start_date = end_date = today - timedelta(days=1)
+ else:
+ start_date = end_date = today
+
+ elif self.doc.frequency == 'Weekly':
+ if self.sending:
+ start_date = today - timedelta(days=today.weekday(), weeks=1)
+ end_date = start_date + timedelta(days=6)
+ else:
+ start_date = today - timedelta(days=today.weekday())
+ end_date = start_date + timedelta(days=6)
+
+ else:
+ import calendar
+
+ if self.sending:
+ if month == 1:
+ year = year - 1
+ prev_month = 12
+ else:
+ prev_month = month - 1
+ start_date = date(year, prev_month, 1)
+ last_day = calendar.monthrange(year, prev_month)[1]
+ end_date = date(year, prev_month, last_day)
+ else:
+ start_date = date(year, month, 1)
+ last_day = calendar.monthrange(year, month)[1]
+ end_date = date(year, month, last_day)
+
+ return start_date, end_date
+
+
+ def generate_new_type_query(self, args):
+ """
+ Returns generated query string for calculating new transactions created
+ """
+ self.process_args(args)
+
+ query = """
+ SELECT
+ %(sum_if_reqd)s
+ COUNT(*) AS 'count'
+ FROM
+ `tab%(doctype)s`
+ WHERE
+ docstatus < 2 AND
+ %(company_condition)s
+ DATE(creation) >= '%(start_date)s' AND
+ DATE(creation) <= '%(end_date)s'""" % args
+
+ return query
+
+
+ def get_bc_accounts_regex(self):
+ """
+ Returns a regular expression of 'Bank or Cash' type account list
+ """
+ bc_account_list = webnotes.conn.sql("""
+ SELECT name
+ FROM `tabAccount`
+ WHERE account_type = 'Bank or Cash'""", as_list=1)
+
+ if bc_account_list:
+ return '(' + '|'.join([ac[0] for ac in bc_account_list]) + ')'
+
+
+ def get(self):
+ """
+ * Execute Query
+ * Prepare Email Body from Print Format
+ """
+ result, email_body = self.execute_queries()
+ #webnotes.msgprint(result)
+ #webnotes.msgprint(email_body)
+ return result, email_body
+
+
+ def execute_queries(self):
+ """
+ * If standard==1, execute get_standard_data
+ * If standard==0, execute python code in custom_code field
+ """
+ result = {}
+ if int(self.doc.use_standard)==1:
+ result = self.get_standard_data()
+ email_body = self.get_standard_body(result)
+ else:
+ result, email_body = self.execute_custom_code(self.doc)
+
+ #webnotes.msgprint(result)
+
+ return result, email_body
+
+
+ def execute_custom_code(self, doc):
+ """
+ Execute custom python code
+ """
+ pass
+
+
+ def send(self):
+ """
+ * Execute get method
+ * Send email to recipients
+ """
+ self.sending = True
+ result, email_body = self.get()
+ recipient_list = self.doc.recipient_list.split("\n")
+
+ # before sending, check if user is disabled or not
+ # do not send if disabled
+ profile_list = webnotes.conn.sql("SELECT name, enabled FROM tabProfile", as_dict=1)
+ for profile in profile_list:
+ if profile['name'] in recipient_list and profile['enabled'] == 0:
+ del recipient_list[recipient_list.index(profile['name'])]
+
+ from webnotes.utils.email_lib import sendmail
+ try:
+ sendmail(
+ recipients=recipient_list,
+ sender='notifications+email_digest@erpnext.com',
+ reply_to='support@erpnext.com',
+ subject=self.doc.frequency + ' Digest',
+ msg=email_body,
+ from_defs=1
+ )
+ except Exception, e:
+ webnotes.msgprint('There was a problem in sending your email. Please contact support@erpnext.com')
+ #webnotes.errprint(webnotes.getTraceback())
+
+
+ def on_update(self):
+ """
+
+ """
+ import webnotes
+ args = {
+ 'db_name': webnotes.conn.get_value('Control Panel', '', 'account_id'),
+ 'event': 'setup.doctype.email_digest.email_digest.send'
+ }
+ from webnotes.utils.scheduler import Scheduler
+ #print "before scheduler"
+ sch = Scheduler()
+ sch.connect()
+
+ if self.doc.enabled == 1:
+ # Create scheduler entry
+ res = sch.conn.sql("""
+ SELECT * FROM Event
+ WHERE
+ db_name = %(db_name)s AND
+ event = %(event)s
+ """, args)
+
+ if not (res and res[0]):
+ args['next_execution'] = self.get_next_execution()
+ sch.conn.begin()
+ sch.conn.sql("""
+ INSERT INTO Event (db_name, event, `interval`, next_execution, recurring)
+ VALUES (%(db_name)s, %(event)s, 86400, %(next_execution)s, 1)
+ """, args)
+ sch.conn.commit()
+
+ else:
+ # delete scheduler entry if no other email digest is enabled
+ res = webnotes.conn.sql("""
+ SELECT * FROM `tabEmail Digest`
+ WHERE enabled=1
+ """)
+ if not (res and res[0]):
+ sch.clear(args['db_name'], args['event'])
+ #print "after on update"
+
+
+ def get_next_sending(self):
+ """
+
+ """
+ # Get TimeZone
+ # Get System TimeZone
+ import time
+ from pytz import timezone
+ import datetime
+ import webnotes.defs
+ cp = webnotes.model.doc.Document('Control Panel','Control Panel')
+ app_tz = timezone(cp.time_zone)
+ server_tz = timezone(getattr(webnotes.defs, 'system_timezone'))
+
+ start_date, end_date = self.get_start_end_dates()
+
+ new_date = end_date + datetime.timedelta(days=1)
+ new_time = datetime.time(hour=6)
+
+ naive_dt = datetime.datetime.combine(new_date, new_time)
+ app_dt = app_tz.localize(naive_dt)
+ server_dt = server_tz.normalize(app_dt.astimezone(server_tz))
+
+ res = {
+ 'app_dt': app_dt.replace(tzinfo=None),
+ 'app_tz': app_tz,
+ 'server_dt': server_dt.replace(tzinfo=None),
+ 'server_tz': server_tz
+ }
+
+ from webnotes.utils import formatdate
+ str_date = formatdate(str(res['app_dt'].date()))
+ str_time = res['app_dt'].time().strftime('%I:%M')
+
+ self.doc.next_send = str_date + " at about " + str_time
+
+ return res
+
+
+ def get_next_execution(self):
+ """
+
+ """
+ from datetime import datetime, timedelta
+ dt_args = self.get_next_sending()
+ server_dt = dt_args['server_dt']
+ now_dt = datetime.now(dt_args['server_tz'])
+ if now_dt.time() <= server_dt.time():
+ next_date = now_dt.date()
+ else:
+ next_date = now_dt.date() + timedelta(days=1)
+
+ next_time = server_dt.time()
+
+ return datetime.combine(next_date, next_time)
+
+
+ def onload(self):
+ """
+
+ """
+ self.get_next_sending()
+
+
+ def get_standard_body(self, result):
+ """
+ Generate email body depending on the result
+ """
+ from webnotes.utils import fmt_money
+ from webnotes.model.doc import Document
+ company = Document('Company', self.doc.company)
+ currency = company.default_currency
+
+ def table(args):
+ if type(args['body']) == type(''):
+ table_body = """\
+ <tbody><tr>
+ <td style='padding: 5px; font-size: 24px; \
+ font-weight: bold; background: #F7F7F5'>""" + \
+ args['body'] + \
+ """\
+ </td>
+ </tr></tbody>"""
+
+ elif type(args['body'] == type([])):
+ body_rows = []
+ for rows in args['body']:
+ for r in rows:
+ body_rows.append("""\
+ <tr>
+ <td style='padding: 5px; font-size: 24px; \
+ font-weight: bold; background: #F7F7F5'>""" \
+ + r + """\
+ </td>
+ </tr>""")
+
+ body_rows.append("<tr><td style='background: #F7F7F5'><br></td></tr>")
+
+ table_body = "<tbody>" + "".join(body_rows) + "</tbody>"
+
+ table_head = """\
+ <thead><tr>
+ <td style='padding: 5px; background: #D8D8D4; font-size: 16px; font-weight: bold'>""" \
+ + args['head'] + """\
+ </td>
+ </tr></thead>"""
+
+ return "<table style='border-collapse: collapse; width: 100%;'>" \
+ + table_head \
+ + table_body \
+ + "</table>"
+
+ currency_amount_str = "<span style='color: grey; font-size: 12px'>%s</span> %s"
+
+ body_dict = {
+
+ 'invoiced_amount': {
+ 'table': 'invoiced_amount' in result and table({
+ 'head': 'Invoiced Amount',
+ 'body': currency_amount_str \
+ % (currency, fmt_money(result['invoiced_amount']['debit']))
+ }),
+ 'idx': 300
+ },
+
+ 'payables': {
+ 'table': 'payables' in result and table({
+ 'head': 'Payables',
+ 'body': currency_amount_str \
+ % (currency, fmt_money(result['payables']['credit']))
+ }),
+ 'idx': 200
+ },
+
+ 'collections': {
+ 'table': 'collections' in result and table({
+ 'head': 'Collections',
+ 'body': currency_amount_str \
+ % (currency, fmt_money(result['collections']['credit']))
+ }),
+ 'idx': 301
+ },
+
+ 'payments': {
+ 'table': 'payments' in result and table({
+ 'head': 'Payments',
+ 'body': currency_amount_str \
+ % (currency, fmt_money(result['payments']['debit']))
+ }),
+ 'idx': 201
+ },
+
+ 'income': {
+ 'table': 'income' in result and table({
+ 'head': 'Income',
+ 'body': currency_amount_str \
+ % (currency, fmt_money(result['income']['value']))
+ }),
+ 'idx': 302
+ },
+
+ 'income_year_to_date': {
+ 'table': 'income_year_to_date' in result and table({
+ 'head': 'Income Year To Date',
+ 'body': currency_amount_str \
+ % (currency, fmt_money(result['income_year_to_date']['value']))
+ }),
+ 'idx': 303
+ },
+
+ 'expenses_booked': {
+ 'table': 'expenses_booked' in result and table({
+ 'head': 'Expenses Booked',
+ 'body': currency_amount_str \
+ % (currency, fmt_money(result['expenses_booked']['value']))
+ }),
+ 'idx': 202
+ },
+
+ 'bank_balance': {
+ 'table': 'bank_balance' in result and result['bank_balance'] and table({
+ 'head': 'Bank Balance',
+ 'body': [
+ [
+ "<span style='font-size: 16px; font-weight: normal'>%s</span>" % bank['name'],
+ currency_amount_str % (currency, fmt_money(bank['value']))
+ ] for bank in result['bank_balance']
+ ]
+ }),
+ 'idx': 400
+ },
+
+ 'new_leads': {
+ 'table': 'new_leads' in result and table({
+ 'head': 'New Leads',
+ 'body': '%s' % result['new_leads']['count']
+ }),
+ 'idx': 100
+ },
+
+ 'new_enquiries': {
+ 'table': 'new_enquiries' in result and table({
+ 'head': 'New Enquiries',
+ 'body': '%s' % result['new_enquiries']['count']
+ }),
+ 'idx': 101
+ },
+
+ 'new_quotations': {
+ 'table': 'new_quotations' in result and table({
+ 'head': 'New Quotations',
+ 'body': '%s' % result['new_quotations']['count']
+ }),
+ 'idx': 102
+ },
+
+ 'new_sales_orders': {
+ 'table': 'new_sales_orders' in result and table({
+ 'head': 'New Sales Orders',
+ 'body': '%s' % result['new_sales_orders']['count']
+ }),
+ 'idx': 103
+ },
+
+ 'new_purchase_orders': {
+ 'table': 'new_purchase_orders' in result and table({
+ 'head': 'New Purchase Orders',
+ 'body': '%s' % result['new_purchase_orders']['count']
+ }),
+ 'idx': 104
+ },
+
+ 'new_transactions': {
+ 'table': 'new_transactions' in result and table({
+ 'head': 'New Transactions',
+ 'body': '%s' % result['new_transactions']['count']
+ }),
+ 'idx': 105
+ }
+
+ #'stock_below_rl':
+ }
+
+ table_list = []
+
+ # Sort these keys depending on idx value
+ bd_keys = sorted(body_dict, key=lambda x: body_dict[x]['idx'])
+
+ for k in bd_keys:
+ if self.doc.fields[k]:
+ if k in result:
+ table_list.append(body_dict[k]['table'])
+ elif k in ['collections', 'payments']:
+ table_list.append(\
+ "<div style='font-size: 16px; color: grey'>[" + \
+ k.capitalize() + \
+ "]<br />Missing: Account of type 'Bank or Cash'\
+ </div>")
+ elif k=='bank_balance':
+ table_list.append(\
+ "<div style='font-size: 16px; color: grey'>[" + \
+ "Bank Balance" + \
+ "]<br />Alert: GL Entry not found for Account of type 'Bank or Cash'\
+ </div>")
+
+
+ i = 0
+ result = []
+ op_len = len(table_list)
+ while(True):
+ if i>=op_len:
+ break
+ elif (op_len - i) == 1:
+ result.append("""\
+ <tr>
+ <td style='width: 50%%; vertical-align: top;'>%s</td>
+ <td></td>
+ </tr>""" % (table_list[i]))
+ else:
+ result.append("""\
+ <tr>
+ <td style='width: 50%%; vertical-align: top;'>%s</td>
+ <td>%s</td>
+ </tr>""" % (table_list[i], table_list[i+1]))
+
+ i = i + 2
+
+ from webnotes.utils import formatdate
+ start_date, end_date = self.get_start_end_dates()
+ digest_daterange = self.doc.frequency=='Daily' \
+ and formatdate(str(start_date)) \
+ or (formatdate(str(start_date)) + " to " + (formatdate(str(end_date))))
+
+ email_body = """
+ <div style='width: 100%%'>
+ <div style='padding: 10px; margin: auto; text-align: center; line-height: 80%%'>
+ <p style='font-weight: bold; font-size: 24px'>%s</p>
+ <p style='font-size: 16px; color: grey'>%s</p>
+ <p style='font-size: 20px; font-weight: bold'>%s</p>
+ </div>
+ <table cellspacing=15 style='width: 100%%'>""" \
+ % ((self.doc.frequency + " Digest"), \
+ digest_daterange, self.doc.company) \
+ + "".join(result) + """\
+ </table><br><p></p>
+ </div>"""
+
+ return email_body
+
+
+def send():
+ """
+
+ """
+ edigest_list = webnotes.conn.sql("""
+ SELECT name FROM `tabEmail Digest`
+ WHERE enabled=1
+ """, as_list=1)
+
+ from webnotes.model.code import get_obj
+ from datetime import datetime, timedelta
+ now = datetime.now()
+ now_date = now.date()
+ now_time = (now + timedelta(hours=2)).time()
+
+ for ed in edigest_list:
+ if ed[0]:
+ ed_obj = get_obj('Email Digest', ed[0])
+ ed_obj.sending = True
+ dt_dict = ed_obj.get_next_sending()
+ send_date = dt_dict['server_dt'].date()
+ send_time = dt_dict['server_dt'].time()
+
+ if (now_date == send_date) and (send_time <= now_time):
+ #webnotes.msgprint('sending ' + ed_obj.doc.name)
+ ed_obj.send()
+ #else:
+ # webnotes.msgprint('not sending ' + ed_obj.doc.name)
diff --git a/erpnext/setup/doctype/email_digest/email_digest.txt b/erpnext/setup/doctype/email_digest/email_digest.txt
index 026caa7..897adad 100644
--- a/erpnext/setup/doctype/email_digest/email_digest.txt
+++ b/erpnext/setup/doctype/email_digest/email_digest.txt
@@ -3,24 +3,25 @@
# These values are common in all dictionaries
{
- 'creation': '2011-07-27 14:23:09',
+ 'creation': '2011-12-14 12:15:09',
'docstatus': 0,
- 'modified': '2011-07-27 17:32:27',
+ 'modified': '2011-12-22 19:01:33',
'modified_by': 'Administrator',
'owner': 'Administrator'
},
# These values are common for all DocType
{
- '_last_update': '1311760331',
+ '_last_update': '1324556758',
+ 'autoname': 'Prompt',
'colour': 'White:FFF',
'doctype': 'DocType',
- 'issingle': 1,
+ 'document_type': 'System',
'module': 'Setup',
'name': '__common__',
'section_style': 'Simple',
'show_in_menu': 0,
- 'version': 4
+ 'version': 81
},
# These values are common for all DocField
@@ -29,23 +30,18 @@
'name': '__common__',
'parent': 'Email Digest',
'parentfield': 'fields',
- 'parenttype': 'DocType',
- 'permlevel': 0
+ 'parenttype': 'DocType'
},
# These values are common for all DocPerm
{
- 'create': 1,
'doctype': 'DocPerm',
- 'idx': 1,
'name': '__common__',
'parent': 'Email Digest',
'parentfield': 'permissions',
'parenttype': 'DocType',
- 'permlevel': 0,
'read': 1,
- 'role': 'Administrator',
- 'write': 1
+ 'role': 'System Manager'
},
# DocType, Email Digest
@@ -56,34 +52,300 @@
# DocPerm
{
- 'doctype': 'DocPerm'
+ 'cancel': 1,
+ 'create': 1,
+ 'doctype': 'DocPerm',
+ 'permlevel': 0,
+ 'write': 1
+ },
+
+ # DocPerm
+ {
+ 'doctype': 'DocPerm',
+ 'permlevel': 1
},
# DocField
{
'doctype': 'DocField',
- 'fieldtype': 'HTML',
- 'idx': 1,
- 'label': 'Body'
+ 'fieldtype': 'Section Break',
+ 'label': 'Settings',
+ 'permlevel': 0
},
# DocField
{
'doctype': 'DocField',
- 'fieldname': 'content_config',
- 'fieldtype': 'Text',
+ 'fieldtype': 'Column Break',
+ 'permlevel': 0
+ },
+
+ # DocField
+ {
+ 'doctype': 'DocField',
+ 'fieldname': 'enabled',
+ 'fieldtype': 'Check',
+ 'label': 'Enabled',
+ 'permlevel': 0
+ },
+
+ # DocField
+ {
+ 'doctype': 'DocField',
+ 'fieldname': 'company',
+ 'fieldtype': 'Select',
+ 'label': 'For Company',
+ 'options': 'link:Company',
+ 'permlevel': 0,
+ 'reqd': 1
+ },
+
+ # DocField
+ {
+ 'allow_on_submit': 0,
+ 'doctype': 'DocField',
+ 'fieldname': 'frequency',
+ 'fieldtype': 'Select',
+ 'label': 'How frequently?',
+ 'options': '\nDaily\nWeekly\nMonthly',
+ 'permlevel': 0,
+ 'reqd': 1
+ },
+
+ # DocField
+ {
+ 'depends_on': 'eval:doc.enabled',
+ 'doctype': 'DocField',
+ 'fieldname': 'next_send',
+ 'fieldtype': 'Data',
+ 'label': 'Next email will be sent on:',
+ 'permlevel': 1
+ },
+
+ # DocField
+ {
+ 'default': '1',
+ 'doctype': 'DocField',
+ 'fieldname': 'use_standard',
+ 'fieldtype': 'Check',
'hidden': 1,
- 'idx': 2,
- 'label': 'Content Config'
+ 'label': 'Use standard?',
+ 'permlevel': 0,
+ 'search_index': 0
},
# DocField
{
'doctype': 'DocField',
- 'fieldname': 'email_config',
+ 'fieldtype': 'Column Break',
+ 'permlevel': 0
+ },
+
+ # DocField
+ {
+ 'doctype': 'DocField',
+ 'fieldtype': 'Button',
+ 'label': 'Add/Remove Recipients',
+ 'permlevel': 0,
+ 'trigger': 'Client'
+ },
+
+ # DocField
+ {
+ 'description': 'Note: Email will not be sent to disabled users',
+ 'doctype': 'DocField',
+ 'fieldname': 'recipient_list',
'fieldtype': 'Text',
+ 'label': 'Recipients',
+ 'permlevel': 1,
+ 'reqd': 1
+ },
+
+ # DocField
+ {
+ 'depends_on': 'eval:doc.use_standard',
+ 'doctype': 'DocField',
+ 'fieldtype': 'Section Break',
+ 'label': 'Select Digest Content',
+ 'permlevel': 0
+ },
+
+ # DocField
+ {
+ 'depends_on': 'eval:doc.use_standard',
+ 'doctype': 'DocField',
+ 'fieldname': 'new_leads',
+ 'fieldtype': 'Check',
+ 'label': 'New Leads',
+ 'permlevel': 0
+ },
+
+ # DocField
+ {
+ 'depends_on': 'eval:doc.use_standard',
+ 'doctype': 'DocField',
+ 'fieldname': 'new_enquiries',
+ 'fieldtype': 'Check',
+ 'label': 'New Enquiries',
+ 'permlevel': 0
+ },
+
+ # DocField
+ {
+ 'depends_on': 'eval:doc.use_standard',
+ 'doctype': 'DocField',
+ 'fieldname': 'new_quotations',
+ 'fieldtype': 'Check',
+ 'label': 'New Quotations',
+ 'permlevel': 0
+ },
+
+ # DocField
+ {
+ 'depends_on': 'eval:doc.use_standard',
+ 'doctype': 'DocField',
+ 'fieldname': 'new_sales_orders',
+ 'fieldtype': 'Check',
+ 'label': 'New Sales Orders',
+ 'permlevel': 0
+ },
+
+ # DocField
+ {
+ 'depends_on': 'eval:doc.use_standard',
+ 'doctype': 'DocField',
+ 'fieldname': 'new_purchase_orders',
+ 'fieldtype': 'Check',
+ 'label': 'New Purchase Orders',
+ 'permlevel': 0
+ },
+
+ # DocField
+ {
+ 'depends_on': 'eval:doc.use_standard',
+ 'doctype': 'DocField',
+ 'fieldname': 'new_transactions',
+ 'fieldtype': 'Check',
+ 'label': 'New Transactions',
+ 'permlevel': 0
+ },
+
+ # DocField
+ {
+ 'depends_on': 'eval:doc.use_standard',
+ 'doctype': 'DocField',
+ 'fieldname': 'payables',
+ 'fieldtype': 'Check',
+ 'label': 'Payables',
+ 'permlevel': 0
+ },
+
+ # DocField
+ {
+ 'depends_on': 'eval:doc.use_standard',
+ 'doctype': 'DocField',
+ 'fieldname': 'payments',
+ 'fieldtype': 'Check',
+ 'label': 'Payments',
+ 'permlevel': 0
+ },
+
+ # DocField
+ {
+ 'depends_on': 'eval:doc.use_standard',
+ 'doctype': 'DocField',
+ 'fieldname': 'expenses_booked',
+ 'fieldtype': 'Check',
+ 'label': 'Expenses Booked',
+ 'permlevel': 0
+ },
+
+ # DocField
+ {
+ 'depends_on': 'eval:doc.use_standard',
+ 'doctype': 'DocField',
+ 'fieldname': 'invoiced_amount',
+ 'fieldtype': 'Check',
+ 'label': 'Invoiced Amount (Receivables)',
+ 'permlevel': 0
+ },
+
+ # DocField
+ {
+ 'depends_on': 'eval:doc.use_standard',
+ 'doctype': 'DocField',
+ 'fieldname': 'collections',
+ 'fieldtype': 'Check',
+ 'label': 'Collections',
+ 'permlevel': 0
+ },
+
+ # DocField
+ {
+ 'depends_on': 'eval:doc.use_standard',
+ 'doctype': 'DocField',
+ 'fieldname': 'income',
+ 'fieldtype': 'Check',
+ 'label': 'Income',
+ 'permlevel': 0
+ },
+
+ # DocField
+ {
+ 'depends_on': 'eval:doc.use_standard',
+ 'doctype': 'DocField',
+ 'fieldname': 'income_year_to_date',
+ 'fieldtype': 'Check',
+ 'label': 'Income Year to Date',
+ 'permlevel': 0
+ },
+
+ # DocField
+ {
+ 'depends_on': 'eval:doc.use_standard',
+ 'doctype': 'DocField',
+ 'fieldname': 'bank_balance',
+ 'fieldtype': 'Check',
+ 'label': 'Bank Balance',
+ 'permlevel': 0
+ },
+
+ # DocField
+ {
+ 'doctype': 'DocField',
+ 'fieldname': 'stock_below_rl',
+ 'fieldtype': 'Check',
'hidden': 1,
- 'idx': 3,
- 'label': 'Email Config'
+ 'label': 'Stock Items below re-order level',
+ 'permlevel': 0
+ },
+
+ # DocField
+ {
+ 'depends_on': 'eval:!doc.use_standard',
+ 'doctype': 'DocField',
+ 'fieldtype': 'Section Break',
+ 'label': 'Enter Custom Code',
+ 'permlevel': 0
+ },
+
+ # DocField
+ {
+ 'depends_on': 'eval:!doc.use_standard',
+ 'doctype': 'DocField',
+ 'fieldname': 'custom_code',
+ 'fieldtype': 'Code',
+ 'label': 'Custom Python Code',
+ 'permlevel': 0
+ },
+
+ # DocField
+ {
+ 'depends_on': 'eval:!doc.use_standard',
+ 'doctype': 'DocField',
+ 'fieldname': 'email_template',
+ 'fieldtype': 'Code',
+ 'label': 'Email Template',
+ 'permlevel': 0
}
]
\ No newline at end of file
diff --git a/erpnext/setup/doctype/features_setup/features_setup.py b/erpnext/setup/doctype/features_setup/features_setup.py
index f12d282..3a549d9 100644
--- a/erpnext/setup/doctype/features_setup/features_setup.py
+++ b/erpnext/setup/doctype/features_setup/features_setup.py
@@ -8,7 +8,6 @@
"""
from webnotes.model import default_fields
from webnotes.utils import set_default
-
for key in self.doc.fields:
if key not in default_fields:
set_default(key, self.doc.fields[key])
diff --git a/erpnext/setup/doctype/features_setup/features_setup.txt b/erpnext/setup/doctype/features_setup/features_setup.txt
index 722d49a..eff542b 100644
--- a/erpnext/setup/doctype/features_setup/features_setup.txt
+++ b/erpnext/setup/doctype/features_setup/features_setup.txt
@@ -5,14 +5,14 @@
{
'creation': '2011-09-07 11:59:05',
'docstatus': 0,
- 'modified': '2011-10-05 10:50:17',
+ 'modified': '2011-12-14 11:05:55',
'modified_by': 'Administrator',
'owner': 'Administrator'
},
# These values are common for all DocType
{
- '_last_update': '1317790484',
+ '_last_update': '1323840127',
'colour': 'White:FFF',
'default_print_format': 'Standard',
'doctype': 'DocType',
@@ -22,7 +22,7 @@
'name_case': 'Title Case',
'section_style': 'Simple',
'show_in_menu': 1,
- 'version': 21
+ 'version': 26
},
# These values are common for all DocField
@@ -179,7 +179,17 @@
'doctype': 'DocField',
'fieldname': 'fs_discounts',
'fieldtype': 'Check',
- 'label': 'Discounts'
+ 'label': 'Sales Discounts'
+ },
+
+ # DocField
+ {
+ 'colour': 'White:FFF',
+ 'description': 'Discount Fields will be available in Purchase Order, Purchase Receipt, Purchase Invoice',
+ 'doctype': 'DocField',
+ 'fieldname': 'fs_purchase_discounts',
+ 'fieldtype': 'Check',
+ 'label': 'Purchase Discounts'
},
# DocField
@@ -215,6 +225,39 @@
{
'doctype': 'DocField',
'fieldtype': 'Section Break',
+ 'label': 'Accounts'
+ },
+
+ # DocField
+ {
+ 'colour': 'White:FFF',
+ 'description': 'Check if you need automatic recurring invoices. After submitting any sales invoice, Recurring section will be visible.',
+ 'doctype': 'DocField',
+ 'fieldname': 'fs_recurring_invoice',
+ 'fieldtype': 'Check',
+ 'label': 'Recurring Invoice'
+ },
+
+ # DocField
+ {
+ 'doctype': 'DocField',
+ 'fieldtype': 'Column Break'
+ },
+
+ # DocField
+ {
+ 'colour': 'White:FFF',
+ 'description': 'To enable <b>Point of Sale</b> features',
+ 'doctype': 'DocField',
+ 'fieldname': 'fs_pos',
+ 'fieldtype': 'Check',
+ 'label': 'Point of Sale'
+ },
+
+ # DocField
+ {
+ 'doctype': 'DocField',
+ 'fieldtype': 'Section Break',
'label': 'Production'
},
@@ -246,16 +289,6 @@
# DocField
{
- 'colour': 'White:FFF',
- 'description': 'To enable <b>Point of Sale</b> features',
- 'doctype': 'DocField',
- 'fieldname': 'fs_pos',
- 'fieldtype': 'Check',
- 'label': 'Point of Sale'
- },
-
- # DocField
- {
'doctype': 'DocField',
'fieldtype': 'Section Break',
'label': 'Miscelleneous'
diff --git a/erpnext/setup/doctype/manage_account/manage_account.py b/erpnext/setup/doctype/manage_account/manage_account.py
index 651794f..5dd2d06 100644
--- a/erpnext/setup/doctype/manage_account/manage_account.py
+++ b/erpnext/setup/doctype/manage_account/manage_account.py
@@ -43,6 +43,7 @@
['company',self.doc.default_company],
['currency',self.doc.default_currency],
['price_list_name',self.doc.default_price_list],
+ ['price_list_currency', self.doc.default_price_list_currency],
['item_group',self.doc.default_item_group],
['customer_group',self.doc.default_customer_group],
['cust_master_name',self.doc.cust_master_name],
diff --git a/erpnext/setup/doctype/manage_account/manage_account.txt b/erpnext/setup/doctype/manage_account/manage_account.txt
index 26b4e63..8a156a0 100644
--- a/erpnext/setup/doctype/manage_account/manage_account.txt
+++ b/erpnext/setup/doctype/manage_account/manage_account.txt
@@ -5,18 +5,20 @@
{
'creation': '2010-08-08 17:09:09',
'docstatus': 0,
- 'modified': '2011-05-19 11:16:11',
+ 'modified': '2011-12-21 13:22:33',
'modified_by': 'Administrator',
'owner': 'Administrator'
},
# These values are common for all DocType
{
- '_last_update': '1308741898',
+
+ '_last_update': '1323855502',
'allow_copy': 1,
'allow_email': 1,
'allow_print': 1,
'colour': 'White:FFF',
+ 'default_print_format': 'Standard',
'doctype': 'DocType',
'hide_toolbar': 0,
'in_create': 1,
@@ -27,7 +29,7 @@
'section_style': 'Tabbed',
'server_code_error': ' ',
'show_in_menu': 1,
- 'version': 514
+ 'version': 515
},
# These values are common for all DocField
@@ -62,7 +64,6 @@
'cancel': 0,
'create': 1,
'doctype': 'DocPerm',
- 'idx': 1,
'permlevel': 0,
'role': 'System Manager',
'submit': 0,
@@ -73,7 +74,6 @@
{
'create': 1,
'doctype': 'DocPerm',
- 'idx': 2,
'permlevel': 0,
'role': 'System Manager',
'write': 1
@@ -82,7 +82,6 @@
# DocPerm
{
'doctype': 'DocPerm',
- 'idx': 3,
'permlevel': 1,
'role': 'System Manager',
'write': 1
@@ -91,7 +90,6 @@
# DocPerm
{
'doctype': 'DocPerm',
- 'idx': 4,
'permlevel': 1,
'role': 'All'
},
@@ -99,7 +97,6 @@
# DocPerm
{
'doctype': 'DocPerm',
- 'idx': 5,
'permlevel': 2,
'role': 'System Manager',
'write': 1
@@ -109,7 +106,6 @@
{
'doctype': 'DocField',
'fieldtype': 'Section Break',
- 'idx': 1,
'label': 'Company'
},
@@ -118,7 +114,6 @@
'doctype': 'DocField',
'fieldname': 'default_company',
'fieldtype': 'Link',
- 'idx': 2,
'label': 'Default Company',
'options': 'Company',
'reqd': 0
@@ -129,7 +124,6 @@
'doctype': 'DocField',
'fieldname': 'current_fiscal_year',
'fieldtype': 'Link',
- 'idx': 3,
'label': 'Current Fiscal Year',
'options': 'Fiscal Year',
'reqd': 1
@@ -140,7 +134,6 @@
'doctype': 'DocField',
'fieldname': 'date_format',
'fieldtype': 'Select',
- 'idx': 4,
'label': 'Date Format',
'options': 'yyyy-mm-dd\ndd-mm-yyyy\ndd/mm/yyyy\nmm/dd/yyyy\nmm-dd-yyyy'
},
@@ -149,7 +142,6 @@
{
'doctype': 'DocField',
'fieldtype': 'Column Break',
- 'idx': 5,
'width': '50%'
},
@@ -159,7 +151,6 @@
'doctype': 'DocField',
'fieldname': 'default_currency',
'fieldtype': 'Select',
- 'idx': 6,
'label': 'Default Currency',
'options': 'link:Currency',
'reqd': 1
@@ -170,7 +161,6 @@
'doctype': 'DocField',
'fieldname': 'default_currency_format',
'fieldtype': 'Select',
- 'idx': 7,
'label': 'Default Currency Format',
'options': 'Lacs\nMillions'
},
@@ -180,7 +170,6 @@
'doctype': 'DocField',
'fieldname': 'default_currency_fraction',
'fieldtype': 'Data',
- 'idx': 8,
'label': 'Default Currency Fraction'
},
@@ -189,7 +178,6 @@
'doctype': 'DocField',
'fieldname': 'sms_sender_name',
'fieldtype': 'Data',
- 'idx': 9,
'label': 'SMS Sender Name'
},
@@ -197,7 +185,6 @@
{
'doctype': 'DocField',
'fieldtype': 'Section Break',
- 'idx': 10,
'label': 'Stock'
},
@@ -205,7 +192,6 @@
{
'doctype': 'DocField',
'fieldtype': 'Column Break',
- 'idx': 11,
'width': '50%'
},
@@ -214,7 +200,6 @@
'doctype': 'DocField',
'fieldname': 'default_item_group',
'fieldtype': 'Link',
- 'idx': 12,
'label': 'Default Item Group',
'options': 'Item Group'
},
@@ -223,7 +208,6 @@
{
'doctype': 'DocField',
'fieldtype': 'HTML',
- 'idx': 13,
'label': 'IGHelp',
'options': '<a href="javascript:cur_frm.cscript.TreePage(\'Item Group\');">To manage Item Groups, click here</a>'
},
@@ -233,7 +217,6 @@
'doctype': 'DocField',
'fieldname': 'default_stock_uom',
'fieldtype': 'Link',
- 'idx': 14,
'label': 'Default Stock UOM',
'options': 'UOM'
},
@@ -243,7 +226,6 @@
'doctype': 'DocField',
'fieldname': 'default_valuation_method',
'fieldtype': 'Select',
- 'idx': 15,
'label': 'Default Valuation Method',
'options': 'FIFO\nMoving Average'
},
@@ -253,7 +235,6 @@
'doctype': 'DocField',
'fieldname': 'default_warehouse_type',
'fieldtype': 'Link',
- 'idx': 16,
'label': 'Default Warehouse Type',
'options': 'Warehouse Type'
},
@@ -261,8 +242,16 @@
# DocField
{
'doctype': 'DocField',
+ 'fieldname': 'auto_indent',
+ 'fieldtype': 'Check',
+ 'label': 'Raise Indent when stock reaches re-order level'
+ },
+
+ # DocField
+ {
+ 'default': '1',
+ 'doctype': 'DocField',
'fieldtype': 'Column Break',
- 'idx': 17,
'width': '50%'
},
@@ -273,7 +262,6 @@
'doctype': 'DocField',
'fieldname': 'tolerance',
'fieldtype': 'Currency',
- 'idx': 18,
'label': 'Allowance Percent'
},
@@ -284,7 +272,6 @@
'doctype': 'DocField',
'fieldname': 'stock_frozen_upto',
'fieldtype': 'Date',
- 'idx': 19,
'label': 'Stock Frozen Upto'
},
@@ -295,7 +282,6 @@
'doctype': 'DocField',
'fieldname': 'stock_auth_role',
'fieldtype': 'Link',
- 'idx': 20,
'label': 'Authorized Role (Frozen Entry)',
'options': 'Role'
},
@@ -304,7 +290,6 @@
{
'doctype': 'DocField',
'fieldtype': 'Section Break',
- 'idx': 21,
'label': 'Accounts'
},
@@ -315,7 +300,6 @@
'doctype': 'DocField',
'fieldname': 'acc_frozen_upto',
'fieldtype': 'Date',
- 'idx': 22,
'label': 'Accounts Frozen Upto'
},
@@ -326,7 +310,6 @@
'doctype': 'DocField',
'fieldname': 'bde_auth_role',
'fieldtype': 'Link',
- 'idx': 23,
'label': 'Authourized Role (Frozen Entry)',
'options': 'Role'
},
@@ -336,7 +319,6 @@
'doctype': 'DocField',
'fieldname': 'credit_controller',
'fieldtype': 'Link',
- 'idx': 24,
'label': 'Credit Controller',
'options': 'Role'
},
@@ -344,8 +326,21 @@
# DocField
{
'doctype': 'DocField',
+ 'fieldtype': 'Column Break'
+ },
+
+ # DocField
+ {
+ 'doctype': 'DocField',
+ 'fieldtype': 'HTML',
+ 'label': 'Account Info',
+ 'options': '<div class="help-box">For more accounting defaults, Open <a href="#!List/Company">Company</a></div>'
+ },
+
+ # DocField
+ {
+ 'doctype': 'DocField',
'fieldtype': 'Section Break',
- 'idx': 25,
'label': 'Selling'
},
@@ -356,7 +351,6 @@
'doctype': 'DocField',
'fieldname': 'cust_master_name',
'fieldtype': 'Select',
- 'idx': 26,
'label': 'Customer Master created by ',
'options': 'Customer Name\nNaming Series'
},
@@ -366,7 +360,6 @@
'doctype': 'DocField',
'fieldname': 'default_customer_group',
'fieldtype': 'Link',
- 'idx': 27,
'label': 'Default Customer Group',
'options': 'Customer Group'
},
@@ -375,7 +368,6 @@
{
'doctype': 'DocField',
'fieldtype': 'HTML',
- 'idx': 28,
'label': 'CGHelp',
'options': '<a href="javascript:cur_frm.cscript.TreePage(\'Customer Group\');">To manage Customer Groups, click here</a>'
},
@@ -385,7 +377,6 @@
'doctype': 'DocField',
'fieldname': 'default_territory',
'fieldtype': 'Link',
- 'idx': 29,
'label': 'Default Territory',
'options': 'Territory'
},
@@ -394,7 +385,6 @@
{
'doctype': 'DocField',
'fieldtype': 'HTML',
- 'idx': 30,
'label': 'TerritoryHelp',
'options': '<a href="javascript:cur_frm.cscript.TreePage(\'Territory\');">To manage Territory, click here</a>'
},
@@ -402,9 +392,15 @@
# DocField
{
'doctype': 'DocField',
+ 'fieldtype': 'Column Break',
+ 'width': '50%'
+ },
+
+ # DocField
+ {
+ 'doctype': 'DocField',
'fieldname': 'default_price_list',
'fieldtype': 'Link',
- 'idx': 31,
'label': 'Default Price List',
'options': 'Price List'
},
@@ -412,9 +408,10 @@
# DocField
{
'doctype': 'DocField',
- 'fieldtype': 'Column Break',
- 'idx': 32,
- 'width': '50%'
+ 'fieldname': 'default_price_list_currency',
+ 'fieldtype': 'Link',
+ 'label': 'Default Price List Currency',
+ 'options': 'Currency'
},
# DocField
@@ -424,7 +421,6 @@
'doctype': 'DocField',
'fieldname': 'so_required',
'fieldtype': 'Select',
- 'idx': 33,
'label': 'Sales Order Required',
'options': 'No\nYes'
},
@@ -436,7 +432,6 @@
'doctype': 'DocField',
'fieldname': 'dn_required',
'fieldtype': 'Select',
- 'idx': 34,
'label': 'Delivery Note Required',
'options': 'No\nYes'
},
@@ -445,7 +440,6 @@
{
'doctype': 'DocField',
'fieldtype': 'Section Break',
- 'idx': 35,
'label': 'Buying'
},
@@ -454,7 +448,6 @@
'doctype': 'DocField',
'fieldname': 'default_supplier_type',
'fieldtype': 'Link',
- 'idx': 36,
'label': 'Default Supplier Type',
'options': 'Supplier Type'
},
@@ -466,7 +459,6 @@
'doctype': 'DocField',
'fieldname': 'supp_master_name',
'fieldtype': 'Select',
- 'idx': 37,
'label': 'Supplier Master created by ',
'options': 'Supplier Name\nNaming Series'
},
@@ -475,7 +467,6 @@
{
'doctype': 'DocField',
'fieldtype': 'Column Break',
- 'idx': 38,
'width': '50%'
},
@@ -486,7 +477,6 @@
'doctype': 'DocField',
'fieldname': 'po_required',
'fieldtype': 'Select',
- 'idx': 39,
'label': 'Purchase Order Required',
'options': 'No\nYes'
},
@@ -498,7 +488,6 @@
'doctype': 'DocField',
'fieldname': 'pr_required',
'fieldtype': 'Select',
- 'idx': 40,
'label': 'Purchase Receipt Required',
'options': 'No\nYes'
},
@@ -507,7 +496,6 @@
{
'doctype': 'DocField',
'fieldtype': 'Section Break',
- 'idx': 41,
'label': 'HR',
'options': '<div style="padding-top: 8px;" class="columnHeading">HR</div>'
},
@@ -519,8 +507,7 @@
'doctype': 'DocField',
'fieldname': 'emp_created_by',
'fieldtype': 'Select',
- 'idx': 42,
'label': 'Employee Records to be created by ',
'options': '\nNaming Series\nEmployee Number'
}
-]
\ No newline at end of file
+]
diff --git a/erpnext/setup/doctype/other_charges/other_charges.js b/erpnext/setup/doctype/other_charges/other_charges.js
index 3d0b324..ddc9755 100644
--- a/erpnext/setup/doctype/other_charges/other_charges.js
+++ b/erpnext/setup/doctype/other_charges/other_charges.js
@@ -36,7 +36,7 @@
// add rows
if(cl.length){
for(var i=0;i<cl.length;i++){
- if(fmt_money(convert_rate(cl[i].tax_amount))!=0)
+ if(fmt_money(convert_rate(cl[i].tax_amount))!=0 && !cl[i].included_in_print_rate)
out += make_row(cl[i].description,fmt_money(convert_rate(cl[i].tax_amount)),0);
}
}
@@ -93,12 +93,10 @@
return 'SELECT tabAccount.name FROM tabAccount WHERE tabAccount.group_or_ledger="Ledger" AND tabAccount.docstatus != 2 AND (tabAccount.account_type = "Tax" OR tabAccount.account_type = "Chargeable") AND tabAccount.company = "'+doc.company+'" AND tabAccount.name LIKE "%s"'
}
-//--------------------filter other charges master company-wise-----------------------------------------
-/*
-cur_frm.fields_dict.charge.get_query = function(doc) {
- return 'SELECT DISTINCT `tabOther Charges`.name FROM `tabOther Charges` WHERE `tabOther Charges`.company = "'+doc.company+'" AND `tabOther Charges`.company is not NULL AND `tabOther Charges`.name LIKE "%s" ORDER BY `tabOther Charges`.name LIMIT 50';
+cur_frm.fields_dict['other_charges'].grid.get_field("cost_center_other_charges").get_query = function(doc) {
+ return 'SELECT `tabCost Center`.`name` FROM `tabCost Center` WHERE `tabCost Center`.`company_name` = "' +doc.company+'" AND `tabCost Center`.%(key)s LIKE "%s" AND `tabCost Center`.`group_or_ledger` = "Ledger" AND `tabCost Center`.`docstatus`!= 2 ORDER BY `tabCost Center`.`name` ASC LIMIT 50';
}
-*/
+
cur_frm.cscript.account_head = function(doc, cdt, cdn) {
var d = locals[cdt][cdn];
diff --git a/erpnext/setup/doctype/permission_control/permission_control.py b/erpnext/setup/doctype/permission_control/permission_control.py
index a24c756..044dff5 100644
--- a/erpnext/setup/doctype/permission_control/permission_control.py
+++ b/erpnext/setup/doctype/permission_control/permission_control.py
@@ -30,7 +30,7 @@
WHERE ifnull(docstatus,0)=0
AND ifnull(istable,0)=0
AND ifnull(issingle,0)=0
- AND `module` NOT IN ('System','Utilities','Setup Masters','Roles','Recycle Bin','Mapper','Application Internal','Development')
+ AND `module` NOT IN ('System','Utilities','Setup Masters','Roles','Recycle Bin','Mapper','Application Internal','Development', 'Core')
ORDER BY `name` ASC""")
rl = [''] + [a[0] for a in sql("select name from tabRole where ifnull(docstatus,0)=0")]
diff --git a/erpnext/setup/doctype/personalize/personalize.py b/erpnext/setup/doctype/personalize/personalize.py
index 3264546..dc9ad66 100644
--- a/erpnext/setup/doctype/personalize/personalize.py
+++ b/erpnext/setup/doctype/personalize/personalize.py
@@ -14,7 +14,8 @@
# on update
#
def validate(self):
- if self.doc.file_list and self.doc.set_from_attachment:
+ from webnotes.utils import cint
+ if self.doc.file_list and cint(self.doc.set_from_attachment):
self.set_html_from_image()
# update control panel - so it loads new letter directly
diff --git a/erpnext/setup/page/setup/setup.js b/erpnext/setup/page/setup/setup.js
index 7c1245a..f536c70 100644
--- a/erpnext/setup/page/setup/setup.js
+++ b/erpnext/setup/page/setup/setup.js
@@ -161,6 +161,7 @@
['Custom Field',1,'Custom Field','dt'+NEWLINE+'label'+NEWLINE+'fieldtype'+NEWLINE+'options','Add and manage custom fields on forms'],
['Email Settings',3,'Email Settings','','Outgoing email server and address'],
['Notification Settings',3,'Notification Control','','Automatic emails set at selected events'],
+ ['Email Digest', 1, 'Email Digest', '', 'Schedule Daily / Weekly / Monthly Summary e-mails'],
['Company',1,'Company','id'+NEWLINE+'is_active'+NEWLINE+'email','Manage list of companies'],
['Fiscal Year',1,'Fiscal Year','id'+NEWLINE+'company'+NEWLINE+'is_active'+NEWLINE+'year','Manage list of fiscal years'],
['Personalize',3,'Personalize','','Set your banner'],
@@ -168,8 +169,10 @@
['Import Data',2,'Import Data','','Import data from CSV files'],
['Manage Users',2,'My Company','','Add / remove users and manage their roles'],
['Web Forms',2,'Webforms','', 'Code to embed forms in yor website'],
- ['Permissions Manager',2,'Permission Engine','', 'Manage all permissions from one tool (beta)'],
- ['Property Setter',1,'Property Setter','', 'Customize properties of a Form (DocType) or Field'],
+ ['Permissions Manager',2,'Permission Engine','', 'Manage all permissions from one tool'],
+ //['Property Setter',1,'Property Setter','', 'Customize properties of a Form (DocType) or Field'],
+ ['Customize Form View',3,'DocLayer','', 'Customize properties of a Form (DocType) or Field'],
+ ['Print Formats', 1, 'Print Format', '', 'Manage Print Formats'],
['Letter Head',1,'Letter Head','','Manage different letter heads for Prints'],
['SMS Settings',3,'SMS Settings','','Integrate your personalized SMS gateway which support http web service'],
['SMS Center',3,'SMS Center','','Send mass sms to your leads, contacts and partners'],
@@ -181,6 +184,7 @@
['Print Heading',1,'Print Heading','','Manage headings for printing transactions'],
['Term',1,'Term','','Manage template of standard Terms for order / invoices etc'],
['Currency',1,'Currency','','Manage list of currencies'],
+ ['Address',1,'Address','','Manage Address of customers, suppliers'],
['Country',1,'Country','','Country master'],
['State',1,'State','','State master'],
['Rename Tool',3,'Rename Tool','','Rename a record'],
diff --git a/erpnext/startup/event_handlers.py b/erpnext/startup/event_handlers.py
index 53b979e..ce5c4c4 100644
--- a/erpnext/startup/event_handlers.py
+++ b/erpnext/startup/event_handlers.py
@@ -44,6 +44,16 @@
if webnotes.form_dict.get('login_from'):
webnotes.session['data']['login_from'] = webnotes.form.getvalue('login_from')
webnotes.session_obj.update()
+
+ exception_list = ['demo@webnotestech.com']
+
+ if webnotes.session['user'] not in exception_list:
+ # Clear previous sessions i.e. logout previous log-in attempts
+ sid_list = webnotes.conn.sql("SELECT sid FROM `tabSessions` WHERE user=%s AND sid!=%s", (webnotes.session['user'], webnotes.session['sid']))
+ from webnotes.auth import LoginManager
+ login_manager = LoginManager()
+ for sid in sid_list:
+ login_manager.logout(sid=sid)
update_account_details()
@@ -53,7 +63,7 @@
def on_logout(login_manager):
if cint(webnotes.conn.get_value('Control Panel', None, 'sync_with_gateway')):
from server_tools.gateway_utils import logout_sso
- logout_sso()
+ logout_sso(login_manager.sid)
#
# create a profile (if logs in for the first time)
@@ -81,4 +91,4 @@
p.enabled = 1
p.owner = user
p.save(1)
-
\ No newline at end of file
+
diff --git a/erpnext/startup/startup.css b/erpnext/startup/startup.css
index f028416..7b2b6e5 100644
--- a/erpnext/startup/startup.css
+++ b/erpnext/startup/startup.css
@@ -4,7 +4,7 @@
}
body, span, div, td, input, textarea, button, select {
- font-family: Verdana, Arial, Sans Serif;
+ font-family: 'Lucida Grande', 'Lucida Sans Unicode', Verdana, sans-serif;
font-size: 12px;
}
diff --git a/erpnext/startup/startup.js b/erpnext/startup/startup.js
index 3e2fde4..07c1629 100644
--- a/erpnext/startup/startup.js
+++ b/erpnext/startup/startup.js
@@ -56,6 +56,14 @@
// menu
var ml = r.message;
+ // login-file
+ if(r.login_url){
+ login_file = 'http://' + r.login_url;
+ }
+ else if(pscript.is_erpnext_saas) {
+ login_file = 'https://www.erpnext.com';
+ }
+
// clear
page_body.left_sidebar.innerHTML = '';
@@ -292,13 +300,6 @@
}
}
- if(r.login_url){
- login_file = 'http://' + r.login_url;
- }
- else if(pscript.is_erpnext_saas) {
- login_file = 'https://www.erpnext.com';
- }
-
$(me.items_area).slideDown();
@@ -571,6 +572,11 @@
'Receivable Voucher': {'entries':['adj_rate']},
'Sales Order': {'sales_order_details':['adj_rate','ref_rate']}
},
+ 'fs_purchase_discounts': {
+ 'Purchase Order': {'po_details':['purchase_ref_rate', 'discount_rate', 'import_ref_rate']},
+ 'Purchase Receipt': {'purchase_receipt_details':['purchase_ref_rate', 'discount_rate', 'import_ref_rate']},
+ 'Payable Voucher': {'entries':['purchase_ref_rate', 'discount_rate', 'import_ref_rate']}
+ },
'fs_brands': {
'Delivery Note': {'delivery_note_details':['brand']},
'Indent': {'indent_details':['brand']},
@@ -689,6 +695,9 @@
},
'fs_pos': {
'Receivable Voucher': {'fields':['is_pos']}
+ },
+ 'fs_recurring_invoice': {
+ 'Receivable Voucher': {'fields': ['Recurring Invoice']}
}
}
diff --git a/erpnext/stock/DocType Mapper/Purchase Order-Purchase Receipt/Purchase Order-Purchase Receipt.txt b/erpnext/stock/DocType Mapper/Purchase Order-Purchase Receipt/Purchase Order-Purchase Receipt.txt
index 42eff14..ec3ff86 100644
--- a/erpnext/stock/DocType Mapper/Purchase Order-Purchase Receipt/Purchase Order-Purchase Receipt.txt
+++ b/erpnext/stock/DocType Mapper/Purchase Order-Purchase Receipt/Purchase Order-Purchase Receipt.txt
@@ -5,7 +5,7 @@
{
'creation': '2010-08-08 17:09:35',
'docstatus': 0,
- 'modified': '2011-10-07 12:10:26',
+ 'modified': '2011-10-12 10:49:40',
'modified_by': 'Administrator',
'owner': 'Administrator'
},
@@ -153,6 +153,30 @@
'to_field': 'schedule_date'
},
+ # Field Mapper Detail
+ {
+ 'doctype': 'Field Mapper Detail',
+ 'from_field': 'net_total',
+ 'match_id': 0,
+ 'to_field': 'net_total'
+ },
+
+ # Field Mapper Detail
+ {
+ 'doctype': 'Field Mapper Detail',
+ 'from_field': 'grand_total',
+ 'match_id': 0,
+ 'to_field': 'grand_total'
+ },
+
+ # Field Mapper Detail
+ {
+ 'doctype': 'Field Mapper Detail',
+ 'from_field': 'total_tax',
+ 'match_id': 0,
+ 'to_field': 'total_tax'
+ },
+
# Table Mapper Detail
{
'doctype': 'Table Mapper Detail',
diff --git a/erpnext/stock/Print Format/Delivery Note Classic/Delivery Note Classic.txt b/erpnext/stock/Print Format/Delivery Note Classic/Delivery Note Classic.txt
new file mode 100644
index 0000000..aa90475
--- /dev/null
+++ b/erpnext/stock/Print Format/Delivery Note Classic/Delivery Note Classic.txt
@@ -0,0 +1,28 @@
+# Print Format, Delivery Note Classic
+[
+
+ # These values are common in all dictionaries
+ {
+ 'creation': '2011-12-13 11:02:59',
+ 'docstatus': 0,
+ 'modified': '2011-12-13 13:11:24',
+ 'modified_by': 'Administrator',
+ 'owner': 'Administrator'
+ },
+
+ # These values are common for all Print Format
+ {
+ 'doc_type': 'Delivery Note',
+ 'doctype': 'Print Format',
+ 'html': '<!--\n\tSample Print Format for ERPNext\n\tPlease use at your own discretion\n\tFor suggestions and contributions:\n\t\thttps://github.com/webnotes/erpnext-print-templates\n\n\tFreely usable under MIT license\n-->\n\n<!-- Style Settings -->\n<style>\n\t/*\n\t\tcommon style for whole page\n\t\tThis should include:\n\t\t+ page size related settings\n\t\t+ font family settings\n\t\t+ line spacing settings\n\t*/\n\t@media screen {\n\t\tbody {\n\t\t\twidth: 8.3in;\n\t\t}\n\t}\n\n\thtml, body, div, span, td {\n\t\tfont-family: "Georgia", serif;\n\t\tfont-size: 12px;\n\t}\n\n\tbody {\n\t\tpadding: 10px;\n\t\tmargin: auto;\n\t\tfont-size: 12px;\n\t\tline-height: 150%;\n\t}\n\n\t.common {\n\t\tfont-family: "Georgia", serif !important;\n\t\tfont-size: 12px;\n\t\tpadding: 10px 0px;\n\t}\n\n\ttable {\n\t\tborder-collapse: collapse;\n\t\twidth: 100%;\n\t\tvertical-align: top;\n\t}\n\n\ttable td {\n\t\tpadding: 2px 0px;\n\t}\n\t\n\ttable h1, h2, h3, h4, h5, h6 {\n\t\tpadding: 0px;\n\t\tmargin: 0px;\n\t}\n\n\ttable.header-table td {\n\t\tvertical-align: top;\n\t}\n\n\ttable.header-table thead {\n\t\tborder-bottom: 1px solid black;\n\t}\n\n\ttable.header-table h3 {\n\t\tcolor: gray;\n\t}\n\n\ttable.header-table thead td {\n\t\tpadding: 5px 0px;\n\t}\n\n\tdiv.page-body table td:nth-child(6),\n\tdiv.page-body table td:nth-child(7) {\n\t\ttext-align: right;\n\t}\n\n\ttable.footer-table td {\n\t\tvertical-align: top;\n\t}\n\n\ttable.footer-table td table td:nth-child(2),\n\ttable.footer-table td table td:nth-child(3) {\n\t\ttext-align: right;\n\t}\n</style>\n\n\n<!-- Javascript -->\n<script>\n\tsi_std = {\n\t\tprint_item_table: function() {\n\t\t\tvar table = print_table(\n\t\t\t\t\'Delivery Note\',\n\t\t\t\tdoc.name,\n\t\t\t\t\'delivery_note_details\',\n\t\t\t\t\'Delivery Note Detail\',\n\t\t\t\t[// Here specify the table columns to be displayed\n\t\t\t\t\t\'SR\', \'item_code\', \'item_name\', \'description\', \'qty\', \'stock_uom\',\n\t\t\t\t\t\'basic_rate\', \'amount\'\n\t\t\t\t],\n\t\t\t\t[// Here specify the labels of column headings\n\t\t\t\t\t\'Sr\', \'Item Code\', \'Item Name\', \'Description\', \'Qty\',\n\t\t\t\t\t\'UoM\', \'Basic Rate\', \'Amount\'\n\t\t\t\t],\n\t\t\t\t[// Here specify the column widths\n\t\t\t\t\t\'3%\', \'10%\', \'15%\', \'32%\', \'5%\',\n\t\t\t\t\t\'5%\', \'15%\', \'15%\'\n\t\t\t\t],\n\t\t\t\tnull,\n\t\t\t\tnull,\n\t\t\t\t{\n\t\t\t\t\t\'description\' : function(data_row) {\n\t\t\t\t\t\tvar to_append = \'\'\n\t\t\t\t\t\tif(data_row.adj_rate){\n\t\t\t\t\t\t\tto_append = \'<div style="padding-left: 15px;"><i>Discount: \' + \n\t\t\t\t\t\t\t\tdata_row.adj_rate + \'%</i></div>\';\n\t\t\t\t\t\t\tif(data_row.description.indexOf(to_append)==-1) {\n\t\t\t\t\t\t\t\tdata_row.description = data_row.description + to_append;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\t\n\t\t\t\t\t\tif(data_row.serial_no) {\n\t\t\t\t\t\t\tto_append = \'<div style="padding-left: 15px;"><i>Serial No.:\' + \n\t\t\t\t\t\t\t\t((data_row.serial_no.indexOf(\'\\n\')>-1)?\'<br />\':\' \') + \n\t\t\t\t\t\t\t\tdata_row.serial_no + \'</i></div>\';\n\t\t\t\t\t\t\tif(data_row.description.indexOf(to_append)==-1) {\n\t\t\t\t\t\t\t\tdata_row.description = data_row.description + to_append;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\n\t\t\t\t\t\treturn data_row.description;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t);\n\n\t\t\t// This code takes care of page breaks\n\t\t\tif(table.appendChild) {\n\t\t\t\tout = table.innerHTML;\n\t\t\t} else {\n\t\t\t\tout = \'\';\n\t\t\t\tfor(var i=0; i < (table.length-1); i++) {\n\t\t\t\t\tout += table[i].innerHTML + \n\t\t\t\t\t\t\'<div style = "page-break-after: always;" \\\n\t\t\t\t\t\tclass = "page_break"></div>\\\n\t\t\t\t\t\t<div class="page-settings"></div>\';\n\t\t\t\t}\n\t\t\t\tout += table[table.length-1].innerHTML;\n\t\t\t}\n\t\t\treturn out;\n\t\t},\n\n\n\t\tprint_other_charges: function(parent) {\n\t\t\tvar oc = getchildren(\'RV Tax Detail\', doc.name, \'other_charges\');\n\t\t\tvar rows = \'<table width=100%>\\n\';\n\t\t\tfor(var i=0; i<oc.length; i++) {\n\t\t\t\trows +=\n\t\t\t\t\t\'<tr>\\n\' +\n\t\t\t\t\t\t\'\\t<td>\' + oc[i].description + \'</td>\\n\' +\n\t\t\t\t\t\t\'\\t<td></td>\\n\' +\n\t\t\t\t\t\t\'\\t<td width=38%>\' + fmt_money(oc[i].tax_amount) + \'</td>\\n\' +\n\t\t\t\t\t\'</tr>\\n\';\n\t\t\t}\n\t\t\treturn rows + \'</table>\\n\';\n\t\t}\n\t};\n</script>\n\n\n<!-- Page Layout Settings -->\n<div class=\'common page-header\'>\n\t<!-- \n\t\tPage Header will contain\n\t\t\t+ table 1\n\t\t\t\t+ table 1a\n\t\t\t\t\t- Name\n\t\t\t\t\t- Address\n\t\t\t\t\t- Contact\n\t\t\t\t\t- Mobile No\n\t\t\t\t+ table 1b\n\t\t\t\t\t- Voucher Date\n\t\t\t\t\t- Due Date\n\t-->\n\t<table class=\'header-table\' cellspacing=0>\n\t\t<thead>\n\t\t\t<tr><td><script>\'<h1>\' + (doc.select_print_heading || \'Delivery Note\') + \'</h1>\'</script></td></tr>\n\t\t\t<tr><td><h3><script>cur_frm.docname</script></h3></td></tr>\n\t\t</thead>\n\t\t<tbody>\n\t\t\t<tr>\n\t\t\t\t<td width=60%><table width=100% cellspacing=0><tbody>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td width=22%><b>Name</b></td>\n\t\t\t\t\t\t<td><script>doc.customer_name</script></td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td><b>Address</b></td>\n\t\t\t\t\t\t<td><script>replace_newlines(doc.address_display)</script></td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td><b>Contact</b></td>\n\t\t\t\t\t\t<td><script>doc.contact_display</script></td>\n\t\t\t\t\t</tr>\n\t\t\t\t</tbody></table></td>\n\t\t\t\t<td><table width=100% cellspacing=0><tbody>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td width=63%><b>Delivery Note Date</b></td>\n\t\t\t\t\t\t<td><script>date.str_to_user(doc.transaction_date)</script></td>\n\t\t\t\t\t<tr>\t\t\t\t\t\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td><b>Sales Order No.</b></td>\n\t\t\t\t\t\t<td>\n\t\t\t\t\t\t\t<script>doc.sales_order_no</script><br />\n\t\t\t\t\t\t\t<i>(<script>date.str_to_user(doc.posting_date)</script>)</i>\n\t\t\t\t\t\t</td>\n\t\t\t\t\t<tr>\t\t\t\t\t\n\t\t\t\t</tbody></table></td>\n\t\t\t</tr>\n\t\t</tbody>\n\t\t<tfoot>\n\t\t\n\t\t</tfoot>\n\t</table>\n</div>\n<div class=\'common page-body\'>\n\t<!-- \n\t\tPage Body will contain\n\t\t\t+ table 2\n\t\t\t\t- Sales Invoice Data\n\t-->\n\t<script>si_std.print_item_table()</script>\n</div>\n<div class=\'common page-footer\'>\n\t<!-- \n\t\tPage Footer will contain\n\t\t\t+ table 3\n\t\t\t\t- Terms and Conditions\n\t\t\t\t- Total Rounded Amount Calculation\n\t\t\t\t- Total Rounded Amount in Words\n\t-->\n\t<table class=\'footer-table\' width=100% cellspacing=0>\n\t\t<thead>\n\t\t\t\n\t\t</thead>\n\t\t<tbody>\n\t\t\t<tr>\n\t\t\t\t<td width=60% style=\'padding-right: 10px;\'>\n\t\t\t\t\t<b>Terms, Conditions & Other Information:</b><br />\n\t\t\t\t\t<script>doc.terms</script>\n\t\t\t\t</td>\n\t\t\t\t<td>\n\t\t\t\t\t<table cellspacing=0 width=100%><tbody>\n\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t<td>Net Total</td>\n\t\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t\t<td width=38%><script>\n\t\t\t\t\t\t\t\tfmt_money(doc.net_total)\n\t\t\t\t\t\t\t</script></td>\n\t\t\t\t\t\t</tr>\n\t\t\t\t\t\t<tr><td colspan=3><script>si_std.print_other_charges()</script></td></tr>\n\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t<td>Grand Total</td>\n\t\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t\t<td><script>\n\t\t\t\t\t\t\t\tfmt_money(doc.grand_total_export)\n\t\t\t\t\t\t\t</script></td>\n\t\t\t\t\t\t</tr>\n\t\t\t\t\t\t<tr style=\'font-weight: bold\'>\n\t\t\t\t\t\t\t<td>Rounded Total</td>\n\t\t\t\t\t\t\t<td><script>doc.currency</script></td>\n\t\t\t\t\t\t\t<td><script>\n\t\t\t\t\t\t\t\tfmt_money(doc.rounded_total_export)\n\t\t\t\t\t\t\t</script></td>\n\t\t\t\t\t\t</tr>\n\t\t\t\t\t</tbody></table>\n\t\t\t\t\t<br /><b>In Words</b><br />\n\t\t\t\t\t<i><script>doc.in_words_export</script></i>\n\t\t\t\t</td>\n\t\t\t</tr>\t\t\n\t\t</tbody>\n\t\t<tfoot>\n\t\t\n\t\t</tfoot>\n\t</table>\n</div>\n\n',
+ 'module': 'Stock',
+ 'name': '__common__',
+ 'standard': 'Yes'
+ },
+
+ # Print Format, Delivery Note Classic
+ {
+ 'doctype': 'Print Format',
+ 'name': 'Delivery Note Classic'
+ }
+]
\ No newline at end of file
diff --git a/erpnext/stock/Print Format/Delivery Note Modern/Delivery Note Modern.txt b/erpnext/stock/Print Format/Delivery Note Modern/Delivery Note Modern.txt
new file mode 100644
index 0000000..1b10b16
--- /dev/null
+++ b/erpnext/stock/Print Format/Delivery Note Modern/Delivery Note Modern.txt
@@ -0,0 +1,28 @@
+# Print Format, Delivery Note Modern
+[
+
+ # These values are common in all dictionaries
+ {
+ 'creation': '2011-12-13 11:02:59',
+ 'docstatus': 0,
+ 'modified': '2011-12-13 13:20:50',
+ 'modified_by': 'Administrator',
+ 'owner': 'Administrator'
+ },
+
+ # These values are common for all Print Format
+ {
+ 'doc_type': 'Delivery Note',
+ 'doctype': 'Print Format',
+ 'html': '<!--\n\tSample Print Format for ERPNext\n\tPlease use at your own discretion\n\tFor suggestions and contributions:\n\t\thttps://github.com/webnotes/erpnext-print-templates\n\n\tFreely usable under MIT license\n-->\n\n<!-- Style Settings -->\n<style>\n\t/*\n\t\tcommon style for whole page\n\t\tThis should include:\n\t\t+ page size related settings\n\t\t+ font family settings\n\t\t+ line spacing settings\n\t*/\n\t@media screen {\n\t\tbody {\n\t\t\twidth: 8.3in;\n\t\t}\n\t}\n\n\thtml, body, div, span, td {\n\t\tfont-family: "Helvetica", "Arial", sans-serif;\n\t\tfont-size: 12px;\n\t}\n\n\tbody {\n\t\tpadding: 10px;\n\t\tmargin: auto;\n\t\tfont-size: 12px;\n\t\tline-height: 150%;\n\t}\n\n\t.common {\n\t\tfont-family: "Helvetica", "Arial", sans-serif !important;\n\t\tfont-size: 12px;\n\t\tpadding: 10px 0px;\n\t}\n\n\ttable {\n\t\tborder-collapse: collapse;\n\t\twidth: 100%;\n\t\tvertical-align: top;\n\t\tborder-style: none !important;\n\t}\n\n\ttable td {\n\t\tpadding: 2px 0px;\n\t\tborder-style: none !important;\n\t}\n\t\n\ttable h1, h2, h3, h4, h5, h6 {\n\t\tpadding: 0px;\n\t\tmargin: 0px;\n\t}\n\n\ttable.header-table td {\n\t\tvertical-align: top;\n\t}\n\n\ttable.header-table h1 {\n\t\ttext-transform: uppercase;\n\t\tcolor: white;\n\t\tfont-size: 55px;\n\t\tfont-style: italic;\n\t}\n\n\ttable.header-table thead tr:nth-child(1) div {\n\t\theight: 24px;\n\t\tbackground-color: #696969;\n\t\tvertical-align: middle;\n\t\tpadding: 12px 0px 0px 0px;\n\t\twidth: 100%;\n\t}\n\n\tdiv.page-body table td:nth-child(6),\n\tdiv.page-body table td:nth-child(7) {\n\t\ttext-align: right;\n\t}\n\n\tdiv.page-body table tr td {\n\t\tbackground-color: #DCDCDC !important;\n\t}\n\n\tdiv.page-body table tr:nth-child(1) td {\n\t\tbackground-color: #696969 !important;\n\t\tcolor: white !important;\n\t}\n\n\ttable.footer-table td {\n\t\tvertical-align: top;\n\t}\n\n\ttable.footer-table td table td:nth-child(2),\n\ttable.footer-table td table td:nth-child(3) {\n\t\ttext-align: right;\n\t}\n\n\ttable.footer-table tfoot td {\n\t\tbackground-color: #696969;\n\t\theight: 10px;\n\t}\n\n\t.imp-details {\n\t\tbackground-color: #DCDCDC;\n\t}\n</style>\n\n\n<!-- Javascript -->\n<script>\n\tsi_std = {\n\t\tprint_item_table: function() {\n\t\t\tvar table = print_table(\n\t\t\t\t\'Delivery Note\',\n\t\t\t\tdoc.name,\n\t\t\t\t\'delivery_note_details\',\n\t\t\t\t\'Delivery Note Detail\',\n\t\t\t\t[// Here specify the table columns to be displayed\n\t\t\t\t\t\'SR\', \'item_code\', \'item_name\', \'description\', \'qty\', \'stock_uom\',\n\t\t\t\t\t\'basic_rate\', \'amount\'\n\t\t\t\t],\n\t\t\t\t[// Here specify the labels of column headings\n\t\t\t\t\t\'Sr\', \'Item Code\', \'Item Name\', \'Description\', \'Qty\',\n\t\t\t\t\t\'UoM\', \'Basic Rate\', \'Amount\'\n\t\t\t\t],\n\t\t\t\t[// Here specify the column widths\n\t\t\t\t\t\'3%\', \'10%\', \'15%\', \'32%\', \'5%\',\n\t\t\t\t\t\'5%\', \'15%\', \'15%\'\n\t\t\t\t],\n\t\t\t\tnull,\n\t\t\t\tnull,\n\t\t\t\t{\n\t\t\t\t\t\'description\' : function(data_row) {\n\t\t\t\t\t\tvar to_append = \'\'\n\t\t\t\t\t\tif(data_row.adj_rate){\n\t\t\t\t\t\t\tto_append = \'<div style="padding-left: 15px;"><i>Discount: \' + \n\t\t\t\t\t\t\t\tdata_row.adj_rate + \'%</i></div>\';\n\t\t\t\t\t\t\tif(data_row.description.indexOf(to_append)==-1) {\n\t\t\t\t\t\t\t\tdata_row.description = data_row.description + to_append;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\t\n\t\t\t\t\t\tif(data_row.serial_no) {\n\t\t\t\t\t\t\tto_append = \'<div style="padding-left: 15px;"><i>Serial No.:\' + \n\t\t\t\t\t\t\t\t((data_row.serial_no.indexOf(\'\\n\')>-1)?\'<br />\':\' \') + \n\t\t\t\t\t\t\t\tdata_row.serial_no + \'</i></div>\';\n\t\t\t\t\t\t\tif(data_row.description.indexOf(to_append)==-1) {\n\t\t\t\t\t\t\t\tdata_row.description = data_row.description + to_append;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\n\t\t\t\t\t\treturn data_row.description;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t);\n\n\t\t\t// This code takes care of page breaks\n\t\t\tif(table.appendChild) {\n\t\t\t\tout = table.innerHTML;\n\t\t\t} else {\n\t\t\t\tout = \'\';\n\t\t\t\tfor(var i=0; i < (table.length-1); i++) {\n\t\t\t\t\tout += table[i].innerHTML + \n\t\t\t\t\t\t\'<div style = "page-break-after: always;" \\\n\t\t\t\t\t\tclass = "page_break"></div>\\\n\t\t\t\t\t\t<div class="page-settings"></div>\';\n\t\t\t\t}\n\t\t\t\tout += table[table.length-1].innerHTML;\n\t\t\t}\n\t\t\treturn out;\n\t\t},\n\n\n\t\tprint_other_charges: function(parent) {\n\t\t\tvar oc = getchildren(\'RV Tax Detail\', doc.name, \'other_charges\');\n\t\t\tvar rows = \'<table width=100%>\\n\';\n\t\t\tfor(var i=0; i<oc.length; i++) {\n\t\t\t\trows +=\n\t\t\t\t\t\'<tr>\\n\' +\n\t\t\t\t\t\t\'\\t<td>\' + oc[i].description + \'</td>\\n\' +\n\t\t\t\t\t\t\'\\t<td></td>\\n\' +\n\t\t\t\t\t\t\'\\t<td width=38%>\' + fmt_money(oc[i].tax_amount) + \'</td>\\n\' +\n\t\t\t\t\t\'</tr>\\n\';\n\t\t\t}\n\t\t\treturn rows + \'</table>\\n\';\n\t\t}\n\t};\n</script>\n\n\n<!-- Page Layout Settings -->\n<div class=\'common page-header\'>\n\t<!-- \n\t\tPage Header will contain\n\t\t\t+ table 1\n\t\t\t\t+ table 1a\n\t\t\t\t\t- Name\n\t\t\t\t\t- Address\n\t\t\t\t\t- Contact\n\t\t\t\t\t- Mobile No\n\t\t\t\t+ table 1b\n\t\t\t\t\t- Voucher Date\n\t\t\t\t\t- Due Date\n\t-->\n\t<table class=\'header-table\' cellspacing=0>\n\t\t<thead>\n\t\t\t<tr><td colspan=2><div><script>\'<h1>\' + (doc.select_print_heading || \'Delivery Note\') + \'</h1>\'</script></div></td></tr>\n\t\t\t<tr><td colspan=2><div style="height:15px"></div></td></tr>\n\t\t</thead>\n\t\t<tbody>\n\t\t\t<tr>\n\t\t\t\t<td width=60%><table width=100% cellspacing=0><tbody>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td width=22%><b>Name</b></td>\n\t\t\t\t\t\t<td><script>doc.customer_name</script></td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td><b>Address</b></td>\n\t\t\t\t\t\t<td><script>replace_newlines(doc.address_display)</script></td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td><b>Contact</b></td>\n\t\t\t\t\t\t<td><script>doc.contact_display</script></td>\n\t\t\t\t\t</tr>\n\t\t\t\t</tbody></table></td>\n\t\t\t\t<td><table width=100% cellspacing=0><tbody>\n\t\t\t\t\t<tr class=\'imp-details\'>\n\t\t\t\t\t\t<td><b>Delivery Note No.</b></td>\n\t\t\t\t\t\t<td><script>cur_frm.docname</script></td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td width=63%><b>Delivery Note Date</b></td>\n\t\t\t\t\t\t<td><script>date.str_to_user(doc.transaction_date)</script></td>\n\t\t\t\t\t<tr>\t\t\t\t\t\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td><b>Sales Order No.</b></td>\n\t\t\t\t\t\t<td>\n\t\t\t\t\t\t\t<script>doc.sales_order_no</script><br />\n\t\t\t\t\t\t\t<i>(<script>date.str_to_user(doc.posting_date)</script>)</i>\n\t\t\t\t\t\t</td>\n\t\t\t\t\t<tr>\t\t\t\t\t\n\t\t\t\t</tbody></table></td>\n\t\t\t</tr>\n\t\t</tbody>\n\t\t<tfoot>\n\t\t\n\t\t</tfoot>\n\t</table>\n</div>\n<div class=\'common page-body\'>\n\t<!-- \n\t\tPage Body will contain\n\t\t\t+ table 2\n\t\t\t\t- Sales Invoice Data\n\t-->\n\t<script>si_std.print_item_table()</script>\n</div>\n<div class=\'common page-footer\'>\n\t<!-- \n\t\tPage Footer will contain\n\t\t\t+ table 3\n\t\t\t\t- Terms and Conditions\n\t\t\t\t- Total Rounded Amount Calculation\n\t\t\t\t- Total Rounded Amount in Words\n\t-->\n\t<table class=\'footer-table\' width=100% cellspacing=0>\n\t\t<thead>\n\t\t\t\n\t\t</thead>\n\t\t<tbody>\n\t\t\t<tr>\n\t\t\t\t<td width=60% style=\'padding-right: 10px;\'>\n\t\t\t\t\t<b>Terms, Conditions & Other Information:</b><br />\n\t\t\t\t\t<script>doc.terms</script>\n\t\t\t\t</td>\n\t\t\t\t<td>\n\t\t\t\t\t<table cellspacing=0 width=100%><tbody>\n\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t<td>Net Total</td>\n\t\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t\t<td width=38%><script>\n\t\t\t\t\t\t\t\tfmt_money(doc.net_total)\n\t\t\t\t\t\t\t</script></td>\n\t\t\t\t\t\t</tr>\n\t\t\t\t\t\t<tr><td colspan=3><script>si_std.print_other_charges()</script></td></tr>\n\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t<td>Grand Total</td>\n\t\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t\t<td><script>\n\t\t\t\t\t\t\t\tfmt_money(doc.grand_total_export)\n\t\t\t\t\t\t\t</script></td>\n\t\t\t\t\t\t</tr>\n\t\t\t\t\t\t<tr style=\'font-weight: bold\' class=\'imp-details\'>\n\t\t\t\t\t\t\t<td>Rounded Total</td>\n\t\t\t\t\t\t\t<td><script>doc.currency</script></td>\n\t\t\t\t\t\t\t<td><script>\n\t\t\t\t\t\t\t\tfmt_money(doc.rounded_total_export)\n\t\t\t\t\t\t\t</script></td>\n\t\t\t\t\t\t</tr>\n\t\t\t\t\t</tbody></table>\n\t\t\t\t\t<br /><b>In Words</b><br />\n\t\t\t\t\t<i><script>doc.in_words_export</script></i>\n\t\t\t\t</td>\n\t\t\t</tr>\t\t\n\t\t</tbody>\n\t\t<tfoot>\n\t\t\t<tr><td colspan=2><div></div></td><tr>\n\t\t</tfoot>\n\t</table>\n</div>\n',
+ 'module': 'Stock',
+ 'name': '__common__',
+ 'standard': 'Yes'
+ },
+
+ # Print Format, Delivery Note Modern
+ {
+ 'doctype': 'Print Format',
+ 'name': 'Delivery Note Modern'
+ }
+]
\ No newline at end of file
diff --git a/erpnext/stock/Print Format/Delivery Note Packing List Wise/Delivery Note Packing List Wise.txt b/erpnext/stock/Print Format/Delivery Note Packing List Wise/Delivery Note Packing List Wise.txt
index 97f57a9..849db97 100644
--- a/erpnext/stock/Print Format/Delivery Note Packing List Wise/Delivery Note Packing List Wise.txt
+++ b/erpnext/stock/Print Format/Delivery Note Packing List Wise/Delivery Note Packing List Wise.txt
@@ -3,9 +3,9 @@
# These values are common in all dictionaries
{
- 'creation': '2011-08-18 16:29:14',
+ 'creation': '2011-08-23 16:49:40',
'docstatus': 0,
- 'modified': '2011-08-23 13:24:12',
+ 'modified': '2011-10-19 14:12:11',
'modified_by': 'Administrator',
'owner': 'Administrator'
},
@@ -13,7 +13,7 @@
# These values are common for all Print Format
{
'doctype': 'Print Format',
- 'html': "<html>\n<head>\n\n<script>\nfunction replaceAll(s,s1,s2){ return s.split(s1).join(s2);}\n\nfunction get_letter_head(){\n var cp = locals['Control Panel']['Control Panel'];\n if(cp.letter_head != 'None') {return cp.letter_head; }\n else{ return ''};\n }\n</script>\n<style>\n.cust_tbl { border-collapse:collapse; }\n.cust_tbl td { border:1px solid #848484; }\n</style>\n</head>\n\n<body>\n<script>\nreplaceAll(doc.print_packing_slip,'[HEADER GOES HERE]',get_letter_head());\n</script>\n</body>\n</html>",
+ 'html': "<html>\n<head>\n\n<script>\nfunction replaceAll(s,s1,s2){ return s.split(s1).join(s2);}\n\nfunction get_letter_head() {\n\t// add letter head\n\tvar cp = locals['Control Panel']['Control Panel'];\n\tif(doc.letter_head)\n\t\tvar lh= cstr(_p.letter_heads[doc.letter_head]);\n\telse if(cp.letter_head)\n\t\tvar lh= cp.letter_head;\n\telse \n\t\tvar lh= '';\n\t\t\n\treturn lh;\n}\n\n</script>\n<style>\n.cust_tbl { border-collapse:collapse; }\n.cust_tbl td { border:1px solid #848484; font-size: 13px}\n.large_font td {font-size: 13px}\n</style>\n</head>\n\n<body>\n<script>\nreplaceAll(doc.print_packing_slip,'[HEADER GOES HERE]',get_letter_head());\n</script>\n</body>\n</html>",
'module': 'Stock',
'name': '__common__',
'standard': 'Yes'
diff --git a/erpnext/stock/Print Format/Delivery Note Spartan/Delivery Note Spartan.txt b/erpnext/stock/Print Format/Delivery Note Spartan/Delivery Note Spartan.txt
new file mode 100644
index 0000000..b093107
--- /dev/null
+++ b/erpnext/stock/Print Format/Delivery Note Spartan/Delivery Note Spartan.txt
@@ -0,0 +1,28 @@
+# Print Format, Delivery Note Spartan
+[
+
+ # These values are common in all dictionaries
+ {
+ 'creation': '2011-12-13 11:02:59',
+ 'docstatus': 0,
+ 'modified': '2011-12-13 13:22:53',
+ 'modified_by': 'Administrator',
+ 'owner': 'Administrator'
+ },
+
+ # These values are common for all Print Format
+ {
+ 'doc_type': 'Delivery Note',
+ 'doctype': 'Print Format',
+ 'html': '<!--\n\tSample Print Format for ERPNext\n\tPlease use at your own discretion\n\tFor suggestions and contributions:\n\t\thttps://github.com/webnotes/erpnext-print-templates\n\n\tFreely usable under MIT license\n-->\n\n<!-- Style Settings -->\n<style>\n\t/*\n\t\tcommon style for whole page\n\t\tThis should include:\n\t\t+ page size related settings\n\t\t+ font family settings\n\t\t+ line spacing settings\n\t*/\n\t@media screen {\n\t\tbody {\n\t\t\twidth: 8.3in;\n\t\t}\n\t}\n\n\thtml, body, div, span, td {\n\t\tfont-family: "Arial", sans-serif;\n\t\tfont-size: 12px;\n\t}\n\n\tbody {\n\t\tpadding: 10px;\n\t\tmargin: auto;\n\t\tfont-size: 12px;\n\t\tline-height: 150%;\n\t}\n\n\t.common {\n\t\tfont-family: "Arial", sans-serif !important;\n\t\tfont-size: 12px;\n\t\tpadding: 0px;\n\t}\n\n\ttable {\n\t\twidth: 100% !important;\n\t\tvertical-align: top;\n\t}\n\n\ttable td {\n\t\tpadding: 2px 0px;\n\t}\n\n\ttable, td {\n\t\tborder-collapse: collapse !important;\n\t\tpadding: 0px;\n\t\tmargin: 0px !important;\n\t}\n\t\n\ttable h1, h2, h3, h4, h5, h6 {\n\t\tpadding: 0px;\n\t\tmargin: 0px;\n\t}\n\n\ttable.header-table td {\n\t\tvertical-align: top;\n\t}\n\n\ttable.header-table h3 {\n\t\tcolor: gray;\n\t}\n\n\ttable.header-table thead td {\n\t\tpadding: 5px;\n\t}\n\n\ttable.header-table > thead,\n\ttable.header-table > tbody > tr > td,\n\ttable.footer-table > tbody > tr > td {\n\t\tborder: 1px solid black;\n\t\tpadding: 5px;\n\t}\n\n\ttable.footer-table > tbody,\n\ttable.header-table > thead {\n\t\tborder-bottom: 3px solid black;\n\t}\n\n\ttable.header-table > thead {\n\t\tborder-top: 3px solid black;\n\t}\n\n\tdiv.page-body table td:nth-child(6),\n\tdiv.page-body table td:nth-child(7) {\n\t\ttext-align: right;\n\t}\n\n\tdiv.page-body td {\n\t\tbackground-color: white !important;\n\t\tborder: 1px solid black !important;\n\t}\n\n\ttable.footer-table td {\n\t\tvertical-align: top;\n\t}\n\n\ttable.footer-table td table td:nth-child(2),\n\ttable.footer-table td table td:nth-child(3) {\n\t\ttext-align: right;\n\t}\n</style>\n\n\n<!-- Javascript -->\n<script>\n\tsi_std = {\n\t\tprint_item_table: function() {\n\t\t\tvar table = print_table(\n\t\t\t\t\'Delivery Note\',\n\t\t\t\tdoc.name,\n\t\t\t\t\'delivery_note_details\',\n\t\t\t\t\'Delivery Note Detail\',\n\t\t\t\t[// Here specify the table columns to be displayed\n\t\t\t\t\t\'SR\', \'item_code\', \'item_name\', \'description\', \'qty\', \'stock_uom\',\n\t\t\t\t\t\'basic_rate\', \'amount\'\n\t\t\t\t],\n\t\t\t\t[// Here specify the labels of column headings\n\t\t\t\t\t\'Sr\', \'Item Code\', \'Item Name\', \'Description\', \'Qty\',\n\t\t\t\t\t\'UoM\', \'Basic Rate\', \'Amount\'\n\t\t\t\t],\n\t\t\t\t[// Here specify the column widths\n\t\t\t\t\t\'3%\', \'10%\', \'15%\', \'32%\', \'5%\',\n\t\t\t\t\t\'5%\', \'15%\', \'15%\'\n\t\t\t\t],\n\t\t\t\tnull,\n\t\t\t\tnull,\n\t\t\t\t{\n\t\t\t\t\t\'description\' : function(data_row) {\n\t\t\t\t\t\tvar to_append = \'\'\n\t\t\t\t\t\tif(data_row.adj_rate){\n\t\t\t\t\t\t\tto_append = \'<div style="padding-left: 15px;"><i>Discount: \' + \n\t\t\t\t\t\t\t\tdata_row.adj_rate + \'%</i></div>\';\n\t\t\t\t\t\t\tif(data_row.description.indexOf(to_append)==-1) {\n\t\t\t\t\t\t\t\tdata_row.description = data_row.description + to_append;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\t\n\t\t\t\t\t\tif(data_row.serial_no) {\n\t\t\t\t\t\t\tto_append = \'<div style="padding-left: 15px;"><i>Serial No.:\' + \n\t\t\t\t\t\t\t\t((data_row.serial_no.indexOf(\'\\n\')>-1)?\'<br />\':\' \') + \n\t\t\t\t\t\t\t\tdata_row.serial_no + \'</i></div>\';\n\t\t\t\t\t\t\tif(data_row.description.indexOf(to_append)==-1) {\n\t\t\t\t\t\t\t\tdata_row.description = data_row.description + to_append;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\n\t\t\t\t\t\treturn data_row.description;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t);\n\n\t\t\t// This code takes care of page breaks\n\t\t\tif(table.appendChild) {\n\t\t\t\tout = table.innerHTML;\n\t\t\t} else {\n\t\t\t\tout = \'\';\n\t\t\t\tfor(var i=0; i < (table.length-1); i++) {\n\t\t\t\t\tout += table[i].innerHTML + \n\t\t\t\t\t\t\'<div style = "page-break-after: always;" \\\n\t\t\t\t\t\tclass = "page_break"></div>\\\n\t\t\t\t\t\t<div class="page-settings"></div>\';\n\t\t\t\t}\n\t\t\t\tout += table[table.length-1].innerHTML;\n\t\t\t}\n\t\t\treturn out;\n\t\t},\n\n\n\t\tprint_other_charges: function(parent) {\n\t\t\tvar oc = getchildren(\'RV Tax Detail\', doc.name, \'other_charges\');\n\t\t\tvar rows = \'<table width=100%>\\n\';\n\t\t\tfor(var i=0; i<oc.length; i++) {\n\t\t\t\trows +=\n\t\t\t\t\t\'<tr>\\n\' +\n\t\t\t\t\t\t\'\\t<td>\' + oc[i].description + \'</td>\\n\' +\n\t\t\t\t\t\t\'\\t<td></td>\\n\' +\n\t\t\t\t\t\t\'\\t<td width=38%>\' + fmt_money(oc[i].tax_amount) + \'</td>\\n\' +\n\t\t\t\t\t\'</tr>\\n\';\n\t\t\t}\n\t\t\treturn rows + \'</table>\\n\';\n\t\t}\n\t};\n</script>\n\n\n<!-- Page Layout Settings -->\n<div class=\'common page-header\'>\n\t<!-- \n\t\tPage Header will contain\n\t\t\t+ table 1\n\t\t\t\t+ table 1a\n\t\t\t\t\t- Name\n\t\t\t\t\t- Address\n\t\t\t\t\t- Contact\n\t\t\t\t\t- Mobile No\n\t\t\t\t+ table 1b\n\t\t\t\t\t- Voucher Date\n\t\t\t\t\t- Due Date\n\t-->\n\t<table class=\'header-table\' cellspacing=0>\n\t\t<thead>\n\t\t\t<tr><td colspan=2><script>\'<h1>\' + (doc.select_print_heading || \'Delivery Note\') + \'</h1>\'</script></td></tr>\n\t\t\t<tr><td colspan=2><h3><script>cur_frm.docname</script></h3></td></tr>\n\t\t</thead>\n\t\t<tbody>\n\t\t\t<tr>\n\t\t\t\t<td width=60%><table width=100% cellspacing=0><tbody>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td width=22%><b>Name</b></td>\n\t\t\t\t\t\t<td><script>doc.customer_name</script></td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td><b>Address</b></td>\n\t\t\t\t\t\t<td><script>replace_newlines(doc.address_display)</script></td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td><b>Contact</b></td>\n\t\t\t\t\t\t<td><script>doc.contact_display</script></td>\n\t\t\t\t\t</tr>\n\t\t\t\t</tbody></table></td>\n\t\t\t\t<td><table width=100% cellspacing=0><tbody>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td width=63%><b>Delivery Note Date</b></td>\n\t\t\t\t\t\t<td><script>date.str_to_user(doc.transaction_date)</script></td>\n\t\t\t\t\t<tr>\t\t\t\t\t\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td><b>Sales Order No.</b></td>\n\t\t\t\t\t\t<td>\n\t\t\t\t\t\t\t<script>doc.sales_order_no</script><br />\n\t\t\t\t\t\t\t<i>(<script>date.str_to_user(doc.posting_date)</script>)</i>\n\t\t\t\t\t\t</td>\n\t\t\t\t\t<tr>\t\t\t\t\t\n\t\t\t\t</tbody></table></td>\n\t\t\t</tr>\n\t\t</tbody>\n\t\t<tfoot>\n\t\t\n\t\t</tfoot>\n\t</table>\n</div>\n<div class=\'common page-body\'>\n\t<!-- \n\t\tPage Body will contain\n\t\t\t+ table 2\n\t\t\t\t- Sales Invoice Data\n\t-->\n\t<script>si_std.print_item_table()</script>\n</div>\n<div class=\'common page-footer\'>\n\t<!-- \n\t\tPage Footer will contain\n\t\t\t+ table 3\n\t\t\t\t- Terms and Conditions\n\t\t\t\t- Total Rounded Amount Calculation\n\t\t\t\t- Total Rounded Amount in Words\n\t-->\n\t<table class=\'footer-table\' width=100% cellspacing=0>\n\t\t<thead>\n\t\t\t\n\t\t</thead>\n\t\t<tbody>\n\t\t\t<tr>\n\t\t\t\t<td width=60% style=\'padding-right: 10px;\'>\n\t\t\t\t\t<b>Terms, Conditions & Other Information:</b><br />\n\t\t\t\t\t<script>doc.terms</script>\n\t\t\t\t</td>\n\t\t\t\t<td>\n\t\t\t\t\t<table cellspacing=0 width=100%><tbody>\n\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t<td>Net Total</td>\n\t\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t\t<td width=38%><script>\n\t\t\t\t\t\t\t\tfmt_money(doc.net_total)\n\t\t\t\t\t\t\t</script></td>\n\t\t\t\t\t\t</tr>\n\t\t\t\t\t\t<tr><td colspan=3><script>si_std.print_other_charges()</script></td></tr>\n\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t<td>Grand Total</td>\n\t\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t\t<td><script>\n\t\t\t\t\t\t\t\tfmt_money(doc.grand_total_export)\n\t\t\t\t\t\t\t</script></td>\n\t\t\t\t\t\t</tr>\n\t\t\t\t\t\t<tr style=\'font-weight: bold\'>\n\t\t\t\t\t\t\t<td>Rounded Total</td>\n\t\t\t\t\t\t\t<td><script>doc.currency</script></td>\n\t\t\t\t\t\t\t<td><script>\n\t\t\t\t\t\t\t\tfmt_money(doc.rounded_total_export)\n\t\t\t\t\t\t\t</script></td>\n\t\t\t\t\t\t</tr>\n\t\t\t\t\t</tbody></table>\n\t\t\t\t\t<br /><b>In Words</b><br />\n\t\t\t\t\t<i><script>doc.in_words_export</script></i>\n\t\t\t\t</td>\n\t\t\t</tr>\t\t\n\t\t</tbody>\n\t\t<tfoot>\n\t\t\n\t\t</tfoot>\n\t</table>\n</div>\n',
+ 'module': 'Stock',
+ 'name': '__common__',
+ 'standard': 'Yes'
+ },
+
+ # Print Format, Delivery Note Spartan
+ {
+ 'doctype': 'Print Format',
+ 'name': 'Delivery Note Spartan'
+ }
+]
\ No newline at end of file
diff --git a/erpnext/stock/Print Format/Purchase Receipt Format/Purchase Receipt Format.txt b/erpnext/stock/Print Format/Purchase Receipt Format/Purchase Receipt Format.txt
index fc7bc0e..8ffb83e 100644
--- a/erpnext/stock/Print Format/Purchase Receipt Format/Purchase Receipt Format.txt
+++ b/erpnext/stock/Print Format/Purchase Receipt Format/Purchase Receipt Format.txt
@@ -5,7 +5,7 @@
{
'creation': '2010-08-08 17:09:34',
'docstatus': 0,
- 'modified': '2009-09-07 11:03:11',
+ 'modified': '2011-10-19 14:18:26',
'modified_by': 'Administrator',
'owner': 'Administrator'
},
@@ -13,7 +13,7 @@
# These values are common for all Print Format
{
'doctype': 'Print Format',
- 'html': '<html>\n<head>\n<!--Other charges function-->\n<script>\n var make_row = function(title,val,bold){\n var bstart = \'<b>\'; var bend = \'</b>\';\n return \'<tr><td style="width:50%">\'+(bold?bstart:\'\')+title+(bold?bend:\'\')+\'</td>\'\n +\'<td style="width:20%;text-align:right">\'+doc.currency+\'</td>\'\n +\'<td style="width:30%;text-align:right">\'+(val?val:\'0.00\')+\'</td>\'\n +\'</tr>\'\n }\n\n function get_other_charges(){\n var out =\'\';\n out += \'<div><table class="noborder" style="width:100%">\';\n out += make_row(\'Total Amount\',fmt_money(convert_rate(doc.total_amount)),1)\n +make_row(\'Grand Total\',fmt_money(convert_rate(doc.grand_total)),1);\n out += \'</table></div>\';\n return out;\n }\n\n function get_buying_costs(){\n var out =\'\';\n if(doc.buying_cost_transport || doc.buying_cost_taxes || doc.buying_cost_other){\n out += \'<div><table class="noborder" style="width:100%">\'\n + \'<tr><td style="width:100%"><b>\'+\'Buying Cost Details\'+\'</b></td></tr>\';\n if(doc.buying_cost_transport){ out += make_row(\'Transport Cost\',fmt_money(convert_rate(doc.buying_cost_transport)),0)}\n if(doc.buying_cost_taxes){ out += make_row(\'Taxes\',fmt_money(convert_rate(doc.buying_cost_taxes)),0)}\n if(doc.buying_cost_other){ out += make_row(\'Other Cost\',fmt_money(convert_rate(doc.buying_cost_other)),0)}\n out += \'</table></div>\';\n }\n return out;\n }\n\n function get_letter_head(){\n var cp = locals[\'Control Panel\'][\'Control Panel\'];\n \tif(cp.letter_head) {return cp.letter_head; }\n }\n \n function convert_rate(val){\n var new_val = flt(val)/flt(doc.conversion_rate);\n return new_val;\n }\n \n function get_transport_details(){\n var out = \'\';\n if(doc.transporter_name || doc.lr_no || doc.lr_date){\n out += \'<div><table class="noborder" style="width:40%">\'\n +\'<tr><td style="width:80%"><b>\' + \'Transporter Details\'+\'</b></td><td style="width:20%"></td></tr>\'\n\n if(doc.transporter_name){ out += \'<tr><td style="width:40%">\' + \'Transporter Name\'+\'</td><td style="width:60%">\'+doc.transporter_name+\'</td></tr>\'}\n if(doc.lr_no){ out += \'<tr><td style="width:40%">\' + \'LR No\'+\'</td><td style="width:60%">\'+doc.lr_no+\'</td></tr>\'}\n if(doc.lr_date){ out += \'<tr><td style="width:40%">\' + \'LR Date\'+\'</td><td style="width:60%">\'+doc.lr_date+\'</td></tr>\'}\n out += \'</table></div>\'\n }\n return out;\n }\n\n</script>\n</head>\n<body>\n<div style="border:1px solid black;padding:15px">\n<!--header-->\n<div><script>get_letter_head()</script></div>\n<div style="border-bottom: 1px solid; padding-bottom: 5px;">\n <div><br><b>Purchase Receipt: <script>doc.name</script></b></div>\n <div>Date: <script>date.str_to_user(doc.transaction_date)</script></div>\n</div>\n\n<div style="padding-top:15px">\n<div><script>doc.supplier</script></div>\n<div><br><script>replace_newlines(doc.address_display)</script></div>\n</div>\n\n<div>\n<br>\n <script>\n var t = print_table(\'Purchase Receipt\', doc.name, \'purchase_receipt_details\', \'Purchase Receipt Detail\', [\'SR\', \'item_code\',\'description\',\'received_qty\',\'qty\',\'rejected_qty\',\'po_rate\',\'amount\',\'billed_qty\'], [\'Sr\', \'Item Code\', \'Description\',\'Received Quantity\',\'Accepted Qty\',\'Rejected Qty\',\'Rate\',\'Amount\',\'Billed Qty\'], [\'4%\',\'12%\', \'24%\', \'10%\',\'10%\',\'10%\',\'10%\',\'10%\',\'10%\'])\n if(t.appendChild) {\n // single\n out = t.innerHTML;\n } \n else {//multiple\n out = \'\'\n for(var i=0;i<t.length;i++) {\n if(i!=t.length-1){\n out += \'<div style:"padding-top:5px;"></div>\' + t[i].innerHTML +\'<div style="page-break-after:always"></div>\';\n }\n else out += \'<div style:"padding-top:5px;"></div>\' + t[i].innerHTML;\n }\n }\n out;\n </script>\n\n</div>\n\n<!--Other charges table-->\n<div>\n<table style="width:100%">\n <tr><td style="width:40%"><script>get_buying_costs()</script></td>\n <td style="width:20%"></td><td style="width:40%"><script>get_other_charges()</script></td></tr>\n</table>\n</div>\n<div><script>get_transport_details()</script></div>\n<div><br>Payment Terms</div>\n<div><br><script>replace_newlines(doc.payment_terms)</script></div>\n<div><br>For NCSCI</div>\n<div><br><br>(Authorised Signatory)</div>\n</div></body>\n</html>',
+ 'html': '<html>\n<head>\n<!--Other charges function-->\n<script>\n var make_row = function(title,val,bold){\n var bstart = \'<b>\'; var bend = \'</b>\';\n return \'<tr><td style="width:50%">\'+(bold?bstart:\'\')+title+(bold?bend:\'\')+\'</td>\'\n +\'<td style="width:20%;text-align:right">\'+doc.currency+\'</td>\'\n +\'<td style="width:30%;text-align:right">\'+(val?val:\'0.00\')+\'</td>\'\n +\'</tr>\'\n }\n\n function get_other_charges(){\n var out =\'\';\n out += \'<div><table class="noborder" style="width:100%">\';\n out += make_row(\'Total Amount\',fmt_money(convert_rate(doc.total_amount)),1)\n +make_row(\'Grand Total\',fmt_money(convert_rate(doc.grand_total)),1);\n out += \'</table></div>\';\n return out;\n }\n\n function get_buying_costs(){\n var out =\'\';\n if(doc.buying_cost_transport || doc.buying_cost_taxes || doc.buying_cost_other){\n out += \'<div><table class="noborder" style="width:100%">\'\n + \'<tr><td style="width:100%"><b>\'+\'Buying Cost Details\'+\'</b></td></tr>\';\n if(doc.buying_cost_transport){ out += make_row(\'Transport Cost\',fmt_money(convert_rate(doc.buying_cost_transport)),0)}\n if(doc.buying_cost_taxes){ out += make_row(\'Taxes\',fmt_money(convert_rate(doc.buying_cost_taxes)),0)}\n if(doc.buying_cost_other){ out += make_row(\'Other Cost\',fmt_money(convert_rate(doc.buying_cost_other)),0)}\n out += \'</table></div>\';\n }\n return out;\n }\n\nfunction get_letter_head() {\n\t// add letter head\n\tvar cp = locals[\'Control Panel\'][\'Control Panel\'];\n\tif(doc.letter_head)\n\t\tvar lh= cstr(_p.letter_heads[doc.letter_head]);\n\telse if(cp.letter_head)\n\t\tvar lh= cp.letter_head;\n\telse \n\t\tvar lh= \'\';\n\t\t\n\treturn lh;\n}\n\n \n function convert_rate(val){\n var new_val = flt(val)/flt(doc.conversion_rate);\n return new_val;\n }\n \n function get_transport_details(){\n var out = \'\';\n if(doc.transporter_name || doc.lr_no || doc.lr_date){\n out += \'<div><table class="noborder" style="width:40%">\'\n +\'<tr><td style="width:80%"><b>\' + \'Transporter Details\'+\'</b></td><td style="width:20%"></td></tr>\'\n\n if(doc.transporter_name){ out += \'<tr><td style="width:40%">\' + \'Transporter Name\'+\'</td><td style="width:60%">\'+doc.transporter_name+\'</td></tr>\'}\n if(doc.lr_no){ out += \'<tr><td style="width:40%">\' + \'LR No\'+\'</td><td style="width:60%">\'+doc.lr_no+\'</td></tr>\'}\n if(doc.lr_date){ out += \'<tr><td style="width:40%">\' + \'LR Date\'+\'</td><td style="width:60%">\'+doc.lr_date+\'</td></tr>\'}\n out += \'</table></div>\'\n }\n return out;\n }\n\n</script>\n</head>\n<body>\n<div style="border:1px solid black;padding:15px">\n<!--header-->\n<div><script>get_letter_head()</script></div>\n<div style="border-bottom: 1px solid; padding-bottom: 5px;">\n <div><br><b>Purchase Receipt: <script>doc.name</script></b></div>\n <div>Date: <script>date.str_to_user(doc.transaction_date)</script></div>\n</div>\n\n<div style="padding-top:15px">\n<div><script>doc.supplier</script></div>\n<div><br><script>replace_newlines(doc.address_display)</script></div>\n</div>\n\n<div>\n<br>\n <script>\n var t = print_table(\'Purchase Receipt\', doc.name, \'purchase_receipt_details\', \'Purchase Receipt Detail\', [\'SR\', \'item_code\',\'description\',\'received_qty\',\'qty\',\'rejected_qty\',\'po_rate\',\'amount\',\'billed_qty\'], [\'Sr\', \'Item Code\', \'Description\',\'Received Quantity\',\'Accepted Qty\',\'Rejected Qty\',\'Rate\',\'Amount\',\'Billed Qty\'], [\'4%\',\'12%\', \'24%\', \'10%\',\'10%\',\'10%\',\'10%\',\'10%\',\'10%\'])\n if(t.appendChild) {\n // single\n out = t.innerHTML;\n } \n else {//multiple\n out = \'\'\n for(var i=0;i<t.length;i++) {\n if(i!=t.length-1){\n out += \'<div style:"padding-top:5px;"></div>\' + t[i].innerHTML +\'<div style="page-break-after:always"></div>\';\n }\n else out += \'<div style:"padding-top:5px;"></div>\' + t[i].innerHTML;\n }\n }\n out;\n </script>\n\n</div>\n\n<!--Other charges table-->\n<div>\n<table style="width:100%">\n <tr><td style="width:40%"><script>get_buying_costs()</script></td>\n <td style="width:20%"></td><td style="width:40%"><script>get_other_charges()</script></td></tr>\n</table>\n</div>\n<div><script>get_transport_details()</script></div>\n<div><br>Payment Terms</div>\n<div><br><script>replace_newlines(doc.payment_terms)</script></div>\n<div><br>For NCSCI</div>\n<div><br><br>(Authorised Signatory)</div>\n</div></body>\n</html>',
'module': 'Stock',
'name': '__common__',
'standard': 'Yes'
diff --git a/erpnext/stock/doctype/bin/bin.py b/erpnext/stock/doctype/bin/bin.py
index cf9509a..881a176 100644
--- a/erpnext/stock/doctype/bin/bin.py
+++ b/erpnext/stock/doctype/bin/bin.py
@@ -11,8 +11,8 @@
set = webnotes.conn.set
sql = webnotes.conn.sql
get_value = webnotes.conn.get_value
-in_transaction = webnotes.conn.in_transaction
-convert_to_lists = webnotes.conn.convert_to_lists
+
+
# -----------------------------------------------------------------------------------------
@@ -25,9 +25,9 @@
# -------------
# stock update
# -------------
- def update_stock(self, actual_qty=0, reserved_qty=0, ordered_qty=0, indented_qty=0, planned_qty=0, dt=None, sle_id='', posting_time='', serial_no = '', is_cancelled = 'No'):
-
- if not dt: dt = nowdate()
+ def update_stock(self, actual_qty=0, reserved_qty=0, ordered_qty=0, indented_qty=0, planned_qty=0, dt=None, sle_id='', posting_time='', serial_no = '', is_cancelled = 'No',doc_type='',doc_name='',is_amended='No'):
+ if not dt:
+ dt = nowdate()
# update the stock values (for current quantities)
self.doc.actual_qty = flt(self.doc.actual_qty) + flt(actual_qty)
self.doc.ordered_qty = flt(self.doc.ordered_qty) + flt(ordered_qty)
@@ -35,23 +35,17 @@
self.doc.indented_qty = flt(self.doc.indented_qty) + flt(indented_qty)
self.doc.planned_qty = flt(self.doc.planned_qty) + flt(planned_qty)
self.doc.projected_qty = flt(self.doc.actual_qty) + flt(self.doc.ordered_qty) + flt(self.doc.indented_qty) + flt(self.doc.planned_qty) - flt(self.doc.reserved_qty)
-
self.doc.save()
-
+ if(( flt(actual_qty)<0 or flt(reserved_qty)>0 )and is_cancelled == 'No' and is_amended=='No'):
+ self.reorder_item(doc_type,doc_name)
- # update valuation for post dated entry
if actual_qty:
# check actual qty with total number of serial no
if serial_no:
self.check_qty_with_serial_no()
-
- prev_sle = self.get_prev_sle(dt, posting_time, sle_id)
- cqty = flt(prev_sle.get('bin_aqat', 0))
- # Block if actual qty becomes negative
- if (flt(cqty) + flt(actual_qty)) < 0 and flt(actual_qty) < 0 and is_cancelled == 'No':
- msgprint('Not enough quantity (requested: %s, current: %s) for Item <b>%s</b> in Warehouse <b>%s</b> as on %s %s' % (flt(actual_qty), flt(cqty), self.doc.item_code, self.doc.warehouse, dt, posting_time), raise_exception = 1)
-
- self.update_item_valuation(sle_id, dt, posting_time, serial_no, prev_sle)
+
+ # update valuation and qty after transaction for post dated entry
+ self.update_entries_after(dt, posting_time)
def check_qty_with_serial_no(self):
"""
@@ -59,11 +53,19 @@
Temporary validation added on: 18-07-2011
"""
if sql("select name from `tabItem` where ifnull(has_serial_no, 'No') = 'Yes' and name = '%s'" % self.doc.item_code):
- sr_count = sql("select count(name) from `tabSerial No` where item_code = '%s' and warehouse = '%s' and status ='In Store' and docstatus != 2" % (self.doc.item_code, self.doc.warehouse))[0][0]
+ sr_count = sql("""select count(name) from `tabSerial No`
+ where item_code = '%s' and warehouse = '%s'
+ and status ='In Store' and docstatus != 2
+ """ % (self.doc.item_code, self.doc.warehouse))[0][0]
+
if sr_count != self.doc.actual_qty:
- msg = "Actual Qty(%s) in Bin is mismatched with total number(%s) of serial no in store for item: '%s' and warehouse: '%s'" % (self.doc.actual_qty, sr_count, self.doc.item_code, self.doc.warehouse)
+ msg = """Actual Qty(%s) in Bin is mismatched with total number(%s) of serial no in store
+ for item: '%s' and warehouse: '%s'""" % \
+ (self.doc.actual_qty, sr_count, self.doc.item_code, self.doc.warehouse)
+
if getattr(webnotes.defs,'admin_email_notification',1):
- sendmail(['developers@iwebnotes.com'], sender='automail@webnotestech.com', subject='Serial No Count vs Bin Actual Qty', parts=[['text/plain', msg]])
+ sendmail(['developers@iwebnotes.com'], sender='automail@webnotestech.com', \
+ subject='Serial No Count vs Bin Actual Qty', parts=[['text/plain', msg]])
msgprint(msg, raise_exception=1)
# --------------------------------
@@ -81,29 +83,19 @@
""", (self.doc.item_code, self.doc.warehouse), as_dict=1)
return sle and sle[0] or None
- # --------------------------------
- # get previous stock ledger entry
- # --------------------------------
-
- def get_prev_sle(self, posting_date, posting_time, sle_id = ''):
- # this function will only be called for a live entry
- # for which the "name" will be the latest (even for the same timestamp)
- # and even for a back-dated entry
- # hence there cannot be any "backdated entries" with a name greater than the
- # current one
+ def get_prev_sle(self, posting_date = '1900-01-01', posting_time = '12:00', sle_id = ''):
+ """
+ get the last sle on or before the current time-bucket,
+ to get actual qty before transaction, this function
+ is called from various transaction like stock entry, reco etc
+ """
- # if there are multiple entries on this timestamp, then the last one will be with
- # the last "name"
- # else, the last entry will be the highest name at the previous timestamp
- # hence, the double sort on timestamp and name should be sufficient condition
- # to get the last sle
-
sle = sql("""
select * from `tabStock Ledger Entry`
where item_code = %s
and warehouse = %s
- and name != %s
and ifnull(is_cancelled, 'No') = 'No'
+ and name != %s
and timestamp(posting_date, posting_time) <= timestamp(%s, %s)
order by timestamp(posting_date, posting_time) desc, name desc
limit 1
@@ -112,30 +104,56 @@
return sle and sle[0] or {}
+ def get_sle_prev_timebucket(self, posting_date = '1900-01-01', posting_time = '12:00'):
+ """get previous stock ledger entry before current time-bucket"""
+ # get the last sle before the current time-bucket, so that all values
+ # are reposted from the current time-bucket onwards.
+ # this is necessary because at the time of cancellation, there may be
+ # entries between the cancelled entries in the same time-bucket
+
+ sle = sql("""
+ select * from `tabStock Ledger Entry`
+ where item_code = %s
+ and warehouse = %s
+ and ifnull(is_cancelled, 'No') = 'No'
+ and timestamp(posting_date, posting_time) < timestamp(%s, %s)
+ order by timestamp(posting_date, posting_time) desc, name desc
+ limit 1
+ """, (self.doc.item_code, self.doc.warehouse, posting_date, posting_time), as_dict=1)
+
+ return sle and sle[0] or {}
- # --------------------------------------------------------------------------------------------------------------------------------------
- # validate negative stock (validate if stock is going -ve in between for back dated entries will consider only is_cancel = 'No' entries)
- # --------------------------------------------------------------------------------------------------------------------------------------
+ #-------------------------------------------------------------
def validate_negative_stock(self, cqty, s):
- if cqty + s['actual_qty'] < 0 and s['is_cancelled'] != 'Yes':
- msgprint(cqty)
- msgprint(s['actual_qty'])
- msgprint('Cannot complete this transaction because stock will become negative in future transaction for Item <b>%s</b> in Warehouse <b>%s</b> on <b>%s %s</b>' % \
- (self.doc.item_code, self.doc.warehouse, s['posting_date'], s['posting_time']))
- raise Exception
+ """
+ validate negative stock for entries current datetime onwards
+ will not consider cancelled entries
+ """
+ diff = cqty + s['actual_qty']
+ if diff < 0 and (abs(diff) > 0.0001) and s['is_cancelled'] == 'No':
+ msgprint("""
+ Negative stock error:
+ Cannot complete this transaction because stock will
+ become negative (%s) for Item <b>%s</b> in Warehouse
+ <b>%s</b> on <b>%s %s</b> in Transaction %s %s""" % \
+ (str(diff), self.doc.item_code, self.doc.warehouse, \
+ s['posting_date'], s['posting_time'], s['voucher_type'], s['voucher_no']), \
+ raise_exception=1)
- # ------------------------------------
- # get serialized inventory values
+
# ------------------------------------
def get_serialized_inventory_values(self, val_rate, in_rate, opening_qty, actual_qty, is_cancelled, serial_nos):
+ """
+ get serialized inventory values
+ """
if flt(in_rate) < 0: # wrong incoming rate
in_rate = val_rate
elif flt(in_rate) == 0: # In case of delivery/stock issue, get average purchase rate of serial nos of current entry
in_rate = flt(sql("select ifnull(avg(purchase_rate), 0) from `tabSerial No` where name in (%s)" % (serial_nos))[0][0])
if in_rate and val_rate == 0: # First entry
- val_rate = in_rate
+ val_rate = in_rate
# val_rate is same as previous entry if val_rate is negative
# Otherwise it will be calculated as per moving average
elif opening_qty + actual_qty > 0 and ((opening_qty * val_rate) + (actual_qty * in_rate)) > 0:
@@ -220,11 +238,16 @@
stock_val = sum([flt(d[0])*flt(d[1]) for d in self.fcfs_bal])
return stock_val
- # ----------------------
- # update item valuation
- # ----------------------
- def update_item_valuation(self, sle_id=None, posting_date=None, posting_time=None, serial_no=None, prev_sle=None):
- # no sle given, start from the first one (for repost)
+ def update_entries_after(self, posting_date, posting_time):
+ """
+ update valution rate and qty after transaction
+ from the current time-bucket onwards
+ """
+
+ # Get prev sle
+ prev_sle = self.get_sle_prev_timebucket(posting_date, posting_time)
+
+ # if no prev sle, start from the first one (for repost)
if not prev_sle:
cqty, cval, val_rate, self.fcfs_bal = 0, 0, 0, []
@@ -235,11 +258,11 @@
val_rate = flt(prev_sle.get('valuation_rate', 0))
self.fcfs_bal = eval(prev_sle.get('fcfs_stack', '[]') or '[]')
- val_method = get_obj('Valuation Control').get_valuation_method(self.doc.item_code) # get valuation method
+ # get valuation method
+ val_method = get_obj('Valuation Control').get_valuation_method(self.doc.item_code)
# recalculate the balances for all stock ledger entries
- # after this one (so that the corrected balance will reflect
- # correctly in all entries after this one)
+ # after the prev sle
sll = sql("""
select *
from `tabStock Ledger Entry`
@@ -248,30 +271,32 @@
and ifnull(is_cancelled, 'No') = 'No'
and timestamp(posting_date, posting_time) > timestamp(%s, %s)
order by timestamp(posting_date, posting_time) asc, name asc""", \
- (self.doc.item_code, self.doc.warehouse, posting_date, posting_time), as_dict = 1)
+ (self.doc.item_code, self.doc.warehouse, \
+ prev_sle.get('posting_date','1900-01-01'), prev_sle.get('posting_time', '12:00')), as_dict = 1)
- # if in live entry - update the values of the current sle
- if sle_id:
- sll = sql("select * from `tabStock Ledger Entry` where name=%s and ifnull(is_cancelled, 'No') = 'No'", sle_id, as_dict=1) + sll
- for s in sll:
+ for sle in sll:
# block if stock level goes negative on any date
- self.validate_negative_stock(cqty, s)
+ self.validate_negative_stock(cqty, sle)
- stock_val, in_rate = 0, s['incoming_rate'] # IN
- serial_nos = s["serial_no"] and ("'"+"', '".join(cstr(s["serial_no"]).split('\n')) + "'") or ''
+ stock_val, in_rate = 0, sle['incoming_rate'] # IN
+ serial_nos = sle["serial_no"] and ("'"+"', '".join(cstr(sle["serial_no"]).split('\n')) \
+ + "'") or ''
# Get valuation rate
- val_rate, stock_val = self.get_valuation_rate(val_method, serial_nos, val_rate, in_rate, stock_val, cqty, s)
+ val_rate, stock_val = self.get_valuation_rate(val_method, serial_nos, \
+ val_rate, in_rate, stock_val, cqty, sle)
# Qty upto the sle
- cqty += s['actual_qty']
+ cqty += sle['actual_qty']
# Stock Value upto the sle
stock_val = self.get_stock_value(val_method, cqty, stock_val, serial_nos)
- # update current sle --> will it be good to update incoming rate in sle for outgoing stock entry?????
+
+ # update current sle --> will it be good to update incoming rate in sle
+ # for outgoing stock entry?????
sql("""update `tabStock Ledger Entry`
set bin_aqat=%s, valuation_rate=%s, fcfs_stack=%s, stock_value=%s
- where name=%s""", (cqty, flt(val_rate), cstr(self.fcfs_bal), stock_val, s['name']))
+ where name=%s""", (cqty, flt(val_rate), cstr(self.fcfs_bal), stock_val, sle['name']))
# update the bin
if sll:
@@ -281,13 +306,54 @@
# item re-order
# -------------
- def reorder_item(self):
- #check if re-order is required
- projected_qty = flt(self.doc.actual_qty) + flt(self.doc.indented_qty) + flt(self.doc.ordered_qty)
- item_reorder_level = sql("select reorder_level from `%sItem` where name = '%s'" % (self.prefix, self.doc.item_code))[0][0] or 0
- if flt(item_reorder_level) > flt(projected_qty):
- msgprint("Item: " + self.doc.item_code + " is to be re-ordered. Indent raised (Not Implemented).")
-
+ def reorder_item(self,doc_type,doc_name):
+ msgprint(get_value('Manage Account', None, 'auto_indent'))
+ if get_value('Manage Account', None, 'auto_indent'):
+ #check if re-order is required
+ indent_detail_fields = sql("select re_order_level,item_name,description,brand,item_group,lead_time_days,min_order_qty,email_notify from tabItem where item_code = %s",(self.doc.item_code),as_dict=1)
+ i = indent_detail_fields[0]
+ item_reorder_level = i['re_order_level'] or 0
+ if ((flt(item_reorder_level) > flt(self.doc.projected_qty)) and item_reorder_level) :
+ self.reorder_indent(i,item_reorder_level,doc_type,doc_name,email_notify=i['email_notify'])
+
+
+ # Re order Auto Intent Generation
+ def reorder_indent(self,i,item_reorder_level,doc_type,doc_name,email_notify=1):
+ indent = Document('Indent')
+ indent.transaction_date = nowdate()
+ indent.naming_series = 'IDT'
+ indent.company = get_defaults()['company']
+ indent.fiscal_year = get_defaults()['fiscal_year']
+ indent.remark = "This is an auto generated Indent. It was raised because the projected quantity has fallen below the minimum re-order level when %s %s was created"%(doc_type,doc_name)
+ indent.save(1)
+ indent_obj = get_obj('Indent',indent.name,with_children=1)
+ indent_details_child = addchild(indent_obj.doc,'indent_details','Indent Detail',0)
+ indent_details_child.item_code = self.doc.item_code
+ indent_details_child.uom = self.doc.stock_uom
+ indent_details_child.warehouse = self.doc.warehouse
+ indent_details_child.schedule_date= add_days(nowdate(),i['lead_time_days'])
+ indent_details_child.item_name = i['item_name']
+ indent_details_child.description = i['description']
+ indent_details_child.item_group = i['item_group']
+ if (i['min_order_qty'] < ( flt(item_reorder_level)-flt(self.doc.projected_qty) )):
+ indent_details_child.qty =flt(flt(item_reorder_level)-flt(self.doc.projected_qty))
+ else:
+ indent_details_child.qty = i['min_order_qty']
+ indent_details_child.brand = i['brand']
+ indent_details_child.save()
+ indent_obj = get_obj('Indent',indent.name,with_children=1)
+ indent_obj.validate()
+ set(indent_obj.doc,'docstatus',1)
+ indent_obj.on_submit()
+ msgprint("Item: " + self.doc.item_code + " is to be re-ordered. Indent %s raised.Was generated from %s %s"%(indent.name,doc_type, doc_name ))
+ if(email_notify):
+ send_email_notification(doc_type,doc_name)
+
+ def send_email_notification(self,doc_type,doc_name):
+ email_list=[d for d in sql("select parent from tabUserRole where role in ('Purchase Manager','Material Manager') ")]
+ msg1='An Indent has been raised for item %s: %s on %s '%(doc_type, doc_name, nowdate())
+ sendmail(email_list, sender='automail@webnotestech.com', \
+ subject='Auto Indent Generation Notification', parts=[['text/plain',msg1]])
# validate
def validate(self):
self.validate_mandatory()
diff --git a/erpnext/stock/doctype/delivery_note/delivery_note.js b/erpnext/stock/doctype/delivery_note/delivery_note.js
index 823eca4..8f9fa6d 100644
--- a/erpnext/stock/doctype/delivery_note/delivery_note.js
+++ b/erpnext/stock/doctype/delivery_note/delivery_note.js
@@ -15,6 +15,7 @@
if(!doc.transaction_date) set_multiple(dt,dn,{transaction_date:get_today()});
if(!doc.posting_date) set_multiple(dt,dn,{posting_date:get_today()});
if(doc.__islocal && doc.customer) cur_frm.cscript.pull_item_details_onload(doc,dt,dn);
+ if(!doc.price_list_currency) set_multiple(cdt, cdn, {price_list_currency: doc.currency, plc_conversion_rate: 1});
if(!doc.posting_time) doc.posting_time = wn.datetime.get_cur_time()
diff --git a/erpnext/stock/doctype/delivery_note/delivery_note.py b/erpnext/stock/doctype/delivery_note/delivery_note.py
index b49f80c..93f72df 100644
--- a/erpnext/stock/doctype/delivery_note/delivery_note.py
+++ b/erpnext/stock/doctype/delivery_note/delivery_note.py
@@ -374,8 +374,7 @@
# if prevdoc_doctype = "Sales Order"
if d[3] < 0 :
# Reduce Reserved Qty from warehouse
- bin = get_obj('Warehouse', d[0]).update_bin(0, flt(update_stock) * flt(d[3]), 0, 0, 0, d[1], self.doc.transaction_date)
-
+ bin = get_obj('Warehouse', d[0]).update_bin(0, flt(update_stock) * flt(d[3]), 0, 0, 0, d[1], self.doc.transaction_date,doc_type=self.doc.doctype,doc_name=self.doc.name, is_amended = (self.doc.amended_from and 'Yes' or 'No'))
# Reduce actual qty from warehouse
self.make_sl_entry(d, d[0], - flt(d[2]) , 0, update_stock)
get_obj('Stock Ledger', 'Stock Ledger').update_stock(self.values)
@@ -443,33 +442,80 @@
# ==========================================
def update_pack_nett_weight(self):
for d in getlist(self.doclist, 'delivery_note_details'):
- if d.item_code:
+ if d.item_code and not d.pack_nett_wt:
item_wt = sql("select nett_weight from `tabItem` where name = %s", (d.item_code))
d.pack_nett_wt = item_wt and flt(item_wt[0][0]) or 0
- # ==========================================
- def print_packing_slip(self):
- prev_pack='0'
- sno=0
- html=''
- tot_nett_wt,tot_gross_wt=0,0
- for d in getlist(self.doclist, 'delivery_note_details'):
- sno=sno+1
- if sno!=1 and prev_pack!=d.pack_no:#Footer goes here
- html+='</table><table style="page-break-after:always" width="100%"><tr><td>CASE NO</td><td>'+cstr(d.pack_no)+'</td><td>NETT WT</td><td>'+cstr(tot_nett_wt)+'</td><td>CHECKED BY</td><td></td></tr><tr><td>SIZE</td><td></td><td>GROSS WT</td><td>'+cstr(tot_gross_wt)+'</td><td>PACKED BY</td><td></td></tr></table></div>'
- if prev_pack!=d.pack_no: #Prepare Header Here
- #Header code goes here
- html+='<div align="center">[HEADER GOES HERE]</div><div><center><h2>Packing Slip</h2></center></div> <table width="100%"><tr><td width="15%">Order No.</td><td width="35%">'+cstr(self.doc.sales_order_no)+'</td><td width="15%">Shipping Marks</td><td>'+cstr(d.shipping_mark)+'</td></tr></table>'
- html+='<table class="cust_tbl" width="100%"><tr><td>S.NO.</td><td>QUANTITY</td><td>CS.NO.</td><td>DESCRIPTION</td><td>WEIGHT</td><tr>'
- sno=0
- tot_nett_wt,to_gross_wt=flt(d.pack_nett_wt),flt(d.pack_gross_wt)
- #Body code goes here
- html+='<tr><td>'+cstr(sno+1)+'</td><td>'+cstr(d.qty)+'</td><td>'+d.item_code+'</td><td>'+d.description+'</td><td>'+cstr(d.pack_nett_wt)+'</td></tr>'
- prev_pack=d.pack_no
- tot_nett_wt+=flt(d.pack_nett_wt)
- tot_gross_wt+=flt(d.pack_gross_wt)
- if html!='':
- html+='</table><table style="page-break-after:always" width="100%"><tr><td>CASE NO</td><td>'+cstr(d.pack_no)+'</td><td>NETT WT</td><td>'+cstr(tot_nett_wt)+'</td><td>CHECKED BY</td><td>'+cstr(self.doc.packing_checked_by)+'</td></tr><tr><td>SIZE</td><td>'+cstr(self.doc.pack_size)+'</td><td>GROSS WT</td><td>'+cstr(tot_gross_wt)+'</td><td>PACKED BY</td><td>'+cstr(self.doc.packed_by)+'</td></tr></table></div>'
- html+='</html>'
+ # ==========================================
+ def get_header(self, so_no, shipping_mark):
+ header = '''
+ <div align="center">[HEADER GOES HERE]</div>
+ <div><center><h2>Packing Slip</h2></center></div>
+ <table width="100%" class="large_font">
+ <tr>
+ <td width="20%">ORDER NO.</td>
+ <td width="30%">'''+cstr(so_no)+'''</td>
+ <td width="20%">SHIPPING MARKS</td>
+ <td width="30%">'''+cstr(shipping_mark)+'''</td>
+ </tr>
+ </table>''';
+
+ return header
+
+ def get_footer(self, row, tot_nett, tot_gross):
+ footer = '''
+ <table style="page-break-after:always" width="100%" class="large_font">
+ <tr>
+ <td>CASE NO</td><td>'''+cstr(row.pack_no)+'''</td>
+ <td>NETT WT</td><td>'''+cstr(tot_nett)+'''</td>
+ <td>CHECKED BY</td><td>'''+cstr(row.packing_checked_by)+'''</td>
+ </tr>
+ <tr>
+ <td>SIZE</td><td>'''+cstr(row.pack_size)+'''</td>
+ <td>GROSS WT</td><td>'''+cstr(tot_gross)+'''</td>
+ <td>PACKED BY</td><td>'''+cstr(row.packed_by)+'''</td>
+ </tr>
+ </table>'''
+
+ return footer
+
+ def print_packing_slip(self):
+ plist = {}
+ for d in getlist(self.doclist, 'delivery_note_details'):
+ if not plist.has_key(cstr(d.pack_no)):
+ plist[cstr(d.pack_no)] = [d]
+ else:
+ plist.get(cstr(d.pack_no)).append(d)
+
+ html=''
+
+ for d in sorted(plist.keys()):
+ tot_nett_wt,tot_gross_wt=0,0
+
+ # header
+ html += self.get_header(self.doc.sales_order_no, self.doc.shipping_mark)
+
+ # item table header
+ html += '''
+ <table class="cust_tbl" width="100%">
+ <tr>
+ <td><b>SR.NO.</b></td><td><b>CS.NO.</b></td><td><b>DESCRIPTION</b></td>
+ <td><b>QUANTITY</b></td><td><b>WEIGHT</b></td>
+ </tr>'''
+
+ # item table data
+ sr_no = 1
+ for r in plist.get(d):
+ html += '<tr><td>'+cstr(sr_no)+'</td><td>'+r.item_code+'</td><td>'+r.description+'</td><td>'+cstr(r.qty)+'</td><td>'+cstr(r.pack_nett_wt)+'</td></tr>'
+
+ tot_nett_wt += flt(r.pack_nett_wt)
+ tot_gross_wt += flt(r.pack_gross_wt)
+
+ sr_no += 1
+
+ html += '</table>'
+
+ # footer
+ html += self.get_footer(r, tot_nett_wt, tot_gross_wt)
self.doc.print_packing_slip=html
diff --git a/erpnext/stock/doctype/delivery_note/delivery_note.txt b/erpnext/stock/doctype/delivery_note/delivery_note.txt
index 9fe13e4..5340955 100644
--- a/erpnext/stock/doctype/delivery_note/delivery_note.txt
+++ b/erpnext/stock/doctype/delivery_note/delivery_note.txt
@@ -5,7 +5,7 @@
{
'creation': '2011-04-18 15:58:20',
'docstatus': 0,
- 'modified': '2011-09-20 18:50:41',
+ 'modified': '2011-12-22 19:03:44',
'modified_by': 'Administrator',
'owner': 'Administrator'
},
@@ -21,7 +21,7 @@
# These values are common for all DocType
{
- '_last_update': '1315560377',
+ '_last_update': '1324367019',
'colour': 'White:FFF',
'default_print_format': 'Standard',
'doctype': 'DocType',
@@ -37,13 +37,12 @@
'show_in_menu': 0,
'subject': 'To %(customer_name)s on %(transaction_date)s | %(per_billed)s% billed',
'tag_fields': 'billing_status',
- 'version': 453
+ 'version': 460
},
# These values are common for all DocFormat
{
'doctype': 'DocFormat',
- 'format': 'Delivery Note Packing List Wise',
'name': '__common__',
'parent': 'Delivery Note',
'parentfield': 'formats',
@@ -116,9 +115,22 @@
# DocPerm
{
+ 'amend': 1,
+ 'cancel': 1,
+ 'create': 1,
+ 'doctype': 'DocPerm',
+ 'permlevel': 0,
+ 'role': 'Sales Manager',
+ 'submit': 1,
+ 'write': 1
+ },
+
+ # DocPerm
+ {
'doctype': 'DocPerm',
'permlevel': 1,
- 'role': 'All'
+ 'role': 'All',
+ 'write': 0
},
# DocPerm
@@ -130,7 +142,26 @@
# DocFormat
{
- 'doctype': 'DocFormat'
+ 'doctype': 'DocFormat',
+ 'format': 'Delivery Note Packing List Wise'
+ },
+
+ # DocFormat
+ {
+ 'doctype': 'DocFormat',
+ 'format': 'Delivery Note Classic'
+ },
+
+ # DocFormat
+ {
+ 'doctype': 'DocFormat',
+ 'format': 'Delivery Note Modern'
+ },
+
+ # DocFormat
+ {
+ 'doctype': 'DocFormat',
+ 'format': 'Delivery Note Spartan'
},
# DocField
@@ -530,34 +561,6 @@
# DocField
{
'colour': 'White:FFF',
- 'description': 'You can make a delivery note from multiple sales orders. Select sales orders one by one and click on the button below.',
- 'doctype': 'DocField',
- 'fieldname': 'sales_order_no',
- 'fieldtype': 'Link',
- 'label': 'Sales Order No',
- 'no_copy': 0,
- 'oldfieldname': 'sales_order_no',
- 'oldfieldtype': 'Link',
- 'options': 'Sales Order',
- 'permlevel': 0,
- 'print_hide': 0
- },
-
- # DocField
- {
- 'doctype': 'DocField',
- 'fieldtype': 'Button',
- 'hidden': 0,
- 'label': 'Get Items',
- 'oldfieldtype': 'Button',
- 'options': 'pull_sales_order_details',
- 'permlevel': 0,
- 'print_hide': 1
- },
-
- # DocField
- {
- 'colour': 'White:FFF',
'description': 'Select the price list as entered in "Price List" master. This will pull the reference rates of items against this price list as specified in "Item" master.',
'doctype': 'DocField',
'fieldname': 'price_list_name',
@@ -574,6 +577,33 @@
# DocField
{
+ 'colour': 'White:FFF',
+ 'description': 'Select the currency in which price list is maintained',
+ 'doctype': 'DocField',
+ 'fieldname': 'price_list_currency',
+ 'fieldtype': 'Select',
+ 'label': 'Price List Currency',
+ 'options': 'link:Currency',
+ 'permlevel': 0,
+ 'print_hide': 1,
+ 'reqd': 1
+ },
+
+ # DocField
+ {
+ 'colour': 'White:FFF',
+ 'description': 'Rate at which Price list currency is converted to your currency',
+ 'doctype': 'DocField',
+ 'fieldname': 'plc_conversion_rate',
+ 'fieldtype': 'Currency',
+ 'label': 'Price List Currency Conversion Rate',
+ 'permlevel': 0,
+ 'print_hide': 1,
+ 'reqd': 1
+ },
+
+ # DocField
+ {
'doctype': 'DocField',
'fieldtype': 'Column Break',
'permlevel': 0,
@@ -615,6 +645,34 @@
# DocField
{
+ 'colour': 'White:FFF',
+ 'description': 'You can make a delivery note from multiple sales orders. Select sales orders one by one and click on the button below.',
+ 'doctype': 'DocField',
+ 'fieldname': 'sales_order_no',
+ 'fieldtype': 'Link',
+ 'label': 'Sales Order No',
+ 'no_copy': 0,
+ 'oldfieldname': 'sales_order_no',
+ 'oldfieldtype': 'Link',
+ 'options': 'Sales Order',
+ 'permlevel': 0,
+ 'print_hide': 0
+ },
+
+ # DocField
+ {
+ 'doctype': 'DocField',
+ 'fieldtype': 'Button',
+ 'hidden': 0,
+ 'label': 'Get Items',
+ 'oldfieldtype': 'Button',
+ 'options': 'pull_sales_order_details',
+ 'permlevel': 0,
+ 'print_hide': 1
+ },
+
+ # DocField
+ {
'doctype': 'DocField',
'fieldtype': 'Section Break',
'permlevel': 0
@@ -622,6 +680,7 @@
# DocField
{
+ 'allow_on_submit': 1,
'doctype': 'DocField',
'fieldname': 'delivery_note_details',
'fieldtype': 'Table',
diff --git a/erpnext/stock/doctype/delivery_note_detail/delivery_note_detail.txt b/erpnext/stock/doctype/delivery_note_detail/delivery_note_detail.txt
index be7b98f..806803f 100644
--- a/erpnext/stock/doctype/delivery_note_detail/delivery_note_detail.txt
+++ b/erpnext/stock/doctype/delivery_note_detail/delivery_note_detail.txt
@@ -5,15 +5,17 @@
{
'creation': '2010-08-08 17:08:58',
'docstatus': 0,
- 'modified': '2011-09-07 17:34:13',
+ 'modified': '2011-10-18 16:32:44',
'modified_by': 'Administrator',
'owner': 'Administrator'
},
# These values are common for all DocType
{
+ '_last_update': '1311621379',
'autoname': 'DND/.#######',
'colour': 'White:FFF',
+ 'default_print_format': 'Standard',
'doctype': 'DocType',
'istable': 1,
'module': 'Stock',
@@ -21,7 +23,7 @@
'section_style': 'Tray',
'server_code_error': ' ',
'show_in_menu': 0,
- 'version': 40
+ 'version': 43
},
# These values are common for all DocField
@@ -357,6 +359,37 @@
# DocField
{
'doctype': 'DocField',
+ 'fieldname': 'pack_size',
+ 'fieldtype': 'Data',
+ 'label': 'Pack Size',
+ 'no_copy': 0,
+ 'permlevel': 0,
+ 'print_hide': 1
+ },
+
+ # DocField
+ {
+ 'doctype': 'DocField',
+ 'fieldname': 'packed_by',
+ 'fieldtype': 'Data',
+ 'label': 'Packed By',
+ 'permlevel': 0,
+ 'print_hide': 1
+ },
+
+ # DocField
+ {
+ 'doctype': 'DocField',
+ 'fieldname': 'packing_checked_by',
+ 'fieldtype': 'Data',
+ 'label': 'Packing Checked By',
+ 'permlevel': 0,
+ 'print_hide': 1
+ },
+
+ # DocField
+ {
+ 'doctype': 'DocField',
'fieldname': 'installed_qty',
'fieldtype': 'Currency',
'label': 'Installed Qty',
diff --git a/erpnext/stock/doctype/item/item.txt b/erpnext/stock/doctype/item/item.txt
index 0d20f7b..c670700 100644
--- a/erpnext/stock/doctype/item/item.txt
+++ b/erpnext/stock/doctype/item/item.txt
@@ -5,18 +5,19 @@
{
'creation': '2010-08-08 17:09:05',
'docstatus': 0,
- 'modified': '2011-08-18 13:03:31',
+ 'modified': '2011-12-20 11:15:42',
'modified_by': 'Administrator',
'owner': 'Administrator'
},
# These values are common for all DocType
{
- '_last_update': '1313651083',
+ '_last_update': '1323333040',
'allow_attach': 1,
'allow_trash': 1,
'autoname': 'field:item_code',
'colour': 'White:FFF',
+ 'default_print_format': 'Standard',
'doctype': 'DocType',
'document_type': 'Master',
'max_attachments': 1,
@@ -28,7 +29,7 @@
'show_in_menu': 0,
'subject': '%(item_name)s',
'tag_fields': 'item_group',
- 'version': 161
+ 'version': 162
},
# These values are common for all DocField
@@ -62,7 +63,6 @@
'cancel': 0,
'create': 0,
'doctype': 'DocPerm',
- 'idx': 1,
'permlevel': 1,
'role': 'Material Manager',
'submit': 0,
@@ -75,7 +75,6 @@
'cancel': 0,
'create': 0,
'doctype': 'DocPerm',
- 'idx': 2,
'permlevel': 0,
'role': 'Material Manager',
'submit': 0,
@@ -88,7 +87,6 @@
'cancel': 0,
'create': 0,
'doctype': 'DocPerm',
- 'idx': 3,
'permlevel': 1,
'role': 'Material User',
'submit': 0,
@@ -101,7 +99,6 @@
'cancel': 0,
'create': 0,
'doctype': 'DocPerm',
- 'idx': 4,
'permlevel': 0,
'role': 'Material User',
'submit': 0,
@@ -113,7 +110,6 @@
'cancel': 1,
'create': 1,
'doctype': 'DocPerm',
- 'idx': 5,
'permlevel': 0,
'role': 'Material Master Manager',
'write': 1
@@ -123,7 +119,6 @@
{
'create': 0,
'doctype': 'DocPerm',
- 'idx': 6,
'permlevel': 1,
'role': 'Material Master Manager',
'write': 0
@@ -134,7 +129,6 @@
'cancel': 1,
'create': 1,
'doctype': 'DocPerm',
- 'idx': 7,
'permlevel': 0,
'role': 'System Manager',
'write': 1
@@ -143,7 +137,6 @@
# DocPerm
{
'doctype': 'DocPerm',
- 'idx': 8,
'permlevel': 1,
'role': 'System Manager'
},
@@ -152,7 +145,6 @@
{
'doctype': 'DocField',
'fieldtype': 'Section Break',
- 'idx': 1,
'label': 'Item',
'no_copy': 0,
'oldfieldtype': 'Section Break',
@@ -164,7 +156,6 @@
'doctype': 'DocField',
'fieldname': 'trash_reason',
'fieldtype': 'Small Text',
- 'idx': 2,
'label': 'Trash Reason',
'oldfieldname': 'trash_reason',
'oldfieldtype': 'Small Text',
@@ -178,7 +169,6 @@
'doctype': 'DocField',
'fieldname': 'item_code',
'fieldtype': 'Data',
- 'idx': 3,
'in_filter': 0,
'label': 'Item Code',
'oldfieldname': 'item_code',
@@ -193,7 +183,6 @@
'doctype': 'DocField',
'fieldname': 'item_name',
'fieldtype': 'Data',
- 'idx': 4,
'in_filter': 1,
'label': 'Item Name',
'oldfieldname': 'item_name',
@@ -210,7 +199,6 @@
'doctype': 'DocField',
'fieldname': 'item_group',
'fieldtype': 'Link',
- 'idx': 5,
'in_filter': 1,
'label': 'Item Group',
'oldfieldname': 'item_group',
@@ -224,7 +212,6 @@
{
'doctype': 'DocField',
'fieldtype': 'HTML',
- 'idx': 6,
'label': 'IGHelp',
'oldfieldtype': 'HTML',
'options': '<a href="javascript:cur_frm.cscript.IGHelp();">To manage Item Group, click here</a>',
@@ -237,7 +224,6 @@
'fieldname': 'brand',
'fieldtype': 'Link',
'hidden': 0,
- 'idx': 7,
'label': 'Brand',
'oldfieldname': 'brand',
'oldfieldtype': 'Link',
@@ -251,7 +237,6 @@
{
'doctype': 'DocField',
'fieldtype': 'Column Break',
- 'idx': 8,
'permlevel': 0
},
@@ -260,7 +245,6 @@
'doctype': 'DocField',
'fieldname': 'description',
'fieldtype': 'Text',
- 'idx': 9,
'in_filter': 0,
'label': 'Description',
'oldfieldname': 'description',
@@ -276,7 +260,6 @@
'doctype': 'DocField',
'fieldname': 'description_html',
'fieldtype': 'Text',
- 'idx': 10,
'label': 'Description HTML',
'permlevel': 0
},
@@ -287,7 +270,6 @@
'description': 'Generates HTML to include image (1st attachment) in the description',
'doctype': 'DocField',
'fieldtype': 'Button',
- 'idx': 11,
'label': 'Add Image',
'permlevel': 0
},
@@ -296,7 +278,6 @@
{
'doctype': 'DocField',
'fieldtype': 'Section Break',
- 'idx': 12,
'label': 'Inventory',
'oldfieldtype': 'Section Break',
'permlevel': 0
@@ -309,7 +290,6 @@
'doctype': 'DocField',
'fieldname': 'stock_uom',
'fieldtype': 'Link',
- 'idx': 13,
'label': 'Default UoM',
'oldfieldname': 'stock_uom',
'oldfieldtype': 'Link',
@@ -326,7 +306,6 @@
'doctype': 'DocField',
'fieldname': 'is_stock_item',
'fieldtype': 'Select',
- 'idx': 14,
'label': 'Is Stock Item',
'oldfieldname': 'is_stock_item',
'oldfieldtype': 'Select',
@@ -340,7 +319,6 @@
'doctype': 'DocField',
'fieldname': 'valuation_method',
'fieldtype': 'Select',
- 'idx': 15,
'label': 'Valuation Method',
'oldfieldname': 'valuation_method',
'oldfieldtype': 'Select',
@@ -353,7 +331,6 @@
'doctype': 'DocField',
'fieldname': 'default_warehouse',
'fieldtype': 'Link',
- 'idx': 16,
'label': 'Default Warehouse',
'oldfieldname': 'default_warehouse',
'oldfieldtype': 'Link',
@@ -368,7 +345,6 @@
'doctype': 'DocField',
'fieldname': 'tolerance',
'fieldtype': 'Currency',
- 'idx': 17,
'label': 'Allowance Percent',
'oldfieldname': 'tolerance',
'oldfieldtype': 'Currency',
@@ -380,7 +356,6 @@
'doctype': 'DocField',
'fieldname': 're_order_level',
'fieldtype': 'Currency',
- 'idx': 18,
'label': 'Re-Order Level',
'oldfieldname': 're_order_level',
'oldfieldtype': 'Currency',
@@ -389,18 +364,11 @@
# DocField
{
- 'colour': 'White:FFF',
- 'default': '0.00',
- 'description': 'If stock level for this item has reached the minimum inventory level, system will prompt you to raise an Indent (Purchase Requisition).',
'doctype': 'DocField',
- 'fieldname': 'minimum_inventory_level',
- 'fieldtype': 'Currency',
- 'idx': 19,
- 'label': 'Minimum Inventory Level',
- 'oldfieldname': 'minimum_inventory_level',
- 'oldfieldtype': 'Currency',
- 'permlevel': 0,
- 'reqd': 0
+ 'fieldname': 'email_notify',
+ 'fieldtype': 'Check',
+ 'label': 'Send Email Notification when stock reaches re-order level',
+ 'permlevel': 0
},
# DocField
@@ -412,7 +380,6 @@
'fieldname': 'min_order_qty',
'fieldtype': 'Currency',
'hidden': 0,
- 'idx': 20,
'label': 'Minimum Order Qty',
'oldfieldname': 'min_order_qty',
'oldfieldtype': 'Currency',
@@ -423,7 +390,6 @@
{
'doctype': 'DocField',
'fieldtype': 'Column Break',
- 'idx': 21,
'oldfieldtype': 'Column Break',
'permlevel': 0,
'width': '50%'
@@ -437,7 +403,6 @@
'doctype': 'DocField',
'fieldname': 'is_asset_item',
'fieldtype': 'Select',
- 'idx': 22,
'label': 'Is Asset Item',
'oldfieldname': 'is_asset_item',
'oldfieldtype': 'Select',
@@ -453,7 +418,6 @@
'doctype': 'DocField',
'fieldname': 'has_batch_no',
'fieldtype': 'Select',
- 'idx': 23,
'label': 'Has Batch No',
'oldfieldname': 'has_batch_no',
'oldfieldtype': 'Select',
@@ -470,7 +434,6 @@
'doctype': 'DocField',
'fieldname': 'has_serial_no',
'fieldtype': 'Select',
- 'idx': 24,
'in_filter': 1,
'label': 'Has Serial No',
'oldfieldname': 'has_serial_no',
@@ -485,7 +448,6 @@
'doctype': 'DocField',
'fieldname': 'warranty_period',
'fieldtype': 'Data',
- 'idx': 25,
'label': 'Warranty Period (in days)',
'oldfieldname': 'warranty_period',
'oldfieldtype': 'Data',
@@ -497,7 +459,6 @@
'doctype': 'DocField',
'fieldname': 'end_of_life',
'fieldtype': 'Date',
- 'idx': 26,
'label': 'End of Life',
'oldfieldname': 'end_of_life',
'oldfieldtype': 'Date',
@@ -509,7 +470,6 @@
'doctype': 'DocField',
'fieldname': 'nett_weight',
'fieldtype': 'Float',
- 'idx': 27,
'label': 'Nett Weight',
'permlevel': 0
},
@@ -519,7 +479,6 @@
'doctype': 'DocField',
'fieldname': 'gross_weight',
'fieldtype': 'Float',
- 'idx': 28,
'label': 'Gross Weight',
'permlevel': 0
},
@@ -529,7 +488,6 @@
'doctype': 'DocField',
'fieldname': 'weight_uom',
'fieldtype': 'Link',
- 'idx': 29,
'label': 'Weight UOM',
'options': 'UOM',
'permlevel': 0
@@ -540,7 +498,6 @@
'colour': 'White:FFF',
'doctype': 'DocField',
'fieldtype': 'Section Break',
- 'idx': 30,
'label': 'Purchase Details',
'oldfieldtype': 'Section Break',
'permlevel': 0
@@ -554,7 +511,6 @@
'doctype': 'DocField',
'fieldname': 'is_purchase_item',
'fieldtype': 'Select',
- 'idx': 31,
'label': 'Is Purchase Item',
'oldfieldname': 'is_purchase_item',
'oldfieldtype': 'Select',
@@ -570,7 +526,6 @@
'doctype': 'DocField',
'fieldname': 'lead_time_days',
'fieldtype': 'Int',
- 'idx': 32,
'label': 'Lead Time Days',
'no_copy': 1,
'oldfieldname': 'lead_time_days',
@@ -585,7 +540,6 @@
'doctype': 'DocField',
'fieldname': 'purchase_account',
'fieldtype': 'Link',
- 'idx': 33,
'label': 'Default Expense Account',
'oldfieldname': 'purchase_account',
'oldfieldtype': 'Link',
@@ -601,7 +555,6 @@
'doctype': 'DocField',
'fieldname': 'cost_center',
'fieldtype': 'Link',
- 'idx': 34,
'label': 'Default Cost Center',
'oldfieldname': 'cost_center',
'oldfieldtype': 'Link',
@@ -616,7 +569,6 @@
'doctype': 'DocField',
'fieldname': 'buying_cost',
'fieldtype': 'Currency',
- 'idx': 35,
'label': 'Buying Cost',
'no_copy': 1,
'oldfieldname': 'buying_cost',
@@ -630,7 +582,6 @@
'doctype': 'DocField',
'fieldname': 'last_purchase_rate',
'fieldtype': 'Currency',
- 'idx': 36,
'label': 'Last Purchase Rate',
'no_copy': 1,
'oldfieldname': 'last_purchase_rate',
@@ -643,7 +594,6 @@
'doctype': 'DocField',
'fieldname': 'standard_rate',
'fieldtype': 'Currency',
- 'idx': 37,
'label': 'Standard Rate',
'oldfieldname': 'standard_rate',
'oldfieldtype': 'Currency',
@@ -654,7 +604,6 @@
{
'doctype': 'DocField',
'fieldtype': 'Column Break',
- 'idx': 38,
'oldfieldtype': 'Column Break',
'permlevel': 0,
'width': '50%'
@@ -665,7 +614,6 @@
'doctype': 'DocField',
'fieldname': 'uom_conversion_details',
'fieldtype': 'Table',
- 'idx': 39,
'label': 'UOM Conversion Details',
'oldfieldname': 'uom_conversion_details',
'oldfieldtype': 'Table',
@@ -677,7 +625,6 @@
{
'doctype': 'DocField',
'fieldtype': 'Section Break',
- 'idx': 40,
'label': 'Sales Details',
'oldfieldtype': 'Section Break',
'permlevel': 0
@@ -691,7 +638,6 @@
'doctype': 'DocField',
'fieldname': 'is_sales_item',
'fieldtype': 'Select',
- 'idx': 41,
'in_filter': 1,
'label': 'Is Sales Item',
'oldfieldname': 'is_sales_item',
@@ -709,7 +655,6 @@
'doctype': 'DocField',
'fieldname': 'is_service_item',
'fieldtype': 'Select',
- 'idx': 42,
'in_filter': 1,
'label': 'Is Service Item',
'oldfieldname': 'is_service_item',
@@ -727,7 +672,6 @@
'doctype': 'DocField',
'fieldname': 'is_sample_item',
'fieldtype': 'Select',
- 'idx': 43,
'label': 'Allow Samples',
'oldfieldname': 'is_sample_item',
'oldfieldtype': 'Select',
@@ -741,7 +685,6 @@
'doctype': 'DocField',
'fieldname': 'max_discount',
'fieldtype': 'Currency',
- 'idx': 44,
'label': 'Max Discount (%)',
'oldfieldname': 'max_discount',
'oldfieldtype': 'Currency',
@@ -753,7 +696,6 @@
'doctype': 'DocField',
'fieldname': 'default_income_account',
'fieldtype': 'Link',
- 'idx': 45,
'label': 'Default Income Account',
'options': 'Account',
'permlevel': 0
@@ -764,7 +706,6 @@
'doctype': 'DocField',
'fieldname': 'default_sales_cost_center',
'fieldtype': 'Link',
- 'idx': 46,
'label': 'Cost Center',
'options': 'Cost Center',
'permlevel': 0
@@ -776,7 +717,6 @@
'fieldname': 'sales_rate',
'fieldtype': 'Currency',
'hidden': 1,
- 'idx': 47,
'label': 'Sales Rate',
'oldfieldname': 'sales_rate',
'oldfieldtype': 'Currency',
@@ -787,7 +727,6 @@
{
'doctype': 'DocField',
'fieldtype': 'Column Break',
- 'idx': 48,
'oldfieldtype': 'Column Break',
'permlevel': 0,
'width': '50%'
@@ -800,7 +739,6 @@
'doctype': 'DocField',
'fieldname': 'ref_rate_details',
'fieldtype': 'Table',
- 'idx': 49,
'label': 'Ref Rate Details',
'oldfieldname': 'ref_rate_details',
'oldfieldtype': 'Table',
@@ -814,7 +752,6 @@
'doctype': 'DocField',
'fieldname': 'item_customer_details',
'fieldtype': 'Table',
- 'idx': 50,
'label': 'Customer Codes',
'options': 'Item Customer Detail',
'permlevel': 0
@@ -824,7 +761,6 @@
{
'doctype': 'DocField',
'fieldtype': 'Section Break',
- 'idx': 51,
'label': 'Item Tax',
'oldfieldtype': 'Section Break',
'permlevel': 0
@@ -835,7 +771,6 @@
'doctype': 'DocField',
'fieldname': 'item_tax',
'fieldtype': 'Table',
- 'idx': 52,
'label': 'Item Tax1',
'oldfieldname': 'item_tax',
'oldfieldtype': 'Table',
@@ -847,7 +782,6 @@
{
'doctype': 'DocField',
'fieldtype': 'Section Break',
- 'idx': 53,
'label': 'Inspection Criteria',
'oldfieldtype': 'Section Break',
'permlevel': 0
@@ -859,7 +793,6 @@
'doctype': 'DocField',
'fieldname': 'inspection_required',
'fieldtype': 'Select',
- 'idx': 54,
'label': 'Inspection Required',
'no_copy': 0,
'oldfieldname': 'inspection_required',
@@ -874,7 +807,6 @@
'doctype': 'DocField',
'fieldname': 'item_specification_details',
'fieldtype': 'Table',
- 'idx': 55,
'label': 'Item Specification Detail',
'oldfieldname': 'item_specification_details',
'oldfieldtype': 'Table',
@@ -886,7 +818,6 @@
{
'doctype': 'DocField',
'fieldtype': 'Section Break',
- 'idx': 56,
'label': 'Manufacturing',
'oldfieldtype': 'Section Break',
'permlevel': 0
@@ -900,7 +831,6 @@
'doctype': 'DocField',
'fieldname': 'is_manufactured_item',
'fieldtype': 'Select',
- 'idx': 57,
'label': 'Allow Bill of Materials',
'oldfieldname': 'is_manufactured_item',
'oldfieldtype': 'Select',
@@ -915,7 +845,6 @@
'doctype': 'DocField',
'fieldname': 'default_bom',
'fieldtype': 'Link',
- 'idx': 58,
'label': 'Default BOM',
'no_copy': 1,
'oldfieldname': 'default_bom',
@@ -932,7 +861,6 @@
'doctype': 'DocField',
'fieldname': 'is_pro_applicable',
'fieldtype': 'Select',
- 'idx': 59,
'label': 'Allow Production Order',
'oldfieldname': 'is_pro_applicable',
'oldfieldtype': 'Select',
@@ -949,7 +877,6 @@
'doctype': 'DocField',
'fieldname': 'is_sub_contracted_item',
'fieldtype': 'Select',
- 'idx': 60,
'label': 'Is Sub Contracted Item',
'oldfieldname': 'is_sub_contracted_item',
'oldfieldtype': 'Select',
@@ -964,8 +891,8 @@
'fieldname': 'file_list',
'fieldtype': 'Text',
'hidden': 1,
- 'idx': 61,
'label': 'File List',
+ 'no_copy': 1,
'permlevel': 0,
'print_hide': 1
},
@@ -976,7 +903,6 @@
'fieldname': 'customer_code',
'fieldtype': 'Data',
'hidden': 1,
- 'idx': 62,
'in_filter': 1,
'label': 'Customer Code',
'no_copy': 1,
diff --git a/erpnext/stock/doctype/landed_cost_wizard/landed_cost_wizard.js b/erpnext/stock/doctype/landed_cost_wizard/landed_cost_wizard.js
index 5209d1a..369fd4d 100644
--- a/erpnext/stock/doctype/landed_cost_wizard/landed_cost_wizard.js
+++ b/erpnext/stock/doctype/landed_cost_wizard/landed_cost_wizard.js
@@ -2,10 +2,7 @@
if(!doc.currency){doc.currency = sys_defaults.currency;}
}
-cur_frm.fields_dict['landed_cost_details'].grid.get_field("account_head").get_query = function(doc,cdt,cdn) {
- return 'SELECT tabAccount.name FROM tabAccount WHERE tabAccount.group_or_ledger="Ledger" AND tabAccount.docstatus != 2 AND tabAccount.account_type = "Chargeable" AND tabAccount.name LIKE "%s"'
-}
cur_frm.fields_dict['landed_cost_details'].grid.get_field("account_head").get_query = function(doc,cdt,cdn) {
- return 'SELECT tabAccount.name FROM tabAccount WHERE tabAccount.group_or_ledger="Ledger" AND tabAccount.docstatus != 2 AND (tabAccount.account_type = "Tax" OR tabAccount.account_type = "Chargeable") AND tabAccount.name LIKE "%s"'
-}
\ No newline at end of file
+ return 'SELECT tabAccount.name FROM tabAccount WHERE tabAccount.group_or_ledger="Ledger" AND tabAccount.docstatus != 2 AND (tabAccount.account_type = "Tax" OR tabAccount.account_type = "Chargeable" or (tabAccount.is_pl_account = "Yes" and tabAccount.debit_or_credit = "Debit")) AND tabAccount.name LIKE "%s"';
+}
diff --git a/erpnext/stock/doctype/landed_cost_wizard/landed_cost_wizard.py b/erpnext/stock/doctype/landed_cost_wizard/landed_cost_wizard.py
index 58ba751..c791e86 100644
--- a/erpnext/stock/doctype/landed_cost_wizard/landed_cost_wizard.py
+++ b/erpnext/stock/doctype/landed_cost_wizard/landed_cost_wizard.py
@@ -1,236 +1,47 @@
-# Please edit this list and import only required elements
import webnotes
+from webnotes.utils import cint, cstr, flt
+from webnotes.model.doc import addchild, getchildren
+from webnotes.model.doclist import getlist
+from webnotes.model.code import get_obj
+from webnotes import msgprint
-from webnotes.utils import add_days, add_months, add_years, cint, cstr, date_diff, default_fields, flt, fmt_money, formatdate, generate_hash, getTraceback, get_defaults, get_first_day, get_last_day, getdate, has_common, month_name, now, nowdate, replace_newlines, sendmail, set_default, str_esc_quote, user_format, validate_email_add
-from webnotes.model import db_exists
-from webnotes.model.doc import Document, addchild, removechild, getchildren, make_autoname, SuperDocType
-from webnotes.model.doclist import getlist, copy_doclist
-from webnotes.model.code import get_obj, get_server_obj, run_server_obj, updatedb, check_syntax
-from webnotes import session, form, is_testing, msgprint, errprint
-
-set = webnotes.conn.set
sql = webnotes.conn.sql
-get_value = webnotes.conn.get_value
-in_transaction = webnotes.conn.in_transaction
-convert_to_lists = webnotes.conn.convert_to_lists
# -----------------------------------------------------------------------------------------
-
class DocType:
def __init__(self, doc, doclist=[]):
self.doc = doc
self.doclist = doclist
+ self.prwise_cost = {}
+
+ def check_mandatory(self):
+ """ Check mandatory fields """
+ if not self.doc.from_pr_date or not self.doc.to_pr_date:
+ msgprint("Please enter From and To PR Date", raise_exception=1)
+
+ if not self.doc.currency:
+ msgprint("Please enter Currency.", raise_exception=1)
+
def get_purchase_receipts(self):
+ """ Get purchase receipts for given period """
+
self.doc.clear_table(self.doclist,'lc_pr_details',1)
- if not self.doc.from_pr_date or not self.doc.to_pr_date:
- msgprint("Please enter From and To PR Date")
- raise Exception
- if not self.doc.currency:
- msgprint("Please enter Currency.")
- raise Exception
- pr = sql("select name from `tabPurchase Receipt` where docstatus = 1 and posting_date >= '%s' and posting_date <= '%s' and currency = '%s' order by name "%(self.doc.from_pr_date,self.doc.to_pr_date,self.doc.currency), as_dict = 1)
+ self.check_mandatory()
+
+ pr = sql("select name from `tabPurchase Receipt` where docstatus = 1 and posting_date >= '%s' and posting_date <= '%s' and currency = '%s' order by name " % (self.doc.from_pr_date, self.doc.to_pr_date, self.doc.currency), as_dict = 1)
if len(pr)>200:
- msgprint("Please enter date of shorter duration as there are too many purchase receipt, hence it cannot be loaded.")
- raise Exception
+ msgprint("Please enter date of shorter duration as there are too many purchase receipt, hence it cannot be loaded.", raise_exception=1)
+
for i in pr:
- if i and i['name']:
- pr_no = addchild(self.doc, 'lc_pr_details', 'LC PR Detail', 1, self.doclist)
- pr_no.purchase_receipt_no = i and i['name'] or ''
- pr_no.save()
+ ch = addchild(self.doc, 'lc_pr_details', 'LC PR Detail', 1, self.doclist)
+ ch.purchase_receipt = i and i['name'] or ''
+ ch.save()
- def update_pr_lc_se(self):
- lst = []
- condition = ' name in('
-
- amt = 0
- for d in getlist(self.doclist, 'lc_pr_details'):
-
- if cint(d.include_in_landed_cost) == 1:
- condition += '"'+d.purchase_receipt_no+'",'
- lst.append(d.purchase_receipt_no)
- condition += '"")'
-
- amount = sql("SELECT SUM(net_total) FROM `tabPurchase Receipt` WHERE docstatus = 1 AND %s"%condition)
- amt = amount and flt(amount[0][0]) or 0
- for lc in getlist(self.doclist, 'landed_cost_details'):
- for name in lst:
- pr_oc_det = sql("select name from `tabPurchase Tax Detail` where parent = %s and category = 'For Valuation' and add_deduct_tax = 'Add' and charge_type = 'Actual' and account_head = %s ",(name, lc.account_head))
- #obj = get_obj('Purchase Receipt', name, with_children = 1)
- if not pr_oc_det:
- obj = get_obj('Purchase Receipt', name, with_children = 1)
- lgth = cint(sql("select count(name) from `tabPurchase Tax Detail` where parent = '%s' "%(name))[0][0])
- pr_oc = addchild(obj.doc, 'purchase_tax_details', 'Purchase Tax Detail', 1)
- pr_oc.category = 'For Valuation'
- pr_oc.add_deduct_tax = 'Add'
- pr_oc.charge_type = 'Actual'
- pr_oc.description = lc.description
- pr_oc.account_head = lc.account_head
- pr_oc.rate = flt(flt(lc.amount) * flt(obj.doc.net_total/ amt))
- pr_oc.tax_amount = flt(flt(lc.amount) * flt(obj.doc.net_total/ amt))
- pr_oc.total = obj.doc.grand_total
- pr_oc.docstatus = 1
- pr_oc.idx = cint(lgth)
- pr_oc.save()
- else:
- obj = get_obj('Purchase Receipt', name)
- sql("update `tabPurchase Tax Detail` set rate = %s, tax_amount = %s where name = %s and parent = %s",(flt(flt(lc.amount) * flt(obj.doc.net_total/ amt)),flt(flt(lc.amount) * flt(obj.doc.net_total/ amt)),pr_oc_det[0][0],name))
-
- self.calc_pr_other_charges(name)
- obj = get_obj('Purchase Receipt', name, with_children = 1)
- for d in getlist(obj.doclist, 'purchase_receipt_details'):
- if flt(d.qty):
- d.valuation_rate = (flt(d.purchase_rate) + (flt(d.rm_supp_cost) / flt(d.qty)) + (flt(d.item_tax_amount)/flt(d.qty))) / flt(d.conversion_factor)
- d.save()
- sql("update `tabStock Ledger Entry` set incoming_rate = '%s' where voucher_detail_no = '%s'"%(flt(d.valuation_rate), d.name))
-
- bin_name = sql("select t1.name, t2.name, t2.posting_date, t2.posting_time from `tabBin` t1, `tabStock Ledger Entry` t2 where t2.voucher_detail_no = '%s' and t2.item_code = t1.item_code and t2.warehouse = t1.warehouse LIMIT 1"%(d.name))
- if bin_name and bin_name[0][0]:
- obj = get_obj('Bin', bin_name[0][0]).update_item_valuation(bin_name[0][1], bin_name[0][2], bin_name[0][3])
-
- # now distribute the taxes among the PRs
- for lc in getlist(self.doclist, 'landed_cost_details'):
- for d in lst:
- pr_id = d.purchase_receipt_no
-
- # load the purchase receipt object
- pr = get_obj('Purchase Receipt', pr_id, with_children = 1)
-
- # get the tax detail (for valuation) in the PR if it exists
- pr_oc_det = sql("select name from `tabPurchase Tax Detail` where parent = %s and category = 'For Valuation' and add_deduct_tax = 'Add' and charge_type = 'Actual' and account_head = %s ",(pr_id, lc.account_head))
-
- # update tax rate and tax amount
- tax_amount = flt(flt(lc.amount) * flt(pr.doc.net_total/ amt))
-
- # for display
- d.net_total = pr.doc.net_total
- d.added_cost = tax_amount
- d.save()
-
- # if not exist, create the tax detail for valuation
- if not pr_oc_det:
- lgth = cint(sql("select count(name) from `tabPurchase Tax Detail` where parent = '%s' "%(pr_id))[0][0])
- pr_oc = addchild(pr.doc, 'purchase_tax_details', 'Purchase Tax Detail', 1)
- pr_oc.category = 'For Valuation'
- pr_oc.add_deduct_tax = 'Add'
- pr_oc.charge_type = 'Actual'
- pr_oc.description = lc.description
- pr_oc.account_head = lc.account_head
- pr_oc.rate = tax_amount
- pr_oc.tax_amount = tax_amount
- pr_oc.total = obj.doc.grand_total
- pr_oc.docstatus = 1
- pr_oc.idx = cint(lgth)
- pr_oc.save()
- else:
- obj = get_obj('Purchase Receipt', name)
- sql("update `tabPurchase Tax Detail` set rate = %s, tax_amount = %s where name = %s and parent = %s", \
- (tax_amount, tax_amount, pr_oc_det[0][0], pr_id))
-
- self.calc_pr_other_charges(name)
-
- # reload - and update the stock entries with the
- # additional valuations
-
- obj = get_obj('Purchase Receipt', name, with_children = 1)
- for d in getlist(obj.doclist, 'purchase_receipt_details'):
- if flt(d.qty):
- d.valuation_rate = (flt(d.purchase_rate) + (flt(d.rm_supp_cost) / flt(d.qty)) + (flt(d.item_tax_amount)/flt(d.qty))) / flt(d.conversion_factor)
- d.save()
- sql("update `tabStock Ledger Entry` set incoming_rate = '%s' where voucher_detail_no = '%s'"%(flt(d.valuation_rate), d.name))
- bin_name = sql("select t1.name, t2.name, t2.posting_date, t2.posting_time from `tabBin` t1, `tabStock Ledger Entry` t2 where t2.voucher_detail_no = '%s' and t2.item_code = t1.item_code and t2.warehouse = t1.warehouse LIMIT 1"%(d.name))
-
- # update valuation of the item
- if bin_name and bin_name[0][0]:
- obj = get_obj('Bin', bin_name[0][0]).update_item_valuation(bin_name[0][1], bin_name[0][2], bin_name[0][3])
-
- def add_deduct_taxes(self, ocd, oc, tax_amount, total_amount, total, prev_total, f=1):
- ocd[oc].total_amount = flt(tax_amount.toFixed(2))
- ocd[oc].total_tax_amount = flt(prev_total.toFixed(2))
- ocd[oc].tax_amount += flt(tax_amount.toFixed(2))
-
- total_amount = flt(ocd[oc].tax_amount)
- total_tax_amount = flt(ocd[oc].total_tax_amount) + (f * flt(total_amount))
-
- if ocd[oc].category != "For Valuation":
- prev_total += f * flt(ocd[oc].total_amount)
- total += f * flt(ocd[oc].tax_amount)
- ocd[oc].total = flt(total) + (f * flt(tax[t].tax_amount))
- else:
- prev_total = prev_total
- ocd[oc].total = flt(total)
- if ocd[oc].category != "For Total":
- item_tax += f * ocd[oc].total_amount
- ocd[oc].save()
-
- return total, prev_total
-
- # calculate the taxes for these PRs
- def calc_pr_other_charges(self, name):
-
- # re-calculate other charges
- obj = get_obj('Purchase Receipt', name, with_children = 1)
- total = 0
- net_total = obj.doc.net_total
-
-
- for prd in getlist(obj.doclist, 'purchase_receipt_details'):
- prev_total, item_tax = flt(prd.amount), 0
- total += flt(flt(prd.qty) * flt(prd.purchase_rate))
-
- check_tax = prd.item_tax_rate and eval(prd.item_tax_rate) or {}
- ocd = getlist(obj.doclist, 'purchase_tax_details')
-
- # calculate tax for other charges
- for oc in range(len(ocd)):
- if check_tax.get(ocd[oc].account_head) and ocd[oc].charge_type != 'Actual':
- rate = check_tax[ocd[oc].account_head]
- else:
- rate = flt(ocd[oc].rate)
-
- tax_amount = self.cal_tax(ocd, prd, rate, net_total, oc)
- if ocd[oc].add_deduct_tax == 'Add':
- add_deduct_taxes(self, ocd, oc, tax_amount, total_amount, total, prev_total, f=1)
-
- elif ocd[oc].add_deduct_tax == 'Deduct':
- add_deduct_taxes(self, ocd, oc, tax_amount, total_amount, total, prev_total, f=-1)
-
- prd.item_tax_amount = flt(item_tax)
- prd.save()
- obj.doc.save()
-
- def cal_tax(self, ocd, prd, rate, net_total, oc):
- tax_amount = 0
- if ocd[oc].charge_type == 'Actual':
- value = flt(flt(rate) / flt(net_total))
- return flt(flt(value) * flt(prd.amount))
-
- elif ocd[oc].charge_type == 'On Net Total':
- return flt(flt(rate) * flt(prd.amount) / 100)
-
- elif ocd[oc].charge_type == 'On Previous Row Amount':
-
- row_no = cstr(ocd[oc].row_id)
- row = (row_no).split("+")
- for r in range(0, len(row.length)):
- id = cint(row[r])
- tax_amount += flt((flt(rate) * flt(ocd[id-1].total_amount) / 100))
- row_id = row_no.find("/")
- if row_id != -1:
- rate = ''
- row = (row_no).split("/")
-
- id1 = cint(row[0])
- id2 = cint(row[1])
- tax_amount = flt(flt(ocd[id1-1].total_amount) / flt(ocd[id2-1].total_amount))
-
- return tax_amount
-
- # get details for landed cost table from master
- # ---------------------------------------------
def get_landed_cost_master_details(self):
+ """ pull details from landed cost master"""
self.doc.clear_table(self.doclist, 'landed_cost_details')
idx = 0
landed_cost = sql("select account_head, description from `tabLanded Cost Master Detail` where parent=%s", (self.doc.landed_cost), as_dict = 1)
@@ -238,3 +49,185 @@
lct = addchild(self.doc, 'landed_cost_details', 'Landed Cost Detail', 1, self.doclist)
lct.account_head = cost['account_head']
lct.description = cost['description']
+
+
+ def get_selected_pr(self):
+ """ Get selected purchase receipt no """
+ self.selected_pr = [d.purchase_receipt for d in getlist(self.doclist, 'lc_pr_details') if d.select_pr]
+ if not self.selected_pr:
+ msgprint("Please select atleast one PR to proceed.", raise_exception=1)
+
+ def validate_selected_pr(self):
+ """Validate selected PR as submitted"""
+ invalid_pr = sql("SELECT name FROM `tabPurchase Receipt` WHERE docstatus != 1 and name in (%s)" % ("'" + "', '".join(self.selected_pr) + "'"))
+ if invalid_pr:
+ msgprint("Selected purchase receipts must be submitted. Following PR are not submitted: %s" % invalid_pr, raise_exception=1)
+
+
+ def get_total_amt(self):
+ """ Get sum of net total of all selected PR"""
+ return sql("SELECT SUM(net_total) FROM `tabPurchase Receipt` WHERE name in (%s)" % ("'" + "', '".join(self.selected_pr) + "'"))[0][0]
+
+
+ def add_charges_in_pr(self):
+ """ Add additional charges in selected pr proportionately"""
+ total_amt = self.get_total_amt()
+
+ for pr in self.selected_pr:
+ pr_obj = get_obj('Purchase Receipt', pr, with_children = 1)
+ cumulative_grand_total = flt(pr_obj.doc.grand_total)
+
+ for lc in getlist(self.doclist, 'landed_cost_details'):
+ amt = flt(lc.amount) * flt(pr_obj.doc.net_total)/ flt(total_amt)
+ self.prwise_cost[pr] = self.prwise_cost.get(pr, 0) + amt
+ cumulative_grand_total += amt
+
+ pr_oc_row = sql("select name from `tabPurchase Tax Detail` where parent = %s and category = 'For Valuation' and add_deduct_tax = 'Add' and charge_type = 'Actual' and account_head = %s",(pr, lc.account_head))
+ if not pr_oc_row: # add if not exists
+ ch = addchild(pr_obj.doc, 'purchase_tax_details', 'Purchase Tax Detail', 1)
+ ch.category = 'For Valuation'
+ ch.add_deduct_tax = 'Add'
+ ch.charge_type = 'Actual'
+ ch.description = lc.description
+ ch.account_head = lc.account_head
+ ch.rate = amt
+ ch.tax_amount = amt
+ ch.total = cumulative_grand_total
+ ch.docstatus = 1
+ ch.idx = 500 # add at the end
+ ch.save(1)
+ else: # overwrite if exists
+ sql("update `tabPurchase Tax Detail` set rate = %s, tax_amount = %s where name = %s and parent = %s ", (amt, amt, pr_oc_row[0][0], pr))
+
+
+ def reset_other_charges(self, pr_obj):
+ """ Reset all calculated values to zero"""
+ for t in getlist(pr_obj.doclist, 'purchase_tax_details'):
+ t.total_tax_amount = 0;
+ t.total_amount = 0;
+ t.tax_amount = 0;
+ t.total = 0;
+ t.save()
+
+
+ def cal_charges_and_item_tax_amt(self):
+ """ Re-calculates other charges values and itemwise tax amount for getting valuation rate"""
+ for pr in self.selected_pr:
+ obj = get_obj('Purchase Receipt', pr, with_children = 1)
+ total = 0
+ self.reset_other_charges(obj)
+
+ for prd in getlist(obj.doclist, 'purchase_receipt_details'):
+ prev_total, item_tax = flt(prd.amount), 0
+ total += flt(prd.qty) * flt(prd.purchase_rate)
+
+ item_tax_rate = prd.item_tax_rate and eval(prd.item_tax_rate) or {}
+
+ ocd = getlist(obj.doclist, 'purchase_tax_details')
+ # calculate tax for other charges
+ for oc in range(len(ocd)):
+ # Get rate : consider if diff for this item
+ if item_tax_rate.get(ocd[oc].account_head) and ocd[oc].charge_type != 'Actual':
+ rate = item_tax_rate[ocd[oc].account_head]
+ else:
+ rate = flt(ocd[oc].rate)
+
+ tax_amount = self.cal_tax(ocd, prd, rate, obj.doc.net_total, oc)
+ total, prev_total, item_tax = self.add_deduct_taxes(ocd, oc, tax_amount, total, prev_total, item_tax)
+
+ prd.item_tax_amount = flt(item_tax)
+ prd.save()
+ obj.doc.save()
+
+
+ def cal_tax(self, ocd, prd, rate, net_total, oc):
+ """ Calculates tax amount for one item"""
+ tax_amount = 0
+ if ocd[oc].charge_type == 'Actual':
+ tax_amount = flt(rate) * flt(prd.amount) / flt(net_total)
+ elif ocd[oc].charge_type == 'On Net Total':
+ tax_amount = flt(rate) * flt(prd.amount) / 100
+ elif ocd[oc].charge_type == 'On Previous Row Amount':
+ row_no = cstr(ocd[oc].row_id)
+ row = row_no.split("+")
+ for r in range(0, len(row)):
+ id = cint(row[r])
+ tax_amount += flt((flt(rate) * flt(ocd[id-1].total_amount) / 100))
+ row_id = row_no.find("/")
+ if row_id != -1:
+ rate = ''
+ row = (row_no).split("/")
+ id1 = cint(row[0])
+ id2 = cint(row[1])
+ tax_amount = flt(flt(ocd[id1-1].total_amount) / flt(ocd[id2-1].total_amount))
+ elif ocd[oc].charge_type == 'On Previous Row Total':
+ row = cint(ocd[oc].row_id)
+ if ocd[row-1].add_deduct_tax == 'Add':
+ tax_amount = flt(rate) * (flt(ocd[row-1].total_tax_amount)+flt(ocd[row-1].total_amount)) / 100
+ elif ocd[row-1].add_deduct_tax == 'Deduct':
+ tax_amount = flt(rate) * (flt(ocd[row-1].total_tax_amount)-flt(ocd[row-1].total_amount)) / 100
+
+ return tax_amount
+
+ def add_deduct_taxes(self, ocd, oc, tax_amount, total, prev_total, item_tax):
+ """Calculates other charges values"""
+ add_ded = ocd[oc].add_deduct_tax == 'Add' and 1 or ocd[oc].add_or_deduct == 'Deduct' and -1
+ ocd[oc].total_amount = flt(tax_amount)
+ ocd[oc].total_tax_amount = flt(prev_total)
+ ocd[oc].tax_amount += flt(tax_amount)
+
+ total_amount = flt(ocd[oc].tax_amount)
+ total_tax_amount = flt(ocd[oc].total_tax_amount) + (add_ded * flt(total_amount))
+
+ if ocd[oc].category != "For Valuation":
+ prev_total += add_ded * flt(ocd[oc].total_amount)
+ total += add_ded * flt(ocd[oc].tax_amount)
+ ocd[oc].total = total
+ else:
+ prev_total = prev_total
+ ocd[oc].total = flt(total)
+ ocd[oc].save()
+
+ if ocd[oc].category != "For Total":
+ item_tax += add_ded * ocd[oc].total_amount
+
+ return total, prev_total, item_tax
+
+
+ def update_sle(self):
+ """ Recalculate valuation rate in all sle after pr posting date"""
+ for pr in self.selected_pr:
+ pr_obj = get_obj('Purchase Receipt', pr, with_children = 1)
+
+ for d in getlist(pr_obj.doclist, 'purchase_receipt_details'):
+ if flt(d.qty):
+ d.valuation_rate = (flt(d.purchase_rate) + (flt(d.rm_supp_cost)/flt(d.qty)) + (flt(d.item_tax_amount)/flt(d.qty))) / flt(d.conversion_factor)
+ d.save()
+ self.update_serial_no(d.serial_no, d.valuation_rate)
+ sql("update `tabStock Ledger Entry` set incoming_rate = '%s' where voucher_detail_no = '%s'"%(flt(d.valuation_rate), d.name))
+
+ bin = sql("select t1.name, t2.posting_date, t2.posting_time from `tabBin` t1, `tabStock Ledger Entry` t2 where t2.voucher_detail_no = '%s' and t2.item_code = t1.item_code and t2.warehouse = t1.warehouse LIMIT 1" % d.name)
+
+ # update valuation rate after pr posting date
+ if bin and bin[0][0]:
+ obj = get_obj('Bin', bin[0][0]).update_entries_after(bin[0][1], bin[0][2])
+
+
+ def update_serial_no(self, sr_no, rate):
+ """ update valuation rate in serial no"""
+ sr_no = sr_no.split('\n')
+ for d in sr_no:
+ sql("update `tabSerial No` set purchase_rate = %s where name = %s", (rate, d))
+
+
+ def update_landed_cost(self):
+ """
+ Add extra cost and recalculate all values in pr,
+ Recalculate valuation rate in all sle after pr posting date
+ """
+ self.get_selected_pr()
+ self.validate_selected_pr()
+ self.add_charges_in_pr()
+ self.cal_charges_and_item_tax_amt()
+ self.update_sle()
+ msgprint("Landed Cost updated successfully")
diff --git a/erpnext/stock/doctype/landed_cost_wizard/landed_cost_wizard.txt b/erpnext/stock/doctype/landed_cost_wizard/landed_cost_wizard.txt
index 90c570a..1e12afa 100644
--- a/erpnext/stock/doctype/landed_cost_wizard/landed_cost_wizard.txt
+++ b/erpnext/stock/doctype/landed_cost_wizard/landed_cost_wizard.txt
@@ -3,16 +3,18 @@
# These values are common in all dictionaries
{
- 'creation': '2010-08-08 17:09:07',
+ 'creation': '2011-11-16 16:17:22',
'docstatus': 0,
- 'modified': '2011-06-30 18:47:46',
+ 'modified': '2011-11-16 16:32:18',
'modified_by': 'Administrator',
'owner': 'wasim@webnotestech.com'
},
# These values are common for all DocType
{
+ '_last_update': '1321441191',
'colour': 'White:FFF',
+ 'default_print_format': 'Standard',
'doctype': 'DocType',
'issingle': 1,
'module': 'Stock',
@@ -20,7 +22,7 @@
'section_style': 'Simple',
'server_code_error': ' ',
'show_in_menu': 1,
- 'version': 31
+ 'version': 35
},
# These values are common for all DocField
@@ -52,7 +54,6 @@
# DocPerm
{
'doctype': 'DocPerm',
- 'idx': 1,
'permlevel': 0,
'role': 'All',
'write': 0
@@ -64,7 +65,6 @@
'cancel': 0,
'create': 1,
'doctype': 'DocPerm',
- 'idx': 2,
'permlevel': 0,
'role': 'Purchase Manager',
'submit': 0,
@@ -75,7 +75,6 @@
{
'create': 1,
'doctype': 'DocPerm',
- 'idx': 3,
'permlevel': 0,
'role': 'System Manager',
'write': 1
@@ -85,7 +84,6 @@
{
'create': 1,
'doctype': 'DocPerm',
- 'idx': 4,
'permlevel': 0,
'role': 'Purchase User',
'write': 1
@@ -94,7 +92,6 @@
# DocPerm
{
'doctype': 'DocPerm',
- 'idx': 5,
'permlevel': 1,
'role': 'All'
},
@@ -102,7 +99,6 @@
# DocPerm
{
'doctype': 'DocPerm',
- 'idx': 6,
'permlevel': 1,
'role': 'System Manager'
},
@@ -110,7 +106,6 @@
# DocPerm
{
'doctype': 'DocPerm',
- 'idx': 7,
'permlevel': 1,
'role': 'Purchase User'
},
@@ -118,7 +113,6 @@
# DocPerm
{
'doctype': 'DocPerm',
- 'idx': 8,
'permlevel': 1,
'role': 'Purchase Manager'
},
@@ -126,9 +120,23 @@
# DocField
{
'doctype': 'DocField',
+ 'fieldtype': 'HTML',
+ 'label': 'Process',
+ 'options': '<div class="field_description"><b>Process:</b><br>1. Fetch and select Purchase Receipt<br>2. Enter extra costs<br>3. Click on Update Landed Cost button<br> 4. Cost will be added into other charges table of selected PR proportionately based on net total<br>5. Item Valuation Rate will be recalculated</div>'
+ },
+
+ # DocField
+ {
+ 'doctype': 'DocField',
+ 'fieldtype': 'Section Break',
+ 'options': 'Simple'
+ },
+
+ # DocField
+ {
+ 'doctype': 'DocField',
'fieldname': 'from_pr_date',
'fieldtype': 'Date',
- 'idx': 1,
'label': 'From PR Date',
'reqd': 1
},
@@ -138,7 +146,6 @@
'doctype': 'DocField',
'fieldname': 'to_pr_date',
'fieldtype': 'Date',
- 'idx': 2,
'label': 'To PR Date',
'reqd': 1
},
@@ -148,7 +155,6 @@
'doctype': 'DocField',
'fieldname': 'currency',
'fieldtype': 'Select',
- 'idx': 3,
'label': 'Currency',
'options': 'link:Currency',
'reqd': 1
@@ -158,7 +164,6 @@
{
'doctype': 'DocField',
'fieldtype': 'Button',
- 'idx': 4,
'label': 'Get Purchase Receipt',
'options': 'get_purchase_receipts'
},
@@ -166,18 +171,8 @@
# DocField
{
'doctype': 'DocField',
- 'fieldtype': 'Section Break',
- 'idx': 5,
- 'label': 'LC PR Detail',
- 'options': 'Simple'
- },
-
- # DocField
- {
- 'doctype': 'DocField',
'fieldname': 'lc_pr_details',
'fieldtype': 'Table',
- 'idx': 6,
'label': 'LC PR Details',
'options': 'LC PR Detail'
},
@@ -186,8 +181,6 @@
{
'doctype': 'DocField',
'fieldtype': 'Section Break',
- 'idx': 7,
- 'label': 'Landed Cost Detail',
'options': 'Simple'
},
@@ -196,7 +189,6 @@
'doctype': 'DocField',
'fieldname': 'landed_cost',
'fieldtype': 'Link',
- 'idx': 8,
'label': 'Select Landed Cost Details Master',
'options': 'Landed Cost Master'
},
@@ -206,7 +198,6 @@
'colour': 'White:FFF',
'doctype': 'DocField',
'fieldtype': 'Button',
- 'idx': 9,
'label': 'Get Details',
'options': 'get_landed_cost_master_details'
},
@@ -216,7 +207,6 @@
'doctype': 'DocField',
'fieldname': 'landed_cost_details',
'fieldtype': 'Table',
- 'idx': 10,
'label': 'Landed Cost Details',
'options': 'Landed Cost Detail'
},
@@ -225,8 +215,7 @@
{
'doctype': 'DocField',
'fieldtype': 'Button',
- 'idx': 11,
'label': 'Update PR',
- 'options': 'update_pr_lc_se'
+ 'options': 'update_landed_cost'
}
]
\ No newline at end of file
diff --git a/erpnext/stock/doctype/lc_pr_detail/lc_pr_detail.txt b/erpnext/stock/doctype/lc_pr_detail/lc_pr_detail.txt
index d09285d..b6bcb42 100644
--- a/erpnext/stock/doctype/lc_pr_detail/lc_pr_detail.txt
+++ b/erpnext/stock/doctype/lc_pr_detail/lc_pr_detail.txt
@@ -5,7 +5,7 @@
{
'creation': '2010-08-08 17:09:07',
'docstatus': 0,
- 'modified': '2011-06-30 18:47:22',
+ 'modified': '2011-11-16 16:10:00',
'modified_by': 'Administrator',
'owner': 'wasim@webnotestech.com'
},
@@ -13,6 +13,7 @@
# These values are common for all DocType
{
'colour': 'White:FFF',
+ 'default_print_format': 'Standard',
'doctype': 'DocType',
'istable': 1,
'module': 'Stock',
@@ -20,7 +21,7 @@
'section_style': 'Simple',
'server_code_error': ' ',
'show_in_menu': 0,
- 'version': 2
+ 'version': 5
},
# These values are common for all DocField
@@ -42,25 +43,23 @@
# DocField
{
'doctype': 'DocField',
- 'fieldname': 'purchase_receipt_no',
+ 'fieldname': 'purchase_receipt',
'fieldtype': 'Link',
- 'idx': 1,
- 'label': 'Purchase Receipt No',
+ 'label': 'Purchase Receipt',
'oldfieldname': 'purchase_receipt_no',
'oldfieldtype': 'Link',
'options': 'Purchase Receipt',
- 'search_index': 1
+ 'width': '220px'
},
# DocField
{
'doctype': 'DocField',
- 'fieldname': 'include_in_landed_cost',
+ 'fieldname': 'select_pr',
'fieldtype': 'Check',
- 'idx': 2,
- 'label': 'Include In Landed Cost',
+ 'label': 'Select PR',
'oldfieldname': 'include_in_landed_cost',
'oldfieldtype': 'Check',
- 'width': '150px'
+ 'width': '120px'
}
]
\ No newline at end of file
diff --git a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.js b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.js
index 1e3d440..aa75b61 100644
--- a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.js
+++ b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.js
@@ -107,7 +107,7 @@
}
// ***************** Get project name *****************
-cur_frm.fields_dict['project_name'].get_query = function(doc, cdt, cdn) {
+cur_frm.fields_dict['purchase_receipt_details'].grid.get_field('project_name').get_query = function(doc, cdt, cdn) {
return 'SELECT `tabProject`.name FROM `tabProject` WHERE `tabProject`.status = "Open" AND `tabProject`.name LIKE "%s" ORDER BY `tabProject`.name ASC LIMIT 50';
}
diff --git a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.txt b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.txt
old mode 100644
new mode 100755
diff --git a/erpnext/stock/doctype/purchase_receipt_detail/purchase_receipt_detail.txt b/erpnext/stock/doctype/purchase_receipt_detail/purchase_receipt_detail.txt
old mode 100644
new mode 100755
index a8e0d47..9aacefd
--- a/erpnext/stock/doctype/purchase_receipt_detail/purchase_receipt_detail.txt
+++ b/erpnext/stock/doctype/purchase_receipt_detail/purchase_receipt_detail.txt
@@ -5,7 +5,7 @@
{
'creation': '2010-08-08 17:09:16',
'docstatus': 0,
- 'modified': '2011-03-16 17:12:38',
+ 'modified': '2011-12-14 10:50:00',
'modified_by': 'Administrator',
'owner': 'Administrator'
},
@@ -14,6 +14,7 @@
{
'autoname': 'GRND/.#######',
'colour': 'White:FFF',
+ 'default_print_format': 'Standard',
'doctype': 'DocType',
'istable': 1,
'module': 'Stock',
@@ -21,7 +22,7 @@
'section_style': 'Tray',
'server_code_error': ' ',
'show_in_menu': 0,
- 'version': 61
+ 'version': 73
},
# These values are common for all DocField
@@ -44,7 +45,6 @@
'doctype': 'DocField',
'fieldname': 'item_code',
'fieldtype': 'Link',
- 'idx': 1,
'in_filter': 1,
'label': 'Item Code',
'oldfieldname': 'item_code',
@@ -62,7 +62,6 @@
'doctype': 'DocField',
'fieldname': 'item_name',
'fieldtype': 'Data',
- 'idx': 2,
'in_filter': 0,
'label': 'Item Name',
'oldfieldname': 'item_name',
@@ -78,7 +77,6 @@
'doctype': 'DocField',
'fieldname': 'description',
'fieldtype': 'Text',
- 'idx': 3,
'label': 'Description',
'oldfieldname': 'description',
'oldfieldtype': 'Text',
@@ -89,29 +87,10 @@
# DocField
{
- 'colour': 'White:FFF',
- 'doctype': 'DocField',
- 'fieldname': 'uom',
- 'fieldtype': 'Link',
- 'idx': 4,
- 'label': 'UOM',
- 'oldfieldname': 'uom',
- 'oldfieldtype': 'Link',
- 'options': 'UOM',
- 'permlevel': 0,
- 'reqd': 1,
- 'search_index': 0,
- 'trigger': 'Client',
- 'width': '100px'
- },
-
- # DocField
- {
'default': '0.00',
'doctype': 'DocField',
'fieldname': 'received_qty',
'fieldtype': 'Currency',
- 'idx': 5,
'label': 'Recd Quantity',
'oldfieldname': 'received_qty',
'oldfieldtype': 'Currency',
@@ -127,7 +106,6 @@
'doctype': 'DocField',
'fieldname': 'qty',
'fieldtype': 'Currency',
- 'idx': 6,
'label': 'Accepted Quantity',
'oldfieldname': 'qty',
'oldfieldtype': 'Currency',
@@ -142,7 +120,6 @@
'doctype': 'DocField',
'fieldname': 'rejected_qty',
'fieldtype': 'Currency',
- 'idx': 7,
'in_filter': 0,
'label': 'Rejected Quantity',
'oldfieldname': 'rejected_qty',
@@ -155,13 +132,66 @@
# DocField
{
+ 'doctype': 'DocField',
+ 'fieldname': 'import_ref_rate',
+ 'fieldtype': 'Currency',
+ 'label': 'Ref Rate ',
+ 'permlevel': 0
+ },
+
+ # DocField
+ {
+ 'doctype': 'DocField',
+ 'fieldname': 'discount_rate',
+ 'fieldtype': 'Currency',
+ 'label': 'Discount %',
+ 'permlevel': 0
+ },
+
+ # DocField
+ {
+ 'colour': 'White:FFF',
+ 'default': '0.00',
+ 'doctype': 'DocField',
+ 'fieldname': 'import_rate',
+ 'fieldtype': 'Currency',
+ 'label': 'Rate',
+ 'oldfieldname': 'import_rate',
+ 'oldfieldtype': 'Currency',
+ 'permlevel': 0,
+ 'print_hide': 0,
+ 'trigger': 'Client',
+ 'width': '100px'
+ },
+
+ # DocField
+ {
+ 'doctype': 'DocField',
+ 'fieldname': 'import_amount',
+ 'fieldtype': 'Currency',
+ 'label': 'Amount',
+ 'oldfieldname': 'import_amount',
+ 'oldfieldtype': 'Currency',
+ 'permlevel': 1
+ },
+
+ # DocField
+ {
+ 'doctype': 'DocField',
+ 'fieldname': 'purchase_ref_rate',
+ 'fieldtype': 'Currency',
+ 'label': 'Ref Rate *',
+ 'permlevel': 0
+ },
+
+ # DocField
+ {
'colour': 'White:FFF',
'default': '0.00',
'doctype': 'DocField',
'fieldname': 'purchase_rate',
'fieldtype': 'Currency',
- 'idx': 8,
- 'label': 'Rate (Default Curr.)',
+ 'label': 'Rate *(Default Curr.)',
'oldfieldname': 'purchase_rate',
'oldfieldtype': 'Currency',
'permlevel': 0,
@@ -177,7 +207,6 @@
'doctype': 'DocField',
'fieldname': 'amount',
'fieldtype': 'Currency',
- 'idx': 9,
'label': 'Amount (Default Curr.)',
'oldfieldname': 'amount',
'oldfieldtype': 'Currency',
@@ -190,28 +219,10 @@
# DocField
{
- 'colour': 'White:FFF',
- 'doctype': 'DocField',
- 'fieldname': 'schedule_date',
- 'fieldtype': 'Date',
- 'idx': 10,
- 'label': 'Schedule date',
- 'no_copy': 1,
- 'oldfieldname': 'schedule_date',
- 'oldfieldtype': 'Date',
- 'permlevel': 0,
- 'print_hide': 1,
- 'report_hide': 0,
- 'reqd': 1
- },
-
- # DocField
- {
'doctype': 'DocField',
'fieldname': 'warehouse',
'fieldtype': 'Link',
'hidden': 0,
- 'idx': 11,
'label': 'Accepted Warehouse',
'oldfieldname': 'warehouse',
'oldfieldtype': 'Link',
@@ -224,16 +235,15 @@
# DocField
{
'colour': 'White:FFF',
- 'default': '0.00',
'doctype': 'DocField',
- 'fieldname': 'import_rate',
- 'fieldtype': 'Currency',
- 'idx': 12,
- 'label': 'Rate',
- 'oldfieldname': 'import_rate',
- 'oldfieldtype': 'Currency',
+ 'fieldname': 'uom',
+ 'fieldtype': 'Link',
+ 'label': 'UOM',
+ 'oldfieldname': 'uom',
+ 'oldfieldtype': 'Link',
+ 'options': 'UOM',
'permlevel': 0,
- 'print_hide': 0,
+ 'reqd': 1,
'trigger': 'Client',
'width': '100px'
},
@@ -241,21 +251,8 @@
# DocField
{
'doctype': 'DocField',
- 'fieldname': 'import_amount',
- 'fieldtype': 'Currency',
- 'idx': 13,
- 'label': 'Amount',
- 'oldfieldname': 'import_amount',
- 'oldfieldtype': 'Currency',
- 'permlevel': 1
- },
-
- # DocField
- {
- 'doctype': 'DocField',
'fieldname': 'conversion_factor',
'fieldtype': 'Currency',
- 'idx': 14,
'label': 'Conversion Factor',
'oldfieldname': 'conversion_factor',
'oldfieldtype': 'Currency',
@@ -271,7 +268,6 @@
'doctype': 'DocField',
'fieldname': 'stock_uom',
'fieldtype': 'Data',
- 'idx': 15,
'label': 'Stock UOM',
'oldfieldname': 'stock_uom',
'oldfieldtype': 'Data',
@@ -283,17 +279,93 @@
# DocField
{
+ 'colour': 'White:FFF',
'doctype': 'DocField',
- 'fieldname': 'stock_qty',
- 'fieldtype': 'Currency',
- 'idx': 16,
- 'label': 'Stock Qty',
- 'oldfieldname': 'stock_qty',
- 'oldfieldtype': 'Currency',
+ 'fieldname': 'rejected_warehouse',
+ 'fieldtype': 'Link',
+ 'hidden': 1,
+ 'label': 'Rejected Warehouse',
+ 'no_copy': 1,
+ 'oldfieldname': 'rejected_warehouse',
+ 'oldfieldtype': 'Link',
+ 'options': 'Warehouse',
+ 'permlevel': 1,
+ 'print_hide': 1,
+ 'width': '100px'
+ },
+
+ # DocField
+ {
+ 'colour': 'White:FFF',
+ 'doctype': 'DocField',
+ 'fieldname': 'schedule_date',
+ 'fieldtype': 'Date',
+ 'label': 'Schedule date',
+ 'no_copy': 1,
+ 'oldfieldname': 'schedule_date',
+ 'oldfieldtype': 'Date',
'permlevel': 0,
'print_hide': 1,
- 'trigger': 'Client',
- 'width': '100px'
+ 'report_hide': 0,
+ 'reqd': 1
+ },
+
+ # DocField
+ {
+ 'colour': 'White:FFF',
+ 'doctype': 'DocField',
+ 'fieldname': 'project_name',
+ 'fieldtype': 'Link',
+ 'in_filter': 1,
+ 'label': 'Project Name',
+ 'options': 'Project',
+ 'permlevel': 0,
+ 'print_hide': 1
+ },
+
+ # DocField
+ {
+ 'colour': 'White:FFF',
+ 'doctype': 'DocField',
+ 'fieldname': 'qa_no',
+ 'fieldtype': 'Link',
+ 'label': 'QA No',
+ 'no_copy': 1,
+ 'oldfieldname': 'qa_no',
+ 'oldfieldtype': 'Link',
+ 'options': 'QA Inspection Report',
+ 'permlevel': 0,
+ 'print_hide': 1
+ },
+
+ # DocField
+ {
+ 'doctype': 'DocField',
+ 'fieldname': 'brand',
+ 'fieldtype': 'Link',
+ 'hidden': 1,
+ 'label': 'Brand',
+ 'oldfieldname': 'brand',
+ 'oldfieldtype': 'Link',
+ 'options': 'Brand',
+ 'permlevel': 1,
+ 'print_hide': 1
+ },
+
+ # DocField
+ {
+ 'doctype': 'DocField',
+ 'fieldname': 'item_group',
+ 'fieldtype': 'Link',
+ 'hidden': 1,
+ 'in_filter': 1,
+ 'label': 'Item Group',
+ 'oldfieldname': 'item_group',
+ 'oldfieldtype': 'Link',
+ 'options': 'Item Group',
+ 'permlevel': 1,
+ 'print_hide': 1,
+ 'search_index': 1
},
# DocField
@@ -302,7 +374,7 @@
'doctype': 'DocField',
'fieldname': 'serial_no',
'fieldtype': 'Text',
- 'idx': 17,
+ 'in_filter': 1,
'label': 'Serial No',
'no_copy': 1,
'oldfieldname': 'serial_no',
@@ -318,84 +390,27 @@
'doctype': 'DocField',
'fieldname': 'batch_no',
'fieldtype': 'Link',
- 'idx': 18,
'label': 'Batch No',
'oldfieldname': 'batch_no',
'oldfieldtype': 'Link',
'options': 'Batch',
'permlevel': 0,
'print_hide': 1,
- 'search_index': 0,
'trigger': 'Client'
},
# DocField
{
- 'colour': 'White:FFF',
'doctype': 'DocField',
- 'fieldname': 'rejected_warehouse',
- 'fieldtype': 'Link',
- 'hidden': 1,
- 'idx': 19,
- 'label': 'Rejected Warehouse',
- 'no_copy': 1,
- 'oldfieldname': 'rejected_warehouse',
- 'oldfieldtype': 'Link',
- 'options': 'Warehouse',
- 'permlevel': 1,
- 'print_hide': 1,
- 'search_index': 0,
- 'width': '100px'
- },
-
- # DocField
- {
- 'colour': 'White:FFF',
- 'doctype': 'DocField',
- 'fieldname': 'qa_no',
- 'fieldtype': 'Link',
- 'idx': 20,
- 'label': 'QA No',
- 'no_copy': 1,
- 'oldfieldname': 'qa_no',
- 'oldfieldtype': 'Link',
- 'options': 'QA Inspection Report',
+ 'fieldname': 'stock_qty',
+ 'fieldtype': 'Currency',
+ 'label': 'Stock Qty',
+ 'oldfieldname': 'stock_qty',
+ 'oldfieldtype': 'Currency',
'permlevel': 0,
'print_hide': 1,
- 'search_index': 0
- },
-
- # DocField
- {
- 'doctype': 'DocField',
- 'fieldname': 'brand',
- 'fieldtype': 'Link',
- 'hidden': 1,
- 'idx': 21,
- 'label': 'Brand',
- 'oldfieldname': 'brand',
- 'oldfieldtype': 'Link',
- 'options': 'Brand',
- 'permlevel': 1,
- 'print_hide': 1,
- 'search_index': 0
- },
-
- # DocField
- {
- 'doctype': 'DocField',
- 'fieldname': 'item_group',
- 'fieldtype': 'Link',
- 'hidden': 1,
- 'idx': 22,
- 'in_filter': 1,
- 'label': 'Item Group',
- 'oldfieldname': 'item_group',
- 'oldfieldtype': 'Link',
- 'options': 'Item Group',
- 'permlevel': 1,
- 'print_hide': 1,
- 'search_index': 0
+ 'trigger': 'Client',
+ 'width': '100px'
},
# DocField
@@ -405,7 +420,6 @@
'fieldname': 'prevdoc_doctype',
'fieldtype': 'Data',
'hidden': 1,
- 'idx': 23,
'label': 'Prevdoc Doctype',
'oldfieldname': 'prevdoc_doctype',
'oldfieldtype': 'Data',
@@ -420,7 +434,6 @@
'fieldname': 'prevdoc_docname',
'fieldtype': 'Link',
'hidden': 0,
- 'idx': 24,
'in_filter': 1,
'label': 'PO No',
'no_copy': 0,
@@ -440,7 +453,6 @@
'fieldname': 'prevdoc_date',
'fieldtype': 'Date',
'hidden': 1,
- 'idx': 25,
'in_filter': 1,
'label': 'PO Date',
'oldfieldname': 'prevdoc_date',
@@ -455,7 +467,6 @@
'fieldname': 'rm_supp_cost',
'fieldtype': 'Currency',
'hidden': 1,
- 'idx': 26,
'in_filter': 0,
'label': 'Raw Materials Supplied Cost',
'oldfieldname': 'rm_supp_cost',
@@ -467,11 +478,11 @@
# DocField
{
+ 'colour': 'White:FFF',
'doctype': 'DocField',
'fieldname': 'item_tax_amount',
'fieldtype': 'Currency',
'hidden': 1,
- 'idx': 27,
'label': 'Item Tax Amount',
'no_copy': 1,
'oldfieldname': 'item_tax_amount',
@@ -479,7 +490,7 @@
'permlevel': 1,
'print_hide': 1,
'reqd': 0,
- 'search_index': 0,
+ 'search_index': 1,
'width': '150px'
},
@@ -490,7 +501,6 @@
'fieldname': 'prevdoc_detail_docname',
'fieldtype': 'Data',
'hidden': 1,
- 'idx': 28,
'in_filter': 1,
'label': 'PO Detail No',
'no_copy': 0,
@@ -508,7 +518,6 @@
'doctype': 'DocField',
'fieldname': 'billed_qty',
'fieldtype': 'Currency',
- 'idx': 29,
'label': 'Billed Quantity',
'no_copy': 1,
'oldfieldname': 'billed_qty',
@@ -520,29 +529,29 @@
# DocField
{
+ 'colour': 'White:FFF',
'doctype': 'DocField',
'fieldname': 'valuation_rate',
'fieldtype': 'Currency',
- 'hidden': 0,
- 'idx': 30,
+ 'hidden': 1,
'in_filter': 0,
'label': 'Valuation Rate',
'no_copy': 1,
'oldfieldname': 'valuation_rate',
'oldfieldtype': 'Currency',
- 'permlevel': 0,
+ 'permlevel': 1,
'print_hide': 1,
'width': '80px'
},
# DocField
{
+ 'colour': 'White:FFF',
'description': 'Tax detail table fetched from item master as a string and stored in this field.\nUsed for Purchase Other Charges',
'doctype': 'DocField',
'fieldname': 'item_tax_rate',
'fieldtype': 'Small Text',
'hidden': 1,
- 'idx': 31,
'in_filter': 0,
'label': 'Item Tax Rate',
'oldfieldname': 'item_tax_rate',
@@ -558,7 +567,6 @@
'doctype': 'DocField',
'fieldname': 'page_break',
'fieldtype': 'Check',
- 'idx': 32,
'label': 'Page Break',
'oldfieldname': 'page_break',
'oldfieldtype': 'Check',
diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.py b/erpnext/stock/doctype/stock_entry/stock_entry.py
index b799eaa..9eeb11f 100644
--- a/erpnext/stock/doctype/stock_entry/stock_entry.py
+++ b/erpnext/stock/doctype/stock_entry/stock_entry.py
@@ -93,7 +93,7 @@
def get_as_on_stock(self, item, wh, dt, tm):
bin = sql("select name from tabBin where item_code = %s and warehouse = %s", (item, wh))
bin_id = bin and bin[0][0] or ''
- prev_sle = get_obj('Bin', bin_id).get_prev_sle(dt, tm)
+ prev_sle = bin_id and get_obj('Bin', bin_id).get_prev_sle(dt, tm) or {}
qty = flt(prev_sle.get('bin_aqat', 0))
return qty
@@ -121,19 +121,46 @@
self.item_dict[i[0]] = [flt(i[1]), cstr(i[2]), cstr(i[3])]
def get_raw_materials(self,pro_obj):
- # get all items from flat bom except, child items of sub-contracted and sub assembly items and sub assembly items itself.
-# flat_bom_items = sql("select item_code, ifnull(sum(qty_consumed_per_unit), 0) * '%s', description, stock_uom from `tabFlat BOM Detail` where parent = '%s' and parent_bom = '%s' and is_pro_applicable = 'No' and docstatus < 2 group by item_code" % ((self.doc.process == 'Backflush') and flt(self.doc.fg_completed_qty) or flt(pro_obj.doc.qty), cstr(pro_obj.doc.bom_no), cstr(pro_obj.doc.bom_no)))
-# self.make_items_dict(flat_bom_items)
+ """
+ get all items from flat bom except
+ child items of sub-contracted and sub assembly items
+ and sub assembly items itself.
+ """
if pro_obj.doc.consider_sa_items == 'Yes':
- # get all Sub Assembly items only from flat bom
- fl_bom_sa_items = sql("select item_code, ifnull(sum(qty_consumed_per_unit), 0) * '%s', description, stock_uom from `tabFlat BOM Detail` where parent = '%s' and parent_bom = '%s' and is_pro_applicable = 'Yes' and docstatus < 2 group by item_code" % ((self.doc.process == 'Backflush') and flt(self.doc.fg_completed_qty) or flt(pro_obj.doc.qty), cstr(pro_obj.doc.bom_no), cstr(pro_obj.doc.bom_no)))
+ # Get all raw materials considering SA items as raw materials,
+ # so no childs of SA items
+
+ fl_bom_sa_items = sql("""
+ select item_code, ifnull(sum(qty_consumed_per_unit), 0) * '%s', description, stock_uom
+ from `tabBOM Material`
+ where parent = '%s' and docstatus < 2
+ group by item_code
+ """ % ((self.doc.process == 'Backflush') and flt(self.doc.fg_completed_qty) \
+ or flt(pro_obj.doc.qty), cstr(pro_obj.doc.bom_no)))
+
self.make_items_dict(fl_bom_sa_items)
if pro_obj.doc.consider_sa_items == 'No':
- # get all sub assembly childs only from flat bom
- #select item_code,ifnull(sum(qty_consumed_per_unit),0)*'%s' as qty,description,stock_uom from ( select distinct fb.name,fb.description,fb.item_code,fb.qty_consumed_per_unit,fb.stock_uom from `tabFlat BOM Detail` fb,`tabBOM Material` bm where bm.parent=fb.parent_bom and bm.docstatus<2 and fb.is_pro_applicable='Yes' and fb.docstatus<2 and fb.parent='%s' and bm.bom_no is null)a group by item_code,stock_uom
- fl_bom_sa_child_item = sql("select item_code,ifnull(sum(qty_consumed_per_unit),0)*'%s' as qty,description,stock_uom from ( select distinct fb.name,fb.description,fb.item_code,fb.qty_consumed_per_unit,fb.stock_uom from `tabFlat BOM Detail` fb,`tabBOM Material` bm where bm.parent=fb.parent_bom and bm.docstatus<2 and fb.is_pro_applicable='Yes' and fb.docstatus<2 and fb.parent='%s' and bm.bom_no is null)a group by item_code,stock_uom" % ((self.doc.process == 'Backflush') and flt(self.doc.fg_completed_qty) or flt(pro_obj.doc.qty), cstr(pro_obj.doc.bom_no)))
+ # get all raw materials with sub assembly childs
+
+ fl_bom_sa_child_item = sql("""
+ select
+ item_code,ifnull(sum(qty_consumed_per_unit),0)*%s as qty,description,stock_uom
+ from
+ (
+ select distinct fb.name, fb.description, fb.item_code, fb.qty_consumed_per_unit, fb.stock_uom
+ from `tabFlat BOM Detail` fb,`tabItem` it
+ where it.name = fb.item_code and ifnull(it.is_pro_applicable, 'No') = 'No'
+ and ifnull(it.is_sub_contracted_item, 'No') = 'No'
+ and fb.docstatus<2 and fb.parent=%s
+ ) a
+ group by item_code,stock_uom
+ """ , ((self.doc.process == 'Backflush') and flt(self.doc.fg_completed_qty) \
+ or flt(pro_obj.doc.qty), cstr(pro_obj.doc.bom_no)))
+
+
+
self.make_items_dict(fl_bom_sa_child_item)
def add_to_stock_entry_detail(self, pro_obj, item_dict, fg_item = 0):
@@ -179,11 +206,10 @@
if flt(d.transfer_qty) <= 0:
msgprint("Transfer Quantity can not be less than or equal to zero at Row No " + cstr(d.idx))
raise Exception
- if d.s_warehouse:
- if flt(d.transfer_qty) > flt(d.actual_qty):
- msgprint("Transfer Quantity is more than Available Qty at Row No " + cstr(d.idx))
- raise Exception
-
+ if d.s_warehouse and flt(d.transfer_qty) > flt(d.actual_qty):
+ msgprint("Transfer Quantity is more than Available Qty at Row No " + cstr(d.idx))
+ raise Exception
+
def calc_amount(self):
total_amount = 0
for d in getlist(self.doclist, 'mtn_details'):
@@ -219,7 +245,7 @@
self.add_to_values(d, cstr(d.s_warehouse), -flt(d.transfer_qty), is_cancelled)
if cstr(d.t_warehouse):
self.add_to_values(d, cstr(d.t_warehouse), flt(d.transfer_qty), is_cancelled)
- get_obj('Stock Ledger', 'Stock Ledger').update_stock(self.values)
+ get_obj('Stock Ledger', 'Stock Ledger').update_stock(self.values, self.doc.amended_from and 'Yes' or 'No')
def validate_for_production_order(self, pro_obj):
diff --git a/erpnext/stock/doctype/stock_ledger/stock_ledger.py b/erpnext/stock/doctype/stock_ledger/stock_ledger.py
index 5165cc9..f22d2c2 100644
--- a/erpnext/stock/doctype/stock_ledger/stock_ledger.py
+++ b/erpnext/stock/doctype/stock_ledger/stock_ledger.py
@@ -93,27 +93,27 @@
# ---------------------
def set_pur_serial_no_values(self, obj, serial_no, d, s, new_rec):
item_details = sql("select item_group, warranty_period from `tabItem` where name = '%s' and (ifnull(end_of_life,'')='' or end_of_life = '0000-00-00' or end_of_life > now()) " %(d.item_code), as_dict=1)
- s.purchase_document_type= obj.doc.doctype
- s.purchase_document_no = obj.doc.name
- s.purchase_date = obj.doc.posting_date
- s.purchase_time = obj.doc.posting_time
- s.purchase_rate = d.purchase_rate or d.incoming_rate
- s.item_code = d.item_code
- s.brand = d.brand
- s.description = d.description
- s.item_group = item_details and item_details[0]['item_group'] or ''
- s.warranty_period = item_details and item_details[0]['warranty_period'] or 0
- s.supplier = obj.doc.supplier
- s.supplier_name = obj.doc.supplier_name
- s.supplier_address = obj.doc.supplier_address
- s.warehouse = d.warehouse or d.t_warehouse
- s.docstatus = 0
- s.status = 'In Store'
- s.modified = nowdate()
- s.modified_by = session['user']
- s.serial_no = serial_no
- s.fiscal_year = obj.doc.fiscal_year
- s.company = obj.doc.company
+ s.purchase_document_type = obj.doc.doctype
+ s.purchase_document_no = obj.doc.name
+ s.purchase_date = obj.doc.posting_date
+ s.purchase_time = obj.doc.posting_time
+ s.purchase_rate = d.valuation_rate or d.incoming_rate
+ s.item_code = d.item_code
+ s.brand = d.brand
+ s.description = d.description
+ s.item_group = item_details and item_details[0]['item_group'] or ''
+ s.warranty_period = item_details and item_details[0]['warranty_period'] or 0
+ s.supplier = obj.doc.supplier
+ s.supplier_name = obj.doc.supplier_name
+ s.supplier_address = obj.doc.supplier_address
+ s.warehouse = d.warehouse or d.t_warehouse
+ s.docstatus = 0
+ s.status = 'In Store'
+ s.modified = nowdate()
+ s.modified_by = session['user']
+ s.serial_no = serial_no
+ s.fiscal_year = obj.doc.fiscal_year
+ s.company = obj.doc.company
s.save(new_rec)
@@ -207,7 +207,7 @@
# -------------
# update stock
# -------------
- def update_stock(self, values):
+ def update_stock(self, values, is_amended = 'No'):
for v in values:
sle_id, serial_nos = '', ''
@@ -224,7 +224,7 @@
if v["actual_qty"]:
sle_id = self.make_entry(v)
- get_obj('Warehouse', v["warehouse"]).update_bin(flt(v["actual_qty"]), 0, 0, 0, 0, v["item_code"], v["posting_date"], sle_id, v["posting_time"], '', v["is_cancelled"])
+ get_obj('Warehouse', v["warehouse"]).update_bin(flt(v["actual_qty"]), 0, 0, 0, 0, v["item_code"], v["posting_date"], sle_id, v["posting_time"], '', v["is_cancelled"],v["voucher_type"],v["voucher_no"], is_amended)
# -----------
diff --git a/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.js b/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.js
index de89d80..2e428df 100644
--- a/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.js
+++ b/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.js
@@ -1,37 +1,7 @@
-cur_frm.cscript.onload = function(doc, cdt, cdn) {
- cfn_set_fields(doc, cdt, cdn);
+cur_frm.cscript.refresh = function(doc) {
+ if (doc.docstatus) hide_field('Steps');
}
-cur_frm.cscript.refresh = function(doc, cdt, cdn) {
- cfn_set_fields(doc, cdt, cdn);
+cur_frm.cscript['Download Template'] = function(doc, cdt, cdn) {
+ $c_obj_csv(make_doclist(cdt, cdn), 'get_template', '');
}
-
-var cfn_set_fields = function(doc, cdt, cdn) {
- refresh_field('remark');
- refresh_field('next_step');
- if (doc.docstatus == 0 && doc.next_step == 'Upload File and Save Document')
- doc.next_step = 'Validate Data';
-
- if (! doc.file_list)
- doc.next_step = 'Upload File and Save Document'
-
- if (doc.next_step == 'Upload File and Save Document') {
- //alert("Upload File and Save Document");
- cur_frm.clear_tip();
- cur_frm.set_tip("Please Enter Reconciliation Date and Attach CSV File with Columns in Following Sequence:-");
- cur_frm.append_tip("Item Code , Warehouse , Qty , MAR");
- hide_field("Validate Data");
- }
- if (doc.next_step == 'Validate Data') {
- //alert("Validate Data");
- cur_frm.clear_tip();
- cur_frm.set_tip("Please Check Remarks");
- unhide_field("Validate Data");
- }
- if (doc.next_step == 'Submit Document') {
- //alert('Submit Document');
- cur_frm.clear_tip();
- cur_frm.set_tip("Please Submit the document.");
- hide_field("Validate Data");
- }
-}
\ No newline at end of file
diff --git a/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py b/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py
index f040df3..7b9d294 100644
--- a/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py
+++ b/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py
@@ -1,273 +1,23 @@
-# Please edit this list and import only required elements
import webnotes
-
-from webnotes.utils import add_days, add_months, add_years, cint, cstr, date_diff, default_fields, flt, fmt_money, formatdate, generate_hash, getTraceback, get_defaults, get_first_day, get_last_day, getdate, has_common, month_name, now, nowdate, replace_newlines, sendmail, set_default, str_esc_quote, user_format, validate_email_add
-from webnotes.model import db_exists
-from webnotes.model.doc import Document, addchild, removechild, getchildren, make_autoname, SuperDocType
-from webnotes.model.doclist import getlist, copy_doclist
-from webnotes.model.code import get_obj, get_server_obj, run_server_obj, updatedb, check_syntax
-from webnotes import session, form, is_testing, msgprint, errprint
-
-set = webnotes.conn.set
+from webnotes.utils import cstr, flt, get_defaults, nowdate
+from webnotes import msgprint
+from webnotes.model.code import get_obj
sql = webnotes.conn.sql
-get_value = webnotes.conn.get_value
-in_transaction = webnotes.conn.in_transaction
-convert_to_lists = webnotes.conn.convert_to_lists
# -----------------------------------------------------------------------------------------
-
class DocType:
def __init__(self, doc, doclist=[]):
self.doc = doc
self.doclist = doclist
- self.label = { 'item_code': 0 , 'warehouse': 1 , 'qty': 2, 'mar': 3,'stock_uom':4, 'actual_qty':5, 'diff': 6} # with mar
+ self.validated = 1
+ self.data = []
- # autoname
- #-----------------
- def autoname(self):
- self.doc.name = make_autoname('SR/' + self.doc.fiscal_year + '/.######')
+ def get_template(self):
+ return [['Item Code', 'Warehouse', 'Quantity', 'Valuation Rate']]
- # -----------------
- # update next step
- # -----------------
- def update_next_step(self,next_step):
- sql("update `tabStock Reconciliation` set next_step = '%s' where name = '%s'" % (next_step,self.doc.name))
-
-
- # -----------
- # add remark
- # -----------
- def add_remark(self, text, next_step, first_time = 0):
- if first_time:
- sql("update `tabStock Reconciliation` set remark = '' where name = '%s'" % self.doc.name)
- else:
- sql("update `tabStock Reconciliation` set remark = concat(remark, '%s'), modified = '%s' where name = '%s'" % (text + "<br>", nowdate(), self.doc.name))
- self.update_next_step(next_step)
-
-
- # --------------
- # validate item
- # --------------
- def validate_item(self, item, count, check_item = 1):
- det = sql("select item_code, has_serial_no from `tabItem` where name = '%s'"% cstr(item), as_dict = 1)
- if not det:
- text = "Item: " + cstr(item) + " mentioned at Row No. " + cstr(count) + "does not exist in the system"
- msgprint(text)
- self.add_remark(text, 'Validate Data', 0)
- check_item = 0
- elif det and det[0]['has_serial_no'] == 'Yes':
- text = "You cannot make Stock Reconciliation of items having serial no. You can directly upload serial no to update their inventory. Please remove Item Code : %s at Row No. %s" %(cstr(item), cstr(count))
- msgprint(text)
- self.add_remark(text, 'Validate Data', 0)
- check_item = 0
- return check_item
-
-
- # -------------------
- # validate warehouse
- # -------------------
- def validate_warehouse(self,wh,count, check_warehouse = 1):
- if not sql("select name from `tabWarehouse` where name = '%s'" % cstr(wh)):
- text = "Warehouse: " + cstr(wh) + " mentioned at Row No. " + cstr(count) + "does not exist in the system"
- self.add_remark(text,'Validate Data',0)
- check_warehouse = 0
- return check_warehouse
-
-
- # ---------------------------
- # validate data of .csv file
- # ---------------------------
- def validate_data(self,stock):
- self.add_remark('','Validate Data',1)
-
- # check whether file uploaded
- if not self.doc.file_list:
- set(self.doc,'next_step','Upload File and Save Document')
- msgprint("Please Attach File", raise_exception=1)
-
- # validate item and warehouse
- check_item,check_warehouse,count = 1, 1, 1
- for s in stock:
- count +=1
- check_item = self.validate_item(s[self.label['item_code']],count) or 0
- check_warehouse = self.validate_warehouse(s[self.label['warehouse']],count) or 0
-
- if check_item and check_warehouse:
- text = "Validation Completed Successfully..."
- self.add_remark(text,'Submit Document',0)
- return check_item and check_warehouse
-
-
- # ------------------------------
- # convert lines in .csv to list
- # ------------------------------
- def convert_into_list(self, stock, submit):
- count, st_list = 1, []
- for s in stock:
- if submit and len(s) != 4:
- msgprint("Data entered at Row No " + cstr(count) + " in Attachment File is not in correct format.", raise_exception=1)
-
- l = [s[0].encode("ascii"), s[1].encode("ascii"), s[2].encode("ascii"), s[3].encode("ascii")]
- st_list.append(l)
- count += 1
- return st_list
-
- # ------------------
- # get current stock
- # ------------------
- def get_current_stock(self, item_code, warehouse):
- bin = sql("select name from `tabBin` where item_code = '%s' and warehouse = '%s'" % (item_code, warehouse))
- prev_sle = bin and get_obj('Bin', bin[0][0]).get_prev_sle(self.doc.reconciliation_date,self.doc.reconciliation_time) or {}
- stock_uom = sql("select stock_uom from `tabItem` where name = %s",item_code)
- return {'actual_qty': prev_sle.get('bin_aqat', 0), 'stock_uom': stock_uom[0][0]}
-
-
- # -----------
- # update mar
- # -----------
- def update_mar(self, d, qty_diff):
- """
- update item valuation in previous date and also on post date if no qty diff
- """
-
- self.update_item_valuation_pre_date(d)
-
- if not flt(d[self.label['qty']]) and not flt(d[self.label['actual_qty']]):
- # seems like a special condition when there is no actual quanitity but there is a rate, may be only for setting a rate!
- self.make_sl_entry(1,d,1)
- self.make_sl_entry(1,d,-1)
- elif not qty_diff:
- self.update_item_valuation_post_date(d)
-
- # update valuation rate as csv file in all sle before reconciliation date
- # ------------------------------------------------------------------------
- def update_item_valuation_pre_date(self, d):
- mar = flt(d[self.label['mar']])
-
- # previous sle
- prev_sle = sql("""
- select name, fcfs_stack
- from `tabStock Ledger Entry`
- where item_code = %s
- and warehouse = %s
- and ifnull(is_cancelled, 'No') = 'No'
- and timestamp(posting_date, posting_time) <= timestamp(%s, %s)
- """, (d[self.label['item_code']], d[self.label['warehouse']], self.doc.reconciliation_date, self.doc.reconciliation_time))
-
- for each in prev_sle:
- # updated fifo stack
- fstack = each[1] and [[i[0], mar] for i in eval(each[1])] or ''
-
- # update incoming rate, valuation rate, stock value and fifo stack
- sql("""update `tabStock Ledger Entry`
- set incoming_rate = %s, valuation_rate = %s, stock_value = bin_aqat*%s, fcfs_stack = %s
- where name = %s
- """, (mar, mar, mar, cstr(fstack), each[0]))
-
-
- # Update item valuation in all sle after the reconcliation date
- # ---------------------------------------------------------
- def update_item_valuation_post_date(self, d):
- bin = sql("select name from `tabBin` where item_code = '%s' and warehouse = '%s'" % (d[self.label['item_code']], d[self.label['warehouse']]))
- bin_obj = get_obj('Bin', bin[0][0])
-
- # prev sle
- prev_sle = bin_obj.get_prev_sle(self.doc.reconciliation_date,self.doc.reconciliation_time)
-
- # update valuation in sle posted after reconciliation datetime
- bin_obj.update_item_valuation(posting_date = self.doc.reconciliation_date, posting_time = self.doc.reconciliation_time, prev_sle = prev_sle)
-
- # --------------
- # make sl entry
- # --------------
- def make_sl_entry(self, update_stock, stock, diff):
- values = []
- values.append({
- 'item_code' : stock[self.label['item_code']],
- 'warehouse' : stock[self.label['warehouse']],
- 'transaction_date' : now(),
- 'posting_date' : self.doc.reconciliation_date,
- 'posting_time' : self.doc.reconciliation_time,
- 'voucher_type' : self.doc.doctype,
- 'voucher_no' : self.doc.name,
- 'voucher_detail_no' : self.doc.name,
- 'actual_qty' : flt(update_stock) * flt(diff),
- 'stock_uom' : stock[self.label['stock_uom']],
- 'incoming_rate' : stock[self.label['mar']] or 0,
- 'company' : self.doc.company,
- 'fiscal_year' : self.doc.fiscal_year,
- 'is_cancelled' : (update_stock==1) and 'No' or 'Yes',
- 'batch_no' : '',
- 'serial_no' : ''
- })
-
- get_obj('Stock Ledger', 'Stock Ledger').update_stock(values)
-
-
- # -----------------------
- # get stock reco details
- # -----------------------
- def get_reconciliation_stock_details(self,submit = 0):
- import csv
- stock = csv.reader(self.get_csv_file_data().splitlines())
- stock = self.convert_into_list(stock, submit)
- if stock[0][0] and stock[0][0].strip()=='Item Code':
- stock.pop(0) # remove the labels
- check = self.validate_data(stock)
- if not check:
- return 0
- return stock
-
- # validate date and time
- # ------------------------
- def validate_datetime(self):
- if not self.doc.reconciliation_date:
- msgprint("Please Enter Reconciliation Date.", raise_exception=1)
- if not self.doc.reconciliation_time:
- msgprint("Please Enter Reconciliation Time.", raise_exception=1)
-
-
-
- # ----------------------
- # stock reconciliations
- # ----------------------
- def stock_reconciliations(self, submit = 0):
- self.validate_datetime()
-
- # get reco data
- rec_stock_detail = self.get_reconciliation_stock_details(submit) or []
- if not rec_stock_detail:
- msgprint("Please Check Remarks", raise_exception=1)
-
- count = 1
- for stock in rec_stock_detail:
- count += 1
-
- # Get qty as per system
- cur_stock_detail = self.get_current_stock(stock[self.label['item_code']],stock[self.label['warehouse']])
- stock.append(cur_stock_detail['stock_uom'])
- stock.append(cur_stock_detail['actual_qty'])
-
- # Qty Diff between file and system
- diff = flt(stock[self.label['qty']]) - flt(cur_stock_detail['actual_qty'])
-
- # Update MAR
- if not stock[self.label['mar']] == '~':
- self.update_mar(stock, diff)
-
- # Make sl entry if qty differ
- if diff:
- self.make_sl_entry(submit, stock, diff)
-
- if rec_stock_detail:
- text = "Stock Reconciliation Completed Successfully..."
- self.add_data_in_CSV(rec_stock_detail)
- self.add_remark(text,'Completed', 0)
-
- # Get csv data
- #--------------------------
def get_csv_file_data(self):
+ """Get csv data"""
filename = self.doc.file_list.split(',')
if not filename:
msgprint("Please Attach File. ", raise_exception=1)
@@ -277,37 +27,160 @@
if not type(content) == str:
content = content.tostring()
+
return content
+ def convert_into_list(self, data):
+ """Convert csv data into list"""
+ count = 1
+ for s in data:
+ if s[0].strip() != 'Item Code': # remove the labels
+ # validate
+ if len(s) != 4:
+ msgprint("Data entered at Row No " + cstr(count) + " in Attachment File is not in correct format.", raise_exception=1)
+ self.validated = 0
+ self.validate_item(s[0], count)
+ self.validate_warehouse(s[1], count)
+
+ # encode as ascii
+ self.data.append([d.encode("ascii") for d in s])
+ count += 1
+
+ if not self.validated:
+ raise Exception
- def getCSVelement(self,v):
- v = cstr(v)
- if not v: return ''
- if (',' in v) or ('' in v) or ('"' in v):
- if '"' in v: v = v.replace('"', '""')
- return '"'+v+'"'
- else: return v or ''
- # Add qty diff column in attached file
- #----------------------------------------
- def add_data_in_CSV(self,data):
- filename = self.doc.file_list.split(',')
- head = []
- for h in ['Item Code','Warehouse','Qty','Actual','Difference','MAR']:
- head.append(self.getCSVelement(h))
- dset = (','.join(head) + "\n")
- for d in data:
- l = [d[self.label['item_code']],d[self.label['warehouse']],d[self.label['qty']],d[self.label['actual_qty']],flt(d[self.label['qty']])-flt(d[self.label['actual_qty']]),d[self.label['mar']]]
- s =[]
- for i in l:
- s.append(self.getCSVelement(i))
- dset +=(','.join(s)+"\n")
+ def get_reconciliation_data(self,submit = 0):
+ """Read and validate csv data"""
+ import csv
+ data = csv.reader(self.get_csv_file_data().splitlines())
+ self.convert_into_list(data)
- from webnotes.utils import file_manager
- file_manager.write_file(filename[1], dset)
- # ----------
- # on submit
- # ----------
+ def validate_item(self, item, count):
+ """ Validate item exists and non-serialized"""
+ det = sql("select item_code, has_serial_no from `tabItem` where name = '%s'"% cstr(item), as_dict = 1)
+ if not det:
+ msgprint("Item: " + cstr(item) + " mentioned at Row No. " + cstr(count) + "does not exist in the system")
+ self.validated = 0
+ elif det and det[0]['has_serial_no'] == 'Yes':
+ msgprint("""You cannot make Stock Reconciliation of items having serial no. \n
+ You can directly upload serial no to update their inventory. \n
+ Please remove Item Code : %s at Row No. %s""" %(cstr(item), cstr(count)))
+ self.validated = 0
+
+
+ def validate_warehouse(self, wh, count,):
+ """Validate warehouse exists"""
+ if not sql("select name from `tabWarehouse` where name = '%s'" % cstr(wh)):
+ msgprint("Warehouse: " + cstr(wh) + " mentioned at Row No. " + cstr(count) + " does not exist in the system")
+ self.validated = 0
+
+
+
+ def validate(self):
+ """Validate attachment data"""
+ #self.data = [['it', 'wh1', 20, 150]]
+ if self.doc.file_list:
+ self.get_reconciliation_data()
+
+
+
+ def get_system_stock(self, it, wh):
+ """get actual qty on reconciliation date and time as per system"""
+ bin = sql("select name from tabBin where item_code=%s and warehouse=%s", (it, wh))
+ prev_sle = bin and get_obj('Bin', bin[0][0]).get_sle_prev_timebucket(self.doc.reconciliation_date, self.doc.reconciliation_time) or {}
+ return {
+ 'actual_qty': prev_sle.get('bin_aqat', 0),
+ 'stock_uom' : sql("select stock_uom from tabItem where name = %s", it)[0][0],
+ 'val_rate' : prev_sle.get('valuation_rate', 0)
+ }
+
+
+ def make_sl_entry(self, is_submit, row, qty_diff, sys_stock):
+ """Make stock ledger entry"""
+ in_rate = self.get_incoming_rate(row, qty_diff, sys_stock)
+ values = [{
+ 'item_code' : row[0],
+ 'warehouse' : row[1],
+ 'transaction_date' : nowdate(),
+ 'posting_date' : self.doc.reconciliation_date,
+ 'posting_time' : self.doc.reconciliation_time,
+ 'voucher_type' : self.doc.doctype,
+ 'voucher_no' : self.doc.name,
+ 'voucher_detail_no' : self.doc.name,
+ 'actual_qty' : flt(is_submit) * flt(qty_diff),
+ 'stock_uom' : sys_stock['stock_uom'],
+ 'incoming_rate' : in_rate,
+ 'company' : get_defaults()['company'],
+ 'fiscal_year' : get_defaults()['fiscal_year'],
+ 'is_cancelled' : (is_submit==1) and 'No' or 'Yes',
+ 'batch_no' : '',
+ 'serial_no' : ''
+ }]
+ get_obj('Stock Ledger', 'Stock Ledger').update_stock(values)
+
+
+ def get_incoming_rate(self, row, qty_diff, sys_stock):
+ """Calculate incoming rate to maintain valuation rate"""
+ in_rate = flt(row[3]) + (flt(sys_stock['actual_qty'])*(flt(row[3]) - flt(sys_stock['val_rate'])))/ flt(qty_diff)
+ return in_rate
+
+
+ def do_stock_reco(self, is_submit = 1):
+ """
+ Make stock entry of qty diff, calculate incoming rate to maintain valuation rate.
+ If no qty diff, but diff in valuation rate, make (+1,-1) entry to update valuation
+ """
+ for row in self.data:
+ # Get qty as per system
+ sys_stock = self.get_system_stock(row[0],row[1])
+
+ # Diff between file and system
+ qty_diff = row[2] != '~' and flt(row[2]) - flt(sys_stock['actual_qty']) or 0
+ rate_diff = row[3] != '~' and flt(row[3]) - flt(sys_stock['val_rate']) or 0
+
+ # Make sl entry
+ if qty_diff:
+ self.make_sl_entry(is_submit, row, qty_diff, sys_stock)
+ elif rate_diff:
+ self.make_sl_entry(is_submit, row, 1, sys_stock)
+ sys_stock['val_rate'] = row[3]
+ sys_stock['actual_qty'] += 1
+ self.make_sl_entry(is_submit, row, -1, sys_stock)
+
+ if is_submit == 1:
+ self.add_data_in_CSV(qty_diff, rate_diff)
+
+ msgprint("Stock Reconciliation Completed Successfully...")
+
+
+ def add_data_in_CSV(self, qty_diff, rate_diff):
+ """Add diffs column in attached file"""
+
+ # add header
+ out = "'Item Code', 'Warehouse', 'Qty', 'Valuation Rate', 'Qty Diff', 'Val Rate Diff'"
+
+ # add data
+ for d in self.data:
+ s = [cstr(i) for i in d] + [cstr(qty_diff), cstr(rate_diff)]
+ out += "\n" + ','.join(s)
+
+ # write to file
+ fname = self.doc.file_list.split(',')
+ from webnotes.utils import file_manager
+ file_manager.write_file(fname[1], out)
+
+
+
def on_submit(self):
- self.stock_reconciliations(submit = 1)
+ if not self.doc.file_list:
+ msgprint("Please attach file before submitting.", raise_exception=1)
+ else:
+ self.do_stock_reco(is_submit = 1)
+
+
+
+ def on_cancel(self):
+ self.validate()
+ self.do_stock_reco(is_submit = -1)
diff --git a/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.txt b/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.txt
index 771068d..9a21130 100644
--- a/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.txt
+++ b/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.txt
@@ -5,16 +5,18 @@
{
'creation': '2010-08-08 17:09:26',
'docstatus': 0,
- 'modified': '2011-04-25 11:46:21',
+ 'modified': '2011-11-24 12:04:03',
'modified_by': 'Administrator',
'owner': 'Administrator'
},
# These values are common for all DocType
{
- '_last_update': '1309508840',
+ '_last_update': '1321617741',
'allow_attach': 1,
+ 'autoname': 'SR/.######',
'colour': 'White:FFF',
+ 'default_print_format': 'Standard',
'doctype': 'DocType',
'max_attachments': 1,
'module': 'Stock',
@@ -23,7 +25,8 @@
'section_style': 'Tray',
'server_code_error': ' ',
'show_in_menu': 0,
- 'version': 85
+ 'subject': 'Date: %(reconciliation_date)s, Time: %(reconciliation_time)s',
+ 'version': 107
},
# These values are common for all DocField
@@ -37,6 +40,7 @@
# These values are common for all DocPerm
{
+ 'amend': 0,
'doctype': 'DocPerm',
'name': '__common__',
'parent': 'Stock Reconciliation',
@@ -53,11 +57,9 @@
# DocPerm
{
- 'amend': 1,
'cancel': 1,
'create': 1,
'doctype': 'DocPerm',
- 'idx': 1,
'permlevel': 0,
'role': 'Material Manager',
'submit': 1,
@@ -66,11 +68,9 @@
# DocPerm
{
- 'amend': 0,
'cancel': 0,
'create': 0,
'doctype': 'DocPerm',
- 'idx': 2,
'permlevel': 1,
'role': 'Material Manager',
'submit': 0,
@@ -79,44 +79,21 @@
# DocPerm
{
- 'amend': 1,
'cancel': 1,
'create': 1,
'doctype': 'DocPerm',
- 'idx': 3,
'permlevel': 0,
'role': 'System Manager',
'submit': 1,
'write': 1
},
- # DocPerm
- {
- 'doctype': 'DocPerm',
- 'idx': 4,
- 'permlevel': 1,
- 'role': 'System Manager'
- },
-
# DocField
{
'doctype': 'DocField',
- 'fieldtype': 'Button',
- 'hidden': 1,
- 'idx': 1,
- 'label': 'Validate Data',
- 'oldfieldtype': 'Button',
- 'options': 'get_reconciliation_stock_details',
- 'permlevel': 0
- },
-
- # DocField
- {
- 'doctype': 'DocField',
- 'fieldtype': 'Section Break',
- 'idx': 2,
- 'label': 'Summary',
- 'oldfieldtype': 'Section Break',
+ 'fieldtype': 'HTML',
+ 'label': 'Steps',
+ 'options': '<div class="field_description"><b>Steps:</b><br>1. Enter Reconciliation Date and Time<br>2. Save the document<br>3. Attach csv file as per template.<br>4. Submit the document<br>5. Enter tilde (~) sign if no difference in qty or valuation rate</div>',
'permlevel': 0
},
@@ -125,14 +102,12 @@
'doctype': 'DocField',
'fieldname': 'reconciliation_date',
'fieldtype': 'Date',
- 'idx': 3,
'in_filter': 0,
'label': 'Reconciliation Date',
'oldfieldname': 'reconciliation_date',
'oldfieldtype': 'Date',
'permlevel': 0,
- 'reqd': 1,
- 'search_index': 1
+ 'reqd': 1
},
# DocField
@@ -140,7 +115,6 @@
'doctype': 'DocField',
'fieldname': 'reconciliation_time',
'fieldtype': 'Time',
- 'idx': 4,
'in_filter': 0,
'label': 'Reconciliation Time',
'oldfieldname': 'reconciliation_time',
@@ -152,97 +126,20 @@
# DocField
{
'doctype': 'DocField',
- 'fieldname': 'next_step',
- 'fieldtype': 'Select',
- 'idx': 5,
- 'label': 'Next Steps',
- 'oldfieldname': 'next_step',
- 'oldfieldtype': 'Select',
- 'options': 'Upload File and Save Document\nValidate Data\nSubmit Document\nCompleted',
- 'permlevel': 1
- },
-
- # DocField
- {
- 'doctype': 'DocField',
'fieldname': 'remark',
'fieldtype': 'Text',
- 'idx': 6,
'label': 'Remark',
'oldfieldname': 'remark',
'oldfieldtype': 'Text',
- 'permlevel': 1
- },
-
- # DocField
- {
- 'doctype': 'DocField',
- 'fieldname': 'company',
- 'fieldtype': 'Link',
- 'idx': 7,
- 'in_filter': 1,
- 'label': 'Company',
- 'oldfieldname': 'company',
- 'oldfieldtype': 'Link',
- 'options': 'Company',
- 'permlevel': 0,
- 'search_index': 0
- },
-
- # DocField
- {
- 'doctype': 'DocField',
- 'fieldname': 'fiscal_year',
- 'fieldtype': 'Select',
- 'idx': 8,
- 'in_filter': 1,
- 'label': 'Fiscal Year',
- 'oldfieldname': 'fiscal_year',
- 'oldfieldtype': 'Select',
- 'options': 'link:Fiscal Year',
- 'permlevel': 0,
- 'search_index': 0
- },
-
- # DocField
- {
- 'doctype': 'DocField',
- 'fieldname': 'amended_from',
- 'fieldtype': 'Data',
- 'idx': 9,
- 'label': 'Amended From',
- 'permlevel': 1
- },
-
- # DocField
- {
- 'doctype': 'DocField',
- 'fieldname': 'amendment_date',
- 'fieldtype': 'Date',
- 'idx': 10,
- 'label': 'Amendment Date',
- 'permlevel': 1
- },
-
- # DocField
- {
- 'doctype': 'DocField',
- 'fieldtype': 'Section Break',
- 'idx': 11,
- 'label': 'Attachment',
- 'oldfieldtype': 'Section Break',
'permlevel': 0
},
# DocField
{
'doctype': 'DocField',
- 'fieldtype': 'HTML',
- 'idx': 12,
- 'label': 'Attachment HTML',
- 'oldfieldtype': 'HTML',
- 'options': 'The attachment must be a CSV(Comma Seperated Value) file',
- 'permlevel': 1
+ 'fieldtype': 'Button',
+ 'label': 'Download Template',
+ 'permlevel': 0
},
# DocField
@@ -251,8 +148,8 @@
'fieldname': 'file_list',
'fieldtype': 'Text',
'hidden': 1,
- 'idx': 13,
'label': 'File List',
+ 'no_copy': 1,
'oldfieldname': 'file_list',
'oldfieldtype': 'Text',
'permlevel': 1,
diff --git a/erpnext/stock/doctype/stock_uom_replace_utility/stock_uom_replace_utility.py b/erpnext/stock/doctype/stock_uom_replace_utility/stock_uom_replace_utility.py
index f8ac737..0fa7a3b 100644
--- a/erpnext/stock/doctype/stock_uom_replace_utility/stock_uom_replace_utility.py
+++ b/erpnext/stock/doctype/stock_uom_replace_utility/stock_uom_replace_utility.py
@@ -85,7 +85,7 @@
for w in wh:
bin = sql("select name from `tabBin` where item_code = '%s' and warehouse = '%s'" % (self.doc.item_code, w[0]))
if bin and bin[0][0]:
- get_obj("Bin", bin[0][0]).update_item_valuation(sle_id = '', posting_date = '', posting_time = '')
+ get_obj("Bin", bin[0][0]).update_entries_after(posting_date = '', posting_time = '')
# acknowledge user
msgprint("Item Valuation Updated Successfully.")
diff --git a/erpnext/stock/doctype/valuation_control/valuation_control.py b/erpnext/stock/doctype/valuation_control/valuation_control.py
index 131c71b..f37b7e7 100644
--- a/erpnext/stock/doctype/valuation_control/valuation_control.py
+++ b/erpnext/stock/doctype/valuation_control/valuation_control.py
@@ -1,82 +1,114 @@
# Please edit this list and import only required elements
-import webnotes
+import webnotes, unittest
-from webnotes.utils import add_days, add_months, add_years, cint, cstr, date_diff, default_fields, flt, fmt_money, formatdate, generate_hash, getTraceback, get_defaults, get_first_day, get_last_day, getdate, has_common, month_name, now, nowdate, replace_newlines, sendmail, set_default, str_esc_quote, user_format, validate_email_add
-from webnotes.model import db_exists
-from webnotes.model.doc import Document, addchild, removechild, getchildren, make_autoname, SuperDocType
-from webnotes.model.doclist import getlist, copy_doclist
-from webnotes.model.code import get_obj, get_server_obj, run_server_obj, updatedb, check_syntax
-from webnotes import session, form, is_testing, msgprint, errprint
+from webnotes.utils import flt
+from webnotes.model.code import get_obj
-set = webnotes.conn.set
-sql = webnotes.conn.sql
-get_value = webnotes.conn.get_value
-in_transaction = webnotes.conn.in_transaction
-convert_to_lists = webnotes.conn.convert_to_lists
+class TestValuationControl(unittest.TestCase):
+ def setUp(self):
+ webnotes.conn.begin()
+
+ def tearDown(self):
+ webnotes.conn.rollback()
+
+ def test_fifo_rate(self):
+ """test fifo rate"""
+ fcfs_stack = [[40,500.0], [12,400.0]]
+ self.assertTrue(DocType(None, None).get_fifo_rate(fcfs_stack)==((40*500.0 + 12*400.0)/52.0))
-# -----------------------------------------------------------------------------------------
+ def test_serial_no_value(self):
+ """test serial no value"""
+ from webnotes.model.doc import Document
+
+ Document(fielddata = {
+ 'doctype': 'Item',
+ 'docstatus': 0,
+ 'name': 'it',
+ 'item_name': 'it',
+ 'item_code': 'it',
+ 'item_group': 'Default',
+ 'is_stock_item': 'Yes',
+ 'has_serial_no': 'Yes',
+ 'stock_uom': 'Nos',
+ 'is_sales_item': 'Yes',
+ 'is_purchase_item': 'Yes',
+ 'is_service_item': 'No',
+ 'is_sub_contracted_item': 'No',
+ 'is_pro_applicable': 'Yes',
+ 'is_manufactured_item': 'Yes'
+ }).save(1)
+
+ s1 = Document(fielddata= {
+ 'doctype':'Serial No',
+ 'serial_no':'s1',
+ 'item_code':'it',
+ 'purchase_rate': 100.0
+ })
+ s2 = Document(fielddata = s1.fields.copy())
+ s3 = Document(fielddata = s1.fields.copy())
+ s4 = Document(fielddata = s1.fields.copy())
+ s1.save(1)
+ s2.purchase_rate = 120.0
+ s2.serial_no = 's2'
+ s2.save(1)
+ s3.purchase_rate = 130.0
+ s3.serial_no = 's3'
+ s3.save(1)
+ s4.purchase_rate = 150.0
+ s4.serial_no = 's4'
+ s4.save(1)
+
+ r = DocType(None, None).get_serializable_inventory_rate('s1,s2,s3')
+ self.assertTrue(flt(r) - (100.0+120.0+130.0)/3 < 0.0001)
class DocType:
def __init__(self, d, dl):
self.doc, self.doclist = d, dl
- # Get FIFO Rate from Stack
- # -------------------------
- def get_fifo_rate(self, fcfs_stack, qty):
- fcfs_val = 0
- withdraw = flt(qty)
- while withdraw:
- batch = fcfs_stack[0]
- if batch[0] <= withdraw:
- # not enough or exactly same qty in current batch, clear batch
- withdraw -= batch[0]
- fcfs_val += (flt(batch[0]) * flt(batch[1]))
- fcfs_stack.pop(0)
- else:
- # all from current batch
- fcfs_val += (flt(withdraw) * flt(batch[1]))
- batch[0] -= withdraw
- withdraw = 0
- fcfs_rate = flt(fcfs_val) / flt(qty)
- return fcfs_rate
-
- # --------------------------------
- # get serializable inventory rate
- # --------------------------------
+ def get_fifo_rate(self, fcfs_stack):
+ """get FIFO (average) Rate from Stack"""
+ if not fcfs_stack:
+ return 0.0
+
+ total = sum(f[0] for f in fcfs_stack)
+ if not total:
+ return 0.0
+
+ return sum(f[0] * f[1] for f in fcfs_stack) / total
+
def get_serializable_inventory_rate(self, serial_no):
+ """get average value of serial numbers"""
+
sr_nos = get_obj("Stock Ledger").get_sr_no_list(serial_no)
- tot = 0
- for s in sr_nos:
- serial_no = s.strip()
- tot += flt(get_value('Serial No', serial_no, 'purchase_rate'))
- return tot / len(sr_nos)
+ return webnotes.conn.sql("""select avg(ifnull(purchase_rate, 0))
+ from `tabSerial No` where name in ("%s")""" % '", "'.join(sr_nos))[0][0] or 0.0
- # ---------------------
- # get valuation method
- # ---------------------
def get_valuation_method(self, item_code):
+ """get valuation method from item or default"""
val_method = webnotes.conn.get_value('Item', item_code, 'valuation_method')
if not val_method:
+ from webnotes.utils import get_defaults
val_method = get_defaults().get('valuation_method', 'FIFO')
return val_method
- # Get Incoming Rate based on valuation method
- # --------------------------------------------
def get_incoming_rate(self, posting_date, posting_time, item, warehouse, qty = 0, serial_no = ''):
+ """Get Incoming Rate based on valuation method"""
in_rate = 0
val_method = self.get_valuation_method(item)
bin_obj = get_obj('Warehouse',warehouse).get_bin(item)
if serial_no:
in_rate = self.get_serializable_inventory_rate(serial_no)
elif val_method == 'FIFO':
- in_rate = 0
+ # get rate based on the last item value?
if qty:
prev_sle = bin_obj.get_prev_sle(posting_date, posting_time)
- fcfs_stack = eval(prev_sle.get('fcfs_stack', '[]') or '[]')
- in_rate = fcfs_stack and self.get_fifo_rate(fcfs_stack, qty) or 0
+ if not prev_sle:
+ return 0.0
+ fcfs_stack = eval(prev_sle.get('fcfs_stack', '[]'))
+ in_rate = fcfs_stack and self.get_fifo_rate(fcfs_stack) or 0
elif val_method == 'Moving Average':
prev_sle = bin_obj.get_prev_sle(posting_date, posting_time)
in_rate = prev_sle and prev_sle.get('valuation_rate', 0) or 0
diff --git a/erpnext/stock/doctype/warehouse/warehouse.py b/erpnext/stock/doctype/warehouse/warehouse.py
index f3d600d..b9d560a 100644
--- a/erpnext/stock/doctype/warehouse/warehouse.py
+++ b/erpnext/stock/doctype/warehouse/warehouse.py
@@ -18,73 +18,88 @@
class DocType:
- def __init__(self, doc, doclist=[]):
- self.doc = doc
- self.doclist = doclist
-
- def get_bin(self, item_code):
- bin = sql("select name from tabBin where item_code = '%s' and warehouse = '%s'" % (item_code, self.doc.name))
- bin = bin and bin[0][0] or ''
- if not bin:
- if not self.doc.warehouse_type :
- msgprint("[Warehouse Type is Mandatory] Please Enter warehouse type in Warehouse " + self.doc.name)
- raise Exception
- bin = Document('Bin')
- bin.item_code = item_code
- bin.stock_uom = get_value('Item', item_code, 'stock_uom')
- bin.warehouse = self.doc.name
- bin.warehouse_type = self.doc.warehouse_type
- bin_obj = get_obj(doc=bin)
- bin_obj.validate()
- bin.save(1)
- bin = bin.name
- else:
- bin_obj = get_obj('Bin',bin)
+ def __init__(self, doc, doclist=[]):
+ self.doc = doc
+ self.doclist = doclist
+
+ def get_bin(self, item_code):
+ bin = sql("select name from tabBin where item_code = '%s' and warehouse = '%s'" % (item_code, self.doc.name))
+ bin = bin and bin[0][0] or ''
+ if not bin:
+ if not self.doc.warehouse_type :
+ msgprint("[Warehouse Type is Mandatory] Please Enter warehouse type in Warehouse " + self.doc.name)
+ raise Exception
+ bin = Document('Bin')
+ bin.item_code = item_code
+ bin.stock_uom = get_value('Item', item_code, 'stock_uom')
+ bin.warehouse = self.doc.name
+ bin.warehouse_type = self.doc.warehouse_type
+ bin_obj = get_obj(doc=bin)
+ bin_obj.validate()
+ bin.save(1)
+ bin = bin.name
+ else:
+ bin_obj = get_obj('Bin',bin)
- return bin_obj
-
+ return bin_obj
+
- def validate_asset(self, item_code):
- if sql("select is_asset_item from tabItem where name=%s", item_code)[0][0] == 'Yes' and self.doc.warehouse_type != 'Fixed Asset':
- msgprint("Fixed Asset Item %s can only be transacted in a Fixed Asset type Warehouse" % item_code)
- raise Exception
+ def validate_asset(self, item_code):
+ if sql("select is_asset_item from tabItem where name=%s", item_code)[0][0] == 'Yes' and self.doc.warehouse_type != 'Fixed Asset':
+ msgprint("Fixed Asset Item %s can only be transacted in a Fixed Asset type Warehouse" % item_code)
+ raise Exception
- # update bin
- # ----------
- def update_bin(self, actual_qty, reserved_qty, ordered_qty, indented_qty, planned_qty, item_code, dt, sle_id = '',posting_time = '', serial_no = '', is_cancelled = 'No'):
- self.validate_asset(item_code)
- it_det = get_value('Item', item_code, 'is_stock_item')
- if it_det and it_det == 'Yes':
- bin = self.get_bin(item_code)
- bin.update_stock(actual_qty, reserved_qty, ordered_qty, indented_qty, planned_qty, dt, sle_id, posting_time, serial_no, is_cancelled)
- return bin
- else:
- msgprint("[Stock Update] Ignored %s since it is not a stock item" % item_code)
+ # update bin
+ # ----------
+ def update_bin(self, actual_qty, reserved_qty, ordered_qty, indented_qty, planned_qty, item_code, dt, sle_id = '',posting_time = '', serial_no = '', is_cancelled = 'No',doc_type='',doc_name='',is_amended='No'):
+ self.validate_asset(item_code)
+ it_det = get_value('Item', item_code, 'is_stock_item')
+ if it_det and it_det == 'Yes':
+ bin = self.get_bin(item_code)
+ bin.update_stock(actual_qty, reserved_qty, ordered_qty, indented_qty, planned_qty, dt, sle_id, posting_time, serial_no, is_cancelled,doc_type,doc_name,is_amended)
+ return bin
+ else:
+ msgprint("[Stock Update] Ignored %s since it is not a stock item" % item_code)
- # repost stock
- # ------------
- def repost_stock(self):
- bl = sql("select name from tabBin where warehouse=%s", self.doc.name)
- for b in bl:
- bobj = get_obj('Bin',b[0])
- bobj.update_item_valuation(posting_date = '2000-01-01', posting_time = '12:00')
+ # repost stock
+ # ------------
+ def repost_stock(self):
+ bl = sql("select name from tabBin where warehouse=%s", self.doc.name)
+ for b in bl:
+ bobj = get_obj('Bin',b[0])
+ bobj.update_entries_after(posting_date = '0000-00-00', posting_time = '00:00')
- sql("COMMIT")
- sql("START TRANSACTION")
+ sql("COMMIT")
+ sql("START TRANSACTION")
- def check_state(self):
- return "\n" + "\n".join([i[0] for i in sql("select state_name from `tabState` where `tabState`.country='%s' " % self.doc.country)])
+ def check_state(self):
+ return "\n" + "\n".join([i[0] for i in sql("select state_name from `tabState` where `tabState`.country='%s' " % self.doc.country)])
- def validate(self):
- if self.doc.email_id:
- if not validate_email_add(self.doc.email_id):
- msgprint("Please enter valid Email Id.")
- raise Exception
- if not self.doc.warehouse_type:
- msgprint("[Warehouse Type is Mandatory] Please Enter Please Entry warehouse type in Warehouse " + self.doc.name)
- raise Exception
- wt = sql("select warehouse_type from `tabWarehouse` where name ='%s'" % self.doc.name)
- if cstr(self.doc.warehouse_type) != cstr(wt and wt[0][0] or ''):
- sql("update `tabStock Ledger Entry` set warehouse_type = '%s' where warehouse = '%s'" % (self.doc.warehouse_type, self.doc.name))
- msgprint("All Stock Ledger Entries Updated.")
+ def validate(self):
+ if self.doc.email_id:
+ if not validate_email_add(self.doc.email_id):
+ msgprint("Please enter valid Email Id.")
+ raise Exception
+ if not self.doc.warehouse_type:
+ msgprint("[Warehouse Type is Mandatory] Please Enter Please Entry warehouse type in Warehouse " + self.doc.name)
+ raise Exception
+ wt = sql("select warehouse_type from `tabWarehouse` where name ='%s'" % self.doc.name)
+ if cstr(self.doc.warehouse_type) != cstr(wt and wt[0][0] or ''):
+ sql("update `tabStock Ledger Entry` set warehouse_type = '%s' where warehouse = '%s'" % (self.doc.warehouse_type, self.doc.name))
+ msgprint("All Stock Ledger Entries Updated.")
+
+ def on_trash(self):
+ # delete bin
+ bins = sql("select * from `tabBin` where warehouse = %s", self.doc.name, as_dict=1)
+ for d in bins:
+ if d['actual_qty'] or d['reserved_qty'] or d['ordered_qty'] or d['indented_qty'] or d['projected_qty'] or d['planned_qty']:
+ msgprint("Warehouse: %s can not be deleted as qty exists for item: %s" % (self.doc.name, d['item_code']), raise_exception=1)
+ else:
+ sql("delete from `tabBin` where name = %s", d['name'])
+
+ # delete cancelled sle
+ if sql("select name from `tabStock Ledger Entry` where warehouse = %s and ifnull('is_cancelled', '') = 'No'", self.doc.name):
+ mdgprint("Warehosue can not be deleted as stock ledger entry exists for this warehosue.", raise_exception=1)
+ else:
+ sql("delete from `tabStock Ledger Entry` where warehouse = %s", self.doc.name)
diff --git a/erpnext/stock/doctype/warehouse/warehouse.txt b/erpnext/stock/doctype/warehouse/warehouse.txt
index da29dfa..87b0eda 100644
--- a/erpnext/stock/doctype/warehouse/warehouse.txt
+++ b/erpnext/stock/doctype/warehouse/warehouse.txt
@@ -5,14 +5,14 @@
{
'creation': '2010-08-08 17:09:30',
'docstatus': 0,
- 'modified': '2011-09-28 16:19:59',
+ 'modified': '2011-11-15 15:06:24',
'modified_by': 'Administrator',
'owner': 'Administrator'
},
# These values are common for all DocType
{
- '_last_update': '1311621379',
+ '_last_update': '1319016431',
'allow_trash': 1,
'autoname': 'field:warehouse_name',
'colour': 'White:FFF',
@@ -25,7 +25,7 @@
'section_style': 'Tabbed',
'server_code_error': ' ',
'show_in_menu': 0,
- 'version': 56
+ 'version': 58
},
# These values are common for all DocField
@@ -319,27 +319,6 @@
# DocField
{
- 'allow_on_submit': 0,
- 'doctype': 'DocField',
- 'fieldname': 'country',
- 'fieldtype': 'Link',
- 'hidden': 0,
- 'in_filter': 0,
- 'label': 'Country',
- 'no_copy': 0,
- 'oldfieldname': 'country',
- 'oldfieldtype': 'Link',
- 'options': 'Country',
- 'permlevel': 0,
- 'print_hide': 0,
- 'report_hide': 0,
- 'reqd': 0,
- 'search_index': 0,
- 'trigger': 'Client'
- },
-
- # DocField
- {
'colour': 'White:FFF',
'doctype': 'DocField',
'fieldname': 'state',
diff --git a/erpnext/support/doctype/support_ticket/__init__.py b/erpnext/support/doctype/support_ticket/__init__.py
index 23c4059..f629cbd 100644
--- a/erpnext/support/doctype/support_ticket/__init__.py
+++ b/erpnext/support/doctype/support_ticket/__init__.py
@@ -49,6 +49,8 @@
st.make_response_record(content, mail.mail['From'], content_type)
webnotes.conn.set(st.doc, 'status', 'Open')
update_feed(st.doc)
+ # extract attachments
+ self.save_attachments(st.doc, mail.attachments)
return
# new ticket
@@ -61,6 +63,7 @@
d.status = 'Open'
try:
d.save(1)
+
# update feed
update_feed(d)
@@ -70,6 +73,30 @@
except:
d.description = 'Unable to extract message'
d.save(1)
+
+ else:
+ # extract attachments
+ self.save_attachments(d, mail.attachments)
+
+
+ def save_attachments(self, doc, attachment_list=[]):
+ """
+ Saves attachments from email
+
+ attachment_list is a list of dict containing:
+ 'filename', 'content', 'content-type'
+ """
+ from webnotes.utils.file_manager import save_file, add_file_list
+ for attachment in attachment_list:
+ webnotes.conn.begin()
+ fid = save_file(attachment['filename'], attachment['content'], 'Support')
+ status = add_file_list('Support Ticket', doc.name, attachment['filename'], fid)
+ if not status:
+ doc.description = doc.description \
+ + "\nCould not attach: " + str(attachment['filename'])
+ doc.save()
+ webnotes.conn.commit()
+
def send_auto_reply(self, d):
"""
diff --git a/erpnext/support/doctype/support_ticket/support_ticket.txt b/erpnext/support/doctype/support_ticket/support_ticket.txt
index 8164764..0e3dee6 100644
--- a/erpnext/support/doctype/support_ticket/support_ticket.txt
+++ b/erpnext/support/doctype/support_ticket/support_ticket.txt
@@ -3,9 +3,9 @@
# These values are common in all dictionaries
{
- 'creation': '2011-05-23 09:01:10',
+ 'creation': '2011-05-23 10:00:38',
'docstatus': 0,
- 'modified': '2011-07-25 14:45:28',
+ 'modified': '2011-12-27 17:40:25',
'modified_by': 'Administrator',
'owner': 'Administrator'
},
@@ -13,6 +13,7 @@
# These values are common for all DocType
{
'_last_update': '1311584009',
+ 'allow_attach': 1,
'allow_trash': 1,
'autoname': 'SUP.######',
'colour': 'White:FFF',
@@ -25,7 +26,7 @@
'show_in_menu': 0,
'subject': '%(subject)s',
'tag_fields': 'status,allocated_to',
- 'version': 144
+ 'version': 149
},
# These values are common for all DocField
@@ -39,12 +40,14 @@
# These values are common for all DocPerm
{
+ 'amend': 0,
'doctype': 'DocPerm',
'name': '__common__',
'parent': 'Support Ticket',
'parentfield': 'permissions',
'parenttype': 'DocType',
- 'read': 1
+ 'read': 1,
+ 'submit': 0
},
# DocType, Support Ticket
@@ -55,23 +58,19 @@
# DocPerm
{
- 'amend': 0,
'cancel': 0,
'create': 1,
'doctype': 'DocPerm',
- 'idx': 1,
'permlevel': 0,
'role': 'Guest',
- 'submit': 0,
'write': 1
},
# DocPerm
{
+ 'cancel': 0,
'create': 1,
'doctype': 'DocPerm',
- 'idx': 2,
- 'match': 'customer',
'permlevel': 0,
'role': 'Customer',
'write': 1
@@ -82,7 +81,6 @@
'cancel': 1,
'create': 1,
'doctype': 'DocPerm',
- 'idx': 3,
'permlevel': 0,
'role': 'Support Team',
'write': 1
@@ -93,8 +91,6 @@
'cancel': 0,
'create': 0,
'doctype': 'DocPerm',
- 'idx': 4,
- 'match': 'allocated_to',
'permlevel': 1,
'role': 'Support Team',
'write': 1
@@ -102,10 +98,12 @@
# DocPerm
{
+ 'cancel': 0,
+ 'create': 0,
'doctype': 'DocPerm',
- 'idx': 5,
'permlevel': 2,
- 'role': 'Support Team'
+ 'role': 'Support Team',
+ 'write': 0
},
# DocField
@@ -115,7 +113,6 @@
'doctype': 'DocField',
'fieldname': 'status',
'fieldtype': 'Select',
- 'idx': 1,
'in_filter': 0,
'label': 'Status',
'no_copy': 1,
@@ -132,7 +129,6 @@
'doctype': 'DocField',
'fieldname': 'subject',
'fieldtype': 'Text',
- 'idx': 2,
'in_filter': 1,
'label': 'Subject',
'permlevel': 0,
@@ -145,7 +141,6 @@
'doctype': 'DocField',
'fieldname': 'raised_by',
'fieldtype': 'Data',
- 'idx': 3,
'in_filter': 1,
'label': 'Raised By (Email)',
'oldfieldname': 'raised_by',
@@ -160,7 +155,6 @@
'doctype': 'DocField',
'fieldname': 'description',
'fieldtype': 'Text',
- 'idx': 4,
'label': 'Description',
'oldfieldname': 'problem_description',
'oldfieldtype': 'Text',
@@ -173,7 +167,6 @@
'depends_on': 'eval:!doc.__islocal',
'doctype': 'DocField',
'fieldtype': 'HTML',
- 'idx': 5,
'label': 'Thread HTML',
'permlevel': 1
},
@@ -184,7 +177,6 @@
'doctype': 'DocField',
'fieldname': 'new_response',
'fieldtype': 'Text',
- 'idx': 6,
'label': 'New Response',
'permlevel': 0
},
@@ -194,8 +186,8 @@
'depends_on': 'eval:!doc.__islocal',
'doctype': 'DocField',
'fieldtype': 'Button',
- 'idx': 7,
'label': 'Send',
+ 'options': 'send_response',
'permlevel': 0
},
@@ -204,7 +196,6 @@
'colour': 'White:FFF',
'doctype': 'DocField',
'fieldtype': 'Section Break',
- 'idx': 8,
'label': 'Additional Info',
'permlevel': 1
},
@@ -214,7 +205,6 @@
'depends_on': 'eval:!doc.__islocal',
'doctype': 'DocField',
'fieldtype': 'Column Break',
- 'idx': 9,
'oldfieldtype': 'Column Break',
'permlevel': 1,
'width': '50%'
@@ -226,7 +216,6 @@
'doctype': 'DocField',
'fieldname': 'customer',
'fieldtype': 'Link',
- 'idx': 10,
'in_filter': 1,
'label': 'Customer',
'oldfieldname': 'customer',
@@ -244,7 +233,6 @@
'doctype': 'DocField',
'fieldname': 'customer_name',
'fieldtype': 'Data',
- 'idx': 11,
'in_filter': 1,
'label': 'Customer Name',
'oldfieldname': 'customer_name',
@@ -259,7 +247,6 @@
'doctype': 'DocField',
'fieldname': 'address_display',
'fieldtype': 'Small Text',
- 'idx': 12,
'label': 'Address',
'permlevel': 2
},
@@ -269,7 +256,6 @@
'doctype': 'DocField',
'fieldname': 'contact_display',
'fieldtype': 'Data',
- 'idx': 13,
'label': 'Contact Name',
'permlevel': 2
},
@@ -279,7 +265,6 @@
'doctype': 'DocField',
'fieldname': 'contact_mobile',
'fieldtype': 'Data',
- 'idx': 14,
'label': 'Mobile No',
'permlevel': 2
},
@@ -289,7 +274,6 @@
'doctype': 'DocField',
'fieldname': 'contact_email',
'fieldtype': 'Data',
- 'idx': 15,
'label': 'Contact Email',
'oldfieldname': 'contact_no',
'oldfieldtype': 'Data',
@@ -302,7 +286,6 @@
'doctype': 'DocField',
'fieldname': 'opening_date',
'fieldtype': 'Date',
- 'idx': 16,
'label': 'Opening Date',
'no_copy': 1,
'oldfieldname': 'opening_date',
@@ -315,7 +298,6 @@
'doctype': 'DocField',
'fieldname': 'opening_time',
'fieldtype': 'Time',
- 'idx': 17,
'label': 'Opening Time',
'no_copy': 1,
'oldfieldname': 'opening_time',
@@ -328,18 +310,17 @@
'depends_on': 'eval:!doc.__islocal',
'doctype': 'DocField',
'fieldtype': 'Column Break',
- 'idx': 18,
'oldfieldtype': 'Column Break',
'permlevel': 1
},
# DocField
{
+ 'colour': 'White:FFF',
'depends_on': 'eval:!doc.__islocal',
'doctype': 'DocField',
'fieldname': 'allocated_to',
'fieldtype': 'Link',
- 'idx': 19,
'in_filter': 1,
'label': 'Allocated To',
'oldfieldname': 'allocated_to',
@@ -355,7 +336,6 @@
'doctype': 'DocField',
'fieldname': 'resolution_details',
'fieldtype': 'Text',
- 'idx': 20,
'label': 'Resolution Details',
'no_copy': 1,
'oldfieldname': 'resolution_details',
@@ -365,11 +345,11 @@
# DocField
{
+ 'colour': 'White:FFF',
'depends_on': 'eval:!doc.__islocal',
'doctype': 'DocField',
'fieldname': 'resolution_date',
'fieldtype': 'Date',
- 'idx': 21,
'in_filter': 0,
'label': 'Resolution Date',
'no_copy': 1,
@@ -385,7 +365,6 @@
'doctype': 'DocField',
'fieldname': 'resolution_time',
'fieldtype': 'Time',
- 'idx': 22,
'label': 'Resolution Time',
'oldfieldname': 'resolution_time',
'oldfieldtype': 'Time',
@@ -399,8 +378,19 @@
'fieldname': 'content_type',
'fieldtype': 'Data',
'hidden': 1,
- 'idx': 23,
'label': 'Content Type',
'permlevel': 0
+ },
+
+ # DocField
+ {
+ 'doctype': 'DocField',
+ 'fieldname': 'file_list',
+ 'fieldtype': 'Text',
+ 'hidden': 1,
+ 'label': 'File List',
+ 'no_copy': 1,
+ 'permlevel': 0,
+ 'print_hide': 1
}
]
\ No newline at end of file
diff --git a/erpnext/utilities/doctype/address/address.txt b/erpnext/utilities/doctype/address/address.txt
index 4f44806..776321b 100644
--- a/erpnext/utilities/doctype/address/address.txt
+++ b/erpnext/utilities/doctype/address/address.txt
@@ -3,26 +3,28 @@
# These values are common in all dictionaries
{
- 'creation': '2011-05-24 10:14:48',
+ 'creation': '2011-05-24 14:57:59',
'docstatus': 0,
- 'modified': '2011-06-09 12:28:53',
+ 'modified': '2011-11-23 13:21:00',
'modified_by': 'Administrator',
'owner': 'Administrator'
},
# These values are common for all DocType
{
- '_last_update': '1307602735',
+ '_last_update': '1319016431',
'allow_trash': 1,
'colour': 'White:FFF',
+ 'default_print_format': 'Standard',
'doctype': 'DocType',
'document_type': 'Master',
'in_dialog': 1,
'module': 'Utilities',
'name': '__common__',
+ 'search_fields': 'customer, supplier, sales_partner, country, state',
'section_style': 'Simple',
'show_in_menu': 0,
- 'version': 42
+ 'version': 43
},
# These values are common for all DocField
@@ -39,7 +41,6 @@
'cancel': 1,
'create': 1,
'doctype': 'DocPerm',
- 'idx': 1,
'name': '__common__',
'parent': 'Address',
'parentfield': 'permissions',
@@ -66,7 +67,6 @@
'colour': 'White:FFF',
'doctype': 'DocField',
'fieldtype': 'Section Break',
- 'idx': 1,
'label': 'Address Details',
'permlevel': 0
},
@@ -78,7 +78,6 @@
'doctype': 'DocField',
'fieldname': 'address_type',
'fieldtype': 'Data',
- 'idx': 2,
'label': 'Address Type',
'permlevel': 0,
'reqd': 1
@@ -90,7 +89,6 @@
'doctype': 'DocField',
'fieldname': 'address_line1',
'fieldtype': 'Data',
- 'idx': 3,
'label': 'Address Line1',
'permlevel': 0,
'reqd': 1
@@ -101,7 +99,6 @@
'doctype': 'DocField',
'fieldname': 'address_line2',
'fieldtype': 'Data',
- 'idx': 4,
'label': 'Address Line2',
'permlevel': 0
},
@@ -112,12 +109,11 @@
'doctype': 'DocField',
'fieldname': 'city',
'fieldtype': 'Data',
- 'idx': 5,
'in_filter': 1,
'label': 'City/Town',
'permlevel': 0,
'reqd': 1,
- 'search_index': 0
+ 'search_index': 1
},
# DocField
@@ -125,11 +121,10 @@
'doctype': 'DocField',
'fieldname': 'pincode',
'fieldtype': 'Data',
- 'idx': 6,
'in_filter': 1,
'label': 'Pincode',
'permlevel': 0,
- 'search_index': 0
+ 'search_index': 1
},
# DocField
@@ -138,13 +133,12 @@
'doctype': 'DocField',
'fieldname': 'country',
'fieldtype': 'Select',
- 'idx': 7,
'in_filter': 1,
'label': 'Country',
'options': 'link:Country',
'permlevel': 0,
'reqd': 1,
- 'search_index': 0,
+ 'search_index': 1,
'trigger': 'Client'
},
@@ -154,7 +148,6 @@
'doctype': 'DocField',
'fieldname': 'state',
'fieldtype': 'Data',
- 'idx': 8,
'in_filter': 1,
'label': 'State',
'options': 'Suggest',
@@ -166,7 +159,6 @@
{
'doctype': 'DocField',
'fieldtype': 'Column Break',
- 'idx': 9,
'permlevel': 0,
'print_hide': 0,
'width': '50%'
@@ -177,7 +169,6 @@
'doctype': 'DocField',
'fieldname': 'phone',
'fieldtype': 'Data',
- 'idx': 10,
'label': 'Phone',
'permlevel': 0,
'reqd': 1
@@ -188,7 +179,6 @@
'doctype': 'DocField',
'fieldname': 'email_id',
'fieldtype': 'Data',
- 'idx': 11,
'label': 'Email Id',
'permlevel': 0
},
@@ -198,7 +188,7 @@
'doctype': 'DocField',
'fieldname': 'fax',
'fieldtype': 'Data',
- 'idx': 12,
+ 'in_filter': 1,
'label': 'Fax',
'permlevel': 0
},
@@ -210,12 +200,9 @@
'doctype': 'DocField',
'fieldname': 'customer',
'fieldtype': 'Link',
- 'idx': 13,
'label': 'Customer',
'options': 'Customer',
- 'permlevel': 0,
- 'search_index': 1,
- 'trigger': 'Client'
+ 'permlevel': 0
},
# DocField
@@ -225,7 +212,7 @@
'doctype': 'DocField',
'fieldname': 'customer_name',
'fieldtype': 'Data',
- 'idx': 14,
+ 'in_filter': 1,
'label': 'Customer Name',
'permlevel': 1
},
@@ -237,12 +224,9 @@
'doctype': 'DocField',
'fieldname': 'supplier',
'fieldtype': 'Link',
- 'idx': 15,
'label': 'Supplier',
'options': 'Supplier',
- 'permlevel': 0,
- 'search_index': 1,
- 'trigger': 'Client'
+ 'permlevel': 0
},
# DocField
@@ -252,9 +236,10 @@
'doctype': 'DocField',
'fieldname': 'supplier_name',
'fieldtype': 'Data',
- 'idx': 16,
+ 'in_filter': 1,
'label': 'Supplier Name',
- 'permlevel': 1
+ 'permlevel': 1,
+ 'search_index': 0
},
# DocField
@@ -264,7 +249,6 @@
'doctype': 'DocField',
'fieldname': 'sales_partner',
'fieldtype': 'Link',
- 'idx': 17,
'label': 'Sales Partner',
'options': 'Sales Partner',
'permlevel': 0
@@ -278,7 +262,6 @@
'doctype': 'DocField',
'fieldname': 'is_primary_address',
'fieldtype': 'Check',
- 'idx': 18,
'label': 'Is Primary Address',
'permlevel': 0
},
@@ -291,7 +274,6 @@
'doctype': 'DocField',
'fieldname': 'is_shipping_address',
'fieldtype': 'Check',
- 'idx': 19,
'label': 'Is Shipping Address',
'permlevel': 0
},
@@ -301,7 +283,6 @@
'doctype': 'DocField',
'fieldname': 'trash_reason',
'fieldtype': 'Small Text',
- 'idx': 20,
'label': 'Trash Reason',
'permlevel': 0
}
diff --git a/erpnext/utilities/doctype/contact/contact.txt b/erpnext/utilities/doctype/contact/contact.txt
index 43fa4d7..e5a6757 100644
--- a/erpnext/utilities/doctype/contact/contact.txt
+++ b/erpnext/utilities/doctype/contact/contact.txt
@@ -5,16 +5,17 @@
{
'creation': '2010-08-08 17:08:55',
'docstatus': 0,
- 'modified': '2011-05-26 11:00:36',
+ 'modified': '2011-12-19 14:11:08',
'modified_by': 'Administrator',
'owner': 'Administrator'
},
# These values are common for all DocType
{
- '_last_update': '1306307671',
+ '_last_update': '1316075905',
'allow_trash': 1,
'colour': 'White:FFF',
+ 'default_print_format': 'Standard',
'doctype': 'DocType',
'document_type': 'Master',
'in_create': 0,
@@ -25,7 +26,7 @@
'server_code_error': ' ',
'show_in_menu': 0,
'subject': '%(first_name)s %(last_name)s - Email: %(email_id)s | Contact: %(phone)s | Mobile: %(mobile_no)s',
- 'version': 242
+ 'version': 243
},
# These values are common for all DocField
@@ -56,7 +57,6 @@
# DocPerm
{
'doctype': 'DocPerm',
- 'idx': 1,
'permlevel': 0,
'role': 'Sales User'
},
@@ -64,7 +64,6 @@
# DocPerm
{
'doctype': 'DocPerm',
- 'idx': 2,
'permlevel': 0,
'role': 'Purchase User'
},
@@ -75,7 +74,6 @@
'cancel': 1,
'create': 1,
'doctype': 'DocPerm',
- 'idx': 3,
'permlevel': 0,
'role': 'Sales Master Manager',
'submit': 0,
@@ -85,7 +83,6 @@
# DocPerm
{
'doctype': 'DocPerm',
- 'idx': 4,
'permlevel': 1,
'role': 'All',
'write': 1
@@ -94,7 +91,6 @@
# DocPerm
{
'doctype': 'DocPerm',
- 'idx': 5,
'permlevel': 2,
'role': 'All'
},
@@ -104,7 +100,6 @@
'cancel': 1,
'create': 1,
'doctype': 'DocPerm',
- 'idx': 6,
'permlevel': 0,
'role': 'Purchase Master Manager',
'write': 1
@@ -115,7 +110,6 @@
'cancel': 1,
'create': 1,
'doctype': 'DocPerm',
- 'idx': 7,
'permlevel': 0,
'role': 'System Manager',
'write': 1
@@ -126,7 +120,6 @@
'colour': 'White:FFF',
'doctype': 'DocField',
'fieldtype': 'Section Break',
- 'idx': 1,
'label': 'Contact Details',
'oldfieldtype': 'Section Break',
'permlevel': 0
@@ -136,7 +129,6 @@
{
'doctype': 'DocField',
'fieldtype': 'Column Break',
- 'idx': 2,
'oldfieldtype': 'Column Break',
'permlevel': 0,
'width': '50%'
@@ -147,7 +139,6 @@
'doctype': 'DocField',
'fieldname': 'first_name',
'fieldtype': 'Data',
- 'idx': 3,
'label': 'First Name',
'oldfieldname': 'first_name',
'oldfieldtype': 'Data',
@@ -160,7 +151,6 @@
'doctype': 'DocField',
'fieldname': 'last_name',
'fieldtype': 'Data',
- 'idx': 4,
'label': 'Last Name',
'oldfieldname': 'last_name',
'oldfieldtype': 'Data',
@@ -174,7 +164,6 @@
'doctype': 'DocField',
'fieldname': 'customer',
'fieldtype': 'Link',
- 'idx': 5,
'label': 'Customer',
'oldfieldname': 'customer',
'oldfieldtype': 'Link',
@@ -191,7 +180,6 @@
'doctype': 'DocField',
'fieldname': 'customer_name',
'fieldtype': 'Data',
- 'idx': 6,
'label': 'Customer Name',
'permlevel': 1
},
@@ -203,7 +191,6 @@
'doctype': 'DocField',
'fieldname': 'supplier',
'fieldtype': 'Link',
- 'idx': 7,
'label': 'Supplier',
'options': 'Supplier',
'permlevel': 0,
@@ -218,7 +205,6 @@
'doctype': 'DocField',
'fieldname': 'supplier_name',
'fieldtype': 'Data',
- 'idx': 8,
'label': 'Supplier Name',
'permlevel': 1
},
@@ -230,7 +216,6 @@
'doctype': 'DocField',
'fieldname': 'sales_partner',
'fieldtype': 'Link',
- 'idx': 9,
'label': 'Sales Partner',
'options': 'Sales Partner',
'permlevel': 0
@@ -244,7 +229,6 @@
'doctype': 'DocField',
'fieldname': 'is_primary_contact',
'fieldtype': 'Check',
- 'idx': 10,
'label': 'Is Primary Contact',
'oldfieldname': 'is_primary_contact',
'oldfieldtype': 'Select',
@@ -255,7 +239,6 @@
{
'doctype': 'DocField',
'fieldtype': 'Column Break',
- 'idx': 11,
'oldfieldtype': 'Column Break',
'permlevel': 0,
'width': '50%'
@@ -266,7 +249,6 @@
'doctype': 'DocField',
'fieldname': 'email_id',
'fieldtype': 'Data',
- 'idx': 12,
'label': 'Email Id',
'oldfieldname': 'email_id',
'oldfieldtype': 'Data',
@@ -279,7 +261,6 @@
'doctype': 'DocField',
'fieldname': 'phone',
'fieldtype': 'Data',
- 'idx': 13,
'label': 'Phone',
'oldfieldname': 'contact_no',
'oldfieldtype': 'Data',
@@ -292,7 +273,6 @@
'doctype': 'DocField',
'fieldname': 'mobile_no',
'fieldtype': 'Data',
- 'idx': 14,
'label': 'Mobile No',
'oldfieldname': 'mobile_no',
'oldfieldtype': 'Data',
@@ -306,7 +286,6 @@
'doctype': 'DocField',
'fieldname': 'department',
'fieldtype': 'Data',
- 'idx': 15,
'label': 'Department',
'options': 'Suggest',
'permlevel': 0
@@ -319,7 +298,6 @@
'doctype': 'DocField',
'fieldname': 'designation',
'fieldtype': 'Data',
- 'idx': 16,
'label': 'Designation',
'options': 'Suggest',
'permlevel': 0
@@ -330,7 +308,6 @@
'doctype': 'DocField',
'fieldname': 'trash_reason',
'fieldtype': 'Small Text',
- 'idx': 17,
'label': 'Trash Reason',
'oldfieldname': 'trash_reason',
'oldfieldtype': 'Small Text',
diff --git a/erpnext/utilities/doctype/reposting_tool/reposting_tool.py b/erpnext/utilities/doctype/reposting_tool/reposting_tool.py
index c4f021b..489a3b6 100644
--- a/erpnext/utilities/doctype/reposting_tool/reposting_tool.py
+++ b/erpnext/utilities/doctype/reposting_tool/reposting_tool.py
@@ -88,7 +88,7 @@
bin_act_qty = flt(bin_obj.doc.actual_qty)
try:
# udpate actual qty and item valuation
- bin_obj.update_item_valuation('', '2000-01-01', '00:00')
+ bin_obj.update_entries_after('0000-00-00', '00:00')
# get bin qty
qty_dict = self.get_bin_qty(bin_obj.doc.warehouse, bin_obj.doc.item_code)
diff --git a/erpnext/utilities/doctype/sms_control/sms_control.py b/erpnext/utilities/doctype/sms_control/sms_control.py
index a1edf83..c595158 100644
--- a/erpnext/utilities/doctype/sms_control/sms_control.py
+++ b/erpnext/utilities/doctype/sms_control/sms_control.py
@@ -63,7 +63,15 @@
def get_sender_name(self):
"returns name as SMS sender"
- return webnotes.conn.get_value('Manage Account', None, 'sms_sender_name') or 'ERPNext'
+ sender_name = webnotes.conn.get_value('Manage Account', None, 'sms_sender_name') or 'ERPNXT'
+ if len(sender_name) > 6:
+ msgprint("""
+ As per TRAI rule, sender name must be exactly 6 characters.
+ Kindly change sender name in Setup --> Global Defaults.
+
+ Note: Hyphen, space, numeric digit, special characters are not allowed.
+ """, raise_exception=1)
+ return sender_name
def get_contact_number(self, arg):
"returns mobile number of the contact"
diff --git a/index.html b/index.html
index cedc9dc..a085f8c 100644
--- a/index.html
+++ b/index.html
@@ -3,7 +3,7 @@
<meta charset="utf-8">
<title>ERPNext</title>
<meta name="author" content="">
- <script type="text/javascript">window._version_number="65"
+ <script type="text/javascript">window._version_number="340"
wn={}
wn.provide=function(namespace){var nsl=namespace.split('.');var l=nsl.length;var parent=window;for(var i=0;i<l;i++){var n=nsl[i];if(!parent[n]){parent[n]={}}
diff --git a/versions-master.db b/versions-master.db
index 3ffd092..728c868 100644
--- a/versions-master.db
+++ b/versions-master.db
Binary files differ