1.商品档案新增最大限制和最小限制
2.mes空桶/余料回库修复
| | |
| | | } |
| | | |
| | | workService.updateWrkIsSuplus(String.valueOf(mast.getWrkNo()), HMES_USER_ID, backType); |
| | | return workService.backLocOperation(String.valueOf(mast.getWrkNo()), HMES_USER_ID); |
| | | return R.ok(); |
| | | } |
| | | |
| | | private HmesStationFreezeStatusDto buildStationFreezeStatus(LocAroundBind bind) { |
| | |
| | | @RequestParam(required = false) String orderByType, |
| | | @RequestParam(required = false) String condition, |
| | | @RequestParam Map<String, Object> param) { |
| | | |
| | | // List<LocDetl> result = new ArrayList<>(); |
| | | List<AbnormalLocDetlParam> result = new ArrayList<>(); |
| | | // excludeTrash(param); |
| | | param.put("curr", curr); |
| | | param.put("limit", limit); |
| | | Page<LocDetl> groupLocDetl = locDetlService.getStockStatis2(toPage(1, 10000, param, LocDetl.class)); |
| | | // List<LocDetl> groupLocDetl = locDetlService.selectGroupPage(param, curr, limit); |
| | | for (LocDetl locDetl : groupLocDetl.getRecords()) { |
| | | AbnormalLocDetlParam abnormalLocDetlParam = new AbnormalLocDetlParam(); |
| | | Mat mat = matService.selectOne(new EntityWrapper<Mat>() |
| | | .eq("matnr", locDetl.getMatnr())); |
| | | if (Cools.isEmpty(mat)) { |
| | | continue; |
| | | } |
| | | |
| | | |
| | | if (!Cools.isEmpty(mat.getStoreMax()) || !Cools.isEmpty(mat.getStoreMin())) { |
| | | abnormalLocDetlParam.setStoreMax(mat.getStoreMax()); |
| | | abnormalLocDetlParam.setStoreMaxDate(mat.getStoreMaxDate()); |
| | | abnormalLocDetlParam.setStoreMin(mat.getStoreMin()); |
| | | abnormalLocDetlParam.setAnfme(locDetl.getAnfme()); |
| | | abnormalLocDetlParam.setMaktx(mat.getMaktx()); |
| | | abnormalLocDetlParam.setMatnr(mat.getMatnr()); |
| | | abnormalLocDetlParam.setSpecs(mat.getSpecs()); |
| | | abnormalLocDetlParam.setBatch(locDetl.getBatch()); |
| | | |
| | | // SimpleDateFormat simple = new SimpleDateFormat("yyyyMMdd"); |
| | | // Date maxDate = simple.parse(locDetl.getBatch()); |
| | | // long time = maxDate.getTime(); |
| | | // Date now = new Date(); |
| | | // long time1 = now.getTime(); |
| | | // abnormalLocDetlParam.setNowTime((int) ((time1 - time) / (1000 * 60 * 60 * 24))); |
| | | |
| | | if (!Cools.isEmpty(mat.getStoreMax()) && locDetl.getAnfme() > mat.getStoreMax()) { |
| | | result.add(abnormalLocDetlParam); |
| | | } else if (!Cools.isEmpty(mat.getStoreMin()) && locDetl.getAnfme() < mat.getStoreMin()) { |
| | | result.add(abnormalLocDetlParam); |
| | | } |
| | | } |
| | | } |
| | | Map<String, Object> queryParam = new HashMap<>(); |
| | | putIfPresent(queryParam, "matnr", param.get("matnr")); |
| | | putIfPresent(queryParam, "maktx", param.get("maktx")); |
| | | putIfPresent(queryParam, "specs", param.get("specs")); |
| | | putIfPresent(queryParam, "warnStatus", param.get("warnStatus")); |
| | | queryParam.put("pageNumber", curr); |
| | | queryParam.put("pageSize", limit); |
| | | |
| | | Page<AbnormalLocDetlParam> locDetlPage = new Page<>(); |
| | | locDetlPage.setRecords(paging(result, curr, limit)); |
| | | locDetlPage.setTotal(result.size()); |
| | | locDetlPage.setRecords(locDetlMapper.groupLocList(queryParam)); |
| | | locDetlPage.setTotal(locDetlMapper.groupLocListCount(queryParam)); |
| | | locDetlPage.setCurrent(curr); |
| | | locDetlPage.setSize(limit); |
| | | return R.ok(locDetlPage); |
| | | } |
| | | |
| | | private List<AbnormalLocDetlParam> paging(List<AbnormalLocDetlParam> result, Integer curr, Integer limit) { |
| | | List<AbnormalLocDetlParam> pageRecord = new ArrayList<AbnormalLocDetlParam>(); |
| | | int minIndex = (curr - 1) * limit; |
| | | int maxIndex = (curr * limit) - 1; |
| | | if (result.size() < maxIndex) { |
| | | maxIndex = result.size(); |
| | | private void putIfPresent(Map<String, Object> target, String key, Object value) { |
| | | String normalized = normalizeFilterText(value); |
| | | if (normalized != null) { |
| | | target.put(key, normalized); |
| | | } |
| | | for (int i = minIndex; i < maxIndex; i++) { |
| | | pageRecord.add(result.get(i)); |
| | | } |
| | | return pageRecord; |
| | | } |
| | | |
| | | @RequestMapping(value = "/locDetl/{id}/auth") |
| | |
| | | /** |
| | | * 库存预警数量上限 |
| | | */ |
| | | @ApiModelProperty(value= "库存预警数量上限") |
| | | @ExcelProperty(value = "库存预警数量上限") |
| | | @TableField("store_max") |
| | | private Double storeMax; |
| | | |
| | | /** |
| | | * 库存预警数量下限 |
| | | */ |
| | | @ApiModelProperty(value= "库存预警数量下限") |
| | | @ExcelProperty(value = "库存预警数量下限") |
| | | @TableField("store_min") |
| | | private Double storeMin; |
| | | |
| | |
| | | */ |
| | | private Integer nowTime; |
| | | |
| | | /** |
| | | * 库存预警状态 |
| | | */ |
| | | @ApiModelProperty(value = "库存预警状态") |
| | | @ExcelProperty("状态") |
| | | private String warnStatus; |
| | | |
| | | |
| | | public String getLocNo$() { |
| | | LocMastService service = SpringUtils.getBean(LocMastService.class); |
| | |
| | | |
| | | import com.baomidou.mybatisplus.mapper.BaseMapper; |
| | | import com.zy.asrs.entity.LocDetl; |
| | | import com.zy.asrs.entity.param.AbnormalLocDetlParam; |
| | | import com.zy.asrs.entity.result.LocDetlAll; |
| | | import com.zy.asrs.entity.result.LocDetlDTO; |
| | | import com.zy.asrs.entity.result.StockVo; |
| | |
| | | |
| | | List<LocDetl> getStockStatis2(Map<String, Object> map); |
| | | |
| | | List<AbnormalLocDetlParam> groupLocList(Map<String, Object> map); |
| | | |
| | | Integer groupLocListCount(Map<String, Object> map); |
| | | |
| | | List<LocDetl> getStockStatisExcel(); |
| | | |
| | | @Select("select sum(a.anfme) as sum from asr_loc_detl a left join asr_loc_mast b on a.loc_no = b.loc_no where b.loc_sts = 'F' and a.matnr = #{matnr}") |
| | |
| | | // 商品 |
| | | Mat mat = matService.selectByMatnr(excel.getMatnr()); |
| | | if (mat == null) { |
| | | mat = excel; |
| | | mat = new Mat(); |
| | | mat.setMatnr(excel.getMatnr()); |
| | | mat.setMaktx(excel.getMaktx()); |
| | | mat.setSafeQty(excel.getSafeQty()); |
| | | mat.setVolume(excel.getVolume()); |
| | | mat.setStoreMax(excel.getStoreMax()); |
| | | mat.setStoreMin(excel.getStoreMin()); |
| | | mat.setTagId(tagId); |
| | | mat.setLocType(tagId); |
| | | if (Objects.isNull(mat.getVolume())) { |
| | |
| | | |
| | | import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; |
| | | import com.alibaba.excel.annotation.ExcelProperty; |
| | | import com.zy.asrs.entity.Mat; |
| | | import lombok.Data; |
| | | |
| | | /** |
| | | * 0.A 1.B 2.C 3.D 4.E 5.F 6.G 7.H 8.I |
| | | * 9.J 10.K 11.L 12.M 13.N 14.O 15.P 16.Q 17.R 18.S |
| | | * 19.T 20.U 21.V 22.W 23.X 24.Y 25.Z |
| | | */ |
| | | @Data |
| | | @ExcelIgnoreUnannotated |
| | | public class MatExcel extends Mat { |
| | | public class MatExcel { |
| | | |
| | | @ExcelProperty(index = 0, value = "一级分类") |
| | | private String priClass; |
| | |
| | | @ExcelProperty(index = 1, value = "二级分类") |
| | | private String secClass; |
| | | |
| | | @ExcelProperty(index = 2, value = "商品编码") |
| | | private String matnr; |
| | | |
| | | @ExcelProperty(index = 3, value = "商品名称") |
| | | private String maktx; |
| | | |
| | | @ExcelProperty(index = 4, value = "归零阀值") |
| | | private Double safeQty; |
| | | |
| | | @ExcelProperty(index = 5, value = "每公斤长度") |
| | | private Double volume; |
| | | |
| | | @ExcelProperty(index = 6, value = "库存预警数量上限") |
| | | private Double storeMax; |
| | | |
| | | @ExcelProperty(index = 7, value = "库存预警数量下限") |
| | | private Double storeMin; |
| | | } |
| | |
| | | |
| | | } |
| | | m=m*mat.getVolume(); |
| | | Double currentStock = locDetlService.getSumAnfme(matnr); |
| | | if (currentStock == null) { |
| | | currentStock = 0D; |
| | | } |
| | | if (mat.getStoreMax() != null && currentStock + m > mat.getStoreMax()) { |
| | | log.info("WCS入库拦截: 物料超过库存上限, matnr={}, currentStock={}, inboundQty={}, storeMax={}", |
| | | matnr, currentStock, m, mat.getStoreMax()); |
| | | return R.error("物料已到达上限禁止入库"); |
| | | } |
| | | //Double val = Math.round((m - matnr.getSafeQty()) * 10000) / 10000.0; |
| | | Config config = configService.selectConfigByCode("SimulationInbound"); |
| | | if (config != null && config.getValue().equals("Y")) { |
| | |
| | | |
| | | #wcs对接 |
| | | wcs: |
| | | # 开关 |
| | | switch: false |
| | | status-sync: |
| | | enabled: true |
| | | initial-delay: 10000 |
| | |
| | | ) t where t.row between ((#{pageNumber}-1)*#{pageSize}+1) and (#{pageNumber}*#{pageSize}) |
| | | </select> |
| | | |
| | | <sql id="groupLocWarnStatusCase"> |
| | | case |
| | | when mm.store_max is null and mm.store_min is null then '未设置' |
| | | when mm.store_max is not null and isnull(stock.anfme, 0) > mm.store_max then '超上限' |
| | | when mm.store_min is not null and isnull(stock.anfme, 0) < mm.store_min then '超下限' |
| | | else '正常' |
| | | end |
| | | </sql> |
| | | |
| | | <sql id="groupLocListCondition"> |
| | | where 1 = 1 |
| | | and (mm.memo is null or mm.memo != '打包上线') |
| | | <if test="matnr != null and matnr != ''"> |
| | | and mm.matnr like '%' + #{matnr} + '%' |
| | | </if> |
| | | <if test="maktx != null and maktx != ''"> |
| | | and mm.maktx like '%' + #{maktx} + '%' |
| | | </if> |
| | | <if test="specs != null and specs != ''"> |
| | | and mm.specs like '%' + #{specs} + '%' |
| | | </if> |
| | | <if test="warnStatus != null and warnStatus != ''"> |
| | | and |
| | | <include refid="groupLocWarnStatusCase"/> |
| | | = #{warnStatus} |
| | | </if> |
| | | </sql> |
| | | |
| | | <select id="groupLocList" resultType="com.zy.asrs.entity.param.AbnormalLocDetlParam"> |
| | | select * from |
| | | ( |
| | | select |
| | | row_number() over (order by mm.matnr asc) as row_num, |
| | | mm.matnr as matnr, |
| | | mm.maktx as maktx, |
| | | mm.specs as specs, |
| | | isnull(stock.anfme, 0) as anfme, |
| | | mm.store_max as storeMax, |
| | | mm.store_min as storeMin, |
| | | <include refid="groupLocWarnStatusCase"/> as warnStatus |
| | | from man_mat mm |
| | | left join ( |
| | | select |
| | | a.matnr, |
| | | sum(a.anfme) as anfme |
| | | from asr_loc_detl a |
| | | group by a.matnr |
| | | ) stock on stock.matnr = mm.matnr |
| | | <include refid="groupLocListCondition"/> |
| | | ) t |
| | | where t.row_num between ((#{pageNumber}-1)*#{pageSize}+1) and (#{pageNumber}*#{pageSize}) |
| | | </select> |
| | | |
| | | <select id="groupLocListCount" resultType="java.lang.Integer"> |
| | | select count(1) |
| | | from man_mat mm |
| | | left join ( |
| | | select |
| | | a.matnr, |
| | | sum(a.anfme) as anfme |
| | | from asr_loc_detl a |
| | | group by a.matnr |
| | | ) stock on stock.matnr = mm.matnr |
| | | <include refid="groupLocListCondition"/> |
| | | </select> |
| | | |
| | | </mapper> |
| | |
| | | <result column="update_by" property="updateBy" /> |
| | | <result column="update_time" property="updateTime" /> |
| | | <result column="memo" property="memo" /> |
| | | <result column="store_max" property="storeMax" /> |
| | | <result column="store_min" property="storeMin" /> |
| | | <result column="store_max_date" property="storeMaxDate" /> |
| | | |
| | | <result column="stock" property="stock" /> |
| | | </resultMap> |
| | |
| | | var cols = [ |
| | | {field: 'matnr', align: 'center', title: '物料号', sort: true} |
| | | , {field: 'maktx', align: 'center', title: '物料名称', sort: true} |
| | | , {field: 'specs', align: 'center', title: '规格'} |
| | | , {field: 'batch', align: 'center', title: '批号', width: 300, sort: true} |
| | | , {field: 'storeMax', align: 'center', title: '数量上限', sort: true} |
| | | , {field: 'storeMin', align: 'center', title: '数量下限', sort: true} |
| | | , { |
| | | field: 'warnStatus', align: 'center', title: '状态', sort: true, templet: function (d) { |
| | | var colorMap = { |
| | | '未设置': '#999999', |
| | | '正常': '#5cb85c', |
| | | '超上限': '#d9534f', |
| | | '超下限': '#337ab7' |
| | | }; |
| | | var text = d.warnStatus || ''; |
| | | var color = colorMap[text] || '#333333'; |
| | | return '<span style="color:' + color + ';">' + text + '</span>'; |
| | | } |
| | | } |
| | | // , {field: 'storeMaxDate', align: 'center', title: '库龄上限', sort: true} |
| | | , {field: 'anfme', align: 'center', title: '实际数量'} |
| | | // , {field: 'nowTime', align: 'center', title: '实际库龄'} |
| | |
| | | form.on('submit(reset)', function (data) { |
| | | pageCurr = 1; |
| | | clearFormVal($('#search-box')); |
| | | form.render('select'); |
| | | tableReload(false); |
| | | }); |
| | | |
| | |
| | | type: 'datetime' |
| | | }); |
| | | |
| | | form.render('select'); |
| | | |
| | | }); |
| | | |
| | |
| | | var printMatCodeNos = []; |
| | | var admin; |
| | | |
| | | function createNumberCell(title, field) { |
| | | return { |
| | | field: field, |
| | | align: 'center', |
| | | title: title, |
| | | templet: function (d) { |
| | | var raw = d[field]; |
| | | if (raw === null || raw === undefined) return ''; |
| | | if (typeof raw === 'string' && raw.trim() === '') return ''; |
| | | var num = Number(raw); |
| | | if (!isFinite(num)) return ''; |
| | | return num.toFixed(2); |
| | | } |
| | | }; |
| | | } |
| | | |
| | | function getCol() { |
| | | var cols = [ |
| | | {type: 'checkbox'} |
| | |
| | | // ,{field: 'store_min', align: 'center',title: '库存下限'} |
| | | // ,{field: 'store_max_date', align: 'center',title: '库龄上限(天)'} |
| | | ]; |
| | | cols.push.apply(cols, matCols); |
| | | var pageMatCols = matCols.filter(function (col) { |
| | | return ['specs', 'model', 'brand'].indexOf(col.field) === -1; |
| | | }); |
| | | cols.push.apply(cols, pageMatCols); |
| | | cols.push( |
| | | createNumberCell('库存预警数量上限', 'storeMax'), |
| | | createNumberCell('库存预警数量下限', 'storeMin') |
| | | ); |
| | | cols.push( |
| | | {fixed: 'right', title: '操作', align: 'center', toolbar: '#operate', width: 150} |
| | | ) |
| | |
| | | </div> |
| | | <div class="layui-inline"> |
| | | <div class="layui-input-inline"> |
| | | <input class="layui-input" type="text" name="specs" placeholder="规格" autocomplete="off"> |
| | | </div> |
| | | </div> |
| | | <div class="layui-inline"> |
| | | <div class="layui-input-inline"> |
| | | <input class="layui-input" type="text" name="batch" placeholder="批号" autocomplete="off"> |
| | | <select name="warnStatus"> |
| | | <option value="">状态</option> |
| | | <option value="未设置">未设置</option> |
| | | <option value="正常">正常</option> |
| | | <option value="超上限">超上限</option> |
| | | <option value="超下限">超下限</option> |
| | | </select> |
| | | </div> |
| | | </div> |
| | | |
| | |
| | | <input name="maktx" class="layui-input" placeholder="输入商品名称"/> |
| | | </div> |
| | | </div> |
| | | <div class="layui-inline"> |
| | | <label class="layui-form-label" style="padding: 8px 15px 8px 15px">商品规格:</label> |
| | | <div class="layui-input-inline"> |
| | | <input name="specs" class="layui-input" placeholder="输入商品规格"/> |
| | | </div> |
| | | </div> |
| | | <div class="layui-inline">  |
| | | <button class="layui-btn icon-btn" lay-filter="search" lay-submit> |
| | | <i class="layui-icon"></i>搜索 |
| | |
| | | <input name="uuid" type="hidden"> |
| | | <input name="nodeId" type="hidden"> |
| | | <input name="tag_id" type="hidden"> |
| | | <input name="model" type="hidden"> |
| | | <input name="name" type="hidden"> |
| | | <input name="batch" type="hidden"> |
| | | <input name="docId" type="hidden"> |
| | |
| | | </div> |
| | | </div> |
| | | <div class="layui-form-item"> |
| | | <label class="layui-form-label">规格</label> |
| | | <label class="layui-form-label">库存预警数量上限</label> |
| | | <div class="layui-input-block"> |
| | | <input name="specs" placeholder="请输入规格" class="layui-input"> |
| | | <input name="storeMax" placeholder="请输入库存预警数量上限" class="layui-input"> |
| | | </div> |
| | | </div> |
| | | <div class="layui-form-item"> |
| | | <label class="layui-form-label">品牌</label> |
| | | <label class="layui-form-label">库存预警数量下限</label> |
| | | <div class="layui-input-block"> |
| | | <input name="brand" placeholder="请输入单箱净重格" class="layui-input"> |
| | | </div> |
| | | </div> |
| | | <div class="layui-form-item"> |
| | | <label class="layui-form-label">型号</label> |
| | | <div class="layui-input-block"> |
| | | <input name="model" placeholder="请输入型号" class="layui-input"> |
| | | <input name="storeMin" placeholder="请输入库存预警数量下限" class="layui-input"> |
| | | </div> |
| | | </div> |
| | | </div> |
| | |
| | | <label class="layui-form-label layui-form-required">每公斤长度</label> |
| | | <div class="layui-input-block"> |
| | | <input id="volume" name="volume" placeholder="请输入" class="layui-input" lay-vertype="tips" lay-verify="required" required=""> |
| | | </div> |
| | | </div> |
| | | <div class="layui-form-item"> |
| | | <label class="layui-form-label">规格</label> |
| | | <div class="layui-input-block"> |
| | | <input name="specs" placeholder="请输入代码" class="layui-input"> |
| | | </div> |
| | | </div> |
| | | <div class="layui-form-item"> |