| | |
| | | result: 'Contacts import complete. Imported %{success} success, with %{error} errors', |
| | | }, |
| | | loadMore: 'Load More Data', |
| | | updateSucc: 'Update Success', |
| | | updateFaild: 'Update Failed', |
| | | complete: 'Complete', |
| | | deprecate: 'Deprecate', |
| | | stockError: 'Empty', |
| | |
| | | result: '导入完成。已导入 %{success} 成功, 和 %{error} 失败', |
| | | }, |
| | | loadMore: '加载更多', |
| | | updateSucc: '更新成功', |
| | | updateFaild: '更新失败', |
| | | complete: '完成', |
| | | deprecate: '废弃', |
| | | stockError: '没有库存', |
| | |
| | | platOrderCode: '客单号', |
| | | anfme: "计划出库数", |
| | | stockUnit: "库存单位", |
| | | workQty: '执行数', |
| | | workQty: '已出数量', |
| | | purQty: "下单数量", |
| | | purUnit: "单位", |
| | | qty: "完成数量", |
| | |
| | | Button, |
| | | useRedirect, |
| | | useUnselectAll, |
| | | useRecordSelection, |
| | | } from 'react-admin'; |
| | | import { Box, Typography, Card, Stack, Drawer } from '@mui/material'; |
| | | import { styled } from '@mui/material/styles'; |
| | |
| | | import AddTaskIcon from '@mui/icons-material/AddTask'; |
| | | import PageEditDrawer from "../../components/PageEditDrawer"; |
| | | import OutStockPublic from "./OutStockPublic"; |
| | | import OutOrderPreview from "./OutOrderPreview"; |
| | | |
| | | const StyledDatagrid = styled(DatagridConfigurable)(({ theme }) => ({ |
| | | '& .css-1vooibu-MuiSvgIcon-root': { |
| | |
| | | const translate = useTranslate(); |
| | | const [createDialog, setCreateDialog] = useState(false); |
| | | const [manualDialog, setManualDialog] = useState(false); |
| | | const [preview, setPreview] = useState(false); |
| | | const [drawerVal, setDrawerVal] = useState(false); |
| | | const [modalType, setmodalType] = useState(0); |
| | | const [select, setSelect] = useState(0); |
| | |
| | | <OutOrderModal |
| | | open={createDialog} |
| | | setOpen={setCreateDialog} |
| | | preview={preview} |
| | | setPreview={setPreview} |
| | | /> |
| | | <OutOrderPreview open={preview} setOpen={setPreview} /> |
| | | <PageEditDrawer |
| | | title={"toolbar.publicWorking"} |
| | | drawerVal={drawerVal} |
| | | setDrawerVal={setDrawerVal} |
| | | > |
| | | <OutStockPublic record={select} open={drawerVal} setOpen={setDrawerVal}/> |
| | | <OutStockPublic record={select} open={drawerVal} setOpen={setDrawerVal} /> |
| | | </PageEditDrawer> |
| | | </Box > |
| | | ) |
| | |
| | | const record = useRecordContext(); |
| | | const notify = useNotify(); |
| | | const refresh = useRefresh(); |
| | | |
| | | const createByOrder = async (event) => { |
| | | event.stopPropagation(); |
| | | setCreateDialog(true); |
| | |
| | | import request from '@/utils/request'; |
| | | import SaveIcon from '@mui/icons-material/Save'; |
| | | import CheckCircleIcon from '@mui/icons-material/CheckCircle'; |
| | | import EditableTextField from "../../components/EditableTextField"; |
| | | import OutOrderPreview from "./OutOrderPreview"; |
| | | |
| | | const StyledDatagrid = styled(DatagridConfigurable)(({ theme }) => ({ |
| | | '& .css-1vooibu-MuiSvgIcon-root': { |
| | |
| | | ] |
| | | |
| | | const OutOrderModal = (props) => { |
| | | const { open, setOpen, record } = props; |
| | | const { open, setOpen, preview, setPreview, record } = props; |
| | | const translate = useTranslate(); |
| | | const [params, setParams] = useState({}); |
| | | const [select, setSelect] = useState([]); |
| | | |
| | | const [drawerVal, setDrawerVal] = useState(false); |
| | | const refresh = useRefresh(); |
| | | |
| | |
| | | /> |
| | | <StyledDatagrid |
| | | preferenceKey='deliveryItem' |
| | | bulkActionButtons={<AddOutStockButton setOpen={setOpen} />} |
| | | bulkActionButtons={<AddOutStockButton setOpen={setOpen} setPreview={setPreview} setSelect={setSelect} />} |
| | | rowClick={(id, resource, record) => false} |
| | | expand={false} |
| | | expandSingle={true} |
| | | omit={['id', 'createTime', 'createBy', 'memo', 'workQty', 'startTime', 'endTime', 'updateBy', 'createTime']} |
| | | omit={['id', 'createTime', 'createBy', 'memo', 'startTime', 'endTime', 'updateBy', 'createTime']} |
| | | > |
| | | <NumberField source="id" /> |
| | | <TextField source="deliveryCode" label="table.field.deliveryItem.deliveryCode" /> |
| | |
| | | <TextField source="maktx" label="table.field.deliveryItem.matnrName" /> |
| | | <TextField source="unit" label="table.field.deliveryItem.unit" /> |
| | | <NumberField source="anfme" label="table.field.deliveryItem.anfme" /> |
| | | <NumberField source="workQty" label="table.field.outStockItem.workQty" /> |
| | | <TextField source="splrName" label="table.field.deliveryItem.splrName" /> |
| | | <TextField source="splrBatch" label="table.field.deliveryItem.splrBatch" /> |
| | | <TextField source="updateBy$" label="common.field.updateBy" /> |
| | |
| | | </Grid> |
| | | </DialogContent> |
| | | </Grid> |
| | | <Grid> |
| | | <OutOrderPreview open={preview} setOpen={setPreview} selectedIds={select} /> |
| | | </Grid> |
| | | </Dialog > |
| | | ) |
| | | } |
| | |
| | | export default OutOrderModal; |
| | | |
| | | const AddOutStockButton = (props) => { |
| | | const { setOpen } = props; |
| | | const { setOpen, setPreview, setSelect } = props; |
| | | const { selectedIds, onUnselectItems } = useListContext(); |
| | | const notify = useNotify(); |
| | | const refresh = useRefresh(); |
| | | const confirm = async (event) => { |
| | | const res = await request.post(`/outStock/generate/orders`, { ids: selectedIds }); |
| | | if (res?.data?.code === 200) { |
| | | notify(res.data.msg); |
| | | } else { |
| | | notify(res.data.msg); |
| | | } |
| | | refresh(); |
| | | setPreview(true) |
| | | setSelect(selectedIds); |
| | | onUnselectItems(); |
| | | setOpen(false); |
| | | // refresh(); |
| | | } |
| | | |
| | | return ( |
New file |
| | |
| | | import { Dialog, DialogActions, DialogContent, DialogTitle, Box, LinearProgress, Grid, } from "@mui/material"; |
| | | import React, { useState, useRef, useEffect, useMemo, memo } from "react"; |
| | | import { |
| | | Toolbar, |
| | | Button, |
| | | useTranslate, |
| | | useNotify, |
| | | useRefresh, |
| | | useGetList, |
| | | } from 'react-admin'; |
| | | import request from '@/utils/request'; |
| | | import { styled } from '@mui/material/styles'; |
| | | import { PAGE_DRAWER_WIDTH, OPERATE_MODE, DEFAULT_PAGE_SIZE } from '@/config/setting'; |
| | | import { DataGrid, useGridApiContext, GridActionsCellItem, useGridApiRef } from '@mui/x-data-grid'; |
| | | import DialogCloseButton from "../../components/DialogCloseButton"; |
| | | |
| | | |
| | | const OutOrderPreview = (props) => { |
| | | const { open, setOpen, record, selectedIds } = props; |
| | | const translate = useTranslate(); |
| | | const gridRef = useGridApiRef(); |
| | | const [rows, setRows] = useState([]); |
| | | const notify = useNotify(); |
| | | const refresh = useRefresh(); |
| | | const handleClose = async (event, reason) => { |
| | | if (reason !== "backdropClick") { |
| | | // const res = await request.get(`/outStock/items/cancel/` + selectedIds); |
| | | setOpen(false); |
| | | } |
| | | }; |
| | | |
| | | if (!selectedIds) { return } |
| | | |
| | | const { data, isLoading, error } = useGetList('/deliveryItem/edit', { |
| | | pagination: { page: 1, perPage: 1000 }, |
| | | filter: { deleted: 0, ids: selectedIds } |
| | | }); |
| | | |
| | | return ( |
| | | <Dialog |
| | | open={open} |
| | | onClose={handleClose} |
| | | aria-labelledby="form-dialog-title" |
| | | aria-hidden |
| | | fullWidth |
| | | maxWidth="lg" |
| | | > |
| | | <DialogTitle id="form-dialog-title" sx={{ |
| | | position: 'sticky', |
| | | top: 0, |
| | | backgroundColor: 'background.paper', |
| | | zIndex: 1000 |
| | | }}> |
| | | {translate('create.title')} |
| | | <Box sx={{ position: 'absolute', top: 8, right: 8, zIndex: 1001 }}> |
| | | <DialogCloseButton onClose={handleClose} /> |
| | | </Box> |
| | | </DialogTitle> |
| | | <DialogContent> |
| | | <Grid container xl={12}> |
| | | <Grid item xl={12}> |
| | | <Box display="flex" sx={{ height: 400, width: '100%', '& .RaConfigurable-root': { width: '100%' } }}> |
| | | <LinearProgress sx={{ height: "2px", position: 'absolute', top: 0, left: 0, right: 0, }} /> |
| | | <OrderPreview rows={data} gridRef={gridRef} /> |
| | | </Box > |
| | | </Grid> |
| | | </Grid> |
| | | <Toolbar sx={{ justifyContent: 'end' }}> |
| | | <ConfirmButton label="toolbar.confirm" variant="contained" size="large" gridRef={gridRef} setOpen={setOpen} /> |
| | | </Toolbar> |
| | | </DialogContent> |
| | | </Dialog> |
| | | ) |
| | | } |
| | | |
| | | export default OutOrderPreview; |
| | | |
| | | const ConfirmButton = ({ gridRef, setOpen }) => { |
| | | const refresh = useRefresh(); |
| | | const notify = useNotify(); |
| | | const confirm = async () => { |
| | | const items = gridRef.current?.getSortedRows(); |
| | | const { data: { code, msg } } = await request.post(`/outStock/generate/orders`, { ids: items }); |
| | | if (code === 200) { |
| | | notify(msg); |
| | | refresh() |
| | | setOpen(false) |
| | | } else { |
| | | notify(msg); |
| | | } |
| | | } |
| | | |
| | | return ( |
| | | <Button label="toolbar.confirm" variant="contained" size="large" onClick={confirm} /> |
| | | ) |
| | | } |
| | | |
| | | const OrderPreview = ({ rows, gridRef }) => { |
| | | gridRef.current = useGridApiRef(); |
| | | |
| | | const columns = [ |
| | | { field: 'matnrCode', headerName: '物料编码', width: 110 }, |
| | | { field: 'maktx', headerName: '物料名称', width: 190 }, |
| | | { |
| | | field: 'anfme', headerName: '出库数量', width: 110, type: 'number', editable: true, |
| | | valueGetter: (value, row) => { |
| | | return row.anfme - row.workQty - row.qty; |
| | | }, |
| | | }, |
| | | { |
| | | field: 'workQty', headerName: '剩余数量', width: 110, type: 'number', |
| | | valueGetter: (value, row) => { |
| | | return row.anfme - row.workQty - row.qty; |
| | | }, |
| | | }, |
| | | { field: 'unit', headerName: '单位', width: 110 }, |
| | | { field: 'splrBatch', headerName: '批次', width: 110 }, |
| | | { field: 'splrName', headerName: '供应商', width: 110 }, |
| | | { field: 'updateTime', headerName: '更新时间', width: 110 }, |
| | | { field: 'updateBy$', headerName: '更新人员', width: 110 }, |
| | | ] |
| | | |
| | | return ( |
| | | <DataGrid |
| | | storeKey={"outOrderItemPreview"} |
| | | rows={rows} |
| | | columns={columns} |
| | | apiRef={gridRef} |
| | | disableRowSelectionOnClick |
| | | hideFooterPagination={true} // 隐藏分页控件 |
| | | hideFooter={true} |
| | | onRowSelectionModelChange={(ids) => { |
| | | setSelectedIds(ids) |
| | | }} |
| | | /> |
| | | ) |
| | | } |
| | | |
| | | |
| | |
| | | const notify = useNotify(); |
| | | const gridRef = useGridApiRef(); |
| | | const [rows, setRows] = useState([]); |
| | | const [fetchRows, setFetchRows] = useState([]); |
| | | const translate = useTranslate(); |
| | | const [rowSelectedIds, setRowSelectedIds] = useState([]); |
| | | const [selectedMatnr, setSelectedMatnr] = useState([]); |
| | | const [selectedIds, setSelectedIds] = useState([]); |
| | | const [formData, setFormData] = useState({ |
| | | orderId: record?.id, |
| | | waveId: DEFAULT_TYPE |
| | | }); |
| | | const [formData, setFormData] = useState({ orderId: record?.id, waveId: DEFAULT_TYPE }); |
| | | const [dialog, setDialog] = useState(false); |
| | | const [selectedValue, setSelectedValue] = useState({}); |
| | | |
| | | useEffect(() => { |
| | | if (selectedMatnr.length < 1) { |
| | | setRows(fetchRows) |
| | | } else { |
| | | const mas = fetchRows.filter(item => selectedMatnr.includes(item.matnrCode)); |
| | | setRows(mas) |
| | | } |
| | | }, [selectedMatnr]) |
| | | |
| | | |
| | | const handleRowClick = (id, resource, record) => { |
| | | setRowSelectedIds(prev => |
| | | prev.includes(id) |
| | | ? prev.filter(item => item !== id) // 取消选择 |
| | | : [...prev, id] // 添加选择 |
| | | ); |
| | | |
| | | //设置库位信息筛选条件 |
| | | setSelectedMatnr(prev => |
| | | prev.includes(record?.matnrCode) |
| | | ? prev.filter(item => item !== record?.matnrCode) // 取消选择 |
| | | : [...prev, record?.matnrCode] // 添加选择 |
| | | ); |
| | | }; |
| | | |
| | | const handleClickOpen = () => { |
| | | setDialog(true); |
| | |
| | | const handleClose = (value) => { |
| | | setDialog(false); |
| | | setSelectedValue(value); |
| | | const newRows = rows.map(item => { |
| | | return selectedIds.includes(item?.id) ? { |
| | | ...item, |
| | | siteNo: value?.site |
| | | } : item |
| | | }) |
| | | setRows(newRows); |
| | | if (selectedIds.length == 0) { |
| | | const newRows = rows.map(item => { |
| | | return { |
| | | ...item, |
| | | siteNo: value?.site |
| | | } |
| | | }) |
| | | setRows(newRows); |
| | | } else { |
| | | const newRows = rows.map(item => { |
| | | return selectedIds.includes(item?.id) ? { |
| | | ...item, |
| | | siteNo: value?.site |
| | | } : item |
| | | }) |
| | | setRows(newRows); |
| | | } |
| | | }; |
| | | |
| | | useEffect(() => { |
| | |
| | | const { data: { code, data, msg } } = await request.post('/outStock/order/getOutTaskItems', { ...formData }); |
| | | if (code === 200) { |
| | | setRows(data) |
| | | setFetchRows(data) |
| | | } else { |
| | | notify(msg); |
| | | } |
| | |
| | | sx={{ height: "2px", position: 'absolute', top: 0, left: 0, right: 0, }} |
| | | /> |
| | | <StyledDatagrid |
| | | storeKey={"outStockPublic"} |
| | | preferenceKey='outStockItem' |
| | | bulkActionButtons={<></>} |
| | | rowClick={false} |
| | | omit={['id', 'splrName', 'qty', 'poCode', 'workQty']} |
| | | rowClick={handleRowClick} |
| | | selectedIds={rowSelectedIds} |
| | | omit={['id', 'splrName', 'qty', 'poCode',]} |
| | | > |
| | | <NumberField source="id" /> |
| | | <TextField source="asnCode" label="table.field.outStockItem.asnCode" /> |
| | |
| | | </Card> |
| | | </Grid> |
| | | <Grid item xl={6.3} gap={2}> |
| | | <Card> |
| | | <Box sx={{ height: 500, width: '100%' }}> |
| | | <Card sx={{ minHeight: 1050, height: 'calc(100% - 10px)', width: '100%' }}> |
| | | <Box> |
| | | <PreviewTable |
| | | rows={rows} |
| | | gridRef={gridRef} |
| | |
| | | } |
| | | }, [selectedIds]) |
| | | |
| | | |
| | | const baseColumns = [ |
| | | // { field: 'id', headerName: 'ID', width: 40 }, |
| | | { field: 'locCode', headerName: '库位', width: 110 }, |
| | |
| | | { field: 'batch', headerName: '批次', width: 90 }, |
| | | { field: 'unit', headerName: '单位', width: 60 }, |
| | | { field: 'outQty', headerName: '出库数量', width: 110, }, |
| | | { |
| | | field: 'anfme', headerName: '库存数量', width: 110, |
| | | { field: 'anfme', headerName: '库存数量', width: 110, |
| | | renderCell: (params) => ( |
| | | <OutStockAnfme value={params.value} /> |
| | | ) |
| | |
| | | |
| | | return ( |
| | | <DataGrid |
| | | storeKey={"locItemPreview"} |
| | | rows={rows} |
| | | columns={columns} |
| | | slots={{ toolbar: CustomToolBar }} |
| | |
| | | /> |
| | | ) |
| | | } |
| | | |
| | | |
| | | |
| | | //提交按钮 |
New file |
| | |
| | | import { Box, Card, Grid, List, LinearProgress, Select, MenuItem, ListItemText, ListItemAvatar, Avatar, ListItemButton, Dialog, DialogTitle, ListItem } from "@mui/material"; |
| | | import React, { useState, useRef, useEffect, useMemo } from "react"; |
| | | import { PAGE_DRAWER_WIDTH, OPERATE_MODE, DEFAULT_PAGE_SIZE, DEFAULT_ITEM_PAGE_SIZE } from '@/config/setting'; |
| | | import { Delete, Edit, Add } from '@mui/icons-material'; |
| | | import request from '@/utils/request'; |
| | | import { useTranslate } from "react-admin"; |
| | | |
| | | const OutStockSiteDialog = (props) => { |
| | | const translate = useTranslate(); |
| | | const { onClose, selectedValue, open } = props; |
| | | const [siteNos, setSiteNos] = useState([]); |
| | | |
| | | const handleClose = () => { |
| | | onClose(selectedValue); |
| | | } |
| | | |
| | | const handleListItemClick = (value) => { |
| | | onClose(value); |
| | | } |
| | | |
| | | useEffect(() => { |
| | | getSiteNos() |
| | | }, [open]) |
| | | |
| | | |
| | | const getSiteNos = async () => { |
| | | const { data: { code, data, msg } } = await request.get('/outStock/tasks/sites'); |
| | | if (code === 200) { |
| | | setSiteNos(data); |
| | | } else { |
| | | notify(msg); |
| | | } |
| | | } |
| | | |
| | | return ( |
| | | <Dialog |
| | | onClose={handleClose} |
| | | open={open} |
| | | > |
| | | <DialogTitle>{translate("toolbar.modiftySite")}</DialogTitle> |
| | | <List sx={{ pt: 0 }}> |
| | | {siteNos.map((site) => ( |
| | | <ListItem disableGutters key={site?.id}> |
| | | <ListItemButton onClick={() => handleListItemClick(site)}> |
| | | <ListItemText primary={site.site} /> |
| | | </ListItemButton> |
| | | </ListItem> |
| | | ))} |
| | | </List> |
| | | </Dialog> |
| | | ); |
| | | } |
| | | |
| | | export default OutStockSiteDialog; |
| | |
| | | return R.ok().add(deliveryItemService.page(pageParam, wrapper)); |
| | | } |
| | | |
| | | |
| | | @PreAuthorize("hasAuthority('manager:deliveryItem:list')") |
| | | @ApiOperation("分页获取列表") |
| | | @PostMapping("/deliveryItem/edit/page") |
| | | public R byPoIdspage(@RequestBody Map<String, Object> map) { |
| | | List<Long> poDetlIds = new ArrayList<>(); |
| | | if (!Objects.isNull(map.get("ids"))) { |
| | | poDetlIds = JSONArray.parseArray(JSONArray.toJSONString(map.get("ids")), Long.class); |
| | | map.remove("ids"); |
| | | } |
| | | BaseParam baseParam = buildParam(map, BaseParam.class); |
| | | PageParam<DeliveryItem, BaseParam> pageParam = new PageParam<>(baseParam, DeliveryItem.class); |
| | | QueryWrapper<DeliveryItem> queryWrapper = pageParam.buildWrapper(true); |
| | | if (!poDetlIds.isEmpty()) { |
| | | queryWrapper.in("id", poDetlIds); |
| | | } else { |
| | | return R.ok(); |
| | | } |
| | | return R.ok().add(deliveryItemService.page(pageParam, queryWrapper)); |
| | | } |
| | | |
| | | |
| | | |
| | | @PreAuthorize("hasAuthority('manager:deliveryItem:list')") |
| | | @PostMapping("/deliveryItem/list") |
| | | public R list(@RequestBody Map<String, Object> map) { |
| | |
| | | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
| | | import com.vincent.rsf.framework.common.Cools; |
| | | import com.vincent.rsf.framework.common.R; |
| | | import com.vincent.rsf.framework.exception.CoolException; |
| | | import com.vincent.rsf.server.manager.controller.params.OrderOutTaskParam; |
| | | import com.vincent.rsf.server.manager.controller.params.OutStockToTaskParams; |
| | | import com.vincent.rsf.server.manager.entity.DeliveryItem; |
| | | import com.vincent.rsf.server.manager.entity.excel.OutStockTemplate; |
| | | import com.vincent.rsf.server.manager.enums.OrderType; |
| | | import com.vincent.rsf.server.manager.enums.OrderWorkType; |
| | |
| | | @RestController |
| | | @Api(tags = "出库单据") |
| | | public class OutStockController extends BaseController { |
| | | |
| | | Logger logger = LoggerFactory.getLogger(OutStockController.class); |
| | | |
| | | @Autowired |
| | |
| | | @PreAuthorize("hasAuthority('manager:outStock:list')") |
| | | @PostMapping("/outStock/page") |
| | | public R page(@RequestBody Map<String, Object> map) { |
| | | BaseParam baseParam = buildParam(map, BaseParam.class); |
| | | PageParam<AsnOrder, BaseParam> pageParam = new PageParam<>(baseParam, AsnOrder.class); |
| | | QueryWrapper<AsnOrder> queryWrapper = pageParam.buildWrapper(true); |
| | | List<String> list = Arrays.asList(OrderType.ORDER_OUT.type); |
| | | queryWrapper.in("type", list); |
| | | return R.ok().add(outStockService.page(pageParam, queryWrapper)); |
| | | } |
| | | |
| | | @PreAuthorize("hasAuthority('manager:outStock:list')") |
| | | @PostMapping("/outStock/dialog/page") |
| | | public R dialogPage(@RequestBody Map<String, Object> map) { |
| | | BaseParam baseParam = buildParam(map, BaseParam.class); |
| | | PageParam<AsnOrder, BaseParam> pageParam = new PageParam<>(baseParam, AsnOrder.class); |
| | | QueryWrapper<AsnOrder> queryWrapper = pageParam.buildWrapper(true); |
| | |
| | | return outStockService.cancelOutOrder(id); |
| | | } |
| | | |
| | | @PreAuthorize("hasAuthority('manager:outStock:update')") |
| | | @ApiOperation("删除已生成明细") |
| | | @GetMapping("/outStock/items/cancel/{ids}") |
| | | public R cancel(@PathVariable Long[] ids) { |
| | | List<Long> list = Arrays.asList(ids); |
| | | if (list.isEmpty()) { |
| | | return R.error("参数不能为空!!"); |
| | | } |
| | | List<AsnOrderItem> orderItems = outStockItemService.list(new LambdaQueryWrapper<AsnOrderItem>().in(AsnOrderItem::getId, list)); |
| | | if (orderItems.isEmpty()) { |
| | | throw new CoolException("单据明细不存在!!"); |
| | | } |
| | | return outStockService.cancelOutOrderByItems(orderItems); |
| | | } |
| | | |
| | | |
| | | @PreAuthorize("hasAuthority('manager:outStock:list')") |
| | | @PostMapping("/outStock/export") |
| | |
| | | if (Objects.isNull(params.get("ids"))) { |
| | | return R.error("参数不能为空!!"); |
| | | } |
| | | List<Long> ids = (List<Long>) params.get("ids"); |
| | | return outStockService.genOutStock(ids, getLoginUserId()); |
| | | List<DeliveryItem> items = JSON.parseArray(JSONObject.toJSONString(params.get("ids")), DeliveryItem.class); |
| | | return outStockService.genOutStock(items, getLoginUserId()); |
| | | } |
| | | |
| | | @PreAuthorize("hasAuthority('manager:outStock:update')") |
| | |
| | | import com.alibaba.fastjson.JSONArray; |
| | | import com.alibaba.fastjson.JSONObject; |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; |
| | | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
| | | import com.vincent.rsf.framework.common.Cools; |
| | | import com.vincent.rsf.framework.common.R; |
| | |
| | | public R page(@RequestBody Map<String, Object> map) { |
| | | BaseParam baseParam = buildParam(map, BaseParam.class); |
| | | PageParam<AsnOrderItem, BaseParam> pageParam = new PageParam<>(baseParam, AsnOrderItem.class); |
| | | return R.ok().add(outStockItemService.listByAsnId(pageParam, pageParam.buildWrapper(true))); |
| | | QueryWrapper<AsnOrderItem> queryWrapper = pageParam.buildWrapper(true); |
| | | return R.ok().add(outStockItemService.listByAsnId(pageParam, queryWrapper)); |
| | | } |
| | | |
| | | @PreAuthorize("hasAuthority('manager:outStockItem:list')") |
| | |
| | | return R.ok("Update Success").add(asnOrderItem); |
| | | } |
| | | |
| | | |
| | | @PreAuthorize("hasAuthority('manager:outStockItem:remove')") |
| | | @OperationLog("Delete 出库单明细") |
| | | @PostMapping("/outStockItem/remove/{ids}") |
| | |
| | | return R.ok().add(vos); |
| | | } |
| | | |
| | | |
| | | @PreAuthorize("hasAuthority('manager:outStockItem:list')") |
| | | @PostMapping("/outStockItem/export") |
| | | @ApiOperation("导出出库单明细") |
| | |
| | | import com.vincent.rsf.server.manager.controller.params.OrderOutTaskParam; |
| | | import com.vincent.rsf.server.manager.controller.params.OutStockToTaskParams; |
| | | import com.vincent.rsf.server.manager.entity.AsnOrder; |
| | | import com.vincent.rsf.server.manager.entity.AsnOrderItem; |
| | | import com.vincent.rsf.server.manager.entity.DeliveryItem; |
| | | |
| | | import java.util.List; |
| | | |
| | |
| | | |
| | | R cancelOutOrder(String id); |
| | | |
| | | R genOutStock(List<Long> ids, Long loginUserId); |
| | | R genOutStock(List<DeliveryItem> ids, Long loginUserId); |
| | | |
| | | R generateWaves(List<Long> ids); |
| | | |
| | |
| | | R genOutStockTask(List<OutStockToTaskParams> params, Long loginUserId, Long outId); |
| | | |
| | | R getSiteNos(); |
| | | |
| | | R cancelOutOrderByItems(List<AsnOrderItem> orderItems); |
| | | } |
| | |
| | | } |
| | | |
| | | Double orgQty = locItems.stream().mapToDouble(LocItem::getAnfme).sum(); |
| | | Double workQty = locItems.stream().mapToDouble(LocItem::getWorkQty).sum(); |
| | | List<LocItem> locItemList = listMap.get(key); |
| | | Double outQty = locItemList.stream().mapToDouble(LocItem::getOutQty).sum(); |
| | | |
| | | // Task serviceOne = taskService.getOne(new LambdaQueryWrapper<Task>().eq(Task::getBarcode, loc.getBarcode())); |
| | | // if (!Objects.isNull(serviceOne)) { |
| | | // throw new CoolException("托盘任务执行中,不能重复创建!"); |
| | | // } |
| | | |
| | | if (map.getType().equals(Constants.TASK_TYPE_OUT_STOCK) || map.getType().equals(Constants.TASK_TYPE_ORDER_OUT_STOCK)) { |
| | | Double useQty = Math.round((outQty + workQty) * 10000) / 10000.0; |
| | | if (orgQty.compareTo(useQty) > 0) { |
| | | if (orgQty.compareTo(outQty) > 0) { |
| | | //拣料出库 |
| | | DeviceSite deviceSite = deviceSiteService.getOne(new LambdaQueryWrapper<DeviceSite>() |
| | | .eq(DeviceSite::getSite, siteNo) |
| | |
| | | */ |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public R genOutStock(List<Long> ids, Long loginUserId) { |
| | | if (Objects.isNull(ids) || ids.isEmpty()) { |
| | | throw new CoolException("参数不能为空!!"); |
| | | } |
| | | List<DeliveryItem> items = deliveryItemService.list(new LambdaQueryWrapper<DeliveryItem>().in(DeliveryItem::getId, ids)); |
| | | public R genOutStock(List<DeliveryItem> items, Long loginUserId) { |
| | | if (items.isEmpty()) { |
| | | throw new CoolException("单据不存在!!"); |
| | | throw new CoolException("参数不能为空!!"); |
| | | } |
| | | Map<Long, List<DeliveryItem>> listMap = items.stream().collect(Collectors.groupingBy(DeliveryItem::getDeliveryId)); |
| | | listMap.keySet().forEach(key -> { |
| | |
| | | AsnOrder order = new AsnOrder(); |
| | | BeanUtils.copyProperties(delivery, order); |
| | | String ruleCode = SerialRuleUtils.generateRuleCode(SerialRuleCode.SYS_OUT_STOCK_CODE, order); |
| | | if (Objects.isNull(ruleCode) || StringUtils.isBlank(ruleCode)) { |
| | | if (StringUtils.isBlank(ruleCode)) { |
| | | throw new CoolException("编码规则错误:请检查 「SYS_OUT_STOCK_CODE」编码是否设置成功"); |
| | | } |
| | | order.setExceStatus(AsnExceStatus.OUT_STOCK_STATUS_TASK_INIT.val) |
| | |
| | | } |
| | | List<AsnOrderItem> orderItems = new ArrayList<>(); |
| | | listMap.get(key).forEach(item -> { |
| | | DeliveryItem deliveryItem = deliveryItemService.getById(item.getId()); |
| | | AsnOrderItem orderItem = new AsnOrderItem(); |
| | | Double anfme = Math.round((item.getAnfme() - item.getWorkQty() - item.getQty()) * 10000) / 10000.0; |
| | | if (item.getAnfme().compareTo(0.0) <= 0) { |
| | | throw new CoolException("出库数量不能小于或等于零!!"); |
| | | } |
| | | Double anfme = Math.round((deliveryItem.getAnfme() - item.getAnfme()) * 10000) / 10000.0; |
| | | if (anfme.compareTo(0.0) < 0) { |
| | | throw new CoolException("出库数量不足!!"); |
| | | } |
| | | |
| | | BeanUtils.copyProperties(item, orderItem); |
| | | orderItem.setId(null) |
| | | .setPoCode(order.getPoCode()) |
| | | .setMaktx(item.getMaktx()) |
| | | .setMatnrCode(item.getMatnrCode()) |
| | | .setFieldsIndex(item.getFieldsIndex()) |
| | | .setAnfme(anfme) |
| | | .setAnfme(item.getAnfme()) |
| | | .setWorkQty(0.0) |
| | | .setAsnId(order.getId()) |
| | | .setAsnCode(order.getCode()) |
| | |
| | | .eq(Delivery::getId, key))) { |
| | | throw new CoolException("主单修改失败!!"); |
| | | } |
| | | |
| | | }); |
| | | return R.ok(); |
| | | } |
| | |
| | | if (Objects.isNull(param)) { |
| | | continue; |
| | | } |
| | | Loc loc = locService.getOne(new LambdaQueryWrapper<Loc>().eq(Loc::getBarcode, param.getBarcode())); |
| | | Loc loc = locService.getOne(new LambdaQueryWrapper<Loc>().eq(Loc::getCode, param.getLocCode()).eq(Loc::getBarcode, param.getBarcode())); |
| | | if (!Objects.isNull(loc)) { |
| | | List<LocItem> locItems = new ArrayList<>(); |
| | | LocItem locItem = locItemService.getById(param.getId()); |
| | |
| | | |
| | | /** |
| | | * 获取出库站点 |
| | | * |
| | | * @return |
| | | */ |
| | | @Override |
| | |
| | | TaskType.TASK_TYPE_PICK_AGAIN_OUT.type); |
| | | List<DeviceSite> sites = deviceSiteService.list(new LambdaQueryWrapper<DeviceSite>().in(DeviceSite::getType, list).groupBy(DeviceSite::getSite)); |
| | | return R.ok(sites); |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public R cancelOutOrderByItems(List<AsnOrderItem> orderItems) { |
| | | Map<Long, List<AsnOrderItem>> listMap = orderItems.stream().collect(Collectors.groupingBy(AsnOrderItem::getAsnId)); |
| | | for (Long key : listMap.keySet()) { |
| | | AsnOrder order = this.getById(key); |
| | | if (Objects.isNull(order)) { |
| | | throw new CoolException("单据不存在!!"); |
| | | } |
| | | List<AsnOrderItem> items = listMap.get(key); |
| | | if (!items.isEmpty()) { |
| | | for (AsnOrderItem orderItem : items) { |
| | | DeliveryItem deliveryItem = deliveryItemService.getById(orderItem.getPoDetlId()); |
| | | Double workQty = Math.round((deliveryItem.getWorkQty() - orderItem.getAnfme()) * 10000) / 10000.0; |
| | | deliveryItem.setWorkQty(workQty.compareTo(0.0) >= 0 ? workQty : 0); |
| | | if (!deliveryItemService.updateById(deliveryItem)) { |
| | | throw new CoolException("DO单明细更新失败!!"); |
| | | } |
| | | |
| | | Delivery delivery = deliveryService.getOne(new LambdaQueryWrapper<Delivery>().eq(Delivery::getCode, orderItem.getPoCode())); |
| | | if (!Objects.isNull(delivery)) { |
| | | Double wkQty = Math.round((delivery.getWorkQty() - delivery.getAnfme()) * 10000) / 10000.0; |
| | | delivery.setWorkQty(wkQty.compareTo(0.0) >= 0 ? wkQty : 0).setExceStatus(POExceStatus.PO_EXCE_STATUS_UN_EXCE.val); |
| | | if (!deliveryService.updateById(delivery)) { |
| | | throw new CoolException("DO单据修改失败!!"); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | if (!this.remove(new LambdaQueryWrapper<AsnOrder>().eq(AsnOrder::getId, key))) { |
| | | throw new CoolException("主单删除失败!!"); |
| | | } |
| | | if (!outStockItemService.remove(new LambdaQueryWrapper<AsnOrderItem>() |
| | | .eq(AsnOrderItem::getAsnId, key))) { |
| | | throw new CoolException("单据明细删除失败!!"); |
| | | } |
| | | } |
| | | return R.ok("操作成功"); |
| | | } |
| | | |
| | | |
| | |
| | | ); |
| | | locItemQueryWrapper.apply(applySql); |
| | | List<LocItem> locItems = locItemService.list(locItemQueryWrapper); |
| | | locItems.sort(Comparator |
| | | .comparing((LocItem item) -> !LocUtils.isShallowLoc(item.getLocCode())) |
| | | ); |
| | | locItems.sort(Comparator.comparing((LocItem item) -> !LocUtils.isShallowLoc(item.getLocCode()))); |
| | | return locItems; |
| | | } |
| | | |
| | |
| | | continue; |
| | | } |
| | | List<LocItem> locItems = null; |
| | | if (WaveRuleType.Efficiency_First.type.equals(waveRule.getType())) { |
| | | locItems = getEfficiencyFirstItemList(asnOrderItem); |
| | | } else if (WaveRuleType.First_In_First_Out.type.equals(waveRule.getType())) { |
| | | locItems = getFirstInFirstOutItemList(asnOrderItem); |
| | | } else { |
| | | locItems = getFirstInFirstOutItemList(asnOrderItem); |
| | | List<LocItem> items = locItemService.list(new LambdaQueryWrapper<LocItem>() |
| | | .eq(StringUtils.isNotBlank(asnOrderItem.getSplrBatch()), LocItem::getBatch, asnOrderItem.getSplrBatch()) |
| | | .eq(StringUtils.isNotBlank(asnOrderItem.getFieldsIndex()), LocItem::getFieldsIndex, asnOrderItem.getFieldsIndex()) |
| | | .eq(StringUtils.isNotBlank(asnOrderItem.getPlatOrderCode()), LocItem::getPlatOrderCode, asnOrderItem.getPlatOrderCode()) |
| | | .eq(LocItem::getAnfme, asnOrderItem.getAnfme()) |
| | | .eq(LocItem::getMatnrId, asnOrderItem.getMatnrId())); |
| | | if (!items.isEmpty()) { |
| | | for (LocItem item : items) { |
| | | if (LocUtils.isShallowLoc(item.getLocCode())) { |
| | | locItems.add(item); |
| | | } |
| | | } |
| | | } |
| | | |
| | | if (Objects.isNull(locItems) || locItems.isEmpty()) { |
| | | if (WaveRuleType.Efficiency_First.type.equals(waveRule.getType())) { |
| | | locItems = getEfficiencyFirstItemList(asnOrderItem); |
| | | } else if (WaveRuleType.First_In_First_Out.type.equals(waveRule.getType())) { |
| | | locItems = getFirstInFirstOutItemList(asnOrderItem); |
| | | } else { |
| | | locItems = getFirstInFirstOutItemList(asnOrderItem); |
| | | } |
| | | } |
| | | |
| | | for (LocItem locItem : locItems) { |
| | | Loc loc = locService.getById(locItem.getLocId()); |
| | | List<LocItem> itemList = locItemService.list(new LambdaQueryWrapper<LocItem>().eq(LocItem::getLocCode, locItem.getLocCode())); |
| | |
| | | # global-config:
|
| | | # field-strategy: 0
|
| | | configuration:
|
| | | # log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
|
| | | log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
|
| | | map-underscore-to-camel-case: true
|
| | | cache-enabled: true
|
| | | call-setters-on-nulls: true
|