Merge branch 'develop' of https://github.com/frappe/erpnext into wip_payrec
diff --git a/erpnext/accounts/doctype/sales_invoice/test_records.json b/erpnext/accounts/doctype/sales_invoice/test_records.json
index b0828f5..eb86672 100644
--- a/erpnext/accounts/doctype/sales_invoice/test_records.json
+++ b/erpnext/accounts/doctype/sales_invoice/test_records.json
@@ -1,385 +1,385 @@
[
{
- "company": "_Test Company",
- "conversion_rate": 1.0,
- "currency": "INR",
- "customer": "_Test Customer",
- "customer_name": "_Test Customer",
- "debit_to": "_Test Customer - _TC",
- "doctype": "Sales Invoice",
- "due_date": "2013-01-23",
+ "company": "_Test Company",
+ "conversion_rate": 1.0,
+ "currency": "INR",
+ "customer": "_Test Customer",
+ "customer_name": "_Test Customer",
+ "debit_to": "_Test Customer - _TC",
+ "doctype": "Sales Invoice",
+ "due_date": "2013-01-23",
"entries": [
{
- "amount": 500.0,
- "base_amount": 500.0,
- "base_rate": 500.0,
- "cost_center": "_Test Cost Center - _TC",
- "description": "138-CMS Shoe",
- "doctype": "Sales Invoice Item",
- "income_account": "Sales - _TC",
- "item_name": "138-CMS Shoe",
- "parentfield": "entries",
- "qty": 1.0,
+ "amount": 500.0,
+ "base_amount": 500.0,
+ "base_rate": 500.0,
+ "cost_center": "_Test Cost Center - _TC",
+ "description": "138-CMS Shoe",
+ "doctype": "Sales Invoice Item",
+ "income_account": "Sales - _TC",
+ "item_name": "138-CMS Shoe",
+ "parentfield": "entries",
+ "qty": 1.0,
"rate": 500.0
}
- ],
- "fiscal_year": "_Test Fiscal Year 2013",
- "grand_total": 561.8,
- "grand_total_export": 561.8,
- "is_pos": 0,
- "naming_series": "_T-Sales Invoice-",
- "net_total": 500.0,
+ ],
+ "fiscal_year": "_Test Fiscal Year 2013",
+ "grand_total": 561.8,
+ "grand_total_export": 561.8,
+ "is_pos": 0,
+ "naming_series": "_T-Sales Invoice-",
+ "net_total": 500.0,
"other_charges": [
{
- "account_head": "_Test Account VAT - _TC",
- "charge_type": "On Net Total",
- "description": "VAT",
- "doctype": "Sales Taxes and Charges",
- "parentfield": "other_charges",
+ "account_head": "_Test Account VAT - _TC",
+ "charge_type": "On Net Total",
+ "description": "VAT",
+ "doctype": "Sales Taxes and Charges",
+ "parentfield": "other_charges",
"rate": 6
- },
+ },
{
- "account_head": "_Test Account Service Tax - _TC",
- "charge_type": "On Net Total",
- "description": "Service Tax",
- "doctype": "Sales Taxes and Charges",
- "parentfield": "other_charges",
+ "account_head": "_Test Account Service Tax - _TC",
+ "charge_type": "On Net Total",
+ "description": "Service Tax",
+ "doctype": "Sales Taxes and Charges",
+ "parentfield": "other_charges",
"rate": 6.36
}
- ],
- "plc_conversion_rate": 1.0,
- "posting_date": "2013-01-23",
- "price_list_currency": "INR",
+ ],
+ "plc_conversion_rate": 1.0,
+ "posting_date": "2013-01-23",
+ "price_list_currency": "INR",
"sales_team": [
{
- "allocated_percentage": 65.5,
- "doctype": "Sales Team",
- "parentfield": "sales_team",
+ "allocated_percentage": 65.5,
+ "doctype": "Sales Team",
+ "parentfield": "sales_team",
"sales_person": "_Test Sales Person 1"
- },
+ },
{
- "allocated_percentage": 34.5,
- "doctype": "Sales Team",
- "parentfield": "sales_team",
+ "allocated_percentage": 34.5,
+ "doctype": "Sales Team",
+ "parentfield": "sales_team",
"sales_person": "_Test Sales Person 2"
}
- ],
- "selling_price_list": "_Test Price List",
+ ],
+ "selling_price_list": "_Test Price List",
"territory": "_Test Territory"
- },
+ },
{
- "company": "_Test Company",
- "conversion_rate": 1.0,
- "currency": "INR",
- "customer": "_Test Customer",
- "customer_name": "_Test Customer",
- "debit_to": "_Test Customer - _TC",
- "doctype": "Sales Invoice",
- "due_date": "2013-01-23",
+ "company": "_Test Company",
+ "conversion_rate": 1.0,
+ "currency": "INR",
+ "customer": "_Test Customer",
+ "customer_name": "_Test Customer",
+ "debit_to": "_Test Customer - _TC",
+ "doctype": "Sales Invoice",
+ "due_date": "2013-03-07",
"entries": [
{
- "amount": 500.0,
- "base_amount": 500.0,
- "base_rate": 500.0,
- "cost_center": "_Test Cost Center - _TC",
- "description": "_Test Item",
- "doctype": "Sales Invoice Item",
- "expense_account": "_Test Account Cost for Goods Sold - _TC",
- "income_account": "Sales - _TC",
- "item_code": "_Test Item",
- "item_name": "_Test Item",
- "parentfield": "entries",
- "price_list_rate": 500.0,
+ "amount": 500.0,
+ "base_amount": 500.0,
+ "base_rate": 500.0,
+ "cost_center": "_Test Cost Center - _TC",
+ "description": "_Test Item",
+ "doctype": "Sales Invoice Item",
+ "expense_account": "_Test Account Cost for Goods Sold - _TC",
+ "income_account": "Sales - _TC",
+ "item_code": "_Test Item",
+ "item_name": "_Test Item",
+ "parentfield": "entries",
+ "price_list_rate": 500.0,
"qty": 1.0
}
- ],
- "fiscal_year": "_Test Fiscal Year 2013",
- "grand_total": 630.0,
- "grand_total_export": 630.0,
- "is_pos": 0,
- "naming_series": "_T-Sales Invoice-",
- "net_total": 500.0,
+ ],
+ "fiscal_year": "_Test Fiscal Year 2013",
+ "grand_total": 630.0,
+ "grand_total_export": 630.0,
+ "is_pos": 0,
+ "naming_series": "_T-Sales Invoice-",
+ "net_total": 500.0,
"other_charges": [
{
- "account_head": "_Test Account VAT - _TC",
- "charge_type": "On Net Total",
- "description": "VAT",
- "doctype": "Sales Taxes and Charges",
- "parentfield": "other_charges",
+ "account_head": "_Test Account VAT - _TC",
+ "charge_type": "On Net Total",
+ "description": "VAT",
+ "doctype": "Sales Taxes and Charges",
+ "parentfield": "other_charges",
"rate": 16
- },
+ },
{
- "account_head": "_Test Account Service Tax - _TC",
- "charge_type": "On Net Total",
- "description": "Service Tax",
- "doctype": "Sales Taxes and Charges",
- "parentfield": "other_charges",
+ "account_head": "_Test Account Service Tax - _TC",
+ "charge_type": "On Net Total",
+ "description": "Service Tax",
+ "doctype": "Sales Taxes and Charges",
+ "parentfield": "other_charges",
"rate": 10
}
- ],
- "plc_conversion_rate": 1.0,
- "posting_date": "2013-03-07",
- "price_list_currency": "INR",
- "selling_price_list": "_Test Price List",
+ ],
+ "plc_conversion_rate": 1.0,
+ "posting_date": "2013-03-07",
+ "price_list_currency": "INR",
+ "selling_price_list": "_Test Price List",
"territory": "_Test Territory"
- },
+ },
{
- "company": "_Test Company",
- "conversion_rate": 1.0,
- "currency": "INR",
- "customer": "_Test Customer",
- "customer_name": "_Test Customer",
- "debit_to": "_Test Customer - _TC",
- "doctype": "Sales Invoice",
- "due_date": "2013-01-23",
+ "company": "_Test Company",
+ "conversion_rate": 1.0,
+ "currency": "INR",
+ "customer": "_Test Customer",
+ "customer_name": "_Test Customer",
+ "debit_to": "_Test Customer - _TC",
+ "doctype": "Sales Invoice",
+ "due_date": "2013-01-23",
"entries": [
{
- "cost_center": "_Test Cost Center - _TC",
- "doctype": "Sales Invoice Item",
- "income_account": "Sales - _TC",
- "item_code": "_Test Item Home Desktop 100",
- "item_name": "_Test Item Home Desktop 100",
- "item_tax_rate": "{\"_Test Account Excise Duty - _TC\": 10}",
- "parentfield": "entries",
- "price_list_rate": 50,
- "qty": 10,
- "rate": 50,
+ "cost_center": "_Test Cost Center - _TC",
+ "doctype": "Sales Invoice Item",
+ "income_account": "Sales - _TC",
+ "item_code": "_Test Item Home Desktop 100",
+ "item_name": "_Test Item Home Desktop 100",
+ "item_tax_rate": "{\"_Test Account Excise Duty - _TC\": 10}",
+ "parentfield": "entries",
+ "price_list_rate": 50,
+ "qty": 10,
+ "rate": 50,
"stock_uom": "_Test UOM"
- },
+ },
{
- "cost_center": "_Test Cost Center - _TC",
- "doctype": "Sales Invoice Item",
- "income_account": "Sales - _TC",
- "item_code": "_Test Item Home Desktop 200",
- "item_name": "_Test Item Home Desktop 200",
- "parentfield": "entries",
- "price_list_rate": 150,
- "qty": 5,
- "rate": 150,
+ "cost_center": "_Test Cost Center - _TC",
+ "doctype": "Sales Invoice Item",
+ "income_account": "Sales - _TC",
+ "item_code": "_Test Item Home Desktop 200",
+ "item_name": "_Test Item Home Desktop 200",
+ "parentfield": "entries",
+ "price_list_rate": 150,
+ "qty": 5,
+ "rate": 150,
"stock_uom": "_Test UOM"
}
- ],
- "fiscal_year": "_Test Fiscal Year 2013",
- "grand_total_export": 0,
- "is_pos": 0,
- "naming_series": "_T-Sales Invoice-",
+ ],
+ "fiscal_year": "_Test Fiscal Year 2013",
+ "grand_total_export": 0,
+ "is_pos": 0,
+ "naming_series": "_T-Sales Invoice-",
"other_charges": [
{
- "account_head": "_Test Account Shipping Charges - _TC",
- "charge_type": "Actual",
- "cost_center": "_Test Cost Center - _TC",
- "description": "Shipping Charges",
- "doctype": "Sales Taxes and Charges",
- "parentfield": "other_charges",
+ "account_head": "_Test Account Shipping Charges - _TC",
+ "charge_type": "Actual",
+ "cost_center": "_Test Cost Center - _TC",
+ "description": "Shipping Charges",
+ "doctype": "Sales Taxes and Charges",
+ "parentfield": "other_charges",
"rate": 100
- },
+ },
{
- "account_head": "_Test Account Customs Duty - _TC",
- "charge_type": "On Net Total",
- "cost_center": "_Test Cost Center - _TC",
- "description": "Customs Duty",
- "doctype": "Sales Taxes and Charges",
- "parentfield": "other_charges",
+ "account_head": "_Test Account Customs Duty - _TC",
+ "charge_type": "On Net Total",
+ "cost_center": "_Test Cost Center - _TC",
+ "description": "Customs Duty",
+ "doctype": "Sales Taxes and Charges",
+ "parentfield": "other_charges",
"rate": 10
- },
+ },
{
- "account_head": "_Test Account Excise Duty - _TC",
- "charge_type": "On Net Total",
- "cost_center": "_Test Cost Center - _TC",
- "description": "Excise Duty",
- "doctype": "Sales Taxes and Charges",
- "parentfield": "other_charges",
+ "account_head": "_Test Account Excise Duty - _TC",
+ "charge_type": "On Net Total",
+ "cost_center": "_Test Cost Center - _TC",
+ "description": "Excise Duty",
+ "doctype": "Sales Taxes and Charges",
+ "parentfield": "other_charges",
"rate": 12
- },
+ },
{
- "account_head": "_Test Account Education Cess - _TC",
- "charge_type": "On Previous Row Amount",
- "cost_center": "_Test Cost Center - _TC",
- "description": "Education Cess",
- "doctype": "Sales Taxes and Charges",
- "parentfield": "other_charges",
- "rate": 2,
+ "account_head": "_Test Account Education Cess - _TC",
+ "charge_type": "On Previous Row Amount",
+ "cost_center": "_Test Cost Center - _TC",
+ "description": "Education Cess",
+ "doctype": "Sales Taxes and Charges",
+ "parentfield": "other_charges",
+ "rate": 2,
"row_id": 3
- },
+ },
{
- "account_head": "_Test Account S&H Education Cess - _TC",
- "charge_type": "On Previous Row Amount",
- "cost_center": "_Test Cost Center - _TC",
- "description": "S&H Education Cess",
- "doctype": "Sales Taxes and Charges",
- "parentfield": "other_charges",
- "rate": 1,
+ "account_head": "_Test Account S&H Education Cess - _TC",
+ "charge_type": "On Previous Row Amount",
+ "cost_center": "_Test Cost Center - _TC",
+ "description": "S&H Education Cess",
+ "doctype": "Sales Taxes and Charges",
+ "parentfield": "other_charges",
+ "rate": 1,
"row_id": 3
- },
+ },
{
- "account_head": "_Test Account CST - _TC",
- "charge_type": "On Previous Row Total",
- "cost_center": "_Test Cost Center - _TC",
- "description": "CST",
- "doctype": "Sales Taxes and Charges",
- "parentfield": "other_charges",
- "rate": 2,
+ "account_head": "_Test Account CST - _TC",
+ "charge_type": "On Previous Row Total",
+ "cost_center": "_Test Cost Center - _TC",
+ "description": "CST",
+ "doctype": "Sales Taxes and Charges",
+ "parentfield": "other_charges",
+ "rate": 2,
"row_id": 5
- },
+ },
{
- "account_head": "_Test Account VAT - _TC",
- "charge_type": "On Net Total",
- "cost_center": "_Test Cost Center - _TC",
- "description": "VAT",
- "doctype": "Sales Taxes and Charges",
- "parentfield": "other_charges",
+ "account_head": "_Test Account VAT - _TC",
+ "charge_type": "On Net Total",
+ "cost_center": "_Test Cost Center - _TC",
+ "description": "VAT",
+ "doctype": "Sales Taxes and Charges",
+ "parentfield": "other_charges",
"rate": 12.5
- },
+ },
{
- "account_head": "_Test Account Discount - _TC",
- "charge_type": "On Previous Row Total",
- "cost_center": "_Test Cost Center - _TC",
- "description": "Discount",
- "doctype": "Sales Taxes and Charges",
- "parentfield": "other_charges",
- "rate": -10,
+ "account_head": "_Test Account Discount - _TC",
+ "charge_type": "On Previous Row Total",
+ "cost_center": "_Test Cost Center - _TC",
+ "description": "Discount",
+ "doctype": "Sales Taxes and Charges",
+ "parentfield": "other_charges",
+ "rate": -10,
"row_id": 7
}
- ],
- "plc_conversion_rate": 1.0,
- "posting_date": "2013-01-23",
- "price_list_currency": "INR",
- "selling_price_list": "_Test Price List",
+ ],
+ "plc_conversion_rate": 1.0,
+ "posting_date": "2013-01-23",
+ "price_list_currency": "INR",
+ "selling_price_list": "_Test Price List",
"territory": "_Test Territory"
- },
+ },
{
- "company": "_Test Company",
- "conversion_rate": 1.0,
- "currency": "INR",
- "customer": "_Test Customer",
- "customer_name": "_Test Customer",
- "debit_to": "_Test Customer - _TC",
- "doctype": "Sales Invoice",
- "due_date": "2013-01-23",
+ "company": "_Test Company",
+ "conversion_rate": 1.0,
+ "currency": "INR",
+ "customer": "_Test Customer",
+ "customer_name": "_Test Customer",
+ "debit_to": "_Test Customer - _TC",
+ "doctype": "Sales Invoice",
+ "due_date": "2013-01-23",
"entries": [
{
- "cost_center": "_Test Cost Center - _TC",
- "doctype": "Sales Invoice Item",
- "income_account": "Sales - _TC",
- "item_code": "_Test Item Home Desktop 100",
- "item_name": "_Test Item Home Desktop 100",
- "item_tax_rate": "{\"_Test Account Excise Duty - _TC\": 10}",
- "parentfield": "entries",
- "price_list_rate": 62.5,
- "qty": 10,
+ "cost_center": "_Test Cost Center - _TC",
+ "doctype": "Sales Invoice Item",
+ "income_account": "Sales - _TC",
+ "item_code": "_Test Item Home Desktop 100",
+ "item_name": "_Test Item Home Desktop 100",
+ "item_tax_rate": "{\"_Test Account Excise Duty - _TC\": 10}",
+ "parentfield": "entries",
+ "price_list_rate": 62.5,
+ "qty": 10,
"stock_uom": "_Test UOM"
- },
+ },
{
- "cost_center": "_Test Cost Center - _TC",
- "doctype": "Sales Invoice Item",
- "income_account": "Sales - _TC",
- "item_code": "_Test Item Home Desktop 200",
- "item_name": "_Test Item Home Desktop 200",
- "parentfield": "entries",
- "price_list_rate": 190.66,
- "qty": 5,
+ "cost_center": "_Test Cost Center - _TC",
+ "doctype": "Sales Invoice Item",
+ "income_account": "Sales - _TC",
+ "item_code": "_Test Item Home Desktop 200",
+ "item_name": "_Test Item Home Desktop 200",
+ "parentfield": "entries",
+ "price_list_rate": 190.66,
+ "qty": 5,
"stock_uom": "_Test UOM"
}
- ],
- "fiscal_year": "_Test Fiscal Year 2013",
- "grand_total_export": 0,
- "is_pos": 0,
- "naming_series": "_T-Sales Invoice-",
+ ],
+ "fiscal_year": "_Test Fiscal Year 2013",
+ "grand_total_export": 0,
+ "is_pos": 0,
+ "naming_series": "_T-Sales Invoice-",
"other_charges": [
{
- "account_head": "_Test Account Excise Duty - _TC",
- "charge_type": "On Net Total",
- "cost_center": "_Test Cost Center - _TC",
- "description": "Excise Duty",
- "doctype": "Sales Taxes and Charges",
- "idx": 1,
- "included_in_print_rate": 1,
- "parentfield": "other_charges",
+ "account_head": "_Test Account Excise Duty - _TC",
+ "charge_type": "On Net Total",
+ "cost_center": "_Test Cost Center - _TC",
+ "description": "Excise Duty",
+ "doctype": "Sales Taxes and Charges",
+ "idx": 1,
+ "included_in_print_rate": 1,
+ "parentfield": "other_charges",
"rate": 12
- },
+ },
{
- "account_head": "_Test Account Education Cess - _TC",
- "charge_type": "On Previous Row Amount",
- "cost_center": "_Test Cost Center - _TC",
- "description": "Education Cess",
- "doctype": "Sales Taxes and Charges",
- "idx": 2,
- "included_in_print_rate": 1,
- "parentfield": "other_charges",
- "rate": 2,
+ "account_head": "_Test Account Education Cess - _TC",
+ "charge_type": "On Previous Row Amount",
+ "cost_center": "_Test Cost Center - _TC",
+ "description": "Education Cess",
+ "doctype": "Sales Taxes and Charges",
+ "idx": 2,
+ "included_in_print_rate": 1,
+ "parentfield": "other_charges",
+ "rate": 2,
"row_id": 1
- },
+ },
{
- "account_head": "_Test Account S&H Education Cess - _TC",
- "charge_type": "On Previous Row Amount",
- "cost_center": "_Test Cost Center - _TC",
- "description": "S&H Education Cess",
- "doctype": "Sales Taxes and Charges",
- "idx": 3,
- "included_in_print_rate": 1,
- "parentfield": "other_charges",
- "rate": 1,
+ "account_head": "_Test Account S&H Education Cess - _TC",
+ "charge_type": "On Previous Row Amount",
+ "cost_center": "_Test Cost Center - _TC",
+ "description": "S&H Education Cess",
+ "doctype": "Sales Taxes and Charges",
+ "idx": 3,
+ "included_in_print_rate": 1,
+ "parentfield": "other_charges",
+ "rate": 1,
"row_id": 1
- },
+ },
{
- "account_head": "_Test Account CST - _TC",
- "charge_type": "On Previous Row Total",
- "cost_center": "_Test Cost Center - _TC",
- "description": "CST",
- "doctype": "Sales Taxes and Charges",
- "idx": 4,
- "included_in_print_rate": 1,
- "parentfield": "other_charges",
- "rate": 2,
+ "account_head": "_Test Account CST - _TC",
+ "charge_type": "On Previous Row Total",
+ "cost_center": "_Test Cost Center - _TC",
+ "description": "CST",
+ "doctype": "Sales Taxes and Charges",
+ "idx": 4,
+ "included_in_print_rate": 1,
+ "parentfield": "other_charges",
+ "rate": 2,
"row_id": 3
- },
+ },
{
- "account_head": "_Test Account VAT - _TC",
- "charge_type": "On Net Total",
- "cost_center": "_Test Cost Center - _TC",
- "description": "VAT",
- "doctype": "Sales Taxes and Charges",
- "idx": 5,
- "included_in_print_rate": 1,
- "parentfield": "other_charges",
+ "account_head": "_Test Account VAT - _TC",
+ "charge_type": "On Net Total",
+ "cost_center": "_Test Cost Center - _TC",
+ "description": "VAT",
+ "doctype": "Sales Taxes and Charges",
+ "idx": 5,
+ "included_in_print_rate": 1,
+ "parentfield": "other_charges",
"rate": 12.5
- },
+ },
{
- "account_head": "_Test Account Customs Duty - _TC",
- "charge_type": "On Net Total",
- "cost_center": "_Test Cost Center - _TC",
- "description": "Customs Duty",
- "doctype": "Sales Taxes and Charges",
- "idx": 6,
- "parentfield": "other_charges",
+ "account_head": "_Test Account Customs Duty - _TC",
+ "charge_type": "On Net Total",
+ "cost_center": "_Test Cost Center - _TC",
+ "description": "Customs Duty",
+ "doctype": "Sales Taxes and Charges",
+ "idx": 6,
+ "parentfield": "other_charges",
"rate": 10
- },
+ },
{
- "account_head": "_Test Account Shipping Charges - _TC",
- "charge_type": "Actual",
- "cost_center": "_Test Cost Center - _TC",
- "description": "Shipping Charges",
- "doctype": "Sales Taxes and Charges",
- "idx": 7,
- "parentfield": "other_charges",
+ "account_head": "_Test Account Shipping Charges - _TC",
+ "charge_type": "Actual",
+ "cost_center": "_Test Cost Center - _TC",
+ "description": "Shipping Charges",
+ "doctype": "Sales Taxes and Charges",
+ "idx": 7,
+ "parentfield": "other_charges",
"rate": 100
- },
+ },
{
- "account_head": "_Test Account Discount - _TC",
- "charge_type": "On Previous Row Total",
- "cost_center": "_Test Cost Center - _TC",
- "description": "Discount",
- "doctype": "Sales Taxes and Charges",
- "idx": 8,
- "parentfield": "other_charges",
- "rate": -10,
+ "account_head": "_Test Account Discount - _TC",
+ "charge_type": "On Previous Row Total",
+ "cost_center": "_Test Cost Center - _TC",
+ "description": "Discount",
+ "doctype": "Sales Taxes and Charges",
+ "idx": 8,
+ "parentfield": "other_charges",
+ "rate": -10,
"row_id": 7
}
- ],
- "plc_conversion_rate": 1.0,
- "posting_date": "2013-01-23",
- "price_list_currency": "INR",
- "selling_price_list": "_Test Price List",
+ ],
+ "plc_conversion_rate": 1.0,
+ "posting_date": "2013-01-23",
+ "price_list_currency": "INR",
+ "selling_price_list": "_Test Price List",
"territory": "_Test Territory"
}
-]
\ No newline at end of file
+]
diff --git a/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py
index 85e5782..1d22e09 100644
--- a/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py
+++ b/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py
@@ -674,6 +674,7 @@
"notification_email_address": "test@example.com, test1@example.com, test2@example.com",
"repeat_on_day_of_month": getdate(today).day,
"posting_date": today,
+ "due_date": None,
"fiscal_year": get_fiscal_year(today)[0],
"invoice_period_from_date": get_first_day(today),
"invoice_period_to_date": get_last_day(today)
diff --git a/erpnext/accounts/report/bank_reconciliation_statement/bank_reconciliation_statement.html b/erpnext/accounts/report/bank_reconciliation_statement/bank_reconciliation_statement.html
index 91e07ab..1a401f5 100644
--- a/erpnext/accounts/report/bank_reconciliation_statement/bank_reconciliation_statement.html
+++ b/erpnext/accounts/report/bank_reconciliation_statement/bank_reconciliation_statement.html
@@ -1,3 +1,6 @@
+<div style="margin-bottom: 7px;" class="text-center">
+ {%= frappe.boot.letter_heads[frappe.defaults.get_default("letter_head")] %}
+</div>
<h2 class="text-center">{%= __("Bank Reconciliation Statement") %}</h2>
<h4 class="text-center">{%= filters.account %}</h3>
<hr>
diff --git a/erpnext/accounts/report/general_ledger/general_ledger.html b/erpnext/accounts/report/general_ledger/general_ledger.html
index 63cd1a1..190d455 100644
--- a/erpnext/accounts/report/general_ledger/general_ledger.html
+++ b/erpnext/accounts/report/general_ledger/general_ledger.html
@@ -1,5 +1,13 @@
+<div style="margin-bottom: 7px;" class="text-center">
+ {%= frappe.boot.letter_heads[frappe.defaults.get_default("letter_head")] %}
+</div>
<h2 class="text-center">{%= __("Statement of Account") %}</h2>
-<h4 class="text-center">{%= filters.account || "General Ledger" %}</h3>
+<h4 class="text-center">{%= filters.account || "General Ledger" %}</h4>
+<h5 class="text-center">
+ {%= dateutil.str_to_user(filters.from_date) %}
+ {%= __("to") %}
+ {%= dateutil.str_to_user(filters.to_date) %}
+</h5>
<hr>
<table class="table table-bordered">
<thead>
diff --git a/erpnext/patches.txt b/erpnext/patches.txt
index b7fc5e7..1a903de 100644
--- a/erpnext/patches.txt
+++ b/erpnext/patches.txt
@@ -68,3 +68,4 @@
erpnext.patches.v4_1.fix_jv_remarks
erpnext.patches.v4_1.fix_sales_order_delivered_status
erpnext.patches.v4_1.fix_delivery_and_billing_status
+execute:frappe.db.sql("update `tabAccount` set root_type='Liability' where root_type='Income' and report_type='Balance Sheet'")
\ No newline at end of file
diff --git a/erpnext/public/js/transaction.js b/erpnext/public/js/transaction.js
index 1790a47..ae5864d 100644
--- a/erpnext/public/js/transaction.js
+++ b/erpnext/public/js/transaction.js
@@ -20,16 +20,13 @@
currency: currency,
price_list_currency: currency,
status: "Draft",
- fiscal_year: frappe.defaults.get_user_default("fiscal_year"),
is_subcontracted: "No",
}, function(fieldname, value) {
if(me.frm.fields_dict[fieldname] && !me.frm.doc[fieldname])
me.frm.set_value(fieldname, value);
});
- if(!this.frm.doc.company) {
- this.frm.set_value("company", frappe.defaults.get_user_default("company"));
- } else {
+ if(this.frm.doc.company) {
cur_frm.script_manager.trigger("company");
}
}
@@ -332,7 +329,7 @@
method: "erpnext.accounts.doctype.pricing_rule.pricing_rule.apply_pricing_rule",
args: { args: this._get_args(item) },
callback: function(r) {
- if (!r.exc) {
+ if (!r.exc && r.message) {
me._set_values_for_item_list(r.message);
if(calculate_taxes_and_totals) me.calculate_taxes_and_totals();
}
diff --git a/erpnext/setup/doctype/company/company.py b/erpnext/setup/doctype/company/company.py
index d24c7e7..f8e043a 100644
--- a/erpnext/setup/doctype/company/company.py
+++ b/erpnext/setup/doctype/company/company.py
@@ -241,7 +241,7 @@
[_('Sales'),_('Direct Income'),'Ledger','Income Account','Profit and Loss', None, 'Income'],
[_('Service'),_('Direct Income'),'Ledger','Income Account','Profit and Loss', None, 'Income'],
[_('Indirect Income'),_('Income'),'Group','Income Account','Profit and Loss', None, 'Income'],
- [_('Source of Funds (Liabilities)'), None,'Group', None,'Balance Sheet', None, 'Income'],
+ [_('Source of Funds (Liabilities)'), None,'Group', None,'Balance Sheet', None, 'Liability'],
[_('Capital Account'),_('Source of Funds (Liabilities)'),'Group', None,'Balance Sheet', None, 'Liability'],
[_('Reserves and Surplus'),_('Capital Account'),'Ledger', None,'Balance Sheet', None, 'Liability'],
[_('Shareholders Funds'),_('Capital Account'),'Ledger', None,'Balance Sheet', None, 'Liability'],
diff --git a/erpnext/setup/page/setup_wizard/setup_wizard.py b/erpnext/setup/page/setup_wizard/setup_wizard.py
index ca52efb..343cba5 100644
--- a/erpnext/setup/page/setup_wizard/setup_wizard.py
+++ b/erpnext/setup/page/setup_wizard/setup_wizard.py
@@ -113,9 +113,11 @@
last_name=%(last_name)s WHERE name=%(name)s""", args)
if args.get("attach_user"):
- filename, filetype, content = args.get("attach_user").split(",")
- fileurl = save_file(filename, content, "User", args.get("name"), decode=True).file_url
- frappe.db.set_value("User", args.get("name"), "user_image", fileurl)
+ attach_user = args.get("attach_user").split(",")
+ if len(attach_user)==3:
+ filename, filetype, content = attach_user
+ fileurl = save_file(filename, content, "User", args.get("name"), decode=True).file_url
+ frappe.db.set_value("User", args.get("name"), "user_image", fileurl)
add_all_roles_to(args.get("name"))
@@ -319,9 +321,11 @@
}).insert()
if args.get("item_img_" + str(i)):
- filename, filetype, content = args.get("item_img_" + str(i)).split(",")
- fileurl = save_file(filename, content, "Item", item, decode=True).file_url
- frappe.db.set_value("Item", item, "image", fileurl)
+ item_image = args.get("item_img_" + str(i)).split(",")
+ if len(item_image)==3:
+ filename, filetype, content = item_image
+ fileurl = save_file(filename, content, "Item", item, decode=True).file_url
+ frappe.db.set_value("Item", item, "image", fileurl)
def create_customers(args):
for i in xrange(1,6):
@@ -374,17 +378,21 @@
"is_default": 1
}).insert()
- filename, filetype, content = args.get("attach_letterhead").split(",")
- fileurl = save_file(filename, content, "Letter Head", _("Standard"), decode=True).file_url
- frappe.db.set_value("Letter Head", _("Standard"), "content", "<img src='%s' style='max-width: 100%%;'>" % fileurl)
+ attach_letterhead = args.get("attach_letterhead").split(",")
+ if len(attach_letterhead)==3:
+ filename, filetype, content = attach_letterhead
+ fileurl = save_file(filename, content, "Letter Head", _("Standard"), decode=True).file_url
+ frappe.db.set_value("Letter Head", _("Standard"), "content", "<img src='%s' style='max-width: 100%%;'>" % fileurl)
def create_logo(args):
if args.get("attach_logo"):
- filename, filetype, content = args.get("attach_logo").split(",")
- fileurl = save_file(filename, content, "Website Settings", "Website Settings",
- decode=True).file_url
- frappe.db.set_value("Website Settings", "Website Settings", "banner_html",
- "<img src='%s' style='max-width: 100%%;'>" % fileurl)
+ attach_logo = args.get("attach_logo").split(",")
+ if len(attach_logo)==3:
+ filename, filetype, content = attach_logo
+ fileurl = save_file(filename, content, "Website Settings", "Website Settings",
+ decode=True).file_url
+ frappe.db.set_value("Website Settings", "Website Settings", "banner_html",
+ "<img src='%s' style='max-width: 100%%;'>" % fileurl)
def add_all_roles_to(name):
user = frappe.get_doc("User", name)
diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.py b/erpnext/stock/doctype/stock_entry/stock_entry.py
index 586179d..7629c3c 100644
--- a/erpnext/stock/doctype/stock_entry/stock_entry.py
+++ b/erpnext/stock/doctype/stock_entry/stock_entry.py
@@ -204,7 +204,7 @@
if not self.posting_date or not self.posting_time:
frappe.throw(_("Posting date and posting time is mandatory"))
- allow_negative_stock = frappe.db.get_value("Stock Settings", None, "allow_negative_stock")
+ allow_negative_stock = cint(frappe.db.get_default("allow_negative_stock"))
for d in self.get('mtn_details'):
args = frappe._dict({
@@ -219,7 +219,8 @@
# get actual stock at source warehouse
d.actual_qty = get_previous_sle(args).get("qty_after_transaction") or 0
- if d.s_warehouse and not allow_negative_stock and d.actual_qty <= d.transfer_qty:
+ # validate qty during submit
+ if d.docstatus==1 and d.s_warehouse and not allow_negative_stock and d.actual_qty < d.transfer_qty:
frappe.throw(_("""Row {0}: Qty not avalable in warehouse {1} on {2} {3}.
Available Qty: {4}, Transfer Qty: {5}""").format(d.idx, d.s_warehouse,
self.posting_date, self.posting_time, d.actual_qty, d.transfer_qty))
@@ -675,9 +676,9 @@
batch_nos = None
args = {
- 'item_code': filters['item_code'],
- 's_warehouse': filters['s_warehouse'],
- 'posting_date': filters['posting_date'],
+ 'item_code': filters.get("item_code"),
+ 's_warehouse': filters.get('s_warehouse'),
+ 'posting_date': filters.get('posting_date'),
'txt': "%%%s%%" % txt,
'mcond':get_match_cond(doctype),
"start": start,
diff --git a/erpnext/stock/doctype/stock_entry/test_stock_entry.py b/erpnext/stock/doctype/stock_entry/test_stock_entry.py
index 260223d..0f6a33f 100644
--- a/erpnext/stock/doctype/stock_entry/test_stock_entry.py
+++ b/erpnext/stock/doctype/stock_entry/test_stock_entry.py
@@ -21,7 +21,7 @@
frappe.db.sql("""delete from `tabMaterial Request`""")
self._clear_stock_account_balance()
- frappe.db.set_value("Stock Settings", None, "auto_indent", True)
+ frappe.db.set_value("Stock Settings", None, "auto_indent", 1)
st1 = frappe.copy_doc(test_records[0])
st1.insert()
@@ -664,15 +664,17 @@
def test_serial_no_not_exists(self):
self._clear_stock_account_balance()
frappe.db.sql("delete from `tabSerial No` where name in ('ABCD', 'EFGH')")
+ make_serialized_item(target_warehouse="_Test Warehouse 1 - _TC")
se = frappe.copy_doc(test_records[0])
se.purpose = "Material Issue"
- se.get("mtn_details")[0].item_code = "_Test Serialized Item"
+ se.get("mtn_details")[0].item_code = "_Test Serialized Item With Series"
se.get("mtn_details")[0].qty = 2
se.get("mtn_details")[0].s_warehouse = "_Test Warehouse 1 - _TC"
se.get("mtn_details")[0].t_warehouse = None
se.get("mtn_details")[0].serial_no = "ABCD\nEFGH"
se.get("mtn_details")[0].transfer_qty = 2
se.insert()
+
self.assertRaises(SerialNoNotExistsError, se.submit)
def test_serial_duplicate(self):
@@ -699,8 +701,8 @@
return se, serial_nos
def test_serial_item_error(self):
- self._clear_stock_account_balance()
se, serial_nos = self.test_serial_by_series()
+ make_serialized_item("_Test Serialized Item", "ABCD\nEFGH")
se = frappe.copy_doc(test_records[0])
se.purpose = "Material Transfer"
@@ -735,6 +737,8 @@
def test_serial_warehouse_error(self):
self._clear_stock_account_balance()
+ make_serialized_item(target_warehouse="_Test Warehouse 1 - _TC")
+
t = make_serialized_item()
serial_nos = get_serial_nos(t.get("mtn_details")[0].serial_no)
@@ -818,11 +822,16 @@
self.assertRaises (StockFreezeError, se.submit)
frappe.db.set_value("Stock Settings", None, "stock_frozen_upto_days", 0)
-def make_serialized_item():
+def make_serialized_item(item_code=None, serial_no=None, target_warehouse=None):
se = frappe.copy_doc(test_records[0])
- se.get("mtn_details")[0].item_code = "_Test Serialized Item With Series"
+ se.get("mtn_details")[0].item_code = item_code or "_Test Serialized Item With Series"
+ se.get("mtn_details")[0].serial_no = serial_no
se.get("mtn_details")[0].qty = 2
se.get("mtn_details")[0].transfer_qty = 2
+
+ if target_warehouse:
+ se.get("mtn_details")[0].t_warehouse = target_warehouse
+
se.insert()
se.submit()
return se
diff --git a/erpnext/stock/utils.py b/erpnext/stock/utils.py
index 340e551..10f5cc2 100644
--- a/erpnext/stock/utils.py
+++ b/erpnext/stock/utils.py
@@ -176,7 +176,6 @@
def reorder_item():
""" Reorder item if stock reaches reorder level"""
-
# if initial setup not completed, return
if not frappe.db.sql("select name from `tabFiscal Year` limit 1"):
return
@@ -185,46 +184,69 @@
frappe.local.auto_indent = cint(frappe.db.get_value('Stock Settings', None, 'auto_indent'))
if frappe.local.auto_indent:
- material_requests = {}
- bin_list = frappe.db.sql("""select item_code, warehouse, projected_qty
- from tabBin where ifnull(item_code, '') != '' and ifnull(warehouse, '') != ''
- and exists (select name from `tabItem`
- where `tabItem`.name = `tabBin`.item_code and
- is_stock_item='Yes' and (is_purchase_item='Yes' or is_sub_contracted_item='Yes') and
- (ifnull(end_of_life, '0000-00-00')='0000-00-00' or end_of_life > curdate()))""",
- as_dict=True)
+ _reorder_item()
- for bin in bin_list:
- #check if re-order is required
- item_reorder = frappe.db.get("Item Reorder",
- {"parent": bin.item_code, "warehouse": bin.warehouse})
- if item_reorder:
- reorder_level = item_reorder.warehouse_reorder_level
- reorder_qty = item_reorder.warehouse_reorder_qty
- material_request_type = item_reorder.material_request_type or "Purchase"
- else:
- reorder_level, reorder_qty = frappe.db.get_value("Item", bin.item_code,
- ["re_order_level", "re_order_qty"])
- material_request_type = "Purchase"
+def _reorder_item():
+ # {"Purchase": {"Company": [{"item_code": "", "warehouse": "", "reorder_qty": 0.0}]}, "Transfer": {...}}
+ material_requests = {"Purchase": {}, "Transfer": {}}
- if flt(reorder_level) and flt(bin.projected_qty) < flt(reorder_level):
- if flt(reorder_level) - flt(bin.projected_qty) > flt(reorder_qty):
- reorder_qty = flt(reorder_level) - flt(bin.projected_qty)
+ item_warehouse_projected_qty = get_item_warehouse_projected_qty()
+ warehouse_company = frappe._dict(frappe.db.sql("""select name, company from `tabWarehouse`"""))
+ default_company = (frappe.defaults.get_defaults()["company"] or
+ frappe.db.sql("""select name from tabCompany limit 1""")[0][0])
- company = frappe.db.get_value("Warehouse", bin.warehouse, "company") or \
- frappe.defaults.get_defaults()["company"] or \
- frappe.db.sql("""select name from tabCompany limit 1""")[0][0]
+ def add_to_material_request(item_code, warehouse, reorder_level, reorder_qty, material_request_type):
+ if warehouse not in item_warehouse_projected_qty[item_code]:
+ # likely a disabled warehouse or a warehouse where BIN does not exist
+ return
- material_requests.setdefault(material_request_type, frappe._dict()).setdefault(
- company, []).append(frappe._dict({
- "item_code": bin.item_code,
- "warehouse": bin.warehouse,
- "reorder_qty": reorder_qty
- })
- )
+ reorder_level = flt(reorder_level)
+ reorder_qty = flt(reorder_qty)
+ projected_qty = item_warehouse_projected_qty[item_code][warehouse]
- if material_requests:
- create_material_request(material_requests)
+ if reorder_level and projected_qty < reorder_level:
+ deficiency = reorder_level - projected_qty
+ if deficiency > reorder_qty:
+ reorder_qty = deficiency
+
+ company = warehouse_company.get(warehouse) or default_company
+
+ material_requests[material_request_type].setdefault(company, []).append({
+ "item_code": item_code,
+ "warehouse": warehouse,
+ "reorder_qty": reorder_qty
+ })
+
+ for item_code in item_warehouse_projected_qty:
+ item = frappe.get_doc("Item", item_code)
+ if item.get("item_reorder"):
+ for d in item.get("item_reorder"):
+ add_to_material_request(item_code, d.warehouse, d.warehouse_reorder_level,
+ d.warehouse_reorder_qty, d.material_request_type)
+
+ else:
+ # raise for default warehouse
+ add_to_material_request(item_code, item.default_warehouse, item.re_order_level, item.re_order_qty, "Purchase")
+
+ if material_requests:
+ create_material_request(material_requests)
+
+def get_item_warehouse_projected_qty():
+ item_warehouse_projected_qty = {}
+
+ for item_code, warehouse, projected_qty in frappe.db.sql("""select item_code, warehouse, projected_qty
+ from tabBin where ifnull(item_code, '') != '' and ifnull(warehouse, '') != ''
+ and exists (select name from `tabItem`
+ where `tabItem`.name = `tabBin`.item_code and
+ is_stock_item='Yes' and (is_purchase_item='Yes' or is_sub_contracted_item='Yes') and
+ (ifnull(end_of_life, '0000-00-00')='0000-00-00' or end_of_life > %s))
+ and exists (select name from `tabWarehouse`
+ where `tabWarehouse`.name = `tabBin`.warehouse
+ and ifnull(disabled, 0)=0)""", nowdate()):
+
+ item_warehouse_projected_qty.setdefault(item_code, {})[warehouse] = flt(projected_qty)
+
+ return item_warehouse_projected_qty
def create_material_request(material_requests):
""" Create indent on reaching reorder level """
@@ -263,6 +285,7 @@
})
for d in items:
+ d = frappe._dict(d)
item = frappe.get_doc("Item", d.item_code)
mr.append("indent_details", {
"doctype": "Material Request Item",
diff --git a/erpnext/support/doctype/support_ticket/support_ticket.py b/erpnext/support/doctype/support_ticket/support_ticket.py
index 9517ea4..4cdc20a 100644
--- a/erpnext/support/doctype/support_ticket/support_ticket.py
+++ b/erpnext/support/doctype/support_ticket/support_ticket.py
@@ -8,31 +8,31 @@
from frappe.utils import now, extract_email_id
class SupportTicket(TransactionBase):
-
+
def get_sender(self, comm):
return frappe.db.get_value('Support Email Settings',None,'support_email')
def get_subject(self, comm):
return '[' + self.name + '] ' + (comm.subject or 'No Subject Specified')
-
+
def get_content(self, comm):
signature = frappe.db.get_value('Support Email Settings',None,'support_signature')
content = comm.content
if signature:
content += '<p>' + signature + '</p>'
return content
-
+
def get_portal_page(self):
return "ticket"
-
+
def validate(self):
self.update_status()
self.set_lead_contact(self.raised_by)
-
+
if self.status == "Closed":
from frappe.widgets.form.assign_to import clear
clear(self.doctype, self.name)
-
+
def set_lead_contact(self, email_id):
import email.utils
email_id = email.utils.parseaddr(email_id)
@@ -41,8 +41,8 @@
self.lead = frappe.db.get_value("Lead", {"email_id": email_id})
if not self.contact:
self.contact = frappe.db.get_value("Contact", {"email_id": email_id})
-
- if not self.company:
+
+ if not self.company:
self.company = frappe.db.get_value("Lead", self.lead, "company") or \
frappe.db.get_default("company")
@@ -53,15 +53,16 @@
if self.status=="Closed" and status !="Closed":
self.resolution_date = now()
if self.status=="Open" and status !="Open":
- self.resolution_date = ""
+ # if no date, it should be set as None and not a blank string "", as per mysql strict config
+ self.resolution_date = None
@frappe.whitelist()
def set_status(name, status):
st = frappe.get_doc("Support Ticket", name)
st.status = status
st.save()
-
+
def auto_close_tickets():
- frappe.db.sql("""update `tabSupport Ticket` set status = 'Closed'
- where status = 'Replied'
+ frappe.db.sql("""update `tabSupport Ticket` set status = 'Closed'
+ where status = 'Replied'
and date_sub(curdate(),interval 15 Day) > modified""")