|
|
@@ -0,0 +1,728 @@
|
|
|
+package com.ruoyi.web.base.controller;
|
|
|
+
|
|
|
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
|
|
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
|
|
+import com.ruoyi.common.core.domain.AjaxResult;
|
|
|
+import com.ruoyi.common.utils.StringUtils;
|
|
|
+import com.ruoyi.common.utils.poi.ExcelUtil;
|
|
|
+import com.ruoyi.framework.web.service.TokenService;
|
|
|
+import com.ruoyi.web.base.domain.BaseCustomer;
|
|
|
+import com.ruoyi.web.base.domain.BaseEmployee;
|
|
|
+import com.ruoyi.web.base.domain.BaseLine;
|
|
|
+import com.ruoyi.web.base.domain.BaseMaterial;
|
|
|
+import com.ruoyi.web.base.domain.BaseMarket;
|
|
|
+import com.ruoyi.web.base.domain.RelCustomerMarket;
|
|
|
+import com.ruoyi.web.base.domain.SalesPrice;
|
|
|
+import com.ruoyi.web.base.domain.SalesPriceItem;
|
|
|
+import com.ruoyi.web.base.domain.SalesOrder;
|
|
|
+import com.ruoyi.web.base.domain.SalesOrderGoods;
|
|
|
+import com.ruoyi.web.base.service.IBaseCustomerService;
|
|
|
+import com.ruoyi.web.base.service.IBaseEmployeeService;
|
|
|
+import com.ruoyi.web.base.service.IBaseLineService;
|
|
|
+import com.ruoyi.web.base.service.IBaseMaterialService;
|
|
|
+import com.ruoyi.web.base.service.IBaseMarketService;
|
|
|
+import com.ruoyi.web.base.service.IRelCustomerMarketService;
|
|
|
+import com.ruoyi.web.base.service.ISalesPriceService;
|
|
|
+import com.ruoyi.web.base.service.ISalesPriceItemService;
|
|
|
+import com.ruoyi.web.base.service.ISalesOrderGoodsService;
|
|
|
+import com.ruoyi.web.base.service.ISalesOrderService;
|
|
|
+import io.swagger.annotations.Api;
|
|
|
+import io.swagger.annotations.ApiOperation;
|
|
|
+import io.swagger.annotations.ApiParam;
|
|
|
+import org.springframework.beans.factory.annotation.Autowired;
|
|
|
+import org.springframework.transaction.annotation.Transactional;
|
|
|
+import org.springframework.web.bind.annotation.*;
|
|
|
+
|
|
|
+import javax.servlet.http.HttpServletRequest;
|
|
|
+import javax.servlet.http.HttpServletResponse;
|
|
|
+import java.math.BigDecimal;
|
|
|
+import java.util.ArrayList;
|
|
|
+import java.util.Collections;
|
|
|
+import java.util.Date;
|
|
|
+import java.util.HashMap;
|
|
|
+import java.util.LinkedHashMap;
|
|
|
+import java.util.LinkedHashSet;
|
|
|
+import java.util.List;
|
|
|
+import java.util.Map;
|
|
|
+import java.util.Set;
|
|
|
+import java.util.stream.Collectors;
|
|
|
+
|
|
|
+import static com.ruoyi.common.core.domain.AjaxResult.success;
|
|
|
+import static com.ruoyi.common.utils.SecurityUtils.getUsername;
|
|
|
+import static com.ruoyi.web.base.util.NumUtils.generateString;
|
|
|
+import static com.ruoyi.web.base.util.NumUtils.substringToInt;
|
|
|
+
|
|
|
+@RestController
|
|
|
+@Api(tags = "销售订单")
|
|
|
+@RequestMapping("/sales-order")
|
|
|
+public class SalesOrderController {
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private ISalesOrderService salesOrderService;
|
|
|
+ @Autowired
|
|
|
+ private ISalesOrderGoodsService salesOrderGoodsService;
|
|
|
+ @Autowired
|
|
|
+ private IBaseCustomerService customerService;
|
|
|
+ @Autowired
|
|
|
+ private IRelCustomerMarketService relCustomerMarketService;
|
|
|
+ @Autowired
|
|
|
+ private IBaseMaterialService baseMaterialService;
|
|
|
+ @Autowired
|
|
|
+ private IBaseEmployeeService baseEmployeeService;
|
|
|
+ @Autowired
|
|
|
+ private IBaseLineService baseLineService;
|
|
|
+ @Autowired
|
|
|
+ private IBaseMarketService baseMarketService;
|
|
|
+ @Autowired
|
|
|
+ private ISalesPriceService salesPriceService;
|
|
|
+ @Autowired
|
|
|
+ private ISalesPriceItemService salesPriceItemService;
|
|
|
+ @Autowired
|
|
|
+ private TokenService tokenService;
|
|
|
+
|
|
|
+ @ApiOperation("销售订单新增")
|
|
|
+ @PostMapping("/add")
|
|
|
+ @Transactional
|
|
|
+ public AjaxResult add(@RequestBody SalesOrder order, HttpServletRequest request) throws Exception {
|
|
|
+ String orgId = tokenService.getLoginOrgId(request);
|
|
|
+ validateBeforeSave(order, orgId, true);
|
|
|
+ fillCustomerAndMarketInfo(order, orgId);
|
|
|
+ recalcGoodsSubTotalsAndOrderTotal(order);
|
|
|
+ order.setOrgId(orgId);
|
|
|
+ order.setDelFlag("0");
|
|
|
+ order.setAuditStatus(1);
|
|
|
+ String username = getUsername();
|
|
|
+ order.setId(null);
|
|
|
+ order.setCreateBy(username);
|
|
|
+ order.setCreateTime(new Date());
|
|
|
+ order.setUpdateBy(null);
|
|
|
+ order.setUpdateTime(null);
|
|
|
+ salesOrderService.save(order);
|
|
|
+ saveGoods(order, orgId, username);
|
|
|
+ return success();
|
|
|
+ }
|
|
|
+
|
|
|
+ @ApiOperation("销售订单修改")
|
|
|
+ @PostMapping("/edit")
|
|
|
+ @Transactional
|
|
|
+ public AjaxResult edit(@RequestBody SalesOrder order, HttpServletRequest request) throws Exception {
|
|
|
+ if (order.getId() == null) {
|
|
|
+ throw new Exception("id不能为空");
|
|
|
+ }
|
|
|
+ SalesOrder old = salesOrderService.getById(order.getId());
|
|
|
+ if (old == null || !"0".equals(old.getDelFlag())) {
|
|
|
+ throw new Exception("销售订单不存在");
|
|
|
+ }
|
|
|
+ if (old.getAuditStatus() != null && old.getAuditStatus() == 1) {
|
|
|
+ throw new Exception("已审核的销售订单不能修改,请先反审核");
|
|
|
+ }
|
|
|
+ String orgId = tokenService.getLoginOrgId(request);
|
|
|
+ validateBeforeSave(order, orgId, false);
|
|
|
+ fillCustomerAndMarketInfo(order, orgId);
|
|
|
+ recalcGoodsSubTotalsAndOrderTotal(order);
|
|
|
+ order.setOrgId(orgId);
|
|
|
+ order.setAuditStatus(1);
|
|
|
+ String username = getUsername();
|
|
|
+ order.setCreateBy(old.getCreateBy());
|
|
|
+ order.setCreateTime(old.getCreateTime());
|
|
|
+ order.setUpdateBy(username);
|
|
|
+ order.setUpdateTime(new Date());
|
|
|
+ salesOrderService.updateById(order);
|
|
|
+ /** 修改保存:先按原单据编号物理删除旧物料清单,再插入本次提交的明细 */
|
|
|
+ String oldOrderNum = StringUtils.isNotBlank(old.getOrderNum()) ? old.getOrderNum().trim() : null;
|
|
|
+ deleteSalesOrderGoodsByOrderNum(orgId, oldOrderNum);
|
|
|
+ saveGoods(order, orgId, username);
|
|
|
+ return success();
|
|
|
+ }
|
|
|
+
|
|
|
+ @ApiOperation("销售订单删除")
|
|
|
+ @PostMapping("/delete")
|
|
|
+ public AjaxResult delete(@RequestBody Map<String, String> params) throws Exception {
|
|
|
+ String ids = params.get("ids");
|
|
|
+ for (String id : ids.split(",")) {
|
|
|
+ SalesOrder order = salesOrderService.getById(id);
|
|
|
+ if (order == null || !"0".equals(order.getDelFlag())) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ if (order.getAuditStatus() != null && order.getAuditStatus() == 1) {
|
|
|
+ throw new Exception("已审核的销售订单不能删除,请先反审核");
|
|
|
+ }
|
|
|
+ // 同步删除子表明细
|
|
|
+ String orgId = order.getOrgId();
|
|
|
+ String orderNum = order.getOrderNum();
|
|
|
+ deleteSalesOrderGoodsByOrderNum(orgId, orderNum);
|
|
|
+
|
|
|
+ SalesOrder up = new SalesOrder();
|
|
|
+ up.setId(Integer.valueOf(id));
|
|
|
+ up.setDelFlag("2");
|
|
|
+ up.setUpdateBy(getUsername());
|
|
|
+ up.setUpdateTime(new Date());
|
|
|
+ salesOrderService.updateById(up);
|
|
|
+ }
|
|
|
+ return success();
|
|
|
+ }
|
|
|
+
|
|
|
+ @ApiOperation("销售订单详情")
|
|
|
+ @PostMapping("/listById")
|
|
|
+ public AjaxResult listById(@ApiParam("详情参数: id") @RequestBody Map<String, String> params, HttpServletRequest request) {
|
|
|
+ String id = params.get("id");
|
|
|
+ SalesOrder order = salesOrderService.getById(id);
|
|
|
+ if (order == null) {
|
|
|
+ return success(null);
|
|
|
+ }
|
|
|
+ String orgId = tokenService.getLoginOrgId(request);
|
|
|
+ List<SalesOrderGoods> goods = salesOrderGoodsService.list(new QueryWrapper<SalesOrderGoods>()
|
|
|
+ .eq("org_id", orgId)
|
|
|
+ .eq("order_num", order.getOrderNum())
|
|
|
+ .eq("del_flag", "0"));
|
|
|
+ enrichGoodsFromMaterial(goods, orgId);
|
|
|
+ order.setGoods(goods);
|
|
|
+ enrichSalesOrderDisplay(order, orgId);
|
|
|
+ return success(order);
|
|
|
+ }
|
|
|
+
|
|
|
+ @ApiOperation("销售订单分页")
|
|
|
+ @GetMapping("/page")
|
|
|
+ public AjaxResult page(@RequestParam("pageNum") Integer pageNum,
|
|
|
+ @RequestParam("pageSize") Integer pageSize,
|
|
|
+ SalesOrder query,
|
|
|
+ HttpServletRequest request) {
|
|
|
+ String orgId = tokenService.getLoginOrgId(request);
|
|
|
+ QueryWrapper<SalesOrder> wrapper = buildWrapper(query, orgId);
|
|
|
+ Page<SalesOrder> page = salesOrderService.page(new Page<SalesOrder>(pageNum, pageSize), wrapper);
|
|
|
+ for (SalesOrder row : page.getRecords()) {
|
|
|
+ enrichSalesOrderDisplay(row, orgId);
|
|
|
+ }
|
|
|
+ return success(page);
|
|
|
+ }
|
|
|
+
|
|
|
+ @ApiOperation("销售订单列表")
|
|
|
+ @PostMapping("/list")
|
|
|
+ public AjaxResult list(@RequestBody SalesOrder query, HttpServletRequest request) {
|
|
|
+ String orgId = tokenService.getLoginOrgId(request);
|
|
|
+ List<SalesOrder> list = salesOrderService.list(buildWrapper(query, orgId));
|
|
|
+ for (SalesOrder row : list) {
|
|
|
+ enrichSalesOrderDisplay(row, orgId);
|
|
|
+ }
|
|
|
+ return success(list);
|
|
|
+ }
|
|
|
+
|
|
|
+ @ApiOperation("销售订单导出")
|
|
|
+ @PostMapping("/export")
|
|
|
+ public void export(HttpServletResponse response, SalesOrder query, HttpServletRequest request) {
|
|
|
+ String orgId = tokenService.getLoginOrgId(request);
|
|
|
+ List<SalesOrder> list = salesOrderService.list(buildWrapper(query, orgId));
|
|
|
+ for (SalesOrder row : list) {
|
|
|
+ enrichSalesOrderDisplay(row, orgId);
|
|
|
+ }
|
|
|
+ ExcelUtil<SalesOrder> util = new ExcelUtil<SalesOrder>(SalesOrder.class);
|
|
|
+ util.exportExcel(response, list, "销售订单");
|
|
|
+ }
|
|
|
+
|
|
|
+ @ApiOperation("销售订单审核")
|
|
|
+ @PostMapping("/audit")
|
|
|
+ public AjaxResult audit(@RequestBody Map<String, String> params) throws Exception {
|
|
|
+ String id = params.get("id");
|
|
|
+ SalesOrder order = getActiveById(id);
|
|
|
+ order.setAuditStatus(1);
|
|
|
+ order.setUpdateBy(getUsername());
|
|
|
+ order.setUpdateTime(new Date());
|
|
|
+ return success(salesOrderService.updateById(order));
|
|
|
+ }
|
|
|
+
|
|
|
+ @ApiOperation("销售订单反审核")
|
|
|
+ @PostMapping("/unaudit")
|
|
|
+ public AjaxResult unaudit(@RequestBody Map<String, String> params) throws Exception {
|
|
|
+ String id = params.get("id");
|
|
|
+ SalesOrder order = getActiveById(id);
|
|
|
+ order.setAuditStatus(0);
|
|
|
+ order.setUpdateBy(getUsername());
|
|
|
+ order.setUpdateTime(new Date());
|
|
|
+ return success(salesOrderService.updateById(order));
|
|
|
+ }
|
|
|
+
|
|
|
+ @ApiOperation("销售订单打印数据")
|
|
|
+ @PostMapping("/print")
|
|
|
+ public AjaxResult print(@RequestBody Map<String, String> params, HttpServletRequest request) throws Exception {
|
|
|
+ String id = params.get("id");
|
|
|
+ SalesOrder order = getActiveById(id);
|
|
|
+ String orgId = tokenService.getLoginOrgId(request);
|
|
|
+ List<SalesOrderGoods> goods = salesOrderGoodsService.list(new QueryWrapper<SalesOrderGoods>()
|
|
|
+ .eq("org_id", orgId)
|
|
|
+ .eq("order_num", order.getOrderNum())
|
|
|
+ .eq("del_flag", "0"));
|
|
|
+ enrichGoodsFromMaterial(goods, orgId);
|
|
|
+ order.setGoods(goods);
|
|
|
+ enrichSalesOrderDisplay(order, orgId);
|
|
|
+ return success(order);
|
|
|
+ }
|
|
|
+
|
|
|
+ @ApiOperation("获取最新销售订单编号")
|
|
|
+ @PostMapping("/getOrderNum")
|
|
|
+ public AjaxResult getOrderNum(HttpServletRequest request) throws Exception {
|
|
|
+ String orgId = tokenService.getLoginOrgId(request);
|
|
|
+ SalesOrder one = salesOrderService.getOne(new QueryWrapper<SalesOrder>()
|
|
|
+ .eq("org_id", orgId)
|
|
|
+ .eq("del_flag", "0")
|
|
|
+ .orderByDesc("id")
|
|
|
+ .last("limit 1"));
|
|
|
+ if (one == null || StringUtils.isBlank(one.getOrderNum())) {
|
|
|
+ return success(generateString("xs", 1));
|
|
|
+ }
|
|
|
+ return success(generateString("xs", substringToInt(one.getOrderNum())));
|
|
|
+ }
|
|
|
+
|
|
|
+ @ApiOperation("按货品编号、客户编号、单据日期查询物料及价格")
|
|
|
+ @PostMapping("/getGoodsPriceInfo")
|
|
|
+ public AjaxResult getGoodsPriceInfo(@RequestBody Map<String, String> params, HttpServletRequest request) throws Exception {
|
|
|
+ String goodsNum = params.get("goodsNum");
|
|
|
+ String customerNum = params.get("customerNum");
|
|
|
+ String documentDate = params.get("documentDate");
|
|
|
+ if (StringUtils.isAnyBlank(goodsNum, customerNum, documentDate)) {
|
|
|
+ throw new Exception("货品编号、客户编号、单据日期不能为空");
|
|
|
+ }
|
|
|
+ String orgId = tokenService.getLoginOrgId(request);
|
|
|
+ String safeDate = documentDate.trim().replace("'", "''");
|
|
|
+
|
|
|
+ BaseMaterial material = baseMaterialService.getOne(new QueryWrapper<BaseMaterial>()
|
|
|
+ .eq("org_id", orgId)
|
|
|
+ .eq("goods_num", goodsNum.trim())
|
|
|
+ .eq("del_flag", "0")
|
|
|
+ .last("limit 1"));
|
|
|
+ if (material == null) {
|
|
|
+ throw new Exception("未找到该货品编号对应物料");
|
|
|
+ }
|
|
|
+
|
|
|
+ RelCustomerMarket rel = relCustomerMarketService.getOne(new QueryWrapper<RelCustomerMarket>()
|
|
|
+ .eq("org_id", orgId)
|
|
|
+ .eq("customer_num", customerNum.trim())
|
|
|
+ .eq("del_flag", "0")
|
|
|
+ .orderByDesc("id")
|
|
|
+ .last("limit 1"));
|
|
|
+ if (rel == null || StringUtils.isBlank(rel.getMarketNum())) {
|
|
|
+ throw new Exception("该客户未维护市场信息");
|
|
|
+ }
|
|
|
+
|
|
|
+ BaseMarket market = baseMarketService.getOne(new QueryWrapper<BaseMarket>()
|
|
|
+ .eq("org_id", orgId)
|
|
|
+ .eq("market_num", rel.getMarketNum())
|
|
|
+ .eq("del_flag", "0")
|
|
|
+ .last("limit 1"));
|
|
|
+ if (market == null || StringUtils.isBlank(market.getPriceType())) {
|
|
|
+ throw new Exception("该市场未维护价格类型");
|
|
|
+ }
|
|
|
+
|
|
|
+ String priceType = market.getPriceType().trim();
|
|
|
+ SalesPrice price = salesPriceService.getOne(new QueryWrapper<SalesPrice>()
|
|
|
+ .eq("org_id", orgId)
|
|
|
+ .eq("del_flag", "0")
|
|
|
+ .eq("price_type", priceType)
|
|
|
+ .eq("effective_date", safeDate)
|
|
|
+ .orderByDesc("id")
|
|
|
+ .last("limit 1"), false);
|
|
|
+ SalesPriceItem priceItem = null;
|
|
|
+ if (price != null && StringUtils.isNotBlank(price.getPriceNum())) {
|
|
|
+ priceItem = salesPriceItemService.getOne(new QueryWrapper<SalesPriceItem>()
|
|
|
+ .eq("org_id", orgId)
|
|
|
+ .eq("price_num", price.getPriceNum())
|
|
|
+ .eq("material_num", goodsNum.trim())
|
|
|
+ .eq("del_flag", "0")
|
|
|
+ .orderByDesc("id")
|
|
|
+ .last("limit 1"), false);
|
|
|
+ }
|
|
|
+
|
|
|
+ Map<String, Object> data = new HashMap<String, Object>();
|
|
|
+ data.put("goodsNum", material.getGoodsNum());
|
|
|
+ data.put("goodsName", material.getGoodsName());
|
|
|
+ data.put("goodsSpec", material.getGoodsSpec());
|
|
|
+ data.put("baseUnit", material.getUnit());
|
|
|
+ data.put("assUnit", material.getAssistantUnit());
|
|
|
+ data.put("customerNum", customerNum.trim());
|
|
|
+ data.put("marketNum", rel.getMarketNum());
|
|
|
+ data.put("priceType", priceType);
|
|
|
+ data.put("documentDate", safeDate);
|
|
|
+ data.put("priceNum", priceItem == null ? null : priceItem.getPriceNum());
|
|
|
+ data.put("unitPrice", priceItem == null || priceItem.getUnitPrice() == null ? BigDecimal.ZERO : priceItem.getUnitPrice());
|
|
|
+ data.put("pickupPrice", priceItem == null ? null : priceItem.getPickupPrice());
|
|
|
+ return success(data);
|
|
|
+ }
|
|
|
+
|
|
|
+ @ApiOperation("物流线-市场-客户三级树(el-tree)")
|
|
|
+ @GetMapping("/lineMarketCustomer")
|
|
|
+ public AjaxResult lineMarketCustomerTree(HttpServletRequest request) {
|
|
|
+ String orgId = tokenService.getLoginOrgId(request);
|
|
|
+ QueryWrapper<BaseLine> lineQw = new QueryWrapper<BaseLine>()
|
|
|
+ .eq("org_id", orgId)
|
|
|
+ .and(w -> w.eq("del_flag", "0").or().isNull("del_flag"))
|
|
|
+ .orderByAsc("line_num")
|
|
|
+ .orderByAsc("id");
|
|
|
+ List<BaseLine> lines = baseLineService.list(lineQw);
|
|
|
+
|
|
|
+ QueryWrapper<BaseMarket> marketQw = new QueryWrapper<BaseMarket>()
|
|
|
+ .eq("org_id", orgId)
|
|
|
+ .and(w -> w.eq("del_flag", "0").or().isNull("del_flag"))
|
|
|
+ .orderByAsc("market_num")
|
|
|
+ .orderByAsc("id");
|
|
|
+ List<BaseMarket> allMarkets = baseMarketService.list(marketQw);
|
|
|
+ Map<String, List<BaseMarket>> marketsByLineNum = allMarkets.stream()
|
|
|
+ .filter(m -> StringUtils.isNotBlank(m.getLineNum()))
|
|
|
+ .collect(Collectors.groupingBy(m -> m.getLineNum().trim(), LinkedHashMap::new, Collectors.toList()));
|
|
|
+
|
|
|
+ QueryWrapper<RelCustomerMarket> relQw = new QueryWrapper<RelCustomerMarket>()
|
|
|
+ .eq("org_id", orgId)
|
|
|
+ .and(w -> w.eq("del_flag", "0").or().isNull("del_flag"))
|
|
|
+ .orderByDesc("id");
|
|
|
+ List<RelCustomerMarket> allRels = relCustomerMarketService.list(relQw);
|
|
|
+
|
|
|
+ List<BaseCustomer> customers = customerService.list(new QueryWrapper<BaseCustomer>()
|
|
|
+ .eq("org_id", orgId)
|
|
|
+ .and(w -> w.eq("del_flag", "0").or().isNull("del_flag")));
|
|
|
+ Map<String, String> customerNameMap = customers.stream()
|
|
|
+ .filter(c -> StringUtils.isNotBlank(c.getCustomerNum()))
|
|
|
+ .collect(Collectors.toMap(BaseCustomer::getCustomerNum,
|
|
|
+ c -> c.getCustomerName() != null ? c.getCustomerName() : "",
|
|
|
+ (a, b) -> a, LinkedHashMap::new));
|
|
|
+
|
|
|
+ Map<String, List<RelCustomerMarket>> relsByLineAndMarket = new LinkedHashMap<String, List<RelCustomerMarket>>();
|
|
|
+ for (RelCustomerMarket r : allRels) {
|
|
|
+ if (StringUtils.isBlank(r.getLineNum()) || StringUtils.isBlank(r.getMarketNum())) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ String key = r.getLineNum().trim() + "\0" + r.getMarketNum().trim();
|
|
|
+ relsByLineAndMarket.computeIfAbsent(key, k -> new ArrayList<RelCustomerMarket>()).add(r);
|
|
|
+ }
|
|
|
+
|
|
|
+ List<Map<String, Object>> tree = new ArrayList<Map<String, Object>>();
|
|
|
+ for (BaseLine line : lines) {
|
|
|
+ String lineNum = line.getLineNum() == null ? "" : line.getLineNum().trim();
|
|
|
+ Map<String, Object> lineNode = new LinkedHashMap<String, Object>();
|
|
|
+ lineNode.put("id", "line:" + lineNum + ":" + line.getId());
|
|
|
+ lineNode.put("label", StringUtils.isNotBlank(line.getLineName()) ? line.getLineName() : lineNum);
|
|
|
+ lineNode.put("type", "line");
|
|
|
+ lineNode.put("lineNum", lineNum);
|
|
|
+ lineNode.put("lineName", line.getLineName());
|
|
|
+
|
|
|
+ List<Map<String, Object>> marketChildren = new ArrayList<Map<String, Object>>();
|
|
|
+ List<BaseMarket> markets = marketsByLineNum.getOrDefault(lineNum, new ArrayList<BaseMarket>());
|
|
|
+ for (BaseMarket market : markets) {
|
|
|
+ String marketNum = market.getMarketNum() == null ? "" : market.getMarketNum().trim();
|
|
|
+ Map<String, Object> marketNode = new LinkedHashMap<String, Object>();
|
|
|
+ marketNode.put("id", "market:" + lineNum + ":" + marketNum + ":" + market.getId());
|
|
|
+ marketNode.put("label", StringUtils.isNotBlank(market.getMarketName()) ? market.getMarketName() : marketNum);
|
|
|
+ marketNode.put("type", "market");
|
|
|
+ marketNode.put("lineNum", lineNum);
|
|
|
+ marketNode.put("marketNum", marketNum);
|
|
|
+ marketNode.put("marketName", market.getMarketName());
|
|
|
+
|
|
|
+ String relKey = lineNum + "\0" + marketNum;
|
|
|
+ List<RelCustomerMarket> rels = relsByLineAndMarket.getOrDefault(relKey, new ArrayList<RelCustomerMarket>());
|
|
|
+ Set<String> seenCustomer = new LinkedHashSet<String>();
|
|
|
+ List<Map<String, Object>> customerChildren = new ArrayList<Map<String, Object>>();
|
|
|
+ for (RelCustomerMarket rel : rels) {
|
|
|
+ String customerNum = rel.getCustomerNum() == null ? "" : rel.getCustomerNum().trim();
|
|
|
+ if (StringUtils.isBlank(customerNum) || !seenCustomer.add(customerNum)) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ String customerName = StringUtils.isNotBlank(rel.getCustomerName())
|
|
|
+ ? rel.getCustomerName()
|
|
|
+ : customerNameMap.getOrDefault(customerNum, customerNum);
|
|
|
+ Map<String, Object> custNode = new LinkedHashMap<String, Object>();
|
|
|
+ custNode.put("id", "customer:" + lineNum + ":" + marketNum + ":" + customerNum + ":" + rel.getId());
|
|
|
+ custNode.put("label", customerName);
|
|
|
+ custNode.put("type", "customer");
|
|
|
+ custNode.put("lineNum", lineNum);
|
|
|
+ custNode.put("marketNum", marketNum);
|
|
|
+ custNode.put("customerNum", customerNum);
|
|
|
+ custNode.put("customerName", customerName);
|
|
|
+ custNode.put("relId", rel.getId());
|
|
|
+ custNode.put("leaf", true);
|
|
|
+ customerChildren.add(custNode);
|
|
|
+ }
|
|
|
+ marketNode.put("children", customerChildren);
|
|
|
+ marketChildren.add(marketNode);
|
|
|
+ }
|
|
|
+ lineNode.put("children", marketChildren);
|
|
|
+ tree.add(lineNode);
|
|
|
+ }
|
|
|
+ return success(tree);
|
|
|
+ }
|
|
|
+
|
|
|
+ private QueryWrapper<SalesOrder> buildWrapper(SalesOrder query, String orgId) {
|
|
|
+ QueryWrapper<SalesOrder> wrapper = new QueryWrapper<SalesOrder>()
|
|
|
+ .eq("org_id", orgId)
|
|
|
+ .eq("del_flag", "0");
|
|
|
+ if (query == null) {
|
|
|
+ return wrapper;
|
|
|
+ }
|
|
|
+ if (query.getDocumentDateStart() != null) {
|
|
|
+ wrapper.ge("document_date", query.getDocumentDateStart());
|
|
|
+ }
|
|
|
+ if (query.getDocumentDateEnd() != null) {
|
|
|
+ wrapper.le("document_date", query.getDocumentDateEnd());
|
|
|
+ }
|
|
|
+ if (query.getSaleDateStart() != null) {
|
|
|
+ wrapper.ge("sale_date", query.getSaleDateStart());
|
|
|
+ }
|
|
|
+ if (query.getSaleDateEnd() != null) {
|
|
|
+ wrapper.le("sale_date", query.getSaleDateEnd());
|
|
|
+ }
|
|
|
+ if (StringUtils.isNotBlank(query.getCustomerName())) {
|
|
|
+ wrapper.like("customer_name", query.getCustomerName());
|
|
|
+ }
|
|
|
+ if (StringUtils.isNotBlank(query.getEmployeeNum())) {
|
|
|
+ wrapper.like("employee_num", query.getEmployeeNum());
|
|
|
+ }
|
|
|
+ if (StringUtils.isNotBlank(query.getLineNum())) {
|
|
|
+ wrapper.like("line_num", query.getLineNum());
|
|
|
+ }
|
|
|
+ if (StringUtils.isNotBlank(query.getMarketNum())) {
|
|
|
+ wrapper.like("market_num", query.getMarketNum());
|
|
|
+ }
|
|
|
+ if (query.getAuditStatus() != null) {
|
|
|
+ wrapper.eq("audit_status", query.getAuditStatus());
|
|
|
+ }
|
|
|
+ wrapper.orderByDesc("id");
|
|
|
+ return wrapper;
|
|
|
+ }
|
|
|
+
|
|
|
+ private void validateBeforeSave(SalesOrder order, String orgId, boolean isAdd) throws Exception {
|
|
|
+ if (order == null) {
|
|
|
+ throw new Exception("参数不能为空");
|
|
|
+ }
|
|
|
+ if (order.getCustomerNum() != null) {
|
|
|
+ order.setCustomerNum(order.getCustomerNum().trim());
|
|
|
+ }
|
|
|
+ if (order.getOrderNum() != null) {
|
|
|
+ order.setOrderNum(order.getOrderNum().trim());
|
|
|
+ }
|
|
|
+ if (StringUtils.isAnyBlank(order.getOrderNum(), order.getCustomerNum())) {
|
|
|
+ throw new Exception("单据编号、客户编号不能为空");
|
|
|
+ }
|
|
|
+ QueryWrapper<SalesOrder> numWrapper = new QueryWrapper<SalesOrder>()
|
|
|
+ .eq("order_num", order.getOrderNum())
|
|
|
+ .eq("del_flag", "0");
|
|
|
+ if (!isAdd && order.getId() != null) {
|
|
|
+ numWrapper.ne("id", order.getId());
|
|
|
+ }
|
|
|
+ if (salesOrderService.count(numWrapper) > 0) {
|
|
|
+ throw new Exception("该单据编号已存在");
|
|
|
+ }
|
|
|
+ if (order.getGoods() == null || order.getGoods().isEmpty()) {
|
|
|
+ throw new Exception("货品清单不能为空");
|
|
|
+ }
|
|
|
+ BaseCustomer customer = customerService.getOne(new QueryWrapper<BaseCustomer>()
|
|
|
+ .eq("org_id", orgId)
|
|
|
+ .eq("customer_num", order.getCustomerNum())
|
|
|
+ .eq("del_flag", "0")
|
|
|
+ .last("limit 1"));
|
|
|
+ if (customer == null) {
|
|
|
+ throw new Exception("客户编号不存在");
|
|
|
+ }
|
|
|
+ if (StringUtils.isNotBlank(order.getEmployeeNum())) {
|
|
|
+ BaseEmployee emp = baseEmployeeService.getOne(new QueryWrapper<BaseEmployee>()
|
|
|
+ .eq("org_id", orgId)
|
|
|
+ .eq("employee_num", order.getEmployeeNum().trim())
|
|
|
+ .eq("del_flag", "0")
|
|
|
+ .last("limit 1"));
|
|
|
+ if (emp == null) {
|
|
|
+ throw new Exception("业务员编号不存在");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private void fillCustomerAndMarketInfo(SalesOrder order, String orgId) throws Exception {
|
|
|
+ BaseCustomer customer = customerService.getOne(new QueryWrapper<BaseCustomer>()
|
|
|
+ .eq("org_id", orgId)
|
|
|
+ .eq("customer_num", order.getCustomerNum())
|
|
|
+ .eq("del_flag", "0")
|
|
|
+ .last("limit 1"));
|
|
|
+ if (customer == null) {
|
|
|
+ throw new Exception("客户编号不存在");
|
|
|
+ }
|
|
|
+ order.setCustomerName(customer.getCustomerName());
|
|
|
+
|
|
|
+ /** 仅按客户编号解析市场、物流线(取客户市场维护表中最新一条),不依赖前端传入 */
|
|
|
+ RelCustomerMarket rel = relCustomerMarketService.getOne(new QueryWrapper<RelCustomerMarket>()
|
|
|
+ .eq("org_id", orgId)
|
|
|
+ .eq("customer_num", order.getCustomerNum())
|
|
|
+ .eq("del_flag", "0")
|
|
|
+ .orderByDesc("id")
|
|
|
+ .last("limit 1"));
|
|
|
+ if (rel != null) {
|
|
|
+ order.setMarketNum(rel.getMarketNum());
|
|
|
+ order.setLineNum(rel.getLineNum());
|
|
|
+ } else {
|
|
|
+ order.setMarketNum(null);
|
|
|
+ order.setLineNum(null);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private void enrichSalesOrderDisplay(SalesOrder order, String orgId) {
|
|
|
+ if (order == null) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ order.setReceivableCustomer(null);
|
|
|
+ order.setEmployeeName(null);
|
|
|
+ if (StringUtils.isNotBlank(order.getCustomerNum())) {
|
|
|
+ BaseCustomer c = customerService.getOne(new QueryWrapper<BaseCustomer>()
|
|
|
+ .eq("org_id", orgId)
|
|
|
+ .eq("customer_num", order.getCustomerNum())
|
|
|
+ .eq("del_flag", "0")
|
|
|
+ .last("limit 1"));
|
|
|
+ if (c != null) {
|
|
|
+ order.setReceivableCustomer(c.getReceivableCustomer());
|
|
|
+ if (StringUtils.isBlank(order.getCustomerName())) {
|
|
|
+ order.setCustomerName(c.getCustomerName());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (StringUtils.isNotBlank(order.getEmployeeNum())) {
|
|
|
+ BaseEmployee e = baseEmployeeService.getOne(new QueryWrapper<BaseEmployee>()
|
|
|
+ .eq("org_id", orgId)
|
|
|
+ .eq("employee_num", order.getEmployeeNum().trim())
|
|
|
+ .eq("del_flag", "0")
|
|
|
+ .last("limit 1"));
|
|
|
+ if (e != null) {
|
|
|
+ order.setEmployeeName(e.getEmployeeName());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private void enrichGoodsFromMaterial(List<SalesOrderGoods> goods, String orgId) {
|
|
|
+ if (goods == null || goods.isEmpty()) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ for (SalesOrderGoods g : goods) {
|
|
|
+ if (StringUtils.isBlank(g.getGoodsNum())) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ BaseMaterial m = baseMaterialService.getOne(new QueryWrapper<BaseMaterial>()
|
|
|
+ .eq("org_id", orgId)
|
|
|
+ .eq("goods_num", g.getGoodsNum())
|
|
|
+ .eq("del_flag", "0")
|
|
|
+ .last("limit 1"));
|
|
|
+ if (m == null) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ if (StringUtils.isBlank(g.getGoodsName())) {
|
|
|
+ g.setGoodsName(m.getGoodsName());
|
|
|
+ }
|
|
|
+ if (StringUtils.isBlank(g.getGoodsSpec())) {
|
|
|
+ g.setGoodsSpec(m.getGoodsSpec());
|
|
|
+ }
|
|
|
+ if (StringUtils.isBlank(g.getBaseUnit())) {
|
|
|
+ g.setBaseUnit(m.getUnit());
|
|
|
+ }
|
|
|
+ if (StringUtils.isBlank(g.getAssUnit())) {
|
|
|
+ g.setAssUnit(m.getAssistantUnit());
|
|
|
+ }
|
|
|
+ if (StringUtils.isBlank(g.getConversionValue())) {
|
|
|
+ g.setConversionValue(m.getConversionValue());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /** 小计=单价×基本计量数量;总计金额=各明细小计之和 */
|
|
|
+ private void recalcGoodsSubTotalsAndOrderTotal(SalesOrder order) {
|
|
|
+ List<SalesOrderGoods> goods = order.getGoods();
|
|
|
+ if (goods == null || goods.isEmpty()) {
|
|
|
+ order.setTotalAmount(null);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ BigDecimal sum = BigDecimal.ZERO;
|
|
|
+ boolean any = false;
|
|
|
+ for (SalesOrderGoods g : goods) {
|
|
|
+ BigDecimal line = null;
|
|
|
+
|
|
|
+ // 优先按 unitPrice * baseNum 计算
|
|
|
+ BigDecimal p = parseMoney(g.getUnitPrice());
|
|
|
+ BigDecimal q = parseMoney(g.getBaseNum());
|
|
|
+ if (p != null && q != null) {
|
|
|
+ line = p.multiply(q);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (line != null) {
|
|
|
+ g.setSubTotal(formatMoney(line));
|
|
|
+ sum = sum.add(line);
|
|
|
+ any = true;
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ // unitPrice 缺失时:不要清空,直接沿用已存在的小计 sub_total
|
|
|
+ BigDecimal existing = parseMoney(g.getSubTotal());
|
|
|
+ if (existing != null) {
|
|
|
+ g.setSubTotal(formatMoney(existing));
|
|
|
+ sum = sum.add(existing);
|
|
|
+ any = true;
|
|
|
+ } else {
|
|
|
+ g.setSubTotal(null);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (any) {
|
|
|
+ order.setTotalAmount(formatMoney(sum));
|
|
|
+ } else {
|
|
|
+ order.setTotalAmount(null);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private BigDecimal parseMoney(String s) {
|
|
|
+ if (StringUtils.isBlank(s)) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ try {
|
|
|
+ return new BigDecimal(s.trim().replace(",", ""));
|
|
|
+ } catch (Exception e) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private String formatMoney(BigDecimal n) {
|
|
|
+ if (n == null) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ return n.stripTrailingZeros().toPlainString();
|
|
|
+ }
|
|
|
+
|
|
|
+ /** 按单据编号将原明细逻辑删除(修改订单时先标记旧清单 del_flag=2) */
|
|
|
+ private void deleteSalesOrderGoodsByOrderNum(String orgId, String orderNum) {
|
|
|
+ if (StringUtils.isBlank(orgId) || StringUtils.isBlank(orderNum)) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ SalesOrderGoods up = new SalesOrderGoods();
|
|
|
+ up.setDelFlag("2");
|
|
|
+ up.setUpdateBy(getUsername());
|
|
|
+ up.setUpdateTime(new Date());
|
|
|
+ salesOrderGoodsService.update(up, new QueryWrapper<SalesOrderGoods>()
|
|
|
+ .eq("org_id", orgId)
|
|
|
+ .eq("order_num", orderNum)
|
|
|
+ .eq("del_flag", "0"));
|
|
|
+ }
|
|
|
+
|
|
|
+ private void saveGoods(SalesOrder order, String orgId, String username) {
|
|
|
+ List<SalesOrderGoods> goods = order.getGoods();
|
|
|
+ if (goods == null) {
|
|
|
+ goods = Collections.emptyList();
|
|
|
+ }
|
|
|
+ Date now = new Date();
|
|
|
+ for (SalesOrderGoods g : goods) {
|
|
|
+ g.setId(null);
|
|
|
+ g.setOrgId(orgId);
|
|
|
+ g.setOrderNum(order.getOrderNum());
|
|
|
+ g.setDelFlag("0");
|
|
|
+ g.setCreateBy(username);
|
|
|
+ g.setCreateTime(now);
|
|
|
+ g.setUpdateBy(null);
|
|
|
+ g.setUpdateTime(null);
|
|
|
+ salesOrderGoodsService.save(g);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private SalesOrder getActiveById(String id) throws Exception {
|
|
|
+ SalesOrder order = salesOrderService.getById(id);
|
|
|
+ if (order == null || !"0".equals(order.getDelFlag())) {
|
|
|
+ throw new Exception("销售订单不存在");
|
|
|
+ }
|
|
|
+ return order;
|
|
|
+ }
|
|
|
+}
|