Cleanup of schedule date functionality in Material Request

This commit is contained in:
Nabin Hait 2017-10-05 18:27:37 +05:30
commit 395cf4689b
14 changed files with 181 additions and 66 deletions

View File

@ -291,9 +291,9 @@
"search_index": 1, "search_index": 1,
"set_only_once": 0, "set_only_once": 0,
"unique": 0 "unique": 0
}, },
{ {
"allow_bulk_edit": 0, "allow_bulk_edit": 0,
"allow_on_submit": 0, "allow_on_submit": 0,
"bold": 0, "bold": 0,
"collapsible": 0, "collapsible": 0,

View File

@ -148,7 +148,7 @@
"ignore_xss_filter": 0, "ignore_xss_filter": 0,
"in_filter": 0, "in_filter": 0,
"in_global_search": 0, "in_global_search": 0,
"in_list_view": 0, "in_list_view": 0,
"in_standard_filter": 0, "in_standard_filter": 0,
"label": "Reqd By Date", "label": "Reqd By Date",
"length": 0, "length": 0,

View File

@ -103,6 +103,7 @@ def make_material_request(item_code, qty):
mr.material_request_type = "Purchase" mr.material_request_type = "Purchase"
mr.transaction_date = frappe.flags.current_date mr.transaction_date = frappe.flags.current_date
mr.schedule_date = frappe.utils.add_days(mr.transaction_date, 7)
mr.append("items", { mr.append("items", {
"doctype": "Material Request Item", "doctype": "Material Request Item",

View File

@ -515,7 +515,8 @@ class ProductionPlanningTool(Document):
"transaction_date": nowdate(), "transaction_date": nowdate(),
"status": "Draft", "status": "Draft",
"company": self.company, "company": self.company,
"requested_by": frappe.session.user "requested_by": frappe.session.user,
"schedule_date": add_days(nowdate(), cint(item_wrapper.lead_time_days)),
}) })
material_request.update({"material_request_type": item_wrapper.default_material_request_type}) material_request.update({"material_request_type": item_wrapper.default_material_request_type})

View File

@ -449,3 +449,4 @@ erpnext.patches.v8_9.delete_gst_doctypes_for_outside_india_accounts
erpnext.patches.v8_9.set_default_fields_in_variant_settings erpnext.patches.v8_9.set_default_fields_in_variant_settings
erpnext.patches.v8_9.update_billing_gstin_for_indian_account erpnext.patches.v8_9.update_billing_gstin_for_indian_account
erpnext.patches.v9_0.fix_subscription_next_date erpnext.patches.v9_0.fix_subscription_next_date
erpnext.patches.v9_0.set_schedule_date_for_material_request

View File

@ -0,0 +1,21 @@
# Copyright (c) 2017, Frappe and Contributors
# License: GNU General Public License v3. See license.txt
from __future__ import unicode_literals
import frappe
def execute():
frappe.reload_doctype("Material Request")
frappe.reload_doctype("Material Request Item")
if not frappe.db.has_column("Material Request", "schedule_date"):
return
#Update only submitted MR
for mr in frappe.get_all("Material Request", filters= [["docstatus", "=", 1]], fields=["name"]):
material_request = frappe.get_doc("Material Request", mr)
if material_request.items:
if not material_request.schedule_date:
max_schedule_date = max([d.schedule_date for d in material_request.items])
frappe.db.set_value("Material Request", mr,
"schedule_date", max_schedule_date, update_modified=False)

View File

@ -92,7 +92,7 @@ erpnext.selling.SalesOrderController = erpnext.selling.SellingController.extend(
// delivery note // delivery note
if(flt(doc.per_delivered, 2) < 100 && ["Sales", "Shopping Cart"].indexOf(doc.order_type)!==-1 && allow_delivery) { if(flt(doc.per_delivered, 2) < 100 && ["Sales", "Shopping Cart"].indexOf(doc.order_type)!==-1 && allow_delivery) {
this.frm.add_custom_button(__('Delivery'), this.frm.add_custom_button(__('Delivery'),
function() { me.make_delivery_note_based_on_delivery_note(); }, __("Make")); function() { me.make_delivery_note_based_on_delivery_date(); }, __("Make"));
this.frm.add_custom_button(__('Production Order'), this.frm.add_custom_button(__('Production Order'),
function() { me.make_production_order() }, __("Make")); function() { me.make_production_order() }, __("Make"));
@ -270,7 +270,7 @@ erpnext.selling.SalesOrderController = erpnext.selling.SellingController.extend(
}) })
}, },
make_delivery_note_based_on_delivery_note: function() { make_delivery_note_based_on_delivery_date: function() {
var me = this; var me = this;
var delivery_dates = []; var delivery_dates = [];

View File

@ -73,6 +73,7 @@ def make_material_request(items):
mr = frappe.get_doc({ mr = frappe.get_doc({
"doctype": "Material Request", "doctype": "Material Request",
"material_request_type": "Purchase", "material_request_type": "Purchase",
"schedule_date": frappe.utils.add_days(frappe.utils.nowdate(), 7),
"items": [{ "items": [{
"schedule_date": frappe.utils.add_days(frappe.utils.nowdate(), 7), "schedule_date": frappe.utils.add_days(frappe.utils.nowdate(), 7),
"item_code": i.name, "item_code": i.name,

View File

@ -17,6 +17,9 @@ frappe.ui.form.on('Material Request', {
// add item, if previous view was item // add item, if previous view was item
erpnext.utils.add_item(frm); erpnext.utils.add_item(frm);
//set schedule_date
set_schedule_date(frm);
// formatter for material request item // formatter for material request item
frm.set_indicator_formatter('item_code', frm.set_indicator_formatter('item_code',
function(doc) { return (doc.qty<=doc.ordered_qty) ? "green" : "orange" }), function(doc) { return (doc.qty<=doc.ordered_qty) ? "green" : "orange" }),
@ -38,13 +41,19 @@ frappe.ui.form.on("Material Request Item", {
}, },
item_code: function(frm, doctype, name) { item_code: function(frm, doctype, name) {
frm.script_manager.copy_from_first_row('items', frm.selected_doc, set_schedule_date(frm);
'schedule_date');
}, },
schedule_date: function(frm, cdt, cdn) { schedule_date: function(frm, cdt, cdn) {
erpnext.utils.copy_value_in_all_row(frm.doc, cdt, cdn, "items", "schedule_date"); var row = locals[cdt][cdn];
} if (row.schedule_date) {
if(!frm.doc.schedule_date) {
erpnext.utils.copy_value_in_all_row(frm.doc, cdt, cdn, "items", "schedule_date");
} else {
set_schedule_date(frm);
}
}
}
}); });
erpnext.buying.MaterialRequestController = erpnext.buying.BuyingController.extend({ erpnext.buying.MaterialRequestController = erpnext.buying.BuyingController.extend({
@ -227,6 +236,28 @@ erpnext.buying.MaterialRequestController = erpnext.buying.BuyingController.exten
} }
} }
}); });
},
validate: function() {
set_schedule_date(this.frm);
},
items_add: function(doc, cdt, cdn) {
var row = frappe.get_doc(cdt, cdn);
if(doc.schedule_date) {
row.schedule_date = doc.schedule_date;
refresh_field("schedule_date", cdn, "items");
} else {
this.frm.script_manager.copy_from_first_row("items", row, ["schedule_date"]);
}
},
items_on_form_rendered: function() {
set_schedule_date(this.frm);
},
schedule_date: function() {
set_schedule_date(this.frm);
} }
}); });
@ -246,3 +277,9 @@ cur_frm.cscript['Unstop Material Request'] = function(){
cur_frm.refresh(); cur_frm.refresh();
}); });
}; };
function set_schedule_date(frm) {
if(frm.doc.schedule_date){
erpnext.utils.copy_value_in_all_row(frm.doc, frm.doc.doctype, frm.doc.name, "items", "schedule_date");
}
}

View File

@ -42,6 +42,38 @@
"set_only_once": 0, "set_only_once": 0,
"unique": 0 "unique": 0
}, },
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "naming_series",
"fieldtype": "Select",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Series",
"length": 0,
"no_copy": 1,
"oldfieldname": "naming_series",
"oldfieldtype": "Select",
"options": "MREQ-",
"permlevel": 0,
"print_hide": 1,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
"set_only_once": 1,
"unique": 0
},
{ {
"allow_bulk_edit": 0, "allow_bulk_edit": 0,
"allow_on_submit": 1, "allow_on_submit": 1,
@ -133,69 +165,33 @@
}, },
{ {
"allow_bulk_edit": 0, "allow_bulk_edit": 0,
"allow_on_submit": 0, "allow_on_submit": 1,
"bold": 0, "bold": 0,
"collapsible": 0, "collapsible": 0,
"columns": 0, "columns": 0,
"fieldname": "naming_series", "fieldname": "schedule_date",
"fieldtype": "Select", "fieldtype": "Date",
"hidden": 0, "hidden": 0,
"ignore_user_permissions": 0, "ignore_user_permissions": 0,
"ignore_xss_filter": 0, "ignore_xss_filter": 0,
"in_filter": 0, "in_filter": 0,
"in_global_search": 0, "in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Series",
"length": 0,
"no_copy": 1,
"oldfieldname": "naming_series",
"oldfieldtype": "Select",
"options": "MREQ-",
"permlevel": 0,
"print_hide": 1,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
"set_only_once": 1,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "amended_from",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 1,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0, "in_list_view": 0,
"in_standard_filter": 0, "in_standard_filter": 0,
"label": "Amended From", "label": "Required Date",
"length": 0, "length": 0,
"no_copy": 1, "no_copy": 0,
"oldfieldname": "amended_from",
"oldfieldtype": "Data",
"options": "Material Request",
"permlevel": 0, "permlevel": 0,
"print_hide": 1, "precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0, "print_hide_if_no_value": 0,
"print_width": "150px", "read_only": 0,
"read_only": 1,
"remember_last_selected_value": 0, "remember_last_selected_value": 0,
"report_hide": 0, "report_hide": 0,
"reqd": 0, "reqd": 0,
"search_index": 0, "search_index": 0,
"set_only_once": 0, "set_only_once": 0,
"unique": 0, "unique": 0
"width": "150px"
}, },
{ {
"allow_bulk_edit": 0, "allow_bulk_edit": 0,
@ -232,6 +228,40 @@
"unique": 0, "unique": 0,
"width": "150px" "width": "150px"
}, },
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "amended_from",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 1,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Amended From",
"length": 0,
"no_copy": 1,
"oldfieldname": "amended_from",
"oldfieldtype": "Data",
"options": "Material Request",
"permlevel": 0,
"print_hide": 1,
"print_hide_if_no_value": 0,
"print_width": "150px",
"read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0,
"width": "150px"
},
{ {
"allow_bulk_edit": 0, "allow_bulk_edit": 0,
"allow_on_submit": 0, "allow_on_submit": 0,
@ -686,7 +716,7 @@
"istable": 0, "istable": 0,
"max_attachments": 0, "max_attachments": 0,
"menu_index": 0, "menu_index": 0,
"modified": "2017-07-26 19:43:31.823549", "modified": "2017-10-05 18:24:17.148782",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Stock", "module": "Stock",
"name": "Material Request", "name": "Material Request",

View File

@ -54,9 +54,18 @@ class MaterialRequest(BuyingController):
frappe.throw(_("Material Request of maximum {0} can be made for Item {1} against Sales Order {2}").format(actual_so_qty - already_indented, item, so_no)) frappe.throw(_("Material Request of maximum {0} can be made for Item {1} against Sales Order {2}").format(actual_so_qty - already_indented, item, so_no))
def validate_schedule_date(self): def validate_schedule_date(self):
for d in self.get('items'): if not self.schedule_date:
if d.schedule_date and getdate(d.schedule_date) < getdate(self.transaction_date): self.schedule_date = max([d.schedule_date for d in self.get("items")])
frappe.throw(_("Expected Date cannot be before Material Request Date"))
if self.schedule_date:
for d in self.get('items'):
if not d.schedule_date:
d.schedule_date = self.schedule_date
if d.schedule_date and getdate(d.schedule_date) < getdate(self.transaction_date):
frappe.throw(_("Expected Date cannot be before Material Request Date"))
else:
frappe.throw(_("Please enter Schedule Date"))
# Validate # Validate
# --------------------- # ---------------------
@ -70,9 +79,9 @@ class MaterialRequest(BuyingController):
self.status = "Draft" self.status = "Draft"
from erpnext.controllers.status_updater import validate_status from erpnext.controllers.status_updater import validate_status
validate_status(self.status, ["Draft", "Submitted", "Stopped", "Cancelled", "Pending", validate_status(self.status,
"Partially Ordered", "Ordered", "Issued", "Transferred"] ["Draft", "Submitted", "Stopped", "Cancelled", "Pending",
) "Partially Ordered", "Ordered", "Issued", "Transferred"])
validate_for_items(self) validate_for_items(self)

View File

@ -29,7 +29,8 @@
], ],
"material_request_type": "Purchase", "material_request_type": "Purchase",
"naming_series": "_T-Material Request-", "naming_series": "_T-Material Request-",
"transaction_date": "2013-02-18" "transaction_date": "2013-02-18",
"schedule_date": "2013-02-19"
}, },
{ {
"company": "_Test Company", "company": "_Test Company",
@ -43,13 +44,14 @@
"item_name": "_Test FG Item", "item_name": "_Test FG Item",
"parentfield": "items", "parentfield": "items",
"qty": 5, "qty": 5,
"schedule_date": "2013-02-18", "schedule_date": "2013-02-19",
"uom": "_Test UOM 1", "uom": "_Test UOM 1",
"warehouse": "_Test Warehouse - _TC" "warehouse": "_Test Warehouse - _TC"
} }
], ],
"material_request_type": "Manufacture", "material_request_type": "Manufacture",
"naming_series": "_T-Material Request-", "naming_series": "_T-Material Request-",
"transaction_date": "2013-02-18" "transaction_date": "2013-02-18",
"schedule_date": "2013-02-19"
} }
] ]

View File

@ -11,14 +11,25 @@ QUnit.test("test material request", function(assert) {
{'schedule_date': frappe.datetime.add_days(frappe.datetime.nowdate(), 5)}, {'schedule_date': frappe.datetime.add_days(frappe.datetime.nowdate(), 5)},
{'qty': 5}, {'qty': 5},
{'item_code': 'Test Product 1'}, {'item_code': 'Test Product 1'},
],
[
{'schedule_date': frappe.datetime.add_days(frappe.datetime.nowdate(), 6)},
{'qty': 2},
{'item_code': 'Test Product 2'},
] ]
]}, ]},
]); ]);
}, },
() => cur_frm.save(), () => cur_frm.save(),
() => { () => {
assert.ok(cur_frm.doc.schedule_date == frappe.datetime.add_days(frappe.datetime.now_date(), 5), "Schedule Date correct");
// get_item_details // get_item_details
assert.ok(cur_frm.doc.items[0].item_name=='Test Product 1', "Item name correct"); assert.ok(cur_frm.doc.items[0].item_name=='Test Product 1', "Item name correct");
assert.ok(cur_frm.doc.items[0].schedule_date == frappe.datetime.add_days(frappe.datetime.now_date(), 5), "Schedule Date correct");
assert.ok(cur_frm.doc.items[1].item_name=='Test Product 2', "Item name correct");
assert.ok(cur_frm.doc.items[1].schedule_date == frappe.datetime.add_days(frappe.datetime.now_date(), 6), "Schedule Date correct");
}, },
() => frappe.tests.click_button('Submit'), () => frappe.tests.click_button('Submit'),
() => frappe.tests.click_button('Yes'), () => frappe.tests.click_button('Yes'),

View File

@ -121,7 +121,8 @@ def create_material_request(material_requests):
mr.update({ mr.update({
"company": company, "company": company,
"transaction_date": nowdate(), "transaction_date": nowdate(),
"material_request_type": "Material Transfer" if request_type=="Transfer" else request_type "material_request_type": "Material Transfer" if request_type=="Transfer" else request_type,
"schedule_date": add_days(nowdate(), cint(items[0].lead_time_days))
}) })
for d in items: for d in items: