From 1e4c28e99d2b675408bb8b3cda743852b6aedc66 Mon Sep 17 00:00:00 2001 From: Saqib Ansari Date: Thu, 23 Apr 2020 15:15:52 +0530 Subject: [PATCH] fix: quotation have expired status even if sales order exists --- erpnext/patches.txt | 1 + .../v12_0/fix_quotation_expired_status.py | 37 +++++++++++++++++++ .../selling/doctype/quotation/quotation.py | 23 +++++++++--- 3 files changed, 55 insertions(+), 6 deletions(-) create mode 100644 erpnext/patches/v12_0/fix_quotation_expired_status.py diff --git a/erpnext/patches.txt b/erpnext/patches.txt index 9ef0b8d510..39ae8e7447 100644 --- a/erpnext/patches.txt +++ b/erpnext/patches.txt @@ -667,3 +667,4 @@ erpnext.patches.v12_0.update_healthcare_refactored_changes erpnext.patches.v12_0.set_total_batch_quantity erpnext.patches.v12_0.rename_mws_settings_fields erpnext.patches.v12_0.set_updated_purpose_in_pick_list +erpnext.patches.v12_0.fix_quotation_expired_status diff --git a/erpnext/patches/v12_0/fix_quotation_expired_status.py b/erpnext/patches/v12_0/fix_quotation_expired_status.py new file mode 100644 index 0000000000..a0320feb7b --- /dev/null +++ b/erpnext/patches/v12_0/fix_quotation_expired_status.py @@ -0,0 +1,37 @@ +import frappe + + +def execute(): + # fixes status of quotations which have status 'Expired' despite having valid sales order created + + # filter out submitted expired quotations which has sales order created + cond = "qo.docstatus = 1 and qo.status = 'Expired'" + invalid_so_against_quo = """ + SELECT + so.name FROM `tabSales Order` so, `tabSales Order Item` so_item + WHERE + so_item.docstatus = 1 and so.docstatus = 1 + and so_item.parent = so.name + and so_item.prevdoc_docname = qo.name + and qo.valid_till < so.transaction_date""" # check if SO was created after quotation expired + + frappe.db.sql( + """UPDATE `tabQuotation` qo SET qo.status = 'Expired' WHERE {cond} and not exists({invalid_so_against_quo})""" + .format(cond=cond, invalid_so_against_quo=invalid_so_against_quo), + (nowdate()) + ) + + valid_so_against_quo = """ + SELECT + so.name FROM `tabSales Order` so, `tabSales Order Item` so_item + WHERE + so_item.docstatus = 1 and so.docstatus = 1 + and so_item.parent = so.name + and so_item.prevdoc_docname = qo.name + and qo.valid_till >= so.transaction_date""" # check if SO was created before quotation expired + + frappe.db.sql( + """UPDATE `tabQuotation` qo SET qo.status = 'Closed' WHERE {cond} and not exists({valid_so_against_quo})""" + .format(cond=cond, valid_so_against_quo=valid_so_against_quo), + (nowdate()) + ) diff --git a/erpnext/selling/doctype/quotation/quotation.py b/erpnext/selling/doctype/quotation/quotation.py index 7c47b8ac51..7cfec5a046 100644 --- a/erpnext/selling/doctype/quotation/quotation.py +++ b/erpnext/selling/doctype/quotation/quotation.py @@ -193,12 +193,23 @@ def _make_sales_order(source_name, target_doc=None, ignore_permissions=False): return doclist def set_expired_status(): - frappe.db.sql(""" - UPDATE - `tabQuotation` SET `status` = 'Expired' - WHERE - `status` not in ('Ordered', 'Expired', 'Lost', 'Cancelled') AND `valid_till` < %s - """, (nowdate())) + # filter out submitted non expired quotations whose validity has been ended + cond = "qo.docstatus = 1 and qo.status != 'Expired' and qo.valid_till < %s" + # check if those QUO have SO against it + so_against_quo = """ + SELECT + so.name FROM `tabSales Order` so, `tabSales Order Item` so_item + WHERE + so_item.docstatus = 1 and so.docstatus = 1 + and so_item.parent = so.name + and so_item.prevdoc_docname = qo.name""" + + # if not exists any SO, set status as Expired + frappe.db.sql( + """UPDATE `tabQuotation` qo SET qo.status = 'Expired' WHERE {cond} and not exists({so_against_quo})""" + .format(cond=cond, so_against_quo=so_against_quo), + (nowdate()) + ) @frappe.whitelist() def make_sales_invoice(source_name, target_doc=None):