Merge branch 'develop'
This commit is contained in:
commit
bd4030bf85
@ -565,16 +565,17 @@ class TestSalesInvoice(unittest.TestCase):
|
|||||||
where against_invoice=%s""", si.doc.name))
|
where against_invoice=%s""", si.doc.name))
|
||||||
|
|
||||||
def test_recurring_invoice(self):
|
def test_recurring_invoice(self):
|
||||||
from webnotes.utils import now_datetime, get_first_day, get_last_day, add_to_date
|
from webnotes.utils import get_first_day, get_last_day, add_to_date, nowdate, getdate
|
||||||
today = now_datetime().date()
|
from accounts.utils import get_fiscal_year
|
||||||
|
today = nowdate()
|
||||||
base_si = webnotes.bean(copy=test_records[0])
|
base_si = webnotes.bean(copy=test_records[0])
|
||||||
base_si.doc.fields.update({
|
base_si.doc.fields.update({
|
||||||
"convert_into_recurring_invoice": 1,
|
"convert_into_recurring_invoice": 1,
|
||||||
"recurring_type": "Monthly",
|
"recurring_type": "Monthly",
|
||||||
"notification_email_address": "test@example.com, test1@example.com, test2@example.com",
|
"notification_email_address": "test@example.com, test1@example.com, test2@example.com",
|
||||||
"repeat_on_day_of_month": today.day,
|
"repeat_on_day_of_month": getdate(today).day,
|
||||||
"posting_date": today,
|
"posting_date": today,
|
||||||
|
"fiscal_year": get_fiscal_year(today)[0],
|
||||||
"invoice_period_from_date": get_first_day(today),
|
"invoice_period_from_date": get_first_day(today),
|
||||||
"invoice_period_to_date": get_last_day(today)
|
"invoice_period_to_date": get_last_day(today)
|
||||||
})
|
})
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
import webnotes
|
import webnotes
|
||||||
from webnotes.utils import nowdate, nowtime, cstr, flt, now, getdate, add_months
|
from webnotes.utils import nowdate, cstr, flt, now, getdate, add_months
|
||||||
from webnotes.model.doc import addchild
|
from webnotes.model.doc import addchild
|
||||||
from webnotes import msgprint, _
|
from webnotes import msgprint, _
|
||||||
from webnotes.utils import formatdate
|
from webnotes.utils import formatdate
|
||||||
@ -64,7 +64,6 @@ def get_balance_on(account=None, date=None):
|
|||||||
try:
|
try:
|
||||||
year_start_date = get_fiscal_year(date, verbose=0)[1]
|
year_start_date = get_fiscal_year(date, verbose=0)[1]
|
||||||
except FiscalYearError, e:
|
except FiscalYearError, e:
|
||||||
from webnotes.utils import getdate
|
|
||||||
if getdate(date) > getdate(nowdate()):
|
if getdate(date) > getdate(nowdate()):
|
||||||
# if fiscal year not found and the date is greater than today
|
# if fiscal year not found and the date is greater than today
|
||||||
# get fiscal year for today's date and its corresponding year start date
|
# get fiscal year for today's date and its corresponding year start date
|
||||||
@ -222,17 +221,26 @@ def get_cost_center_list(doctype, txt, searchfield, start, page_len, filters):
|
|||||||
tuple(filter_values + ["%%%s%%" % txt, start, page_len]))
|
tuple(filter_values + ["%%%s%%" % txt, start, page_len]))
|
||||||
|
|
||||||
def remove_against_link_from_jv(ref_type, ref_no, against_field):
|
def remove_against_link_from_jv(ref_type, ref_no, against_field):
|
||||||
webnotes.conn.sql("""update `tabJournal Voucher Detail` set `%s`=null,
|
linked_jv = webnotes.conn.sql_list("""select parent from `tabJournal Voucher Detail`
|
||||||
modified=%s, modified_by=%s
|
where `%s`=%s and docstatus < 2""" % (against_field, "%s"), (ref_no))
|
||||||
where `%s`=%s and docstatus < 2""" % (against_field, "%s", "%s", against_field, "%s"),
|
|
||||||
(now(), webnotes.session.user, ref_no))
|
if linked_jv:
|
||||||
|
webnotes.conn.sql("""update `tabJournal Voucher Detail` set `%s`=null,
|
||||||
|
modified=%s, modified_by=%s
|
||||||
|
where `%s`=%s and docstatus < 2""" % (against_field, "%s", "%s", against_field, "%s"),
|
||||||
|
(now(), webnotes.session.user, ref_no))
|
||||||
|
|
||||||
webnotes.conn.sql("""update `tabGL Entry`
|
webnotes.conn.sql("""update `tabGL Entry`
|
||||||
set against_voucher_type=null, against_voucher=null,
|
set against_voucher_type=null, against_voucher=null,
|
||||||
modified=%s, modified_by=%s
|
modified=%s, modified_by=%s
|
||||||
where against_voucher_type=%s and against_voucher=%s
|
where against_voucher_type=%s and against_voucher=%s
|
||||||
and voucher_no != ifnull(against_voucher, '')""",
|
and voucher_no != ifnull(against_voucher, '')""",
|
||||||
(now(), webnotes.session.user, ref_type, ref_no))
|
(now(), webnotes.session.user, ref_type, ref_no))
|
||||||
|
|
||||||
|
webnotes.msgprint("{msg} {linked_jv}".format(msg = _("""Following linked Journal Vouchers \
|
||||||
|
made against this transaction has been unlinked. You can link them again with other \
|
||||||
|
transactions via Payment Reconciliation Tool."""), linked_jv="\n".join(linked_jv)))
|
||||||
|
|
||||||
|
|
||||||
@webnotes.whitelist()
|
@webnotes.whitelist()
|
||||||
def get_company_default(company, fieldname):
|
def get_company_default(company, fieldname):
|
||||||
@ -370,4 +378,4 @@ def get_account_for(account_for_doctype, account_for):
|
|||||||
account_for_field = "account_type"
|
account_for_field = "account_type"
|
||||||
|
|
||||||
return webnotes.conn.get_value("Account", {account_for_field: account_for_doctype,
|
return webnotes.conn.get_value("Account", {account_for_field: account_for_doctype,
|
||||||
"master_name": account_for})
|
"master_name": account_for})
|
@ -22,7 +22,7 @@ class TestPurchaseOrder(unittest.TestCase):
|
|||||||
|
|
||||||
pr = make_purchase_receipt(po.doc.name)
|
pr = make_purchase_receipt(po.doc.name)
|
||||||
pr[0]["supplier_warehouse"] = "_Test Warehouse 1 - _TC"
|
pr[0]["supplier_warehouse"] = "_Test Warehouse 1 - _TC"
|
||||||
|
pr[0]["posting_date"] = "2013-05-12"
|
||||||
self.assertEquals(pr[0]["doctype"], "Purchase Receipt")
|
self.assertEquals(pr[0]["doctype"], "Purchase Receipt")
|
||||||
self.assertEquals(len(pr), len(test_records[0]))
|
self.assertEquals(len(pr), len(test_records[0]))
|
||||||
|
|
||||||
@ -52,7 +52,7 @@ class TestPurchaseOrder(unittest.TestCase):
|
|||||||
|
|
||||||
self.assertEquals(pr[0]["doctype"], "Purchase Receipt")
|
self.assertEquals(pr[0]["doctype"], "Purchase Receipt")
|
||||||
self.assertEquals(len(pr), len(test_records[0]))
|
self.assertEquals(len(pr), len(test_records[0]))
|
||||||
|
pr[0]["posting_date"] = "2013-05-12"
|
||||||
pr[0].naming_series = "_T-Purchase Receipt-"
|
pr[0].naming_series = "_T-Purchase Receipt-"
|
||||||
pr[1].qty = 4.0
|
pr[1].qty = 4.0
|
||||||
pr_bean = webnotes.bean(pr)
|
pr_bean = webnotes.bean(pr)
|
||||||
@ -66,6 +66,7 @@ class TestPurchaseOrder(unittest.TestCase):
|
|||||||
|
|
||||||
pr1 = make_purchase_receipt(po.doc.name)
|
pr1 = make_purchase_receipt(po.doc.name)
|
||||||
pr1[0].naming_series = "_T-Purchase Receipt-"
|
pr1[0].naming_series = "_T-Purchase Receipt-"
|
||||||
|
pr1[0]["posting_date"] = "2013-05-12"
|
||||||
pr1[1].qty = 8
|
pr1[1].qty = 8
|
||||||
pr1_bean = webnotes.bean(pr1)
|
pr1_bean = webnotes.bean(pr1)
|
||||||
pr1_bean.insert()
|
pr1_bean.insert()
|
||||||
@ -88,7 +89,7 @@ class TestPurchaseOrder(unittest.TestCase):
|
|||||||
|
|
||||||
self.assertEquals(pi[0]["doctype"], "Purchase Invoice")
|
self.assertEquals(pi[0]["doctype"], "Purchase Invoice")
|
||||||
self.assertEquals(len(pi), len(test_records[0]))
|
self.assertEquals(len(pi), len(test_records[0]))
|
||||||
|
pi[0]["posting_date"] = "2013-05-12"
|
||||||
pi[0].bill_no = "NA"
|
pi[0].bill_no = "NA"
|
||||||
webnotes.bean(pi).insert()
|
webnotes.bean(pi).insert()
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"app_name": "ERPNext",
|
"app_name": "ERPNext",
|
||||||
"app_version": "3.4.5",
|
"app_version": "3.4.6",
|
||||||
"base_template": "app/portal/templates/base.html",
|
"base_template": "app/portal/templates/base.html",
|
||||||
"modules": {
|
"modules": {
|
||||||
"Accounts": {
|
"Accounts": {
|
||||||
|
@ -381,24 +381,41 @@ class AccountsController(TransactionBase):
|
|||||||
})
|
})
|
||||||
|
|
||||||
def validate_multiple_billing(self, ref_dt, item_ref_dn, based_on, parentfield):
|
def validate_multiple_billing(self, ref_dt, item_ref_dn, based_on, parentfield):
|
||||||
|
from controllers.status_updater import get_tolerance_for
|
||||||
|
item_tolerance = {}
|
||||||
|
global_tolerance = None
|
||||||
|
|
||||||
for item in self.doclist.get({"parentfield": "entries"}):
|
for item in self.doclist.get({"parentfield": "entries"}):
|
||||||
if item.fields.get(item_ref_dn):
|
if item.fields.get(item_ref_dn):
|
||||||
already_billed = webnotes.conn.sql("""select sum(%s) from `tab%s`
|
already_billed = webnotes.conn.sql("""select sum(%s) from `tab%s`
|
||||||
where %s=%s and docstatus=1""" % (based_on, self.tname, item_ref_dn, '%s'),
|
where %s=%s and docstatus=1""" % (based_on, self.tname, item_ref_dn, '%s'),
|
||||||
item.fields[item_ref_dn])[0][0]
|
item.fields[item_ref_dn])[0][0]
|
||||||
|
|
||||||
max_allowed_amt = flt(webnotes.conn.get_value(ref_dt + " Item",
|
|
||||||
item.fields[item_ref_dn], based_on), self.precision(based_on, item))
|
|
||||||
|
|
||||||
total_billed_amt = flt(flt(already_billed) + flt(item.fields[based_on]),
|
total_billed_amt = flt(flt(already_billed) + flt(item.fields[based_on]),
|
||||||
self.precision(based_on, item))
|
self.precision(based_on, item))
|
||||||
|
|
||||||
|
ref_amt = flt(webnotes.conn.get_value(ref_dt + " Item",
|
||||||
|
item.fields[item_ref_dn], based_on), self.precision(based_on, item))
|
||||||
|
|
||||||
|
tolerance, item_tolerance, global_tolerance = get_tolerance_for(item.item_code,
|
||||||
|
item_tolerance, global_tolerance)
|
||||||
|
|
||||||
if max_allowed_amt and total_billed_amt - max_allowed_amt > 0.02:
|
max_allowed_amt = flt(ref_amt * (100 + tolerance) / 100)
|
||||||
webnotes.msgprint(_("Row ")+ cstr(item.idx) + ": " + cstr(item.item_code) +
|
|
||||||
_(" will be over-billed against mentioned ") + cstr(ref_dt) +
|
if total_billed_amt - max_allowed_amt > 0.01:
|
||||||
_(". Max allowed " + cstr(based_on) + ": " + cstr(max_allowed_amt)),
|
reduce_by = total_billed_amt - max_allowed_amt
|
||||||
raise_exception=1)
|
|
||||||
|
webnotes.throw(_("Row #") + cstr(item.idx) + ": " +
|
||||||
|
_(" Max amount allowed for Item ") + cstr(item.item_code) +
|
||||||
|
_(" against ") + ref_dt + " " +
|
||||||
|
cstr(item.fields[ref_dt.lower().replace(" ", "_")]) + _(" is ") +
|
||||||
|
cstr(max_allowed_amt) + ". \n" +
|
||||||
|
_("""If you want to increase your overflow tolerance, please increase \
|
||||||
|
tolerance % in Global Defaults or Item master.
|
||||||
|
Or, you must reduce the amount by """) + cstr(reduce_by) + "\n" +
|
||||||
|
_("""Also, please check if the order item has already been billed \
|
||||||
|
in the Sales Order"""))
|
||||||
|
|
||||||
def get_company_default(self, fieldname):
|
def get_company_default(self, fieldname):
|
||||||
from accounts.utils import get_company_default
|
from accounts.utils import get_company_default
|
||||||
return get_company_default(self.doc.company, fieldname)
|
return get_company_default(self.doc.company, fieldname)
|
||||||
|
@ -151,7 +151,9 @@ class StatusUpdater(DocListController):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
# check if overflow is within tolerance
|
# check if overflow is within tolerance
|
||||||
tolerance = self.get_tolerance_for(item['item_code'])
|
tolerance, self.tolerance, self.global_tolerance = get_tolerance_for(item['item_code'],
|
||||||
|
self.tolerance, self.global_tolerance)
|
||||||
|
|
||||||
overflow_percent = ((item[args['target_field']] - item[args['target_ref_field']]) /
|
overflow_percent = ((item[args['target_field']] - item[args['target_ref_field']]) /
|
||||||
item[args['target_ref_field']]) * 100
|
item[args['target_ref_field']]) * 100
|
||||||
|
|
||||||
@ -170,23 +172,6 @@ class StatusUpdater(DocListController):
|
|||||||
|
|
||||||
Also, please check if the order item has already been billed in the Sales Order""" %
|
Also, please check if the order item has already been billed in the Sales Order""" %
|
||||||
item, raise_exception=1)
|
item, raise_exception=1)
|
||||||
|
|
||||||
def get_tolerance_for(self, item_code):
|
|
||||||
"""
|
|
||||||
Returns the tolerance for the item, if not set, returns global tolerance
|
|
||||||
"""
|
|
||||||
if self.tolerance.get(item_code): return self.tolerance[item_code]
|
|
||||||
|
|
||||||
tolerance = flt(webnotes.conn.get_value('Item',item_code,'tolerance') or 0)
|
|
||||||
|
|
||||||
if not tolerance:
|
|
||||||
if self.global_tolerance == None:
|
|
||||||
self.global_tolerance = flt(webnotes.conn.get_value('Global Defaults', None,
|
|
||||||
'tolerance'))
|
|
||||||
tolerance = self.global_tolerance
|
|
||||||
|
|
||||||
self.tolerance[item_code] = tolerance
|
|
||||||
return tolerance
|
|
||||||
|
|
||||||
|
|
||||||
def update_qty(self, change_modified=True):
|
def update_qty(self, change_modified=True):
|
||||||
@ -245,4 +230,22 @@ class StatusUpdater(DocListController):
|
|||||||
set %(status_field)s = if(ifnull(%(target_parent_field)s,0)<0.001,
|
set %(status_field)s = if(ifnull(%(target_parent_field)s,0)<0.001,
|
||||||
'Not %(keyword)s', if(%(target_parent_field)s>=99.99,
|
'Not %(keyword)s', if(%(target_parent_field)s>=99.99,
|
||||||
'Fully %(keyword)s', 'Partly %(keyword)s'))
|
'Fully %(keyword)s', 'Partly %(keyword)s'))
|
||||||
where name='%(name)s'""" % args)
|
where name='%(name)s'""" % args)
|
||||||
|
|
||||||
|
def get_tolerance_for(item_code, item_tolerance={}, global_tolerance=None):
|
||||||
|
"""
|
||||||
|
Returns the tolerance for the item, if not set, returns global tolerance
|
||||||
|
"""
|
||||||
|
if item_tolerance.get(item_code):
|
||||||
|
return item_tolerance[item_code], item_tolerance, global_tolerance
|
||||||
|
|
||||||
|
tolerance = flt(webnotes.conn.get_value('Item',item_code,'tolerance') or 0)
|
||||||
|
|
||||||
|
if not tolerance:
|
||||||
|
if global_tolerance == None:
|
||||||
|
global_tolerance = flt(webnotes.conn.get_value('Global Defaults', None,
|
||||||
|
'tolerance'))
|
||||||
|
tolerance = global_tolerance
|
||||||
|
|
||||||
|
item_tolerance[item_code] = tolerance
|
||||||
|
return tolerance, item_tolerance, global_tolerance
|
@ -34,6 +34,7 @@ class TestProductionOrder(unittest.TestCase):
|
|||||||
stock_entry = webnotes.bean(stock_entry)
|
stock_entry = webnotes.bean(stock_entry)
|
||||||
|
|
||||||
stock_entry.doc.fg_completed_qty = 4
|
stock_entry.doc.fg_completed_qty = 4
|
||||||
|
stock_entry.doc.posting_date = "2013-05-12"
|
||||||
stock_entry.run_method("get_items")
|
stock_entry.run_method("get_items")
|
||||||
stock_entry.submit()
|
stock_entry.submit()
|
||||||
|
|
||||||
@ -50,7 +51,7 @@ class TestProductionOrder(unittest.TestCase):
|
|||||||
|
|
||||||
stock_entry = make_stock_entry(pro_order, "Manufacture/Repack")
|
stock_entry = make_stock_entry(pro_order, "Manufacture/Repack")
|
||||||
stock_entry = webnotes.bean(stock_entry)
|
stock_entry = webnotes.bean(stock_entry)
|
||||||
|
stock_entry.doc.posting_date = "2013-05-12"
|
||||||
stock_entry.doc.fg_completed_qty = 15
|
stock_entry.doc.fg_completed_qty = 15
|
||||||
stock_entry.run_method("get_items")
|
stock_entry.run_method("get_items")
|
||||||
stock_entry.insert()
|
stock_entry.insert()
|
||||||
|
@ -28,6 +28,7 @@ class TestQuotation(unittest.TestCase):
|
|||||||
|
|
||||||
sales_order[0]["delivery_date"] = "2014-01-01"
|
sales_order[0]["delivery_date"] = "2014-01-01"
|
||||||
sales_order[0]["naming_series"] = "_T-Quotation-"
|
sales_order[0]["naming_series"] = "_T-Quotation-"
|
||||||
|
sales_order[0]["transaction_date"] = "2013-05-12"
|
||||||
webnotes.bean(sales_order).insert()
|
webnotes.bean(sales_order).insert()
|
||||||
|
|
||||||
|
|
||||||
|
@ -53,6 +53,7 @@ class TestSalesOrder(unittest.TestCase):
|
|||||||
self.assertEquals(len([d for d in si if d["doctype"]=="Sales Invoice Item"]), 1)
|
self.assertEquals(len([d for d in si if d["doctype"]=="Sales Invoice Item"]), 1)
|
||||||
|
|
||||||
si = webnotes.bean(si)
|
si = webnotes.bean(si)
|
||||||
|
si.doc.posting_date = "2013-10-10"
|
||||||
si.insert()
|
si.insert()
|
||||||
si.submit()
|
si.submit()
|
||||||
|
|
||||||
|
@ -125,6 +125,7 @@ class TestMaterialRequest(unittest.TestCase):
|
|||||||
from stock.doctype.material_request.material_request import make_purchase_order
|
from stock.doctype.material_request.material_request import make_purchase_order
|
||||||
po_doclist = make_purchase_order(mr.doc.name)
|
po_doclist = make_purchase_order(mr.doc.name)
|
||||||
po_doclist[0].supplier = "_Test Supplier"
|
po_doclist[0].supplier = "_Test Supplier"
|
||||||
|
po_doclist[0].transaction_date = "2013-07-07"
|
||||||
po_doclist[1].qty = 27.0
|
po_doclist[1].qty = 27.0
|
||||||
po_doclist[2].qty = 1.5
|
po_doclist[2].qty = 1.5
|
||||||
po_doclist[1].schedule_date = "2013-07-09"
|
po_doclist[1].schedule_date = "2013-07-09"
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
{
|
{
|
||||||
"creation": "2013-05-24 19:29:10",
|
"creation": "2013-05-24 19:29:10",
|
||||||
"docstatus": 0,
|
"docstatus": 0,
|
||||||
"modified": "2013-12-18 10:38:39",
|
"modified": "2014-01-03 18:28:20",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"owner": "Administrator"
|
"owner": "Administrator"
|
||||||
},
|
},
|
||||||
@ -334,6 +334,16 @@
|
|||||||
"report_hide": 0,
|
"report_hide": 0,
|
||||||
"reqd": 0
|
"reqd": 0
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"default": ":Company",
|
||||||
|
"depends_on": "eval:sys_defaults.auto_accounting_for_stock",
|
||||||
|
"doctype": "DocField",
|
||||||
|
"fieldname": "cost_center",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"label": "Cost Center",
|
||||||
|
"options": "Cost Center",
|
||||||
|
"print_hide": 1
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"doctype": "DocField",
|
"doctype": "DocField",
|
||||||
"fieldname": "project_name",
|
"fieldname": "project_name",
|
||||||
|
Loading…
Reference in New Issue
Block a user