Merge branch 'hotfix'
diff --git a/erpnext/__init__.py b/erpnext/__init__.py
index e510e38..783c4b4 100644
--- a/erpnext/__init__.py
+++ b/erpnext/__init__.py
@@ -5,7 +5,7 @@
from erpnext.hooks import regional_overrides
from frappe.utils import getdate
-__version__ = '11.1.17'
+__version__ = '11.1.18'
def get_default_company(user=None):
'''Get default company for user'''
diff --git a/erpnext/accounts/deferred_revenue.py b/erpnext/accounts/deferred_revenue.py
index e638fc7..3afb4bc 100644
--- a/erpnext/accounts/deferred_revenue.py
+++ b/erpnext/accounts/deferred_revenue.py
@@ -2,9 +2,9 @@
import frappe
from frappe import _
-from frappe.utils import date_diff, add_months, today, getdate, add_days, flt
+from frappe.utils import date_diff, add_months, today, getdate, add_days, flt, get_last_day
from erpnext.accounts.utils import get_account_currency
-from erpnext.accounts.general_ledger import make_gl_entries
+from frappe.email import sendmail_to_system_managers
def validate_service_stop_date(doc):
''' Validates service_stop_date for Purchase Invoice and Sales Invoice '''
@@ -33,47 +33,49 @@
frappe.throw(_("Cannot change Service Stop Date for item in row {0}".format(item.idx)))
def convert_deferred_expense_to_expense(start_date=None, end_date=None):
+ # book the expense/income on the last day, but it will be trigger on the 1st of month at 12:00 AM
+ if not start_date:
+ start_date = add_months(today(), -1)
+ if not end_date:
+ end_date = add_days(today(), -1)
+
# check for the purchase invoice for which GL entries has to be done
invoices = frappe.db.sql_list('''
- select distinct parent from `tabPurchase Invoice Item` where service_start_date<=%s and service_end_date>=%s
+ select distinct parent from `tabPurchase Invoice Item`
+ where service_start_date<=%s and service_end_date>=%s
and enable_deferred_expense = 1 and docstatus = 1 and ifnull(amount, 0) > 0
- ''', (end_date or today(), start_date or add_months(today(), -1)))
+ ''', (end_date, start_date))
# For each invoice, book deferred expense
for invoice in invoices:
doc = frappe.get_doc("Purchase Invoice", invoice)
- book_deferred_income_or_expense(doc, start_date, end_date)
+ book_deferred_income_or_expense(doc, end_date)
def convert_deferred_revenue_to_income(start_date=None, end_date=None):
+ # book the expense/income on the last day, but it will be trigger on the 1st of month at 12:00 AM
+ if not start_date:
+ start_date = add_months(today(), -1)
+ if not end_date:
+ end_date = add_days(today(), -1)
+
# check for the sales invoice for which GL entries has to be done
invoices = frappe.db.sql_list('''
- select distinct parent from `tabSales Invoice Item` where service_start_date<=%s and service_end_date>=%s
+ select distinct parent from `tabSales Invoice Item`
+ where service_start_date<=%s and service_end_date>=%s
and enable_deferred_revenue = 1 and docstatus = 1 and ifnull(amount, 0) > 0
- ''', (end_date or today(), start_date or add_months(today(), -1)))
+ ''', (end_date, start_date))
- # For each invoice, book deferred revenue
for invoice in invoices:
doc = frappe.get_doc("Sales Invoice", invoice)
- book_deferred_income_or_expense(doc, start_date, end_date)
+ book_deferred_income_or_expense(doc, end_date)
-def get_booking_dates(doc, item, start_date=None, end_date=None):
+def get_booking_dates(doc, item, posting_date=None):
+ if not posting_date:
+ posting_date = add_days(today(), -1)
+
+ last_gl_entry = False
+
deferred_account = "deferred_revenue_account" if doc.doctype=="Sales Invoice" else "deferred_expense_account"
- last_gl_entry, skip = False, False
-
- booking_end_date = getdate(add_days(today(), -1) if not end_date else end_date)
- if booking_end_date < item.service_start_date or \
- (item.service_stop_date and booking_end_date.month > item.service_stop_date.month):
- return None, None, None, True
- elif booking_end_date >= item.service_end_date:
- last_gl_entry = True
- booking_end_date = item.service_end_date
- elif item.service_stop_date and item.service_stop_date <= booking_end_date:
- last_gl_entry = True
- booking_end_date = item.service_stop_date
-
- booking_start_date = getdate(add_months(today(), -1) if not start_date else start_date)
- booking_start_date = booking_start_date \
- if booking_start_date > item.service_start_date else item.service_start_date
prev_gl_entry = frappe.db.sql('''
select name, posting_date from `tabGL Entry` where company=%s and account=%s and
@@ -81,17 +83,28 @@
order by posting_date desc limit 1
''', (doc.company, item.get(deferred_account), doc.doctype, doc.name, item.name), as_dict=True)
- if not prev_gl_entry and item.service_start_date < booking_start_date:
- booking_start_date = item.service_start_date
- elif prev_gl_entry:
- booking_start_date = getdate(add_days(prev_gl_entry[0].posting_date, 1))
- skip = True if booking_start_date > booking_end_date else False
+ if prev_gl_entry:
+ start_date = getdate(add_days(prev_gl_entry[0].posting_date, 1))
+ else:
+ start_date = item.service_start_date
- return last_gl_entry, booking_start_date, booking_end_date, skip
+ end_date = get_last_day(start_date)
+ if end_date >= item.service_end_date:
+ end_date = item.service_end_date
+ last_gl_entry = True
+ elif item.service_stop_date and end_date >= item.service_stop_date:
+ end_date = item.service_stop_date
+ last_gl_entry = True
-def calculate_amount_and_base_amount(doc, item, last_gl_entry, total_days, total_booking_days):
- account_currency = get_account_currency(item.expense_account)
+ if end_date > getdate(posting_date):
+ end_date = posting_date
+ if getdate(start_date) <= getdate(end_date):
+ return start_date, end_date, last_gl_entry
+ else:
+ return None, None, None
+
+def calculate_amount(doc, item, last_gl_entry, total_days, total_booking_days, account_currency):
if doc.doctype == "Sales Invoice":
total_credit_debit, total_credit_debit_currency = "debit", "debit_in_account_currency"
deferred_account = "deferred_revenue_account"
@@ -123,28 +136,15 @@
return amount, base_amount
-def book_deferred_income_or_expense(doc, start_date=None, end_date=None):
- # book the expense/income on the last day, but it will be trigger on the 1st of month at 12:00 AM
- # start_date: 1st of the last month or the start date
- # end_date: end_date or today-1
+def book_deferred_income_or_expense(doc, posting_date=None):
enable_check = "enable_deferred_revenue" \
if doc.doctype=="Sales Invoice" else "enable_deferred_expense"
- gl_entries = []
- for item in doc.get('items'):
- if not item.get(enable_check): continue
-
- skip = False
- last_gl_entry, booking_start_date, booking_end_date, skip = \
- get_booking_dates(doc, item, start_date, end_date)
-
- if skip: continue
- total_days = date_diff(item.service_end_date, item.service_start_date) + 1
- total_booking_days = date_diff(booking_end_date, booking_start_date) + 1
+ def _book_deferred_revenue_or_expense(item):
+ start_date, end_date, last_gl_entry = get_booking_dates(doc, item, posting_date=posting_date)
+ if not (start_date and end_date): return
account_currency = get_account_currency(item.expense_account)
- amount, base_amount = calculate_amount_and_base_amount(doc, item, last_gl_entry, total_days, total_booking_days)
-
if doc.doctype == "Sales Invoice":
against, project = doc.customer, doc.project
credit_account, debit_account = item.income_account, item.deferred_revenue_account
@@ -152,36 +152,62 @@
against, project = doc.supplier, item.project
credit_account, debit_account = item.deferred_expense_account, item.expense_account
- # GL Entry for crediting the amount in the deferred expense
- gl_entries.append(
- doc.get_gl_dict({
- "account": credit_account,
- "against": against,
- "credit": base_amount,
- "credit_in_account_currency": amount,
- "cost_center": item.cost_center,
- "voucher_detail_no": item.name,
- 'posting_date': booking_end_date,
- 'project': project
- }, account_currency)
- )
- # GL Entry to debit the amount from the expense
- gl_entries.append(
- doc.get_gl_dict({
- "account": debit_account,
- "against": against,
- "debit": base_amount,
- "debit_in_account_currency": amount,
- "cost_center": item.cost_center,
- "voucher_detail_no": item.name,
- 'posting_date': booking_end_date,
- 'project': project
- }, account_currency)
- )
+ total_days = date_diff(item.service_end_date, item.service_start_date) + 1
+ total_booking_days = date_diff(end_date, start_date) + 1
+
+ amount, base_amount = calculate_amount(doc, item, last_gl_entry,
+ total_days, total_booking_days, account_currency)
+
+ make_gl_entries(doc, credit_account, debit_account, against,
+ amount, base_amount, end_date, project, account_currency, item.cost_center, item.name)
+
+ if getdate(end_date) < getdate(posting_date) and not last_gl_entry:
+ _book_deferred_revenue_or_expense(item)
+
+
+ for item in doc.get('items'):
+ if item.get(enable_check):
+ _book_deferred_revenue_or_expense(item)
+
+def make_gl_entries(doc, credit_account, debit_account, against,
+ amount, base_amount, posting_date, project, account_currency, cost_center, voucher_detail_no):
+ # GL Entry for crediting the amount in the deferred expense
+ from erpnext.accounts.general_ledger import make_gl_entries
+
+ gl_entries = []
+ gl_entries.append(
+ doc.get_gl_dict({
+ "account": credit_account,
+ "against": against,
+ "credit": base_amount,
+ "credit_in_account_currency": amount,
+ "cost_center": cost_center,
+ "voucher_detail_no": voucher_detail_no,
+ 'posting_date': posting_date,
+ 'project': project
+ }, account_currency)
+ )
+ # GL Entry to debit the amount from the expense
+ gl_entries.append(
+ doc.get_gl_dict({
+ "account": debit_account,
+ "against": against,
+ "debit": base_amount,
+ "debit_in_account_currency": amount,
+ "cost_center": cost_center,
+ "voucher_detail_no": voucher_detail_no,
+ 'posting_date': posting_date,
+ 'project': project
+ }, account_currency)
+ )
+
if gl_entries:
try:
make_gl_entries(gl_entries, cancel=(doc.docstatus == 2), merge_entries=True)
frappe.db.commit()
except:
frappe.db.rollback()
- frappe.log_error(message = frappe.get_traceback(), title = _("Error while processing deferred accounting for {0}").format(doc.name))
\ No newline at end of file
+ title = _("Error while processing deferred accounting for {0}").format(doc.name)
+ traceback = frappe.get_traceback()
+ frappe.log_error(message=traceback , title=title)
+ sendmail_to_system_managers(title, traceback)
\ No newline at end of file
diff --git a/erpnext/accounts/doctype/account/account.py b/erpnext/accounts/doctype/account/account.py
index ac74b45..3d9604d 100644
--- a/erpnext/accounts/doctype/account/account.py
+++ b/erpnext/accounts/doctype/account/account.py
@@ -112,6 +112,8 @@
["company", "name"], as_dict=True):
acc_name_map[d["company"]] = d["name"]
+ if not acc_name_map: return
+
for company in descendants:
doc = frappe.copy_doc(self)
doc.flags.ignore_root_company_validation = True
diff --git a/erpnext/accounts/doctype/account/test_account.py b/erpnext/accounts/doctype/account/test_account.py
index 4c057d9..90177c6 100644
--- a/erpnext/accounts/doctype/account/test_account.py
+++ b/erpnext/accounts/doctype/account/test_account.py
@@ -144,7 +144,7 @@
# related to Account Inventory Integration
["_Test Account Stock In Hand", "Current Assets", 0, None, None],
-
+
# fixed asset depreciation
["_Test Fixed Asset", "Current Assets", 0, "Fixed Asset", None],
["_Test Accumulated Depreciations", "Current Assets", 0, None, None],
@@ -181,13 +181,17 @@
return account
def create_account(**kwargs):
- account = frappe.get_doc(dict(
- doctype = "Account",
- account_name = kwargs.get('account_name'),
- account_type = kwargs.get('account_type'),
- parent_account = kwargs.get('parent_account'),
- company = kwargs.get('company')
- ))
-
- account.save()
- return account.name
+ account = frappe.db.get_value("Account", filters={"account_name": kwargs.get("account_name"), "company": kwargs.get("company")})
+ if account:
+ return account
+ else:
+ account = frappe.get_doc(dict(
+ doctype = "Account",
+ account_name = kwargs.get('account_name'),
+ account_type = kwargs.get('account_type'),
+ parent_account = kwargs.get('parent_account'),
+ company = kwargs.get('company')
+ ))
+
+ account.save()
+ return account.name
diff --git a/erpnext/accounts/doctype/bank_reconciliation/bank_reconciliation.py b/erpnext/accounts/doctype/bank_reconciliation/bank_reconciliation.py
index dafa330..fae5213 100644
--- a/erpnext/accounts/doctype/bank_reconciliation/bank_reconciliation.py
+++ b/erpnext/accounts/doctype/bank_reconciliation/bank_reconciliation.py
@@ -23,36 +23,36 @@
journal_entries = frappe.db.sql("""
- select
- "Journal Entry" as payment_document, t1.name as payment_entry,
- t1.cheque_no as cheque_number, t1.cheque_date,
+ select
+ "Journal Entry" as payment_document, t1.name as payment_entry,
+ t1.cheque_no as cheque_number, t1.cheque_date,
sum(t2.debit_in_account_currency) as debit, sum(t2.credit_in_account_currency) as credit,
- t1.posting_date, t2.against_account, t1.clearance_date, t2.account_currency
+ t1.posting_date, t2.against_account, t1.clearance_date, t2.account_currency
from
`tabJournal Entry` t1, `tabJournal Entry Account` t2
where
t2.parent = t1.name and t2.account = %s and t1.docstatus=1
- and t1.posting_date >= %s and t1.posting_date <= %s
+ and t1.posting_date >= %s and t1.posting_date <= %s
and ifnull(t1.is_opening, 'No') = 'No' {0}
group by t2.account, t1.name
order by t1.posting_date ASC, t1.name DESC
""".format(condition), (self.bank_account, self.from_date, self.to_date), as_dict=1)
payment_entries = frappe.db.sql("""
- select
- "Payment Entry" as payment_document, name as payment_entry,
- reference_no as cheque_number, reference_date as cheque_date,
- if(paid_from=%(account)s, paid_amount, "") as credit,
- if(paid_from=%(account)s, "", received_amount) as debit,
+ select
+ "Payment Entry" as payment_document, name as payment_entry,
+ reference_no as cheque_number, reference_date as cheque_date,
+ if(paid_from=%(account)s, paid_amount, 0) as credit,
+ if(paid_from=%(account)s, 0, received_amount) as debit,
posting_date, ifnull(party,if(paid_from=%(account)s,paid_to,paid_from)) as against_account, clearance_date,
if(paid_to=%(account)s, paid_to_account_currency, paid_from_account_currency) as account_currency
from `tabPayment Entry`
where
(paid_from=%(account)s or paid_to=%(account)s) and docstatus=1
and posting_date >= %(from)s and posting_date <= %(to)s {0}
- order by
+ order by
posting_date ASC, name DESC
- """.format(condition),
+ """.format(condition),
{"account":self.bank_account, "from":self.from_date, "to":self.to_date}, as_dict=1)
pos_entries = []
@@ -80,7 +80,7 @@
for d in entries:
row = self.append('payment_entries', {})
- amount = d.get('debit', 0) - d.get('credit', 0)
+ amount = flt(d.get('debit', 0)) - flt(d.get('credit', 0))
formatted_amount = fmt_money(abs(amount), 2, d.account_currency)
d.amount = formatted_amount + " " + (_("Dr") if amount > 0 else _("Cr"))
@@ -107,10 +107,10 @@
d.clearance_date = None
frappe.db.set_value(d.payment_document, d.payment_entry, "clearance_date", d.clearance_date)
- frappe.db.sql("""update `tab{0}` set clearance_date = %s, modified = %s
- where name=%s""".format(d.payment_document),
+ frappe.db.sql("""update `tab{0}` set clearance_date = %s, modified = %s
+ where name=%s""".format(d.payment_document),
(d.clearance_date, nowdate(), d.payment_entry))
-
+
clearance_date_updated = True
if clearance_date_updated:
diff --git a/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py
index f9364e2..45a2950 100644
--- a/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py
+++ b/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py
@@ -14,8 +14,9 @@
from erpnext.exceptions import InvalidAccountCurrency, InvalidCurrency
from erpnext.stock.doctype.serial_no.serial_no import SerialNoWarehouseError
from frappe.model.naming import make_autoname
-from erpnext.accounts.doctype.account.test_account import get_inventory_account
+from erpnext.accounts.doctype.account.test_account import get_inventory_account, create_account
from erpnext.controllers.taxes_and_totals import get_itemised_tax_breakup_data
+from erpnext.stock.doctype.item.test_item import create_item
from six import iteritems
class TestSalesInvoice(unittest.TestCase):
def make(self):
@@ -762,7 +763,7 @@
set_perpetual_inventory(0)
frappe.db.sql("delete from `tabPOS Profile`")
-
+
def test_pos_si_without_payment(self):
set_perpetual_inventory()
make_pos_profile()
@@ -1514,6 +1515,56 @@
accounts_settings.allow_cost_center_in_entry_of_bs_account = 0
accounts_settings.save()
+ def test_deferred_revenue(self):
+ deferred_account = create_account(account_name="Deferred Revenue",
+ parent_account="Current Liabilities - _TC", company="_Test Company")
+
+ item = create_item("_Test Item for Deferred Accounting")
+ item.enable_deferred_revenue = 1
+ item.deferred_revenue_account = deferred_account
+ item.no_of_months = 12
+ item.save()
+
+ si = create_sales_invoice(item=item.name, posting_date="2019-01-10", do_not_submit=True)
+ si.items[0].enable_deferred_revenue = 1
+ si.items[0].service_start_date = "2019-01-10"
+ si.items[0].service_end_date = "2019-03-15"
+ si.items[0].deferred_revenue_account = deferred_account
+ si.save()
+ si.submit()
+
+ from erpnext.accounts.deferred_revenue import convert_deferred_revenue_to_income
+ convert_deferred_revenue_to_income(start_date="2019-01-01", end_date="2019-01-31")
+
+ expected_gle = [
+ [deferred_account, 33.85, 0.0, "2019-01-31"],
+ ["Sales - _TC", 0.0, 33.85, "2019-01-31"]
+ ]
+
+ self.check_gl_entries(si.name, expected_gle, "2019-01-10")
+
+ convert_deferred_revenue_to_income(start_date="2019-01-01", end_date="2019-03-31")
+
+ expected_gle = [
+ [deferred_account, 43.08, 0.0, "2019-02-28"],
+ ["Sales - _TC", 0.0, 43.08, "2019-02-28"],
+ [deferred_account, 23.07, 0.0, "2019-03-15"],
+ ["Sales - _TC", 0.0, 23.07, "2019-03-15"]
+ ]
+
+ self.check_gl_entries(si.name, expected_gle, "2019-01-31")
+
+ def check_gl_entries(self, voucher_no, expected_gle, posting_date):
+ gl_entries = frappe.db.sql("""select account, debit, credit, posting_date
+ from `tabGL Entry`
+ where voucher_type='Sales Invoice' and voucher_no=%s and posting_date > %s
+ order by posting_date asc, account asc""", (voucher_no, posting_date), as_dict=1)
+
+ for i, gle in enumerate(gl_entries):
+ self.assertEqual(expected_gle[i][0], gle.account)
+ self.assertEqual(expected_gle[i][1], gle.debit)
+ self.assertEqual(expected_gle[i][2], gle.credit)
+ self.assertEqual(getdate(expected_gle[i][3]), gle.posting_date)
def create_sales_invoice(**args):
si = frappe.new_doc("Sales Invoice")
@@ -1611,4 +1662,4 @@
if against_voucher_type == 'Purchase Invoice':
bal = bal * -1
- return bal
+ return bal
\ No newline at end of file
diff --git a/erpnext/accounts/report/accounts_receivable_summary/accounts_receivable_summary.py b/erpnext/accounts/report/accounts_receivable_summary/accounts_receivable_summary.py
index ffd1994..244aa8a 100644
--- a/erpnext/accounts/report/accounts_receivable_summary/accounts_receivable_summary.py
+++ b/erpnext/accounts/report/accounts_receivable_summary/accounts_receivable_summary.py
@@ -146,6 +146,7 @@
row += [partywise_advance_amount.get(party, 0)]
+ paid_amt = 0
if party_dict.paid_amt > 0:
paid_amt = flt(party_dict.paid_amt - partywise_advance_amount.get(party, 0))
diff --git a/erpnext/healthcare/doctype/healthcare_service_unit_type/healthcare_service_unit_type.js b/erpnext/healthcare/doctype/healthcare_service_unit_type/healthcare_service_unit_type.js
index 84255b29..288ebc4 100644
--- a/erpnext/healthcare/doctype/healthcare_service_unit_type/healthcare_service_unit_type.js
+++ b/erpnext/healthcare/doctype/healthcare_service_unit_type/healthcare_service_unit_type.js
@@ -49,7 +49,7 @@
var disable = function(frm){
var doc = frm.doc;
frappe.call({
- method: "erpnext.healthcare.doctype.healthcare_service_unit_type.healthcare_service_unit_type.disable_enable",
+ method: "erpnext.healthcare.doctype.healthcare_service_unit_type.healthcare_service_unit_type.disable_enable",
args: {status: 1, doc_name: doc.name, item: doc.item, is_billable: doc.is_billable},
callback: function(){
cur_frm.reload_doc();
@@ -60,7 +60,7 @@
var enable = function(frm){
var doc = frm.doc;
frappe.call({
- method: "erpnext.healthcare.doctype.healthcare_service_unit_type.healthcare_service_unit_type.disable_enable",
+ method: "erpnext.healthcare.doctype.healthcare_service_unit_type.healthcare_service_unit_type.disable_enable",
args: {status: 0, doc_name: doc.name, item: doc.item, is_billable: doc.is_billable},
callback: function(){
cur_frm.reload_doc();
diff --git a/erpnext/healthcare/doctype/healthcare_service_unit_type/healthcare_service_unit_type.py b/erpnext/healthcare/doctype/healthcare_service_unit_type/healthcare_service_unit_type.py
index 727d035..6504994 100644
--- a/erpnext/healthcare/doctype/healthcare_service_unit_type/healthcare_service_unit_type.py
+++ b/erpnext/healthcare/doctype/healthcare_service_unit_type/healthcare_service_unit_type.py
@@ -111,7 +111,7 @@
frappe.db.set_value("Healthcare Service Unit Type", doc_name, "item_code", item_code)
@frappe.whitelist()
-def disable_enable(status, doc_name, item, is_billable):
+def disable_enable(status, doc_name, item=None, is_billable=None):
frappe.db.set_value("Healthcare Service Unit Type", doc_name, "disabled", status)
if(is_billable == 1):
frappe.db.set_value("Item", item, "disabled", status)
diff --git a/erpnext/hr/doctype/salary_slip/salary_slip.py b/erpnext/hr/doctype/salary_slip/salary_slip.py
index 3fd266b..684f348 100644
--- a/erpnext/hr/doctype/salary_slip/salary_slip.py
+++ b/erpnext/hr/doctype/salary_slip/salary_slip.py
@@ -441,7 +441,7 @@
def calculate_net_pay(self):
if self.salary_structure:
self.calculate_component_amounts()
-
+
disable_rounded_total = cint(frappe.db.get_value("Global Defaults", None, "disable_rounded_total"))
precision = frappe.defaults.get_global_default("currency_precision")
self.total_deduction = 0
@@ -452,10 +452,10 @@
self.set_loan_repayment()
- self.net_pay = flt(self.gross_pay) - (flt(self.total_deduction) + flt(self.total_loan_repayment))
+ self.net_pay = (flt(self.gross_pay) - (flt(self.total_deduction) + flt(self.total_loan_repayment))) * flt(self.payment_days / self.total_working_days)
self.rounded_total = rounded(self.net_pay,
self.precision("net_pay") if disable_rounded_total else 0)
-
+
if self.net_pay < 0:
frappe.throw(_("Net Pay cannnot be negative"))
diff --git a/erpnext/manufacturing/doctype/bom/bom.py b/erpnext/manufacturing/doctype/bom/bom.py
index db94350..c65693b 100644
--- a/erpnext/manufacturing/doctype/bom/bom.py
+++ b/erpnext/manufacturing/doctype/bom/bom.py
@@ -618,7 +618,7 @@
is_stock_item=is_stock_item,
qty_field="stock_qty",
select_columns = """, bom_item.source_warehouse, bom_item.operation, bom_item.include_item_in_manufacturing,
- (Select idx from `tabBOM Item` where item_code = bom_item.item_code and parent = %(parent)s ) as idx""")
+ (Select idx from `tabBOM Item` where item_code = bom_item.item_code and parent = %(parent)s limit 1) as idx""")
items = frappe.db.sql(query, { "parent": bom, "qty": qty, "bom": bom, "company": company }, as_dict=True)
elif fetch_scrap_items:
diff --git a/erpnext/projects/doctype/task/task.py b/erpnext/projects/doctype/task/task.py
index fffa9c1..1230278 100755
--- a/erpnext/projects/doctype/task/task.py
+++ b/erpnext/projects/doctype/task/task.py
@@ -159,6 +159,13 @@
self.update_nsm_model()
+ def update_status(self):
+ if self.status not in ('Cancelled', 'Closed') and self.exp_end_date:
+ from datetime import datetime
+ if self.exp_end_date < datetime.now().date():
+ self.db_set('status', 'Overdue')
+ self.update_project()
+
@frappe.whitelist()
def check_if_child_exists(name):
child_tasks = frappe.get_all("Task", filters={"parent_task": name})
@@ -186,10 +193,9 @@
task.save()
def set_tasks_as_overdue():
- frappe.db.sql("""update tabTask set `status`='Overdue'
- where exp_end_date is not null
- and exp_end_date < CURDATE()
- and `status` not in ('Closed', 'Cancelled')""")
+ tasks = frappe.get_all("Task", filters={'status':['not in',['Cancelled', 'Closed']]})
+ for task in tasks:
+ frappe.get_doc("Task", task.name).update_status()
@frappe.whitelist()
def get_children(doctype, parent, task=None, project=None, is_root=False):
diff --git a/erpnext/projects/doctype/task/test_task.py b/erpnext/projects/doctype/task/test_task.py
index 9971946..b733f67 100644
--- a/erpnext/projects/doctype/task/test_task.py
+++ b/erpnext/projects/doctype/task/test_task.py
@@ -117,4 +117,4 @@
if save:
task.save()
- return task
\ No newline at end of file
+ return task
diff --git a/erpnext/setup/doctype/brand/test_records.json b/erpnext/setup/doctype/brand/test_records.json
index d2a4ad4..e4f892e 100644
--- a/erpnext/setup/doctype/brand/test_records.json
+++ b/erpnext/setup/doctype/brand/test_records.json
@@ -1,6 +1,6 @@
[
{
- "brand": "_Test Brand",
+ "brand": "_Test Brand",
"doctype": "Brand"
}
]
\ No newline at end of file
diff --git a/erpnext/stock/doctype/item/item.py b/erpnext/stock/doctype/item/item.py
index bd06688..8321b3e 100644
--- a/erpnext/stock/doctype/item/item.py
+++ b/erpnext/stock/doctype/item/item.py
@@ -758,6 +758,9 @@
d.conversion_factor = value
def validate_attributes(self):
+ if not self.variant_based_on:
+ self.variant_based_on = 'Item Attribute'
+
if (self.has_variants or self.variant_of) and self.variant_based_on == 'Item Attribute':
attributes = []
if not self.attributes:
@@ -780,7 +783,7 @@
variant = get_variant(self.variant_of, args, self.name)
if variant:
frappe.throw(_("Item variant {0} exists with same attributes")
- .format(variant), ItemVariantExistsError)
+ .format(variant), ItemVariantExistsError)
validate_item_variant_attributes(self, args)
diff --git a/erpnext/stock/doctype/item/test_item.py b/erpnext/stock/doctype/item/test_item.py
index d02559e..ac499e0 100644
--- a/erpnext/stock/doctype/item/test_item.py
+++ b/erpnext/stock/doctype/item/test_item.py
@@ -17,7 +17,7 @@
from six import iteritems
test_ignore = ["BOM"]
-test_dependencies = ["Warehouse", "Item Group"]
+test_dependencies = ["Warehouse", "Item Group", "Brand"]
def make_item(item_code, properties=None):
if frappe.db.exists("Item", item_code):
@@ -393,3 +393,6 @@
"company": "_Test Company"
})
item.save()
+ else:
+ item = frappe.get_doc("Item", item_code)
+ return item
diff --git a/erpnext/templates/pages/regional/india/update-gstin.html b/erpnext/templates/pages/regional/india/update-gstin.html
index 3d9ab5d..d738fb4 100644
--- a/erpnext/templates/pages/regional/india/update-gstin.html
+++ b/erpnext/templates/pages/regional/india/update-gstin.html
@@ -32,7 +32,7 @@
<p class='text-muted'>Please update your GSTIN for us to issue correct tax invoice</p>
<form method='GET' action='/regional/india/update-gstin.html'>
<input type='hidden' value='{{ party.name }}' name='party'>
- {% for address in party.__onload.addr_list %}
+ {% for address in party.get_onload('addr_list') %}
<div class='bordered' style='max-width: 300px; margin-bottom: 15px;'>
{{ address.display }}
<p><input type='text' class='form-control'