feat: add pending qty section to batch/serial selector dialog (#25519)

* feat: add pending qty section to batch/serial selector dialog

* fix: call attach in setup and refresh, fix conditional

* refactor: camel to snake casing
This commit is contained in:
Alan
2021-05-14 12:36:41 +05:30
committed by GitHub
parent 2aa401826e
commit 55c2fec683
2 changed files with 96 additions and 1 deletions

View File

@@ -74,9 +74,10 @@ erpnext.SerialNoBatchSelector = Class.extend({
fieldname: 'qty',
fieldtype:'Float',
read_only: me.has_batch && !me.has_serial_no,
label: __(me.has_batch && !me.has_serial_no ? 'Total Qty' : 'Qty'),
label: __(me.has_batch && !me.has_serial_no ? 'Selected Qty' : 'Qty'),
default: flt(me.item.stock_qty),
},
...get_pending_qty_fields(me),
{
fieldname: 'uom',
read_only: 1,
@@ -181,6 +182,7 @@ erpnext.SerialNoBatchSelector = Class.extend({
if (this.has_batch && !this.has_serial_no) {
this.update_total_qty();
this.update_pending_qtys();
}
this.dialog.show();
@@ -321,7 +323,21 @@ erpnext.SerialNoBatchSelector = Class.extend({
qty_field.set_input(total_qty);
},
update_pending_qtys: function() {
const pending_qty_field = this.dialog.fields_dict.pending_qty;
const total_selected_qty_field = this.dialog.fields_dict.total_selected_qty;
if (!pending_qty_field || !total_selected_qty_field) return;
const me = this;
const required_qty = this.dialog.fields_dict.required_qty.value;
const selected_qty = this.dialog.fields_dict.qty.value;
const total_selected_qty = selected_qty + calc_total_selected_qty(me);
const pending_qty = required_qty - total_selected_qty;
pending_qty_field.set_input(pending_qty);
total_selected_qty_field.set_input(total_selected_qty);
},
get_batch_fields: function() {
var me = this;
@@ -423,6 +439,7 @@ erpnext.SerialNoBatchSelector = Class.extend({
}
me.update_total_qty();
me.update_pending_qtys();
}
},
],
@@ -519,3 +536,60 @@ erpnext.SerialNoBatchSelector = Class.extend({
];
}
});
function get_pending_qty_fields(me) {
if (!check_can_calculate_pending_qty(me)) return [];
const { frm: { doc: { fg_completed_qty }}, item: { item_code, stock_qty }} = me;
const { qty_consumed_per_unit } = erpnext.stock.bom.items[item_code];
const total_selected_qty = calc_total_selected_qty(me);
const required_qty = flt(fg_completed_qty) * flt(qty_consumed_per_unit);
const pending_qty = required_qty - (flt(stock_qty) + total_selected_qty);
const pending_qty_fields = [
{ fieldtype: 'Section Break', label: __('Pending Quantity') },
{
fieldname: 'required_qty',
read_only: 1,
fieldtype: 'Float',
label: __('Required Qty'),
default: required_qty
},
{ fieldtype: 'Column Break' },
{
fieldname: 'total_selected_qty',
read_only: 1,
fieldtype: 'Float',
label: __('Total Selected Qty'),
default: total_selected_qty
},
{ fieldtype: 'Column Break' },
{
fieldname: 'pending_qty',
read_only: 1,
fieldtype: 'Float',
label: __('Pending Qty'),
default: pending_qty
},
];
return pending_qty_fields;
}
function calc_total_selected_qty(me) {
const { frm: { doc: { items }}, item: { name, item_code }} = me;
const totalSelectedQty = items
.filter( item => ( item.name !== name ) && ( item.item_code === item_code ) )
.map( item => flt(item.qty) )
.reduce( (i, j) => i + j, 0);
return totalSelectedQty;
}
function check_can_calculate_pending_qty(me) {
const { frm: { doc }, item } = me;
const docChecks = doc.bom_no
&& doc.fg_completed_qty
&& erpnext.stock.bom
&& erpnext.stock.bom.name === doc.bom_no;
const itemChecks = !!item;
return docChecks && itemChecks;
}