[fix] [mapper] from delivery note to sales invoice, only map unbilled items
diff --git a/accounts/doctype/sales_invoice/sales_invoice.js b/accounts/doctype/sales_invoice/sales_invoice.js
index 345dbc9..d8d06dd 100644
--- a/accounts/doctype/sales_invoice/sales_invoice.js
+++ b/accounts/doctype/sales_invoice/sales_invoice.js
@@ -93,12 +93,18 @@
wn.model.map_current_doc({
method: "stock.doctype.delivery_note.delivery_note.make_sales_invoice",
source_doctype: "Delivery Note",
- get_query_filters: {
- docstatus: 1,
- customer: cur_frm.doc.customer || undefined,
- company: cur_frm.doc.company
+ get_query: function() {
+ var filters = {
+ docstatus: 1,
+ company: cur_frm.doc.company
+ };
+ if(cur_frm.doc.customer) filters["customer"] = cur_frm.doc.customer;
+ return {
+ query: "controllers.queries.get_delivery_notes_to_be_billed",
+ filters: filters
+ };
}
- })
+ });
});
// cur_frm.add_custom_button(wn._("POS View"), function() {
diff --git a/accounts/doctype/sales_invoice/sales_invoice.py b/accounts/doctype/sales_invoice/sales_invoice.py
index ca93786..09df5f6 100644
--- a/accounts/doctype/sales_invoice/sales_invoice.py
+++ b/accounts/doctype/sales_invoice/sales_invoice.py
@@ -1001,10 +1001,12 @@
bean = webnotes.bean(target)
bean.run_method("onload_post_render")
- def update_item(obj, target, source_parent):
- target.amount = (flt(obj.qty) - flt(obj.delivered_qty)) * flt(obj.basic_rate)
- target.export_amount = (flt(obj.qty) - flt(obj.delivered_qty)) * flt(obj.export_rate)
- target.qty = flt(obj.qty) - flt(obj.delivered_qty)
+ def update_item(source_doc, target_doc, source_parent):
+ target_doc.amount = (flt(source_doc.qty) - flt(source_doc.delivered_qty)) * \
+ flt(source_doc.basic_rate)
+ target_doc.export_amount = (flt(source_doc.qty) - flt(source_doc.delivered_qty)) * \
+ flt(source_doc.export_rate)
+ target_doc.qty = flt(source_doc.qty) - flt(source_doc.delivered_qty)
doclist = get_mapped_doclist("Sales Invoice", source_name, {
"Sales Invoice": {
diff --git a/controllers/accounts_controller.py b/controllers/accounts_controller.py
index 725fdb3..3d72e6f 100644
--- a/controllers/accounts_controller.py
+++ b/controllers/accounts_controller.py
@@ -394,7 +394,6 @@
total_billed_amt = flt(flt(already_billed) + flt(item.fields[based_on]),
self.precision(based_on, item))
- webnotes.errprint([max_allowed_amt, total_billed_amt])
if max_allowed_amt and total_billed_amt - max_allowed_amt > 0.02:
webnotes.msgprint(_("Row ")+ cstr(item.idx) + ": " + cstr(item.item_code) +
diff --git a/controllers/queries.py b/controllers/queries.py
index caa2f6f..462c22d 100644
--- a/controllers/queries.py
+++ b/controllers/queries.py
@@ -23,7 +23,7 @@
filters = filters.items()
flt = []
for f in filters:
- if f[1][0] == '!':
+ if isinstance(f[1], basestring) and f[1][0] == '!':
flt.append([doctype, f[0], '!=', f[1][1:]])
else:
flt.append([doctype, f[0], '=', f[1]])
@@ -204,4 +204,20 @@
and `%s` like %s order by ref_currency asc limit %s, %s""" %
("%s", "%s", searchfield, "%s", "%s", "%s"),
(filters["price_list_name"], filters['buying_or_selling'], "%%%s%%" % txt,
- start, page_len))
\ No newline at end of file
+ start, page_len))
+
+def get_delivery_notes_to_be_billed(doctype, txt, searchfield, start, page_len, filters):
+ return webnotes.conn.sql("""select `tabDelivery Note`.name, `tabDelivery Note`.customer_name
+ from `tabDelivery Note`
+ where `tabDelivery Note`.`%(key)s` like %(txt)s %(fcond)s and
+ (ifnull((select sum(qty) from `tabDelivery Note Item` where
+ `tabDelivery Note Item`.parent=`tabDelivery Note`.name), 0) >
+ ifnull((select sum(qty) from `tabSales Invoice Item` where
+ `tabSales Invoice Item`.delivery_note=`tabDelivery Note`.name), 0))
+ %(mcond)s order by `tabDelivery Note`.`%(key)s` asc
+ limit %(start)s, %(page_len)s""" % {
+ "key": searchfield,
+ "fcond": get_filters_cond(doctype, filters, []),
+ "mcond": get_match_cond(doctype),
+ "start": "%(start)s", "page_len": "%(page_len)s", "txt": "%(txt)s"
+ }, { "start": start, "page_len": page_len, "txt": ("%%%s%%" % txt) }, debug=True)
\ No newline at end of file
diff --git a/public/js/transaction.js b/public/js/transaction.js
index 2cee843..4a647ad 100644
--- a/public/js/transaction.js
+++ b/public/js/transaction.js
@@ -75,8 +75,10 @@
company: function() {
if(this.frm.doc.company && this.frm.fields_dict.currency) {
- var company_currency = this.get_company_currency();
- this.frm.set_value("currency", company_currency);
+ if(!this.frm.doc.currency) {
+ this.frm.set_value("currency", this.get_company_currency());
+ }
+
this.frm.script_manager.trigger("currency");
}
},
diff --git a/stock/doctype/delivery_note/delivery_note.py b/stock/doctype/delivery_note/delivery_note.py
index 81c4b6c..25a70b6 100644
--- a/stock/doctype/delivery_note/delivery_note.py
+++ b/stock/doctype/delivery_note/delivery_note.py
@@ -369,11 +369,37 @@
from accounts.general_ledger import make_gl_entries
make_gl_entries(gl_entries, cancel=(self.doc.docstatus == 2))
+def get_invoiced_qty_map(delivery_note):
+ """returns a map: {dn_detail: invoiced_qty}"""
+ invoiced_qty_map = {}
+
+ for dn_detail, qty in webnotes.conn.sql("""select dn_detail, qty from `tabSales Invoice Item`
+ where delivery_note=%s and docstatus=1""", delivery_note):
+ if not invoiced_qty_map.get(dn_detail):
+ invoiced_qty_map[dn_detail] = 0
+ invoiced_qty_map[dn_detail] += qty
+
+ return invoiced_qty_map
+
@webnotes.whitelist()
def make_sales_invoice(source_name, target_doclist=None):
+ invoiced_qty_map = get_invoiced_qty_map(source_name)
+
def update_accounts(source, target):
si = webnotes.bean(target)
si.run_method("onload_post_render")
+
+ si.set_doclist(si.doclist.get({"parentfield": ["!=", "entries"]}) +
+ si.doclist.get({"parentfield": "entries", "qty": [">", 0]}))
+
+ if len(si.doclist.get({"parentfield": "entries"})) == 0:
+ webnotes.msgprint(_("Hey! All these items have already been invoiced."),
+ raise_exception=True)
+
+ return si.doclist
+
+ def update_item(source_doc, target_doc, source_parent):
+ target_doc.qty = source_doc.qty - invoiced_qty_map.get(source_doc.name, 0)
doclist = get_mapped_doclist("Delivery Note", source_name, {
"Delivery Note": {
@@ -391,6 +417,7 @@
"prevdoc_docname": "sales_order",
"serial_no": "serial_no"
},
+ "postprocess": update_item
},
"Sales Taxes and Charges": {
"doctype": "Sales Taxes and Charges",