|
|
@@ -1,102 +1,762 @@
|
|
|
<% layout('/layouts/default.html', {title: '生产用料清单', libs: ['dataGrid']}){ %>
|
|
|
+
|
|
|
<div class="main-content">
|
|
|
+
|
|
|
<div class="box box-main">
|
|
|
+
|
|
|
<div class="box-header">
|
|
|
+
|
|
|
<div class="box-title">
|
|
|
+
|
|
|
<i class="fa fa-list-ul"></i> ${text('增加领料单 - 生产用料清单')}:${erpProductionOrder.billNo}
|
|
|
+
|
|
|
</div>
|
|
|
+
|
|
|
<div class="box-tools pull-right">
|
|
|
+
|
|
|
<a href="javascript:void(0)" class="btn btn-primary" id="btnSubmitPick"><i class="fa fa-check"></i> ${text('提交领料')}</a>
|
|
|
+
|
|
|
<a href="${ctx}/mes/erpPickMaterialBill/selectDetail?billNo=${erpProductionOrder.billNo!}" class="btn btn-default addTabPage" title="${text('返回')}"><i class="fa fa-mail-reply"></i> ${text('返回')}</a>
|
|
|
+
|
|
|
<a href="#" class="btn btn-default" id="btnSetting" title="${text('设置')}"><i class="fa fa-navicon"></i></a>
|
|
|
+
|
|
|
</div>
|
|
|
+
|
|
|
</div>
|
|
|
- <div class="box-body">
|
|
|
+
|
|
|
+ <div class="box-body pick-material-grid-wrap">
|
|
|
+
|
|
|
+ <div class="alert alert-info" style="margin-bottom:10px;padding:8px 12px;">
|
|
|
+
|
|
|
+ <i class="fa fa-info-circle"></i>
|
|
|
+
|
|
|
+ ${text('启用批号管理的物料,系统查询 ERP 即时库存批号;发料仓无库存时会查组织内其他仓库。请点击「选批号」弹窗选择(与 ERP 即时库存一致)。')}
|
|
|
+
|
|
|
+ </div>
|
|
|
+
|
|
|
<#form:form id="searchForm" model="${erpProductionOrder}" action="${ctx}/mes/erpPickMaterialBill/materialData" method="post" class="form-inline hide"
|
|
|
+
|
|
|
data-page-no="${parameter.pageNo}" data-page-size="${parameter.pageSize}" data-order-by="${parameter.orderBy}">
|
|
|
+
|
|
|
<#form:hidden path="billNo"/>
|
|
|
+
|
|
|
<#form:hidden path="entryId"/>
|
|
|
+
|
|
|
</#form:form>
|
|
|
+
|
|
|
<table id="dataGrid"></table>
|
|
|
+
|
|
|
<div id="dataGridPage"></div>
|
|
|
+
|
|
|
</div>
|
|
|
+
|
|
|
</div>
|
|
|
+
|
|
|
</div>
|
|
|
+
|
|
|
<% } %>
|
|
|
+<style>
|
|
|
+.pick-material-grid-wrap { overflow-x: auto; }
|
|
|
+.pick-row-finished td { background-color: #fafafa !important; color: #999; }
|
|
|
+.pick-row-finished .pick-qty-input { background-color: #eee; }
|
|
|
+.pick-lot-wrap { min-width: 200px; line-height: 1.4; }
|
|
|
+.pick-lot-wrap .pick-lot-actions { margin-bottom: 4px; }
|
|
|
+.pick-lot-wrap .pick-lot-display {
|
|
|
+ display: block;
|
|
|
+ font-size: 11px;
|
|
|
+ color: #666;
|
|
|
+ max-width: 240px;
|
|
|
+ overflow: hidden;
|
|
|
+ text-overflow: ellipsis;
|
|
|
+ white-space: nowrap;
|
|
|
+ cursor: pointer;
|
|
|
+}
|
|
|
+.pick-lot-wrap .pick-lot-display:hover { color: #337ab7; text-decoration: underline; }
|
|
|
+.pick-lot-wrap .pick-lot-select { width: 100%; max-width: 240px; margin-top: 4px; }
|
|
|
+.pick-lot-hint-text {
|
|
|
+ display: block;
|
|
|
+ max-width: 220px;
|
|
|
+ overflow: hidden;
|
|
|
+ text-overflow: ellipsis;
|
|
|
+ white-space: nowrap;
|
|
|
+ cursor: help;
|
|
|
+}
|
|
|
+.pick-qty-hint-text {
|
|
|
+ display: block;
|
|
|
+ max-width: 240px;
|
|
|
+ overflow: hidden;
|
|
|
+ text-overflow: ellipsis;
|
|
|
+ white-space: nowrap;
|
|
|
+ cursor: help;
|
|
|
+}
|
|
|
+.lot-search-table-wrap { overflow: auto; max-height: 340px; }
|
|
|
+.lot-search-table-wrap table { min-width: 620px; margin: 0; font-size: 12px; }
|
|
|
+.lot-search-table-wrap .lot-search-pick { min-width: 48px; }
|
|
|
+</style>
|
|
|
<script>
|
|
|
+
|
|
|
var billNo = '${erpProductionOrder.billNo!}';
|
|
|
+
|
|
|
var entryId = '${erpProductionOrder.entryId!}';
|
|
|
|
|
|
+var lotOptionsUrl = '${ctx}/mes/erpPickMaterialBill/lotOptions';
|
|
|
+var lotSearchUrl = '${ctx}/mes/erpPickMaterialBill/lotSearch';
|
|
|
+
|
|
|
+function escapeHtml(text) {
|
|
|
+ if (text == null) return '';
|
|
|
+ return String(text).replace(/&/g,'&').replace(/"/g,'"').replace(/</g,'<').replace(/>/g,'>');
|
|
|
+}
|
|
|
+
|
|
|
+function readLotQtyText(lot) {
|
|
|
+ if (!lot) return '0';
|
|
|
+ if (lot.qtyText != null && lot.qtyText !== '') return String(lot.qtyText);
|
|
|
+ var q = lot.qty;
|
|
|
+ if (q == null || q === '') return '0';
|
|
|
+ if (typeof q === 'number') return String(q);
|
|
|
+ if (typeof q === 'string') return q;
|
|
|
+ return String(q);
|
|
|
+}
|
|
|
+
|
|
|
+function formatLotOptionLabel(lot) {
|
|
|
+ var lotNo = lot.lotNumber || '';
|
|
|
+ var qty = readLotQtyText(lot);
|
|
|
+ var stockLabel = lot.stockName || lot.stockNumber || '';
|
|
|
+ return lotNo + ' (可用:' + qty + (stockLabel ? ' ' + stockLabel : '') + ')';
|
|
|
+}
|
|
|
+
|
|
|
+function readRowLotNumber(rowOrId) {
|
|
|
+ var id = (typeof rowOrId === 'object') ? rowOrId.id : rowOrId;
|
|
|
+ var hidden = $('.pick-lot-value[data-id="'+id+'"]').val();
|
|
|
+ if (hidden && $.trim(hidden) !== '') {
|
|
|
+ return $.trim(hidden);
|
|
|
+ }
|
|
|
+ var $select = $('.pick-lot-select[data-id="'+id+'"]');
|
|
|
+ if ($select.length > 0) {
|
|
|
+ var selected = $.trim($select.val() || '');
|
|
|
+ if (selected !== '') {
|
|
|
+ return selected;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (typeof rowOrId === 'object') {
|
|
|
+ if (rowOrId.pickStatusLabel === '无库存') {
|
|
|
+ return '';
|
|
|
+ }
|
|
|
+ return rowOrId.lotNumber || rowOrId.suggestedLotNumber || '';
|
|
|
+ }
|
|
|
+ return '';
|
|
|
+}
|
|
|
+
|
|
|
+function isRowLotBlocked(row) {
|
|
|
+ if (row.pickStatusLabel === '已领完') {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ if (!row.batchManage) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ if (readRowLotNumber(row)) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ if (row.availableLots && row.availableLots.length > 0) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ return row.pickStatusLabel === '待选批号' || row.lotPickable === false;
|
|
|
+}
|
|
|
+
|
|
|
+function isRowPickable(row) {
|
|
|
+ if (!row.noPickedQty || row.noPickedQty <= 0) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ if (row.canPickQty != null && row.canPickQty <= 0) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ if (row.pickStatusLabel === '无库存' || row.pickStatusLabel === '已领完' || row.pickStatusLabel === '不可领') {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ if (!row.batchManage) {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ if (readRowLotNumber(row)) {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ if (row.availableLots && row.availableLots.length > 0) {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ return false;
|
|
|
+}
|
|
|
+
|
|
|
+function formatPickStatus(val, obj, row) {
|
|
|
+ var label = row.pickStatusLabel || (isRowPickable(row) ? '可领料' : '待选批号');
|
|
|
+ if (readRowLotNumber(row)) {
|
|
|
+ label = '可领料';
|
|
|
+ }
|
|
|
+ if (label === '可领料') {
|
|
|
+ return '<span class="text-success pick-status" data-id="'+row.id+'">可领料</span>';
|
|
|
+ }
|
|
|
+ if (label === '已领完') {
|
|
|
+ return '<span class="text-muted pick-status" data-id="'+row.id+'">已领完</span>';
|
|
|
+ }
|
|
|
+ if (label === '无库存') {
|
|
|
+ return '<span class="text-danger pick-status" data-id="'+row.id+'">无库存</span>';
|
|
|
+ }
|
|
|
+ if (label === '不可领') {
|
|
|
+ return '<span class="text-danger pick-status" data-id="'+row.id+'">不可领</span>';
|
|
|
+ }
|
|
|
+ return '<span class="text-warning pick-status" data-id="'+row.id+'">待选批号</span>';
|
|
|
+}
|
|
|
+
|
|
|
+function formatStockStatus(val, obj, row) {
|
|
|
+ if (row.pickStatusLabel === '无库存') {
|
|
|
+ return '<span class="text-danger" title="'+escapeHtml(row.lotHint||'')+'">无库存</span>';
|
|
|
+ }
|
|
|
+ if (row.batchManage && !readRowLotNumber(row) && (!row.availableLots || row.availableLots.length === 0)) {
|
|
|
+ return '<span class="text-warning" title="'+escapeHtml(row.lotHint||'')+'">待选批号</span>';
|
|
|
+ }
|
|
|
+ return escapeHtml(val || '-');
|
|
|
+}
|
|
|
+
|
|
|
function formatPickQty(val, obj, row){
|
|
|
var defaultQty = row.noPickedQty == null ? 0 : row.noPickedQty;
|
|
|
+ if (row.canPickQty != null && row.canPickQty > 0 && defaultQty > row.canPickQty) {
|
|
|
+ defaultQty = row.canPickQty;
|
|
|
+ }
|
|
|
var inputVal = val == null || val === '' ? defaultQty : val;
|
|
|
+ var pickable = isRowPickable(row);
|
|
|
+ var readonly = pickable ? '' : 'readonly="readonly"';
|
|
|
return '<input type="text" class="form-control input-sm pick-qty-input" data-id="'+row.id+'" '+
|
|
|
- 'data-no-picked="'+defaultQty+'" data-material="'+(row.materialNumber||'')+'" '+
|
|
|
- 'style="width:90px;text-align:right;" value="'+inputVal+'"/>';
|
|
|
+ 'data-no-picked="'+(row.noPickedQty == null ? 0 : row.noPickedQty)+'" '+
|
|
|
+ 'data-can-pick="'+(row.canPickQty == null ? '' : row.canPickQty)+'" '+
|
|
|
+ 'data-material="'+(row.materialNumber||'')+'" '+
|
|
|
+ 'data-stock="'+(row.stockNumber||'')+'" data-stock-status="'+(row.stockStatusNumber||'')+'" '+
|
|
|
+ 'data-stock-org="'+(row.stockOrgNumber||'')+'" data-batch-manage="'+(row.batchManage?'1':'0')+'" '+
|
|
|
+ readonly+' style="width:90px;text-align:right;" value="'+inputVal+'"/>';
|
|
|
+}
|
|
|
+
|
|
|
+function formatCanPickQty(val, obj, row) {
|
|
|
+ if (val == null || val === '') {
|
|
|
+ return '<span class="text-muted">-</span>';
|
|
|
+ }
|
|
|
+ var cls = val <= 0 ? 'text-danger' : 'text-success';
|
|
|
+ return '<span class="'+cls+'">'+val+'</span>';
|
|
|
+}
|
|
|
+
|
|
|
+function formatPickQtyHint(val, obj, row) {
|
|
|
+ if (!val) {
|
|
|
+ return '';
|
|
|
+ }
|
|
|
+ var cls = (val.indexOf('可领数量 0') >= 0 || val.indexOf('超过') >= 0) ? 'text-danger' : 'text-muted';
|
|
|
+ return '<span class="'+cls+' pick-qty-hint-text" title="'+escapeHtml(val)+'">'+escapeHtml(val)+'</span>';
|
|
|
}
|
|
|
|
|
|
+function buildLotSelectHtml(row) {
|
|
|
+ if (!row.batchManage) {
|
|
|
+ return '<span class="text-muted">-</span>';
|
|
|
+ }
|
|
|
+ var selected = readRowLotNumber(row) || row.lotNumber || row.suggestedLotNumber || '';
|
|
|
+ var lots = row.availableLots || [];
|
|
|
+ var html = '<div class="pick-lot-wrap">';
|
|
|
+ html += '<input type="hidden" class="pick-lot-value" data-id="'+row.id+'" value="'+escapeHtml(selected)+'"/>';
|
|
|
+ html += '<div class="pick-lot-actions">';
|
|
|
+ html += '<a href="javascript:void(0)" class="btn btn-xs btn-primary pick-lot-open" data-id="'+row.id+'" '+
|
|
|
+ 'data-material="'+escapeHtml(row.materialNumber||'')+'" data-material-name="'+escapeHtml(row.materialName||'')+'" '+
|
|
|
+ 'data-stock="'+escapeHtml(row.stockNumber||'')+'" data-stock-name="'+escapeHtml(row.stockName||'')+'" '+
|
|
|
+ 'data-stock-status="'+escapeHtml(row.stockStatusNumber||'')+'" data-stock-org="'+escapeHtml(row.stockOrgNumber||'')+'">'+
|
|
|
+ '<i class="fa fa-search"></i> 选批号</a>';
|
|
|
+ html += '</div>';
|
|
|
+ if (lots.length > 0) {
|
|
|
+ html += '<select class="form-control input-sm pick-lot-select" data-id="'+row.id+'" '+
|
|
|
+ 'data-batch-manage="1" data-material="'+escapeHtml(row.materialNumber||'')+'" '+
|
|
|
+ 'data-material-name="'+escapeHtml(row.materialName||'')+'" '+
|
|
|
+ 'data-stock="'+escapeHtml(row.stockNumber||'')+'" '+
|
|
|
+ 'data-stock-name="'+escapeHtml(row.stockName||'')+'" '+
|
|
|
+ 'data-stock-status="'+escapeHtml(row.stockStatusNumber||'')+'" '+
|
|
|
+ 'data-stock-org="'+escapeHtml(row.stockOrgNumber||'')+'">';
|
|
|
+ html += '<option value="">-- 下拉快速选择 --</option>';
|
|
|
+ for (var i = 0; i < lots.length; i++) {
|
|
|
+ var lot = lots[i];
|
|
|
+ var lotNo = lot.lotNumber || '';
|
|
|
+ var label = formatLotOptionLabel(lot);
|
|
|
+ var sel = (lotNo === selected) ? ' selected' : '';
|
|
|
+ html += '<option value="'+escapeHtml(lotNo)+'"'+sel+'>'+escapeHtml(label)+'</option>';
|
|
|
+ }
|
|
|
+ html += '</select>';
|
|
|
+ }
|
|
|
+ var displayText = selected ? ('已选: ' + selected)
|
|
|
+ : (row.pickStatusLabel === '无库存' ? 'ERP 无库存,无法选批号' : '未选批号,请点击上方按钮查询');
|
|
|
+ html += '<span class="pick-lot-display" data-id="'+row.id+'" title="'+escapeHtml(selected || '点击查询 ERP 即时库存')+'">'+escapeHtml(displayText)+'</span>';
|
|
|
+ html += '</div>';
|
|
|
+ return html;
|
|
|
+}
|
|
|
+
|
|
|
+function formatLotHint(val, obj, row) {
|
|
|
+ if (!row.batchManage) {
|
|
|
+ return '';
|
|
|
+ }
|
|
|
+ var hint = row.lotHint || '';
|
|
|
+ if (!hint) {
|
|
|
+ return '<span class="text-muted">加载中...</span>';
|
|
|
+ }
|
|
|
+ var cls = (hint.indexOf('少于') >= 0 || hint.indexOf('无批号') >= 0 || hint.indexOf('无该物料') >= 0 || hint.indexOf('无法领料') >= 0) ? 'text-danger'
|
|
|
+ : (hint.indexOf('未查到') >= 0 || hint.indexOf('其他仓库') >= 0 || hint.indexOf('选批号') >= 0 || hint.indexOf('请先') >= 0) ? 'text-warning' : 'text-success';
|
|
|
+ return '<span class="'+cls+' pick-lot-hint pick-lot-hint-text" data-id="'+row.id+'" title="'+escapeHtml(hint)+'">'+escapeHtml(hint)+'</span>';
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+function formatLotSelect(val, obj, row) {
|
|
|
+
|
|
|
+ return buildLotSelectHtml(row);
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+function getPickQtyById(id) {
|
|
|
+
|
|
|
+ var $input = $('.pick-qty-input[data-id="'+id+'"]');
|
|
|
+
|
|
|
+ var pickQty = parseFloat($input.val());
|
|
|
+
|
|
|
+ if (isNaN(pickQty) || pickQty <= 0) {
|
|
|
+
|
|
|
+ pickQty = parseFloat($input.data('no-picked'));
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ return isNaN(pickQty) ? 0 : pickQty;
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+function applyRowPickState(id, pickable, hint) {
|
|
|
+ var $chk = $('.pick-select[data-id="'+id+'"]');
|
|
|
+ var $qty = $('.pick-qty-input[data-id="'+id+'"]');
|
|
|
+ var $tr = $chk.closest('tr.jqgrow');
|
|
|
+ if (pickable) {
|
|
|
+ $chk.prop('disabled', false).prop('checked', true);
|
|
|
+ $qty.prop('readonly', false);
|
|
|
+ $tr.removeClass('pick-row-finished');
|
|
|
+ } else {
|
|
|
+ $chk.prop('disabled', true).prop('checked', false);
|
|
|
+ $qty.prop('readonly', true);
|
|
|
+ var status = $('.pick-status[data-id="'+id+'"]').text();
|
|
|
+ if (status === '已领完') {
|
|
|
+ $tr.addClass('pick-row-finished');
|
|
|
+ } else {
|
|
|
+ $tr.removeClass('pick-row-finished');
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (hint) {
|
|
|
+ var cls = (hint.indexOf('少于') >= 0) ? 'text-danger pick-lot-hint pick-lot-hint-text'
|
|
|
+ : (hint.indexOf('已选') >= 0 || hint.indexOf('已推荐') >= 0) ? 'text-success pick-lot-hint pick-lot-hint-text' : 'text-warning pick-lot-hint pick-lot-hint-text';
|
|
|
+ $('.pick-lot-hint[data-id="'+id+'"]').attr('class', cls).attr('title', hint).text(hint);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+function applyLotSelection(id, lotNumber, hint) {
|
|
|
+ $('.pick-lot-value[data-id="'+id+'"]').val(lotNumber);
|
|
|
+ var displayText = '已选: ' + lotNumber;
|
|
|
+ $('.pick-lot-display[data-id="'+id+'"]').text(displayText).attr('title', lotNumber);
|
|
|
+ var $select = $('.pick-lot-select[data-id="'+id+'"]');
|
|
|
+ if ($select.length > 0) {
|
|
|
+ if ($select.find('option[value="'+lotNumber.replace(/"/g,'\\"')+'"]').length === 0) {
|
|
|
+ $select.append('<option value="'+escapeHtml(lotNumber)+'">'+escapeHtml(lotNumber)+'</option>');
|
|
|
+ }
|
|
|
+ $select.val(lotNumber);
|
|
|
+ }
|
|
|
+ $('.pick-status[data-id="'+id+'"]').html('<span class="text-success">可领料</span>');
|
|
|
+ applyRowPickState(id, true, hint || ('已选批号 '+lotNumber));
|
|
|
+}
|
|
|
+
|
|
|
+function renderLotSearchTable(lots) {
|
|
|
+ if (!lots || lots.length === 0) {
|
|
|
+ return '<div class="text-muted" style="padding:10px;">未查到批号库存</div>';
|
|
|
+ }
|
|
|
+ var html = '<div class="lot-search-table-wrap"><table class="table table-bordered table-hover table-condensed"><thead><tr>'+
|
|
|
+ '<th style="width:160px;">批号</th><th style="width:180px;">仓库</th><th style="width:90px;">可用量</th><th style="width:70px;">操作</th></tr></thead><tbody>';
|
|
|
+ for (var i = 0; i < lots.length; i++) {
|
|
|
+ var lot = lots[i];
|
|
|
+ var lotNo = lot.lotNumber || '';
|
|
|
+ var qty = readLotQtyText(lot);
|
|
|
+ var stock = lot.stockName || lot.stockNumber || '-';
|
|
|
+ html += '<tr><td>'+escapeHtml(lotNo)+'</td><td title="'+escapeHtml(stock)+'">'+escapeHtml(stock)+'</td>'+
|
|
|
+ '<td align="right">'+escapeHtml(qty)+'</td><td align="center">'+
|
|
|
+ '<button type="button" class="btn btn-xs btn-primary lot-search-pick" data-idx="'+i+'">选择</button></td></tr>';
|
|
|
+ }
|
|
|
+ html += '</tbody></table></div>';
|
|
|
+ return html;
|
|
|
+}
|
|
|
+
|
|
|
+function openLotSearchPopup($btn) {
|
|
|
+ var pickRowId = String($btn.data('id'));
|
|
|
+ var params = {
|
|
|
+ materialNumber: $btn.data('material'),
|
|
|
+ stockNumber: '',
|
|
|
+ stockName: $btn.data('stock-name') || '',
|
|
|
+ stockStatusNumber: $btn.data('stock-status') || '',
|
|
|
+ stockOrgNumber: $btn.data('stock-org') || '',
|
|
|
+ lotKeyword: ''
|
|
|
+ };
|
|
|
+ js.layer.open({
|
|
|
+ type: 1,
|
|
|
+ area: ['820px', '560px'],
|
|
|
+ title: 'ERP 即时库存 - ' + ($btn.data('material-name') || $btn.data('material') || ''),
|
|
|
+ resize: false,
|
|
|
+ scrollbar: true,
|
|
|
+ content: js.template('lotSearchTpl', {
|
|
|
+ materialNumber: params.materialNumber,
|
|
|
+ materialName: $btn.data('material-name') || '',
|
|
|
+ issueStockName: $btn.data('stock-name') || $btn.data('stock') || ''
|
|
|
+ }),
|
|
|
+ success: function(layero, index) {
|
|
|
+ layero = $(layero);
|
|
|
+ var currentLots = [];
|
|
|
+ var pickLot = function(lot) {
|
|
|
+ if (!lot) return;
|
|
|
+ var lotNo = lot.lotNumber || '';
|
|
|
+ if (lotNo === '') return;
|
|
|
+ var stock = lot.stockName || lot.stockNumber || '';
|
|
|
+ var qtyText = readLotQtyText(lot);
|
|
|
+ var hint = '已选批号 ' + lotNo + '(可用 ' + qtyText + (stock ? ',仓库 ' + stock : '') + ')';
|
|
|
+ applyLotSelection(pickRowId, lotNo, hint);
|
|
|
+ js.layer.close(index);
|
|
|
+ };
|
|
|
+ var doSearch = function() {
|
|
|
+ params.lotKeyword = $.trim(layero.find('#lotKeyword').val() || '');
|
|
|
+ params.stockNumber = '';
|
|
|
+ layero.find('#lotSearchResult').html('<div class="text-muted" style="padding:10px;">查询中...</div>');
|
|
|
+ $.getJSON(lotSearchUrl, params, function(data) {
|
|
|
+ currentLots = data.lots || [];
|
|
|
+ layero.find('#lotSearchHint').text(data.lotHint || '');
|
|
|
+ layero.find('#lotSearchResult').html(renderLotSearchTable(currentLots));
|
|
|
+ });
|
|
|
+ };
|
|
|
+ layero.off('click.lotPick').on('click.lotPick', '.lot-search-pick', function(e) {
|
|
|
+ e.preventDefault();
|
|
|
+ e.stopPropagation();
|
|
|
+ var idx = parseInt($(this).attr('data-idx'), 10);
|
|
|
+ if (isNaN(idx)) return;
|
|
|
+ pickLot(currentLots[idx]);
|
|
|
+ });
|
|
|
+ layero.find('#btnLotSearch').off('click').on('click', doSearch);
|
|
|
+ layero.find('#lotKeyword').off('keypress').on('keypress', function(e){ if (e.which === 13) doSearch(); });
|
|
|
+ doSearch();
|
|
|
+ }
|
|
|
+ });
|
|
|
+}
|
|
|
+
|
|
|
+function refreshLotOptions(id) {
|
|
|
+ var $qty = $('.pick-qty-input[data-id="'+id+'"]');
|
|
|
+ if ($qty.length === 0 || $qty.data('batch-manage') !== '1') {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ var $open = $('.pick-lot-open[data-id="'+id+'"]');
|
|
|
+ var params = {
|
|
|
+ materialNumber: $qty.data('material') || $open.data('material'),
|
|
|
+ stockNumber: $qty.data('stock') || $open.data('stock'),
|
|
|
+ stockName: $open.data('stock-name') || '',
|
|
|
+ stockStatusNumber: $qty.data('stock-status') || $open.data('stock-status'),
|
|
|
+ stockOrgNumber: $qty.data('stock-org') || $open.data('stock-org'),
|
|
|
+ pickQty: getPickQtyById(id)
|
|
|
+ };
|
|
|
+ $.getJSON(lotOptionsUrl, params, function(data){
|
|
|
+ var lots = data.lots || [];
|
|
|
+ var suggested = data.suggestedLotNumber || '';
|
|
|
+ var hint = data.lotHint || '';
|
|
|
+ if (hint) {
|
|
|
+ var cls = (hint.indexOf('少于') >= 0) ? 'text-danger' : 'text-warning';
|
|
|
+ $('.pick-lot-hint[data-id="'+id+'"]').attr('class', cls + ' pick-lot-hint pick-lot-hint-text').attr('title', hint).text(hint);
|
|
|
+ }
|
|
|
+ if (lots.length === 0) {
|
|
|
+ $('.pick-status[data-id="'+id+'"]').html('<span class="text-danger pick-status">无库存</span>');
|
|
|
+ applyRowPickState(id, false, hint);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ applyRowPickState(id, true, hint);
|
|
|
+ var $select = $('.pick-lot-select[data-id="'+id+'"]');
|
|
|
+ if ($select.length === 0) {
|
|
|
+ var rowHtml = buildLotSelectHtml({
|
|
|
+ id: id,
|
|
|
+ batchManage: true,
|
|
|
+ materialNumber: params.materialNumber,
|
|
|
+ materialName: $open.data('material-name') || '',
|
|
|
+ stockNumber: params.stockNumber,
|
|
|
+ stockName: params.stockName,
|
|
|
+ stockStatusNumber: params.stockStatusNumber,
|
|
|
+ stockOrgNumber: params.stockOrgNumber,
|
|
|
+ availableLots: lots,
|
|
|
+ lotNumber: suggested,
|
|
|
+ suggestedLotNumber: suggested
|
|
|
+ });
|
|
|
+ $open.closest('td').html(rowHtml);
|
|
|
+ if (suggested) {
|
|
|
+ applyLotSelection(id, suggested, hint);
|
|
|
+ }
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ var html = '<option value="">快速选择</option>';
|
|
|
+ for (var i = 0; i < lots.length; i++) {
|
|
|
+ var lot = lots[i];
|
|
|
+ var lotNo = lot.lotNumber || '';
|
|
|
+ var label = formatLotOptionLabel(lot);
|
|
|
+ var sel = (lotNo === suggested) ? ' selected' : '';
|
|
|
+ html += '<option value="'+escapeHtml(lotNo)+'"'+sel+'>'+escapeHtml(label)+'</option>';
|
|
|
+ }
|
|
|
+ $select.html(html);
|
|
|
+ if (suggested) {
|
|
|
+ applyLotSelection(id, suggested, hint);
|
|
|
+ }
|
|
|
+ });
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
$('#dataGrid').dataGrid({
|
|
|
+
|
|
|
searchForm: $("#searchForm"),
|
|
|
+ shrinkToFit: false,
|
|
|
+
|
|
|
columnModel: [
|
|
|
+
|
|
|
{header:'${text("选择")}', name:'pickSelect', width:50, align:"center", frozen:true, formatter: function(val, obj, row){
|
|
|
- var disabled = !row.noPickedQty || row.noPickedQty <= 0 ? 'disabled' : '';
|
|
|
- return '<input type="checkbox" class="pick-select" data-id="'+row.id+'" '+disabled+' checked="checked"/>';
|
|
|
+ var pickable = isRowPickable(row);
|
|
|
+ var disabled = pickable ? '' : 'disabled';
|
|
|
+ var checked = pickable ? 'checked="checked"' : '';
|
|
|
+ return '<input type="checkbox" class="pick-select" data-id="'+row.id+'" '+disabled+' '+checked+'/>';
|
|
|
}},
|
|
|
+
|
|
|
{header:'${text("用料清单")}', name:'ppbomNo', index:'ppbomNo', width:150, align:"center", frozen:true},
|
|
|
+
|
|
|
{header:'${text("序号")}', name:'seq', index:'seq', width:70, align:"center"},
|
|
|
+
|
|
|
{header:'${text("子项物料编码")}', name:'materialNumber', index:'materialNumber', width:220, align:"left"},
|
|
|
+
|
|
|
{header:'${text("子项物料名称")}', name:'materialName', index:'materialName', width:260, align:"left"},
|
|
|
+
|
|
|
{header:'${text("应发数量")}', name:'mustQty', index:'mustQty', width:100, align:"right"},
|
|
|
+
|
|
|
{header:'${text("已领数量")}', name:'pickedQty', index:'pickedQty', width:100, align:"right"},
|
|
|
+
|
|
|
{header:'${text("未领数量")}', name:'noPickedQty', index:'noPickedQty', width:100, align:"right"},
|
|
|
+
|
|
|
+ {header:'${text("可领数量")}', name:'canPickQty', index:'canPickQty', width:90, align:"right", formatter: formatCanPickQty},
|
|
|
+
|
|
|
{header:'${text("本次领料")}', name:'pickQty', index:'pickQty', width:110, align:"right", formatter: formatPickQty},
|
|
|
+
|
|
|
{header:'${text("单位")}', name:'unitName', index:'unitName', width:90, align:"center"},
|
|
|
+
|
|
|
{header:'${text("发料仓库")}', name:'stockName', index:'stockName', width:180, align:"left"},
|
|
|
- {header:'${text("库存状态")}', name:'stockStatusName', index:'stockStatusName', width:100, align:"center"},
|
|
|
- {header:'${text("批号")}', name:'lotText', index:'lotText', width:120, align:"center"}
|
|
|
+
|
|
|
+ {header:'${text("领料状态")}', name:'pickStatusLabel', width:100, align:"center", formatter: formatPickStatus},
|
|
|
+
|
|
|
+ {header:'${text("库存状态")}', name:'stockStatusName', index:'stockStatusName', width:100, align:"center", formatter: formatStockStatus},
|
|
|
+
|
|
|
+ {header:'${text("批号")}', name:'lotNumber', index:'lotNumber', width:260, align:"left", formatter: formatLotSelect},
|
|
|
+
|
|
|
+ {header:'${text("批号说明")}', name:'lotHint', index:'lotHint', width:200, align:"left", formatter: formatLotHint},
|
|
|
+
|
|
|
+ {header:'${text("领料说明")}', name:'pickQtyHint', index:'pickQtyHint', width:220, align:"left", formatter: formatPickQtyHint}
|
|
|
+
|
|
|
],
|
|
|
- ajaxSuccess: function(){}
|
|
|
+
|
|
|
+ ajaxSuccess: function(data){
|
|
|
+ setTimeout(function(){
|
|
|
+ $('.pick-status').each(function(){
|
|
|
+ var text = $.trim($(this).text());
|
|
|
+ if (text === '已领完' || text === '无库存') {
|
|
|
+ $(this).closest('tr.jqgrow').addClass('pick-row-finished');
|
|
|
+ }
|
|
|
+ });
|
|
|
+ $('.pick-qty-input[data-batch-manage="1"]').each(function(){
|
|
|
+ refreshLotOptions($(this).data('id'));
|
|
|
+ });
|
|
|
+ }, 200);
|
|
|
+ }
|
|
|
+});
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+$(document).on('change blur input', '.pick-qty-input', function(){
|
|
|
+ var id = $(this).data('id');
|
|
|
+ if ($(this).data('batch-manage') === '1') {
|
|
|
+ refreshLotOptions(id);
|
|
|
+ }
|
|
|
+});
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+$(document).on('click', '.pick-lot-open', function(e){
|
|
|
+ e.preventDefault();
|
|
|
+ e.stopPropagation();
|
|
|
+ openLotSearchPopup($(this));
|
|
|
});
|
|
|
|
|
|
+$(document).on('click', '.pick-lot-display', function(e){
|
|
|
+ e.preventDefault();
|
|
|
+ e.stopPropagation();
|
|
|
+ var id = $(this).data('id');
|
|
|
+ var $btn = $('.pick-lot-open[data-id="'+id+'"]');
|
|
|
+ if ($btn.length > 0) {
|
|
|
+ openLotSearchPopup($btn);
|
|
|
+ }
|
|
|
+});
|
|
|
+
|
|
|
+$(document).on('change', '.pick-lot-select', function(){
|
|
|
+ var id = $(this).data('id');
|
|
|
+ var lotNumber = $.trim($(this).val() || '');
|
|
|
+ if (lotNumber === '') {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ applyLotSelection(id, lotNumber, '已选批号 '+lotNumber);
|
|
|
+});
|
|
|
+
|
|
|
+function readLotNumber(id) {
|
|
|
+ return readRowLotNumber(id);
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
$('#btnSubmitPick').click(function(){
|
|
|
+
|
|
|
var lines = [];
|
|
|
+
|
|
|
var hasError = false;
|
|
|
+
|
|
|
$('.pick-select:checked').each(function(){
|
|
|
+
|
|
|
var id = $(this).data('id');
|
|
|
+
|
|
|
var $input = $('.pick-qty-input[data-id="'+id+'"]');
|
|
|
+
|
|
|
var pickQty = parseFloat($input.val());
|
|
|
+
|
|
|
if (isNaN(pickQty) || pickQty <= 0) {
|
|
|
+
|
|
|
return;
|
|
|
+
|
|
|
}
|
|
|
+
|
|
|
var noPickedQty = parseFloat($input.data('no-picked'));
|
|
|
+
|
|
|
var materialNumber = $input.data('material') || id;
|
|
|
+
|
|
|
if (!isNaN(noPickedQty) && pickQty > noPickedQty) {
|
|
|
+
|
|
|
js.showMessage('物料 '+materialNumber+' 领料数量不能超过未领数量 '+noPickedQty);
|
|
|
+
|
|
|
+ hasError = true;
|
|
|
+
|
|
|
+ return false;
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ var canPickQty = parseFloat($input.data('can-pick'));
|
|
|
+ if (!isNaN(canPickQty) && canPickQty <= 0) {
|
|
|
+ js.showMessage('物料 '+materialNumber+' 可领数量为 0,存在未审核领料单或已达最小发料批量上限');
|
|
|
+ hasError = true;
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ if (!isNaN(canPickQty) && pickQty > canPickQty) {
|
|
|
+ js.showMessage('物料 '+materialNumber+' 本次领料 '+pickQty+' 超过可领数量 '+canPickQty);
|
|
|
+ hasError = true;
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ var lotNumber = readLotNumber(id);
|
|
|
+ var statusText = $.trim($('.pick-status[data-id="'+id+'"]').text());
|
|
|
+ var materialName = $('.pick-lot-open[data-id="'+id+'"]').data('material-name') || '';
|
|
|
+
|
|
|
+ if (statusText === '无库存') {
|
|
|
+ js.showMessage('物料 '+materialNumber+'【'+materialName+'】ERP 即时库存无批号,无法领料。请先在 ERP 做入库/调拨');
|
|
|
+ hasError = true;
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ if ($input.data('batch-manage') === '1' && lotNumber === '') {
|
|
|
+ js.showMessage('物料 '+materialNumber+'【'+materialName+'】请先点击「选批号」选择 ERP 批号');
|
|
|
hasError = true;
|
|
|
return false;
|
|
|
}
|
|
|
- lines.push({ ppbomEntryId: String(id), pickQty: pickQty });
|
|
|
+
|
|
|
+ var line = { ppbomEntryId: String(id), pickQty: pickQty };
|
|
|
+
|
|
|
+ if (lotNumber !== '') {
|
|
|
+
|
|
|
+ line.lotNumber = lotNumber;
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ lines.push(line);
|
|
|
+
|
|
|
});
|
|
|
+
|
|
|
if (hasError) {
|
|
|
+
|
|
|
return;
|
|
|
+
|
|
|
}
|
|
|
+
|
|
|
if (lines.length === 0) {
|
|
|
+
|
|
|
js.showMessage('请勾选明细并填写大于 0 的本次领料数量');
|
|
|
+
|
|
|
return;
|
|
|
+
|
|
|
}
|
|
|
+
|
|
|
js.confirm('确认提交 '+lines.length+' 行到 ERP 生成生产领料单?', function(){
|
|
|
+
|
|
|
$.ajax({
|
|
|
+
|
|
|
url: '${ctx}/mes/erpPickMaterialBill/submitPickMaterial',
|
|
|
+
|
|
|
type: 'POST',
|
|
|
+
|
|
|
contentType: 'application/json;charset=UTF-8',
|
|
|
+
|
|
|
data: JSON.stringify({ billNo: billNo, entryId: entryId, lines: lines }),
|
|
|
+
|
|
|
success: function(data){
|
|
|
+
|
|
|
js.showMessage(data.message);
|
|
|
+
|
|
|
if (data.result == Global.TRUE) {
|
|
|
+
|
|
|
$('#searchForm').submit();
|
|
|
+
|
|
|
}
|
|
|
+
|
|
|
}
|
|
|
+
|
|
|
});
|
|
|
+
|
|
|
});
|
|
|
+
|
|
|
});
|
|
|
+
|
|
|
</script>
|
|
|
+<script id="lotSearchTpl" type="text/template">//<!--
|
|
|
+<div class="form-horizontal" style="padding:12px;">
|
|
|
+ <div class="form-group" style="margin-bottom:8px;">
|
|
|
+ <label class="control-label col-sm-3">物料编码</label>
|
|
|
+ <div class="col-sm-9"><p class="form-control-static">{{d.materialNumber}}</p></div>
|
|
|
+ </div>
|
|
|
+ <div class="form-group" style="margin-bottom:8px;">
|
|
|
+ <label class="control-label col-sm-3">物料名称</label>
|
|
|
+ <div class="col-sm-9"><p class="form-control-static">{{d.materialName}}</p></div>
|
|
|
+ </div>
|
|
|
+ <div class="form-group" style="margin-bottom:8px;">
|
|
|
+ <label class="control-label col-sm-3">发料仓库</label>
|
|
|
+ <div class="col-sm-9"><p class="form-control-static">{{d.issueStockName}}(查询组织内全部仓库)</p></div>
|
|
|
+ </div>
|
|
|
+ <div class="form-group" style="margin-bottom:8px;">
|
|
|
+ <label class="control-label col-sm-3">批号</label>
|
|
|
+ <div class="col-sm-6"><input type="text" id="lotKeyword" class="form-control input-sm" placeholder="可选,批号关键字"/></div>
|
|
|
+ <div class="col-sm-3"><button type="button" id="btnLotSearch" class="btn btn-primary btn-sm btn-block"><i class="fa fa-search"></i> 查询</button></div>
|
|
|
+ </div>
|
|
|
+ <div id="lotSearchHint" class="text-muted" style="margin-bottom:6px;"></div>
|
|
|
+ <div id="lotSearchResult"></div>
|
|
|
+</div>
|
|
|
+//--></script>
|
|
|
+
|
|
|
+
|