1. 调拔单功能优化
2. 7.30问题及bug修复
| | |
| | | omit={['id', 'orderId', 'poDetlId', 'poCode', 'qrcode', 'packName', 'createTime', 'memo', 'fieldsIndex', 'matnrId', 'splrCode', 'status', 'createBy$']} |
| | | > |
| | | <NumberField source="id" /> |
| | | <NumberField source="asnId" label="table.field.asnOrderItemLog.asnId" /> |
| | | <TextField source="asnCode" label="table.field.asnOrderItemLog.asnCode" /> |
| | | <NumberField source="asnId" label="table.field.asnOrderItemLog.orderId" /> |
| | | <TextField source="asnCode" label="table.field.asnOrderItemLog.orderCode" /> |
| | | <TextField source="platItemId" label="table.field.asnOrderItemLog.platItemId" /> |
| | | <NumberField source="poDetlId" label="table.field.asnOrderItemLog.poDetlId" /> |
| | | <TextField source="poCode" label="table.field.asnOrderItemLog.poCode" /> |
| | |
| | | useRecordSelection, |
| | | useRefresh, |
| | | } from 'react-admin'; |
| | | import { Box, Typography, Card, Stack } from '@mui/material'; |
| | | import { styled } from '@mui/material/styles'; |
| | | import AsnOrderLogCreate from "./AsnOrderLogCreate"; |
| | | import AsnOrderLogPanel from "./AsnOrderLogPanel"; |
| | | import EmptyData from "../../components/EmptyData"; |
| | | import { PAGE_DRAWER_WIDTH, OPERATE_MODE, DEFAULT_PAGE_SIZE } from '@/config/setting'; |
| | | import DictionarySelect from "../../components/DictionarySelect"; |
| | | import MyCreateButton from "../../components/MyCreateButton"; |
| | | import MyExportButton from '../../components/MyExportButton'; |
| | | import { Box, Typography, Card, Stack } from '@mui/material'; |
| | | import ConfirmButton from '../../components/ConfirmButton'; |
| | | import PageDrawer from "../../components/PageDrawer"; |
| | | import { PAGE_DRAWER_WIDTH, OPERATE_MODE, DEFAULT_PAGE_SIZE } from '@/config/setting'; |
| | | import AsnOrderLogCreate from "./AsnOrderLogCreate"; |
| | | import CachedIcon from '@mui/icons-material/Cached'; |
| | | import EmptyData from "../../components/EmptyData"; |
| | | import AsnOrderLogPanel from "./AsnOrderLogPanel"; |
| | | import { styled } from '@mui/material/styles'; |
| | | import * as Common from '@/utils/common'; |
| | | import request from '@/utils/request'; |
| | | import ConfirmButton from '../../components/ConfirmButton'; |
| | | import CachedIcon from '@mui/icons-material/Cached'; |
| | | |
| | | |
| | | const StyledDatagrid = styled(DatagridConfigurable)(({ theme }) => ({ |
| | | '& .css-1vooibu-MuiSvgIcon-root': { |
| | | height: '.9em' |
| | |
| | | width: 150 |
| | | }, |
| | | '& .MuiTableCell-root': { |
| | | whiteSpace: 'nowrap', |
| | | overflow: 'visible', |
| | | textOverflow: 'unset' |
| | | } |
| | | whiteSpace: 'nowrap', |
| | | overflow: 'visible', |
| | | textOverflow: 'unset' |
| | | } |
| | | })); |
| | | |
| | | const filters = [ |
| | | <SearchInput source="condition" alwaysOn />, |
| | | <TextInput source="code" label="table.field.asnOrderLog.code" />, |
| | | <TextInput source="poCode" label="table.field.asnOrderLog.poCode" />, |
| | | <NumberInput source="poId" label="table.field.asnOrderLog.poId" />, |
| | | <TextInput source="type" label="table.field.asnOrderLog.type" />, |
| | | <TextInput source="wkType" label="table.field.asnOrderLog.wkType" />, |
| | | <NumberInput source="anfme" label="table.field.asnOrderLog.anfme" />, |
| | | <NumberInput source="qty" label="table.field.asnOrderLog.qty" />, |
| | | <TextInput source="logisNo" label="table.field.asnOrderLog.logisNo" />, |
| | | <DateInput source="arrTime" label="table.field.asnOrderLog.arrTime" />, |
| | | <SelectInput source="rleStatus" label="table.field.asnOrderLog.rleStatus" |
| | | choices={[ |
| | | { id: 0, name: ' 正常' }, |
| | | { id: 1, name: ' 已释放' }, |
| | | ]} |
| | | />, |
| | | <SelectInput source="ntyStatus" label="table.field.asnOrderLog.ntyStatus" |
| | | choices={[ |
| | | { id: 0, name: ' 未上报' }, |
| | | { id: 1, name: ' 已上报' }, |
| | | { id: 2, name: ' 部分上报' }, |
| | | ]} |
| | | />, |
| | | |
| | | <TextInput label="common.field.memo" source="memo" />, |
| | | <SelectInput |
| | | label="common.field.status" |
| | | source="status" |
| | | choices={[ |
| | | { id: '1', name: 'common.enums.statusTrue' }, |
| | | { id: '0', name: 'common.enums.statusFalse' }, |
| | | ]} |
| | | resettable |
| | | />, |
| | | ] |
| | | |
| | | const AsnOrderLogList = () => { |
| | | const translate = useTranslate(); |
| | | const [createDialog, setCreateDialog] = useState(false); |
| | | const [drawerVal, setDrawerVal] = useState(false); |
| | | const dicts = JSON.parse(localStorage.getItem('sys_dicts'))?.filter(dict => (dict.dictTypeCode == 'sys_order_type')) || []; |
| | | |
| | | const filters = [ |
| | | <SearchInput source="condition" alwaysOn />, |
| | | <TextInput source="code" label="table.field.asnOrderLog.code" />, |
| | | <TextInput source="poCode" label="table.field.asnOrderLog.poCode" />, |
| | | <NumberInput source="poId" label="table.field.asnOrderLog.poId" />, |
| | | // <TextInput source="type" label="table.field.asnOrderLog.type" />, |
| | | // <TextInput source="wkType" label="table.field.asnOrderLog.wkType" />, |
| | | <NumberInput source="anfme" label="table.field.asnOrderLog.anfme" />, |
| | | <NumberInput source="qty" label="table.field.asnOrderLog.qty" />, |
| | | <TextInput source="logisNo" label="table.field.asnOrderLog.logisNo" />, |
| | | <DateInput source="arrTime" label="table.field.asnOrderLog.arrTime" />, |
| | | // <SelectInput source="ntyStatus" label="table.field.asnOrderLog.ntyStatus" |
| | | // choices={[ |
| | | // { id: 0, name: ' 未上报' }, |
| | | // { id: 1, name: ' 已上报' }, |
| | | // { id: 2, name: ' 部分上报' }, |
| | | // ]} |
| | | // />, |
| | | <AutocompleteInput |
| | | choices={dicts} |
| | | optionText="label" |
| | | label="table.field.asnOrder.type" |
| | | source="type" |
| | | // defaultValue="in" |
| | | optionValue="value" |
| | | parse={v => v} |
| | | alwaysOn |
| | | />, |
| | | <ReferenceInput source="wkType" reference="dictData" filter={{ dictTypeCode: 'sys_business_type', group: "1" }} label="table.field.asnOrder.wkType" alwaysOn> |
| | | <AutocompleteInput label="table.field.asnOrder.wkType" optionValue="value" /> |
| | | </ReferenceInput>, |
| | | <DictionarySelect |
| | | label='table.field.asnOrder.exceStatus' |
| | | name="exceStatus" |
| | | group="1" |
| | | dictTypeCode="sys_asn_exce_status" |
| | | alwaysOn |
| | | />, |
| | | ] |
| | | |
| | | return ( |
| | | <Box display="flex"> |
| | |
| | | rowClick={'edit'} |
| | | expand={false} |
| | | expandSingle={true} |
| | | omit={['id', 'createTime', 'createBy', 'memo','logisNo', 'poId', 'rleStatus$','statusBool','createBy$']} |
| | | omit={['id', 'createTime', 'createBy', 'memo', 'logisNo', 'poId', 'rleStatus$', 'statusBool', 'createBy$']} |
| | | > |
| | | <NumberField source="id" /> |
| | | <TextField source="code" label="table.field.asnOrderLog.code" /> |
| | |
| | | const record = useRecordContext(); |
| | | const notify = useNotify(); |
| | | const continueReceipt = async () => { |
| | | const { data: { code, data, msg } } = await request.post(`/asnOrderLog/continue/${record.id}`); |
| | | if (code === 200) { |
| | | notify(msg); |
| | | } else { |
| | | notify(msg); |
| | | } |
| | | refresh(); |
| | | const { data: { code, data, msg } } = await request.post(`/asnOrderLog/continue/${record.id}`); |
| | | if (code === 200) { |
| | | notify(msg); |
| | | } else { |
| | | notify(msg); |
| | | } |
| | | refresh(); |
| | | } |
| | | |
| | | return ( |
| | | <ConfirmButton label={"toolbar.continue"} startIcon={<CachedIcon />} onConfirm={continueReceipt} /> |
| | | record.type == 'in' ? <ConfirmButton label={"toolbar.continue"} startIcon={<CachedIcon />} onConfirm={continueReceipt} /> : <></> |
| | | ) |
| | | } |
| | | } |
| | |
| | | <NumberInput source="qty" label="table.field.asnOrder.qty" />, |
| | | <TextInput source="logisNo" label="table.field.asnOrder.logisNo" />, |
| | | <DateInput source="arrTime" label="table.field.asnOrder.arrTime" />, |
| | | <SelectInput source="rleStatus" label="table.field.asnOrder.rleStatus" |
| | | choices={[ |
| | | { id: 0, name: ' 正常' }, |
| | | { id: 1, name: ' 已释放' }, |
| | | ]} |
| | | />, |
| | | <TextInput label="common.field.memo" source="memo" />, |
| | | <DictionarySelect |
| | | label='table.field.asnOrder.exceStatus' |
| | |
| | | <SimpleForm |
| | | shouldUnregister |
| | | warnWhenUnsavedChanges |
| | | toolbar={<FormToolbar />} |
| | | toolbar={false} |
| | | mode="onTouched" |
| | | defaultValues={{}} |
| | | sx={{ |
| | | "& .MuiFormLabel-root.MuiInputLabel-root.Mui-disabled": { |
| | | bgcolor: 'white', |
| | | WebkitTextFillColor: "rgba(0, 0, 0)" |
| | | }, |
| | | |
| | | "& .MuiInputBase-input.MuiFilledInput-input.Mui-disabled": { |
| | | bgcolor: 'white', |
| | | WebkitTextFillColor: "rgba(0, 0, 0)" |
| | | }, |
| | | "& .MuiFilledInput-root.MuiInputBase-sizeSmall": { |
| | | bgcolor: 'white', |
| | | } |
| | | }} |
| | | // validate={(values) => { }} |
| | | > |
| | | <Grid container width={{ xs: '100%', xl: '100%' }} rowSpacing={3} columnSpacing={3}> |
| | |
| | | source="type" |
| | | optionValue="value" |
| | | parse={v => v} |
| | | readOnly |
| | | /> |
| | | <AutocompleteInput |
| | | choices={business} |
| | |
| | | source="wkType" |
| | | optionValue="value" |
| | | parse={v => v} |
| | | readOnly |
| | | /> |
| | | <TextInput |
| | | label="table.field.purchase.source" |
| | | source="source" |
| | | parse={v => v} |
| | | readOnly |
| | | validate={required()} |
| | | /> |
| | | <NumberInput |
| | | label="table.field.purchase.anfme" |
| | | source="anfme" |
| | | readOnly |
| | | validate={required()} |
| | | /> |
| | | </Stack> |
| | |
| | | <TextInput |
| | | label="table.field.purchase.project" |
| | | source="project" |
| | | readOnly |
| | | parse={v => v} |
| | | /> |
| | | <TextInput |
| | | label="table.field.purchase.channel" |
| | | source="channel" |
| | | parse={v => v} |
| | | readOnly |
| | | /> |
| | | <TextInput |
| | | label="table.field.purchase.platCode" |
| | | source="platCode" |
| | | parse={v => v} |
| | | readOnly |
| | | /> |
| | | <DateInput |
| | | label="table.field.purchase.startTime" |
| | | source="startTime" |
| | | readOnly |
| | | /> |
| | | <DateInput |
| | | label="table.field.purchase.endTime" |
| | | source="endTime" |
| | | readOnly |
| | | /> |
| | | </Stack> |
| | | </Grid> |
| | |
| | | actions={( |
| | | <TopToolbar> |
| | | <FilterButton /> |
| | | <MyCreateButton onClick={() => { setCreateDialog(true) }} /> |
| | | {/* <MyCreateButton onClick={() => { setCreateDialog(true) }} /> */} |
| | | <SelectColumnsButton preferenceKey='purchaseItem' /> |
| | | {/* <MyExportButton /> */} |
| | | </TopToolbar> |
| | |
| | | omit={['id', 'memo']} |
| | | > |
| | | <NumberField source="id" /> |
| | | <TextField source="code" label="table.field.transferOrder.code" /> |
| | | <TextField source="code" label="table.field.transferOrder.code"/> |
| | | <TextField source="poCode" label="table.field.transferOrder.poCode" /> |
| | | <TextField source="type$" label="table.field.transferOrder.type" /> |
| | | <TextField cellClassName="wkType" source="wkType$" label="table.field.transferOrder.wkType" /> |
| | |
| | | throw new CoolException("数据错误!!"); |
| | | } |
| | | if (!one.getExceStatus().equals(AsnExceStatus.OUT_STOCK_STATUS_TASK_DONE.val)) { |
| | | throw new CoolException("出库单未完成,无法完成收货!!"); |
| | | throw new CoolException("调拔出库单未完成,不可执行收货操作!!"); |
| | | } |
| | | } |
| | | |
| | |
| | | package com.vincent.rsf.server.manager.schedules; |
| | | |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; |
| | | import com.vincent.rsf.framework.exception.CoolException; |
| | | import com.vincent.rsf.server.manager.entity.WkOrder; |
| | | import com.vincent.rsf.server.manager.entity.WkOrderItem; |
| | | import com.vincent.rsf.server.manager.entity.AsnOrderItemLog; |
| | | import com.vincent.rsf.server.manager.entity.AsnOrderLog; |
| | | import com.vincent.rsf.server.manager.entity.*; |
| | | import com.vincent.rsf.server.manager.enums.AsnExceStatus; |
| | | import com.vincent.rsf.server.manager.enums.OrderType; |
| | | import com.vincent.rsf.server.manager.service.AsnOrderItemLogService; |
| | | import com.vincent.rsf.server.manager.service.AsnOrderItemService; |
| | | import com.vincent.rsf.server.manager.service.AsnOrderLogService; |
| | | import com.vincent.rsf.server.manager.service.AsnOrderService; |
| | | import com.vincent.rsf.server.manager.enums.POExceStatus; |
| | | import com.vincent.rsf.server.manager.service.*; |
| | | import org.springframework.beans.BeanUtils; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.scheduling.annotation.Scheduled; |
| | |
| | | |
| | | import java.util.ArrayList; |
| | | import java.util.List; |
| | | import java.util.Objects; |
| | | import java.util.Set; |
| | | import java.util.stream.Collectors; |
| | | |
| | |
| | | public class AsnOrderLogSchedule { |
| | | |
| | | @Autowired |
| | | private PurchaseService purchaseService; |
| | | @Autowired |
| | | private DeliveryService deliveryService; |
| | | @Autowired |
| | | private AsnOrderService asnOrderService; |
| | | @Autowired |
| | | private AsnOrderItemService asnOrderItemService; |
| | | |
| | | @Autowired |
| | | private AsnOrderLogService asnOrderLogService; |
| | | |
| | | @Autowired |
| | | private AsnOrderItemLogService asnOrderItemLogService; |
| | | |
| | | /** |
| | | * @author Ryan |
| | | * @description 删除已完成订单加入Log表 |
| | | * @param |
| | | * @return |
| | | * @author Ryan |
| | | * @description 删除已完成订单加入Log表 |
| | | * @time 2025/3/19 19:09 |
| | | */ |
| | | @Scheduled(cron = "0 0/05 * * * ? ") |
| | | @Scheduled(cron = "0/35 * * * * ? ") |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public void moveOrderToLog() { |
| | | List<WkOrder> wkOrders = asnOrderService.list(new LambdaQueryWrapper<WkOrder>() |
| | | .eq(WkOrder::getType, OrderType.ORDER_IN.type) |
| | | .eq(WkOrder::getType, OrderType.ORDER_IN.type) |
| | | .eq(WkOrder::getExceStatus, AsnExceStatus.ASN_EXCE_STATUS_TASK_DONE.val)); |
| | | if (wkOrders.isEmpty()) { |
| | | return; |
| | | } |
| | | moveOrderToLog(wkOrders, OrderType.ORDER_IN.type); |
| | | try { |
| | | moveOrderToLog(wkOrders, OrderType.ORDER_IN.type); |
| | | } catch (Exception e) { |
| | | throw new CoolException(e.getMessage()); |
| | | } |
| | | } |
| | | |
| | | |
| | | /** |
| | | * @author Ryan |
| | | * @description 出库单完成后,状态修改 |
| | | * @param |
| | | * @return |
| | | * @time 2025/6/16 08:35 |
| | | */ |
| | | // @Scheduled(cron = "0/30 * * * * ? ") |
| | | * @param |
| | | * @return |
| | | * @author Ryan |
| | | * @description 出库单完成后,状态修改 |
| | | * @time 2025/6/16 08:35 |
| | | */ |
| | | @Scheduled(cron = "0/30 * * * * ? ") |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public void outStockComplete() { |
| | | List<WkOrder> wkOrders = asnOrderService.list(new LambdaQueryWrapper<WkOrder>() |
| | | .eq(WkOrder::getType, OrderType.ORDER_OUT.type) |
| | | .eq(WkOrder::getExceStatus, AsnExceStatus.OUT_STOCK_STATUS_TASK_DONE.val) |
| | | .eq(WkOrder::getType, OrderType.ORDER_OUT.type) |
| | | .eq(WkOrder::getExceStatus, AsnExceStatus.OUT_STOCK_STATUS_TASK_DONE.val) |
| | | .apply("anfme = work_qty") |
| | | ); |
| | | if (wkOrders.isEmpty()) { |
| | | return; |
| | | } |
| | | moveOrderToLog(wkOrders, OrderType.ORDER_OUT.type); |
| | | try { |
| | | moveOrderToLog(wkOrders, OrderType.ORDER_OUT.type); |
| | | } catch (Exception e) { |
| | | throw new CoolException(e.getMessage()); |
| | | } |
| | | } |
| | | |
| | | // /** |
| | | // * @author Ryan |
| | | // * @date 2025/7/30 |
| | | // * @description: 更新调拔单状态 |
| | | // * @version 1.0 |
| | | // */ |
| | | // @Scheduled(cron = "0/30 * * * * ? ") |
| | | // @Transactional(rollbackFor = Exception.class) |
| | | // public void updateTransferExc() { |
| | | // |
| | | // } |
| | | |
| | | |
| | | |
| | | /** |
| | |
| | | * @description 添加历史单据 |
| | | * @time 2025/6/16 08:56 |
| | | */ |
| | | private void moveOrderToLog(List<WkOrder> wkOrders, String type) { |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public void moveOrderToLog(List<WkOrder> wkOrders, String type) throws Exception{ |
| | | Set<Long> longSet = wkOrders.stream().map(WkOrder::getId).collect(Collectors.toSet()); |
| | | List<WkOrderItem> orderItems = asnOrderItemService.list(new LambdaQueryWrapper<WkOrderItem>() |
| | | .in(WkOrderItem::getOrderId, longSet)); |
| | |
| | | if (!asnOrderItemLogService.saveBatch(logs)) { |
| | | throw new CoolException("单据明细历史档保存失败!!"); |
| | | } |
| | | |
| | | //更新PO/DO单执行状态 |
| | | if (type.equals(OrderType.ORDER_IN.type)) { |
| | | if (!Objects.isNull(order.getPoId())) { |
| | | if (!purchaseService.update(new LambdaUpdateWrapper<Purchase>() |
| | | .set(Purchase::getExceStatus, POExceStatus.PO_EXCE_STATUS_ALL_DONE.val) |
| | | .eq(Purchase::getId, order.getPoId()))) { |
| | | throw new CoolException("PO单更新状态更新失败!!"); |
| | | } |
| | | } |
| | | } else { |
| | | if (!Objects.isNull(order.getPoId())) { |
| | | if (!deliveryService.update(new LambdaUpdateWrapper<Delivery>() |
| | | .eq(Delivery::getId, order.getPoId()) |
| | | .set(Delivery::getExceStatus, POExceStatus.PO_EXCE_STATUS_ALL_DONE.val))) { |
| | | throw new CoolException("DO单更新状态更新失败"); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | if (!asnOrderItemService.remove(new LambdaQueryWrapper<WkOrderItem>() |
| | | .in(WkOrderItem::getOrderId, longSet))) { |
| | | throw new CoolException("原单据明细删除失败!!"); |
| | | } |
| | | if (!this.asnOrderService.removeByIds(longSet)) { |
| | | throw new CoolException("原单据删除失败!!"); |
| | | } |
| | | // if (!asnOrderItemService.remove(new LambdaQueryWrapper<WkOrderItem>() |
| | | // .in(WkOrderItem::getOrderId, longSet))) { |
| | | // throw new CoolException("原单据明细删除失败!!"); |
| | | // } |
| | | // if (!this.asnOrderService.removeByIds(longSet)) { |
| | | // throw new CoolException("原单据删除失败!!"); |
| | | // } |
| | | } |
| | | |
| | | |
| | |
| | | .setExceStatus(AsnExceStatus.ASN_EXCE_STATUS_EXCE_ING.val); |
| | | |
| | | WkOrder wkOrder = asnOrderService.getOne(new LambdaQueryWrapper<WkOrder>().eq(WkOrder::getCode, orderLog.getCode())); |
| | | if (Objects.isNull(wkOrder)) { |
| | | if (!Objects.isNull(wkOrder)) { |
| | | throw new CoolException("收货单据已添加,刷新后再操作!!"); |
| | | } |
| | | |
| | |
| | | import org.apache.commons.lang3.StringUtils; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | import org.springframework.web.multipart.MultipartFile; |
| | | |
| | | import java.io.IOException; |
| | |
| | | * @return |
| | | */ |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public R excelImport(MultipartFile file, Map<String, Object> hashMap, Long loginUserId) throws Exception { |
| | | ExcelImportResult result = ExcelImportUtil.importExcelMore(file.getInputStream(), DeliveryTemplate.class, ExcelUtil.getDefaultImportParams()); |
| | | if (result.getList().isEmpty()) { |
| | |
| | | sbFaild.append(orderTemplate.getMatnrCode()).append("物料不存在"); |
| | | throw new CoolException(sbFaild.toString()); |
| | | } |
| | | if (!matnr.getName().equals(orderTemplate.getMaktx())) { |
| | | throw new CoolException("导入物料名称与库内名称不一致!!"); |
| | | } |
| | | orderItem.setDeliveryId(order.getId()) |
| | | .setDeliveryCode(order.getCode()) |
| | | .setSplrBatch(orderTemplate.getSplrBatch()) |
| | |
| | | |
| | | @Override |
| | | public Delivery removeDo(List<Long> list) { |
| | | List<Delivery> deliveries = this.list(new LambdaQueryWrapper<Delivery>().eq(Delivery::getId, list)); |
| | | List<Delivery> deliveries = this.list(new LambdaQueryWrapper<Delivery>().in(Delivery::getId, list)); |
| | | if (deliveries.isEmpty()) { |
| | | throw new BusinessException("数据错误:单据信息不存在!!"); |
| | | } |