diff --git a/.travis.yml b/.travis.yml
index 869fe959c00..a8a0d826145 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -3,6 +3,11 @@ dist: trusty
python:
- "2.7"
+ - "3.6"
+
+env:
+ - TEST_TYPE="Server Side Test"
+ - TEST_TYPE="Patch Test"
services:
- mysql
@@ -39,18 +44,8 @@ before_script:
- bench start &
- sleep 10
-jobs:
- include:
- - stage: test
- script:
- - set -e
- - bench run-tests --app erpnext --coverage
- after_script:
- - coveralls -b apps/erpnext -d ../../sites/.coverage
- env: Server Side Test
- - # stage
- script:
- - wget http://build.erpnext.com/20171108_190013_955977f8_database.sql.gz
- - bench --force restore ~/frappe-bench/20171108_190013_955977f8_database.sql.gz --mariadb-root-password travis
- - bench migrate
- env: Patch Testing
+script:
+ - bash $TRAVIS_BUILD_DIR/travis/run-tests.sh
+
+after_script:
+ - coveralls -b apps/erpnext -d ../../sites/.coverage
diff --git a/erpnext/__init__.py b/erpnext/__init__.py
index a06efa0ff75..8c18da086ec 100644
--- a/erpnext/__init__.py
+++ b/erpnext/__init__.py
@@ -5,7 +5,7 @@ import frappe
from erpnext.hooks import regional_overrides
from frappe.utils import getdate
-__version__ = '11.1.39'
+__version__ = '11.1.40'
def get_default_company(user=None):
'''Get default company for user'''
diff --git a/erpnext/accounts/doctype/pricing_rule/pricing_rule.py b/erpnext/accounts/doctype/pricing_rule/pricing_rule.py
index 7f0f60ff02e..186f3fd1e60 100644
--- a/erpnext/accounts/doctype/pricing_rule/pricing_rule.py
+++ b/erpnext/accounts/doctype/pricing_rule/pricing_rule.py
@@ -350,7 +350,7 @@ def filter_pricing_rules(args, pricing_rules):
if len(pricing_rules) > 1:
rate_or_discount = list(set([d.rate_or_discount for d in pricing_rules]))
if len(rate_or_discount) == 1 and rate_or_discount[0] == "Discount Percentage":
- pricing_rules = filter(lambda x: x.for_price_list==args.price_list, pricing_rules) \
+ pricing_rules = list(filter(lambda x: x.for_price_list==args.price_list, pricing_rules)) \
or pricing_rules
if len(pricing_rules) > 1 and not args.for_shopping_cart:
@@ -373,7 +373,7 @@ def apply_internal_priority(pricing_rules, field_set, args):
filtered_rules = []
for field in field_set:
if args.get(field):
- filtered_rules = filter(lambda x: x[field]==args[field], pricing_rules)
+ filtered_rules = list(filter(lambda x: x[field]==args[field], pricing_rules))
if filtered_rules: break
return filtered_rules or pricing_rules
diff --git a/erpnext/accounts/doctype/pricing_rule/test_pricing_rule.py b/erpnext/accounts/doctype/pricing_rule/test_pricing_rule.py
index e4f37c44ffc..9b1ee496753 100644
--- a/erpnext/accounts/doctype/pricing_rule/test_pricing_rule.py
+++ b/erpnext/accounts/doctype/pricing_rule/test_pricing_rule.py
@@ -18,9 +18,6 @@ class TestPricingRule(unittest.TestCase):
frappe.db.sql("delete from `tabPricing Rule`")
def test_pricing_rule_for_discount(self):
- from erpnext.stock.get_item_details import get_item_details
- from frappe import MandatoryError
-
test_record = {
"doctype": "Pricing Rule",
"title": "_Test Pricing Rule",
@@ -94,9 +91,6 @@ class TestPricingRule(unittest.TestCase):
self.assertEquals(details.get("discount_percentage"), 15)
def test_pricing_rule_for_margin(self):
- from erpnext.stock.get_item_details import get_item_details
- from frappe import MandatoryError
-
test_record = {
"doctype": "Pricing Rule",
"title": "_Test Pricing Rule",
@@ -139,9 +133,6 @@ class TestPricingRule(unittest.TestCase):
self.assertEquals(details.get("margin_rate_or_amount"), 10)
def test_pricing_rule_for_variants(self):
- from erpnext.stock.get_item_details import get_item_details
- from frappe import MandatoryError
-
if not frappe.db.exists("Item", "Test Variant PRT"):
frappe.get_doc({
"doctype": "Item",
diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
index ca94b52c532..e06db8f4bc6 100644
--- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
+++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
@@ -487,7 +487,7 @@ class SalesInvoice(SellingController):
"""Set against account for debit to account"""
against_acc = []
for d in self.get('items'):
- if d.income_account not in against_acc:
+ if d.income_account and d.income_account not in against_acc:
against_acc.append(d.income_account)
self.against_income_account = ','.join(against_acc)
diff --git a/erpnext/accounts/doctype/tax_withholding_category/test_tax_withholding_category.py b/erpnext/accounts/doctype/tax_withholding_category/test_tax_withholding_category.py
index 25301967080..638e57ed2b9 100644
--- a/erpnext/accounts/doctype/tax_withholding_category/test_tax_withholding_category.py
+++ b/erpnext/accounts/doctype/tax_withholding_category/test_tax_withholding_category.py
@@ -22,7 +22,7 @@ class TestTaxWithholdingCategory(unittest.TestCase):
invoices = []
# create invoices for lower than single threshold tax rate
- for _ in xrange(2):
+ for _ in range(2):
pi = create_purchase_invoice(supplier = "Test TDS Supplier")
pi.submit()
invoices.append(pi)
diff --git a/erpnext/accounts/report/balance_sheet/balance_sheet.js b/erpnext/accounts/report/balance_sheet/balance_sheet.js
index f22f3a10091..4bc29da2c7d 100644
--- a/erpnext/accounts/report/balance_sheet/balance_sheet.js
+++ b/erpnext/accounts/report/balance_sheet/balance_sheet.js
@@ -10,4 +10,10 @@ frappe.require("assets/erpnext/js/financial_statements.js", function() {
"fieldtype": "Check",
"default": 1
});
+
+ frappe.query_reports["Balance Sheet"]["filters"].push({
+ "fieldname": "include_default_book_entries",
+ "label": __("Include Default Book Entries"),
+ "fieldtype": "Check"
+ });
});
diff --git a/erpnext/accounts/report/cash_flow/cash_flow.js b/erpnext/accounts/report/cash_flow/cash_flow.js
index 391f57beac6..04221110930 100644
--- a/erpnext/accounts/report/cash_flow/cash_flow.js
+++ b/erpnext/accounts/report/cash_flow/cash_flow.js
@@ -15,4 +15,10 @@ frappe.require("assets/erpnext/js/financial_statements.js", function() {
"label": __("Accumulated Values"),
"fieldtype": "Check"
});
+
+ frappe.query_reports["Cash Flow"]["filters"].push({
+ "fieldname": "include_default_book_entries",
+ "label": __("Include Default Book Entries"),
+ "fieldtype": "Check"
+ });
});
\ No newline at end of file
diff --git a/erpnext/accounts/report/cash_flow/cash_flow.py b/erpnext/accounts/report/cash_flow/cash_flow.py
index f048c1acda5..0f9813947a7 100644
--- a/erpnext/accounts/report/cash_flow/cash_flow.py
+++ b/erpnext/accounts/report/cash_flow/cash_flow.py
@@ -14,8 +14,8 @@ def execute(filters=None):
if cint(frappe.db.get_single_value('Accounts Settings', 'use_custom_cash_flow')):
from erpnext.accounts.report.cash_flow.custom_cash_flow import execute as execute_custom
return execute_custom(filters=filters)
-
- period_list = get_period_list(filters.from_fiscal_year, filters.to_fiscal_year,
+
+ period_list = get_period_list(filters.from_fiscal_year, filters.to_fiscal_year,
filters.periodicity, filters.accumulated_values, filters.company)
cash_flow_accounts = get_cash_flow_accounts()
@@ -25,18 +25,18 @@ def execute(filters=None):
accumulated_values=filters.accumulated_values, ignore_closing_entries=True, ignore_accumulated_values_for_fy= True)
expense = get_data(filters.company, "Expense", "Debit", period_list, filters=filters,
accumulated_values=filters.accumulated_values, ignore_closing_entries=True, ignore_accumulated_values_for_fy= True)
-
+
net_profit_loss = get_net_profit_loss(income, expense, period_list, filters.company)
data = []
company_currency = frappe.get_cached_value('Company', filters.company, "default_currency")
-
+
for cash_flow_account in cash_flow_accounts:
section_data = []
data.append({
- "account_name": cash_flow_account['section_header'],
+ "account_name": cash_flow_account['section_header'],
"parent_account": None,
- "indent": 0.0,
+ "indent": 0.0,
"account": cash_flow_account['section_header']
})
@@ -44,18 +44,18 @@ def execute(filters=None):
# add first net income in operations section
if net_profit_loss:
net_profit_loss.update({
- "indent": 1,
+ "indent": 1,
"parent_account": cash_flow_accounts[0]['section_header']
})
data.append(net_profit_loss)
section_data.append(net_profit_loss)
for account in cash_flow_account['account_types']:
- account_data = get_account_type_based_data(filters.company,
- account['account_type'], period_list, filters.accumulated_values)
+ account_data = get_account_type_based_data(filters.company,
+ account['account_type'], period_list, filters.accumulated_values, filters)
account_data.update({
"account_name": account['label'],
- "account": account['label'],
+ "account": account['label'],
"indent": 1,
"parent_account": cash_flow_account['section_header'],
"currency": company_currency
@@ -63,7 +63,7 @@ def execute(filters=None):
data.append(account_data)
section_data.append(account_data)
- add_total_row_account(data, section_data, cash_flow_account['section_footer'],
+ add_total_row_account(data, section_data, cash_flow_account['section_footer'],
period_list, company_currency)
add_total_row_account(data, data, _("Net Change in Cash"), period_list, company_currency)
@@ -105,13 +105,15 @@ def get_cash_flow_accounts():
# combine all cash flow accounts for iteration
return [operation_accounts, investing_accounts, financing_accounts]
-def get_account_type_based_data(company, account_type, period_list, accumulated_values):
+def get_account_type_based_data(company, account_type, period_list, accumulated_values, filters):
data = {}
total = 0
for period in period_list:
start_date = get_start_date(period, accumulated_values, company)
- amount = get_account_type_based_gl_data(company, start_date, period['to_date'], account_type)
+ amount = get_account_type_based_gl_data(company, start_date,
+ period['to_date'], account_type, filters)
+
if amount and account_type == "Depreciation":
amount *= -1
@@ -121,14 +123,24 @@ def get_account_type_based_data(company, account_type, period_list, accumulated_
data["total"] = total
return data
-def get_account_type_based_gl_data(company, start_date, end_date, account_type):
+def get_account_type_based_gl_data(company, start_date, end_date, account_type, filters):
+ cond = ""
+
+ if filters.finance_book:
+ cond = " and finance_book = '%s'" %(frappe.db.escape(filters.finance_book))
+ if filters.include_default_book_entries:
+ company_fb = frappe.db.get_value("Company", company, 'default_finance_book')
+
+ cond = """ and finance_book in ('%s', '%s')
+ """ %(frappe.db.escape(filters.finance_book), frappe.db.escape(company_fb))
+
gl_sum = frappe.db.sql_list("""
select sum(credit) - sum(debit)
from `tabGL Entry`
where company=%s and posting_date >= %s and posting_date <= %s
and voucher_type != 'Period Closing Voucher'
- and account in ( SELECT name FROM tabAccount WHERE account_type = %s)
- """, (company, start_date, end_date, account_type))
+ and account in ( SELECT name FROM tabAccount WHERE account_type = %s) {cond}
+ """.format(cond=cond), (company, start_date, end_date, account_type))
return gl_sum[0] if gl_sum and gl_sum[0] else 0
@@ -154,7 +166,7 @@ def add_total_row_account(out, data, label, period_list, currency, consolidated
key = period if consolidated else period['key']
total_row.setdefault(key, 0.0)
total_row[key] += row.get(key, 0.0)
-
+
total_row.setdefault("total", 0.0)
total_row["total"] += row["total"]
diff --git a/erpnext/accounts/report/consolidated_financial_statement/consolidated_financial_statement.js b/erpnext/accounts/report/consolidated_financial_statement/consolidated_financial_statement.js
index 7b373f0d9ae..e69a993e8ce 100644
--- a/erpnext/accounts/report/consolidated_financial_statement/consolidated_financial_statement.js
+++ b/erpnext/accounts/report/consolidated_financial_statement/consolidated_financial_statement.js
@@ -55,5 +55,10 @@ frappe.query_reports["Consolidated Financial Statement"] = {
"fieldtype": "Check",
"default": 0
},
+ {
+ "fieldname": "include_default_book_entries",
+ "label": __("Include Default Book Entries"),
+ "fieldtype": "Check"
+ }
]
}
diff --git a/erpnext/accounts/report/consolidated_financial_statement/consolidated_financial_statement.py b/erpnext/accounts/report/consolidated_financial_statement/consolidated_financial_statement.py
index 1bb8580f644..ed000bbac4c 100644
--- a/erpnext/accounts/report/consolidated_financial_statement/consolidated_financial_statement.py
+++ b/erpnext/accounts/report/consolidated_financial_statement/consolidated_financial_statement.py
@@ -355,7 +355,8 @@ def set_gl_entries_by_account(from_date, to_date, root_lft, root_rgt, filters, g
"lft": root_lft,
"rgt": root_rgt,
"company": d.name,
- "finance_book": filters.get("finance_book")
+ "finance_book": filters.get("finance_book"),
+ "company_fb": frappe.db.get_value("Company", d.name, 'default_finance_book')
},
as_dict=True)
@@ -386,7 +387,10 @@ def get_additional_conditions(from_date, ignore_closing_entries, filters):
additional_conditions.append("gl.posting_date >= %(from_date)s")
if filters.get("finance_book"):
- additional_conditions.append("ifnull(finance_book, '') in (%(finance_book)s, '')")
+ if filters.get("include_default_book_entries"):
+ additional_conditions.append("finance_book in (%(finance_book)s, %(company_fb)s)")
+ else:
+ additional_conditions.append("finance_book in (%(finance_book)s)")
return " and {}".format(" and ".join(additional_conditions)) if additional_conditions else ""
diff --git a/erpnext/accounts/report/financial_statements.py b/erpnext/accounts/report/financial_statements.py
index fe030c5f1ce..9765310fc9b 100644
--- a/erpnext/accounts/report/financial_statements.py
+++ b/erpnext/accounts/report/financial_statements.py
@@ -359,7 +359,8 @@ def set_gl_entries_by_account(
"to_date": to_date,
"cost_center": filters.cost_center,
"project": filters.project,
- "finance_book": filters.get("finance_book")
+ "finance_book": filters.get("finance_book"),
+ "company_fb": frappe.db.get_value("Company", company, 'default_finance_book')
},
as_dict=True)
@@ -393,7 +394,10 @@ def get_additional_conditions(from_date, ignore_closing_entries, filters):
additional_conditions.append("cost_center in %(cost_center)s")
if filters.get("finance_book"):
- additional_conditions.append("ifnull(finance_book, '') in (%(finance_book)s, '')")
+ if filters.get("include_default_book_entries"):
+ additional_conditions.append("finance_book in (%(finance_book)s, %(company_fb)s)")
+ else:
+ additional_conditions.append("finance_book in (%(finance_book)s)")
return " and {}".format(" and ".join(additional_conditions)) if additional_conditions else ""
diff --git a/erpnext/accounts/report/general_ledger/general_ledger.js b/erpnext/accounts/report/general_ledger/general_ledger.js
index e74c16af6fe..e162606b7ac 100644
--- a/erpnext/accounts/report/general_ledger/general_ledger.js
+++ b/erpnext/accounts/report/general_ledger/general_ledger.js
@@ -216,6 +216,11 @@ frappe.query_reports["General Ledger"] = {
"fieldname": "show_opening_entries",
"label": __("Show Opening Entries"),
"fieldtype": "Check"
+ },
+ {
+ "fieldname": "include_default_book_entries",
+ "label": __("Include Default Book Entries"),
+ "fieldtype": "Check"
}
]
}
diff --git a/erpnext/accounts/report/general_ledger/general_ledger.py b/erpnext/accounts/report/general_ledger/general_ledger.py
index ccb427665b2..ae63ab60329 100644
--- a/erpnext/accounts/report/general_ledger/general_ledger.py
+++ b/erpnext/accounts/report/general_ledger/general_ledger.py
@@ -133,6 +133,10 @@ def get_gl_entries(filters):
sum(debit_in_account_currency) as debit_in_account_currency,
sum(credit_in_account_currency) as credit_in_account_currency"""
+ if filters.get("include_default_book_entries"):
+ filters['company_fb'] = frappe.db.get_value("Company",
+ filters.get("company"), 'default_finance_book')
+
gl_entries = frappe.db.sql(
"""
select
@@ -188,7 +192,10 @@ def get_conditions(filters):
conditions.append("project in %(project)s")
if filters.get("finance_book"):
- conditions.append("ifnull(finance_book, '') in (%(finance_book)s, '')")
+ if filters.get("include_default_book_entries"):
+ conditions.append("finance_book in (%(finance_book)s, %(company_fb)s)")
+ else:
+ conditions.append("finance_book in (%(finance_book)s)")
from frappe.desk.reportview import build_match_conditions
match_conditions = build_match_conditions("GL Entry")
diff --git a/erpnext/accounts/report/non_billed_report.py b/erpnext/accounts/report/non_billed_report.py
index 41ec9b74665..9f19c0d7591 100644
--- a/erpnext/accounts/report/non_billed_report.py
+++ b/erpnext/accounts/report/non_billed_report.py
@@ -12,20 +12,21 @@ def get_ordered_to_be_billed_data(args):
child_tab = doctype + " Item"
precision = get_field_precision(frappe.get_meta(child_tab).get_field("billed_amt"),
currency=get_default_currency()) or 2
-
+
project_field = get_project_field(doctype, party)
return frappe.db.sql("""
Select
`{parent_tab}`.name, `{parent_tab}`.{date_field}, `{parent_tab}`.{party}, `{parent_tab}`.{party}_name,
{project_field}, `{child_tab}`.item_code, `{child_tab}`.base_amount,
- (`{child_tab}`.billed_amt * ifnull(`{parent_tab}`.conversion_rate, 1)),
+ (`{child_tab}`.billed_amt * ifnull(`{parent_tab}`.conversion_rate, 1)),
(`{child_tab}`.base_amount - (`{child_tab}`.billed_amt * ifnull(`{parent_tab}`.conversion_rate, 1))),
`{child_tab}`.item_name, `{child_tab}`.description, `{parent_tab}`.company
from
`{parent_tab}`, `{child_tab}`
where
- `{parent_tab}`.name = `{child_tab}`.parent and `{parent_tab}`.docstatus = 1 and `{parent_tab}`.status != 'Closed'
+ `{parent_tab}`.name = `{child_tab}`.parent and `{parent_tab}`.docstatus = 1
+ and `{parent_tab}`.status not in ('Closed', 'Completed')
and `{child_tab}`.amount > 0 and round(`{child_tab}`.billed_amt *
ifnull(`{parent_tab}`.conversion_rate, 1), {precision}) < `{child_tab}`.base_amount
order by
diff --git a/erpnext/accounts/report/profit_and_loss_statement/profit_and_loss_statement.js b/erpnext/accounts/report/profit_and_loss_statement/profit_and_loss_statement.js
index 250e516d7d2..7741a45feeb 100644
--- a/erpnext/accounts/report/profit_and_loss_statement/profit_and_loss_statement.js
+++ b/erpnext/accounts/report/profit_and_loss_statement/profit_and_loss_statement.js
@@ -41,6 +41,11 @@ frappe.require("assets/erpnext/js/financial_statements.js", function() {
"fieldname": "accumulated_values",
"label": __("Accumulated Values"),
"fieldtype": "Check"
+ },
+ {
+ "fieldname": "include_default_book_entries",
+ "label": __("Include Default Book Entries"),
+ "fieldtype": "Check"
}
);
});
diff --git a/erpnext/accounts/report/sales_payment_summary/test_sales_payment_summary.py b/erpnext/accounts/report/sales_payment_summary/test_sales_payment_summary.py
index 62843e74efc..a51c4276301 100644
--- a/erpnext/accounts/report/sales_payment_summary/test_sales_payment_summary.py
+++ b/erpnext/accounts/report/sales_payment_summary/test_sales_payment_summary.py
@@ -47,8 +47,8 @@ class TestSalesPaymentSummary(unittest.TestCase):
pe.submit()
mop = get_mode_of_payments(filters)
- self.assertTrue('Credit Card' in mop.values()[0])
- self.assertTrue('Cash' in mop.values()[0])
+ self.assertTrue('Credit Card' in list(mop.values())[0])
+ self.assertTrue('Cash' in list(mop.values())[0])
# Cancel all Cash payment entry and check if this mode of payment is still fetched.
payment_entries = frappe.get_all("Payment Entry", filters={"mode_of_payment": "Cash", "docstatus": 1}, fields=["name", "docstatus"])
@@ -57,8 +57,8 @@ class TestSalesPaymentSummary(unittest.TestCase):
pe.cancel()
mop = get_mode_of_payments(filters)
- self.assertTrue('Credit Card' in mop.values()[0])
- self.assertTrue('Cash' not in mop.values()[0])
+ self.assertTrue('Credit Card' in list(mop.values())[0])
+ self.assertTrue('Cash' not in list(mop.values())[0])
def test_get_mode_of_payments_details(self):
filters = get_filters()
@@ -84,7 +84,7 @@ class TestSalesPaymentSummary(unittest.TestCase):
mopd = get_mode_of_payment_details(filters)
- mopd_values = mopd.values()[0]
+ mopd_values = list(mopd.values())[0]
for mopd_value in mopd_values:
if mopd_value[0] == "Credit Card":
cc_init_amount = mopd_value[1]
@@ -96,7 +96,7 @@ class TestSalesPaymentSummary(unittest.TestCase):
pe.cancel()
mopd = get_mode_of_payment_details(filters)
- mopd_values = mopd.values()[0]
+ mopd_values = list(mopd.values())[0]
for mopd_value in mopd_values:
if mopd_value[0] == "Credit Card":
cc_final_amount = mopd_value[1]
diff --git a/erpnext/accounts/report/trial_balance/trial_balance.py b/erpnext/accounts/report/trial_balance/trial_balance.py
index b5f0186d4d2..5758b0bc6b1 100644
--- a/erpnext/accounts/report/trial_balance/trial_balance.py
+++ b/erpnext/accounts/report/trial_balance/trial_balance.py
@@ -105,7 +105,7 @@ def get_rootwise_opening_balances(filters, report_type):
if filters.finance_book:
fb_conditions = " and finance_book = %(finance_book)s"
if filters.include_default_book_entries:
- fb_conditions = " and (finance_book in (%(finance_book)s, %(company_fb)s) or finance_book is null)"
+ fb_conditions = " and (finance_book in (%(finance_book)s, %(company_fb)s))"
additional_conditions += fb_conditions
diff --git a/erpnext/agriculture/doctype/disease/disease.py b/erpnext/agriculture/doctype/disease/disease.py
index c7707a54652..8a0e6f33d68 100644
--- a/erpnext/agriculture/doctype/disease/disease.py
+++ b/erpnext/agriculture/doctype/disease/disease.py
@@ -6,7 +6,6 @@ from __future__ import unicode_literals
import frappe
from frappe import _
from frappe.model.document import Document
-from frappe import _
class Disease(Document):
def validate(self):
diff --git a/erpnext/agriculture/doctype/soil_texture/soil_texture.py b/erpnext/agriculture/doctype/soil_texture/soil_texture.py
index 8c1d7ed5ac1..2254bf87914 100644
--- a/erpnext/agriculture/doctype/soil_texture/soil_texture.py
+++ b/erpnext/agriculture/doctype/soil_texture/soil_texture.py
@@ -7,7 +7,6 @@ import frappe
from frappe import _
from frappe.model.document import Document
from frappe.utils import flt, cint
-from frappe import _
class SoilTexture(Document):
soil_edit_order = [2, 1, 0]
@@ -35,8 +34,8 @@ class SoilTexture(Document):
if sum(self.soil_edit_order) < 5: return
last_edit_index = self.soil_edit_order.index(min(self.soil_edit_order))
- # set composition of the last edited soil
- self.set( self.soil_types[last_edit_index],
+ # set composition of the last edited soil
+ self.set( self.soil_types[last_edit_index],
100 - sum(cint(self.get(soil_type)) for soil_type in self.soil_types) + cint(self.get(self.soil_types[last_edit_index])))
# calculate soil type
diff --git a/erpnext/agriculture/doctype/water_analysis/water_analysis.py b/erpnext/agriculture/doctype/water_analysis/water_analysis.py
index 88f1fbd9cce..bd2cd118e1d 100644
--- a/erpnext/agriculture/doctype/water_analysis/water_analysis.py
+++ b/erpnext/agriculture/doctype/water_analysis/water_analysis.py
@@ -6,7 +6,6 @@ from __future__ import unicode_literals
import frappe
from frappe import _
from frappe.model.document import Document
-from frappe import _
class WaterAnalysis(Document):
def load_contents(self):
diff --git a/erpnext/assets/doctype/asset_value_adjustment/asset_value_adjustment.py b/erpnext/assets/doctype/asset_value_adjustment/asset_value_adjustment.py
index ac3c3507027..56425a0dcb4 100644
--- a/erpnext/assets/doctype/asset_value_adjustment/asset_value_adjustment.py
+++ b/erpnext/assets/doctype/asset_value_adjustment/asset_value_adjustment.py
@@ -36,7 +36,7 @@ class AssetValueAdjustment(Document):
fixed_asset_account, accumulated_depreciation_account, depreciation_expense_account = \
get_depreciation_accounts(asset)
- depreciation_cost_center, depreciation_series = frappe.get_cached_value('Company', asset.company,
+ depreciation_cost_center, depreciation_series = frappe.get_cached_value('Company', asset.company,
["depreciation_cost_center", "series_for_depreciation_entry"])
je = frappe.new_doc("Journal Entry")
@@ -75,8 +75,8 @@ class AssetValueAdjustment(Document):
rate_per_day = flt(d.value_after_depreciation) / flt(total_days)
from_date = self.date
else:
- no_of_depreciations = len([e.name for e in asset.schedules
- if (cint(s.finance_book_id) == d.idx and not e.journal_entry)])
+ no_of_depreciations = len([s.name for s in asset.schedules
+ if (cint(s.finance_book_id) == d.idx and not s.journal_entry)])
value_after_depreciation = d.value_after_depreciation
for data in asset.schedules:
diff --git a/erpnext/assets/doctype/location/test_location.py b/erpnext/assets/doctype/location/test_location.py
index 22d25b5e11c..c98b0b0936c 100644
--- a/erpnext/assets/doctype/location/test_location.py
+++ b/erpnext/assets/doctype/location/test_location.py
@@ -25,9 +25,12 @@ class TestLocation(unittest.TestCase):
temp['features'][0]['properties']['feature_of'] = location
formatted_locations.extend(temp['features'])
- formatted_location_string = str(formatted_locations)
test_location = frappe.get_doc('Location', 'Test Location Area')
test_location.save()
- self.assertEqual(formatted_location_string, str(json.loads(test_location.get('location'))['features']))
+ test_location_features = json.loads(test_location.get('location'))['features']
+ ordered_test_location_features = sorted(test_location_features, key=lambda x: x['properties']['feature_of'])
+ ordered_formatted_locations = sorted(formatted_locations, key=lambda x: x['properties']['feature_of'])
+
+ self.assertEqual(ordered_formatted_locations, ordered_test_location_features)
self.assertEqual(area, test_location.get('area'))
diff --git a/erpnext/buying/doctype/purchase_order/purchase_order.js b/erpnext/buying/doctype/purchase_order/purchase_order.js
index c032df32706..7b90b2b2a6f 100644
--- a/erpnext/buying/doctype/purchase_order/purchase_order.js
+++ b/erpnext/buying/doctype/purchase_order/purchase_order.js
@@ -104,7 +104,7 @@ erpnext.buying.PurchaseOrderController = erpnext.buying.BuyingController.extend(
if(doc.docstatus == 1 && !in_list(["Closed", "Delivered"], doc.status)) {
if (this.frm.has_perm("submit")) {
- if(flt(doc.per_billed, 2) < 100 || doc.per_received < 100) {
+ if(flt(doc.per_billed, 6) < 100 || flt(doc.per_received, 6) < 100) {
cur_frm.add_custom_button(__('Close'), this.close_purchase_order, __("Status"));
}
}
diff --git a/erpnext/buying/doctype/purchase_order/purchase_order.json b/erpnext/buying/doctype/purchase_order/purchase_order.json
index 8c586d14669..0e145009efa 100644
--- a/erpnext/buying/doctype/purchase_order/purchase_order.json
+++ b/erpnext/buying/doctype/purchase_order/purchase_order.json
@@ -20,6 +20,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "supplier_section",
"fieldtype": "Section Break",
"hidden": 0,
@@ -53,6 +54,7 @@
"collapsible": 0,
"columns": 0,
"default": "{supplier_name}",
+ "fetch_if_empty": 0,
"fieldname": "title",
"fieldtype": "Data",
"hidden": 1,
@@ -86,6 +88,7 @@
"collapsible": 0,
"columns": 0,
"default": "",
+ "fetch_if_empty": 0,
"fieldname": "naming_series",
"fieldtype": "Select",
"hidden": 0,
@@ -121,6 +124,7 @@
"collapsible": 0,
"columns": 0,
"description": "",
+ "fetch_if_empty": 0,
"fieldname": "supplier",
"fieldtype": "Link",
"hidden": 0,
@@ -156,6 +160,7 @@
"collapsible": 0,
"columns": 0,
"depends_on": "eval:doc.supplier && doc.docstatus===0 && (!(doc.items && doc.items.length) || (doc.items.length==1 && !doc.items[0].item_code))",
+ "fetch_if_empty": 0,
"fieldname": "get_items_from_open_material_requests",
"fieldtype": "Button",
"hidden": 0,
@@ -189,6 +194,7 @@
"collapsible": 0,
"columns": 0,
"fetch_from": "supplier.supplier_name",
+ "fetch_if_empty": 0,
"fieldname": "supplier_name",
"fieldtype": "Data",
"hidden": 0,
@@ -222,6 +228,7 @@
"collapsible": 0,
"columns": 0,
"description": "",
+ "fetch_if_empty": 0,
"fieldname": "company",
"fieldtype": "Link",
"hidden": 0,
@@ -256,6 +263,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "column_break1",
"fieldtype": "Column Break",
"hidden": 0,
@@ -290,6 +298,7 @@
"collapsible": 0,
"columns": 0,
"default": "Today",
+ "fetch_if_empty": 0,
"fieldname": "transaction_date",
"fieldtype": "Date",
"hidden": 0,
@@ -324,6 +333,7 @@
"collapsible": 0,
"columns": 0,
"default": "",
+ "fetch_if_empty": 0,
"fieldname": "schedule_date",
"fieldtype": "Date",
"hidden": 0,
@@ -357,6 +367,7 @@
"collapsible": 0,
"columns": 0,
"depends_on": "eval:doc.docstatus===1",
+ "fetch_if_empty": 0,
"fieldname": "order_confirmation_no",
"fieldtype": "Data",
"hidden": 0,
@@ -390,6 +401,7 @@
"collapsible": 0,
"columns": 0,
"depends_on": "eval:doc.order_confirmation_no",
+ "fetch_if_empty": 0,
"fieldname": "order_confirmation_date",
"fieldtype": "Date",
"hidden": 0,
@@ -422,6 +434,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "amended_from",
"fieldtype": "Link",
"hidden": 0,
@@ -457,6 +470,7 @@
"collapsible": 0,
"collapsible_depends_on": "",
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "drop_ship",
"fieldtype": "Section Break",
"hidden": 0,
@@ -490,6 +504,7 @@
"collapsible": 0,
"columns": 0,
"depends_on": "",
+ "fetch_if_empty": 0,
"fieldname": "customer",
"fieldtype": "Link",
"hidden": 0,
@@ -524,6 +539,7 @@
"collapsible": 0,
"columns": 0,
"depends_on": "",
+ "fetch_if_empty": 0,
"fieldname": "customer_name",
"fieldtype": "Data",
"hidden": 0,
@@ -556,6 +572,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "column_break_19",
"fieldtype": "Column Break",
"hidden": 0,
@@ -588,6 +605,7 @@
"collapsible": 0,
"columns": 0,
"depends_on": "",
+ "fetch_if_empty": 0,
"fieldname": "customer_contact_person",
"fieldtype": "Link",
"hidden": 0,
@@ -621,6 +639,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "customer_contact_display",
"fieldtype": "Small Text",
"hidden": 1,
@@ -653,6 +672,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "customer_contact_mobile",
"fieldtype": "Small Text",
"hidden": 1,
@@ -685,6 +705,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "customer_contact_email",
"fieldtype": "Code",
"hidden": 1,
@@ -718,6 +739,7 @@
"bold": 0,
"collapsible": 1,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "section_addresses",
"fieldtype": "Section Break",
"hidden": 0,
@@ -750,6 +772,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "supplier_address",
"fieldtype": "Link",
"hidden": 0,
@@ -782,6 +805,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "contact_person",
"fieldtype": "Link",
"hidden": 0,
@@ -815,6 +839,7 @@
"collapsible": 0,
"columns": 0,
"depends_on": "",
+ "fetch_if_empty": 0,
"fieldname": "address_display",
"fieldtype": "Small Text",
"hidden": 0,
@@ -846,6 +871,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "contact_display",
"fieldtype": "Small Text",
"hidden": 0,
@@ -877,6 +903,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "contact_mobile",
"fieldtype": "Small Text",
"hidden": 0,
@@ -908,6 +935,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "contact_email",
"fieldtype": "Small Text",
"hidden": 0,
@@ -939,6 +967,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "col_break_address",
"fieldtype": "Column Break",
"hidden": 0,
@@ -971,6 +1000,7 @@
"collapsible": 0,
"columns": 0,
"depends_on": "",
+ "fetch_if_empty": 0,
"fieldname": "shipping_address",
"fieldtype": "Link",
"hidden": 0,
@@ -1004,6 +1034,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "shipping_address_display",
"fieldtype": "Small Text",
"hidden": 0,
@@ -1036,6 +1067,7 @@
"bold": 0,
"collapsible": 1,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "currency_and_price_list",
"fieldtype": "Section Break",
"hidden": 0,
@@ -1068,6 +1100,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "currency",
"fieldtype": "Link",
"hidden": 0,
@@ -1103,6 +1136,7 @@
"collapsible": 0,
"columns": 0,
"description": "",
+ "fetch_if_empty": 0,
"fieldname": "conversion_rate",
"fieldtype": "Float",
"hidden": 0,
@@ -1137,6 +1171,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "cb_price_list",
"fieldtype": "Column Break",
"hidden": 0,
@@ -1167,6 +1202,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "buying_price_list",
"fieldtype": "Link",
"hidden": 0,
@@ -1199,6 +1235,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "price_list_currency",
"fieldtype": "Link",
"hidden": 0,
@@ -1231,6 +1268,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "plc_conversion_rate",
"fieldtype": "Float",
"hidden": 0,
@@ -1263,6 +1301,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "ignore_pricing_rule",
"fieldtype": "Check",
"hidden": 0,
@@ -1294,6 +1333,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "sec_warehouse",
"fieldtype": "Section Break",
"hidden": 0,
@@ -1325,6 +1365,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "set_warehouse",
"fieldtype": "Link",
"hidden": 0,
@@ -1358,6 +1399,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "col_break_warehouse",
"fieldtype": "Column Break",
"hidden": 0,
@@ -1390,6 +1432,7 @@
"collapsible": 0,
"columns": 0,
"default": "No",
+ "fetch_if_empty": 0,
"fieldname": "is_subcontracted",
"fieldtype": "Select",
"hidden": 0,
@@ -1423,6 +1466,7 @@
"collapsible": 0,
"columns": 0,
"depends_on": "eval:doc.is_subcontracted==\"Yes\"",
+ "fetch_if_empty": 0,
"fieldname": "supplier_warehouse",
"fieldtype": "Link",
"hidden": 0,
@@ -1456,6 +1500,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "items_section",
"fieldtype": "Section Break",
"hidden": 0,
@@ -1489,6 +1534,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "scan_barcode",
"fieldtype": "Data",
"hidden": 0,
@@ -1521,6 +1567,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "items",
"fieldtype": "Table",
"hidden": 0,
@@ -1556,6 +1603,7 @@
"collapsible": 0,
"collapsible_depends_on": "supplied_items",
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "raw_material_details",
"fieldtype": "Section Break",
"hidden": 0,
@@ -1589,6 +1637,7 @@
"collapsible": 0,
"columns": 0,
"depends_on": "",
+ "fetch_if_empty": 0,
"fieldname": "supplied_items",
"fieldtype": "Table",
"hidden": 0,
@@ -1623,6 +1672,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "sb_last_purchase",
"fieldtype": "Section Break",
"hidden": 0,
@@ -1653,6 +1703,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "total_qty",
"fieldtype": "Float",
"hidden": 0,
@@ -1685,6 +1736,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "base_total",
"fieldtype": "Currency",
"hidden": 0,
@@ -1718,6 +1770,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "base_net_total",
"fieldtype": "Currency",
"hidden": 0,
@@ -1752,6 +1805,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "column_break_26",
"fieldtype": "Column Break",
"hidden": 0,
@@ -1782,6 +1836,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "total",
"fieldtype": "Currency",
"hidden": 0,
@@ -1815,6 +1870,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "net_total",
"fieldtype": "Currency",
"hidden": 0,
@@ -1849,6 +1905,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "total_net_weight",
"fieldtype": "Float",
"hidden": 0,
@@ -1881,6 +1938,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "taxes_section",
"fieldtype": "Section Break",
"hidden": 0,
@@ -1915,6 +1973,7 @@
"collapsible": 0,
"columns": 0,
"description": "",
+ "fetch_if_empty": 0,
"fieldname": "taxes_and_charges",
"fieldtype": "Link",
"hidden": 0,
@@ -1949,6 +2008,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "column_break_50",
"fieldtype": "Column Break",
"hidden": 0,
@@ -1980,6 +2040,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "shipping_rule",
"fieldtype": "Link",
"hidden": 0,
@@ -2013,6 +2074,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "section_break_52",
"fieldtype": "Section Break",
"hidden": 0,
@@ -2044,6 +2106,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "taxes",
"fieldtype": "Table",
"hidden": 0,
@@ -2078,6 +2141,7 @@
"bold": 0,
"collapsible": 1,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "sec_tax_breakup",
"fieldtype": "Section Break",
"hidden": 0,
@@ -2110,6 +2174,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "other_charges_calculation",
"fieldtype": "Text",
"hidden": 0,
@@ -2142,6 +2207,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "totals",
"fieldtype": "Section Break",
"hidden": 0,
@@ -2175,6 +2241,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "base_taxes_and_charges_added",
"fieldtype": "Currency",
"hidden": 0,
@@ -2209,6 +2276,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "base_taxes_and_charges_deducted",
"fieldtype": "Currency",
"hidden": 0,
@@ -2243,6 +2311,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "base_total_taxes_and_charges",
"fieldtype": "Currency",
"hidden": 0,
@@ -2277,6 +2346,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "column_break_39",
"fieldtype": "Column Break",
"hidden": 0,
@@ -2308,6 +2378,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "taxes_and_charges_added",
"fieldtype": "Currency",
"hidden": 0,
@@ -2342,6 +2413,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "taxes_and_charges_deducted",
"fieldtype": "Currency",
"hidden": 0,
@@ -2376,6 +2448,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "total_taxes_and_charges",
"fieldtype": "Currency",
"hidden": 0,
@@ -2410,6 +2483,7 @@
"collapsible": 1,
"collapsible_depends_on": "discount_amount",
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "discount_section",
"fieldtype": "Section Break",
"hidden": 0,
@@ -2443,6 +2517,7 @@
"collapsible": 0,
"columns": 0,
"default": "Grand Total",
+ "fetch_if_empty": 0,
"fieldname": "apply_discount_on",
"fieldtype": "Select",
"hidden": 0,
@@ -2476,6 +2551,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "base_discount_amount",
"fieldtype": "Currency",
"hidden": 0,
@@ -2509,6 +2585,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "column_break_45",
"fieldtype": "Column Break",
"hidden": 0,
@@ -2540,6 +2617,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "additional_discount_percentage",
"fieldtype": "Float",
"hidden": 0,
@@ -2572,6 +2650,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "discount_amount",
"fieldtype": "Currency",
"hidden": 0,
@@ -2605,6 +2684,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "totals_section",
"fieldtype": "Section Break",
"hidden": 0,
@@ -2636,6 +2716,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "base_grand_total",
"fieldtype": "Currency",
"hidden": 0,
@@ -2670,6 +2751,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "base_rounding_adjustment",
"fieldtype": "Currency",
"hidden": 0,
@@ -2704,6 +2786,7 @@
"collapsible": 0,
"columns": 0,
"description": "In Words will be visible once you save the Purchase Order.",
+ "fetch_if_empty": 0,
"fieldname": "base_in_words",
"fieldtype": "Data",
"hidden": 0,
@@ -2737,6 +2820,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "base_rounded_total",
"fieldtype": "Currency",
"hidden": 0,
@@ -2771,6 +2855,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "column_break4",
"fieldtype": "Column Break",
"hidden": 0,
@@ -2802,6 +2887,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "grand_total",
"fieldtype": "Currency",
"hidden": 0,
@@ -2836,6 +2922,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "rounding_adjustment",
"fieldtype": "Currency",
"hidden": 0,
@@ -2869,6 +2956,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "rounded_total",
"fieldtype": "Currency",
"hidden": 0,
@@ -2881,6 +2969,7 @@
"label": "Rounded Total",
"length": 0,
"no_copy": 0,
+ "options": "currency",
"permlevel": 0,
"precision": "",
"print_hide": 0,
@@ -2901,6 +2990,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "disable_rounded_total",
"fieldtype": "Check",
"hidden": 0,
@@ -2933,6 +3023,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "in_words",
"fieldtype": "Data",
"hidden": 0,
@@ -2966,6 +3057,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "advance_paid",
"fieldtype": "Currency",
"hidden": 0,
@@ -2998,6 +3090,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "payment_schedule_section",
"fieldtype": "Section Break",
"hidden": 0,
@@ -3030,6 +3123,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "payment_terms_template",
"fieldtype": "Link",
"hidden": 0,
@@ -3063,6 +3157,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "payment_schedule",
"fieldtype": "Table",
"hidden": 0,
@@ -3097,6 +3192,7 @@
"collapsible": 1,
"collapsible_depends_on": "terms",
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "terms_section_break",
"fieldtype": "Section Break",
"hidden": 0,
@@ -3130,6 +3226,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "tc_name",
"fieldtype": "Link",
"hidden": 0,
@@ -3164,6 +3261,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "terms",
"fieldtype": "Text Editor",
"hidden": 0,
@@ -3197,6 +3295,7 @@
"bold": 0,
"collapsible": 1,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "more_info",
"fieldtype": "Section Break",
"hidden": 0,
@@ -3230,6 +3329,7 @@
"collapsible": 0,
"columns": 0,
"default": "Draft",
+ "fetch_if_empty": 0,
"fieldname": "status",
"fieldtype": "Select",
"hidden": 0,
@@ -3264,6 +3364,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "ref_sq",
"fieldtype": "Data",
"hidden": 1,
@@ -3297,6 +3398,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "party_account_currency",
"fieldtype": "Link",
"hidden": 1,
@@ -3330,6 +3432,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "column_break_74",
"fieldtype": "Column Break",
"hidden": 0,
@@ -3363,6 +3466,7 @@
"columns": 0,
"depends_on": "eval:!doc.__islocal",
"description": "",
+ "fetch_if_empty": 0,
"fieldname": "per_received",
"fieldtype": "Percent",
"hidden": 0,
@@ -3398,6 +3502,7 @@
"columns": 0,
"depends_on": "eval:!doc.__islocal",
"description": "",
+ "fetch_if_empty": 0,
"fieldname": "per_billed",
"fieldtype": "Percent",
"hidden": 0,
@@ -3431,6 +3536,7 @@
"bold": 0,
"collapsible": 1,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "column_break5",
"fieldtype": "Section Break",
"hidden": 0,
@@ -3465,6 +3571,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "letter_head",
"fieldtype": "Link",
"hidden": 0,
@@ -3499,6 +3606,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "select_print_heading",
"fieldtype": "Link",
"hidden": 0,
@@ -3533,6 +3641,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "column_break_86",
"fieldtype": "Column Break",
"hidden": 0,
@@ -3565,6 +3674,7 @@
"collapsible": 0,
"columns": 0,
"description": "",
+ "fetch_if_empty": 0,
"fieldname": "group_same_items",
"fieldtype": "Check",
"hidden": 0,
@@ -3598,6 +3708,7 @@
"collapsible": 0,
"columns": 0,
"default": "",
+ "fetch_if_empty": 0,
"fieldname": "language",
"fieldtype": "Data",
"hidden": 0,
@@ -3631,6 +3742,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "subscription_section",
"fieldtype": "Section Break",
"hidden": 0,
@@ -3665,6 +3777,7 @@
"columns": 0,
"depends_on": "",
"description": "",
+ "fetch_if_empty": 0,
"fieldname": "from_date",
"fieldtype": "Date",
"hidden": 0,
@@ -3698,6 +3811,7 @@
"columns": 0,
"depends_on": "",
"description": "",
+ "fetch_if_empty": 0,
"fieldname": "to_date",
"fieldtype": "Date",
"hidden": 0,
@@ -3729,6 +3843,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "column_break_97",
"fieldtype": "Column Break",
"hidden": 0,
@@ -3760,6 +3875,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "auto_repeat",
"fieldtype": "Link",
"hidden": 0,
@@ -3794,6 +3910,7 @@
"collapsible": 0,
"columns": 0,
"depends_on": "eval: doc.auto_repeat",
+ "fetch_if_empty": 0,
"fieldname": "update_auto_repeat_reference",
"fieldtype": "Button",
"hidden": 0,
@@ -3831,7 +3948,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
- "modified": "2019-01-07 16:51:56.739693",
+ "modified": "2019-06-24 20:55:03.466766",
"modified_by": "Administrator",
"module": "Buying",
"name": "Purchase Order",
diff --git a/erpnext/buying/doctype/purchase_order_item/purchase_order_item.json b/erpnext/buying/doctype/purchase_order_item/purchase_order_item.json
index 3d981c56da7..238d9545342 100755
--- a/erpnext/buying/doctype/purchase_order_item/purchase_order_item.json
+++ b/erpnext/buying/doctype/purchase_order_item/purchase_order_item.json
@@ -1915,7 +1915,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
- "default": "1",
+ "default": "0",
"depends_on": "eval:parent.is_subcontracted == 'Yes'",
"fieldname": "include_exploded_items",
"fieldtype": "Check",
@@ -2344,7 +2344,7 @@
"issingle": 0,
"istable": 1,
"max_attachments": 0,
- "modified": "2019-01-07 16:51:57.546323",
+ "modified": "2019-06-23 20:03:13.818917",
"modified_by": "Administrator",
"module": "Buying",
"name": "Purchase Order Item",
@@ -2359,4 +2359,4 @@
"track_changes": 1,
"track_seen": 0,
"track_views": 0
-}
\ No newline at end of file
+}
diff --git a/erpnext/controllers/accounts_controller.py b/erpnext/controllers/accounts_controller.py
index 92d380421d7..79695732683 100644
--- a/erpnext/controllers/accounts_controller.py
+++ b/erpnext/controllers/accounts_controller.py
@@ -747,7 +747,12 @@ class AccountsController(TransactionBase):
count += 1
item.qty = group_item_qty[item.item_code]
item.amount = group_item_amount[item.item_code]
- item.rate = flt(flt(item.amount) / flt(item.qty), item.precision("rate"))
+
+ if item.qty:
+ item.rate = flt(flt(item.amount) / flt(item.qty), item.precision("rate"))
+ else:
+ item.rate = 0
+
item.idx = count
del group_item_qty[item.item_code]
else:
diff --git a/erpnext/controllers/buying_controller.py b/erpnext/controllers/buying_controller.py
index 664bce4e4fa..917c901cfcb 100644
--- a/erpnext/controllers/buying_controller.py
+++ b/erpnext/controllers/buying_controller.py
@@ -428,8 +428,9 @@ class BuyingController(StockController):
elif not flt(d.rejected_qty):
d.rejected_qty = flt(d.received_qty) - flt(d.qty)
+ val = flt(d.qty) + flt(d.rejected_qty)
# Check Received Qty = Accepted Qty + Rejected Qty
- if ((flt(d.qty) + flt(d.rejected_qty)) != flt(d.received_qty)):
+ if (flt(val, d.precision("received_qty")) != flt(d.received_qty, d.precision("received_qty"))):
frappe.throw(_("Accepted + Rejected Qty must be equal to Received quantity for Item {0}").format(d.item_code))
def validate_negative_quantity(self, item_row, field_list):
diff --git a/erpnext/controllers/status_updater.py b/erpnext/controllers/status_updater.py
index 2484586d041..a3018029bc0 100644
--- a/erpnext/controllers/status_updater.py
+++ b/erpnext/controllers/status_updater.py
@@ -27,7 +27,7 @@ status_map = {
],
"Quotation": [
["Draft", None],
- ["Submitted", "eval:self.docstatus==1"],
+ ["Open", "eval:self.docstatus==1"],
["Lost", "eval:self.status=='Lost'"],
["Ordered", "has_sales_order"],
["Cancelled", "eval:self.docstatus==2"],
diff --git a/erpnext/erpnext_integrations/connectors/woocommerce_connection.py b/erpnext/erpnext_integrations/connectors/woocommerce_connection.py
index 4700202213f..0b6ea8cc7ca 100644
--- a/erpnext/erpnext_integrations/connectors/woocommerce_connection.py
+++ b/erpnext/erpnext_integrations/connectors/woocommerce_connection.py
@@ -22,7 +22,16 @@ def verify_request():
frappe.set_user(woocommerce_settings.creation_user)
@frappe.whitelist(allow_guest=True)
-def order():
+def order(*args, **kwargs):
+ try:
+ _order(*args, **kwargs)
+ except Exception:
+ error_message = frappe.get_traceback()+"\n\n Request Data: \n"+json.loads(frappe.request.data).__str__()
+ frappe.log_error(error_message, "WooCommerce Error")
+ raise
+
+
+def _order(*args, **kwargs):
woocommerce_settings = frappe.get_doc("Woocommerce Settings")
if frappe.flags.woocomm_test_order_data:
fd = frappe.flags.woocomm_test_order_data
diff --git a/erpnext/erpnext_integrations/doctype/amazon_mws_settings/amazon_methods.py b/erpnext/erpnext_integrations/doctype/amazon_mws_settings/amazon_methods.py
index 124910e35de..1c39d8818c4 100644
--- a/erpnext/erpnext_integrations/doctype/amazon_mws_settings/amazon_methods.py
+++ b/erpnext/erpnext_integrations/doctype/amazon_mws_settings/amazon_methods.py
@@ -40,7 +40,7 @@ def get_products_details():
products_response = call_mws_method(products.get_matching_product,marketplaceid=marketplace,
asins=asin_list)
- matching_products_list = products_response.parsed
+ matching_products_list = products_response.parsed
for product in matching_products_list:
skus = [row["sku"] for row in sku_asin if row["asin"]==product.ASIN]
for sku in skus:
@@ -116,7 +116,7 @@ def call_mws_method(mws_method, *args, **kwargs):
mws_settings = frappe.get_doc("Amazon MWS Settings")
max_retries = mws_settings.max_retry_limit
- for x in xrange(0, max_retries):
+ for x in range(0, max_retries):
try:
response = mws_method(*args, **kwargs)
return response
diff --git a/erpnext/hooks.py b/erpnext/hooks.py
index 9b18e5e1f3a..a067e28747e 100644
--- a/erpnext/hooks.py
+++ b/erpnext/hooks.py
@@ -42,7 +42,7 @@ update_and_get_user_progress = "erpnext.utilities.user_progress_utils.update_def
on_session_creation = "erpnext.shopping_cart.utils.set_cart_count"
on_logout = "erpnext.shopping_cart.utils.clear_cart_count"
-treeviews = ['Account', 'Cost Center', 'Warehouse', 'Item Group', 'Customer Group', 'Sales Person', 'Territory', 'Assessment Group']
+treeviews = ['Account', 'Cost Center', 'Warehouse', 'Item Group', 'Customer Group', 'Sales Person', 'Territory', 'Assessment Group', 'Department']
# website
update_website_context = "erpnext.shopping_cart.utils.update_website_context"
diff --git a/erpnext/hr/doctype/attendance/attendance_calendar.js b/erpnext/hr/doctype/attendance/attendance_calendar.js
index b21afe5eaee..104f09d69ff 100644
--- a/erpnext/hr/doctype/attendance/attendance_calendar.js
+++ b/erpnext/hr/doctype/attendance/attendance_calendar.js
@@ -2,8 +2,8 @@
// For license information, please see license.txt
frappe.views.calendar["Attendance"] = {
field_map: {
- "start": "date",
- "end": "date",
+ "start": "attendance_date",
+ "end": "attendance_date",
"id": "name",
"docstatus": 1
},
diff --git a/erpnext/hr/doctype/department/department.js b/erpnext/hr/doctype/department/department.js
index 76bc932144c..963f3615cc5 100644
--- a/erpnext/hr/doctype/department/department.js
+++ b/erpnext/hr/doctype/department/department.js
@@ -4,7 +4,7 @@
frappe.ui.form.on('Department', {
refresh: function(frm) {
// read-only for root department
- if(!frm.doc.parent_department) {
+ if(!frm.doc.parent_department && !frm.is_new()) {
frm.set_read_only();
frm.set_intro(__("This is a root department and cannot be edited."));
}
diff --git a/erpnext/hr/doctype/department/department.json b/erpnext/hr/doctype/department/department.json
index aed7f42faf8..3b400ce8d76 100644
--- a/erpnext/hr/doctype/department/department.json
+++ b/erpnext/hr/doctype/department/department.json
@@ -1,5 +1,6 @@
{
"allow_copy": 0,
+ "allow_events_in_timeline": 0,
"allow_guest_to_view": 0,
"allow_import": 1,
"allow_rename": 1,
@@ -19,6 +20,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "department_name",
"fieldtype": "Data",
"hidden": 0,
@@ -52,6 +54,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "parent_department",
"fieldtype": "Link",
"hidden": 0,
@@ -85,6 +88,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "company",
"fieldtype": "Link",
"hidden": 0,
@@ -118,6 +122,7 @@
"bold": 1,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "is_group",
"fieldtype": "Check",
"hidden": 0,
@@ -150,6 +155,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "disabled",
"fieldtype": "Check",
"hidden": 0,
@@ -182,6 +188,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "section_break_4",
"fieldtype": "Section Break",
"hidden": 0,
@@ -214,6 +221,7 @@
"collapsible": 0,
"columns": 0,
"description": "Days for which Holidays are blocked for this department.",
+ "fetch_if_empty": 0,
"fieldname": "leave_block_list",
"fieldtype": "Link",
"hidden": 0,
@@ -246,6 +254,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "leave_section",
"fieldtype": "Section Break",
"hidden": 0,
@@ -279,6 +288,7 @@
"collapsible": 0,
"columns": 0,
"description": "The first Leave Approver in the list will be set as the default Leave Approver.",
+ "fetch_if_empty": 0,
"fieldname": "leave_approvers",
"fieldtype": "Table",
"hidden": 0,
@@ -312,6 +322,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "expense_section",
"fieldtype": "Section Break",
"hidden": 0,
@@ -345,6 +356,7 @@
"collapsible": 0,
"columns": 0,
"description": "The first Expense Approver in the list will be set as the default Expense Approver.",
+ "fetch_if_empty": 0,
"fieldname": "expense_approvers",
"fieldtype": "Table",
"hidden": 0,
@@ -378,6 +390,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "lft",
"fieldtype": "Int",
"hidden": 1,
@@ -410,6 +423,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "rgt",
"fieldtype": "Int",
"hidden": 1,
@@ -442,6 +456,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "old_parent",
"fieldtype": "Data",
"hidden": 1,
@@ -479,7 +494,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
- "modified": "2018-08-29 06:26:12.995703",
+ "modified": "2019-06-25 18:43:05.550387",
"modified_by": "Administrator",
"module": "HR",
"name": "Department",
@@ -543,7 +558,7 @@
"write": 1
}
],
- "quick_entry": 1,
+ "quick_entry": 0,
"read_only": 0,
"read_only_onload": 0,
"show_name_in_global_search": 1,
diff --git a/erpnext/hr/doctype/employee_attendance_tool/employee_attendance_tool.js b/erpnext/hr/doctype/employee_attendance_tool/employee_attendance_tool.js
index 376d0c0a5a5..22ba5ad473e 100644
--- a/erpnext/hr/doctype/employee_attendance_tool/employee_attendance_tool.js
+++ b/erpnext/hr/doctype/employee_attendance_tool/employee_attendance_tool.js
@@ -2,9 +2,8 @@ frappe.ui.form.on("Employee Attendance Tool", {
refresh: function(frm) {
frm.disable_save();
},
-
+
onload: function(frm) {
- frm.doc.department = frm.doc.branch = frm.doc.company = "All";
frm.set_value("date", frappe.datetime.get_today());
erpnext.employee_attendance_tool.load_employees(frm);
},
@@ -24,7 +23,7 @@ frappe.ui.form.on("Employee Attendance Tool", {
company: function(frm) {
erpnext.employee_attendance_tool.load_employees(frm);
}
-
+
});
diff --git a/erpnext/hr/doctype/employee_attendance_tool/employee_attendance_tool.py b/erpnext/hr/doctype/employee_attendance_tool/employee_attendance_tool.py
index ea5f4bdecab..32fcee1abe4 100644
--- a/erpnext/hr/doctype/employee_attendance_tool/employee_attendance_tool.py
+++ b/erpnext/hr/doctype/employee_attendance_tool/employee_attendance_tool.py
@@ -17,12 +17,11 @@ def get_employees(date, department = None, branch = None, company = None):
attendance_not_marked = []
attendance_marked = []
filters = {"status": "Active", "date_of_joining": ["<=", date]}
- if department != "All":
- filters["department"] = department
- if branch != "All":
- filters["branch"] = branch
- if company != "All":
- filters["company"] = company
+
+ for field, value in {'department': department,
+ 'branch': branch, 'company': company}.items():
+ if value:
+ filters[field] = value
employee_list = frappe.get_list("Employee", fields=["employee", "employee_name"], filters=filters, order_by="employee_name")
marked_employee = {}
diff --git a/erpnext/hr/doctype/job_applicant/job_applicant.js b/erpnext/hr/doctype/job_applicant/job_applicant.js
index 977702e314c..05071e19743 100644
--- a/erpnext/hr/doctype/job_applicant/job_applicant.js
+++ b/erpnext/hr/doctype/job_applicant/job_applicant.js
@@ -25,5 +25,13 @@ frappe.ui.form.on("Job Applicant", {
}
}
+ frm.set_query("job_title", function() {
+ return {
+ filters: {
+ 'status': 'Open'
+ }
+ };
+ });
+
}
});
\ No newline at end of file
diff --git a/erpnext/hr/doctype/salary_slip/salary_slip.py b/erpnext/hr/doctype/salary_slip/salary_slip.py
index d3b960d29eb..c73c708b204 100644
--- a/erpnext/hr/doctype/salary_slip/salary_slip.py
+++ b/erpnext/hr/doctype/salary_slip/salary_slip.py
@@ -5,7 +5,7 @@ from __future__ import unicode_literals
import frappe, erpnext
import datetime, math
-from frappe.utils import add_days, cint, cstr, flt, getdate, rounded, date_diff, money_in_words, getdate
+from frappe.utils import add_days, cint, cstr, flt, getdate, rounded, date_diff, money_in_words
from frappe.model.naming import make_autoname
from frappe import msgprint, _
diff --git a/erpnext/manufacturing/doctype/bom/test_bom.py b/erpnext/manufacturing/doctype/bom/test_bom.py
index e230e598489..45a7b935d38 100644
--- a/erpnext/manufacturing/doctype/bom/test_bom.py
+++ b/erpnext/manufacturing/doctype/bom/test_bom.py
@@ -90,7 +90,7 @@ class TestBOM(unittest.TestCase):
self.assertEqual(bom.base_total_cost, 486000)
def test_bom_cost_multi_uom_multi_currency_based_on_price_list(self):
- frappe.db.set_value("Price List", "_Test Price List", "price_not_uom_dependant", 1)
+ frappe.db.set_value("Price List", "_Test Price List", "price_not_uom_dependent", 1)
for item_code, rate in (("_Test Item", 3600), ("_Test Item Home Desktop Manufactured", 3000)):
frappe.db.sql("delete from `tabItem Price` where price_list='_Test Price List' and item_code=%s",
item_code)
diff --git a/erpnext/manufacturing/doctype/production_order/production_order.py b/erpnext/manufacturing/doctype/production_order/production_order.py
index 2f2c40ef2d4..b5abb733b01 100644
--- a/erpnext/manufacturing/doctype/production_order/production_order.py
+++ b/erpnext/manufacturing/doctype/production_order/production_order.py
@@ -18,6 +18,7 @@ from erpnext.stock.stock_balance import get_planned_qty, update_bin_qty
from frappe.utils.csvutils import getlink
from erpnext.stock.utils import get_bin, validate_warehouse_company, get_latest_stock_qty
from erpnext.utilities.transaction_base import validate_uom_is_integer
+from six import text_type
class OverProductionError(frappe.ValidationError): pass
class StockOverProductionError(frappe.ValidationError): pass
@@ -591,10 +592,10 @@ def make_timesheet(production_order, company):
@frappe.whitelist()
def add_timesheet_detail(timesheet, args):
- if isinstance(timesheet, unicode):
+ if isinstance(timesheet, text_type):
timesheet = frappe.get_doc('Timesheet', timesheet)
- if isinstance(args, unicode):
+ if isinstance(args, text_type):
args = json.loads(args)
timesheet.append('time_logs', args)
diff --git a/erpnext/patches.txt b/erpnext/patches.txt
index b6083ef44c0..962ef8a8a8d 100755
--- a/erpnext/patches.txt
+++ b/erpnext/patches.txt
@@ -533,7 +533,7 @@ erpnext.patches.v11_0.create_department_records_for_each_company
erpnext.patches.v11_0.make_location_from_warehouse
erpnext.patches.v11_0.make_asset_finance_book_against_old_entries
erpnext.patches.v11_0.check_buying_selling_in_currency_exchange
-erpnext.patches.v11_0.move_item_defaults_to_child_table_for_multicompany #02-07-2018
+erpnext.patches.v11_0.move_item_defaults_to_child_table_for_multicompany #02-07-2018 #19-06-2019
erpnext.patches.v11_0.refactor_erpnext_shopify #2018-09-07
erpnext.patches.v11_0.rename_overproduction_percent_field
erpnext.patches.v11_0.update_backflush_subcontract_rm_based_on_bom
@@ -586,7 +586,7 @@ erpnext.patches.v11_0.add_permissions_in_gst_settings
erpnext.patches.v11_1.setup_guardian_role
execute:frappe.delete_doc('DocType', 'Notification Control')
erpnext.patches.v11_0.remove_barcodes_field_from_copy_fields_to_variants
-erpnext.patches.v10_0.item_barcode_childtable_migrate # 16-02-2019
+erpnext.patches.v10_0.item_barcode_childtable_migrate # 16-02-2019 #25-06-2019
erpnext.patches.v11_0.make_italian_localization_fields # 26-03-2019
erpnext.patches.v11_1.make_job_card_time_logs
erpnext.patches.v11_1.set_variant_based_on
@@ -601,4 +601,5 @@ execute:frappe.delete_doc("Report", "Inactive Items")
erpnext.patches.v11_1.delete_scheduling_tool
erpnext.patches.v11_1.update_bank_transaction_status
erpnext.patches.v11_1.renamed_delayed_item_report
-erpnext.patches.v11_1.set_missing_opportunity_from
\ No newline at end of file
+erpnext.patches.v11_1.set_missing_opportunity_from
+erpnext.patches.v11_1.set_quotation_status
\ No newline at end of file
diff --git a/erpnext/patches/v10_0/item_barcode_childtable_migrate.py b/erpnext/patches/v10_0/item_barcode_childtable_migrate.py
index e30e0a74c00..c16f3554b30 100644
--- a/erpnext/patches/v10_0/item_barcode_childtable_migrate.py
+++ b/erpnext/patches/v10_0/item_barcode_childtable_migrate.py
@@ -7,9 +7,10 @@ import frappe
def execute():
+ if frappe.get_all("Item Barcode", limit=1): return
frappe.reload_doc("stock", "doctype", "item_barcode")
- items_barcode = frappe.get_all('Item', ['name', 'barcode'], { 'barcode': ('!=', '') })
+ items_barcode = frappe.db.sql("select name, barcode from tabItem where barcode is not null", as_dict=True)
frappe.reload_doc("stock", "doctype", "item")
diff --git a/erpnext/patches/v11_0/move_item_defaults_to_child_table_for_multicompany.py b/erpnext/patches/v11_0/move_item_defaults_to_child_table_for_multicompany.py
index 01f84a03136..c7c76355400 100644
--- a/erpnext/patches/v11_0/move_item_defaults_to_child_table_for_multicompany.py
+++ b/erpnext/patches/v11_0/move_item_defaults_to_child_table_for_multicompany.py
@@ -17,10 +17,8 @@ def execute():
frappe.reload_doc('stock', 'doctype', 'item_default')
frappe.reload_doc('stock', 'doctype', 'item')
- if frappe.db.a_row_exists('Item Default'): return
-
companies = frappe.get_all("Company")
- if len(companies) == 1:
+ if len(companies) == 1 and not frappe.get_all("Item Default", limit=1):
try:
frappe.db.sql('''
INSERT INTO `tabItem Default`
@@ -35,32 +33,64 @@ def execute():
except:
pass
else:
- item_details = frappe.get_all("Item", fields=["name", "default_warehouse", "buying_cost_center",
- "expense_account", "selling_cost_center", "income_account"], limit=100)
+ item_details = frappe.db.sql(""" SELECT name, default_warehouse,
+ buying_cost_center, expense_account, selling_cost_center, income_account
+ FROM tabItem
+ WHERE
+ name not in (select distinct parent from `tabItem Default`) and ifnull(disabled, 0) = 0"""
+ , as_dict=1)
- for item in item_details:
- item_defaults = []
+ items_default_data = {}
+ for item_data in item_details:
+ for d in [["default_warehouse", "Warehouse"], ["expense_account", "Account"],
+ ["income_account", "Account"], ["buying_cost_center", "Cost Center"],
+ ["selling_cost_center", "Cost Center"]]:
+ if item_data.get(d[0]):
+ company = frappe.get_value(d[1], item_data.get(d[0]), "company", cache=True)
- def insert_into_item_defaults(doc_field_name, doc_field_value, company):
- for d in item_defaults:
- if d.get("company") == company:
- d[doc_field_name] = doc_field_value
- return
- item_defaults.append({
- "company": company,
- doc_field_name: doc_field_value
- })
+ if item_data.name not in items_default_data:
+ items_default_data[item_data.name] = {}
- for d in [
- ["default_warehouse", "Warehouse"], ["expense_account", "Account"], ["income_account", "Account"],
- ["buying_cost_center", "Cost Center"], ["selling_cost_center", "Cost Center"]
- ]:
- if item.get(d[0]):
- company = frappe.get_value(d[1], item.get(d[0]), "company", cache=True)
- insert_into_item_defaults(d[0], item.get(d[0]), company)
+ company_wise_data = items_default_data[item_data.name]
- doc = frappe.get_doc("Item", item.name)
- doc.extend("item_defaults", item_defaults)
+ if company not in company_wise_data:
+ company_wise_data[company] = {}
- for child_doc in doc.item_defaults:
- child_doc.db_insert()
\ No newline at end of file
+ default_data = company_wise_data[company]
+ default_data[d[0]] = item_data.get(d[0])
+
+ to_insert_data = []
+
+ # items_default_data data structure will be as follow
+ # {
+ # 'item_code 1': {'company 1': {'default_warehouse': 'Test Warehouse 1'}},
+ # 'item_code 2': {
+ # 'company 1': {'default_warehouse': 'Test Warehouse 1'},
+ # 'company 2': {'default_warehouse': 'Test Warehouse 1'}
+ # }
+ # }
+
+ for item_code, companywise_item_data in items_default_data.items():
+ for company, item_default_data in companywise_item_data.items():
+ to_insert_data.append((
+ frappe.generate_hash("", 10),
+ item_code,
+ 'Item',
+ 'item_defaults',
+ company,
+ item_default_data.get('default_warehouse'),
+ item_default_data.get('expense_account'),
+ item_default_data.get('income_account'),
+ item_default_data.get('buying_cost_center'),
+ item_default_data.get('selling_cost_center'),
+ ))
+
+ if to_insert_data:
+ frappe.db.sql('''
+ INSERT INTO `tabItem Default`
+ (
+ `name`, `parent`, `parenttype`, `parentfield`, `company`, `default_warehouse`,
+ `expense_account`, `income_account`, `buying_cost_center`, `selling_cost_center`
+ )
+ VALUES {}
+ '''.format(', '.join(['%s'] * len(to_insert_data))), tuple(to_insert_data))
\ No newline at end of file
diff --git a/erpnext/patches/v11_1/set_quotation_status.py b/erpnext/patches/v11_1/set_quotation_status.py
new file mode 100644
index 00000000000..87643a23545
--- /dev/null
+++ b/erpnext/patches/v11_1/set_quotation_status.py
@@ -0,0 +1,7 @@
+from __future__ import unicode_literals
+import frappe
+
+def execute():
+
+ frappe.db.sql(""" UPDATE `tabQuotation` set status = 'Open'
+ where docstatus = 1 and status = 'Submitted' """)
diff --git a/erpnext/projects/doctype/timesheet/test_timesheet.py b/erpnext/projects/doctype/timesheet/test_timesheet.py
index f1179033bed..32f0428fcd8 100644
--- a/erpnext/projects/doctype/timesheet/test_timesheet.py
+++ b/erpnext/projects/doctype/timesheet/test_timesheet.py
@@ -103,8 +103,8 @@ class TestTimesheet(unittest.TestCase):
{
"billable": 1,
"activity_type": "_Test Activity Type",
- "from_type": now_datetime(),
- "hours": 3,
+ "from_time": now_datetime(),
+ "to_time": now_datetime() + datetime.timedelta(hours=3),
"company": "_Test Company"
}
)
@@ -113,8 +113,8 @@ class TestTimesheet(unittest.TestCase):
{
"billable": 1,
"activity_type": "_Test Activity Type",
- "from_type": now_datetime(),
- "hours": 3,
+ "from_time": now_datetime(),
+ "to_time": now_datetime() + datetime.timedelta(hours=3),
"company": "_Test Company"
}
)
diff --git a/erpnext/public/js/controllers/transaction.js b/erpnext/public/js/controllers/transaction.js
index 1a9ea8288c8..d0ebce8c429 100644
--- a/erpnext/public/js/controllers/transaction.js
+++ b/erpnext/public/js/controllers/transaction.js
@@ -1290,7 +1290,9 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({
},
callback: function(r) {
if(!r.exc) {
- me.frm.set_value("taxes", r.message);
+ for (let tax of r.message) {
+ me.frm.add_child("taxes", tax);
+ }
me.calculate_taxes_and_totals();
}
}
diff --git a/erpnext/regional/report/fichier_des_ecritures_comptables_[fec]/fichier_des_ecritures_comptables_[fec].py b/erpnext/regional/report/fichier_des_ecritures_comptables_[fec]/fichier_des_ecritures_comptables_[fec].py
index e1b6c4db4f9..e903c9f00a4 100644
--- a/erpnext/regional/report/fichier_des_ecritures_comptables_[fec]/fichier_des_ecritures_comptables_[fec].py
+++ b/erpnext/regional/report/fichier_des_ecritures_comptables_[fec]/fichier_des_ecritures_comptables_[fec].py
@@ -69,13 +69,13 @@ def get_gl_entries(filters):
gl_entries = frappe.db.sql("""
select
- gl.posting_date as GlPostDate, gl.name as GlName, gl.account, gl.transaction_date,
+ gl.posting_date as GlPostDate, gl.name as GlName, gl.account, gl.transaction_date,
sum(gl.debit) as debit, sum(gl.credit) as credit,
sum(gl.debit_in_account_currency) as debitCurr, sum(gl.credit_in_account_currency) as creditCurr,
- gl.voucher_type, gl.voucher_no, gl.against_voucher_type,
- gl.against_voucher, gl.account_currency, gl.against,
+ gl.voucher_type, gl.voucher_no, gl.against_voucher_type,
+ gl.against_voucher, gl.account_currency, gl.against,
gl.party_type, gl.party,
- inv.name as InvName, inv.title as InvTitle, inv.posting_date as InvPostDate,
+ inv.name as InvName, inv.title as InvTitle, inv.posting_date as InvPostDate,
pur.name as PurName, pur.title as PurTitle, pur.posting_date as PurPostDate,
jnl.cheque_no as JnlRef, jnl.posting_date as JnlPostDate, jnl.title as JnlTitle,
pay.name as PayName, pay.posting_date as PayPostDate, pay.title as PayTitle,
@@ -84,7 +84,7 @@ def get_gl_entries(filters):
emp.employee_name, emp.name as empName,
stu.title as student_name, stu.name as stuName,
member_name, mem.name as memName
-
+
from `tabGL Entry` gl
left join `tabSales Invoice` inv on gl.voucher_no = inv.name
left join `tabPurchase Invoice` pur on gl.voucher_no = pur.name
@@ -124,7 +124,7 @@ def get_result_as_list(data, filters):
if account_number[0] is not None:
CompteNum = account_number[0]
else:
- frappe.throw(_("Account number for account {0} is not available.
Please setup your Chart of Accounts correctly.").format(account.name))
+ frappe.throw(_("Account number for account {0} is not available.
Please setup your Chart of Accounts correctly.").format(d.get("account")))
if d.get("party_type") == "Customer":
CompAuxNum = d.get("cusName")
diff --git a/erpnext/regional/report/hsn_wise_summary_of_outward_supplies/hsn_wise_summary_of_outward_supplies.js b/erpnext/regional/report/hsn_wise_summary_of_outward_supplies/hsn_wise_summary_of_outward_supplies.js
index dcb81cb087e..dfdf9dc0958 100644
--- a/erpnext/regional/report/hsn_wise_summary_of_outward_supplies/hsn_wise_summary_of_outward_supplies.js
+++ b/erpnext/regional/report/hsn_wise_summary_of_outward_supplies/hsn_wise_summary_of_outward_supplies.js
@@ -29,7 +29,20 @@ frappe.query_reports["HSN-wise-summary of outward supplies"] = {
"placeholder":"Company GSTIN",
"options": [""],
"width": "80"
- }
+ },
+ {
+ "fieldname":"from_date",
+ "label": __("From Date"),
+ "fieldtype": "Date",
+ "width": "80"
+ },
+ {
+ "fieldname":"to_date",
+ "label": __("To Date"),
+ "fieldtype": "Date",
+ "width": "80"
+ },
+
],
onload: (report) => {
fetch_gstins(report);
diff --git a/erpnext/regional/report/hsn_wise_summary_of_outward_supplies/hsn_wise_summary_of_outward_supplies.py b/erpnext/regional/report/hsn_wise_summary_of_outward_supplies/hsn_wise_summary_of_outward_supplies.py
index e938e29c440..222dfa1eb78 100644
--- a/erpnext/regional/report/hsn_wise_summary_of_outward_supplies/hsn_wise_summary_of_outward_supplies.py
+++ b/erpnext/regional/report/hsn_wise_summary_of_outward_supplies/hsn_wise_summary_of_outward_supplies.py
@@ -88,7 +88,9 @@ def get_conditions(filters):
for opts in (("company", " and company=%(company)s"),
("gst_hsn_code", " and gst_hsn_code=%(gst_hsn_code)s"),
- ("company_gstin", " and company_gstin=%(company_gstin)s")):
+ ("company_gstin", " and company_gstin=%(company_gstin)s"),
+ ("from_date", " and posting_date >= %(from_date)s"),
+ ("to_date", "and posting_date <= %(to_date)s")):
if filters.get(opts[0]):
conditions += opts[1]
diff --git a/erpnext/selling/doctype/quotation/quotation.json b/erpnext/selling/doctype/quotation/quotation.json
index 33fc4dbeb04..65fbe52d9a4 100644
--- a/erpnext/selling/doctype/quotation/quotation.json
+++ b/erpnext/selling/doctype/quotation/quotation.json
@@ -3096,7 +3096,7 @@
"no_copy": 1,
"oldfieldname": "status",
"oldfieldtype": "Select",
- "options": "Draft\nSubmitted\nOrdered\nLost\nCancelled\nOpen\nReplied",
+ "options": "Draft\nOpen\nReplied\nOrdered\nLost\nCancelled",
"permlevel": 0,
"print_hide": 1,
"print_hide_if_no_value": 0,
@@ -3224,7 +3224,7 @@
"istable": 0,
"max_attachments": 1,
"menu_index": 0,
- "modified": "2019-05-11 19:26:50.735628",
+ "modified": "2019-06-25 15:31:04.724730",
"modified_by": "Administrator",
"module": "Selling",
"name": "Quotation",
diff --git a/erpnext/selling/doctype/quotation/quotation.py b/erpnext/selling/doctype/quotation/quotation.py
index c344d266949..8b339ba82f2 100644
--- a/erpnext/selling/doctype/quotation/quotation.py
+++ b/erpnext/selling/doctype/quotation/quotation.py
@@ -161,6 +161,10 @@ def _make_sales_order(source_name, target_doc=None, ignore_permissions=False):
"Sales Team": {
"doctype": "Sales Team",
"add_if_empty": True
+ },
+ "Payment Schedule": {
+ "doctype": "Payment Schedule",
+ "add_if_empty": True
}
}, target_doc, set_missing_values, ignore_permissions=ignore_permissions)
diff --git a/erpnext/selling/doctype/quotation/quotation_list.js b/erpnext/selling/doctype/quotation/quotation_list.js
index 61a8bc1cab3..5f4e2546fbc 100644
--- a/erpnext/selling/doctype/quotation/quotation_list.js
+++ b/erpnext/selling/doctype/quotation/quotation_list.js
@@ -13,11 +13,11 @@ frappe.listview_settings['Quotation'] = {
},
get_indicator: function(doc) {
- if(doc.status==="Submitted") {
+ if(doc.status==="Open") {
if (doc.valid_till && doc.valid_till < frappe.datetime.nowdate()) {
return [__("Expired"), "darkgrey", "valid_till,<," + frappe.datetime.nowdate()];
} else {
- return [__("Submitted"), "blue", "status,=,Submitted"];
+ return [__("Open"), "orange", "status,=,Open"];
}
} else if(doc.status==="Ordered") {
return [__("Ordered"), "green", "status,=,Ordered"];
diff --git a/erpnext/selling/doctype/quotation/test_quotation.py b/erpnext/selling/doctype/quotation/test_quotation.py
index 8bb8c618f29..7ee4a76ca66 100644
--- a/erpnext/selling/doctype/quotation/test_quotation.py
+++ b/erpnext/selling/doctype/quotation/test_quotation.py
@@ -3,7 +3,7 @@
from __future__ import unicode_literals
import frappe
-from frappe.utils import flt, add_days, nowdate, add_months
+from frappe.utils import flt, add_days, nowdate, add_months, getdate
import unittest
test_dependencies = ["Product Bundle"]
@@ -18,7 +18,7 @@ class TestQuotation(unittest.TestCase):
self.assertTrue(quotation.payment_schedule)
- def test_make_sales_order_terms_not_copied(self):
+ def test_make_sales_order_terms_copied(self):
from erpnext.selling.doctype.quotation.quotation import make_sales_order
quotation = frappe.copy_doc(test_records[0])
@@ -29,7 +29,7 @@ class TestQuotation(unittest.TestCase):
sales_order = make_sales_order(quotation.name)
- self.assertFalse(sales_order.get('payment_schedule'))
+ self.assertTrue(sales_order.get('payment_schedule'))
def test_make_sales_order_with_different_currency(self):
from erpnext.selling.doctype.quotation.quotation import make_sales_order
@@ -109,10 +109,10 @@ class TestQuotation(unittest.TestCase):
sales_order.insert()
self.assertEqual(sales_order.payment_schedule[0].payment_amount, 8906.00)
- self.assertEqual(sales_order.payment_schedule[0].due_date, quotation.transaction_date)
+ self.assertEqual(sales_order.payment_schedule[0].due_date, getdate(quotation.transaction_date))
self.assertEqual(sales_order.payment_schedule[1].payment_amount, 8906.00)
self.assertEqual(
- sales_order.payment_schedule[1].due_date, add_days(quotation.transaction_date, 30)
+ sales_order.payment_schedule[1].due_date, getdate(add_days(quotation.transaction_date, 30))
)
def test_valid_till(self):
diff --git a/erpnext/selling/doctype/sales_order/sales_order.js b/erpnext/selling/doctype/sales_order/sales_order.js
index 53b3e73f5e2..84c1693d20c 100644
--- a/erpnext/selling/doctype/sales_order/sales_order.js
+++ b/erpnext/selling/doctype/sales_order/sales_order.js
@@ -133,7 +133,7 @@ erpnext.selling.SalesOrderController = erpnext.selling.SellingController.extend(
if (this.frm.has_perm("submit")) {
// close
- if(flt(doc.per_delivered, 6) < 100 || flt(doc.per_billed) < 100) {
+ if(flt(doc.per_delivered, 6) < 100 || flt(doc.per_billed, 6) < 100) {
this.frm.add_custom_button(__('Close'),
function() { me.close_sales_order() }, __("Status"))
}
diff --git a/erpnext/selling/doctype/sales_order/sales_order.py b/erpnext/selling/doctype/sales_order/sales_order.py
index 184c6bd70d6..a490082c42c 100755
--- a/erpnext/selling/doctype/sales_order/sales_order.py
+++ b/erpnext/selling/doctype/sales_order/sales_order.py
@@ -574,8 +574,8 @@ def make_delivery_note(source_name, target_doc=None):
if item:
target.cost_center = frappe.db.get_value("Project", source_parent.project, "cost_center") \
- or item.get("selling_cost_center") \
- or item_group.get("selling_cost_center")
+ or item.get("buying_cost_center") \
+ or item_group.get("buying_cost_center")
target_doc = get_mapped_doc("Sales Order", source_name, {
"Sales Order": {
diff --git a/erpnext/stock/doctype/delivery_note/delivery_note.py b/erpnext/stock/doctype/delivery_note/delivery_note.py
index 23f7ed1889d..04f0c1c9a1e 100644
--- a/erpnext/stock/doctype/delivery_note/delivery_note.py
+++ b/erpnext/stock/doctype/delivery_note/delivery_note.py
@@ -443,7 +443,12 @@ def make_sales_invoice(source_name, target_doc=None):
def get_pending_qty(item_row):
pending_qty = item_row.qty - invoiced_qty_map.get(item_row.name, 0)
- returned_qty = flt(returned_qty_map.get(item_row.item_code, 0))
+
+ returned_qty = 0
+ if returned_qty_map.get(item_row.item_code) > 0:
+ returned_qty = flt(returned_qty_map.get(item_row.item_code, 0))
+ returned_qty_map[item_row.item_code] -= pending_qty
+
if returned_qty:
if returned_qty >= pending_qty:
pending_qty = 0
@@ -451,6 +456,7 @@ def make_sales_invoice(source_name, target_doc=None):
else:
pending_qty -= returned_qty
returned_qty = 0
+
return pending_qty, returned_qty
doc = get_mapped_doc("Delivery Note", source_name, {
diff --git a/erpnext/stock/doctype/delivery_trip/delivery_trip.py b/erpnext/stock/doctype/delivery_trip/delivery_trip.py
index 01b4734bf58..bc8c7493d5c 100644
--- a/erpnext/stock/doctype/delivery_trip/delivery_trip.py
+++ b/erpnext/stock/doctype/delivery_trip/delivery_trip.py
@@ -20,8 +20,7 @@ class DeliveryTrip(Document):
# Google Maps returns distances in meters by default
self.default_distance_uom = frappe.db.get_single_value("Global Defaults", "default_distance_unit") or "Meter"
self.uom_conversion_factor = frappe.db.get_value("UOM Conversion Factor",
- {"from_uom": "Meter", "to_uom": self.default_distance_uom},
- "value")
+ {"from_uom": "Meter", "to_uom": self.default_distance_uom}, "value")
def validate(self):
self.validate_stop_addresses()
@@ -139,7 +138,7 @@ class DeliveryTrip(Document):
# Include last leg in the final distance calculation
self.uom = self.default_distance_uom
total_distance = sum([leg.get("distance", {}).get("value", 0.0)
- for leg in directions.get("legs")]) # in meters
+ for leg in directions.get("legs")]) # in meters
self.total_distance = total_distance * self.uom_conversion_factor
else:
idx += len(route) - 1
@@ -358,8 +357,12 @@ def notify_customers(delivery_trip):
email_recipients = []
for stop in delivery_trip.delivery_stops:
- contact_info = frappe.db.get_value("Contact", stop.contact,
- ["first_name", "last_name", "email_id", "gender"], as_dict=1)
+ contact_info = frappe.db.get_value("Contact", stop.contact, ["first_name", "last_name", "email_id"], as_dict=1)
+
+ context.update({"items": []})
+ if stop.delivery_note:
+ items = frappe.get_all("Delivery Note Item", filters={"parent": stop.delivery_note, "docstatus": 1}, fields=["*"])
+ context.update({"items": items})
if contact_info and contact_info.email_id:
context.update(stop.as_dict())
@@ -369,9 +372,9 @@ def notify_customers(delivery_trip):
dispatch_template = frappe.get_doc("Email Template", dispatch_template_name)
frappe.sendmail(recipients=contact_info.email_id,
- subject=dispatch_template.subject,
- message=frappe.render_template(dispatch_template.response, context),
- attachments=get_attachments(stop))
+ subject=dispatch_template.subject,
+ message=frappe.render_template(dispatch_template.response, context),
+ attachments=get_attachments(stop))
stop.db_set("email_sent_to", contact_info.email_id)
email_recipients.append(contact_info.email_id)
@@ -388,9 +391,7 @@ def get_attachments(delivery_stop):
return []
dispatch_attachment = frappe.db.get_single_value("Delivery Settings", "dispatch_attachment")
- attachments = frappe.attach_print("Delivery Note",
- delivery_stop.delivery_note,
- file_name="Delivery Note",
- print_format=dispatch_attachment)
+ attachments = frappe.attach_print("Delivery Note", delivery_stop.delivery_note,
+ file_name="Delivery Note", print_format=dispatch_attachment)
return [attachments]
diff --git a/erpnext/stock/doctype/item/item.py b/erpnext/stock/doctype/item/item.py
index 16fd811fee3..c5697eda7a8 100644
--- a/erpnext/stock/doctype/item/item.py
+++ b/erpnext/stock/doctype/item/item.py
@@ -67,8 +67,6 @@ class Item(WebsiteGenerator):
from frappe.model.naming import set_name_by_naming_series
set_name_by_naming_series(self)
self.item_code = self.name
- elif not self.item_code:
- msgprint(_("Item Code is mandatory because Item is not automatically numbered"), raise_exception=1)
self.item_code = strip(self.item_code)
self.name = self.item_code
diff --git a/erpnext/stock/doctype/price_list/price_list.json b/erpnext/stock/doctype/price_list/price_list.json
index 6b447ee8834..56340fb05ca 100644
--- a/erpnext/stock/doctype/price_list/price_list.json
+++ b/erpnext/stock/doctype/price_list/price_list.json
@@ -1,5 +1,6 @@
{
"allow_copy": 0,
+ "allow_events_in_timeline": 0,
"allow_guest_to_view": 0,
"allow_import": 1,
"allow_rename": 1,
@@ -22,6 +23,7 @@
"collapsible": 0,
"columns": 0,
"default": "1",
+ "fetch_if_empty": 0,
"fieldname": "enabled",
"fieldtype": "Check",
"hidden": 0,
@@ -53,6 +55,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "sb_1",
"fieldtype": "Section Break",
"hidden": 0,
@@ -83,6 +86,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "price_list_name",
"fieldtype": "Data",
"hidden": 0,
@@ -116,6 +120,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "currency",
"fieldtype": "Link",
"hidden": 0,
@@ -148,6 +153,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "buying",
"fieldtype": "Check",
"hidden": 0,
@@ -179,6 +185,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "selling",
"fieldtype": "Check",
"hidden": 0,
@@ -210,7 +217,8 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
- "fieldname": "price_not_uom_dependant",
+ "fetch_if_empty": 0,
+ "fieldname": "price_not_uom_dependent",
"fieldtype": "Check",
"hidden": 0,
"ignore_user_permissions": 0,
@@ -219,7 +227,7 @@
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
- "label": "Price Not UOM Dependant",
+ "label": "Price Not UOM Dependent",
"length": 0,
"no_copy": 0,
"permlevel": 0,
@@ -242,6 +250,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "column_break_3",
"fieldtype": "Column Break",
"hidden": 0,
@@ -272,6 +281,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "countries",
"fieldtype": "Table",
"hidden": 0,
@@ -310,7 +320,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 1,
- "modified": "2018-08-29 06:35:16.546274",
+ "modified": "2019-06-24 17:16:28.027302",
"modified_by": "Administrator",
"module": "Stock",
"name": "Price List",
diff --git a/erpnext/stock/doctype/price_list/test_price_list_uom.js b/erpnext/stock/doctype/price_list/test_price_list_uom.js
index 526d0da97d8..7fbce7d59d2 100644
--- a/erpnext/stock/doctype/price_list/test_price_list_uom.js
+++ b/erpnext/stock/doctype/price_list/test_price_list_uom.js
@@ -7,7 +7,7 @@ QUnit.test("test price list with uom dependancy", function(assert) {
() => frappe.set_route('Form', 'Price List', 'Standard Buying'),
() => {
- cur_frm.set_value('price_not_uom_dependant','1');
+ cur_frm.set_value('price_not_uom_dependent','1');
frappe.timeout(1);
},
() => cur_frm.save(),
diff --git a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py
index 5c1f573c457..052118f67ea 100644
--- a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py
+++ b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py
@@ -4,11 +4,10 @@
from __future__ import unicode_literals
import frappe
-from frappe.utils import flt, cint, nowdate
+from frappe.utils import flt, cint, nowdate, getdate
from frappe import throw, _
import frappe.defaults
-from frappe.utils import getdate
from erpnext.controllers.buying_controller import BuyingController
from erpnext.accounts.utils import get_account_currency
from frappe.desk.notifications import clear_doctype_notifications
@@ -128,7 +127,7 @@ class PurchaseReceipt(BuyingController):
self.company, self.base_grand_total)
self.update_prevdoc_status()
- if self.per_billed < 100:
+ if cint(self.per_billed) < 100:
self.update_billing_status()
else:
self.status = "Completed"
diff --git a/erpnext/stock/doctype/stock_entry/test_stock_entry.py b/erpnext/stock/doctype/stock_entry/test_stock_entry.py
index c19228fea8b..dfcce5f820b 100644
--- a/erpnext/stock/doctype/stock_entry/test_stock_entry.py
+++ b/erpnext/stock/doctype/stock_entry/test_stock_entry.py
@@ -562,7 +562,7 @@ class TestStockEntry(unittest.TestCase):
for d in stock_entry.get("items"):
if d.item_code != "_Test FG Item 2":
rm_cost += flt(d.amount)
- fg_cost = filter(lambda x: x.item_code=="_Test FG Item 2", stock_entry.get("items"))[0].amount
+ fg_cost = list(filter(lambda x: x.item_code=="_Test FG Item 2", stock_entry.get("items")))[0].amount
self.assertEqual(fg_cost,
flt(rm_cost + bom_operation_cost + work_order.additional_operating_cost, 2))
diff --git a/erpnext/stock/get_item_details.py b/erpnext/stock/get_item_details.py
index 851088be948..0828a5ca543 100644
--- a/erpnext/stock/get_item_details.py
+++ b/erpnext/stock/get_item_details.py
@@ -834,12 +834,12 @@ def get_price_list_currency(price_list):
def get_price_list_uom_dependant(price_list):
if price_list:
result = frappe.db.get_value("Price List", {"name": price_list,
- "enabled": 1}, ["name", "price_not_uom_dependant"], as_dict=True)
+ "enabled": 1}, ["name", "price_not_uom_dependent"], as_dict=True)
if not result:
throw(_("Price List {0} is disabled or does not exist").format(price_list))
- return not result.price_not_uom_dependant
+ return not result.price_not_uom_dependent
def get_price_list_currency_and_exchange_rate(args):
diff --git a/erpnext/templates/pages/search_help.py b/erpnext/templates/pages/search_help.py
index 4a4b0dbd934..cd767b3099c 100644
--- a/erpnext/templates/pages/search_help.py
+++ b/erpnext/templates/pages/search_help.py
@@ -5,6 +5,7 @@ from jinja2 import utils
from html2text import html2text
from frappe.utils import sanitize_html
from frappe.utils.global_search import search
+from six import text_type
def get_context(context):
context.no_cache = 1
@@ -12,7 +13,7 @@ def get_context(context):
query = str(utils.escape(sanitize_html(frappe.form_dict.q)))
context.title = _('Help Results for')
context.query = query
-
+
context.route = '/search_help'
d = frappe._dict()
d.results_sections = get_help_results_sections(query)
@@ -73,7 +74,7 @@ def prepare_api_results(api, topics_data):
for topic in topics_data:
route = api.base_url + '/' + (api.post_route + '/' if api.post_route else "")
for key in api.post_route_key_list.split(','):
- route += unicode(topic[key])
+ route += text_type(topic[key])
results.append(frappe._dict({
'title': topic[api.post_title_key],
diff --git a/travis/run-tests.sh b/travis/run-tests.sh
new file mode 100755
index 00000000000..7cfd64833b7
--- /dev/null
+++ b/travis/run-tests.sh
@@ -0,0 +1,12 @@
+#!/bin/bash
+
+set -e
+
+if [[ $TEST_TYPE == 'Server Side Test' ]]; then
+ bench run-tests --app erpnext --coverage
+
+elif [[ $TEST_TYPE == 'Patch Test' ]]; then
+ wget http://build.erpnext.com/20171108_190013_955977f8_database.sql.gz
+ bench --force restore ~/frappe-bench/20171108_190013_955977f8_database.sql.gz --mariadb-root-password travis
+ bench migrate
+fi