Merge pull request #4109 from rmehta/fix-sales-purchase-order-status
[fix] sales & purchase order status
diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
index dba7647..33fa4e3 100644
--- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
+++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
@@ -207,8 +207,8 @@
def validate_time_logs_are_submitted(self):
for d in self.get("items"):
if d.time_log_batch:
- status = frappe.db.get_value("Time Log Batch", d.time_log_batch, "status")
- if status!="Submitted":
+ docstatus = frappe.db.get_value("Time Log Batch", d.time_log_batch, "docstatus")
+ if docstatus!=1:
frappe.throw(_("Time Log Batch {0} must be 'Submitted'").format(d.time_log_batch))
def set_pos_fields(self, for_validate=False):
diff --git a/erpnext/buying/doctype/purchase_order/purchase_order.json b/erpnext/buying/doctype/purchase_order/purchase_order.json
index e4d04ea..6a7256a 100644
--- a/erpnext/buying/doctype/purchase_order/purchase_order.json
+++ b/erpnext/buying/doctype/purchase_order/purchase_order.json
@@ -1468,6 +1468,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "default": "Draft",
"fieldname": "status",
"fieldtype": "Select",
"hidden": 0,
@@ -1478,7 +1479,7 @@
"no_copy": 1,
"oldfieldname": "status",
"oldfieldtype": "Select",
- "options": "\nDraft\nSubmitted\nStopped\nCancelled",
+ "options": "\nDraft\nTo Receive and Bill\nTo Bill\nTo Receive\nCompleted\nStopped\nCancelled",
"permlevel": 0,
"print_hide": 1,
"read_only": 1,
@@ -2032,7 +2033,7 @@
"is_submittable": 1,
"issingle": 0,
"istable": 0,
- "modified": "2015-09-30 08:52:56.137185",
+ "modified": "2015-10-02 07:17:59.659036",
"modified_by": "Administrator",
"module": "Buying",
"name": "Purchase Order",
diff --git a/erpnext/buying/doctype/purchase_order/purchase_order.py b/erpnext/buying/doctype/purchase_order/purchase_order.py
index e8c79d8..0affd78 100644
--- a/erpnext/buying/doctype/purchase_order/purchase_order.py
+++ b/erpnext/buying/doctype/purchase_order/purchase_order.py
@@ -36,13 +36,7 @@
def validate(self):
super(PurchaseOrder, self).validate()
- if not self.status:
- self.status = "Draft"
-
- from erpnext.controllers.status_updater import validate_status
- validate_status(self.status, ["Draft", "Submitted", "Stopped",
- "Cancelled"])
-
+ self.set_status()
pc_obj = frappe.get_doc('Purchase Common')
pc_obj.validate_for_items(self)
self.check_for_stopped_status(pc_obj)
@@ -160,12 +154,10 @@
def update_status(self, status):
self.check_modified_date()
- frappe.db.set(self,'status',cstr(status))
-
+ self.db_set('status', status)
+ self.set_status(update=True)
self.update_requested_qty()
self.update_ordered_qty()
-
- msgprint(_("Status of {0} {1} is now {2}").format(self.doctype, self.name, status))
self.notify_update()
clear_doctype_notifications(self)
@@ -183,8 +175,6 @@
purchase_controller.update_last_purchase_rate(self, is_submit = 1)
- frappe.db.set(self,'status','Submitted')
-
def on_cancel(self):
pc_obj = frappe.get_doc('Purchase Common')
self.check_for_stopped_status(pc_obj)
@@ -238,7 +228,7 @@
po.update_status("Stopped")
else:
if po.status == "Stopped":
- po.update_status("Submitted")
+ po.update_status("Draft")
frappe.local.message_log = []
diff --git a/erpnext/controllers/status_updater.py b/erpnext/controllers/status_updater.py
index 42eaf4d..7d18867 100644
--- a/erpnext/controllers/status_updater.py
+++ b/erpnext/controllers/status_updater.py
@@ -30,7 +30,19 @@
],
"Sales Order": [
["Draft", None],
- ["Submitted", "eval:self.docstatus==1"],
+ ["To Deliver and Bill", "eval:self.per_delivered < 100 and self.per_billed < 100 and self.docstatus == 1"],
+ ["To Bill", "eval:self.per_delivered == 100 and self.per_billed < 100 and self.docstatus == 1"],
+ ["To Deliver", "eval:self.per_delivered < 100 and self.per_billed == 100 and self.docstatus == 1"],
+ ["Completed", "eval:self.per_delivered == 100 and self.per_billed == 100 and self.docstatus == 1"],
+ ["Stopped", "eval:self.status=='Stopped'"],
+ ["Cancelled", "eval:self.docstatus==2"],
+ ],
+ "Purchase Order": [
+ ["Draft", None],
+ ["To Receive and Bill", "eval:self.per_received < 100 and self.per_billed < 100 and self.docstatus == 1"],
+ ["To Bill", "eval:self.per_received == 100 and self.per_billed < 100 and self.docstatus == 1"],
+ ["To Receive", "eval:self.per_received < 100 and self.per_billed == 100 and self.docstatus == 1"],
+ ["Completed", "eval:self.per_received == 100 and self.per_billed == 100 and self.docstatus == 1"],
["Stopped", "eval:self.status=='Stopped'"],
["Cancelled", "eval:self.docstatus==2"],
],
@@ -222,7 +234,9 @@
where name='%(name)s'""" % args)
if args.get("set_modified"):
- frappe.get_doc(args["target_parent_dt"], name).notify_update()
+ target = frappe.get_doc(args["target_parent_dt"], name)
+ target.set_status(update=True)
+ target.notify_update()
def update_billing_status_for_zero_amount_refdoc(self, ref_dt):
ref_fieldname = ref_dt.lower().replace(" ", "_")
diff --git a/erpnext/patches.txt b/erpnext/patches.txt
index fe930c4..9eaa012 100644
--- a/erpnext/patches.txt
+++ b/erpnext/patches.txt
@@ -213,4 +213,5 @@
erpnext.patches.v6_3.convert_applicable_territory
erpnext.patches.v6_4.round_status_updater_percentages
erpnext.patches.v6_4.repost_gle_for_journal_entries_where_reference_name_missing
-erpnext.patches.v6_4.fix_journal_entries_due_to_reconciliation
\ No newline at end of file
+erpnext.patches.v6_4.fix_journal_entries_due_to_reconciliation
+erpnext.patches.v6_4.fix_status_in_sales_and_purchase_order
diff --git a/erpnext/patches/v6_4/fix_status_in_sales_and_purchase_order.py b/erpnext/patches/v6_4/fix_status_in_sales_and_purchase_order.py
new file mode 100644
index 0000000..867a5b2
--- /dev/null
+++ b/erpnext/patches/v6_4/fix_status_in_sales_and_purchase_order.py
@@ -0,0 +1,7 @@
+import frappe
+
+def execute():
+ for doctype in ("Sales Order", "Purchase Order"):
+ for doc in frappe.get_all(doctype, filters={"docstatus": 1}):
+ doc = frappe.get_doc(doctype, doc.name)
+ doc.set_status(update=True)
diff --git a/erpnext/projects/doctype/time_log/time_log_calendar.js b/erpnext/projects/doctype/time_log/time_log_calendar.js
index 61229d6..132355f 100644
--- a/erpnext/projects/doctype/time_log/time_log_calendar.js
+++ b/erpnext/projects/doctype/time_log/time_log_calendar.js
@@ -10,6 +10,7 @@
"allDay": "allDay"
},
gantt: true,
+ gantt_scale: "hours",
filters: [
{
"fieldtype": "Link",
diff --git a/erpnext/projects/doctype/time_log_batch/time_log_batch.py b/erpnext/projects/doctype/time_log_batch/time_log_batch.py
index 55d5937..03bd881 100644
--- a/erpnext/projects/doctype/time_log_batch/time_log_batch.py
+++ b/erpnext/projects/doctype/time_log_batch/time_log_batch.py
@@ -34,7 +34,7 @@
def validate_time_log_is_submitted(self, tl):
if tl.status == "Batched for Billing":
frappe.throw(_("Time Log {0} already billed").format(tl.name))
- elif tl.status != "Submitted":
+ elif tl.docstatus != 1:
frappe.throw(_("Time Log {0} must be 'Submitted'").format(tl.name))
def set_status(self):
diff --git a/erpnext/selling/doctype/sales_order/sales_order.json b/erpnext/selling/doctype/sales_order/sales_order.json
index a7fa954..0e26727 100644
--- a/erpnext/selling/doctype/sales_order/sales_order.json
+++ b/erpnext/selling/doctype/sales_order/sales_order.json
@@ -1977,7 +1977,7 @@
"no_copy": 1,
"oldfieldname": "status",
"oldfieldtype": "Select",
- "options": "\nDraft\nSubmitted\nStopped\nCancelled",
+ "options": "\nDraft\nTo Deliver and Bill\nTo Bill\nTo Deliver\nCompleted\nStopped\nCancelled",
"permlevel": 0,
"print_hide": 1,
"read_only": 1,
@@ -2553,7 +2553,7 @@
"is_submittable": 1,
"issingle": 0,
"istable": 0,
- "modified": "2015-09-30 08:52:52.211212",
+ "modified": "2015-10-02 07:17:43.178678",
"modified_by": "Administrator",
"module": "Selling",
"name": "Sales Order",
diff --git a/erpnext/selling/doctype/sales_order/sales_order.py b/erpnext/selling/doctype/sales_order/sales_order.py
index 3e68903..eda8c73 100644
--- a/erpnext/selling/doctype/sales_order/sales_order.py
+++ b/erpnext/selling/doctype/sales_order/sales_order.py
@@ -20,6 +20,27 @@
class WarehouseRequired(frappe.ValidationError): pass
class SalesOrder(SellingController):
+ def validate(self):
+ super(SalesOrder, self).validate()
+
+ self.validate_order_type()
+ self.validate_delivery_date()
+ self.validate_mandatory()
+ self.validate_proj_cust()
+ self.validate_po()
+ self.validate_uom_is_integer("stock_uom", "qty")
+ self.validate_for_items()
+ self.validate_warehouse()
+
+ from erpnext.stock.doctype.packed_item.packed_item import make_packing_list
+ make_packing_list(self,'items')
+
+ self.validate_with_previous_doc()
+ self.set_status()
+
+ if not self.billing_status: self.billing_status = 'Not Billed'
+ if not self.delivery_status: self.delivery_status = 'Not Delivered'
+
def validate_mandatory(self):
# validate transaction date v/s delivery date
if self.delivery_date:
@@ -93,33 +114,6 @@
if not res:
frappe.throw(_("Customer {0} does not belong to project {1}").format(self.customer, self.project_name))
- def validate(self):
- super(SalesOrder, self).validate()
-
- self.validate_order_type()
- self.validate_delivery_date()
- self.validate_mandatory()
- self.validate_proj_cust()
- self.validate_po()
- self.validate_uom_is_integer("stock_uom", "qty")
- self.validate_for_items()
- self.validate_warehouse()
-
- from erpnext.stock.doctype.packed_item.packed_item import make_packing_list
- make_packing_list(self,'items')
-
- self.validate_with_previous_doc()
-
- if not self.status:
- self.status = "Draft"
-
- from erpnext.controllers.status_updater import validate_status
- validate_status(self.status, ["Draft", "Submitted", "Stopped",
- "Cancelled"])
-
- if not self.billing_status: self.billing_status = 'Not Billed'
- if not self.delivery_status: self.delivery_status = 'Not Delivered'
-
def validate_warehouse(self):
from erpnext.stock.utils import validate_warehouse_company
@@ -162,7 +156,6 @@
frappe.get_doc('Authorization Control').validate_approving_authority(self.doctype, self.base_grand_total, self)
self.update_prevdoc_status('submit')
- frappe.db.set(self, 'status', 'Submitted')
def on_cancel(self):
# Cannot cancel stopped SO
@@ -175,7 +168,7 @@
self.update_prevdoc_status('cancel')
frappe.db.set(self, 'status', 'Cancelled')
-
+
def check_credit_limit(self):
from erpnext.selling.doctype.customer.customer import check_credit_limit
check_credit_limit(self.customer, self.company)
@@ -223,17 +216,16 @@
def stop_sales_order(self):
self.check_modified_date()
- frappe.db.set(self, 'status', 'Stopped')
+ self.db_set('status', 'Stopped')
self.update_reserved_qty()
- frappe.msgprint(_("{0} {1} status is Stopped").format(self.doctype, self.name))
self.notify_update()
clear_doctype_notifications(self)
def unstop_sales_order(self):
self.check_modified_date()
- frappe.db.set(self, 'status', 'Submitted')
+ self.db_set('status', 'Draft')
+ self.set_status(update=True)
self.update_reserved_qty()
- frappe.msgprint(_("{0} {1} status is Unstopped").format(self.doctype, self.name))
clear_doctype_notifications(self)
def update_reserved_qty(self, so_item_rows=None):
diff --git a/erpnext/startup/notifications.py b/erpnext/startup/notifications.py
index c7e63f1..12d0308 100644
--- a/erpnext/startup/notifications.py
+++ b/erpnext/startup/notifications.py
@@ -2,7 +2,6 @@
# License: GNU General Public License v3. See license.txt
from __future__ import unicode_literals
-import frappe
def get_notification_config():
return { "for_doctype":
@@ -15,7 +14,11 @@
"Contact": {"status": "Open"},
"Opportunity": {"status": "Open"},
"Quotation": {"docstatus": 0},
- "Sales Order": { "per_billed": ("<", 100), "status": ("!=", "Stopped"), "docstatus": ("<", 2) },
+ "Sales Order": {
+ "status": ("!=", "Stopped"),
+ "status": ("!=", "Completed"),
+ "docstatus": ("<", 2)
+ },
"Journal Entry": {"docstatus": 0},
"Sales Invoice": { "outstanding_amount": (">", 0), "docstatus": ("<", 2) },
"Purchase Invoice": {"docstatus": 0},
@@ -26,7 +29,11 @@
"Delivery Note": {"docstatus": 0},
"Stock Entry": {"docstatus": 0},
"Material Request": {"docstatus": 0},
- "Purchase Order": { "per_billed": ("<", 100), "status": ("!=", "Stopped"), "docstatus": ("<", 2) },
+ "Purchase Order": {
+ "status": ("!=", "Completed"),
+ "status": ("!=", "Stopped"),
+ "docstatus": ("<", 2)
+ },
"Production Order": { "status": "In Process" },
"BOM": {"docstatus": 0},
"Timesheet": {"docstatus": 0},