diff --git a/data/master.sql.gz b/data/master.sql.gz index 3d3e220c869..f3eaf3488a8 100644 Binary files a/data/master.sql.gz and b/data/master.sql.gz 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 19491102743..e58f738329b 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', @@ -116,17 +125,6 @@ 'validation_logic': 'docstatus =1' }, - # 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' - }, - # Table Mapper Detail { 'doctype': 'Table Mapper Detail', 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 94408e7a2b3..1744c4dc27e 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/Print Format/Cheque Printing Format/Cheque Printing Format.txt b/erpnext/accounts/Print Format/Cheque Printing Format/Cheque Printing Format.txt index e0d2bce9e6b..aa903116e0a 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 831630677fc..4da54436180 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': '\n \n\n\n \n \n \n \n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n

FORM No. 16 A

\n

Certificate No:

\n

[See rule 31 (1)(b)]

\n

Certifiction of deduction of tax at source under section 203 of the Income-tax Act, 1961

\n

[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

\n 196C; income of Foreign Institutional Investors from securities referred to in section 196D]\n
Name and address of person deducing taxAcknowledgement No.s of all quarterly statements of TDS under sub-section(3) of section 200 as provided by TIN Facilitation Centre or NSDL web-siteName and address of the person to whom payment is made or in whose account it is credited
\n \n

\n \n
\n
\n \n \n \n

\n \n
\n
\n \n Registration Details OF THE DEDUCTOR
\n \n
\n
\n \n
NATURE OF PAYMENT


\n
\n \n
\n
\n \n PAN NO. OF THE PAYEE
\n \n \n
\n
DETAILS OF PAYMENT, TAX DEDUCTION AND DEPOSIT OF TAX INTO CENTRAL GOVERNMENT ACCOUNT\n

(The deductor is to provide transaction wise details of tax deducted and deposited)

\n
\n \n
\n Certified that a sum of Rs. has been deducted at source and paid to the credit of the Central Government as per details given above



\n

Signature of person responsible for deduction of tax \n

\n \n \n \n \n \n \n \n \n \n
Place: Full Name:
Date: Designation:
\n
\n\n', + 'html': '\n \n\n\n \n \n \n \n \n \n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
\n
\n

FORM No. 16 A

\n

Certificate No:

\n

[See rule 31 (1)(b)]

\n

Certifiction of deduction of tax at source under section 203 of the Income-tax Act, 1961

\n

[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

\n 196C; income of Foreign Institutional Investors from securities referred to in section 196D]\n
Name and address of person deducing taxAcknowledgement No.s of all quarterly statements of TDS under sub-section(3) of section 200 as provided by TIN Facilitation Centre or NSDL web-siteName and address of the person to whom payment is made or in whose account it is credited
\n \n

\n \n
\n
\n \n \n \n

\n \n
\n
\n \n Registration Details OF THE DEDUCTOR
\n \n
\n
\n \n
NATURE OF PAYMENT


\n
\n \n
\n
\n \n PAN NO. OF THE PAYEE
\n \n \n
\n
DETAILS OF PAYMENT, TAX DEDUCTION AND DEPOSIT OF TAX INTO CENTRAL GOVERNMENT ACCOUNT\n

(The deductor is to provide transaction wise details of tax deducted and deposited)

\n
\n \n
\n Certified that a sum of Rs. has been deducted at source and paid to the credit of the Central Government as per details given above



\n

Signature of person responsible for deduction of tax \n

\n \n \n \n \n \n \n \n \n \n
Place: Full Name:
Date: Designation:
\n
\n\n', '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 00000000000..6a7e83589f1 --- /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': '\n\n\n\n\n\n\n
\n\n\n\n\n\n\n\n\n
NO: DATE:
M/s
\n\n
\n \n\n
\n\n\n
\n \n
\n\n
\n\n\n\n\n\n
For
 
Signatory
\n\n', + '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 fa0145af2d3..932df2e5d6c 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': '
\n

\n

\n\n\n\n\n\n\n\n\n\n\n \n\n\n\n\n\n\n\n\n
Receipt No.:
Date :
Remark:
Received From:
\n
\n\n

\n

\n
This receipt is issued subject to realization of the
\n
\n
\n\n\n\n\n

For ,


(Authorised Signatory)
', + 'html': '
\n

\n

\n\n\n\n\n\n\n\n\n\n\n \n\n\n\n\n\n\n\n\n
Receipt No.:
Date :
Remark:
Received From:
\n
\n\n

\n

\n
This receipt is issued subject to realization of the Cheque
\n
\n
\n\n\n\n\n

For ,


(Authorised Signatory)
', '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 00000000000..2fed0c4d9cf --- /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-11-15 17:30:44', + 'docstatus': 0, + 'modified': '2011-11-16 13:46:05', + 'modified_by': 'Administrator', + 'owner': 'Administrator' + }, + + # These values are common for all Print Format + { + 'doc_type': 'Receivable Voucher', + 'doctype': 'Print Format', + 'html': '\n\n\n\n\n\n\n\n\n\n\n
\n\t\n\t\n\t\t\n\t\t\t\n\t\t\t\n\t\t\n\t\t\n\t\t\t\n\t\t\t\t\n\t\t\t\t\n\t\t\t\n\t\t\n\t\t\n\t\t\n\t\t\n\t

Invoice

\n\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\n\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\n\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\n\t\t\t\t
Name
Address
Contact
\n\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\t\t\t\t\t\n\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\t\t\t\t\t\n\t\t\t\t
Invoice Date
Due Date
\n
\n
\n\t\n\t\n
\n
\n\t\n\t\n\t\t\n\t\t\t\n\t\t\n\t\t\n\t\t\t\n\t\t\t\t\n\t\t\t\t\n\t\t\t\t\t\n\t\t\n\t\t\n\t\t\n\t\t\n\t
\n\t\t\t\t\tTerms, Conditions & Other Information:
\n\t\t\t\t\t\n\t\t\t\t
\n\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\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\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\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\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t
Net Total
Grand Total
Rounded Total
\n\t\t\t\t\t
In Words
\n\t\t\t\t\t\n\t\t\t\t
\n
\n\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 00000000000..ea8a9110829 --- /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-11-15 17:30:44', + 'docstatus': 0, + 'modified': '2011-11-16 13:44:58', + 'modified_by': 'Administrator', + 'owner': 'Administrator' + }, + + # These values are common for all Print Format + { + 'doc_type': 'Receivable Voucher', + 'doctype': 'Print Format', + 'html': '\n\n\n\n\n\n\n\n\n\n\n
\n\t\n\t\n\t\t\n\t\t\t\n\t\t\t\n\t\t\n\t\t\n\t\t\t\n\t\t\t\t\n\t\t\t\t\n\t\t\t\n\t\t\n\t\t\n\t\t\n\t\t\n\t

Invoice

\n\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\n\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\n\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\n\t\t\t\t
Name
Address
Contact
\n\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\n\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\t\t\t\t\t\n\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\t\t\t\t\t\n\t\t\t\t
Invoice No.
Invoice Date
Due Date
\n
\n
\n\t\n\t\n
\n
\n\t\n\t\n\t\t\n\t\t\t\n\t\t\n\t\t\n\t\t\t\n\t\t\t\t\n\t\t\t\t\n\t\t\t\t\t\n\t\t\n\t\t\n\t\t\t\n\t\t\n\t
\n\t\t\t\t\tTerms, Conditions & Other Information:
\n\t\t\t\t\t\n\t\t\t\t
\n\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\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\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\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\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t
Net Total
Grand Total
Rounded Total
\n\t\t\t\t\t
In Words
\n\t\t\t\t\t\n\t\t\t\t
\n
\n\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 00000000000..d466b73be0c --- /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-11-15 17:30:44', + 'docstatus': 0, + 'modified': '2011-11-16 14:45:46', + 'modified_by': 'Administrator', + 'owner': 'Administrator' + }, + + # These values are common for all Print Format + { + 'doc_type': 'Receivable Voucher', + 'doctype': 'Print Format', + 'html': '\n\n\n\n\n\n\n\n\n\n\n
\n\t\n\t\n\t\t\n\t\t\t\n\t\t\t\n\t\t\n\t\t\n\t\t\t\n\t\t\t\t\n\t\t\t\t\n\t\t\t\n\t\t\n\t\t\n\t\t\n\t\t\n\t

Invoice

\n\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\n\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\n\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\n\t\t\t\t
Name
Address
Contact
\n\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\t\t\t\t\t\n\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\t\t\t\t\t\n\t\t\t\t
Invoice Date
Due Date
\n
\n
\n\t\n\t\n
\n
\n\t\n\t\n\t\t\n\t\t\t\n\t\t\n\t\t\n\t\t\t\n\t\t\t\t\n\t\t\t\t\n\t\t\t\t\t\n\t\t\n\t\t\n\t\t\n\t\t\n\t
\n\t\t\t\t\tTerms, Conditions & Other Information:
\n\t\t\t\t\t\n\t\t\t\t
\n\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\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\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\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\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t
Net Total
Grand Total
Rounded Total
\n\t\t\t\t\t
In Words
\n\t\t\t\t\t\n\t\t\t\t
\n
\n\n\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/lease_agreement/lease_agreement.js b/erpnext/accounts/doctype/lease_agreement/lease_agreement.js index 8ffd522c8d0..7b90be9d0a7 100644 --- a/erpnext/accounts/doctype/lease_agreement/lease_agreement.js +++ b/erpnext/accounts/doctype/lease_agreement/lease_agreement.js @@ -75,4 +75,4 @@ cur_frm.add_fetch('invoice','grand_total','invoice_amount'); cur_frm.fields_dict.invoice.get_query=function(doc){ return "SELECT tv.name FROM `tabReceivable Voucher` tv WHERE debit_to='"+doc.account+"' and tv.%(key)s like '%s' ORDER BY tv.name LIMIT 50" -} \ No newline at end of file +} diff --git a/erpnext/accounts/doctype/payable_voucher/payable_voucher.js b/erpnext/accounts/doctype/payable_voucher/payable_voucher.js index 5c276835047..550c0149973 100644 --- a/erpnext/accounts/doctype/payable_voucher/payable_voucher.js +++ b/erpnext/accounts/doctype/payable_voucher/payable_voucher.js @@ -52,7 +52,6 @@ cur_frm.cscript.refresh = function(doc, dt, dn) { //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); @@ -144,13 +143,6 @@ cur_frm.cscript.is_opening = function(doc, dt, dn) { } /* ******************************** TRIGGERS **************************************** */ -/* -// Supplier -// --------- -cur_frm.cscript.supplier = function(doc,cdt,cdn){ - get_server_fields('get_credit_to','','',doc,cdt,cdn); -} -*/ // Conversion Rate // ---------------- @@ -420,7 +412,7 @@ cur_frm.cscript.make_jv = function(doc, dt, dn, det) { } // ***************** Get project name ***************** -cur_frm.fields_dict['project_name'].get_query = function(doc, cdt, cdn) { +cur_frm.fields_dict['pv_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/accounts/doctype/payable_voucher/payable_voucher.py b/erpnext/accounts/doctype/payable_voucher/payable_voucher.py index 9f2848ad6f7..c4f0bc57469 100644 --- a/erpnext/accounts/doctype/payable_voucher/payable_voucher.py +++ b/erpnext/accounts/doctype/payable_voucher/payable_voucher.py @@ -232,15 +232,11 @@ class DocType(TransactionBase): # 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/pos_setting/pos_setting.js b/erpnext/accounts/doctype/pos_setting/pos_setting.js index 4eed7b6918d..2bbc08cf589 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 ed67ba2f0bd..58f66c7f6ba 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 index 1e05160261b..1c1c0ae97a7 100644 --- 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-10-20 18:41:17', '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': 27 }, # 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', @@ -77,7 +76,6 @@ 'doctype': 'DocField', 'fieldname': 'brand', 'fieldtype': 'Data', - 'idx': 3, 'label': 'Brand', 'oldfieldname': 'brand', 'oldfieldtype': 'Data', @@ -90,7 +88,6 @@ 'doctype': 'DocField', 'fieldname': 'description', 'fieldtype': 'Text', - 'idx': 4, 'label': 'Description', 'oldfieldname': 'description', 'oldfieldtype': 'Text', @@ -103,7 +100,6 @@ 'doctype': 'DocField', 'fieldname': 'item_group', 'fieldtype': 'Link', - 'idx': 5, 'in_filter': 1, 'label': 'Item Group', 'oldfieldname': 'item_group', @@ -111,7 +107,7 @@ 'options': 'Item Group', 'permlevel': 1, 'print_hide': 1, - 'search_index': 0 + 'search_index': 1 }, # DocField @@ -119,7 +115,6 @@ 'doctype': 'DocField', 'fieldname': 'rate', 'fieldtype': 'Currency', - 'idx': 6, 'label': 'Rate (Default Curr.)', 'oldfieldname': 'rate', 'oldfieldtype': 'Currency', @@ -134,7 +129,6 @@ 'doctype': 'DocField', 'fieldname': 'import_rate', 'fieldtype': 'Currency', - 'idx': 7, 'label': 'Rate', 'oldfieldname': 'import_rate', 'oldfieldtype': 'Currency', @@ -149,7 +143,6 @@ 'doctype': 'DocField', 'fieldname': 'qty', 'fieldtype': 'Currency', - 'idx': 8, 'label': 'Qty', 'oldfieldname': 'qty', 'oldfieldtype': 'Currency', @@ -164,7 +157,6 @@ 'doctype': 'DocField', 'fieldname': 'amount', 'fieldtype': 'Currency', - 'idx': 9, 'label': 'Amount (Default Curr.)', 'oldfieldname': 'amount', 'oldfieldtype': 'Currency', @@ -178,7 +170,6 @@ 'doctype': 'DocField', 'fieldname': 'import_amount', 'fieldtype': 'Currency', - 'idx': 10, 'label': 'Amount', 'oldfieldname': 'import_amount', 'oldfieldtype': 'Currency', @@ -192,7 +183,6 @@ 'doctype': 'DocField', 'fieldname': 'expense_head', 'fieldtype': 'Link', - 'idx': 11, 'label': 'Expense Head', 'oldfieldname': 'expense_head', 'oldfieldtype': 'Link', @@ -210,7 +200,6 @@ 'doctype': 'DocField', 'fieldname': 'cost_center', 'fieldtype': 'Link', - 'idx': 12, 'label': 'Cost Center', 'oldfieldname': 'cost_center', 'oldfieldtype': 'Link', @@ -221,12 +210,24 @@ 'width': '120px' }, + # 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': 'purchase_order', 'fieldtype': 'Link', - 'idx': 13, 'in_filter': 1, 'label': 'Pur Order', 'oldfieldname': 'purchase_order', @@ -243,7 +244,6 @@ 'fieldname': 'po_detail', 'fieldtype': 'Data', 'hidden': 1, - 'idx': 14, 'in_filter': 1, 'label': 'PO Detail', 'oldfieldname': 'po_detail', @@ -258,7 +258,6 @@ 'doctype': 'DocField', 'fieldname': 'purchase_receipt', 'fieldtype': 'Link', - 'idx': 15, 'in_filter': 1, 'label': 'Pur Receipt', 'oldfieldname': 'purchase_receipt', @@ -275,7 +274,6 @@ 'fieldname': 'pr_detail', 'fieldtype': 'Data', 'hidden': 1, - 'idx': 16, 'in_filter': 1, 'label': 'PR Detail', 'oldfieldname': 'pr_detail', @@ -291,7 +289,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 +303,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 ec8f2918d04..bb19681b98c 100644 --- a/erpnext/accounts/doctype/receivable_voucher/receivable_voucher.js +++ b/erpnext/accounts/doctype/receivable_voucher/receivable_voucher.js @@ -48,9 +48,9 @@ cur_frm.cscript.onload_post_render = function(doc, dt, dn) { // 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); @@ -74,6 +74,9 @@ cur_frm.cscript.hide_fields = function(doc, cdt, cdn) { // ------- 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 +93,6 @@ cur_frm.cscript.refresh = function(doc, dt, dn) { } 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 diff --git a/erpnext/accounts/doctype/receivable_voucher/receivable_voucher.txt b/erpnext/accounts/doctype/receivable_voucher/receivable_voucher.txt index 2f3b48d3fc6..1abd6a725b1 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-10-19 16:31:54', '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': '1319014846', 'change_log': '1. Change in pull_details method dt.-26-06-2009', 'colour': 'White:FFF', 'default_print_format': 'Standard', @@ -25,15 +34,16 @@ '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': 363 }, - # These values are common for all DocField + # These values are common for all DocFormat { - 'doctype': 'DocField', + 'doctype': 'DocFormat', + 'format': 'POS Invoice', 'name': '__common__', 'parent': 'Receivable Voucher', - 'parentfield': 'fields', + 'parentfield': 'formats', 'parenttype': 'DocType' }, @@ -114,6 +124,11 @@ 'write': 0 }, + # DocFormat + { + 'doctype': 'DocFormat' + }, + # DocField { 'doctype': 'DocField', diff --git a/erpnext/analysis/search_criteria/trend_analyzer/trend_analyzer.js b/erpnext/analysis/search_criteria/trend_analyzer/trend_analyzer.js index 9a87abbd11d..9426a235206 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 @@ report.customize_filters = function() { 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 @@ report.customize_filters = function() { 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 @@ report.get_query = function() { 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 @@ report.get_query = function() { 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 9edf04563b7..42a7c5cc7e9 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 @@ customer_group = filter_values.get('customer_group') 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 @@ col_names.append('Total (Amt)') # ********************************************* 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 @@ if order_type: add_cond += ' AND t1.order_type = "%s"' % order_type # 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 00000000000..bd10b2d3289 --- /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-11-15 17:30:44', + 'docstatus': 0, + 'modified': '2011-11-15 17:30:44', + 'modified_by': 'Administrator', + 'owner': 'Administrator' + }, + + # These values are common for all Print Format + { + 'doc_type': 'Purchase Order', + 'doctype': 'Print Format', + 'html': '\n\n\n\n\n\n\n\n\n\n\n
\n\t\n\t\n\t\t\n\t\t\t\n\t\t\t\n\t\t\n\t\t\n\t\t\t\n\t\t\t\t\n\t\t\t\t\n\t\t\t\n\t\t\n\t\t\n\t\t\n\t\t\n\t

Purchase Order

\n\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\n\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\n\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\n\t\t\t\t
Name
Address
Contact
\n\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\t\t\t\t\t\n\t\t\t\t
Purchase Order Date
\n
\n
\n\t\n\t\n
\n
\n\t\n\t\n\t\t\n\t\t\t\n\t\t\n\t\t\n\t\t\t\n\t\t\t\t\n\t\t\t\t\n\t\t\t\t\t\n\t\t\n\t\t\n\t\t\n\t\t\n\t
\n\t\t\t\t\tTerms, Conditions & Other Information:
\n\t\t\t\t\t\n\t\t\t\t
\n\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\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\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t
Net Total
Grand Total
\n\t\t\t\t\t
In Words
\n\t\t\t\t\t\n\t\t\t\t
\n
\n\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 00000000000..94c5a3f1d81 --- /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-11-15 17:30:45', + 'docstatus': 0, + 'modified': '2011-11-15 17:30:45', + 'modified_by': 'Administrator', + 'owner': 'Administrator' + }, + + # These values are common for all Print Format + { + 'doc_type': 'Purchase Order', + 'doctype': 'Print Format', + 'html': '\n\n\n\n\n\n\n\n\n\n\n
\n\t\n\t\n\t\t\n\t\t\t\n\t\t\t\n\t\t\n\t\t\n\t\t\t\n\t\t\t\t\n\t\t\t\t\n\t\t\t\n\t\t\n\t\t\n\t\t\n\t\t\n\t

Purchase Order

\n\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\n\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\n\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\n\t\t\t\t
Name
Address
Contact
\n\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\n\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\t\t\t\t\t\n\t\t\t\t
Purchase Order No.
Purchase Order Date
\n
\n
\n\t\n\t\n
\n
\n\t\n\t\n\t\t\n\t\t\t\n\t\t\n\t\t\n\t\t\t\n\t\t\t\t\n\t\t\t\t\n\t\t\t\t\t\n\t\t\n\t\t\n\t\t\t\n\t\t\n\t
\n\t\t\t\t\tTerms, Conditions & Other Information:
\n\t\t\t\t\t\n\t\t\t\t
\n\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\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\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t
Net Total
Grand Total
\n\t\t\t\t\t
In Words
\n\t\t\t\t\t\n\t\t\t\t
\n
\n\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 00000000000..adb397ab807 --- /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-11-15 17:30:45', + 'docstatus': 0, + 'modified': '2011-11-16 14:45:05', + 'modified_by': 'Administrator', + 'owner': 'Administrator' + }, + + # These values are common for all Print Format + { + 'doc_type': 'Purchase Order', + 'doctype': 'Print Format', + 'html': '\n\n\n\n\n\n\n\n\n\n\n
\n\t\n\t\n\t\t\n\t\t\t\n\t\t\t\n\t\t\n\t\t\n\t\t\t\n\t\t\t\t\n\t\t\t\t\n\t\t\t\n\t\t\n\t\t\n\t\t\n\t\t\n\t

Purchase Order

\n\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\n\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\n\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\n\t\t\t\t
Name
Address
Contact
\n\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\t\t\t\t\t\n\t\t\t\t
Purchase Order Date
\n
\n
\n\t\n\t\n
\n
\n\t\n\t\n\t\t\n\t\t\t\n\t\t\n\t\t\n\t\t\t\n\t\t\t\t\n\t\t\t\t\n\t\t\t\t\t\n\t\t\n\t\t\n\t\t\n\t\t\n\t
\n\t\t\t\t\tTerms, Conditions & Other Information:
\n\t\t\t\t\t\n\t\t\t\t
\n\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\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\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t
Net Total
Grand Total
\n\t\t\t\t\t
In Words
\n\t\t\t\t\t\n\t\t\t\t
\n
\n\n\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 cd6c91296c1..6d9f5f6e86a 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 @@ -52,13 +53,24 @@ 'name': 'Indent' }, + # 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 c207266bbbb..136237aa6c0 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 index 71d78df1f3e..bfd014e2376 100644 --- 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-10-20 18:39:20', + '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': 54 }, # 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', @@ -106,13 +103,43 @@ 'width': '300px' }, + # DocField + { + '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': 'uom', + 'fieldtype': 'Link', + 'label': 'UOM', + 'oldfieldname': 'uom', + 'oldfieldtype': 'Link', + 'options': 'UOM', + 'permlevel': 0, + 'print_hide': 0, + 'reqd': 1, + 'trigger': 'Client', + 'width': '100px' + }, + # DocField { 'default': '0.00', 'doctype': 'DocField', 'fieldname': 'purchase_rate', 'fieldtype': 'Currency', - 'idx': 7, 'label': 'Rate (Default Curr.)', 'oldfieldname': 'purchase_rate', 'oldfieldtype': 'Currency', @@ -129,7 +156,6 @@ 'doctype': 'DocField', 'fieldname': 'amount', 'fieldtype': 'Currency', - 'idx': 8, 'label': 'Amount (Default Curr.)', 'oldfieldname': 'amount', 'oldfieldtype': 'Currency', @@ -138,29 +164,12 @@ 'reqd': 1 }, - # 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', @@ -169,30 +178,11 @@ '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', @@ -205,7 +195,6 @@ 'fieldname': 'warehouse', 'fieldtype': 'Link', 'hidden': 0, - 'idx': 11, 'label': 'Warehouse', 'oldfieldname': 'warehouse', 'oldfieldtype': 'Link', @@ -223,7 +212,6 @@ 'fieldname': 'conversion_factor', 'fieldtype': 'Currency', 'hidden': 0, - 'idx': 11, 'label': 'Conversion Factor', 'oldfieldname': 'conversion_factor', 'oldfieldtype': 'Currency', @@ -238,16 +226,17 @@ { '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 + 'fieldname': 'stock_qty', + 'fieldtype': 'Currency', + 'hidden': 0, + 'label': 'Stock Qty', + 'no_copy': 1, + 'oldfieldname': 'stock_qty', + 'oldfieldtype': 'Currency', + 'permlevel': 0, + 'print_hide': 1, + 'trigger': 'Client', + 'width': '100px' }, # DocField @@ -256,7 +245,6 @@ 'fieldname': 'stock_uom', 'fieldtype': 'Data', 'hidden': 0, - 'idx': 12, 'label': 'Stock UOM', 'oldfieldname': 'stock_uom', 'oldfieldtype': 'Data', @@ -266,6 +254,34 @@ 'width': '100px' }, + # 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 + { + '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', @@ -273,7 +289,6 @@ 'fieldname': 'prevdoc_docname', 'fieldtype': 'Link', 'hidden': 0, - 'idx': 13, 'in_filter': 1, 'label': 'Indent No', 'no_copy': 0, @@ -292,7 +307,6 @@ 'fieldname': 'prevdoc_date', 'fieldtype': 'Date', 'hidden': 0, - 'idx': 14, 'in_filter': 1, 'label': 'Indent Date', 'oldfieldname': 'prevdoc_date', @@ -309,7 +323,6 @@ 'fieldname': 'prevdoc_detail_docname', 'fieldtype': 'Data', 'hidden': 1, - 'idx': 15, 'in_filter': 1, 'label': 'Indent Detail No', 'no_copy': 0, @@ -326,14 +339,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 +353,6 @@ 'fieldname': 'item_group', 'fieldtype': 'Link', 'hidden': 0, - 'idx': 17, 'in_filter': 1, 'label': 'Item Group', 'oldfieldname': 'item_group', @@ -350,24 +360,7 @@ 'options': 'Item Group', 'permlevel': 1, 'print_hide': 1, - 'search_index': 0 - }, - - # DocField - { - 'doctype': 'DocField', - 'fieldname': 'stock_qty', - 'fieldtype': 'Currency', - 'hidden': 0, - 'idx': 20, - 'label': 'Stock Qty', - 'no_copy': 1, - 'oldfieldname': 'stock_qty', - 'oldfieldtype': 'Currency', - 'permlevel': 0, - 'print_hide': 1, - 'trigger': 'Client', - 'width': '100px' + 'search_index': 1 }, # DocField @@ -376,7 +369,6 @@ 'fieldname': 'received_qty', 'fieldtype': 'Currency', 'hidden': 0, - 'idx': 21, 'label': 'Received Qty', 'no_copy': 1, 'oldfieldname': 'received_qty', @@ -392,7 +384,6 @@ 'fieldname': 'billed_qty', 'fieldtype': 'Currency', 'hidden': 0, - 'idx': 22, 'label': 'Billed Quantity', 'no_copy': 1, 'oldfieldname': 'billed_qty', @@ -409,7 +400,6 @@ 'fieldname': 'item_tax_rate', 'fieldtype': 'Small Text', 'hidden': 1, - 'idx': 23, 'label': 'Item Tax Rate', 'oldfieldname': 'item_tax_rate', 'oldfieldtype': 'Small Text', @@ -420,12 +410,11 @@ # DocField { - 'allow_on_submit': 1, + 'allow_on_submit': 0, 'doctype': 'DocField', '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_order/purchase_order.js b/erpnext/buying/doctype/purchase_order/purchase_order.js index 57141269ec3..d3fa37b807d 100644 --- a/erpnext/buying/doctype/purchase_order/purchase_order.js +++ b/erpnext/buying/doctype/purchase_order/purchase_order.js @@ -111,11 +111,10 @@ cur_frm.cscript.transaction_date = function(doc,cdt,cdn){ // ---------------------- 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/home/doctype/home_control/home_control.py b/erpnext/home/doctype/home_control/home_control.py index 8242e744315..ce15bfd57ac 100644 --- a/erpnext/home/doctype/home_control/home_control.py +++ b/erpnext/home/doctype/home_control/home_control.py @@ -31,6 +31,8 @@ class DocType: 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 @@ class DocType: 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/my_company/my_company.js b/erpnext/home/page/my_company/my_company.js index 40bf1555851..e88c45897c9 100644 --- a/erpnext/home/page/my_company/my_company.js +++ b/erpnext/home/page/my_company/my_company.js @@ -242,7 +242,7 @@ MemberItem = function(parent, det, mlist) { // 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(); @@ -731,7 +731,7 @@ RoleObj = function(profile_id){ this.make_role_body(profile_id); this.make_help_body(); - this.body.innerHTML = 'Loading... ' + this.body.innerHTML = 'Loading... ' var me=this; d.onshow = function() { @@ -829,7 +829,7 @@ RoleObj.prototype.make_label = function(tbl, ridx, cidx, role){ 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 +942,8 @@ RoleObj.prototype.set_permissions = function(perm, role){ for(var i=0; i<(head_lst.length-1);i++){ $td(perm_tbl,0,i).innerHTML= ""+head_lst[i]+""; } - 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= %(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 50710568e81..badd69bd8e5 100644 --- a/erpnext/hr/doctype/salary_manager/salary_manager.py +++ b/erpnext/hr/doctype/salary_manager/salary_manager.py @@ -46,7 +46,7 @@ class DocType: 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 66a72823803..c1ca4c6038e 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': '
You can generate multiple salary slips based on the selected criteria, submit and mail those to the employee directly from here
' }, @@ -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 2439ffaa4b4..24d1774e34c 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 c258d153ab0..8c0c74767c2 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 00000000000..50811c0aa23 --- /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 48ef3bf42f0..7a7f04988e4 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 3e17b6f7b98..433ea2ee54c 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 @@ KBPoints = function(parent, points, voted, dt, dn, owner) { // 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 f268d0bbf0b..a3dff131693 100644 --- a/erpnext/knowledge_base/page/questions/questions.js +++ b/erpnext/knowledge_base/page/questions/questions.js @@ -35,8 +35,6 @@ function KnowledgeBase(w) { 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/employeewise_balance_leave_report.py b/erpnext/patches/employeewise_balance_leave_report.py new file mode 100644 index 00000000000..6af236484ea --- /dev/null +++ b/erpnext/patches/employeewise_balance_leave_report.py @@ -0,0 +1,12 @@ +""" + 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 + d = Document('Search Criteria', 'employeewise_balance_leave_report') + d.criteria_name = 'Employee Leave Balance Report' + d.description = 'Employeewise Balance Leave Report' + d.save() \ No newline at end of file diff --git a/erpnext/patches/install_print_formats.py b/erpnext/patches/install_print_formats.py new file mode 100644 index 00000000000..3b5627bba06 --- /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 00000000000..66afafc8663 --- /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 00000000000..e2304c760de --- /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 00000000000..9285e8a56df --- /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 a3093c1d2d4..7e8a083d4db 100644 --- a/erpnext/patches/patch.py +++ b/erpnext/patches/patch.py @@ -1,7 +1,7 @@ # REMEMBER to update this # ======================== -last_patch = 384 +last_patch = 388 #------------------------------------------- @@ -344,8 +344,7 @@ def execute(patch_no): 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 = [ @@ -454,3 +453,12 @@ def execute(patch_no): reload_doc('stock', 'Module Def', 'Stock') sql("delete from `tabModule Def Item` where display_name = 'Serial No' and parent = 'Support'") sql("update `tabDocType` set subject = 'Item Code: %(item_code)s, Warehouse: %(warehouse)s' where name = 'Serial No'") + 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/print_formats/DeliveryNoteClassic.html b/erpnext/patches/print_formats/DeliveryNoteClassic.html new file mode 100644 index 00000000000..0db80b9daba --- /dev/null +++ b/erpnext/patches/print_formats/DeliveryNoteClassic.html @@ -0,0 +1,279 @@ + + + + + + + + + + + + +
+ + +
+ + diff --git a/erpnext/patches/print_formats/DeliveryNoteModern.html b/erpnext/patches/print_formats/DeliveryNoteModern.html new file mode 100644 index 00000000000..634bea0c350 --- /dev/null +++ b/erpnext/patches/print_formats/DeliveryNoteModern.html @@ -0,0 +1,306 @@ + + + + + + + + + + + + +
+ + +
+ + diff --git a/erpnext/patches/print_formats/DeliveryNoteSpartan.html b/erpnext/patches/print_formats/DeliveryNoteSpartan.html new file mode 100644 index 00000000000..4be12c456c4 --- /dev/null +++ b/erpnext/patches/print_formats/DeliveryNoteSpartan.html @@ -0,0 +1,302 @@ + + + + + + + + + + + + +
+ + +
+ + + diff --git a/erpnext/patches/print_formats/PurchaseOrderClassic.html b/erpnext/patches/print_formats/PurchaseOrderClassic.html new file mode 100644 index 00000000000..0e51c6148aa --- /dev/null +++ b/erpnext/patches/print_formats/PurchaseOrderClassic.html @@ -0,0 +1,249 @@ + + + + + + + + + + + + +
+ + +
+ + diff --git a/erpnext/patches/print_formats/PurchaseOrderModern.html b/erpnext/patches/print_formats/PurchaseOrderModern.html new file mode 100644 index 00000000000..b159242aded --- /dev/null +++ b/erpnext/patches/print_formats/PurchaseOrderModern.html @@ -0,0 +1,276 @@ + + + + + + + + + + + + +
+ + +
+ + diff --git a/erpnext/patches/print_formats/PurchaseOrderSpartan.html b/erpnext/patches/print_formats/PurchaseOrderSpartan.html new file mode 100644 index 00000000000..b1c1cd5bc1a --- /dev/null +++ b/erpnext/patches/print_formats/PurchaseOrderSpartan.html @@ -0,0 +1,272 @@ + + + + + + + + + + + + +
+ + +
+ + + diff --git a/erpnext/patches/print_formats/QuotationClassic.html b/erpnext/patches/print_formats/QuotationClassic.html new file mode 100644 index 00000000000..2dd24fadd7e --- /dev/null +++ b/erpnext/patches/print_formats/QuotationClassic.html @@ -0,0 +1,256 @@ + + + + + + + + + + + + +
+ + +
+ + diff --git a/erpnext/patches/print_formats/QuotationModern.html b/erpnext/patches/print_formats/QuotationModern.html new file mode 100644 index 00000000000..83103b00f91 --- /dev/null +++ b/erpnext/patches/print_formats/QuotationModern.html @@ -0,0 +1,283 @@ + + + + + + + + + + + + +
+ + +
+ + diff --git a/erpnext/patches/print_formats/QuotationSpartan.html b/erpnext/patches/print_formats/QuotationSpartan.html new file mode 100644 index 00000000000..e6afe4d9d36 --- /dev/null +++ b/erpnext/patches/print_formats/QuotationSpartan.html @@ -0,0 +1,279 @@ + + + + + + + + + + + + +
+ + +
+ + + diff --git a/erpnext/patches/print_formats/SalesInvoiceClassic.html b/erpnext/patches/print_formats/SalesInvoiceClassic.html new file mode 100644 index 00000000000..dc0d092e8d7 --- /dev/null +++ b/erpnext/patches/print_formats/SalesInvoiceClassic.html @@ -0,0 +1,261 @@ + + + + + + + + + + + + +
+ + +
+ + diff --git a/erpnext/patches/print_formats/SalesInvoiceModern.html b/erpnext/patches/print_formats/SalesInvoiceModern.html new file mode 100644 index 00000000000..bdffa1cbd9e --- /dev/null +++ b/erpnext/patches/print_formats/SalesInvoiceModern.html @@ -0,0 +1,288 @@ + + + + + + + + + + + + +
+ + +
+ + diff --git a/erpnext/patches/print_formats/SalesInvoiceSpartan.html b/erpnext/patches/print_formats/SalesInvoiceSpartan.html new file mode 100644 index 00000000000..6358a424554 --- /dev/null +++ b/erpnext/patches/print_formats/SalesInvoiceSpartan.html @@ -0,0 +1,284 @@ + + + + + + + + + + + + +
+ + +
+ + + diff --git a/erpnext/patches/print_formats/SalesOrderClassic.html b/erpnext/patches/print_formats/SalesOrderClassic.html new file mode 100644 index 00000000000..fcf104ebf03 --- /dev/null +++ b/erpnext/patches/print_formats/SalesOrderClassic.html @@ -0,0 +1,260 @@ + + + + + + + + + + + + +
+ + +
+ + diff --git a/erpnext/patches/print_formats/SalesOrderModern.html b/erpnext/patches/print_formats/SalesOrderModern.html new file mode 100644 index 00000000000..7013e5d3f92 --- /dev/null +++ b/erpnext/patches/print_formats/SalesOrderModern.html @@ -0,0 +1,287 @@ + + + + + + + + + + + + +
+ + +
+ + diff --git a/erpnext/patches/print_formats/SalesOrderSpartan.html b/erpnext/patches/print_formats/SalesOrderSpartan.html new file mode 100644 index 00000000000..59ed6a7d364 --- /dev/null +++ b/erpnext/patches/print_formats/SalesOrderSpartan.html @@ -0,0 +1,283 @@ + + + + + + + + + + + + +
+ + +
+ + + diff --git a/erpnext/patches/project_patch.py b/erpnext/patches/project_patch.py new file mode 100644 index 00000000000..c5473a0facc --- /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_bom.py b/erpnext/patches/reload_bom.py new file mode 100644 index 00000000000..f050f3c710d --- /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_flat_bom.py b/erpnext/patches/reload_flat_bom.py new file mode 100644 index 00000000000..b493610d16a --- /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_lc_wizard.py b/erpnext/patches/reload_lc_wizard.py new file mode 100644 index 00000000000..6b8565eafef --- /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 00000000000..e3c6adfcbf6 --- /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/repost_account_bal.py b/erpnext/patches/repost_account_bal.py new file mode 100644 index 00000000000..34edc04af80 --- /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/sal_man_patch.py b/erpnext/patches/sal_man_patch.py new file mode 100644 index 00000000000..aef625154bf --- /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/production/doctype/bill_of_materials/bill_of_materials.py b/erpnext/production/doctype/bill_of_materials/bill_of_materials.py index 9727a63fa86..a62e4f2c3b8 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 @@ class DocType: #----------- 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 @@ class DocType: 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 @@ class DocType: 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 item_code, description, qty_consumed_per_unit, stock_uom, moving_avg_rate, last_purchase_rate, standard_rate, '%s' as parent_bom, bom_mat_no, 'No' as is_pro_applicable from `tabFlat BOM Detail` where parent = '%s' and is_pro_applicable = 'No' and docstatus = 1" % ( d.bom_no, cstr(d.bom_no))) + 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 259081793dc..3713667fb7e 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': '
', @@ -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', @@ -263,13 +260,22 @@ 'reqd': 1 }, + # 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 1ce35a2f144..436519e889d 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 73393005fb2..f0d5d58bdfd 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/sandbox/test_leave.py b/erpnext/sandbox/test_leave.py new file mode 100644 index 00000000000..cc2149f473b --- /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 f1035bc455a..d1e00970c2d 100644 --- a/erpnext/sandbox/test_stock_entry.py +++ b/erpnext/sandbox/test_stock_entry.py @@ -101,7 +101,7 @@ class TestStockEntry(unittest.TestCase): 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 @@ class TestStockEntry(unittest.TestCase): [{'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 @@ class TestStockEntry(unittest.TestCase): '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/testdata/leaves.py b/erpnext/sandbox/testdata/leaves.py new file mode 100644 index 00000000000..8d44ffba78d --- /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/stock_entry.py b/erpnext/sandbox/testdata/stock_entry.py index 8f2a30c64af..3316016a439 100644 --- a/erpnext/sandbox/testdata/stock_entry.py +++ b/erpnext/sandbox/testdata/stock_entry.py @@ -34,6 +34,38 @@ mr = [ ) ] +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 @@ mtn = [ '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/selling/Print Format/Quotation Classic/Quotation Classic.txt b/erpnext/selling/Print Format/Quotation Classic/Quotation Classic.txt new file mode 100644 index 00000000000..a20d15fad1f --- /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-11-15 17:30:44', + 'docstatus': 0, + 'modified': '2011-11-16 12:30:36', + 'modified_by': 'Administrator', + 'owner': 'Administrator' + }, + + # These values are common for all Print Format + { + 'doc_type': 'Quotation', + 'doctype': 'Print Format', + 'html': '\n\n\n\n\n\n\n\n\n\n\n
\n\t\n\t\n\t\t\n\t\t\t\n\t\t\t\n\t\t\n\t\t\n\t\t\t\n\t\t\t\t\n\t\t\t\t\n\t\t\t\n\t\t\n\t\t\n\t\t\n\t\t\n\t

Quotation

\n\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\n\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\n\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\n\t\t\t\t
Name
Address
Contact
\n\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\t\t\t\t\t\n\t\t\t\t
Quotation Date
\n
\n
\n\t\n\t\n
\n
\n\t\n\t\n\t\t\n\t\t\t\n\t\t\n\t\t\n\t\t\t\n\t\t\t\t\n\t\t\t\t\n\t\t\t\t\t\n\t\t\n\t\t\n\t\t\n\t\t\n\t
\n\t\t\t\t\tTerms, Conditions & Other Information:
\n\t\t\t\t\t\n\t\t\t\t
\n\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\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\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\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\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t
Net Total
Grand Total
Rounded Total
\n\t\t\t\t\t
In Words
\n\t\t\t\t\t\n\t\t\t\t
\n
\n\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 00000000000..f5c02af8f84 --- /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-11-15 17:30:44', + 'docstatus': 0, + 'modified': '2011-11-16 12:30:57', + 'modified_by': 'Administrator', + 'owner': 'Administrator' + }, + + # These values are common for all Print Format + { + 'doc_type': 'Quotation', + 'doctype': 'Print Format', + 'html': '\n\n\n\n\n\n\n\n\n\n\n
\n\t\n\t\n\t\t\n\t\t\t\n\t\t\t\n\t\t\n\t\t\n\t\t\t\n\t\t\t\t\n\t\t\t\t\n\t\t\t\n\t\t\n\t\t\n\t\t\n\t\t\n\t

Quotation

\n\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\n\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\n\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\n\t\t\t\t
Name
Address
Contact
\n\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\n\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\t\t\t\t\t\n\t\t\t\t
Quotation No.
Quotation Date
\n
\n
\n\t\n\t\n
\n
\n\t\n\t\n\t\t\n\t\t\t\n\t\t\n\t\t\n\t\t\t\n\t\t\t\t\n\t\t\t\t\n\t\t\t\t\t\n\t\t\n\t\t\n\t\t\t\n\t\t\n\t
\n\t\t\t\t\tTerms, Conditions & Other Information:
\n\t\t\t\t\t\n\t\t\t\t
\n\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\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\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\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\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t
Net Total
Grand Total
Rounded Total
\n\t\t\t\t\t
In Words
\n\t\t\t\t\t\n\t\t\t\t
\n
\n\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 00000000000..d253d01b7c0 --- /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-11-16 13:27:17', + 'docstatus': 0, + 'modified': '2011-11-16 14:45:26', + 'modified_by': 'Administrator', + 'owner': 'Administrator' + }, + + # These values are common for all Print Format + { + 'doc_type': 'Quotation', + 'doctype': 'Print Format', + 'html': '\n\n\n\n\n\n\n\n\n\n\n
\n\t\n\t\n\t\t\n\t\t\t\n\t\t\t\n\t\t\n\t\t\n\t\t\t\n\t\t\t\t\n\t\t\t\t\n\t\t\t\n\t\t\n\t\t\n\t\t\n\t\t\n\t

Quotation

\n\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\n\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\n\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\n\t\t\t\t
Name
Address
Contact
\n\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\t\t\t\t\t\n\t\t\t\t
Quotation Date
\n
\n
\n\t\n\t\n
\n
\n\t\n\t\n\t\t\n\t\t\t\n\t\t\n\t\t\n\t\t\t\n\t\t\t\t\n\t\t\t\t\n\t\t\t\t\t\n\t\t\n\t\t\n\t\t\n\t\t\n\t
\n\t\t\t\t\tTerms, Conditions & Other Information:
\n\t\t\t\t\t\n\t\t\t\t
\n\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\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\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\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\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t
Net Total
Grand Total
Rounded Total
\n\t\t\t\t\t
In Words
\n\t\t\t\t\t\n\t\t\t\t
\n
\n\n\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 00000000000..28a9d685b70 --- /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-11-15 17:30:44', + 'docstatus': 0, + 'modified': '2011-11-15 17:30:44', + 'modified_by': 'Administrator', + 'owner': 'Administrator' + }, + + # These values are common for all Print Format + { + 'doc_type': 'Sales Order', + 'doctype': 'Print Format', + 'html': '\n\n\n\n\n\n\n\n\n\n\n
\n\t\n\t\n\t\t\n\t\t\t\n\t\t\t\n\t\t\n\t\t\n\t\t\t\n\t\t\t\t\n\t\t\t\t\n\t\t\t\n\t\t\n\t\t\n\t\t\n\t\t\n\t

Sales Order

\n\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\n\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\n\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\n\t\t\t\t
Name
Address
Contact
\n\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\t\t\t\t\t\n\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\t\t\t\t\t\n\t\t\t\t
Sales Order Date
Delivery Date
\n
\n
\n\t\n\t\n
\n
\n\t\n\t\n\t\t\n\t\t\t\n\t\t\n\t\t\n\t\t\t\n\t\t\t\t\n\t\t\t\t\n\t\t\t\t\t\n\t\t\n\t\t\n\t\t\n\t\t\n\t
\n\t\t\t\t\tTerms, Conditions & Other Information:
\n\t\t\t\t\t\n\t\t\t\t
\n\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\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\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\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\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t
Net Total
Grand Total
Rounded Total
\n\t\t\t\t\t
In Words
\n\t\t\t\t\t\n\t\t\t\t
\n
\n\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 00000000000..80ab0cbd1a4 --- /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-11-15 17:30:44', + 'docstatus': 0, + 'modified': '2011-11-15 17:30:44', + 'modified_by': 'Administrator', + 'owner': 'Administrator' + }, + + # These values are common for all Print Format + { + 'doc_type': 'Sales Order', + 'doctype': 'Print Format', + 'html': '\n\n\n\n\n\n\n\n\n\n\n
\n\t\n\t\n\t\t\n\t\t\t\n\t\t\t\n\t\t\n\t\t\n\t\t\t\n\t\t\t\t\n\t\t\t\t\n\t\t\t\n\t\t\n\t\t\n\t\t\n\t\t\n\t

Sales Order

\n\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\n\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\n\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\n\t\t\t\t
Name
Address
Contact
\n\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\n\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\t\t\t\t\t\n\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\t\t\t\t\t\n\t\t\t\t
Sales Order No.
Sales Order Date
Delivery Date
\n
\n
\n\t\n\t\n
\n
\n\t\n\t\n\t\t\n\t\t\t\n\t\t\n\t\t\n\t\t\t\n\t\t\t\t\n\t\t\t\t\n\t\t\t\t\t\n\t\t\n\t\t\n\t\t\t\n\t\t\n\t
\n\t\t\t\t\tTerms, Conditions & Other Information:
\n\t\t\t\t\t\n\t\t\t\t
\n\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\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\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\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\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t
Net Total
Grand Total
Rounded Total
\n\t\t\t\t\t
In Words
\n\t\t\t\t\t\n\t\t\t\t
\n
\n\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 00000000000..37d8aedd522 --- /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-11-15 17:30:44', + 'docstatus': 0, + 'modified': '2011-11-16 14:46:00', + 'modified_by': 'Administrator', + 'owner': 'Administrator' + }, + + # These values are common for all Print Format + { + 'doc_type': 'Sales Order', + 'doctype': 'Print Format', + 'html': '\n\n\n\n\n\n\n\n\n\n\n
\n\t\n\t\n\t\t\n\t\t\t\n\t\t\t\n\t\t\n\t\t\n\t\t\t\n\t\t\t\t\n\t\t\t\t\n\t\t\t\n\t\t\n\t\t\n\t\t\n\t\t\n\t

Sales Order

\n\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\n\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\n\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\n\t\t\t\t
Name
Address
Contact
\n\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\t\t\t\t\t\n\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\t\t\t\t\t\n\t\t\t\t
Sales Order Date
Delivery Date
\n
\n
\n\t\n\t\n
\n
\n\t\n\t\n\t\t\n\t\t\t\n\t\t\n\t\t\n\t\t\t\n\t\t\t\t\n\t\t\t\t\n\t\t\t\t\t\n\t\t\n\t\t\n\t\t\n\t\t\n\t
\n\t\t\t\t\tTerms, Conditions & Other Information:
\n\t\t\t\t\t\n\t\t\t\t
\n\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\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\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\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\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t
Net Total
Grand Total
Rounded Total
\n\t\t\t\t\t
In Words
\n\t\t\t\t\t\n\t\t\t\t
\n
\n\n\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/quotation/quotation.py b/erpnext/selling/doctype/quotation/quotation.py index 11755406faf..10bccaf79b1 100644 --- a/erpnext/selling/doctype/quotation/quotation.py +++ b/erpnext/selling/doctype/quotation/quotation.py @@ -133,24 +133,13 @@ class DocType(TransactionBase): # 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/startup/startup.css b/erpnext/startup/startup.css index f02841689de..7b2b6e582dc 100644 --- a/erpnext/startup/startup.css +++ b/erpnext/startup/startup.css @@ -4,7 +4,7 @@ h1, h2, h3, h4 { } 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 a0661ae06f6..fcb097bd4ed 100644 --- a/erpnext/startup/startup.js +++ b/erpnext/startup/startup.js @@ -43,18 +43,8 @@ function startup_setup() { // ------------------ $dh(page_body.footer); - // for logout and payment - var callback = function(r,rt) { - if(r.message){ - login_file = 'http://' + r.message; - } - else if(pscript.is_erpnext_saas) { - login_file = 'https://www.erpnext.com'; - } - // setup toolbar - pscript.startup_setup_toolbar(); - } - $c_obj('Home Control', 'get_login_url', '', callback); + // setup toolbar + pscript.startup_setup_toolbar(); } // ==================================================================== @@ -66,6 +56,14 @@ pscript.startup_make_sidebar = function() { // 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 = ''; @@ -299,10 +297,10 @@ SidebarItem.prototype.show_items = function() { // add to menu-item mapper menu_item_map['Page'][me.det.module_label + ' Custom Reports'] = smi.pointer; - } - } + + $(me.items_area).slideDown(); // high light @@ -565,7 +563,7 @@ pscript.feature_dict = { 'Timesheet': {'timesheet_details':['project_name']} }, 'fs_packing_details': { - 'Delivery Note': {'fields':['packing_details','print_packing_slip'],'delivery_note_details':['no_of_packs','pack_gross_wt','pack_nett_wt','pack_no','pack_unit']}, + 'Delivery Note': {'fields':['packing_details','print_packing_slip','packing_checked_by','packed_by','pack_size','shipping_mark'],'delivery_note_details':['no_of_packs','pack_gross_wt','pack_nett_wt','pack_no','pack_unit']}, 'Sales Order': {'fields':['packing_details']} }, 'fs_discounts': { 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 c34f00617d5..196d028b675 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 00000000000..6b815c0f73a --- /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-11-15 17:30:44', + 'docstatus': 0, + 'modified': '2011-11-15 17:30:44', + 'modified_by': 'Administrator', + 'owner': 'Administrator' + }, + + # These values are common for all Print Format + { + 'doc_type': 'Delivery Note', + 'doctype': 'Print Format', + 'html': '\n\n\n\n\n\n\n\n\n\n\n
\n\t\n\t\n\t\t\n\t\t\t\n\t\t\t\n\t\t\n\t\t\n\t\t\t\n\t\t\t\t\n\t\t\t\t\n\t\t\t\n\t\t\n\t\t\n\t\t\n\t\t\n\t

Delivery Note

\n\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\n\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\n\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\n\t\t\t\t
Name
Address
Contact
\n\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\t\t\t\t\t\n\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\t\t\t\t\t\n\t\t\t\t
Delivery Note Date
Sales Order No.\n\t\t\t\t\t\t\t
\n\t\t\t\t\t\t\t()\n\t\t\t\t\t\t
\n
\n
\n\t\n\t\n
\n
\n\t\n\t\n\t\t\n\t\t\t\n\t\t\n\t\t\n\t\t\t\n\t\t\t\t\n\t\t\t\t\n\t\t\t\t\t\n\t\t\n\t\t\n\t\t\n\t\t\n\t
\n\t\t\t\t\tTerms, Conditions & Other Information:
\n\t\t\t\t\t\n\t\t\t\t
\n\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\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\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\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\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t
Net Total
Grand Total
Rounded Total
\n\t\t\t\t\t
In Words
\n\t\t\t\t\t\n\t\t\t\t
\n
\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 00000000000..9b86f5be723 --- /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-11-15 17:30:44', + 'docstatus': 0, + 'modified': '2011-11-15 17:30:44', + 'modified_by': 'Administrator', + 'owner': 'Administrator' + }, + + # These values are common for all Print Format + { + 'doc_type': 'Delivery Note', + 'doctype': 'Print Format', + 'html': '\n\n\n\n\n\n\n\n\n\n\n
\n\t\n\t\n\t\t\n\t\t\t\n\t\t\t\n\t\t\n\t\t\n\t\t\t\n\t\t\t\t\n\t\t\t\t\n\t\t\t\n\t\t\n\t\t\n\t\t\n\t\t\n\t

Delivery Note

\n\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\n\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\n\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\n\t\t\t\t
Name
Address
Contact
\n\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\n\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\t\t\t\t\t\n\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\t\t\t\t\t\n\t\t\t\t
Delivery Note No.
Delivery Note Date
Sales Order No.\n\t\t\t\t\t\t\t
\n\t\t\t\t\t\t\t()\n\t\t\t\t\t\t
\n
\n
\n\t\n\t\n
\n
\n\t\n\t\n\t\t\n\t\t\t\n\t\t\n\t\t\n\t\t\t\n\t\t\t\t\n\t\t\t\t\n\t\t\t\t\t\n\t\t\n\t\t\n\t\t\t\n\t\t\n\t
\n\t\t\t\t\tTerms, Conditions & Other Information:
\n\t\t\t\t\t\n\t\t\t\t
\n\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\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\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\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\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t
Net Total
Grand Total
Rounded Total
\n\t\t\t\t\t
In Words
\n\t\t\t\t\t\n\t\t\t\t
\n
\n\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 97f57a9f890..849db976853 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': "\n\n\n\n\n\n\n\n\n\n", + 'html': "\n\n\n\n\n\n\n\n\n\n", '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 00000000000..f8e989c3a2d --- /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-11-15 17:30:44', + 'docstatus': 0, + 'modified': '2011-11-16 14:43:28', + 'modified_by': 'Administrator', + 'owner': 'Administrator' + }, + + # These values are common for all Print Format + { + 'doc_type': 'Delivery Note', + 'doctype': 'Print Format', + 'html': '\n\n\n\n\n\n\n\n\n\n\n
\n\t\n\t\n\t\t\n\t\t\t\n\t\t\t\n\t\t\n\t\t\n\t\t\t\n\t\t\t\t\n\t\t\t\t\n\t\t\t\n\t\t\n\t\t\n\t\t\n\t\t\n\t

Delivery Note

\n\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\n\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\n\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\n\t\t\t\t
Name
Address
Contact
\n\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\t\t\t\t\t\n\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\t\t\t\t\t\n\t\t\t\t
Delivery Note Date
Sales Order No.\n\t\t\t\t\t\t\t
\n\t\t\t\t\t\t\t()\n\t\t\t\t\t\t
\n
\n
\n\t\n\t\n
\n
\n\t\n\t\n\t\t\n\t\t\t\n\t\t\n\t\t\n\t\t\t\n\t\t\t\t\n\t\t\t\t\n\t\t\t\t\t\n\t\t\n\t\t\n\t\t\n\t\t\n\t
\n\t\t\t\t\tTerms, Conditions & Other Information:
\n\t\t\t\t\t\n\t\t\t\t
\n\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\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\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\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\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t
Net Total
Grand Total
Rounded Total
\n\t\t\t\t\t
In Words
\n\t\t\t\t\t\n\t\t\t\t
\n
\n\n\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 fc7bc0e3015..8ffb83e5d32 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': '\n\n\n\n\n\n
\n\n
\n
\n

Purchase Receipt:
\n
Date:
\n
\n\n
\n
\n

\n
\n\n
\n
\n \n\n
\n\n\n
\n\n \n \n
\n
\n
\n

Payment Terms
\n

\n

For NCSCI
\n


(Authorised Signatory)
\n
\n', + 'html': '\n\n\n\n\n\n
\n\n
\n
\n

Purchase Receipt:
\n
Date:
\n
\n\n
\n
\n

\n
\n\n
\n
\n \n\n
\n\n\n
\n\n \n \n
\n
\n
\n

Payment Terms
\n

\n

For NCSCI
\n


(Authorised Signatory)
\n
\n', 'module': 'Stock', 'name': '__common__', 'standard': 'Yes' diff --git a/erpnext/stock/doctype/bin/bin.py b/erpnext/stock/doctype/bin/bin.py index cf9509a332f..e3af0a27894 100644 --- a/erpnext/stock/doctype/bin/bin.py +++ b/erpnext/stock/doctype/bin/bin.py @@ -1,18 +1,11 @@ # 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 +from webnotes.utils import cint, cstr, flt, nowdate +from webnotes.model.code import get_obj +from webnotes import msgprint -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 # ----------------------------------------------------------------------------------------- @@ -39,19 +32,13 @@ class DocType: self.doc.save() - # 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 %s in Warehouse %s 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 +46,19 @@ class DocType: 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 +76,19 @@ class DocType: """, (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,23 +97,49 @@ class DocType: 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 %s in Warehouse %s on %s %s' % \ - (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 %s in Warehouse + %s on %s %s 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 @@ -220,11 +231,16 @@ class DocType: 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 +251,11 @@ class DocType: 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 +264,32 @@ class DocType: 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: diff --git a/erpnext/stock/doctype/delivery_note/delivery_note.py b/erpnext/stock/doctype/delivery_note/delivery_note.py index 6d48914429c..ea8c648b748 100644 --- a/erpnext/stock/doctype/delivery_note/delivery_note.py +++ b/erpnext/stock/doctype/delivery_note/delivery_note.py @@ -19,463 +19,504 @@ convert_to_lists = webnotes.conn.convert_to_lists from utilities.transaction_base import TransactionBase class DocType(TransactionBase): - def __init__(self, doc, doclist=[]): - self.doc = doc - self.doclist = doclist - self.tname = 'Delivery Note Detail' - self.fname = 'delivery_note_details' + def __init__(self, doc, doclist=[]): + self.doc = doc + self.doclist = doclist + self.tname = 'Delivery Note Detail' + self.fname = 'delivery_note_details' - # Notification objects - self.notify_obj = get_obj('Notification Control') + # Notification objects + self.notify_obj = get_obj('Notification Control') - # Autoname - # --------- - def autoname(self): - self.doc.name = make_autoname(self.doc.naming_series+'.#####') + # Autoname + # --------- + def autoname(self): + self.doc.name = make_autoname(self.doc.naming_series+'.#####') # DOCTYPE TRIGGERS FUNCTIONS # ============================================================================== #************Fiscal Year Validation***************************** - def validate_fiscal_year(self): - get_obj('Sales Common').validate_fiscal_year(self.doc.fiscal_year,self.doc.posting_date,'Posting Date') + def validate_fiscal_year(self): + get_obj('Sales Common').validate_fiscal_year(self.doc.fiscal_year,self.doc.posting_date,'Posting Date') - # ****** Get contact person details based on customer selected **** - def get_contact_details(self): - return get_obj('Sales Common').get_contact_details(self,0) + # ****** Get contact person details based on customer selected **** + def get_contact_details(self): + return get_obj('Sales Common').get_contact_details(self,0) - # *********** Get Commission rate of Sales Partner **************** - def get_comm_rate(self, sales_partner): - return get_obj('Sales Common').get_comm_rate(sales_partner, self) + # *********** Get Commission rate of Sales Partner **************** + def get_comm_rate(self, sales_partner): + return get_obj('Sales Common').get_comm_rate(sales_partner, self) - # *************** Pull Sales Order Details ************************ - def pull_sales_order_details(self): - self.validate_prev_docname() - self.doc.clear_table(self.doclist,'other_charges') + # *************** Pull Sales Order Details ************************ + def pull_sales_order_details(self): + self.validate_prev_docname() + self.doc.clear_table(self.doclist,'other_charges') - if self.doc.sales_order_no: - get_obj('DocType Mapper', 'Sales Order-Delivery Note').dt_map('Sales Order', 'Delivery Note', self.doc.sales_order_no, self.doc, self.doclist, "[['Sales Order', 'Delivery Note'],['Sales Order Detail', 'Delivery Note Detail'],['RV Tax Detail','RV Tax Detail'],['Sales Team','Sales Team']]") - else: - msgprint("Please select Sales Order No. whose details need to be pulled") + if self.doc.sales_order_no: + get_obj('DocType Mapper', 'Sales Order-Delivery Note').dt_map('Sales Order', 'Delivery Note', self.doc.sales_order_no, self.doc, self.doclist, "[['Sales Order', 'Delivery Note'],['Sales Order Detail', 'Delivery Note Detail'],['RV Tax Detail','RV Tax Detail'],['Sales Team','Sales Team']]") + else: + msgprint("Please select Sales Order No. whose details need to be pulled") - return cstr(self.doc.sales_order_no) + return cstr(self.doc.sales_order_no) - #-------------------set item details -uom and item group---------------- - def set_item_details(self): - for d in getlist(self.doclist,'delivery_note_details'): - res = sql("select stock_uom, item_group from `tabItem` where name ='%s'"%d.item_code) - if not d.stock_uom: d.stock_uom = res and cstr(res[0][0]) or '' - if not d.item_group: d.item_group = res and cstr(res[0][1]) or '' - d.save() + #-------------------set item details -uom and item group---------------- + def set_item_details(self): + for d in getlist(self.doclist,'delivery_note_details'): + res = sql("select stock_uom, item_group from `tabItem` where name ='%s'"%d.item_code) + if not d.stock_uom: d.stock_uom = res and cstr(res[0][0]) or '' + if not d.item_group: d.item_group = res and cstr(res[0][1]) or '' + d.save() - # ::::: Validates that Sales Order is not pulled twice ::::::: - def validate_prev_docname(self): - for d in getlist(self.doclist, 'delivery_note_details'): - if self.doc.sales_order_no == d.prevdoc_docname: - msgprint(cstr(self.doc.sales_order_no) + " sales order details have already been pulled. ") - raise Exception, "Validation Error. " + # ::::: Validates that Sales Order is not pulled twice ::::::: + def validate_prev_docname(self): + for d in getlist(self.doclist, 'delivery_note_details'): + if self.doc.sales_order_no == d.prevdoc_docname: + msgprint(cstr(self.doc.sales_order_no) + " sales order details have already been pulled. ") + raise Exception, "Validation Error. " - #Set Actual Qty based on item code and warehouse - #------------------------------------------------------ - def set_actual_qty(self): - for d in getlist(self.doclist, 'delivery_note_details'): - if d.item_code and d.warehouse: - actual_qty = sql("select actual_qty from `tabBin` where item_code = '%s' and warehouse = '%s'" % (d.item_code, d.warehouse)) - d.actual_qty = actual_qty and flt(actual_qty[0][0]) or 0 + #Set Actual Qty based on item code and warehouse + #------------------------------------------------------ + def set_actual_qty(self): + for d in getlist(self.doclist, 'delivery_note_details'): + if d.item_code and d.warehouse: + actual_qty = sql("select actual_qty from `tabBin` where item_code = '%s' and warehouse = '%s'" % (d.item_code, d.warehouse)) + d.actual_qty = actual_qty and flt(actual_qty[0][0]) or 0 - # GET TERMS & CONDITIONS - # ------------------------------------- - def get_tc_details(self): - return get_obj('Sales Common').get_tc_details(self) + # GET TERMS & CONDITIONS + # ------------------------------------- + def get_tc_details(self): + return get_obj('Sales Common').get_tc_details(self) - #pull project customer - #------------------------- - def pull_project_customer(self): - res = sql("select customer from `tabProject` where name = '%s'"%self.doc.project_name) - if res: - get_obj('DocType Mapper', 'Project-Delivery Note').dt_map('Project', 'Delivery Note', self.doc.project_name, self.doc, self.doclist, "[['Project', 'Delivery Note']]") + #pull project customer + #------------------------- + def pull_project_customer(self): + res = sql("select customer from `tabProject` where name = '%s'"%self.doc.project_name) + if res: + get_obj('DocType Mapper', 'Project-Delivery Note').dt_map('Project', 'Delivery Note', self.doc.project_name, self.doc, self.doclist, "[['Project', 'Delivery Note']]") # DELIVERY NOTE DETAILS TRIGGER FUNCTIONS # ================================================================================ - # ***************** Get Item Details ****************************** - def get_item_details(self, item_code): - return get_obj('Sales Common').get_item_details(item_code, self) + # ***************** Get Item Details ****************************** + def get_item_details(self, item_code): + return get_obj('Sales Common').get_item_details(item_code, self) - # *** Re-calculates Basic Rate & amount based on Price List Selected *** - def get_adj_percent(self, arg=''): - get_obj('Sales Common').get_adj_percent(self) + # *** Re-calculates Basic Rate & amount based on Price List Selected *** + def get_adj_percent(self, arg=''): + get_obj('Sales Common').get_adj_percent(self) - # ********** Get Actual Qty of item in warehouse selected ************* - def get_actual_qty(self,args): - args = eval(args) - actual_qty = sql("select actual_qty from `tabBin` where item_code = '%s' and warehouse = '%s'" % (args['item_code'], args['warehouse']), as_dict=1) - ret = { - 'actual_qty' : actual_qty and flt(actual_qty[0]['actual_qty']) or 0 - } - return ret + # ********** Get Actual Qty of item in warehouse selected ************* + def get_actual_qty(self,args): + args = eval(args) + actual_qty = sql("select actual_qty from `tabBin` where item_code = '%s' and warehouse = '%s'" % (args['item_code'], args['warehouse']), as_dict=1) + ret = { + 'actual_qty' : actual_qty and flt(actual_qty[0]['actual_qty']) or 0 + } + return ret # OTHER CHARGES TRIGGER FUNCTIONS # ==================================================================================== - # *********** Get Tax rate if account type is TAX ******************** - def get_rate(self,arg): - return get_obj('Sales Common').get_rate(arg) + # *********** Get Tax rate if account type is TAX ******************** + def get_rate(self,arg): + return get_obj('Sales Common').get_rate(arg) - # Load Default Charges - # ---------------------------------------------------------- - def load_default_taxes(self): - return get_obj('Sales Common').load_default_taxes(self) + # Load Default Charges + # ---------------------------------------------------------- + def load_default_taxes(self): + return get_obj('Sales Common').load_default_taxes(self) - # **** Pull details from other charges master (Get Other Charges) **** - def get_other_charges(self): - return get_obj('Sales Common').get_other_charges(self) + # **** Pull details from other charges master (Get Other Charges) **** + def get_other_charges(self): + return get_obj('Sales Common').get_other_charges(self) - #check in manage account if sales order required or not. - # ==================================================================================== - def so_required(self): - res = sql("select value from `tabSingles` where doctype = 'Manage Account' and field = 'so_required'") - if res and res[0][0] == 'Yes': - for d in getlist(self.doclist,'delivery_note_details'): - if not d.prevdoc_docname: - msgprint("Sales Order No. required against item %s"%d.item_code) - raise Exception + #check in manage account if sales order required or not. + # ==================================================================================== + def so_required(self): + res = sql("select value from `tabSingles` where doctype = 'Manage Account' and field = 'so_required'") + if res and res[0][0] == 'Yes': + for d in getlist(self.doclist,'delivery_note_details'): + if not d.prevdoc_docname: + msgprint("Sales Order No. required against item %s"%d.item_code) + raise Exception # VALIDATE # ==================================================================================== - def validate(self): - self.so_required() - self.validate_fiscal_year() - self.validate_proj_cust() - sales_com_obj = get_obj(dt = 'Sales Common') - sales_com_obj.check_stop_sales_order(self) - sales_com_obj.check_active_sales_items(self) - sales_com_obj.get_prevdoc_date(self) - self.validate_mandatory() - #self.validate_prevdoc_details() - self.validate_reference_value() - self.validate_for_items() - sales_com_obj.make_packing_list(self,'delivery_note_details') - get_obj('Stock Ledger').validate_serial_no(self, 'packing_details') - sales_com_obj.validate_max_discount(self, 'delivery_note_details') #verify whether rate is not greater than max discount - sales_com_obj.get_allocated_sum(self) # this is to verify that the allocated % of sales persons is 100% - sales_com_obj.check_conversion_rate(self) - # ::::::: Get total in Words :::::::: - dcc = TransactionBase().get_company_currency(self.doc.company) - self.doc.in_words = sales_com_obj.get_total_in_words(dcc, self.doc.rounded_total) - self.doc.in_words_export = sales_com_obj.get_total_in_words(self.doc.currency, self.doc.rounded_total_export) + def validate(self): + self.so_required() + self.validate_fiscal_year() + self.validate_proj_cust() + sales_com_obj = get_obj(dt = 'Sales Common') + sales_com_obj.check_stop_sales_order(self) + sales_com_obj.check_active_sales_items(self) + sales_com_obj.get_prevdoc_date(self) + self.validate_mandatory() + #self.validate_prevdoc_details() + self.validate_reference_value() + self.validate_for_items() + sales_com_obj.make_packing_list(self,'delivery_note_details') + get_obj('Stock Ledger').validate_serial_no(self, 'packing_details') + sales_com_obj.validate_max_discount(self, 'delivery_note_details') #verify whether rate is not greater than max discount + sales_com_obj.get_allocated_sum(self) # this is to verify that the allocated % of sales persons is 100% + sales_com_obj.check_conversion_rate(self) + # ::::::: Get total in Words :::::::: + dcc = TransactionBase().get_company_currency(self.doc.company) + self.doc.in_words = sales_com_obj.get_total_in_words(dcc, self.doc.rounded_total) + self.doc.in_words_export = sales_com_obj.get_total_in_words(self.doc.currency, self.doc.rounded_total_export) - # ::::::: Set Net Weight of each Packing - self.update_pack_nett_weight() - self.print_packing_slip() - # ::::::: Set actual qty for each item in selected warehouse ::::::: - self.update_current_stock() - # :::::: set DN status ::::::: + # ::::::: Set Net Weight of each Packing + self.update_pack_nett_weight() + self.print_packing_slip() + # ::::::: Set actual qty for each item in selected warehouse ::::::: + self.update_current_stock() + # :::::: set DN status ::::::: - self.doc.status = 'Draft' - if not self.doc.billing_status: self.doc.billing_status = 'Not Billed' - if not self.doc.installation_status: self.doc.installation_status = 'Not Installed' + self.doc.status = 'Draft' + if not self.doc.billing_status: self.doc.billing_status = 'Not Billed' + if not self.doc.installation_status: self.doc.installation_status = 'Not Installed' - # ************** Validate Mandatory ************************* - def validate_mandatory(self): - # :::::::::: Amendment Date :::::::::::::: - if self.doc.amended_from and not self.doc.amendment_date: - msgprint("Please Enter Amendment Date") - raise Exception, "Validation Error. " + # ************** Validate Mandatory ************************* + def validate_mandatory(self): + # :::::::::: Amendment Date :::::::::::::: + if self.doc.amended_from and not self.doc.amendment_date: + msgprint("Please Enter Amendment Date") + raise Exception, "Validation Error. " - #check for does customer belong to same project as entered.. - #------------------------------------------------------------------------------------------------- - def validate_proj_cust(self): - if self.doc.project_name and self.doc.customer: - res = sql("select name from `tabProject` where name = '%s' and (customer = '%s' or ifnull(customer,'')='')"%(self.doc.project_name, self.doc.customer)) - if not res: - msgprint("Customer - %s does not belong to project - %s. \n\nIf you want to use project for multiple customers then please make customer details blank in project - %s."%(self.doc.customer,self.doc.project_name,self.doc.project_name)) - raise Exception + #check for does customer belong to same project as entered.. + #------------------------------------------------------------------------------------------------- + def validate_proj_cust(self): + if self.doc.project_name and self.doc.customer: + res = sql("select name from `tabProject` where name = '%s' and (customer = '%s' or ifnull(customer,'')='')"%(self.doc.project_name, self.doc.customer)) + if not res: + msgprint("Customer - %s does not belong to project - %s. \n\nIf you want to use project for multiple customers then please make customer details blank in project - %s."%(self.doc.customer,self.doc.project_name,self.doc.project_name)) + raise Exception - # Validate values with reference document - #---------------------------------------- - def validate_reference_value(self): - get_obj('DocType Mapper', 'Sales Order-Delivery Note', with_children = 1).validate_reference_value(self, self.doc.name) + # Validate values with reference document + #---------------------------------------- + def validate_reference_value(self): + get_obj('DocType Mapper', 'Sales Order-Delivery Note', with_children = 1).validate_reference_value(self, self.doc.name) - # ******* Validate Previous Document Details ************ - def validate_prevdoc_details(self): - for d in getlist(self.doclist,'delivery_note_details'): + # ******* Validate Previous Document Details ************ + def validate_prevdoc_details(self): + for d in getlist(self.doclist,'delivery_note_details'): - prevdoc = d.prevdoc_doctype - prevdoc_docname = d.prevdoc_docname + prevdoc = d.prevdoc_doctype + prevdoc_docname = d.prevdoc_docname - if prevdoc_docname and prevdoc: - # ::::::::::: Validates Transaction Date of DN and previous doc (i.e. SO , PO, PR) ********* - trans_date = sql("select transaction_date from `tab%s` where name = '%s'" %(prevdoc,prevdoc_docname))[0][0] - if trans_date and getdate(self.doc.transaction_date) < (trans_date): - msgprint("Your Voucher Date cannot be before "+cstr(prevdoc)+" Date.") - raise Exception - # ::::::::: Validates DN and previous doc details :::::::::::::::::: - get_name = sql("select name from `tab%s` where name = '%s'" % (prevdoc, prevdoc_docname)) - name = get_name and get_name[0][0] or '' - if name: #check for incorrect docname - if prevdoc == 'Sales Order': - dt = sql("select company, docstatus, customer, currency, sales_partner from `tab%s` where name = '%s'" % (prevdoc, name)) - cust_name = dt and dt[0][2] or '' - if cust_name != self.doc.customer: - msgprint(cstr(prevdoc) + ": " + cstr(prevdoc_docname) + " customer :" + cstr(cust_name) + " does not match with customer : " + cstr(self.doc.customer) + " of current document.") - raise Exception, "Validation Error. " - sal_partner = dt and dt[0][4] or '' - if sal_partner != self.doc.sales_partner: - msgprint(cstr(prevdoc) + ": " + cstr(prevdoc_docname) + " sales partner name :" + cstr(sal_partner) + " does not match with sales partner name : " + cstr(self.doc.sales_partner_name) + " of current document.") - raise Exception, "Validation Error. " - else: - dt = sql("select company, docstatus, supplier, currency from `tab%s` where name = '%s'" % (prevdoc, name)) - supp_name = dt and dt[0][2] or '' - company_name = dt and dt[0][0] or '' - docstatus = dt and dt[0][1] or 0 - currency = dt and dt[0][3] or '' - if (currency != self.doc.currency): - msgprint(cstr(prevdoc) + ": " + cstr(prevdoc_docname) + " currency : "+ cstr(currency) + "does not match with Currency: " + cstr(self.doc.currency) + "of current document") - raise Exception, "Validation Error." - if (company_name != self.doc.company): - msgprint(cstr(prevdoc) + ": " + cstr(prevdoc_docname) + " does not belong to the Company: " + cstr(self.doc.company_name)) - raise Exception, "Validation Error." - if (docstatus != 1): - msgprint(cstr(prevdoc) + ": " + cstr(prevdoc_docname) + " is not Submitted Document.") - raise Exception, "Validation Error." - else: - msgprint(cstr(prevdoc) + ": " + cstr(prevdoc_docname) + " is not a valid " + cstr(prevdoc)) - raise Exception, "Validation Error." + if prevdoc_docname and prevdoc: + # ::::::::::: Validates Transaction Date of DN and previous doc (i.e. SO , PO, PR) ********* + trans_date = sql("select transaction_date from `tab%s` where name = '%s'" %(prevdoc,prevdoc_docname))[0][0] + if trans_date and getdate(self.doc.transaction_date) < (trans_date): + msgprint("Your Voucher Date cannot be before "+cstr(prevdoc)+" Date.") + raise Exception + # ::::::::: Validates DN and previous doc details :::::::::::::::::: + get_name = sql("select name from `tab%s` where name = '%s'" % (prevdoc, prevdoc_docname)) + name = get_name and get_name[0][0] or '' + if name: #check for incorrect docname + if prevdoc == 'Sales Order': + dt = sql("select company, docstatus, customer, currency, sales_partner from `tab%s` where name = '%s'" % (prevdoc, name)) + cust_name = dt and dt[0][2] or '' + if cust_name != self.doc.customer: + msgprint(cstr(prevdoc) + ": " + cstr(prevdoc_docname) + " customer :" + cstr(cust_name) + " does not match with customer : " + cstr(self.doc.customer) + " of current document.") + raise Exception, "Validation Error. " + sal_partner = dt and dt[0][4] or '' + if sal_partner != self.doc.sales_partner: + msgprint(cstr(prevdoc) + ": " + cstr(prevdoc_docname) + " sales partner name :" + cstr(sal_partner) + " does not match with sales partner name : " + cstr(self.doc.sales_partner_name) + " of current document.") + raise Exception, "Validation Error. " + else: + dt = sql("select company, docstatus, supplier, currency from `tab%s` where name = '%s'" % (prevdoc, name)) + supp_name = dt and dt[0][2] or '' + company_name = dt and dt[0][0] or '' + docstatus = dt and dt[0][1] or 0 + currency = dt and dt[0][3] or '' + if (currency != self.doc.currency): + msgprint(cstr(prevdoc) + ": " + cstr(prevdoc_docname) + " currency : "+ cstr(currency) + "does not match with Currency: " + cstr(self.doc.currency) + "of current document") + raise Exception, "Validation Error." + if (company_name != self.doc.company): + msgprint(cstr(prevdoc) + ": " + cstr(prevdoc_docname) + " does not belong to the Company: " + cstr(self.doc.company_name)) + raise Exception, "Validation Error." + if (docstatus != 1): + msgprint(cstr(prevdoc) + ": " + cstr(prevdoc_docname) + " is not Submitted Document.") + raise Exception, "Validation Error." + else: + msgprint(cstr(prevdoc) + ": " + cstr(prevdoc_docname) + " is not a valid " + cstr(prevdoc)) + raise Exception, "Validation Error." - # ******************** Validate Items ************************** - def validate_for_items(self): - check_list, chk_dupl_itm = [], [] - for d in getlist(self.doclist,'delivery_note_details'): - ch = sql("select is_stock_item from `tabItem` where name = '%s'"%d.item_code) - if d.prevdoc_doctype and d.prevdoc_detail_docname and ch and ch[0][0]=='Yes': - self.validate_items_with_prevdoc(d) + # ******************** Validate Items ************************** + def validate_for_items(self): + check_list, chk_dupl_itm = [], [] + for d in getlist(self.doclist,'delivery_note_details'): + ch = sql("select is_stock_item from `tabItem` where name = '%s'"%d.item_code) + if d.prevdoc_doctype and d.prevdoc_detail_docname and ch and ch[0][0]=='Yes': + self.validate_items_with_prevdoc(d) - # validates whether item is not entered twice - e = [d.item_code, d.description, d.warehouse, d.prevdoc_docname or '', d.batch_no or ''] - f = [d.item_code, d.description, d.prevdoc_docname or ''] + # validates whether item is not entered twice + e = [d.item_code, d.description, d.warehouse, d.prevdoc_docname or '', d.batch_no or ''] + f = [d.item_code, d.description, d.prevdoc_docname or ''] - if ch and ch[0][0] == 'Yes': - if e in check_list: - msgprint("Please check whether item %s has been entered twice wrongly." % d.item_code) - else: - check_list.append(e) - elif ch and ch[0][0] == 'No': - if f in chk_dupl_itm: - msgprint("Please check whether item %s has been entered twice wrongly." % d.item_code) - else: - chk_dupl_itm.append(f) + if ch and ch[0][0] == 'Yes': + if e in check_list: + msgprint("Please check whether item %s has been entered twice wrongly." % d.item_code) + else: + check_list.append(e) + elif ch and ch[0][0] == 'No': + if f in chk_dupl_itm: + msgprint("Please check whether item %s has been entered twice wrongly." % d.item_code) + else: + chk_dupl_itm.append(f) - # check if same item, warehouse present in prevdoc - # ------------------------------------------------------------------ - def validate_items_with_prevdoc(self, d): - if d.prevdoc_doctype == 'Sales Order': - data = sql("select item_code, reserved_warehouse from `tabSales Order Detail` where parent = '%s' and name = '%s'" % (d.prevdoc_docname, d.prevdoc_detail_docname)) - if d.prevdoc_doctype == 'Purchase Receipt': - data = sql("select item_code, rejected_warehouse from `tabPurchase Receipt Detail` where parent = '%s' and name = '%s'" % (d.prevdoc_docname, d.prevdoc_detail_docname)) - if not data or data[0][0] != d.item_code or data[0][1] != d.warehouse: - msgprint("Item: %s / Warehouse: %s is not matching with Sales Order: %s. Sales Order might be modified after fetching data from it. Please delete items and fetch again." % (d.item_code, d.warehouse, d.prevdoc_docname)) - raise Exception + # check if same item, warehouse present in prevdoc + # ------------------------------------------------------------------ + def validate_items_with_prevdoc(self, d): + if d.prevdoc_doctype == 'Sales Order': + data = sql("select item_code, reserved_warehouse from `tabSales Order Detail` where parent = '%s' and name = '%s'" % (d.prevdoc_docname, d.prevdoc_detail_docname)) + if d.prevdoc_doctype == 'Purchase Receipt': + data = sql("select item_code, rejected_warehouse from `tabPurchase Receipt Detail` where parent = '%s' and name = '%s'" % (d.prevdoc_docname, d.prevdoc_detail_docname)) + if not data or data[0][0] != d.item_code or data[0][1] != d.warehouse: + msgprint("Item: %s / Warehouse: %s is not matching with Sales Order: %s. Sales Order might be modified after fetching data from it. Please delete items and fetch again." % (d.item_code, d.warehouse, d.prevdoc_docname)) + raise Exception - # ********* UPDATE CURRENT STOCK ***************************** - def update_current_stock(self): - for d in getlist(self.doclist, 'delivery_note_details'): - bin = sql("select actual_qty from `tabBin` where item_code = %s and warehouse = %s", (d.item_code, d.warehouse), as_dict = 1) - d.actual_qty = bin and flt(bin[0]['actual_qty']) or 0 + # ********* UPDATE CURRENT STOCK ***************************** + def update_current_stock(self): + for d in getlist(self.doclist, 'delivery_note_details'): + bin = sql("select actual_qty from `tabBin` where item_code = %s and warehouse = %s", (d.item_code, d.warehouse), as_dict = 1) + d.actual_qty = bin and flt(bin[0]['actual_qty']) or 0 - for d in getlist(self.doclist, 'packing_details'): - bin = sql("select actual_qty, projected_qty from `tabBin` where item_code = %s and warehouse = %s", (d.item_code, d.warehouse), as_dict = 1) - d.actual_qty = bin and flt(bin[0]['actual_qty']) or 0 - d.projected_qty = bin and flt(bin[0]['projected_qty']) or 0 + for d in getlist(self.doclist, 'packing_details'): + bin = sql("select actual_qty, projected_qty from `tabBin` where item_code = %s and warehouse = %s", (d.item_code, d.warehouse), as_dict = 1) + d.actual_qty = bin and flt(bin[0]['actual_qty']) or 0 + d.projected_qty = bin and flt(bin[0]['projected_qty']) or 0 # ON SUBMIT # ================================================================================================= - def on_submit(self): - set(self.doc, 'message', 'Items against your Order #%s have been delivered. Delivery #%s: ' % (self.doc.po_no, self.doc.name)) - self.check_qty_in_stock() - # Check for Approving Authority - get_obj('Authorization Control').validate_approving_authority(self.doc.doctype, self.doc.company, self.doc.grand_total, self) - sl_obj = get_obj("Stock Ledger") - sl_obj.validate_serial_no_warehouse(self, 'packing_details') - sl_obj.update_serial_record(self, 'packing_details', is_submit = 1, is_incoming = 0) - get_obj("Sales Common").update_prevdoc_detail(1,self) - self.update_stock_ledger(update_stock = 1) + def on_submit(self): + set(self.doc, 'message', 'Items against your Order #%s have been delivered. Delivery #%s: ' % (self.doc.po_no, self.doc.name)) + self.check_qty_in_stock() + # Check for Approving Authority + get_obj('Authorization Control').validate_approving_authority(self.doc.doctype, self.doc.company, self.doc.grand_total, self) + sl_obj = get_obj("Stock Ledger") + sl_obj.validate_serial_no_warehouse(self, 'packing_details') + sl_obj.update_serial_record(self, 'packing_details', is_submit = 1, is_incoming = 0) + get_obj("Sales Common").update_prevdoc_detail(1,self) + self.update_stock_ledger(update_stock = 1) - #------------Check Credit Limit--------------------- - self.credit_limit() + #------------Check Credit Limit--------------------- + self.credit_limit() - # set DN status - set(self.doc, 'status', 'Submitted') + # set DN status + set(self.doc, 'status', 'Submitted') - # on submit notification - self.notify_obj.notify_contact('Delivery Note',self.doc.doctype,self.doc.name, self.doc.email_id, self.doc.contact_person) + # on submit notification + self.notify_obj.notify_contact('Delivery Note',self.doc.doctype,self.doc.name, self.doc.email_id, self.doc.contact_person) - # *********** Checks whether actual quantity is present in warehouse ************* - def check_qty_in_stock(self): - for d in getlist(self.doclist, 'packing_details'): - is_stock_item = sql("select is_stock_item from `tabItem` where name = '%s'" % d.item_code)[0][0] - if is_stock_item == 'Yes' and d.warehouse and flt(d.qty) > flt(d.actual_qty): - msgprint("For Item: " + cstr(d.item_code) + " at Warehouse: " + cstr(d.warehouse) + " Quantity: " + cstr(d.qty) +" is not Available. (Must be less than or equal to " + cstr(d.actual_qty) + " )") - raise Exception, "Validation Error" + # *********** Checks whether actual quantity is present in warehouse ************* + def check_qty_in_stock(self): + for d in getlist(self.doclist, 'packing_details'): + is_stock_item = sql("select is_stock_item from `tabItem` where name = '%s'" % d.item_code)[0][0] + if is_stock_item == 'Yes' and d.warehouse and flt(d.qty) > flt(d.actual_qty): + msgprint("For Item: " + cstr(d.item_code) + " at Warehouse: " + cstr(d.warehouse) + " Quantity: " + cstr(d.qty) +" is not Available. (Must be less than or equal to " + cstr(d.actual_qty) + " )") + raise Exception, "Validation Error" # ON CANCEL # ================================================================================================= - def on_cancel(self): - sales_com_obj = get_obj(dt = 'Sales Common') - sales_com_obj.check_stop_sales_order(self) - self.check_next_docstatus() - get_obj('Stock Ledger').update_serial_record(self, 'packing_details', is_submit = 0, is_incoming = 0) - sales_com_obj.update_prevdoc_detail(0,self) - self.update_stock_ledger(update_stock = -1) - # :::::: set DN status ::::::: - set(self.doc, 'status', 'Cancelled') + def on_cancel(self): + sales_com_obj = get_obj(dt = 'Sales Common') + sales_com_obj.check_stop_sales_order(self) + self.check_next_docstatus() + get_obj('Stock Ledger').update_serial_record(self, 'packing_details', is_submit = 0, is_incoming = 0) + sales_com_obj.update_prevdoc_detail(0,self) + self.update_stock_ledger(update_stock = -1) + # :::::: set DN status ::::::: + set(self.doc, 'status', 'Cancelled') - # ******************** Check Next DocStatus ************************** - def check_next_docstatus(self): - submit_rv = sql("select t1.name from `tabReceivable Voucher` t1,`tabRV Detail` t2 where t1.name = t2.parent and t2.delivery_note = '%s' and t1.docstatus = 1" % (self.doc.name)) - if submit_rv: - msgprint("Sales Invoice : " + cstr(submit_rv[0][0]) + " has already been submitted !") - raise Exception , "Validation Error." + # ******************** Check Next DocStatus ************************** + def check_next_docstatus(self): + submit_rv = sql("select t1.name from `tabReceivable Voucher` t1,`tabRV Detail` t2 where t1.name = t2.parent and t2.delivery_note = '%s' and t1.docstatus = 1" % (self.doc.name)) + if submit_rv: + msgprint("Sales Invoice : " + cstr(submit_rv[0][0]) + " has already been submitted !") + raise Exception , "Validation Error." - submit_in = sql("select t1.name from `tabInstallation Note` t1, `tabInstalled Item Details` t2 where t1.name = t2.parent and t2.prevdoc_docname = '%s' and t1.docstatus = 1" % (self.doc.name)) - if submit_in: - msgprint("Installation Note : "+cstr(submit_in[0][0]) +" has already been submitted !") - raise Exception , "Validation Error." + submit_in = sql("select t1.name from `tabInstallation Note` t1, `tabInstalled Item Details` t2 where t1.name = t2.parent and t2.prevdoc_docname = '%s' and t1.docstatus = 1" % (self.doc.name)) + if submit_in: + msgprint("Installation Note : "+cstr(submit_in[0][0]) +" has already been submitted !") + raise Exception , "Validation Error." # UPDATE STOCK LEDGER # ================================================================================================= - def update_stock_ledger(self, update_stock, is_stopped = 0): - self.values = [] - for d in self.get_item_list(is_stopped): - stock_item = sql("SELECT is_stock_item, is_sample_item FROM tabItem where name = '%s'"%(d[1]), as_dict = 1) # stock ledger will be updated only if it is a stock item - if stock_item[0]['is_stock_item'] == "Yes": - if not d[0]: - msgprint("Message: Please enter Warehouse for item %s as it is stock item."% d[1]) - raise Exception - # 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) + def update_stock_ledger(self, update_stock, is_stopped = 0): + self.values = [] + for d in self.get_item_list(is_stopped): + stock_item = sql("SELECT is_stock_item, is_sample_item FROM tabItem where name = '%s'"%(d[1]), as_dict = 1) # stock ledger will be updated only if it is a stock item + if stock_item[0]['is_stock_item'] == "Yes": + if not d[0]: + msgprint("Message: Please enter Warehouse for item %s as it is stock item."% d[1]) + raise Exception + # 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) - # 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) + # 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) - # ***************** Gets Items from packing list ***************** - def get_item_list(self, is_stopped): - return get_obj('Sales Common').get_item_list(self, is_stopped) + # ***************** Gets Items from packing list ***************** + def get_item_list(self, is_stopped): + return get_obj('Sales Common').get_item_list(self, is_stopped) - # ********************** Make Stock Entry ************************************ - def make_sl_entry(self, d, wh, qty, in_value, update_stock): - self.values.append({ - 'item_code' : d[1], - 'warehouse' : wh, - 'transaction_date' : self.doc.transaction_date, - 'posting_date' : self.doc.posting_date, - 'posting_time' : self.doc.posting_time, - 'voucher_type' : 'Delivery Note', - 'voucher_no' : self.doc.name, - 'voucher_detail_no' : '', - 'actual_qty' : qty, - 'stock_uom' : d[4], - 'incoming_rate' : in_value, - 'company' : self.doc.company, - 'fiscal_year' : self.doc.fiscal_year, - 'is_cancelled' : (update_stock==1) and 'No' or 'Yes', - 'batch_no' : d[5], - 'serial_no' : d[6] - }) + # ********************** Make Stock Entry ************************************ + def make_sl_entry(self, d, wh, qty, in_value, update_stock): + self.values.append({ + 'item_code' : d[1], + 'warehouse' : wh, + 'transaction_date' : self.doc.transaction_date, + 'posting_date' : self.doc.posting_date, + 'posting_time' : self.doc.posting_time, + 'voucher_type' : 'Delivery Note', + 'voucher_no' : self.doc.name, + 'voucher_detail_no' : '', + 'actual_qty' : qty, + 'stock_uom' : d[4], + 'incoming_rate' : in_value, + 'company' : self.doc.company, + 'fiscal_year' : self.doc.fiscal_year, + 'is_cancelled' : (update_stock==1) and 'No' or 'Yes', + 'batch_no' : d[5], + 'serial_no' : d[6] + }) - # SEND SMS - # ============================================================================================ - def send_sms(self): - if not self.doc.customer_mobile_no: - msgprint("Please enter customer mobile no") - elif not self.doc.message: - msgprint("Please enter the message you want to send") - else: - msgprint(get_obj("SMS Control", "SMS Control").send_sms([self.doc.customer_mobile_no,], self.doc.message)) + # SEND SMS + # ============================================================================================ + def send_sms(self): + if not self.doc.customer_mobile_no: + msgprint("Please enter customer mobile no") + elif not self.doc.message: + msgprint("Please enter the message you want to send") + else: + msgprint(get_obj("SMS Control", "SMS Control").send_sms([self.doc.customer_mobile_no,], self.doc.message)) #------------ check credit limit of items in DN Detail which are not fetched from sales order---------- - def credit_limit(self): - amount, total = 0, 0 - for d in getlist(self.doclist, 'delivery_note_details'): - if not d.prevdoc_docname: - amount += d.amount - if amount != 0: - total = (amount/self.doc.net_total)*self.doc.grand_total - get_obj('Sales Common').check_credit(self, total) - - # on update - def on_update(self): - self.set_actual_qty() - get_obj('Stock Ledger').scrub_serial_nos(self) - - # Repair Delivery Note - # =========================================== - def repair_delivery_note(self): - get_obj('Sales Common', 'Sales Common').repair_curr_doctype_details(self) - - # Packing Slip Related - # ========================================== - def update_pack_nett_weight(self): - for d in getlist(self.doclist, 'delivery_note_details'): - if d.item_code: - 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])*flt(d.qty) 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:#Footer goes here - html+='
CASE NO'+cstr(d.pack_no)+'NETT WT'+cstr(tot_nett_wt)+'CHECKED BY
SIZEGROSS WT'+cstr(tot_gross_wt)+'PACKED BY
' - if prev_pack!=d.pack_no: #Prepare Header Here - #Header code goes here - html+='
[HEADER GOES HERE]

Packing Slip

Order No.'+cstr(self.doc.sales_order_no)+'Shipping Marks'+cstr(d.pack_no)+'
' - html+='' - sno=0 - tot_nett_wt,to_gross_wt=flt(d.pack_nett_wt),flt(d.pack_gross_wt) - #Body code goes here - html+='' - prev_pack=d.pack_no - tot_nett_wt+=flt(d.pack_nett_wt) - tot_gross_wt+=flt(d.pack_gross_wt) - html+='' - self.doc.print_packing_slip=html - - + def credit_limit(self): + amount, total = 0, 0 + for d in getlist(self.doclist, 'delivery_note_details'): + if not d.prevdoc_docname: + amount += d.amount + if amount != 0: + total = (amount/self.doc.net_total)*self.doc.grand_total + get_obj('Sales Common').check_credit(self, total) + # on update + def on_update(self): + self.set_actual_qty() + get_obj('Stock Ledger').scrub_serial_nos(self) + # Repair Delivery Note + # =========================================== + def repair_delivery_note(self): + get_obj('Sales Common', 'Sales Common').repair_curr_doctype_details(self) + # Packing Slip Related + # ========================================== + def update_pack_nett_weight(self): + for d in getlist(self.doclist, 'delivery_note_details'): + 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 get_header(self, so_no, shipping_mark): + header = ''' +
[HEADER GOES HERE]
+

Packing Slip

+
S.NO.QUANTITYCS.NO.DESCRIPTIONWEIGHT
'+cstr(sno+1)+''+cstr(d.qty)+''+d.item_code+''+cstr(d.pack_nett_wt)+'
+ + + + + + +
ORDER NO.'''+cstr(so_no)+'''SHIPPING MARKS'''+cstr(shipping_mark)+'''
'''; + + return header + + def get_footer(self, row, tot_nett, tot_gross): + footer = ''' + + + + + + + + + + + +
CASE NO'''+cstr(row.pack_no)+'''NETT WT'''+cstr(tot_nett)+'''CHECKED BY'''+cstr(row.packing_checked_by)+'''
SIZE'''+cstr(row.pack_size)+'''GROSS WT'''+cstr(tot_gross)+'''PACKED BY'''+cstr(row.packed_by)+'''
''' + + 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 += ''' + + + + + ''' + + # item table data + sr_no = 1 + for r in plist.get(d): + html += '' + + tot_nett_wt += flt(r.pack_nett_wt) + tot_gross_wt += flt(r.pack_gross_wt) + + sr_no += 1 + + html += '
SR.NO.CS.NO.DESCRIPTIONQUANTITYWEIGHT
'+cstr(sr_no)+''+r.item_code+''+r.description+''+cstr(r.qty)+''+cstr(r.pack_nett_wt)+'
' + # 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 a3897ec17b4..8109af5c4e6 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-07 17:36:34', + 'modified': '2011-10-18 13:57:23', 'modified_by': 'Administrator', 'owner': 'Administrator' }, @@ -21,7 +21,7 @@ # These values are common for all DocType { - '_last_update': '1314093417', + '_last_update': '1318321312', 'colour': 'White:FFF', 'default_print_format': 'Standard', 'doctype': 'DocType', @@ -37,7 +37,7 @@ 'show_in_menu': 0, 'subject': 'To %(customer_name)s on %(transaction_date)s | %(per_billed)s% billed', 'tag_fields': 'billing_status', - 'version': 450 + 'version': 454 }, # These values are common for all DocFormat @@ -114,6 +114,18 @@ 'write': 1 }, + # DocPerm + { + 'amend': 1, + 'cancel': 1, + 'create': 1, + 'doctype': 'DocPerm', + 'permlevel': 0, + 'role': 'Sales Manager', + 'submit': 1, + 'write': 1 + }, + # DocPerm { 'doctype': 'DocPerm', @@ -133,11 +145,6 @@ 'doctype': 'DocFormat' }, - # DocFormat - { - 'doctype': 'DocFormat' - }, - # DocField { 'colour': 'White:FFF', @@ -627,6 +634,7 @@ # DocField { + 'allow_on_submit': 1, 'doctype': 'DocField', 'fieldname': 'delivery_note_details', 'fieldtype': 'Table', @@ -1390,6 +1398,42 @@ 'in_filter': 0, 'label': 'Print Packing Slip', 'permlevel': 0, - 'print_hide': 0 + 'print_hide': 1 + }, + + # DocField + { + 'doctype': 'DocField', + 'fieldname': 'shipping_mark', + 'fieldtype': 'Text', + 'label': 'Shipping Mark', + 'permlevel': 0 + }, + + # DocField + { + 'doctype': 'DocField', + 'fieldname': 'packed_by', + 'fieldtype': 'Text', + 'label': 'Packed By', + 'permlevel': 0 + }, + + # DocField + { + 'doctype': 'DocField', + 'fieldname': 'packing_checked_by', + 'fieldtype': 'Text', + 'label': 'Packing Checked By', + 'permlevel': 0 + }, + + # DocField + { + 'doctype': 'DocField', + 'fieldname': 'pack_size', + 'fieldtype': 'Text', + 'label': 'Pack Size', + 'permlevel': 0 } ] \ No newline at end of file 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 be7b98f771f..806803f73a7 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 @@ -354,6 +356,37 @@ 'width': '100px' }, + # 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', diff --git a/erpnext/stock/doctype/item/item.py b/erpnext/stock/doctype/item/item.py index 28f1d12e855..4dca7040f27 100644 --- a/erpnext/stock/doctype/item/item.py +++ b/erpnext/stock/doctype/item/item.py @@ -63,6 +63,9 @@ class DocType: child.conversion_factor = 1 child.save() + # On delete 1. Delete BIN (if none of the corrosponding transactions present, it gets deleted. if present, rolled back due to exception) + def on_trash(self): + sql("delete from tabBin where item_code='%s'"%(self.doc.item_code)) # Check whether Ref Rate is not entered twice for same Price List and Currency def check_ref_rate_detail(self): @@ -124,7 +127,7 @@ class DocType: self.doc.min_order_qty = 0 self.check_non_asset_warehouse() - if self.doc.is_pro_applicable == 'Yes' and self.doc.is_manufactured_item != 'Yes': + if self.doc.is_pro_applicable and self.doc.is_pro_applicable == 'Yes' and self.doc.is_manufactured_item and self.doc.is_manufactured_item != 'Yes': msgprint("If making Production Order is allowed then, it should also allow to make Bill of Materials. Refer Manufacturing section.") raise Exception diff --git a/erpnext/stock/doctype/item/test_item.py b/erpnext/stock/doctype/item/test_item.py new file mode 100644 index 00000000000..529c82ab698 --- /dev/null +++ b/erpnext/stock/doctype/item/test_item.py @@ -0,0 +1,62 @@ +import unittest +import webnotes +import copy + +from webnotes.model.doclist import DocList +from webnotes.model.doc import Document +from webnotes.model.code import get_obj +from webnotes.utils import flt + +sql = webnotes.conn.sql + + +class TestItem(unittest.TestCase): + def setUp(self): + webnotes.conn.begin() + + def tearDown(self): + webnotes.conn.rollback() + + def testInsert(self): + d = DocList() + + count_before = flt(sql("select count(*) from tab"+_doctype)[0][0]) + if docok: + for i in docok: + d.doc = i + d.children = None + d.doc.fields['__islocal']=1 + d.save(1) + count_after = flt(sql("select count(*) from tab"+_doctype)[0][0]) + self.assertTrue(count_before+len(docok)==count_after) + + def testFailAssert(self): + if docnotok: + with self.assertRaises(Exception) as context: + d = DocList() + d.doc = docnotok[0] + d.children = None + d.doc.fields['__islocal']=1 + d.save(1) + +# Test Data + +tabOK = [ + {'is_purchase_item': None, 'is_pro_applicable': 'No', 'is_manufactured_item': None, 'description': 'Gel Ink', 'default_warehouse': None, 'item_name': 'Gel Ink', 'item_group': 'Ink', 'item_code': 'GELINK', 'is_sub_contracted_item': None, 'is_stock_item': 'Yes', 'stock_uom': 'Nos', 'docstatus': '0'}, + {'is_purchase_item': None, 'is_pro_applicable': 'No', 'is_manufactured_item': None, 'description': 'Gel Refill', 'default_warehouse': None, 'item_name': 'Gel Refill', 'item_group': 'Refill', 'item_code': 'GELREF', 'is_sub_contracted_item': None, 'is_stock_item': 'Yes', 'stock_uom': 'Nos', 'docstatus': '0'}, + {'is_purchase_item': None, 'is_pro_applicable': 'No', 'is_manufactured_item': None, 'description': 'Gel Pen', 'default_warehouse': None, 'item_name': 'Gel Pen', 'item_group': 'Pen', 'item_code': 'GELPEN', 'is_sub_contracted_item': None, 'is_stock_item': 'Yes', 'stock_uom': 'Nos', 'docstatus': '0'} + ] + +tabNotOK = [ + {'is_purchase_item': None, 'is_pro_applicable': None, 'is_manufactured_item': None, 'description': 'F Ink', 'default_warehouse': None, 'item_name': 'F Ink', 'item_group': 'F Ink', 'item_code': None, 'is_sub_contracted_item': None, 'is_stock_item': 'No', 'stock_uom': 'Nos', 'docstatus': '0'} + ] + +_doctype = 'Item' + +for i in tabOK: i['doctype']=_doctype +for i in tabNotOK: i['doctype']=_doctype + +docok = [Document(fielddata=r) for r in tabOK] +docnotok = [Document(fielddata=r) for r in tabNotOK] + + 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 5209d1ab26c..369fd4d2673 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 @@ cur_frm.cscript.onload = function(doc, cdt, cdn) { 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 58ba751f43e..2b828f90597 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,177 @@ class DocType: 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() + 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_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 90c570aebc8..1e12afae71c 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,17 +113,30 @@ # DocPerm { 'doctype': 'DocPerm', - 'idx': 8, 'permlevel': 1, 'role': 'Purchase Manager' }, + # DocField + { + 'doctype': 'DocField', + 'fieldtype': 'HTML', + 'label': 'Process', + 'options': '
Process:
1. Fetch and select Purchase Receipt
2. Enter extra costs
3. Click on Update Landed Cost button
4. Cost will be added into other charges table of selected PR proportionately based on net total
5. Item Valuation Rate will be recalculated
' + }, + + # 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,26 +164,15 @@ { 'doctype': 'DocField', 'fieldtype': 'Button', - 'idx': 4, 'label': 'Get Purchase Receipt', 'options': 'get_purchase_receipts' }, - # 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 d09285db92e..b6bcb42a9d8 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 f6f4984c840..ec7307979a9 100644 --- a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.js +++ b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.js @@ -105,7 +105,7 @@ cur_frm.cscript.transaction_date = function(doc,cdt,cdn){ } // ***************** 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_detail/purchase_receipt_detail.txt b/erpnext/stock/doctype/purchase_receipt_detail/purchase_receipt_detail.txt index a8e0d47060e..2e3514e36f3 100644 --- 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-11-16 15:43:36', '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': 63 }, # 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', @@ -87,31 +85,12 @@ 'width': '300px' }, - # 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', @@ -121,28 +100,12 @@ 'width': '100px' }, - # DocField - { - 'default': '0.00', - 'doctype': 'DocField', - 'fieldname': 'qty', - 'fieldtype': 'Currency', - 'idx': 6, - 'label': 'Accepted Quantity', - 'oldfieldname': 'qty', - 'oldfieldtype': 'Currency', - 'permlevel': 0, - 'trigger': 'Client', - 'width': '100px' - }, - # DocField { 'default': '0.00', 'doctype': 'DocField', 'fieldname': 'rejected_qty', 'fieldtype': 'Currency', - 'idx': 7, 'in_filter': 0, 'label': 'Rejected Quantity', 'oldfieldname': 'rejected_qty', @@ -160,7 +123,6 @@ 'doctype': 'DocField', 'fieldname': 'purchase_rate', 'fieldtype': 'Currency', - 'idx': 8, 'label': 'Rate (Default Curr.)', 'oldfieldname': 'purchase_rate', 'oldfieldtype': 'Currency', @@ -171,13 +133,26 @@ 'width': '100px' }, + # DocField + { + 'default': '0.00', + 'doctype': 'DocField', + 'fieldname': 'qty', + 'fieldtype': 'Currency', + 'label': 'Accepted Quantity', + 'oldfieldname': 'qty', + 'oldfieldtype': 'Currency', + 'permlevel': 0, + 'trigger': 'Client', + 'width': '100px' + }, + # DocField { 'default': '0.00', 'doctype': 'DocField', 'fieldname': 'amount', 'fieldtype': 'Currency', - 'idx': 9, 'label': 'Amount (Default Curr.)', 'oldfieldname': 'amount', 'oldfieldtype': 'Currency', @@ -192,32 +167,15 @@ { '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', + 'fieldname': 'uom', 'fieldtype': 'Link', - 'hidden': 0, - 'idx': 11, - 'label': 'Accepted Warehouse', - 'oldfieldname': 'warehouse', + 'label': 'UOM', + 'oldfieldname': 'uom', 'oldfieldtype': 'Link', - 'options': 'Warehouse', + 'options': 'UOM', 'permlevel': 0, - 'print_hide': 0, + 'reqd': 1, + 'trigger': 'Client', 'width': '100px' }, @@ -228,7 +186,6 @@ 'doctype': 'DocField', 'fieldname': 'import_rate', 'fieldtype': 'Currency', - 'idx': 12, 'label': 'Rate', 'oldfieldname': 'import_rate', 'oldfieldtype': 'Currency', @@ -243,7 +200,6 @@ 'doctype': 'DocField', 'fieldname': 'import_amount', 'fieldtype': 'Currency', - 'idx': 13, 'label': 'Amount', 'oldfieldname': 'import_amount', 'oldfieldtype': 'Currency', @@ -255,7 +211,6 @@ 'doctype': 'DocField', 'fieldname': 'conversion_factor', 'fieldtype': 'Currency', - 'idx': 14, 'label': 'Conversion Factor', 'oldfieldname': 'conversion_factor', 'oldfieldtype': 'Currency', @@ -266,12 +221,26 @@ 'width': '100px' }, + # DocField + { + 'doctype': 'DocField', + 'fieldname': 'warehouse', + 'fieldtype': 'Link', + 'hidden': 0, + 'label': 'Accepted Warehouse', + 'oldfieldname': 'warehouse', + 'oldfieldtype': 'Link', + 'options': 'Warehouse', + 'permlevel': 0, + 'print_hide': 0, + 'width': '100px' + }, + # DocField { 'doctype': 'DocField', 'fieldname': 'stock_uom', 'fieldtype': 'Data', - 'idx': 15, 'label': 'Stock UOM', 'oldfieldname': 'stock_uom', 'oldfieldtype': 'Data', @@ -283,17 +252,65 @@ # 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 + { + '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 + { + '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 @@ -302,7 +319,7 @@ 'doctype': 'DocField', 'fieldname': 'serial_no', 'fieldtype': 'Text', - 'idx': 17, + 'in_filter': 1, 'label': 'Serial No', 'no_copy': 1, 'oldfieldname': 'serial_no', @@ -318,84 +335,55 @@ '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', 'permlevel': 0, - 'print_hide': 1, - 'search_index': 0 + 'print_hide': 1 }, # DocField { 'doctype': 'DocField', - 'fieldname': 'brand', - 'fieldtype': 'Link', - 'hidden': 1, - 'idx': 21, - 'label': 'Brand', - 'oldfieldname': 'brand', - 'oldfieldtype': 'Link', - 'options': 'Brand', - 'permlevel': 1, + 'fieldname': 'stock_qty', + 'fieldtype': 'Currency', + 'label': 'Stock Qty', + 'oldfieldname': 'stock_qty', + 'oldfieldtype': 'Currency', + 'permlevel': 0, 'print_hide': 1, - 'search_index': 0 + 'trigger': 'Client', + 'width': '100px' }, # DocField { + 'colour': 'White:FFF', 'doctype': 'DocField', - 'fieldname': 'item_group', + 'fieldname': 'project_name', '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 + 'label': 'Project Name', + 'options': 'Project', + 'permlevel': 0, + 'print_hide': 1 }, # DocField @@ -405,7 +393,6 @@ 'fieldname': 'prevdoc_doctype', 'fieldtype': 'Data', 'hidden': 1, - 'idx': 23, 'label': 'Prevdoc Doctype', 'oldfieldname': 'prevdoc_doctype', 'oldfieldtype': 'Data', @@ -420,7 +407,6 @@ 'fieldname': 'prevdoc_docname', 'fieldtype': 'Link', 'hidden': 0, - 'idx': 24, 'in_filter': 1, 'label': 'PO No', 'no_copy': 0, @@ -440,7 +426,6 @@ 'fieldname': 'prevdoc_date', 'fieldtype': 'Date', 'hidden': 1, - 'idx': 25, 'in_filter': 1, 'label': 'PO Date', 'oldfieldname': 'prevdoc_date', @@ -455,7 +440,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 +451,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 +463,7 @@ 'permlevel': 1, 'print_hide': 1, 'reqd': 0, - 'search_index': 0, + 'search_index': 1, 'width': '150px' }, @@ -490,7 +474,6 @@ 'fieldname': 'prevdoc_detail_docname', 'fieldtype': 'Data', 'hidden': 1, - 'idx': 28, 'in_filter': 1, 'label': 'PO Detail No', 'no_copy': 0, @@ -508,7 +491,6 @@ 'doctype': 'DocField', 'fieldname': 'billed_qty', 'fieldtype': 'Currency', - 'idx': 29, 'label': 'Billed Quantity', 'no_copy': 1, 'oldfieldname': 'billed_qty', @@ -520,11 +502,11 @@ # 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, @@ -537,12 +519,12 @@ # 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 +540,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 024bd1f34b8..208dd288f45 100644 --- a/erpnext/stock/doctype/stock_entry/stock_entry.py +++ b/erpnext/stock/doctype/stock_entry/stock_entry.py @@ -93,7 +93,7 @@ class DocType: 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,17 +121,46 @@ class DocType: 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 - fl_bom_sa_child_item = 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 in (select distinct parent_bom from `tabFlat BOM Detail` where parent = '%s' and parent_bom != '%s' and is_pro_applicable = 'Yes' and docstatus < 2 ) 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), 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): @@ -165,8 +194,9 @@ class DocType: self.get_raw_materials(pro_obj) self.doc.clear_table(self.doclist, 'mtn_details', 1) - + self.add_to_stock_entry_detail(pro_obj, self.item_dict) + if self.doc.process == 'Backflush': item_dict = {cstr(pro_obj.doc.production_item) : [self.doc.fg_completed_qty, pro_obj.doc.description, pro_obj.doc.stock_uom]} self.add_to_stock_entry_detail(pro_obj, item_dict, fg_item = 1) @@ -176,11 +206,10 @@ class DocType: 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'): diff --git a/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py b/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py index f040df38392..e133d6fad30 100644 --- a/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py +++ b/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py @@ -131,18 +131,18 @@ class DocType: update item valuation in previous date and also on post date if no qty diff """ - self.update_item_valuation_pre_date(d) + self.update_entries_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) + self.update_entries_post_date(d) # update valuation rate as csv file in all sle before reconciliation date # ------------------------------------------------------------------------ - def update_item_valuation_pre_date(self, d): + def update_entries_pre_date(self, d): mar = flt(d[self.label['mar']]) # previous sle @@ -168,15 +168,12 @@ class DocType: # Update item valuation in all sle after the reconcliation date # --------------------------------------------------------- - def update_item_valuation_post_date(self, d): + def update_entries_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) + bin_obj.update_entries_after(posting_date = self.doc.reconciliation_date, posting_time = self.doc.reconciliation_time) # -------------- # make sl entry 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 f8ac7372a52..0fa7a3bf06f 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 @@ class DocType: 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 131c71b13e4..f37b7e7c7f7 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 f3d600de133..b59ce753971 100644 --- a/erpnext/stock/doctype/warehouse/warehouse.py +++ b/erpnext/stock/doctype/warehouse/warehouse.py @@ -68,7 +68,7 @@ class DocType: 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') + bobj.update_entries_after(posting_date = '0000-00-00', posting_time = '00:00') sql("COMMIT") sql("START TRANSACTION") diff --git a/erpnext/utilities/doctype/reposting_tool/reposting_tool.py b/erpnext/utilities/doctype/reposting_tool/reposting_tool.py index c4f021b2979..489a3b67782 100644 --- a/erpnext/utilities/doctype/reposting_tool/reposting_tool.py +++ b/erpnext/utilities/doctype/reposting_tool/reposting_tool.py @@ -88,7 +88,7 @@ class DocType: 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 a1edf83bf36..c5951585a78 100644 --- a/erpnext/utilities/doctype/sms_control/sms_control.py +++ b/erpnext/utilities/doctype/sms_control/sms_control.py @@ -63,7 +63,15 @@ class DocType: 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 64eef0f666a..c28b0aa3a9a 100644 --- a/index.html +++ b/index.html @@ -3,7 +3,7 @@ ERPNext -
- \ No newline at end of file + diff --git a/versions-master.db b/versions-master.db index 0b3bcb2d3f1..57072436b65 100644 Binary files a/versions-master.db and b/versions-master.db differ