buhuazhen
2 天以前 acaf0e69a594f36ef9be6749c2b8d66e4ef6123b
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
package com.ruoyi.sales.controller;
 
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.approve.mapper.ApproveProcessMapper;
import com.ruoyi.approve.pojo.ApproveProcess;
import com.ruoyi.approve.service.impl.ApproveProcessServiceImpl;
import com.ruoyi.approve.vo.ApproveProcessVO;
import com.ruoyi.common.enums.FileNameType;
import com.ruoyi.common.utils.OrderUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.framework.aspectj.lang.annotation.Log;
import com.ruoyi.framework.aspectj.lang.enums.BusinessType;
import com.ruoyi.framework.security.LoginUser;
import com.ruoyi.framework.web.controller.BaseController;
import com.ruoyi.framework.web.domain.AjaxResult;
import com.ruoyi.other.service.impl.TempFileServiceImpl;
import com.ruoyi.procurementrecord.utils.StockUtils;
import com.ruoyi.sales.dto.ShippingInfoDto;
import com.ruoyi.sales.mapper.ShipmentApprovalMapper;
import com.ruoyi.sales.mapper.ShippingInfoMapper;
import com.ruoyi.sales.pojo.SalesLedger;
import com.ruoyi.sales.pojo.SalesLedgerProduct;
import com.ruoyi.sales.pojo.ShipmentApproval;
import com.ruoyi.sales.pojo.ShippingInfo;
import com.ruoyi.sales.service.ISalesLedgerProductService;
import com.ruoyi.sales.service.ISalesLedgerService;
import com.ruoyi.sales.service.ShippingInfoService;
import com.ruoyi.sales.service.impl.CommonFileServiceImpl;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
 
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.time.LocalDate;
import java.util.List;
 
/**
 * @author :yys
 * @date : 2025/10/22 9:34
 */
@RestController
@RequestMapping("/shippingInfo")
@Api(tags = "发货信息管理")
public class ShippingInfoController extends BaseController {
 
    @Autowired
    private ShippingInfoService shippingInfoService;
 
    @Autowired
    private CommonFileServiceImpl commonFileService;
 
    @Autowired
    private ApproveProcessServiceImpl approveProcessService;
    @Autowired
    private StockUtils stockUtils;
    @Autowired
    private ISalesLedgerService salesLedgerService;
 
 
    @GetMapping("/listPage")
    @ApiOperation("发货信息列表")
    public AjaxResult listPage(Page page, ShippingInfo req) {
        IPage<ShippingInfoDto> listPage = shippingInfoService.listPage(page,req);
        return AjaxResult.success(listPage);
    }
 
    @PostMapping("/add")
    @ApiOperation("添加发货信息")
    @Transactional(rollbackFor = Exception.class)
    @Log(title = "发货信息管理", businessType = BusinessType.INSERT)
    public AjaxResult add(@RequestBody ShippingInfoDto req) throws Exception {
        LoginUser loginUser = SecurityUtils.getLoginUser();
 
        // 查询销售单号
        String salesContractNo = "";
        if (req.getSalesLedgerId() != null) {
            SalesLedger salesLedger = salesLedgerService.getById(req.getSalesLedgerId());
            if (salesLedger != null) {
                salesContractNo = salesLedger.getSalesContractNo();
            }
        }
 
        String sh = OrderUtils.countTodayByCreateTime(shippingInfoMapper, "SH", "shipping_no");
 
        // 查询该销售合同下是否有"待审核"的发货记录,用于合并审批(需审批人相同)
        boolean shouldMergeApproval = false;
        ApproveProcess existingApprove = null;
        List<ShippingInfo> pendingShippings = shippingInfoMapper.selectList(
            new LambdaQueryWrapper<ShippingInfo>()
                .eq(ShippingInfo::getSalesLedgerId, req.getSalesLedgerId())
                .eq(ShippingInfo::getStatus, "待审核")
        );
        if (!CollectionUtils.isEmpty(pendingShippings) && salesContractNo != null && !salesContractNo.isEmpty()) {
            // 找到对应的审批流程(通过销售单号匹配,且审批人相同)
            existingApprove = approveProcessService.getOne(
                new LambdaQueryWrapper<ApproveProcess>()
                    .like(ApproveProcess::getApproveReason, "销售单号:" + salesContractNo)
                    .eq(ApproveProcess::getApproveType, 7) // 发货审批类型
                    .eq(ApproveProcess::getApproveStatus, 0) // 待审核状态
                    .eq(ApproveProcess::getApproveUser, loginUser.getUserId()) // 审批人相同
                    .orderByDesc(ApproveProcess::getCreateTime)
                    .last("limit 1")
            );
            if (existingApprove != null) {
                shouldMergeApproval = true;
            }
        }
 
        // 生成当前发货信息的描述
        StringBuilder currentShippingDesc = new StringBuilder();
        currentShippingDesc.append("发货单号:").append(sh);
        if (salesContractNo != null && !salesContractNo.isEmpty()) {
            currentShippingDesc.append("\n销售单号:").append(salesContractNo);
        }
        currentShippingDesc.append("\n").append(req.getType());
        if ("货车".equals(req.getType()) && req.getShippingCarNumber() != null && !req.getShippingCarNumber().isEmpty()) {
            currentShippingDesc.append(":").append(req.getShippingCarNumber());
        } else if ("快递".equals(req.getType()) && req.getExpressCompany() != null && !req.getExpressCompany().isEmpty()) {
            currentShippingDesc.append(":").append(req.getExpressCompany());
        }
 
        if (shouldMergeApproval && existingApprove != null) {
            // 合并审批:将被合并的发货单号添加到审批原因中
            String updatedReason = existingApprove.getApproveReason() + "\n\n" + currentShippingDesc.toString();
            existingApprove.setApproveReason(updatedReason);
            approveProcessService.updateById(existingApprove);
        } else {
            // 创建新的审批流程
            ApproveProcessVO approveProcessVO = new ApproveProcessVO();
            approveProcessVO.setApproveType(7);
            approveProcessVO.setApproveDeptId(loginUser.getCurrentDeptId());
            approveProcessVO.setApproveReason(currentShippingDesc.toString());
            approveProcessVO.setApproveUserIds(req.getApproveUserIds());
            approveProcessVO.setApproveUser(loginUser.getUserId());
            approveProcessVO.setApproveTime(LocalDate.now().toString());
            approveProcessService.addApprove(approveProcessVO);
        }
 
        // 添加发货记录
        req.setShippingNo(sh);
        req.setStatus("待审核");
        boolean save = shippingInfoService.save(req);
        return save ? AjaxResult.success() : AjaxResult.error();
    }
 
    @ApiOperation("发货扣库存")
    @PostMapping("/deductStock")
    @Transactional(rollbackFor = Exception.class)
    @Log(title = "发货信息管理", businessType = BusinessType.UPDATE)
    public AjaxResult deductStock(@RequestBody ShippingInfoDto req) throws IOException {
        return shippingInfoService.deductStock( req) ? AjaxResult.success() : AjaxResult.error();
    }
 
    @PostMapping("/update")
    @ApiOperation("修改发货信息")
    @Transactional(rollbackFor = Exception.class)
    @Log(title = "发货信息管理", businessType = BusinessType.UPDATE)
    public AjaxResult update(@RequestBody ShippingInfo req) {
        ShippingInfo byId = shippingInfoService.getById(req.getId());
        if (byId == null) {
            return AjaxResult.error("发货信息不存在");
        }
        boolean update = shippingInfoService.updateById(req);
        return update ? AjaxResult.success() : AjaxResult.error();
    }
 
    @DeleteMapping("/delete")
    @ApiOperation("删除发货信息")
    @Transactional(rollbackFor = Exception.class)
    @Log(title = "发货信息管理", businessType = BusinessType.DELETE)
    public AjaxResult delete(@RequestBody List<Long> ids) {
 
        return shippingInfoService.delete(ids) ? AjaxResult.success("删除成功") : AjaxResult.error("删除失败");
    }
 
    @Autowired
    private ShippingInfoMapper shippingInfoMapper;
 
    /**
     * 导出发货信息管理
     */
    @PostMapping("/export")
    @ApiOperation("导出发货信息")
    public void export(HttpServletResponse response) {
        List<ShippingInfo> list = shippingInfoMapper.listAll();
        ExcelUtil<ShippingInfo> util = new ExcelUtil<ShippingInfo>(ShippingInfo.class);
        util.exportExcel(response, list, "发货信息");
    }
 
 
    @GetMapping("/getByCustomerName")
    @ApiOperation("通过客户名称查询")
    public AjaxResult getByCustomerName(String customerName) {
        return AjaxResult.success(shippingInfoService.getShippingInfoByCustomerName(customerName));
    }
 
    /**
     * 一键发货 - 自动审批通过并出库
     */
    @PostMapping("/oneClickShipping")
    @ApiOperation("一键发货")
    @Transactional(rollbackFor = Exception.class)
    @Log(title = "发货信息管理", businessType = BusinessType.INSERT)
    public AjaxResult oneClickShipping(@RequestBody ShippingInfoDto req) throws IOException {
        return shippingInfoService.oneClickShipping(req) ? AjaxResult.success("发货成功") : AjaxResult.error("发货失败");
    }
 
    /**
     * 批量一键发货 - 将销售台账下所有未发货的产品全部发货
     */
    @PostMapping("/batchOneClickShipping")
    @ApiOperation("批量一键发货")
    @Transactional(rollbackFor = Exception.class)
    @Log(title = "发货信息管理", businessType = BusinessType.INSERT)
    public AjaxResult batchOneClickShipping(@RequestBody ShippingInfoDto req) throws IOException {
        if (req.getSalesLedgerId() == null) {
            return AjaxResult.error("销售台账ID不能为空");
        }
        return shippingInfoService.batchOneClickShipping(req.getSalesLedgerId(), req) ? AjaxResult.success("批量发货成功") : AjaxResult.error("批量发货失败");
    }
}