Merge branch 'devlop' of http://47.97.1.152:5880/r/wms-master into devlop
| | |
| | | useRecordContext, |
| | | useTranslate, |
| | | useNotify, |
| | | useRefresh, |
| | | useListContext, |
| | | FunctionField, |
| | | TextField, |
| | |
| | | import ConstructionIcon from "@mui/icons-material/Construction"; |
| | | import FileDownloadIcon from '@mui/icons-material/FileDownload'; |
| | | import EditIcon from '@mui/icons-material/Edit'; |
| | | |
| | | import request from '@/utils/request'; |
| | | |
| | | |
| | | const StyledDatagrid = styled(DatagridConfigurable)(({ theme }) => ({ |
| | |
| | | navigate(`/asnOrderItem?asnId=${record.id}`); |
| | | }; |
| | | |
| | | |
| | | const inspection = () => { }; |
| | | |
| | | const print = () => { |
| | | }; |
| | | |
| | | |
| | | return ( |
| | | <Box display="flex"> |
| | | <List |
| | |
| | | actions={( |
| | | <TopToolbar> |
| | | |
| | | <Button onClick={inspection} label={"toolbar.inspection"}> |
| | | <ConstructionIcon /> |
| | | </Button> |
| | | <FilterButton /> |
| | | <MyCreateButton onClick={() => { setCreateDialog(true); setmodalType(0) }} /> |
| | | <SelectColumnsButton preferenceKey='asnOrder' /> |
| | |
| | | > |
| | | <StyledDatagrid |
| | | preferenceKey='asnOrder' |
| | | bulkActionButtons={() => <BulkDeleteButton mutationMode={OPERATE_MODE} />} |
| | | bulkActionButtons={<> <InspectionsButton /><BulkDeleteButton mutationMode={OPERATE_MODE} /></>} |
| | | rowClick={(id, resource, record) => false} |
| | | expand={(e) => <AsnOrderPanel key={Math.floor(Math.random() * 100)} />} |
| | | expandSingle={true} |
| | |
| | | label={'ra.action.edit'} |
| | | > |
| | | </Button> */} |
| | | <InspectionButton /> |
| | | <DeleteButton sx={{ padding: '1px', fontSize: '.75rem' }} mutationMode={OPERATE_MODE} /> |
| | | </WrapperField> |
| | | </StyledDatagrid> |
| | |
| | | </Button> |
| | | ) |
| | | } |
| | | |
| | | const InspectionButton = () => { |
| | | const record = useRecordContext(); |
| | | const notify = useNotify(); |
| | | const refresh = useRefresh(); |
| | | const inspection = () => { |
| | | requestInspect([record]) |
| | | }; |
| | | |
| | | const requestInspect = async (rows) => { |
| | | const { data: { code, data, msg } } = await request.post(`/asnOrder/inspect`, rows); |
| | | |
| | | if (code === 200) { |
| | | notify(msg); |
| | | refresh() |
| | | } else { |
| | | notify(msg); |
| | | } |
| | | } |
| | | |
| | | |
| | | return ( |
| | | <Button onClick={inspection} label={"toolbar.inspection"}> |
| | | <ConstructionIcon /> |
| | | </Button> |
| | | ) |
| | | } |
| | | |
| | | const InspectionsButton = () => { |
| | | const { selectedIds, onUnselectItems, data } = useListContext(); |
| | | const notify = useNotify(); |
| | | const refresh = useRefresh(); |
| | | const inspection = () => { |
| | | if (selectedIds.length === 0) { |
| | | notify('请选择通知单'); |
| | | return; |
| | | } else { |
| | | const rows = data.filter((item) => selectedIds.includes(item.id)) |
| | | requestInspect(rows) |
| | | } |
| | | }; |
| | | |
| | | const requestInspect = async (rows) => { |
| | | const { data: { code, data, msg } } = await request.post(`/asnOrder/inspect`, rows); |
| | | |
| | | if (code === 200) { |
| | | notify(msg); |
| | | refresh() |
| | | } else { |
| | | notify(msg); |
| | | } |
| | | } |
| | | |
| | | |
| | | return ( |
| | | <Button onClick={inspection} label={"toolbar.inspection"}> |
| | | <ConstructionIcon /> |
| | | </Button> |
| | | ) |
| | | } |
| | |
| | | import React, { useState, useRef, useEffect, useMemo } from "react"; |
| | | import { Box, Card, CardContent, Grid, Typography, Tooltip, Paper, TableContainer, Table, TableBody, TableCell, TableHead, TableRow } from '@mui/material'; |
| | | import { Box, Card, CardContent, Grid, Typography, Button, TextField, Tooltip, Paper, TableContainer, Table, TableBody, TableCell, TableHead, TableRow } from '@mui/material'; |
| | | import { |
| | | useTranslate, |
| | | useRecordContext, |
| | |
| | | import * as Common from '@/utils/common' |
| | | import { styled } from "@mui/material/styles"; |
| | | import request from '@/utils/request'; |
| | | import debounce from 'lodash/debounce'; |
| | | import { DataGrid } from '@mui/x-data-grid'; |
| | | const AsnOrderPanel = () => { |
| | | const record = useRecordContext(); |
| | | if (!record) return null; |
| | | const translate = useTranslate(); |
| | | const notify = useNotify(); |
| | | const [rows, setRows] = useState([]); |
| | | const [maktx, setMaktx] = useState(''); |
| | | const asnId = record.id; |
| | | |
| | | useEffect(() => { |
| | | http(); |
| | | }, [asnId]); |
| | | debouncedHttp({ maktx }); |
| | | }, [asnId, maktx]); |
| | | |
| | | const http = async () => { |
| | | const res = await request.post('/asnOrderItem/page', { asnId }); |
| | | |
| | | const http = async (parmas) => { |
| | | const res = await request.post('/asnOrderItem/page', { ...parmas, asnId }); |
| | | if (res?.data?.code === 200) { |
| | | setRows(res.data.data.records) |
| | | } else { |
| | |
| | | } |
| | | } |
| | | |
| | | const debouncedHttp = useMemo(() => debounce(http, 300), []); |
| | | |
| | | const StyledTableRow = styled(TableRow)(({ theme }) => ({ |
| | | "& .MuiButtonBase-root.": { |
| | |
| | | |
| | | const columns = [ |
| | | { |
| | | id: 'asnId', |
| | | label: 'table.field.asnOrderItem.asnId', |
| | | minWidth: 100, |
| | | field: 'asnId', |
| | | headerName: translate('table.field.asnOrderItem.asnId') |
| | | }, |
| | | { |
| | | id: 'asnCode', |
| | | label: 'table.field.asnOrderItem.asnCode', |
| | | minWidth: 100, |
| | | field: 'asnCode', |
| | | headerName: translate('table.field.asnOrderItem.asnCode') |
| | | }, |
| | | { |
| | | id: 'poDetlId', |
| | | label: 'table.field.asnOrderItem.poDetlId', |
| | | minWidth: 100, |
| | | field: 'poDetlId', |
| | | headerName: translate('table.field.asnOrderItem.poDetlId') |
| | | }, |
| | | { |
| | | id: 'poDetlCode', |
| | | label: 'table.field.asnOrderItem.poDetlCode', |
| | | minWidth: 100, |
| | | field: 'poDetlCode', |
| | | headerName: translate('table.field.asnOrderItem.poDetlCode') |
| | | }, |
| | | { |
| | | id: 'matnrId', |
| | | label: 'table.field.asnOrderItem.matnrId', |
| | | minWidth: 100, |
| | | field: 'matnrId', |
| | | headerName: translate('table.field.asnOrderItem.matnrId') |
| | | }, |
| | | { |
| | | id: 'maktx', |
| | | label: 'table.field.asnOrderItem.maktx', |
| | | minWidth: 100, |
| | | field: 'maktx', |
| | | headerName: translate('table.field.asnOrderItem.maktx') |
| | | }, |
| | | { |
| | | id: 'anfme', |
| | | label: 'table.field.asnOrderItem.anfme', |
| | | minWidth: 100, |
| | | field: 'anfme', |
| | | headerName: translate('table.field.asnOrderItem.anfme') |
| | | }, |
| | | { |
| | | id: 'stockUnit', |
| | | label: 'table.field.asnOrderItem.stockUnit', |
| | | minWidth: 100, |
| | | field: 'stockUnit', |
| | | headerName: translate('table.field.asnOrderItem.stockUnit') |
| | | }, |
| | | { |
| | | id: 'purQty', |
| | | label: 'table.field.asnOrderItem.purQty', |
| | | minWidth: 100, |
| | | field: 'purQty', |
| | | headerName: translate('table.field.asnOrderItem.purQty') |
| | | }, |
| | | { |
| | | id: 'purUnit', |
| | | label: 'table.field.asnOrderItem.purUnit', |
| | | minWidth: 100, |
| | | field: 'purUnit', |
| | | headerName: translate('table.field.asnOrderItem.purUnit') |
| | | }, |
| | | { |
| | | id: 'qty', |
| | | label: 'table.field.asnOrderItem.qty', |
| | | minWidth: 100, |
| | | field: 'qty', |
| | | headerName: translate('table.field.asnOrderItem.qty') |
| | | }, |
| | | { |
| | | id: 'splrCode', |
| | | label: 'table.field.asnOrderItem.splrCode', |
| | | minWidth: 100, |
| | | field: 'splrCode', |
| | | headerName: translate('table.field.asnOrderItem.splrCode') |
| | | }, |
| | | { |
| | | id: 'splrName', |
| | | label: 'table.field.asnOrderItem.splrName', |
| | | minWidth: 100, |
| | | field: 'splrName', |
| | | headerName: translate('table.field.asnOrderItem.splrName') |
| | | }, |
| | | { |
| | | id: 'qrcode', |
| | | label: 'table.field.asnOrderItem.qrcode', |
| | | minWidth: 100, |
| | | field: 'barcode', |
| | | headerName: translate('table.field.asnOrderItem.barcode') |
| | | }, |
| | | { |
| | | id: 'barcode', |
| | | label: 'table.field.asnOrderItem.barcode', |
| | | minWidth: 100, |
| | | }, |
| | | { |
| | | id: 'packName', |
| | | label: 'table.field.asnOrderItem.packName', |
| | | minWidth: 100, |
| | | field: 'packName', |
| | | headerName: translate('table.field.asnOrderItem.packName') |
| | | }] |
| | | |
| | | const [selectedRows, setSelectedRows] = useState([]); |
| | | |
| | | const handleSelectionChange = (ids) => { |
| | | setSelectedRows(ids) |
| | | |
| | | }; |
| | | const maktxChange = (value) => { |
| | | setMaktx(value) |
| | | } |
| | | |
| | | const wakbarcode = () => { |
| | | |
| | | } |
| | | |
| | | const wakprint = () => { |
| | | |
| | | } |
| | | |
| | | |
| | | return ( |
| | | |
| | | <Box sx={{ |
| | | position: 'relative', |
| | | padding: '5px 10px' |
| | | }}> |
| | | <TableContainer component={Paper} > |
| | | <Table size="small" > |
| | | <TableHead> |
| | | <StyledTableRow key={'head'}> |
| | | {columns.map((column, idx) => { |
| | | const value = column.label; |
| | | return ( |
| | | <> |
| | | <StyledTableCell |
| | | key={column.id} |
| | | align={column.align || "left"} |
| | | // style={{ paddingLeft: idx === 0 && (depth * 16 + 16) }} |
| | | > |
| | | {column.format ? column.format(value) : translate(value)} |
| | | </StyledTableCell> |
| | | </> |
| | | ); |
| | | |
| | | })} |
| | | </StyledTableRow> |
| | | </TableHead> |
| | | <div style={{ display: 'flex', justifyContent: 'space-between', marginBottom: '4px', alignItems: 'center' }}> |
| | | <TextField value={maktx} onChange={(e) => maktxChange(e.target.value)} label="搜索物料" variant="outlined" sx={{ width: '300px' }} /> |
| | | |
| | | <TableBody> |
| | | {rows.map((row) => ( |
| | | <StyledTableRow key={row.id + Math.random()}> |
| | | {columns.map((column) => ( |
| | | <StyledTableCell key={column.id} > |
| | | {row[column.id]} |
| | | </StyledTableCell> |
| | | ))} |
| | | </StyledTableRow> |
| | | ))} |
| | | <div style={{ display: 'flex', gap: '10px' }}> |
| | | <Button variant="contained" onClick={wakbarcode}>生成条码</Button> |
| | | <Button variant="contained" onClick={wakprint}>打印</Button> |
| | | </div> |
| | | </div> |
| | | |
| | | </TableBody> |
| | | </Table> |
| | | </TableContainer> |
| | | </Box> |
| | | |
| | | <DataGrid |
| | | size="small" |
| | | rows={rows} |
| | | columns={columns} |
| | | checkboxSelection |
| | | onRowSelectionModelChange={handleSelectionChange} |
| | | selectionModel={selectedRows} |
| | | disableColumnMenu={true} |
| | | disableColumnSorting |
| | | disableMultipleColumnsSorting |
| | | /> |
| | | </Box > |
| | | |
| | | ); |
| | | }; |
| | |
| | | const notify = useNotify(); |
| | | const refresh = useRefresh(); |
| | | |
| | | |
| | | const [createDialog, setCreateDialog] = useState(false); |
| | | |
| | | return ( |
| | |
| | | server: { |
| | | port: 8122, |
| | | host: '0.0.0.0', |
| | | open: true, |
| | | // available in run dev |
| | | proxy: { |
| | | '/rsf-server': { |
| | |
| | | import com.vincent.rsf.server.manager.service.*; |
| | | import com.vincent.rsf.server.system.constant.SerialRuleCode; |
| | | import com.vincent.rsf.server.system.utils.SerialRuleUtils; |
| | | import org.apache.commons.lang3.StringUtils; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.scheduling.annotation.Scheduled; |
| | | import org.springframework.stereotype.Component; |
| | |
| | | if (Objects.isNull(matnr)) { |
| | | throw new CoolException("数据错误:当前物料不存在!!"); |
| | | } |
| | | // //TODO barcode生成策略 |
| | | String trackCode = SerialRuleUtils.generateRuleCode(SerialRuleCode.SYS_LABEL_CODE, item); |
| | | if (StringUtils.isBlank(trackCode)) { |
| | | throw new CoolException("单据跟踪码生成失败:请检查「sys_asn_mantr_label」是否配置完成!!"); |
| | | } |
| | | // String barcode = code + matnr.getCode(); |
| | | orderItem.setAnfme(item.getAnfme()) |
| | | .setAsnId(order.getId()) |
| | |
| | | .setSplrCode(item.getSplrCode()) |
| | | .setPoDetlId(item.getId()) |
| | | .setPlatItemId(item.getPlatItemId()) |
| | | // .setBarcode(barcode) |
| | | .setTrackCode(trackCode) |
| | | .setPoCode(purchase.getCode()) |
| | | .setPurQty(item.getAnfme()) |
| | | .setPurUnit(item.getUnit()) |
| | | .setMatnrCode(matnr.getCode()) |
| | | .setMaktx(matnr.getName()) |
| | | .setMatnrId(matnr.getId() + ""); |
| | | orderItems.add(orderItem); |
| | |
| | | }); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 生成物料标签 |
| | | */ |
| | | @Scheduled(cron = "0 0/05 * * * ? ") |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public void generateMatnrLabel() { |
| | | List<AsnOrderItem> list = asnOrderItemService.list(new LambdaQueryWrapper<AsnOrderItem>() |
| | | .isNull(AsnOrderItem::getTrackCode) |
| | | .select(AsnOrderItem::getId)); |
| | | if (Objects.isNull(list) || list.isEmpty()) { |
| | | return; |
| | | } |
| | | List<AsnOrderItem> items = new ArrayList<>(); |
| | | list.forEach(item -> { |
| | | String trackCode = SerialRuleUtils.generateRuleCode(SerialRuleCode.SYS_LABEL_CODE, item); |
| | | if (StringUtils.isBlank(trackCode)) { |
| | | throw new CoolException("单据跟踪码生成失败:请检查「sys_asn_mantr_label」是否配置完成!!"); |
| | | } |
| | | item.setTrackCode(trackCode); |
| | | items.add(item); |
| | | }); |
| | | |
| | | if (!asnOrderItemService.updateBatchById(items)) { |
| | | throw new CoolException("生成编码失败!!"); |
| | | } |
| | | } |
| | | |
| | | } |
| | |
| | | //保存扩展字段 |
| | | ExtendFieldsUtils.saveFields(params); |
| | | AsnOrderItem asnOrderItem = JSONObject.parseObject(JSONObject.toJSONString(params), AsnOrderItem.class); |
| | | if (StringUtils.isBlank(asnOrderItem.getTrackCode())) { |
| | | SerialRuleUtils.generateRuleCode(SerialRuleCode.SYS_LABEL_CODE, params); |
| | | } |
| | | if (!this.saveOrUpdate(asnOrderItem)) { |
| | | throw new CoolException("收货通知单明细保存失败!!"); |
| | | } |
| | |
| | | item.put("asnId", orders.getId()); |
| | | item.put("asnCode", orders.getCode()); |
| | | item.put("poCode", orders.getPoCode()); |
| | | |
| | | if (!asnOrderItemService.fieldsSave(item)) { |
| | | throw new CoolException("明细保存失败!!"); |
| | | } |
| | |
| | | public final static String SYS_RECEIPT_BATCH = "sys_receipt_batch"; |
| | | |
| | | /** |
| | | * ASN标签生成规则 |
| | | * ASN物料标签生成规则 |
| | | */ |
| | | public final static String SYS_LABEL_CODE = "sys_label_code"; |
| | | public final static String SYS_LABEL_CODE = "sys_asn_mantr_label"; |
| | | |
| | | /** |
| | | * 质检单业务类型 |
| | |
| | | .list(new LambdaQueryWrapper<SerialRuleItem>() |
| | | .eq(SerialRuleItem::getRuleId, serialRule.getId()) |
| | | .orderByAsc(SerialRuleItem::getSort)); |
| | | if (Objects.isNull(ruleItems)) { |
| | | if (Objects.isNull(ruleItems) || ruleItems.isEmpty()) { |
| | | throw new CoolException("编码规则明细为空!!"); |
| | | } |
| | | |
| | |
| | | //判断是否设置截取长度和起始截取位置 |
| | | buffer.append(subStr(format, rule.getLenStr(), rule.getLen())); |
| | | } else if (rule.getWkType().equals(SerialRuleType.WK_FEILD.wkType)) { |
| | | String subStr = subStr(objectToMap(obj).get(rule.getFeildValue()).toString(), rule.getLenStr(), rule.getLen()); |
| | | buffer.append(subStr); |
| | | String subStr; |
| | | if (!Objects.isNull(objectToMap(obj).get(rule.getFeildValue()))) { |
| | | subStr = subStr(objectToMap(obj).get(rule.getFeildValue()).toString(), rule.getLenStr(), rule.getLen()); |
| | | buffer.append(subStr); |
| | | } |
| | | } |
| | | }); |
| | | |