feat: Trigger rule application from client side
- Table is reset and overwritten with applied rules on checkbox trigger - Sider fixes
This commit is contained in:
@@ -517,26 +517,3 @@ erpnext.buying.get_items_from_product_bundle = function(frm) {
|
|||||||
|
|
||||||
dialog.show();
|
dialog.show();
|
||||||
}
|
}
|
||||||
|
|
||||||
erpnext.apply_putaway_rule = (frm) => {
|
|
||||||
if (!frm.doc.company) {
|
|
||||||
frappe.throw({message:__("Please select a Company first."), title: __("Mandatory")})
|
|
||||||
}
|
|
||||||
if (!frm.doc.items.length) return;
|
|
||||||
|
|
||||||
frappe.call({
|
|
||||||
method: "erpnext.stock.doctype.putaway_rule.putaway_rule.apply_putaway_rule",
|
|
||||||
args: {
|
|
||||||
items: frm.doc.items,
|
|
||||||
company: frm.doc.company
|
|
||||||
},
|
|
||||||
callback: (result) => {
|
|
||||||
if(!result.exc) {
|
|
||||||
if(result.message) {
|
|
||||||
frm.doc.items = result.message;
|
|
||||||
frm.get_field("items").refresh();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
@@ -2029,3 +2029,33 @@ erpnext.show_serial_batch_selector = function (frm, d, callback, on_close, show_
|
|||||||
}, show_dialog);
|
}, show_dialog);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
erpnext.apply_putaway_rule = (frm) => {
|
||||||
|
if (!frm.doc.company) {
|
||||||
|
frappe.throw({message: __("Please select a Company first."), title: __("Mandatory")});
|
||||||
|
}
|
||||||
|
if (!frm.doc.items.length) return;
|
||||||
|
|
||||||
|
frappe.call({
|
||||||
|
method: "erpnext.stock.doctype.putaway_rule.putaway_rule.apply_putaway_rule",
|
||||||
|
args: {
|
||||||
|
doctype: frm.doctype,
|
||||||
|
items: frm.doc.items,
|
||||||
|
company: frm.doc.company,
|
||||||
|
sync: true
|
||||||
|
},
|
||||||
|
callback: (result) => {
|
||||||
|
if (!result.exc && result.message) {
|
||||||
|
frm.clear_table("items");
|
||||||
|
|
||||||
|
let items = result.message;
|
||||||
|
items.forEach((row) => {
|
||||||
|
delete row["name"];
|
||||||
|
let child = frm.add_child("items");
|
||||||
|
Object.assign(child, row);
|
||||||
|
});
|
||||||
|
frm.get_field("items").grid.refresh();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
@@ -30,8 +30,8 @@ erpnext.stock.ItemDashboard = Class.extend({
|
|||||||
let company = unescape($(this).attr('data-company'));
|
let company = unescape($(this).attr('data-company'));
|
||||||
frappe.db.get_value('Putaway Rule',
|
frappe.db.get_value('Putaway Rule',
|
||||||
{'item_code': item, 'warehouse': warehouse, 'company': company}, 'name', (r) => {
|
{'item_code': item, 'warehouse': warehouse, 'company': company}, 'name', (r) => {
|
||||||
frappe.set_route("Form", "Putaway Rule", r.name);
|
frappe.set_route("Form", "Putaway Rule", r.name);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
function handle_move_add(element, action) {
|
function handle_move_add(element, action) {
|
||||||
@@ -88,7 +88,7 @@ erpnext.stock.ItemDashboard = Class.extend({
|
|||||||
start: this.start,
|
start: this.start,
|
||||||
sort_by: this.sort_by,
|
sort_by: this.sort_by,
|
||||||
sort_order: this.sort_order
|
sort_order: this.sort_order
|
||||||
}
|
};
|
||||||
|
|
||||||
var me = this;
|
var me = this;
|
||||||
frappe.call({
|
frappe.call({
|
||||||
@@ -104,10 +104,12 @@ erpnext.stock.ItemDashboard = Class.extend({
|
|||||||
this.max_count = 0;
|
this.max_count = 0;
|
||||||
this.result.empty();
|
this.result.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let context = "";
|
||||||
if (this.page_name === "warehouse-capacity-summary") {
|
if (this.page_name === "warehouse-capacity-summary") {
|
||||||
var context = this.get_capacity_dashboard_data(data);
|
context = this.get_capacity_dashboard_data(data);
|
||||||
} else {
|
} else {
|
||||||
var context = this.get_item_dashboard_data(data, this.max_count, true);
|
context = this.get_item_dashboard_data(data, this.max_count, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.max_count = this.max_count;
|
this.max_count = this.max_count;
|
||||||
@@ -152,7 +154,7 @@ erpnext.stock.ItemDashboard = Class.extend({
|
|||||||
});
|
});
|
||||||
|
|
||||||
let can_write = 0;
|
let can_write = 0;
|
||||||
if(frappe.boot.user.can_write.indexOf("Stock Entry")>=0){
|
if (frappe.boot.user.can_write.indexOf("Stock Entry") >= 0) {
|
||||||
can_write = 1;
|
can_write = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -165,23 +167,23 @@ erpnext.stock.ItemDashboard = Class.extend({
|
|||||||
},
|
},
|
||||||
|
|
||||||
get_capacity_dashboard_data: function(data) {
|
get_capacity_dashboard_data: function(data) {
|
||||||
if(!data) data = [];
|
if (!data) data = [];
|
||||||
|
|
||||||
data.forEach(function(d) {
|
data.forEach(function(d) {
|
||||||
d.color = d.percent_occupied >=80 ? "#f8814f" : "#2490ef";
|
d.color = d.percent_occupied >=80 ? "#f8814f" : "#2490ef";
|
||||||
});
|
});
|
||||||
|
|
||||||
let can_write = 0;
|
let can_write = 0;
|
||||||
if(frappe.boot.user.can_write.indexOf("Putaway Rule")>=0){
|
if (frappe.boot.user.can_write.indexOf("Putaway Rule") >= 0) {
|
||||||
can_write = 1;
|
can_write = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
data: data,
|
data: data,
|
||||||
can_write: can_write,
|
can_write: can_write,
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
|
|
||||||
erpnext.stock.move_item = function(item, source, target, actual_qty, rate, callback) {
|
erpnext.stock.move_item = function(item, source, target, actual_qty, rate, callback) {
|
||||||
var dialog = new frappe.ui.Dialog({
|
var dialog = new frappe.ui.Dialog({
|
||||||
|
|||||||
@@ -214,7 +214,7 @@ erpnext.stock.PurchaseReceiptController = erpnext.buying.BuyingController.extend
|
|||||||
},
|
},
|
||||||
|
|
||||||
apply_putaway_rule: function() {
|
apply_putaway_rule: function() {
|
||||||
// if (this.frm.doc.apply_putaway_rule) erpnext.apply_putaway_rule(this.frm);
|
if (this.frm.doc.apply_putaway_rule) erpnext.apply_putaway_rule(this.frm);
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -87,7 +87,7 @@ class PurchaseReceipt(BuyingController):
|
|||||||
from erpnext.stock.doctype.putaway_rule.putaway_rule import apply_putaway_rule
|
from erpnext.stock.doctype.putaway_rule.putaway_rule import apply_putaway_rule
|
||||||
|
|
||||||
if self.get("items") and self.apply_putaway_rule:
|
if self.get("items") and self.apply_putaway_rule:
|
||||||
self.items = apply_putaway_rule(self.doctype, self.get("items"), self.company)
|
apply_putaway_rule(self.doctype, self.get("items"), self.company)
|
||||||
|
|
||||||
def validate(self):
|
def validate(self):
|
||||||
self.validate_posting_time()
|
self.validate_posting_time()
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ def get_putaway_capacity(rule):
|
|||||||
return free_space if free_space > 0 else 0
|
return free_space if free_space > 0 else 0
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def apply_putaway_rule(doctype, items, company):
|
def apply_putaway_rule(doctype, items, company, sync=None):
|
||||||
""" Applies Putaway Rule on line items.
|
""" Applies Putaway Rule on line items.
|
||||||
|
|
||||||
items: List of Purchase Receipt Item objects
|
items: List of Purchase Receipt Item objects
|
||||||
@@ -82,7 +82,7 @@ def apply_putaway_rule(doctype, items, company):
|
|||||||
|
|
||||||
source_warehouse = item.get("s_warehouse")
|
source_warehouse = item.get("s_warehouse")
|
||||||
serial_nos = get_serial_nos(item.get("serial_no"))
|
serial_nos = get_serial_nos(item.get("serial_no"))
|
||||||
conversion = flt(item.conversion_factor) or 1
|
item.conversion_factor = flt(item.conversion_factor) or 1
|
||||||
pending_qty, item_code = flt(item.qty), item.item_code
|
pending_qty, item_code = flt(item.qty), item.item_code
|
||||||
pending_stock_qty = flt(item.transfer_qty) if doctype == "Stock Entry" else flt(item.stock_qty)
|
pending_stock_qty = flt(item.transfer_qty) if doctype == "Stock Entry" else flt(item.stock_qty)
|
||||||
if not pending_qty or not item_code:
|
if not pending_qty or not item_code:
|
||||||
@@ -109,11 +109,11 @@ def apply_putaway_rule(doctype, items, company):
|
|||||||
for rule in item_wise_rules[item_code]:
|
for rule in item_wise_rules[item_code]:
|
||||||
if pending_stock_qty > 0 and rule.free_space:
|
if pending_stock_qty > 0 and rule.free_space:
|
||||||
stock_qty_to_allocate = flt(rule.free_space) if pending_stock_qty >= flt(rule.free_space) else pending_stock_qty
|
stock_qty_to_allocate = flt(rule.free_space) if pending_stock_qty >= flt(rule.free_space) else pending_stock_qty
|
||||||
qty_to_allocate = stock_qty_to_allocate / (conversion)
|
qty_to_allocate = stock_qty_to_allocate / item.conversion_factor
|
||||||
|
|
||||||
if uom_must_be_whole_number:
|
if uom_must_be_whole_number:
|
||||||
qty_to_allocate = floor(qty_to_allocate)
|
qty_to_allocate = floor(qty_to_allocate)
|
||||||
stock_qty_to_allocate = qty_to_allocate * conversion
|
stock_qty_to_allocate = qty_to_allocate * item.conversion_factor
|
||||||
|
|
||||||
if not qty_to_allocate: break
|
if not qty_to_allocate: break
|
||||||
|
|
||||||
@@ -124,17 +124,19 @@ def apply_putaway_rule(doctype, items, company):
|
|||||||
pending_qty -= qty_to_allocate
|
pending_qty -= qty_to_allocate
|
||||||
rule["free_space"] -= stock_qty_to_allocate
|
rule["free_space"] -= stock_qty_to_allocate
|
||||||
|
|
||||||
if not pending_stock_qty: break
|
if not pending_stock_qty > 0: break
|
||||||
|
|
||||||
# if pending qty after applying all rules, add row without warehouse
|
# if pending qty after applying all rules, add row without warehouse
|
||||||
if pending_stock_qty > 0:
|
if pending_stock_qty > 0:
|
||||||
# updated_table = add_row(item, pending_qty, '', updated_table, serial_nos=serial_nos)
|
|
||||||
items_not_accomodated.append([item.item_code, pending_qty])
|
items_not_accomodated.append([item.item_code, pending_qty])
|
||||||
|
|
||||||
if items_not_accomodated:
|
if items_not_accomodated:
|
||||||
show_unassigned_items_message(items_not_accomodated)
|
show_unassigned_items_message(items_not_accomodated)
|
||||||
|
|
||||||
return updated_table if updated_table else items
|
items[:] = updated_table if updated_table else items # modify items table
|
||||||
|
|
||||||
|
if sync and json.loads(sync): # sync with client side
|
||||||
|
return items
|
||||||
|
|
||||||
def get_ordered_putaway_rules(item_code, company, source_warehouse=None):
|
def get_ordered_putaway_rules(item_code, company, source_warehouse=None):
|
||||||
"""Returns an ordered list of putaway rules to apply on an item."""
|
"""Returns an ordered list of putaway rules to apply on an item."""
|
||||||
@@ -174,12 +176,14 @@ def get_ordered_putaway_rules(item_code, company, source_warehouse=None):
|
|||||||
def add_row(item, to_allocate, warehouse, updated_table, rule=None, serial_nos=None):
|
def add_row(item, to_allocate, warehouse, updated_table, rule=None, serial_nos=None):
|
||||||
new_updated_table_row = copy.deepcopy(item)
|
new_updated_table_row = copy.deepcopy(item)
|
||||||
new_updated_table_row.idx = 1 if not updated_table else cint(updated_table[-1].idx) + 1
|
new_updated_table_row.idx = 1 if not updated_table else cint(updated_table[-1].idx) + 1
|
||||||
new_updated_table_row.name = "New " + str(item.doctype) + " " + str(new_updated_table_row.idx)
|
new_updated_table_row.name = None
|
||||||
new_updated_table_row.qty = to_allocate
|
new_updated_table_row.qty = to_allocate
|
||||||
new_updated_table_row.stock_qty = flt(to_allocate) * flt(new_updated_table_row.conversion_factor)
|
|
||||||
if item.doctype == "Stock Entry Detail":
|
if item.doctype == "Stock Entry Detail":
|
||||||
new_updated_table_row.t_warehouse = warehouse
|
new_updated_table_row.t_warehouse = warehouse
|
||||||
|
new_updated_table_row.transfer_qty = flt(to_allocate) * flt(new_updated_table_row.conversion_factor)
|
||||||
else:
|
else:
|
||||||
|
new_updated_table_row.stock_qty = flt(to_allocate) * flt(new_updated_table_row.conversion_factor)
|
||||||
new_updated_table_row.warehouse = warehouse
|
new_updated_table_row.warehouse = warehouse
|
||||||
new_updated_table_row.rejected_qty = 0
|
new_updated_table_row.rejected_qty = 0
|
||||||
new_updated_table_row.received_qty = to_allocate
|
new_updated_table_row.received_qty = to_allocate
|
||||||
|
|||||||
@@ -573,10 +573,10 @@ frappe.ui.form.on('Stock Entry', {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
apply_putaway_rule: function(frm) {
|
apply_putaway_rule: function (frm) {
|
||||||
// if (frm.doc.apply_putaway_rule) erpnext.apply_putaway_rule(frm);
|
if (frm.doc.apply_putaway_rule) erpnext.apply_putaway_rule(frm);
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
|
|
||||||
frappe.ui.form.on('Stock Entry Detail', {
|
frappe.ui.form.on('Stock Entry Detail', {
|
||||||
qty: function(frm, cdt, cdn) {
|
qty: function(frm, cdt, cdn) {
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ class StockEntry(StockController):
|
|||||||
apply_rule = self.apply_putaway_rule and (self.purpose in ["Material Transfer", "Material Receipt"])
|
apply_rule = self.apply_putaway_rule and (self.purpose in ["Material Transfer", "Material Receipt"])
|
||||||
|
|
||||||
if self.get("items") and apply_rule:
|
if self.get("items") and apply_rule:
|
||||||
self.items = apply_putaway_rule(self.doctype, self.get("items"), self.company)
|
apply_putaway_rule(self.doctype, self.get("items"), self.company)
|
||||||
|
|
||||||
def validate(self):
|
def validate(self):
|
||||||
self.pro_doc = frappe._dict()
|
self.pro_doc = frappe._dict()
|
||||||
|
|||||||
@@ -10,8 +10,8 @@ frappe.pages['warehouse-capacity-summary'].on_page_load = function(wrapper) {
|
|||||||
page.company_field = page.add_field({
|
page.company_field = page.add_field({
|
||||||
fieldname: 'company',
|
fieldname: 'company',
|
||||||
label: __('Company'),
|
label: __('Company'),
|
||||||
fieldtype:'Link',
|
fieldtype: 'Link',
|
||||||
options:'Company',
|
options: 'Company',
|
||||||
reqd: 1,
|
reqd: 1,
|
||||||
default: frappe.defaults.get_default("company"),
|
default: frappe.defaults.get_default("company"),
|
||||||
change: function() {
|
change: function() {
|
||||||
@@ -23,8 +23,8 @@ frappe.pages['warehouse-capacity-summary'].on_page_load = function(wrapper) {
|
|||||||
page.warehouse_field = page.add_field({
|
page.warehouse_field = page.add_field({
|
||||||
fieldname: 'warehouse',
|
fieldname: 'warehouse',
|
||||||
label: __('Warehouse'),
|
label: __('Warehouse'),
|
||||||
fieldtype:'Link',
|
fieldtype: 'Link',
|
||||||
options:'Warehouse',
|
options: 'Warehouse',
|
||||||
change: function() {
|
change: function() {
|
||||||
page.capacity_dashboard.start = 0;
|
page.capacity_dashboard.start = 0;
|
||||||
page.capacity_dashboard.refresh();
|
page.capacity_dashboard.refresh();
|
||||||
@@ -34,8 +34,8 @@ frappe.pages['warehouse-capacity-summary'].on_page_load = function(wrapper) {
|
|||||||
page.item_field = page.add_field({
|
page.item_field = page.add_field({
|
||||||
fieldname: 'item_code',
|
fieldname: 'item_code',
|
||||||
label: __('Item'),
|
label: __('Item'),
|
||||||
fieldtype:'Link',
|
fieldtype: 'Link',
|
||||||
options:'Item',
|
options: 'Item',
|
||||||
change: function() {
|
change: function() {
|
||||||
page.capacity_dashboard.start = 0;
|
page.capacity_dashboard.start = 0;
|
||||||
page.capacity_dashboard.refresh();
|
page.capacity_dashboard.refresh();
|
||||||
@@ -45,8 +45,8 @@ frappe.pages['warehouse-capacity-summary'].on_page_load = function(wrapper) {
|
|||||||
page.parent_warehouse_field = page.add_field({
|
page.parent_warehouse_field = page.add_field({
|
||||||
fieldname: 'parent_warehouse',
|
fieldname: 'parent_warehouse',
|
||||||
label: __('Parent Warehouse'),
|
label: __('Parent Warehouse'),
|
||||||
fieldtype:'Link',
|
fieldtype: 'Link',
|
||||||
options:'Warehouse',
|
options: 'Warehouse',
|
||||||
get_query: function() {
|
get_query: function() {
|
||||||
return {
|
return {
|
||||||
filters: {
|
filters: {
|
||||||
@@ -67,8 +67,8 @@ frappe.pages['warehouse-capacity-summary'].on_page_load = function(wrapper) {
|
|||||||
sort_order: 'desc',
|
sort_order: 'desc',
|
||||||
options: [
|
options: [
|
||||||
{fieldname: 'stock_capacity', label: __('Capacity (Stock UOM)')},
|
{fieldname: 'stock_capacity', label: __('Capacity (Stock UOM)')},
|
||||||
{fieldname: 'percent_occupied', label:__('% Occupied')},
|
{fieldname: 'percent_occupied', label: __('% Occupied')},
|
||||||
{fieldname: 'actual_qty', label:__('Balance Qty (Stock ')}
|
{fieldname: 'actual_qty', label: __('Balance Qty (Stock ')}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
change: function(sort_by, sort_order) {
|
change: function(sort_by, sort_order) {
|
||||||
@@ -90,14 +90,14 @@ frappe.pages['warehouse-capacity-summary'].on_page_load = function(wrapper) {
|
|||||||
sort_order: 'desc',
|
sort_order: 'desc',
|
||||||
method: 'erpnext.stock.dashboard.warehouse_capacity_dashboard.get_data',
|
method: 'erpnext.stock.dashboard.warehouse_capacity_dashboard.get_data',
|
||||||
template: 'warehouse_capacity_summary'
|
template: 'warehouse_capacity_summary'
|
||||||
})
|
});
|
||||||
|
|
||||||
page.capacity_dashboard.before_refresh = function() {
|
page.capacity_dashboard.before_refresh = function() {
|
||||||
this.item_code = page.item_field.get_value();
|
this.item_code = page.item_field.get_value();
|
||||||
this.warehouse = page.warehouse_field.get_value();
|
this.warehouse = page.warehouse_field.get_value();
|
||||||
this.parent_warehouse = page.parent_warehouse_field.get_value();
|
this.parent_warehouse = page.parent_warehouse_field.get_value();
|
||||||
this.company = page.company_field.get_value();
|
this.company = page.company_field.get_value();
|
||||||
}
|
};
|
||||||
|
|
||||||
page.capacity_dashboard.refresh();
|
page.capacity_dashboard.refresh();
|
||||||
|
|
||||||
@@ -105,16 +105,16 @@ frappe.pages['warehouse-capacity-summary'].on_page_load = function(wrapper) {
|
|||||||
page.main.on('click', 'a[data-type="'+ doctype.toLowerCase() +'"]', function() {
|
page.main.on('click', 'a[data-type="'+ doctype.toLowerCase() +'"]', function() {
|
||||||
var name = $(this).attr('data-name');
|
var name = $(this).attr('data-name');
|
||||||
var field = page[doctype.toLowerCase() + '_field'];
|
var field = page[doctype.toLowerCase() + '_field'];
|
||||||
if(field.get_value()===name) {
|
if (field.get_value()===name) {
|
||||||
frappe.set_route('Form', doctype, name)
|
frappe.set_route('Form', doctype, name);
|
||||||
} else {
|
} else {
|
||||||
field.set_input(name);
|
field.set_input(name);
|
||||||
page.capacity_dashboard.refresh();
|
page.capacity_dashboard.refresh();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
setup_click('Item');
|
setup_click('Item');
|
||||||
setup_click('Warehouse');
|
setup_click('Warehouse');
|
||||||
});
|
});
|
||||||
}
|
};
|
||||||
Reference in New Issue
Block a user