[Delivery Note] Moved prevdoc to Sales Order and Sales Invoice so links will work webnotes/erpnext#868

This commit is contained in:
Rushabh Mehta 2013-10-03 12:22:52 +05:30
parent fa228e9c9b
commit f1b6f67a98
10 changed files with 85 additions and 75 deletions

View File

@ -965,8 +965,7 @@ def make_delivery_note(source_name, target_doclist=None):
"doctype": "Delivery Note Item", "doctype": "Delivery Note Item",
"field_map": { "field_map": {
"name": "prevdoc_detail_docname", "name": "prevdoc_detail_docname",
"parent": "prevdoc_docname", "parent": "against_sales_invoice",
"parenttype": "prevdoc_doctype",
"serial_no": "serial_no" "serial_no": "serial_no"
}, },
"postprocess": update_item "postprocess": update_item

View File

@ -0,0 +1,12 @@
# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd.
# License: GNU General Public License v3. See license.txt
from __future__ import unicode_literals
import webnotes
def execute():
webnotes.conn.sql("""update `tabDelivery Note Item` set against_sales_order=prevdoc_docname
where prevdoc_doctype='Sales Order' """)
webnotes.conn.sql("""update `tabDelivery Note Item` set against_sales_invoice=prevdoc_docname
where prevdoc_doctype='Sales Invoice' """)

View File

@ -220,4 +220,5 @@ patch_list = [
"patches.september_2013.p04_unsubmit_serial_nos", "patches.september_2013.p04_unsubmit_serial_nos",
"patches.september_2013.p05_fix_customer_in_pos", "patches.september_2013.p05_fix_customer_in_pos",
"patches.october_2013.fix_is_cancelled_in_sle", "patches.october_2013.fix_is_cancelled_in_sle",
"patches.october_2013.p01_update_delivery_note_prevdocs",
] ]

View File

@ -123,12 +123,12 @@ class DocType(TransactionBase):
if flt(d.qty) > flt(d.delivered_qty): if flt(d.qty) > flt(d.delivered_qty):
reserved_qty_for_main_item = flt(d.qty) - flt(d.delivered_qty) reserved_qty_for_main_item = flt(d.qty) - flt(d.delivered_qty)
if obj.doc.doctype == "Delivery Note" and d.prevdoc_doctype == 'Sales Order': if obj.doc.doctype == "Delivery Note" and d.against_sales_order:
# if SO qty is 10 and there is tolerance of 20%, then it will allow DN of 12. # if SO qty is 10 and there is tolerance of 20%, then it will allow DN of 12.
# But in this case reserved qty should only be reduced by 10 and not 12 # But in this case reserved qty should only be reduced by 10 and not 12
already_delivered_qty = self.get_already_delivered_qty(obj.doc.name, already_delivered_qty = self.get_already_delivered_qty(obj.doc.name,
d.prevdoc_docname, d.prevdoc_detail_docname) d.against_sales_order, d.prevdoc_detail_docname)
so_qty, reserved_warehouse = self.get_so_qty_and_warehouse(d.prevdoc_detail_docname) so_qty, reserved_warehouse = self.get_so_qty_and_warehouse(d.prevdoc_detail_docname)
if already_delivered_qty + d.qty > so_qty: if already_delivered_qty + d.qty > so_qty:
@ -168,7 +168,7 @@ class DocType(TransactionBase):
def get_already_delivered_qty(self, dn, so, so_detail): def get_already_delivered_qty(self, dn, so, so_detail):
qty = webnotes.conn.sql("""select sum(qty) from `tabDelivery Note Item` qty = webnotes.conn.sql("""select sum(qty) from `tabDelivery Note Item`
where prevdoc_detail_docname = %s and docstatus = 1 where prevdoc_detail_docname = %s and docstatus = 1
and prevdoc_doctype = 'Sales Order' and prevdoc_docname = %s and against_sales_order = %s
and parent != %s""", (so_detail, so, dn)) and parent != %s""", (so_detail, so, dn))
return qty and flt(qty[0][0]) or 0.0 return qty and flt(qty[0][0]) or 0.0
@ -218,7 +218,6 @@ class DocType(TransactionBase):
pi.qty = flt(qty) pi.qty = flt(qty)
pi.actual_qty = bin and flt(bin['actual_qty']) or 0 pi.actual_qty = bin and flt(bin['actual_qty']) or 0
pi.projected_qty = bin and flt(bin['projected_qty']) or 0 pi.projected_qty = bin and flt(bin['projected_qty']) or 0
pi.prevdoc_doctype = line.prevdoc_doctype
if not pi.warehouse: if not pi.warehouse:
pi.warehouse = warehouse pi.warehouse = warehouse
if not pi.batch_no: if not pi.batch_no:
@ -283,8 +282,8 @@ class DocType(TransactionBase):
def check_stop_sales_order(self,obj): def check_stop_sales_order(self,obj):
for d in getlist(obj.doclist,obj.fname): for d in getlist(obj.doclist,obj.fname):
ref_doc_name = '' ref_doc_name = ''
if d.fields.has_key('prevdoc_docname') and d.prevdoc_docname and d.prevdoc_doctype == 'Sales Order': if d.fields.has_key('against_sales_order') and d.against_sales_order:
ref_doc_name = d.prevdoc_docname ref_doc_name = d.against_sales_order
elif d.fields.has_key('sales_order') and d.sales_order and not d.delivery_note: elif d.fields.has_key('sales_order') and d.sales_order and not d.delivery_note:
ref_doc_name = d.sales_order ref_doc_name = d.sales_order
if ref_doc_name: if ref_doc_name:
@ -321,14 +320,22 @@ class DocType(TransactionBase):
def get_prevdoc_date(self, obj): def get_prevdoc_date(self, obj):
for d in getlist(obj.doclist, obj.fname): for d in getlist(obj.doclist, obj.fname):
if d.prevdoc_doctype and d.prevdoc_docname: date_field = None
if d.prevdoc_doctype in ["Sales Invoice", "Delivery Note"]:
pdoctype, pname = d.prevdoc_doctype, d.prevdoc_docname
if d.against_sales_invoice:
pdoctype, pname = "Sales Invoice", d.against_sales_invoice
elif d.against_sales_order:
pdoctype, pname = "Sales Order", d.against_sales_order
if pdoctype and pname:
if pdoctype in ["Sales Invoice", "Delivery Note"]:
date_field = "posting_date" date_field = "posting_date"
else: else:
date_field = "transaction_date" date_field = "transaction_date"
d.prevdoc_date = webnotes.conn.get_value(d.prevdoc_doctype, d.prevdoc_date = webnotes.conn.get_value(pdoctype, pname, date_field)
d.prevdoc_docname, date_field)
def get_batch_no(doctype, txt, searchfield, start, page_len, filters): def get_batch_no(doctype, txt, searchfield, start, page_len, filters):
from controllers.queries import get_match_cond from controllers.queries import get_match_cond

View File

@ -341,8 +341,7 @@ def make_delivery_note(source_name, target_doclist=None):
"field_map": { "field_map": {
"export_rate": "export_rate", "export_rate": "export_rate",
"name": "prevdoc_detail_docname", "name": "prevdoc_detail_docname",
"parent": "prevdoc_docname", "parent": "against_sales_order",
"parenttype": "prevdoc_doctype",
"reserved_warehouse": "warehouse" "reserved_warehouse": "warehouse"
}, },
"postprocess": update_item, "postprocess": update_item,

View File

@ -74,8 +74,7 @@ class TestSalesOrder(unittest.TestCase):
from stock.doctype.delivery_note.test_delivery_note import test_records as dn_test_records from stock.doctype.delivery_note.test_delivery_note import test_records as dn_test_records
dn = webnotes.bean(webnotes.copy_doclist(dn_test_records[0])) dn = webnotes.bean(webnotes.copy_doclist(dn_test_records[0]))
dn.doclist[1].item_code = so.doclist[1].item_code dn.doclist[1].item_code = so.doclist[1].item_code
dn.doclist[1].prevdoc_doctype = "Sales Order" dn.doclist[1].against_sales_order = so.doc.name
dn.doclist[1].prevdoc_docname = so.doc.name
dn.doclist[1].prevdoc_detail_docname = so.doclist[1].name dn.doclist[1].prevdoc_detail_docname = so.doclist[1].name
if delivered_qty: if delivered_qty:
dn.doclist[1].qty = delivered_qty dn.doclist[1].qty = delivered_qty

View File

@ -22,7 +22,7 @@ erpnext.stock.DeliveryNoteController = erpnext.selling.SellingController.extend(
var from_sales_invoice = false; var from_sales_invoice = false;
from_sales_invoice = cur_frm.get_doclist({parentfield: "delivery_note_details"}) from_sales_invoice = cur_frm.get_doclist({parentfield: "delivery_note_details"})
.some(function(item) { .some(function(item) {
return item.prevdoc_doctype==="Sales Invoice" ? true : false; return item.against_sales_invoice ? true : false;
}); });
if(!from_sales_invoice) if(!from_sales_invoice)
@ -181,12 +181,12 @@ cur_frm.pformat.sales_order_no= function(doc, cdt, cdn){
if(cl.length){ if(cl.length){
prevdoc_list = new Array(); prevdoc_list = new Array();
for(var i=0;i<cl.length;i++){ for(var i=0;i<cl.length;i++){
if(cl[i].prevdoc_doctype == 'Sales Order' && cl[i].prevdoc_docname && prevdoc_list.indexOf(cl[i].prevdoc_docname) == -1) { if(cl[i].against_sales_order && prevdoc_list.indexOf(cl[i].against_sales_order) == -1) {
prevdoc_list.push(cl[i].prevdoc_docname); prevdoc_list.push(cl[i].against_sales_order);
if(prevdoc_list.length ==1) if(prevdoc_list.length ==1)
out += make_row(cl[i].prevdoc_doctype, cl[i].prevdoc_docname, cl[i].prevdoc_date,0); out += make_row("Sales Order", cl[i].against_sales_order, cl[i].prevdoc_date, 0);
else else
out += make_row('', cl[i].prevdoc_docname, cl[i].prevdoc_date,0); out += make_row('', cl[i].against_sales_order, cl[i].prevdoc_date,0);
} }
} }
} }

View File

@ -28,7 +28,7 @@ class DocType(SellingController):
'target_parent_field': 'per_delivered', 'target_parent_field': 'per_delivered',
'target_ref_field': 'qty', 'target_ref_field': 'qty',
'source_field': 'qty', 'source_field': 'qty',
'percent_join_field': 'prevdoc_docname', 'percent_join_field': 'against_sales_order',
'status_field': 'delivery_status', 'status_field': 'delivery_status',
'keyword': 'Delivered' 'keyword': 'Delivered'
}] }]
@ -73,7 +73,7 @@ class DocType(SellingController):
"""check in manage account if sales order required or not""" """check in manage account if sales order required or not"""
if webnotes.conn.get_value("Selling Settings", None, 'so_required') == 'Yes': if webnotes.conn.get_value("Selling Settings", None, 'so_required') == 'Yes':
for d in getlist(self.doclist,'delivery_note_details'): for d in getlist(self.doclist,'delivery_note_details'):
if not d.prevdoc_docname: if not d.against_sales_order:
msgprint("Sales Order No. required against item %s"%d.item_code) msgprint("Sales Order No. required against item %s"%d.item_code)
raise Exception raise Exception
@ -106,26 +106,27 @@ class DocType(SellingController):
if not self.doc.installation_status: self.doc.installation_status = 'Not Installed' if not self.doc.installation_status: self.doc.installation_status = 'Not Installed'
def validate_with_previous_doc(self): def validate_with_previous_doc(self):
prev_doctype = [d.prevdoc_doctype for d in self.doclist.get({ items = self.doclist.get({"parentfield": "delivery_note_details"})
"parentfield": "delivery_note_details"}) if cstr(d.prevdoc_doctype) != ""]
for fn in (("Sales Order", "against_sales_order"), ("Sales Invoice", "against_sales_invoice")):
if prev_doctype: if items.get_distinct_values(fn[1]):
super(DocType, self).validate_with_previous_doc(self.tname, {
prev_doctype[0]: {
"ref_dn_field": "prevdoc_docname",
"compare_fields": [["customer", "="], ["company", "="], ["project_name", "="],
["currency", "="]],
},
})
if cint(webnotes.defaults.get_global_default('maintain_same_sales_rate')):
super(DocType, self).validate_with_previous_doc(self.tname, { super(DocType, self).validate_with_previous_doc(self.tname, {
prev_doctype[0] + " Item": { fn[0]: {
"ref_dn_field": "prevdoc_detail_docname", "ref_dn_field": fn[1],
"compare_fields": [["export_rate", "="]], "compare_fields": [["customer", "="], ["company", "="], ["project_name", "="],
"is_child_table": True ["currency", "="]],
} },
}) })
if cint(webnotes.defaults.get_global_default('maintain_same_sales_rate')):
super(DocType, self).validate_with_previous_doc(self.tname, {
fn[0] + " Item": {
"ref_dn_field": "prevdoc_detail_docname",
"compare_fields": [["export_rate", "="]],
"is_child_table": True
}
})
def validate_proj_cust(self): def validate_proj_cust(self):
"""check for does customer belong to same project as entered..""" """check for does customer belong to same project as entered.."""
if self.doc.project_name and self.doc.customer: if self.doc.project_name and self.doc.customer:
@ -137,8 +138,8 @@ class DocType(SellingController):
def validate_for_items(self): def validate_for_items(self):
check_list, chk_dupl_itm = [], [] check_list, chk_dupl_itm = [], []
for d in getlist(self.doclist,'delivery_note_details'): for d in getlist(self.doclist,'delivery_note_details'):
e = [d.item_code, d.description, d.warehouse, d.prevdoc_docname or '', d.batch_no or ''] e = [d.item_code, d.description, d.warehouse, d.against_sales_order or d.against_sales_invoice, d.batch_no or '']
f = [d.item_code, d.description, d.prevdoc_docname or ''] f = [d.item_code, d.description, d.against_sales_order or d.against_sales_invoice]
if webnotes.conn.get_value("Item", d.item_code, "is_stock_item") == 'Yes': if webnotes.conn.get_value("Item", d.item_code, "is_stock_item") == 'Yes':
if e in check_list: if e in check_list:
@ -323,7 +324,7 @@ class DocType(SellingController):
"""check credit limit of items in DN Detail which are not fetched from sales order""" """check credit limit of items in DN Detail which are not fetched from sales order"""
amount, total = 0, 0 amount, total = 0, 0
for d in getlist(self.doclist, 'delivery_note_details'): for d in getlist(self.doclist, 'delivery_note_details'):
if not d.prevdoc_docname: if not (d.against_sales_order or d.against_sales_invoice):
amount += d.amount amount += d.amount
if amount != 0: if amount != 0:
total = (amount/self.doc.net_total)*self.doc.grand_total total = (amount/self.doc.net_total)*self.doc.grand_total
@ -375,7 +376,7 @@ def make_sales_invoice(source_name, target_doclist=None):
"name": "dn_detail", "name": "dn_detail",
"parent": "delivery_note", "parent": "delivery_note",
"prevdoc_detail_docname": "so_detail", "prevdoc_detail_docname": "so_detail",
"prevdoc_docname": "sales_order", "against_sales_order": "sales_order",
"serial_no": "serial_no" "serial_no": "serial_no"
}, },
"postprocess": update_item "postprocess": update_item

View File

@ -2,7 +2,7 @@
{ {
"creation": "2013-04-22 13:15:44", "creation": "2013-04-22 13:15:44",
"docstatus": 0, "docstatus": 0,
"modified": "2013-08-29 16:58:16", "modified": "2013-10-03 11:09:48",
"modified_by": "Administrator", "modified_by": "Administrator",
"owner": "Administrator" "owner": "Administrator"
}, },
@ -350,35 +350,17 @@
}, },
{ {
"doctype": "DocField", "doctype": "DocField",
"fieldname": "prevdoc_doctype", "fieldname": "against_sales_order",
"fieldtype": "Data", "fieldtype": "Link",
"hidden": 1, "label": "Against Sales Order",
"in_filter": 1, "options": "Sales Order"
"label": "Document Type",
"no_copy": 1,
"oldfieldname": "prevdoc_doctype",
"oldfieldtype": "Data",
"print_hide": 1,
"print_width": "150px",
"read_only": 1,
"search_index": 1,
"width": "150px"
}, },
{ {
"doctype": "DocField", "doctype": "DocField",
"fieldname": "prevdoc_docname", "fieldname": "against_sales_invoice",
"fieldtype": "Data", "fieldtype": "Link",
"hidden": 0, "label": "Against Sales Invoice",
"in_filter": 1, "options": "Sales Invoice"
"label": "Against Document No",
"no_copy": 1,
"oldfieldname": "prevdoc_docname",
"oldfieldtype": "Data",
"print_hide": 1,
"print_width": "150px",
"read_only": 1,
"search_index": 1,
"width": "150px"
}, },
{ {
"doctype": "DocField", "doctype": "DocField",
@ -420,6 +402,17 @@
"print_hide": 1, "print_hide": 1,
"read_only": 1 "read_only": 1
}, },
{
"doctype": "DocField",
"fieldname": "buying_amount",
"fieldtype": "Currency",
"hidden": 1,
"label": "Buying Amount",
"no_copy": 1,
"options": "Company:company:default_currency",
"print_hide": 1,
"read_only": 1
},
{ {
"allow_on_submit": 1, "allow_on_submit": 1,
"doctype": "DocField", "doctype": "DocField",

View File

@ -895,8 +895,7 @@ def make_return_jv_from_delivery_note(se, ref):
ref.doclist[0].name) ref.doclist[0].name)
if not invoices_against_delivery: if not invoices_against_delivery:
sales_orders_against_delivery = [d.prevdoc_docname for d in sales_orders_against_delivery = [d.against_sales_order for d in ref.doclist if d.against_sales_order]
ref.doclist.get({"prevdoc_doctype": "Sales Order"}) if d.prevdoc_docname]
if sales_orders_against_delivery: if sales_orders_against_delivery:
invoices_against_delivery = get_invoice_list("Sales Invoice Item", "sales_order", invoices_against_delivery = get_invoice_list("Sales Invoice Item", "sales_order",