Commit d6bdf26ad35175c0958d8b6eefcb11bb3bd2bb07

Authored by 曾国涛
1 parent 32270f03

feat(order): 新增订单费用字段申请功能

- 在 ApplyTypeEnum 中添加 ORDER_COST_FIELD_EDIT_APPLY 类型
- 在 OrderFieldLockApplyQueryVO 中添加 typeIn 字段,支持多类型查询
- 实现订单费用字段锁定和编辑功能
- 新增 BusinessProfitDetailVO 类,用于业务净利润分析
- 优化订单利润分析相关服务和控制器
Showing 55 changed files with 3292 additions and 51 deletions
src/main/java/com/order/erp/common/constant/Constant.java
@@ -161,7 +161,7 @@ public class Constant { @@ -161,7 +161,7 @@ public class Constant {
161 161
162 public static final int SEVEN = 7; 162 public static final int SEVEN = 7;
163 public static final int FOURTEEN= 14; 163 public static final int FOURTEEN= 14;
164 - public static final int THIRTY = 30; 164 + public static final Integer THIRTY = 30;
165 165
166 public static final int TWENTY_FIRST = 21; 166 public static final int TWENTY_FIRST = 21;
167 167
src/main/java/com/order/erp/controller/OrderCostController.java 0 → 100644
  1 +package com.order.erp.controller;
  2 +
  3 +import com.order.erp.common.constant.ServerResult;
  4 +import com.order.erp.domain.vo.OrderProfitAnalysisVo;
  5 +import com.order.erp.domain.vo.order.*;
  6 +import com.order.erp.service.order.IOrderCostInfoService;
  7 +import com.order.erp.service.order.OrderProfitAnalysisService;
  8 +import io.swagger.annotations.Api;
  9 +import io.swagger.annotations.ApiOperation;
  10 +import org.springframework.beans.factory.annotation.Autowired;
  11 +import org.springframework.validation.annotation.Validated;
  12 +import org.springframework.web.bind.annotation.*;
  13 +
  14 +import javax.annotation.Resource;
  15 +import javax.servlet.http.HttpServletResponse;
  16 +import java.util.Collections;
  17 +
  18 +/**
  19 + * @author zhongnanhuang
  20 + * @version 1.0
  21 + * @project order-erp
  22 + * @description 订单利润表控制层
  23 + * @date 2023/10/23 11:48:36
  24 + */
  25 +@RestController
  26 +@RequestMapping("/order/cost")
  27 +@Api(tags = "订单费用表")
  28 +public class OrderCostController {
  29 +
  30 + @Resource
  31 + OrderProfitAnalysisService orderProfitAnalysisService;
  32 + @Autowired
  33 + IOrderCostInfoService orderCostInfoService;
  34 +
  35 +
  36 + @PostMapping("/InnerProfitDetail/listByPage")
  37 + @ApiOperation("内部生产费用明细表")
  38 + public ServerResult listInnerProfitDetailByPage(@RequestBody @Validated OrderBaseInfoQueryVO queryVO) {
  39 + queryVO.setProductionDepartment(Collections.singletonList("内部"));
  40 + return orderCostInfoService.listInnerProfitDetailByPage(queryVO);
  41 + }
  42 + @PostMapping("/BusinessProfitDetail/listByPage")
  43 + @ApiOperation("包装费用明细表")
  44 + public ServerResult listBusinessProfitDetailsByPage(@RequestBody @Validated OrderBaseInfoQueryVO queryVO) {
  45 + return orderCostInfoService.listBusinessProfitDetailByPage(queryVO);
  46 + }
  47 + @PostMapping("/edit")
  48 + @ApiOperation("编辑")
  49 + public ServerResult edit(@RequestBody OrderCostInfoVO vo) throws Exception {
  50 + return orderCostInfoService.edit(vo);
  51 + }
  52 +
  53 + @PostMapping("/applyEditFileds")
  54 + @ApiOperation("申请编辑字段")
  55 + public ServerResult applyEditFileds(OrderCostInfolockFieldVO vo) throws Exception {
  56 + return orderCostInfoService.applyEditFileds(vo);
  57 + }
  58 +
  59 +}
src/main/java/com/order/erp/controller/OrderProfitController.java
@@ -2,16 +2,20 @@ package com.order.erp.controller; @@ -2,16 +2,20 @@ package com.order.erp.controller;
2 2
3 import com.order.erp.common.constant.ServerResult; 3 import com.order.erp.common.constant.ServerResult;
4 import com.order.erp.domain.vo.OrderProfitAnalysisVo; 4 import com.order.erp.domain.vo.OrderProfitAnalysisVo;
5 -import com.order.erp.domain.vo.order.OrderProfitAnalysisVO;  
6 -import com.order.erp.domain.vo.order.ProfitCalculateVO; 5 +import com.order.erp.domain.vo.order.*;
  6 +import com.order.erp.service.order.IOrderCostInfoService;
7 import com.order.erp.service.order.OrderProfitAnalysisService; 7 import com.order.erp.service.order.OrderProfitAnalysisService;
  8 +import io.swagger.annotations.Api;
  9 +import io.swagger.annotations.ApiOperation;
  10 +import org.springframework.beans.factory.annotation.Autowired;
8 import org.springframework.validation.annotation.Validated; 11 import org.springframework.validation.annotation.Validated;
9 -import org.springframework.web.bind.annotation.PostMapping;  
10 -import org.springframework.web.bind.annotation.RequestBody;  
11 -import org.springframework.web.bind.annotation.RequestMapping;  
12 -import org.springframework.web.bind.annotation.RestController; 12 +import org.springframework.web.bind.annotation.*;
13 13
14 import javax.annotation.Resource; 14 import javax.annotation.Resource;
  15 +import javax.servlet.http.HttpServletResponse;
  16 +import java.io.IOException;
  17 +import java.util.Arrays;
  18 +import java.util.Collections;
15 19
16 /** 20 /**
17 * @author zhongnanhuang 21 * @author zhongnanhuang
@@ -36,4 +40,5 @@ public class OrderProfitController { @@ -36,4 +40,5 @@ public class OrderProfitController {
36 public ServerResult calculate(@RequestBody @Validated ProfitCalculateVO calculateVO) { 40 public ServerResult calculate(@RequestBody @Validated ProfitCalculateVO calculateVO) {
37 return orderProfitAnalysisService.calculate(calculateVO); 41 return orderProfitAnalysisService.calculate(calculateVO);
38 } 42 }
  43 +
39 } 44 }
src/main/java/com/order/erp/controller/ProjectController.java 0 → 100644
  1 +package com.order.erp.controller;
  2 +
  3 +import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
  4 +import com.order.erp.common.constant.ServerResult;
  5 +import com.order.erp.domain.vo.OrderProfitAnalysisVo;
  6 +import com.order.erp.domain.vo.order.*;
  7 +import com.order.erp.service.order.IOrderCostInfoService;
  8 +import com.order.erp.service.order.IProjectBaseInfoService;
  9 +import com.order.erp.service.order.OrderProfitAnalysisService;
  10 +import io.swagger.annotations.Api;
  11 +import io.swagger.annotations.ApiOperation;
  12 +import org.springframework.beans.factory.annotation.Autowired;
  13 +import org.springframework.validation.annotation.Validated;
  14 +import org.springframework.web.bind.annotation.*;
  15 +
  16 +import javax.annotation.Resource;
  17 +import javax.servlet.http.HttpServletResponse;
  18 +import java.util.Collections;
  19 +
  20 +/**
  21 + * @author zhongnanhuang
  22 + * @version 1.0
  23 + * @project order-erp
  24 + * @description 订单利润表控制层
  25 + * @date 2023/10/23 11:48:36
  26 + */
  27 +@RestController
  28 +@RequestMapping("/project")
  29 +@Api(tags = "项目信息")
  30 +public class ProjectController {
  31 + @Autowired
  32 + IOrderCostInfoService orderCostInfoService;
  33 + @Autowired
  34 + IProjectBaseInfoService projectBaseInfoService;
  35 +
  36 + @PostMapping("/edit")
  37 + @ApiOperation("编辑")
  38 + public ServerResult<OrderProfitAnalysisVO> edit(@RequestBody @Validated ProjectBaseInfoVO vo) {
  39 + return projectBaseInfoService.edit(vo);
  40 + }
  41 +
  42 + @PostMapping("/applyEditFileds")
  43 + @ApiOperation("申请修改")
  44 + public ServerResult<OrderProfitAnalysisVO> applyEditFileds(@RequestBody @Validated ProjectBaseInfoLockFieldVO vo) {
  45 + return projectBaseInfoService.applyEditFileds(vo);
  46 + }
  47 +
  48 + @PostMapping("/pageProjectLockFieldApply")
  49 + @ApiOperation("分页查询项目字段申请记录")
  50 + public ServerResult<OrderProfitAnalysisVO> pageProjectLockFieldApply(@RequestBody @Validated QueryProjectLockFieldVO vo) {
  51 + return projectBaseInfoService.pageProjectLockFieldApply(vo);
  52 + }
  53 +
  54 + @PostMapping("/audit")
  55 + @ApiOperation("审核")
  56 + public ServerResult<OrderProfitAnalysisVO> audit(@RequestBody @Validated AuditVO vo) {
  57 + return projectBaseInfoService.audit(vo);
  58 + }
  59 + @PostMapping("/InnerProfitInfo/listByPage")
  60 + @ApiOperation("内部生产利润分析表")
  61 + public ServerResult<Page<InnerProfitInfoVO>> listInnerProfitInfoByPage(@RequestBody @Validated OrderBaseInfoQueryVO queryVO) {
  62 + queryVO.setProductionDepartment(Collections.singletonList("内部"));
  63 + return projectBaseInfoService.listInnerProfitInfoByPage(queryVO);
  64 + }
  65 +
  66 + @PostMapping("/BusinessProfitInfo/listByPage")
  67 + @ApiOperation("业务研发净利润分析表")
  68 + public ServerResult<Page<BusinessProfitInfoVO>> listBusinessProfitInfosByPage(@RequestBody @Validated OrderBaseInfoQueryVO queryVO) {
  69 + queryVO.setProductionDepartment(Collections.singletonList("内部"));
  70 + return projectBaseInfoService.listBusinessProfitInfoByPage(queryVO);
  71 + }
  72 +
  73 + @PostMapping("/businessProfit/export")
  74 + @ApiOperation("业务研发净利润分析表导出")
  75 + public void exportBusinessProfitInfo(HttpServletResponse response, @RequestParam("projectNoPrefix") String projectNoPrefix) throws Exception {
  76 + projectBaseInfoService.exportBusinessProfitInfo(response, projectNoPrefix);
  77 + }
  78 +
  79 + @PostMapping("/innerProfit/export")
  80 + @ApiOperation("内部研发净利润分析表导出")
  81 + public void exportInnerProfitInfo(HttpServletResponse response, @RequestParam("projectNoPrefix") String projectNoPrefix) throws Exception {
  82 + projectBaseInfoService.exportInnerProfitInfo(response, projectNoPrefix);
  83 + }
  84 +
  85 +}
src/main/java/com/order/erp/domain/ApplyTypeEnum.java
@@ -24,6 +24,8 @@ public enum ApplyTypeEnum { @@ -24,6 +24,8 @@ public enum ApplyTypeEnum {
24 CHECK_BILL_APPLY(40, "应付账单申请"), 24 CHECK_BILL_APPLY(40, "应付账单申请"),
25 25
26 DEPARTMENT_INVOICE_APPLY(50,"生产科发票申请"), 26 DEPARTMENT_INVOICE_APPLY(50,"生产科发票申请"),
  27 +
  28 + ORDER_COST_FIELD_EDIT_APPLY(60,"订单费用字段申请"),
27 ; 29 ;
28 private Integer type; 30 private Integer type;
29 31
src/main/java/com/order/erp/domain/ProjectApplyTypeEnum.java 0 → 100644
  1 +package com.order.erp.domain;
  2 +
  3 +import com.baomidou.mybatisplus.annotation.EnumValue;
  4 +import com.fasterxml.jackson.annotation.JsonValue;
  5 +import lombok.AllArgsConstructor;
  6 +import lombok.Getter;
  7 +
  8 +/**
  9 + * @author: xms
  10 + * @description: TODO
  11 + * @date: 2023/9/13 18:05
  12 + * @version: 1.0
  13 + */
  14 +@Getter
  15 +@AllArgsConstructor
  16 +public enum ProjectApplyTypeEnum {
  17 +
  18 + FIELD_EDIT_APPLY(0, "字段编辑申请"),
  19 + ;
  20 + @EnumValue
  21 + @JsonValue
  22 + private Integer type;
  23 +
  24 + private String desc;
  25 +}
src/main/java/com/order/erp/domain/dto/order/OrderCostInfoDO.java 0 → 100644
  1 +package com.order.erp.domain.dto.order;
  2 +
  3 +import com.baomidou.mybatisplus.annotation.TableName;
  4 +import com.baomidou.mybatisplus.annotation.IdType;
  5 +import com.baomidou.mybatisplus.annotation.TableId;
  6 +import java.io.Serializable;
  7 +import java.math.BigDecimal;
  8 +
  9 +import com.order.erp.domain.dto.BaseDO;
  10 +import io.swagger.annotations.ApiModel;
  11 +import lombok.AllArgsConstructor;
  12 +import lombok.Data;
  13 +import lombok.EqualsAndHashCode;
  14 +import lombok.NoArgsConstructor;
  15 +import lombok.experimental.SuperBuilder;
  16 +
  17 +/**
  18 + * <p>
  19 + *
  20 + * </p>
  21 + *
  22 + * @author author
  23 + * @since 2024-12-22
  24 + */
  25 +@Data
  26 +@EqualsAndHashCode(callSuper = false)
  27 +@SuperBuilder
  28 +@AllArgsConstructor
  29 +@NoArgsConstructor
  30 +@TableName("order_cost_info")
  31 +@ApiModel(value="OrderCostinfo对象", description="")
  32 +public class OrderCostInfoDO extends BaseDO implements Serializable {
  33 +
  34 + private static final long serialVersionUID = 1L;
  35 +
  36 + @TableId(value = "id", type = IdType.AUTO)
  37 + private Long id;
  38 +
  39 + private Long orderId;
  40 +
  41 + private BigDecimal productionDepartmentPredictPrice;
  42 +
  43 + private BigDecimal productionActualPrice;
  44 +
  45 + private BigDecimal packetActualRmbTotalPrice;
  46 +
  47 +
  48 +}
src/main/java/com/order/erp/domain/dto/order/OrderProfitAnalysisDO.java
@@ -6,6 +6,7 @@ import lombok.*; @@ -6,6 +6,7 @@ import lombok.*;
6 import lombok.experimental.SuperBuilder; 6 import lombok.experimental.SuperBuilder;
7 7
8 import java.io.Serializable; 8 import java.io.Serializable;
  9 +import java.math.BigDecimal;
9 10
10 /** 11 /**
11 * 订单利润分析表(OrderProfitAnalysis)实体类 12 * 订单利润分析表(OrderProfitAnalysis)实体类
@@ -98,5 +99,19 @@ public class OrderProfitAnalysisDO extends BaseDO implements Serializable { @@ -98,5 +99,19 @@ public class OrderProfitAnalysisDO extends BaseDO implements Serializable {
98 */ 99 */
99 private int profitType; 100 private int profitType;
100 101
  102 + /**
  103 + * 生产科预算金额
  104 + */
  105 + private BigDecimal productionDepartmentPredictPrice;
  106 +
  107 + /**
  108 + * 实际发生费用
  109 + */
  110 + private BigDecimal productionActualPrice;
  111 +
  112 + /**
  113 + * 包装费用实际金额
  114 + */
  115 + private BigDecimal packetActualRmbTotalPrice;
101 116
102 } 117 }
src/main/java/com/order/erp/domain/dto/order/ProjectBaseInfoDO.java 0 → 100644
  1 +package com.order.erp.domain.dto.order;
  2 +
  3 +import com.baomidou.mybatisplus.annotation.TableName;
  4 +import com.baomidou.mybatisplus.annotation.IdType;
  5 +import com.baomidou.mybatisplus.annotation.TableId;
  6 +
  7 +import java.math.BigDecimal;
  8 +import java.time.LocalDateTime;
  9 +import java.io.Serializable;
  10 +import io.swagger.annotations.ApiModel;
  11 +import lombok.Data;
  12 +import lombok.EqualsAndHashCode;
  13 +import lombok.experimental.Accessors;
  14 +
  15 +/**
  16 + * <p>
  17 + *
  18 + * </p>
  19 + *
  20 + * @author author
  21 + * @since 2024-12-18
  22 + */
  23 +@Data
  24 +@EqualsAndHashCode(callSuper = false)
  25 +@Accessors(chain = true)
  26 +@TableName("project_base_info")
  27 +@ApiModel(value="ProjectBaseInfoDO", description="")
  28 +public class ProjectBaseInfoDO implements Serializable {
  29 +
  30 + private static final long serialVersionUID = 1L;
  31 +
  32 + @TableId(value = "id", type = IdType.AUTO)
  33 + private Long id;
  34 +
  35 + private String projectNoPrefix;
  36 +
  37 + private BigDecimal developmentCopyRmbTotalPrice;
  38 +
  39 + private LocalDateTime projectStartTime;
  40 +
  41 + private LocalDateTime projectEndTime;
  42 +
  43 +
  44 + private BigDecimal spainPaidRmbCommission;
  45 +
  46 + private BigDecimal paidRmbCommission;
  47 +
  48 + private BigDecimal actualExchangeRate;
  49 +
  50 +
  51 +}
src/main/java/com/order/erp/domain/model/OrderCostFieldLockRecord.java 0 → 100644
  1 +package com.order.erp.domain.model;
  2 +
  3 +import com.baomidou.mybatisplus.annotation.TableName;
  4 +import com.baomidou.mybatisplus.annotation.IdType;
  5 +import com.baomidou.mybatisplus.annotation.TableId;
  6 +import java.time.LocalDateTime;
  7 +import com.baomidou.mybatisplus.annotation.FieldFill;
  8 +import com.baomidou.mybatisplus.annotation.TableField;
  9 +import java.io.Serializable;
  10 +
  11 +import com.order.erp.domain.dto.BaseDO;
  12 +import io.swagger.annotations.ApiModel;
  13 +import io.swagger.annotations.ApiModelProperty;
  14 +import lombok.AllArgsConstructor;
  15 +import lombok.Data;
  16 +import lombok.EqualsAndHashCode;
  17 +import lombok.NoArgsConstructor;
  18 +import lombok.experimental.Accessors;
  19 +import lombok.experimental.SuperBuilder;
  20 +
  21 +/**
  22 + * <p>
  23 + *
  24 + * </p>
  25 + *
  26 + * @author author
  27 + * @since 2024-12-22
  28 + */
  29 +@Data
  30 +@EqualsAndHashCode(callSuper = false)
  31 +@SuperBuilder
  32 +@NoArgsConstructor
  33 +@AllArgsConstructor
  34 +@TableName("order_cost_field_lock_record")
  35 +@ApiModel(value="OrderCostFieldLockRecord对象", description="")
  36 +public class OrderCostFieldLockRecord extends BaseDO implements Serializable {
  37 +
  38 + private static final long serialVersionUID = 1L;
  39 +
  40 + @TableId(value = "id", type = IdType.AUTO)
  41 + private Long id;
  42 +
  43 + private String fields;
  44 +
  45 + private Long userId;
  46 +
  47 + private Long orderId;
  48 +
  49 +
  50 +
  51 +}
src/main/java/com/order/erp/domain/model/ProjectApplyDO.java 0 → 100644
  1 +package com.order.erp.domain.model;
  2 +
  3 +import com.baomidou.mybatisplus.annotation.TableName;
  4 +import com.baomidou.mybatisplus.annotation.IdType;
  5 +import com.baomidou.mybatisplus.annotation.TableId;
  6 +
  7 +import java.io.Serializable;
  8 +
  9 +import com.order.erp.domain.ProjectApplyTypeEnum;
  10 +import com.order.erp.domain.dto.BaseDO;
  11 +import io.swagger.annotations.ApiModel;
  12 +import io.swagger.annotations.ApiModelProperty;
  13 +import lombok.AllArgsConstructor;
  14 +import lombok.Data;
  15 +import lombok.EqualsAndHashCode;
  16 +import lombok.NoArgsConstructor;
  17 +import lombok.experimental.SuperBuilder;
  18 +
  19 +/**
  20 + * <p>
  21 + * 项目-字段锁定申请表
  22 + * </p>
  23 + *
  24 + * @author author
  25 + * @since 2024-12-22
  26 + */
  27 +@Data
  28 +@EqualsAndHashCode(callSuper = false)
  29 +@SuperBuilder
  30 +@AllArgsConstructor
  31 +@NoArgsConstructor
  32 +@TableName("project_apply")
  33 +@ApiModel(value="ProjectFieldLockApply对象", description="项目-字段锁定申请表")
  34 +public class ProjectApplyDO extends BaseDO implements Serializable {
  35 +
  36 + private static final long serialVersionUID = 1L;
  37 +
  38 + @TableId(value = "id", type = IdType.AUTO)
  39 + private Long id;
  40 +
  41 + @ApiModelProperty(value = "项目id")
  42 + private Long projectId;
  43 +
  44 +
  45 + @ApiModelProperty(value = "申请用户id")
  46 + private Long applyUserId;
  47 +
  48 + @ApiModelProperty(value = "审批用户id")
  49 + private Long auditUserId;
  50 +
  51 + @ApiModelProperty(value = "锁定字段 json字符串")
  52 + private String fields;
  53 +
  54 + @ApiModelProperty(value = "锁定字段 json字符串")
  55 + private ProjectApplyTypeEnum type;
  56 +
  57 + @ApiModelProperty(value = "状态:0 待审批,1 通过,2 拒绝")
  58 + private Integer status;
  59 +
  60 + @ApiModelProperty(value = "审核备注")
  61 + private String auditRemark;
  62 +
  63 + @ApiModelProperty(value = "审批角色code集合,分割")
  64 + private String auditRoleCodes;
  65 +
  66 + @ApiModelProperty(value = "申请原因")
  67 + private String applyRemark;
  68 +
  69 +
  70 +}
src/main/java/com/order/erp/domain/model/ProjectFieldLockRecord.java 0 → 100644
  1 +package com.order.erp.domain.model;
  2 +
  3 +import com.baomidou.mybatisplus.annotation.TableName;
  4 +import com.baomidou.mybatisplus.annotation.IdType;
  5 +import com.baomidou.mybatisplus.annotation.TableId;
  6 +import java.time.LocalDateTime;
  7 +import com.baomidou.mybatisplus.annotation.FieldFill;
  8 +import com.baomidou.mybatisplus.annotation.TableField;
  9 +import java.io.Serializable;
  10 +
  11 +import com.order.erp.domain.dto.BaseDO;
  12 +import io.swagger.annotations.ApiModel;
  13 +import io.swagger.annotations.ApiModelProperty;
  14 +import lombok.AllArgsConstructor;
  15 +import lombok.Data;
  16 +import lombok.EqualsAndHashCode;
  17 +import lombok.NoArgsConstructor;
  18 +import lombok.experimental.Accessors;
  19 +import lombok.experimental.SuperBuilder;
  20 +
  21 +/**
  22 + * <p>
  23 + * 项目-字段锁定记录表
  24 + * </p>
  25 + *
  26 + * @author author
  27 + * @since 2024-12-22
  28 + */
  29 +@Data
  30 +@EqualsAndHashCode(callSuper = false)
  31 +@AllArgsConstructor
  32 +@NoArgsConstructor
  33 +@SuperBuilder
  34 +@TableName("project_field_lock_record")
  35 +@ApiModel(value="ProjectFieldLockRecord对象", description="项目-字段锁定记录表")
  36 +public class ProjectFieldLockRecord extends BaseDO implements Serializable {
  37 +
  38 + private static final long serialVersionUID = 1L;
  39 +
  40 + @TableId(value = "id", type = IdType.AUTO)
  41 + private Long id;
  42 +
  43 + @ApiModelProperty(value = "项目id")
  44 + private Long projectId;
  45 +
  46 + @ApiModelProperty(value = "用户id")
  47 + private Long userId;
  48 +
  49 + @ApiModelProperty(value = "锁定字段 json字符串")
  50 + private String fields;
  51 +
  52 +
  53 +
  54 +}
src/main/java/com/order/erp/domain/vo/order/AuditVO.java
1 package com.order.erp.domain.vo.order; 1 package com.order.erp.domain.vo.order;
2 2
3 import com.order.erp.domain.vo.BasePageVO; 3 import com.order.erp.domain.vo.BasePageVO;
  4 +import io.swagger.annotations.ApiModelProperty;
4 import lombok.*; 5 import lombok.*;
5 import lombok.experimental.SuperBuilder; 6 import lombok.experimental.SuperBuilder;
6 7
@@ -23,17 +24,20 @@ public class AuditVO extends BasePageVO implements Serializable { @@ -23,17 +24,20 @@ public class AuditVO extends BasePageVO implements Serializable {
23 * 申请id 24 * 申请id
24 */ 25 */
25 @NotNull(message = "申请id不能为空") 26 @NotNull(message = "申请id不能为空")
  27 + @ApiModelProperty(value = "申请id", required = true)
26 private Long id; 28 private Long id;
27 29
28 /** 30 /**
29 * 状态:1 通过,2 拒绝 31 * 状态:1 通过,2 拒绝
30 */ 32 */
31 @NotNull(message = "状态不能为空") 33 @NotNull(message = "状态不能为空")
  34 + @ApiModelProperty(value = "状态:1 通过,2 拒绝", required = true)
32 private Integer status; 35 private Integer status;
33 36
34 /** 37 /**
35 * 拒绝原因备注 38 * 拒绝原因备注
36 */ 39 */
  40 + @ApiModelProperty(value = "拒绝原因备注")
37 private String refuseRemark; 41 private String refuseRemark;
38 } 42 }
39 43
src/main/java/com/order/erp/domain/vo/order/BusinessProfitDetailVO.java 0 → 100644
  1 +package com.order.erp.domain.vo.order;
  2 +
  3 +import io.swagger.annotations.ApiModelProperty;
  4 +import lombok.*;
  5 +import lombok.experimental.SuperBuilder;
  6 +
  7 +import java.io.Serializable;
  8 +import java.math.BigDecimal;
  9 +
  10 +/**
  11 + * 业务/研发净利润分析
  12 + *
  13 + * @author makejava
  14 + * @since 2024-08-05 16:26:34
  15 + */
  16 +@Data
  17 +@AllArgsConstructor
  18 +@ToString
  19 +@NoArgsConstructor
  20 +@EqualsAndHashCode(callSuper = false)
  21 +@SuperBuilder
  22 +public class BusinessProfitDetailVO implements Serializable {
  23 +
  24 +
  25 + /**
  26 + * 客户编码
  27 + */
  28 + @ApiModelProperty(value = "客户编码")
  29 + private String customerCode;
  30 +
  31 + /**
  32 + * 项目号
  33 + */
  34 + @ApiModelProperty(value = "项目号")
  35 + private String projectNo;
  36 +
  37 + /**
  38 + * 生产科
  39 + */
  40 + @ApiModelProperty(value = "生产部门")
  41 + private String productionDepartment;
  42 +
  43 + /**
  44 + * 内部编号
  45 + */
  46 + @ApiModelProperty(value = "内部编号")
  47 + private String innerNo;
  48 +
  49 + /**
  50 + * pic图片地址
  51 + */
  52 + @ApiModelProperty(value = "图片地址")
  53 + private String picUrl;
  54 +
  55 + /**
  56 + * 订单数量
  57 + */
  58 + @ApiModelProperty(value = "订单数量")
  59 + private Integer orderCount;
  60 +
  61 + /**
  62 + * 包装费用$
  63 + */
  64 + @ApiModelProperty(value = "包装费用(美元)")
  65 + private Double packetPrice;
  66 +
  67 + /**
  68 + * 包装费用合计$
  69 + */
  70 + @ApiModelProperty(value = "包装费用合计(美元)")
  71 + private Double packetTotalPrice;
  72 +
  73 + /**
  74 + * 包装费用合计¥
  75 + */
  76 + @ApiModelProperty(value = "包装费用合计(人民币)")
  77 + private Double packetRmbTotalPrice;
  78 +
  79 + /**
  80 + * 包装费用实际金额
  81 + */
  82 + @ApiModelProperty(value = "包装费用实际金额(人民币)")
  83 + private BigDecimal packetActualRmbTotalPrice;
  84 +
  85 + /**
  86 + * 包装费用实际金额¥
  87 + */
  88 + @ApiModelProperty(value = "包装费用实际金额(人民币)")
  89 + private BigDecimal packetActualRmbPrice;
  90 +
  91 + /**
  92 + * 包装费用实际金额$
  93 + */
  94 + @ApiModelProperty(value = "包装费用实际金额(美元)")
  95 + private BigDecimal packetActualPrice;
  96 +
  97 + /**
  98 + * 包装费用收益
  99 + */
  100 + @ApiModelProperty(value = "包装费用收益(人民币)")
  101 + private BigDecimal packetProfitRmbPrice;
  102 +
  103 + /**
  104 + * 包装费用利润率
  105 + */
  106 + @ApiModelProperty(value = "包装费用利润率")
  107 + private BigDecimal packetProfitRate;
  108 +
  109 + /**
  110 + * 锁定字段信息
  111 + */
  112 + @ApiModelProperty(value = "锁定字段信息")
  113 + private OrderCostInfolockFieldVO lockFields;
  114 +
  115 +
  116 +}
  117 +
src/main/java/com/order/erp/domain/vo/order/BusinessProfitInfoVO.java 0 → 100644
  1 +package com.order.erp.domain.vo.order;
  2 +
  3 +import io.swagger.annotations.ApiModelProperty;
  4 +import lombok.*;
  5 +import lombok.experimental.SuperBuilder;
  6 +
  7 +import java.io.Serializable;
  8 +import java.math.BigDecimal;
  9 +import java.time.LocalDateTime;
  10 +
  11 +/**
  12 + * 业务/研发净利润分析
  13 + *
  14 + * @author makejava
  15 + * @since 2024-08-05 16:26:34
  16 + */
  17 +@Data
  18 +@AllArgsConstructor
  19 +@ToString
  20 +@NoArgsConstructor
  21 +@EqualsAndHashCode(callSuper = false)
  22 +@SuperBuilder
  23 +public class BusinessProfitInfoVO implements Serializable {
  24 +
  25 +
  26 + /**
  27 + * 客户编码
  28 + */
  29 + @ApiModelProperty(value = "客户编码")
  30 + private String customerCode;
  31 +
  32 + /**
  33 + * 项目号
  34 + */
  35 + @ApiModelProperty(value = "项目号")
  36 + private String projectNoPrefix;
  37 +
  38 + /**
  39 + * 客户总价¥
  40 + */
  41 + @ApiModelProperty(value = "客户总价(人民币)")
  42 + private Double customerRmbTotalPrice;
  43 +
  44 + /**
  45 + * 客户总价¥
  46 + */
  47 + @ApiModelProperty(value = "客户总价")
  48 + private Double customerTotalPrice;
  49 +
  50 + /**
  51 + * 生成科总价¥
  52 + */
  53 + @ApiModelProperty(value = "生产部门总价")
  54 + private Double productionDepartmentTotalPrice;
  55 +
  56 + /**
  57 + * 生产科
  58 + */
  59 + @ApiModelProperty(value = "生产部门")
  60 + private String productionDepartment;
  61 +
  62 + /**
  63 + * 内部编号
  64 + */
  65 + @ApiModelProperty(value = "内部编号")
  66 + private String innerNo;
  67 +
  68 + /**
  69 + * pic图片地址
  70 + */
  71 + @ApiModelProperty(value = "图片地址")
  72 + private String picUrl;
  73 +
  74 + /**
  75 + * 订单数量
  76 + */
  77 + @ApiModelProperty(value = "订单数量")
  78 + private Integer orderCount;
  79 +
  80 + /**
  81 + * 包装费用$
  82 + */
  83 + @ApiModelProperty(value = "包装费用(美元)")
  84 + private Double packetPrice;
  85 +
  86 + /**
  87 + * 包装费用合计$
  88 + */
  89 + @ApiModelProperty(value = "包装费用合计(美元)")
  90 + private Double packetTotalPrice;
  91 +
  92 + /**
  93 + * 包装费用合计¥
  94 + */
  95 + @ApiModelProperty(value = "包装费用合计(人民币)")
  96 + private Double packetRmbTotalPrice;
  97 +
  98 + /**
  99 + * 包装费用实际金额
  100 + */
  101 + @ApiModelProperty(value = "包装费用实际金额(人民币)")
  102 + private BigDecimal packetActualRmbTotalPrice;
  103 +
  104 + /**
  105 + * 包装费用实际金额¥
  106 + */
  107 + @ApiModelProperty(value = "包装费用实际金额(人民币)")
  108 + private BigDecimal packetActualRmbPrice;
  109 +
  110 + /**
  111 + * 包装费用实际金额$
  112 + */
  113 + @ApiModelProperty(value = "包装费用实际金额(美元)")
  114 + private BigDecimal packetActualPrice;
  115 +
  116 + /**
  117 + * 包装费用收益
  118 + */
  119 + @ApiModelProperty(value = "包装费用收益(人民币)")
  120 + private BigDecimal packetProfitRmbPrice;
  121 +
  122 + /**
  123 + * 包装费用利润率
  124 + */
  125 + @ApiModelProperty(value = "包装费用利润率")
  126 + private BigDecimal packetProfitRate;
  127 +
  128 + /**
  129 + * 研发复制费合计¥
  130 + */
  131 + @ApiModelProperty(value = "研发复制费合计(人民币)")
  132 + private BigDecimal developmentCopyRmbTotalPrice;
  133 +
  134 + /**
  135 + * 固定成本
  136 + */
  137 + @ApiModelProperty(value = "固定成本")
  138 + private BigDecimal fixedCost;
  139 +
  140 + /**
  141 + * 西班牙已发提成¥
  142 + */
  143 + @ApiModelProperty(value = "西班牙已发提成(人民币)")
  144 + private BigDecimal spainPaidRmbCommission;
  145 +
  146 + /**
  147 + * 西班牙提成¥
  148 + */
  149 + @ApiModelProperty(value = "西班牙提成(人民币)")
  150 + private BigDecimal spainRmbCommission;
  151 +
  152 + /**
  153 + * 西班牙未发提成¥
  154 + */
  155 + @ApiModelProperty(value = "西班牙未发提成(人民币)")
  156 + private BigDecimal spainUnpaidRmbCommission;
  157 +
  158 + /**
  159 + * 已发提成¥
  160 + */
  161 + @ApiModelProperty(value = "已发提成(人民币)")
  162 + private BigDecimal paidRmbCommission;
  163 +
  164 + /**
  165 + * 提成¥
  166 + */
  167 + @ApiModelProperty(value = "提成(人民币)")
  168 + private BigDecimal rmbCommission;
  169 +
  170 + /**
  171 + * 未发提成¥
  172 + */
  173 + @ApiModelProperty(value = "未发提成(人民币)")
  174 + private BigDecimal unpaidRmbCommission;
  175 +
  176 + /**
  177 + * 实际汇率
  178 + */
  179 + @ApiModelProperty(value = "实际汇率")
  180 + private BigDecimal actualExchangeRate;
  181 +
  182 + /**
  183 + * 支出合计
  184 + */
  185 + @ApiModelProperty(value = "支出合计(人民币)")
  186 + private BigDecimal rmbTotalExpense;
  187 +
  188 + /**
  189 + * 毛利润
  190 + */
  191 + @ApiModelProperty(value = "毛利润")
  192 + private BigDecimal profit;
  193 +
  194 + /**
  195 + * 毛利率
  196 + */
  197 + @ApiModelProperty(value = "毛利率")
  198 + private BigDecimal profitRate;
  199 +
  200 + /**
  201 + * 研发净利润
  202 + */
  203 + @ApiModelProperty(value = "研发净利润")
  204 + private BigDecimal developmentProfit;
  205 +
  206 + /**
  207 + * 研发净利率
  208 + */
  209 + @ApiModelProperty(value = "研发净利率")
  210 + private BigDecimal developmentProfitRate;
  211 +
  212 + /**
  213 + * 实际跟单单价
  214 + */
  215 + @ApiModelProperty(value = "实际跟单单价(人民币)")
  216 + private BigDecimal actualOrderRmbPrice;
  217 +
  218 + /**
  219 + * 实际跟单单价$
  220 + */
  221 + @ApiModelProperty(value = "实际跟单单价(美元)")
  222 + private BigDecimal actualOrderPrice;
  223 +
  224 + /**
  225 + * 汇率收益
  226 + */
  227 + @ApiModelProperty(value = "汇率收益")
  228 + private BigDecimal exchangeRateProfit;
  229 +
  230 + /**
  231 + * 综合收益
  232 + */
  233 + @ApiModelProperty(value = "综合收益")
  234 + private BigDecimal comprehensiveProfit;
  235 +
  236 + /**
  237 + * 项目开始时间
  238 + */
  239 + @ApiModelProperty(value = "项目开始时间")
  240 + private LocalDateTime projectStartTime;
  241 +
  242 + /**
  243 + * 项目结束时间
  244 + */
  245 + @ApiModelProperty(value = "项目结束时间")
  246 + private LocalDateTime projectEndTime;
  247 +
  248 + @ApiModelProperty(value = "生产开始时间")
  249 + private LocalDateTime produceStartTime;
  250 +
  251 + @ApiModelProperty(value = "生产结束时间")
  252 + private LocalDateTime produceEndTime;
  253 +
  254 + @ApiModelProperty(value = "锁定字段信息")
  255 + private ProjectBaseInfoLockFieldVO lockFields;
  256 +
  257 +
  258 +}
  259 +
src/main/java/com/order/erp/domain/vo/order/InnerProfitDetailVO.java 0 → 100644
  1 +package com.order.erp.domain.vo.order;
  2 +
  3 +import io.swagger.annotations.ApiModelProperty;
  4 +import lombok.*;
  5 +import lombok.experimental.SuperBuilder;
  6 +
  7 +import java.io.Serializable;
  8 +import java.math.BigDecimal;
  9 +import java.util.Map;
  10 +
  11 +/**
  12 + * 业务/研发净利润分析
  13 + *
  14 + * @author makejava
  15 + * @since 2024-08-05 16:26:34
  16 + */
  17 +@Data
  18 +@AllArgsConstructor
  19 +@ToString
  20 +@NoArgsConstructor
  21 +@EqualsAndHashCode(callSuper = false)
  22 +@SuperBuilder
  23 +public class InnerProfitDetailVO implements Serializable {
  24 +
  25 +
  26 + /**
  27 + * 客户编码
  28 + */
  29 + @ApiModelProperty(value = "客户编码")
  30 + private String customerCode;
  31 +
  32 + /**
  33 + * 项目号
  34 + */
  35 + @ApiModelProperty(value = "项目号")
  36 + private String projectNo;
  37 + @ApiModelProperty(value = "生产科")
  38 + private String productionDepartment;
  39 +
  40 + /**
  41 + * 内部编号
  42 + */
  43 + @ApiModelProperty(value = "内部编码")
  44 + private String innerNo;
  45 + /**
  46 + * pic图片地址
  47 + */
  48 + @ApiModelProperty(value = "图片")
  49 + private String picUrl;
  50 +
  51 + /**
  52 + * 订单数量
  53 + */
  54 + @ApiModelProperty(value = "数量")
  55 + private Integer orderCount;
  56 +
  57 + /**
  58 + * 生产科预算金额由财务手动输入
  59 + */
  60 + @ApiModelProperty(value = "生产科预算金额")
  61 + private BigDecimal productionDepartmentPredictPrice;
  62 +
  63 +
  64 + /**
  65 + * 实际发生费用 手动输入
  66 + */
  67 + @ApiModelProperty(value = "实际发生费用")
  68 + private BigDecimal productionActualPrice;
  69 +
  70 + /**
  71 + * 生产科总价合计
  72 + */
  73 + @ApiModelProperty(value = "生产科总价")
  74 + private Double productionDepartmentTotalPrice;
  75 + /**
  76 + * 生产科总价合计
  77 + */
  78 + @ApiModelProperty(value = "生产科单价")
  79 + private Double productionDepartmentPrice;
  80 +
  81 +
  82 + /**
  83 + * 预算占比
  84 + * 预算占比计算(实际发生费用/预算金额
  85 + */
  86 + @ApiModelProperty(value = "预算占比")
  87 + private BigDecimal predictRatio;
  88 +
  89 + /**
  90 + * 预算占比与实际占比差
  91 + * 预算占比与实际占比差计算(1-预算占比)
  92 + */
  93 + @ApiModelProperty(value = "预算占比与实际占比差")
  94 + private BigDecimal predictAndActualRatio;
  95 +
  96 + /**
  97 + * 内部生产毛利润计算:生产科总价-预算金额
  98 + */
  99 + @ApiModelProperty(value = "事前毛利润")
  100 + private BigDecimal beforeGrossProfit;
  101 +
  102 + /**
  103 + * 内部生产毛利润率计算:事前毛利润/生产科总价
  104 + */
  105 + @ApiModelProperty(value = "事前毛利润")
  106 + private BigDecimal beforeGrossProfitRate;
  107 +
  108 + /**
  109 + * 内部生产毛利润计算:生产科总价-实际发生费用就是得出
  110 + */
  111 + @ApiModelProperty(value = "事后毛利润")
  112 + private BigDecimal grossProfit;
  113 +
  114 + /**
  115 + * 内部生产毛利润率计算:事后毛利润/生产科总价
  116 + */
  117 + @ApiModelProperty(value = "事后毛利润")
  118 + private BigDecimal grossProfitRate;
  119 +
  120 + private OrderCostInfolockFieldVO lockFields;
  121 +
  122 +}
  123 +
src/main/java/com/order/erp/domain/vo/order/InnerProfitInfoVO.java 0 → 100644
  1 +package com.order.erp.domain.vo.order;
  2 +
  3 +import io.swagger.annotations.ApiModelProperty;
  4 +import lombok.*;
  5 +import lombok.experimental.SuperBuilder;
  6 +
  7 +import java.io.Serializable;
  8 +import java.math.BigDecimal;
  9 +import java.time.LocalDateTime;
  10 +
  11 +/**
  12 + * 业务/研发净利润分析
  13 + *
  14 + * @author makejava
  15 + * @since 2024-08-05 16:26:34
  16 + */
  17 +@Data
  18 +@AllArgsConstructor
  19 +@ToString
  20 +@NoArgsConstructor
  21 +@EqualsAndHashCode(callSuper = false)
  22 +@SuperBuilder
  23 +public class InnerProfitInfoVO implements Serializable {
  24 +
  25 +
  26 + /**
  27 + * 客户编码
  28 + */
  29 + @ApiModelProperty(value = "客户编码")
  30 + private String customerCode;
  31 +
  32 + /**
  33 + * 项目号
  34 + */
  35 + @ApiModelProperty(value = "项目号")
  36 + private String projectNoPrefix;
  37 + @ApiModelProperty(value = "生产科")
  38 + private String productionDepartment;
  39 +
  40 + /**
  41 + * 订单数量
  42 + */
  43 + @ApiModelProperty(value = "数量")
  44 + private Integer orderCount;
  45 +
  46 + /**
  47 + * 生产科预算金额由财务手动输入
  48 + */
  49 + @ApiModelProperty(value = "生产科预算金额")
  50 + private BigDecimal productionDepartmentPredictPrice;
  51 +
  52 +
  53 + /**
  54 + * 实际发生费用 手动输入
  55 + */
  56 + @ApiModelProperty(value = "实际发生费用")
  57 + private BigDecimal productionActualPrice;
  58 +
  59 + /**
  60 + * 生产科总价合计
  61 + */
  62 + @ApiModelProperty(value = "生产科总价")
  63 + private Double productionDepartmentTotalPrice;
  64 +
  65 +
  66 + /**
  67 + * 预算占比
  68 + * 预算占比计算(实际发生费用/预算金额
  69 + */
  70 + @ApiModelProperty(value = "预算占比")
  71 + private BigDecimal predictRatio;
  72 +
  73 + /**
  74 + * 预算占比与实际占比差
  75 + * 预算占比与实际占比差计算(1-预算占比)
  76 + */
  77 + @ApiModelProperty(value = "预算占比与实际占比差")
  78 + private BigDecimal predictAndActualRatio;
  79 +
  80 + /**
  81 + * 内部生产毛利润计算:生产科总价-预算金额
  82 + */
  83 + @ApiModelProperty(value = "事前毛利润")
  84 + private BigDecimal beforeGrossProfit;
  85 +
  86 + /**
  87 + * 内部生产毛利润率计算:事前毛利润/生产科总价
  88 + */
  89 + @ApiModelProperty(value = "事前毛利润")
  90 + private BigDecimal beforeGrossProfitRate;
  91 +
  92 + /**
  93 + * 内部生产毛利润计算:生产科总价-实际发生费用就是得出
  94 + */
  95 + @ApiModelProperty(value = "事后毛利润")
  96 + private BigDecimal grossProfit;
  97 +
  98 + /**
  99 + * 内部生产毛利润率计算:事后毛利润/生产科总价
  100 + */
  101 + @ApiModelProperty(value = "事后毛利润")
  102 + private BigDecimal grossProfitRate;
  103 +
  104 + /**
  105 + * 内部生产固定成本
  106 + */
  107 + @ApiModelProperty(value = "内部生产固定成本")
  108 + private BigDecimal innerProductionFixedCost;
  109 +
  110 + /**
  111 + * 内部生产提成
  112 + */
  113 + @ApiModelProperty(value = "内部生产提成")
  114 + private BigDecimal innerProductionCommission;
  115 + /**
  116 + * 内部生产净利润
  117 + */
  118 + @ApiModelProperty(value = "内部生产净利润")
  119 + private BigDecimal innerProductionProfit;
  120 + /**
  121 + * 内部生产净利润率
  122 + */
  123 + @ApiModelProperty(value = "内部生产净利润率")
  124 + private BigDecimal innerProductionProfitRate;
  125 +
  126 + /**
  127 + * 项目开始时间
  128 + */
  129 + @ApiModelProperty(value = "项目开始时间")
  130 + private LocalDateTime produceStartTime;
  131 + /**
  132 + * 项目结束时间
  133 + */
  134 + @ApiModelProperty(value = "项目结束时间")
  135 + private LocalDateTime produceEndTime;
  136 +
  137 +}
  138 +
src/main/java/com/order/erp/domain/vo/order/OrderBaseInfoQueryVO.java
@@ -61,6 +61,12 @@ public class OrderBaseInfoQueryVO extends BasePageVO implements Serializable { @@ -61,6 +61,12 @@ public class OrderBaseInfoQueryVO extends BasePageVO implements Serializable {
61 private List<String> projectNo; 61 private List<String> projectNo;
62 62
63 /** 63 /**
  64 + * 项目号右模糊
  65 + */
  66 + private String projectNoLikeRight;
  67 +
  68 +
  69 + /**
64 * 客户编码集合 70 * 客户编码集合
65 */ 71 */
66 private List<String> customerCode; 72 private List<String> customerCode;
src/main/java/com/order/erp/domain/vo/order/OrderCostInfoVO.java 0 → 100644
  1 +package com.order.erp.domain.vo.order;
  2 +
  3 +import com.baomidou.mybatisplus.annotation.IdType;
  4 +import com.baomidou.mybatisplus.annotation.TableId;
  5 +import com.baomidou.mybatisplus.annotation.TableName;
  6 +import io.swagger.annotations.ApiModel;
  7 +import lombok.AllArgsConstructor;
  8 +import lombok.Data;
  9 +import lombok.EqualsAndHashCode;
  10 +import lombok.NoArgsConstructor;
  11 +import lombok.experimental.SuperBuilder;
  12 +
  13 +import java.io.Serializable;
  14 +import java.math.BigDecimal;
  15 +
  16 +/**
  17 + * <p>
  18 + *
  19 + * </p>
  20 + *
  21 + * @author author
  22 + * @since 2024-12-22
  23 + */
  24 +@Data
  25 +@EqualsAndHashCode(callSuper = false)
  26 +@SuperBuilder
  27 +@AllArgsConstructor
  28 +@NoArgsConstructor
  29 +@TableName("order_cost_info")
  30 +@ApiModel(value="OrderCostDetail对象", description="")
  31 +public class OrderCostInfoVO implements Serializable {
  32 +
  33 + private static final long serialVersionUID = 1L;
  34 +
  35 + @TableId(value = "id", type = IdType.AUTO)
  36 + private Long id;
  37 +
  38 + private Long orderId;
  39 +
  40 + private BigDecimal productionDepartmentPredictPrice;
  41 +
  42 + private BigDecimal productionActualPrice;
  43 +
  44 + private BigDecimal packetActualRmbTotalPrice;
  45 +
  46 +
  47 +}
src/main/java/com/order/erp/domain/vo/order/OrderCostInfolockFieldVO.java 0 → 100644
  1 +package com.order.erp.domain.vo.order;
  2 +
  3 +import com.baomidou.mybatisplus.annotation.TableName;
  4 +import io.swagger.annotations.ApiModel;
  5 +import lombok.AllArgsConstructor;
  6 +import lombok.Data;
  7 +import lombok.EqualsAndHashCode;
  8 +import lombok.NoArgsConstructor;
  9 +import lombok.experimental.SuperBuilder;
  10 +
  11 +import java.io.Serializable;
  12 +
  13 +/**
  14 + * <p>
  15 + *
  16 + * </p>
  17 + *
  18 + * @author author
  19 + * @since 2024-12-22
  20 + */
  21 +@Data
  22 +@EqualsAndHashCode(callSuper = false)
  23 +@SuperBuilder
  24 +@AllArgsConstructor
  25 +@NoArgsConstructor
  26 +@TableName("order_cost_info")
  27 +@ApiModel(value="OrderCostDetail对象", description="")
  28 +public class OrderCostInfolockFieldVO implements Serializable {
  29 +
  30 + private static final long serialVersionUID = 1L;
  31 +
  32 + private Long orderId;
  33 +
  34 + private String productionDepartmentPredictPrice;
  35 +
  36 + private String productionActualPrice;
  37 +
  38 + private String packetActualRmbTotalPrice;
  39 +
  40 +
  41 +}
src/main/java/com/order/erp/domain/vo/order/OrderFieldLockApplyQueryVO.java
@@ -59,6 +59,11 @@ public class OrderFieldLockApplyQueryVO extends BasePageVO implements Serializab @@ -59,6 +59,11 @@ public class OrderFieldLockApplyQueryVO extends BasePageVO implements Serializab
59 private Integer type; 59 private Integer type;
60 60
61 /** 61 /**
  62 + * 申请类型:枚举类ApplyTypeEnum
  63 + */
  64 + private List<Integer> typeIn;
  65 +
  66 + /**
62 * 项目号 67 * 项目号
63 */ 68 */
64 private List<String> projectNo; 69 private List<String> projectNo;
src/main/java/com/order/erp/domain/vo/order/OrderInfoResultVO.java
@@ -38,6 +38,10 @@ public class OrderInfoResultVO extends OrderBaseInfoVO implements Serializable { @@ -38,6 +38,10 @@ public class OrderInfoResultVO extends OrderBaseInfoVO implements Serializable {
38 * 质检信息 38 * 质检信息
39 */ 39 */
40 private OrderInspectionStageVO inspectionStageInfo; 40 private OrderInspectionStageVO inspectionStageInfo;
  41 + /**
  42 + * 费用明细
  43 + */
  44 + private OrderCostInfoVO orderCostInfo;
41 45
42 /** 46 /**
43 * 字段锁定集合 47 * 字段锁定集合
src/main/java/com/order/erp/domain/vo/order/OrderLockFieldVO.java
@@ -46,6 +46,11 @@ public class OrderLockFieldVO implements Serializable { @@ -46,6 +46,11 @@ public class OrderLockFieldVO implements Serializable {
46 private OrderInspectionStageFieldVO inspectionStageFields; 46 private OrderInspectionStageFieldVO inspectionStageFields;
47 47
48 /** 48 /**
  49 + * 费用字段
  50 + */
  51 + private OrderCostInfolockFieldVO costInfolockFieldVO;
  52 +
  53 + /**
49 * 应收款账单字段 54 * 应收款账单字段
50 */ 55 */
51 // private List<InvoiceBillOrderDO> invoiceBillOrderDOList; 56 // private List<InvoiceBillOrderDO> invoiceBillOrderDOList;
src/main/java/com/order/erp/domain/vo/order/OrderProfitAnalysisVO.java
@@ -4,6 +4,7 @@ import lombok.*; @@ -4,6 +4,7 @@ import lombok.*;
4 import lombok.experimental.SuperBuilder; 4 import lombok.experimental.SuperBuilder;
5 5
6 import java.io.Serializable; 6 import java.io.Serializable;
  7 +import java.math.BigDecimal;
7 8
8 /** 9 /**
9 * 订单利润分析表(OrderProfitAnalysis)实体类 10 * 订单利润分析表(OrderProfitAnalysis)实体类
@@ -34,7 +35,6 @@ public class OrderProfitAnalysisVO implements Serializable { @@ -34,7 +35,6 @@ public class OrderProfitAnalysisVO implements Serializable {
34 */ 35 */
35 private Double customerTotalPrice; 36 private Double customerTotalPrice;
36 37
37 -  
38 /** 38 /**
39 * 客户单价¥ 39 * 客户单价¥
40 */ 40 */
@@ -111,4 +111,6 @@ public class OrderProfitAnalysisVO implements Serializable { @@ -111,4 +111,6 @@ public class OrderProfitAnalysisVO implements Serializable {
111 */ 111 */
112 private Integer recordNum; 112 private Integer recordNum;
113 113
  114 +
  115 +
114 } 116 }
src/main/java/com/order/erp/domain/vo/order/OrderProfitQueryVO.java 0 → 100644
  1 +package com.order.erp.domain.vo.order;
  2 +
  3 +import com.order.erp.domain.vo.BasePageVO;
  4 +import lombok.*;
  5 +import lombok.experimental.SuperBuilder;
  6 +
  7 +import java.io.Serializable;
  8 +import java.util.List;
  9 +import java.util.Set;
  10 +
  11 +/**
  12 + * 订单基础信息表(OrderBaseInfo)实体类
  13 + *
  14 + * @author makejava
  15 + * @since 2023-09-08 15:26:43
  16 + */
  17 +@Data
  18 +@AllArgsConstructor
  19 +@ToString
  20 +@NoArgsConstructor
  21 +@EqualsAndHashCode(callSuper = false)
  22 +@SuperBuilder
  23 +public class OrderProfitQueryVO extends BasePageVO implements Serializable {
  24 + private static final long serialVersionUID = -84816007994858993L;
  25 +
  26 + private List<Long> ids;
  27 +
  28 + private Set<Long> orderIds;
  29 +
  30 +
  31 + private Long id;
  32 +
  33 + /**
  34 + * 生成开始时间
  35 + */
  36 + private String createStartTime;
  37 +
  38 + /**
  39 + * 生成结束时间
  40 + */
  41 + private String createEndTime;
  42 +
  43 + /**
  44 + * 单据状态
  45 + */
  46 + private List<String> orderStatus;
  47 +
  48 + /**
  49 + * 提交人名称
  50 + */
  51 + private String commitUserName;
  52 +
  53 + /**
  54 + * 提交人手机号码
  55 + */
  56 + private String commitUserPhone;
  57 +
  58 + /**
  59 + * 项目号
  60 + */
  61 + private List<String> projectNo;
  62 +
  63 + /**
  64 + * 客户编码集合
  65 + */
  66 + private List<String> customerCode;
  67 +
  68 + /**
  69 + * 客户STYLE#
  70 + */
  71 + private List<String> customerStyle;
  72 +
  73 + /**
  74 + * 内部编号
  75 + */
  76 + private List<String> innerNo;
  77 +
  78 + /**
  79 + * 生产科
  80 + */
  81 + private List<String> productionDepartment;
  82 +
  83 + /**
  84 + * 生成科拖货开始时间
  85 + */
  86 + private String productionDepartmentConsignStartTime;
  87 +
  88 + /**
  89 + * 生成科拖货结束时间
  90 + */
  91 + private String productionDepartmentConsignEndTime;
  92 +
  93 + /**
  94 + * 订单上HOD开始时间
  95 + */
  96 + private String orderHodStartTime;
  97 +
  98 + /**
  99 + * 订单上HOD结束时间
  100 + */
  101 + private String orderHodEndTime;
  102 +
  103 + /**
  104 + * 最小利润率
  105 + */
  106 + private Double profitRateLqt;
  107 +
  108 + /**
  109 + * 最大利润率
  110 + */
  111 + private Double profitRateGqt;
  112 +
  113 + /**
  114 + * 想法来源
  115 + */
  116 + private List<String> ideaSource;
  117 +
  118 + /**
  119 + * 想法来源占比
  120 + */
  121 + private Double ideaSourceRate;
  122 +
  123 + /**
  124 + * 设计师
  125 + */
  126 + private String designer;
  127 +
  128 + /**
  129 + * 手工初型1
  130 + */
  131 + private List<String> manualPreform1;
  132 +
  133 + /**
  134 + * 手工初型1占比
  135 + */
  136 + private Double manualPreform1Rate;
  137 +
  138 + /**
  139 + * 手工初型2
  140 + */
  141 + private List<String> manualPreform2;
  142 +
  143 + /**
  144 + * 手工初型2占比
  145 + */
  146 + private Double manualPreform2Rate;
  147 +
  148 + /**
  149 + * pp样品确认意见
  150 + */
  151 + private List<String> ppConfirmResult;
  152 +
  153 + /**
  154 + * 自测通过开始时间
  155 + */
  156 + private String selfTestPassStartTime;
  157 +
  158 + /**
  159 + * 自测通过结束时间
  160 + */
  161 + private String selfTestPassEndTime;
  162 +
  163 + /**
  164 + * 中期验货结果PASS / FAIL
  165 + */
  166 + private List<String> midCheckResult;
  167 +
  168 + /**
  169 + * 尾期验货结果PASS / FAIL
  170 + */
  171 + private List<String> endCheckResult;
  172 +
  173 + /**
  174 + * 选择的字段
  175 + */
  176 + private OrderLockFieldVO fieldVO;
  177 +
  178 + /**
  179 + * 创建人
  180 + */
  181 + private String createBy;
  182 +
  183 + /**
  184 + * 业务员
  185 + */
  186 + private List<String> businessPerson;
  187 +
  188 +
  189 + private List<Long> exportOrderIds;
  190 +
  191 + /**
  192 + * invoice 首页筛选invoice。
  193 + */
  194 + private List<String> invoiceNo;
  195 +
  196 + /**
  197 + * checkNo 首页筛选Check。
  198 + */
  199 + private List<String> CheckNo;
  200 + /**
  201 + * invoice invoice状态。
  202 + */
  203 + private Long invoiceStatus;
  204 + /**
  205 + * checkNo checkNo状态。
  206 + */
  207 + private Long checkNoStatus;
  208 +}
  209 +
src/main/java/com/order/erp/domain/vo/order/ProjectApplyVO.java 0 → 100644
  1 +package com.order.erp.domain.vo.order;
  2 +
  3 +import com.baomidou.mybatisplus.annotation.IdType;
  4 +import com.baomidou.mybatisplus.annotation.TableId;
  5 +import com.baomidou.mybatisplus.annotation.TableName;
  6 +import com.order.erp.domain.dto.BaseDO;
  7 +import io.swagger.annotations.ApiModel;
  8 +import io.swagger.annotations.ApiModelProperty;
  9 +import lombok.AllArgsConstructor;
  10 +import lombok.Data;
  11 +import lombok.EqualsAndHashCode;
  12 +import lombok.NoArgsConstructor;
  13 +import lombok.experimental.SuperBuilder;
  14 +
  15 +import java.io.Serializable;
  16 +
  17 +/**
  18 + * <p>
  19 + * 项目-字段锁定申请表
  20 + * </p>
  21 + *
  22 + * @author author
  23 + * @since 2024-12-22
  24 + */
  25 +@Data
  26 +@EqualsAndHashCode(callSuper = false)
  27 +@SuperBuilder
  28 +@AllArgsConstructor
  29 +@NoArgsConstructor
  30 +@TableName("project_apply")
  31 +@ApiModel(value="ProjectApply对象", description="项目-字段锁定申请表")
  32 +public class ProjectApplyVO extends BaseDO implements Serializable {
  33 +
  34 + private static final long serialVersionUID = 1L;
  35 +
  36 + @TableId(value = "id", type = IdType.AUTO)
  37 + private Long id;
  38 +
  39 + @ApiModelProperty(value = "项目id")
  40 + private Long projectId;
  41 +
  42 + @ApiModelProperty(value = "项目号")
  43 + private String projectNoPrefix;
  44 +
  45 + @ApiModelProperty(value = "申请用户id")
  46 + private Long applyUserId;
  47 +
  48 + @ApiModelProperty(value = "审批用户id")
  49 + private Long auditUserId;
  50 +
  51 + @ApiModelProperty(value = "锁定字段 json字符串")
  52 + private String fields;
  53 +
  54 + @ApiModelProperty(value = "状态:0 待审批,1 通过,2 拒绝")
  55 + private Integer status;
  56 +
  57 + @ApiModelProperty(value = "审核备注")
  58 + private String auditRemark;
  59 +
  60 + @ApiModelProperty(value = "审批角色code集合,分割")
  61 + private String auditRoleCodes;
  62 +
  63 + @ApiModelProperty(value = "申请原因")
  64 + private String applyRemark;
  65 +
  66 +
  67 +}
src/main/java/com/order/erp/domain/vo/order/ProjectBaseInfoLockFieldVO.java 0 → 100644
  1 +package com.order.erp.domain.vo.order;
  2 +
  3 +import com.baomidou.mybatisplus.annotation.IdType;
  4 +import com.baomidou.mybatisplus.annotation.TableId;
  5 +import com.baomidou.mybatisplus.annotation.TableName;
  6 +import com.order.erp.domain.dto.BaseDO;
  7 +import io.swagger.annotations.ApiModel;
  8 +import io.swagger.annotations.ApiModelProperty;
  9 +import lombok.Data;
  10 +import lombok.EqualsAndHashCode;
  11 +import lombok.experimental.Accessors;
  12 +
  13 +import java.io.Serializable;
  14 +import java.math.BigDecimal;
  15 +import java.time.LocalDateTime;
  16 +
  17 +/**
  18 + * <p>
  19 + * 项目-字段锁定申请表
  20 + * </p>
  21 + *
  22 + * @author author
  23 + * @since 2024-12-22
  24 + */
  25 +@Data
  26 +@EqualsAndHashCode(callSuper = false)
  27 +@Accessors(chain = true)
  28 +@ApiModel(value="ProjectFieldLockApply对象", description="项目-字段锁定申请表")
  29 +public class ProjectBaseInfoLockFieldVO implements Serializable {
  30 +
  31 +
  32 + private Long projectId;
  33 +
  34 + private String projectNoPrefix;
  35 +
  36 + private String developmentCopyRmbTotalPrice;
  37 +
  38 + private String projectStartTime;
  39 +
  40 + private String projectEndTime;
  41 +
  42 +
  43 + private String spainPaidRmbCommission;
  44 +
  45 + private String paidRmbCommission;
  46 +
  47 + private String actualExchangeRate;
  48 +
  49 +
  50 +}
src/main/java/com/order/erp/domain/vo/order/ProjectBaseInfoVO.java 0 → 100644
  1 +package com.order.erp.domain.vo.order;
  2 +
  3 +import com.baomidou.mybatisplus.annotation.IdType;
  4 +import com.baomidou.mybatisplus.annotation.TableId;
  5 +import com.baomidou.mybatisplus.annotation.TableName;
  6 +import io.swagger.annotations.ApiModel;
  7 +import lombok.Data;
  8 +import lombok.EqualsAndHashCode;
  9 +import lombok.experimental.Accessors;
  10 +
  11 +import java.io.Serializable;
  12 +import java.math.BigDecimal;
  13 +import java.time.LocalDateTime;
  14 +
  15 +/**
  16 + * <p>
  17 + *
  18 + * </p>
  19 + *
  20 + * @author author
  21 + * @since 2024-12-18
  22 + */
  23 +@Data
  24 +@EqualsAndHashCode(callSuper = false)
  25 +@Accessors(chain = true)
  26 +@TableName("project_base_info")
  27 +@ApiModel(value="ProjectBaseInfoDO", description="")
  28 +public class ProjectBaseInfoVO implements Serializable {
  29 +
  30 + private static final long serialVersionUID = 1L;
  31 +
  32 + @TableId(value = "id", type = IdType.AUTO)
  33 + private Long id;
  34 +
  35 + private String projectNoPrefix;
  36 +
  37 + private BigDecimal developmentCopyRmbTotalPrice;
  38 +
  39 + private LocalDateTime projectStartTime;
  40 +
  41 + private LocalDateTime projectEndTime;
  42 +
  43 +
  44 + private BigDecimal spainPaidRmbCommission;
  45 +
  46 + private BigDecimal paidRmbCommission;
  47 +
  48 + private BigDecimal actualExchangeRate;
  49 +
  50 +
  51 +}
src/main/java/com/order/erp/domain/vo/order/QueryProjectLockFieldVO.java 0 → 100644
  1 +package com.order.erp.domain.vo.order;
  2 +
  3 +import com.baomidou.mybatisplus.annotation.TableName;
  4 +import com.order.erp.domain.vo.BasePageVO;
  5 +import io.swagger.annotations.ApiModel;
  6 +import lombok.AllArgsConstructor;
  7 +import lombok.Data;
  8 +import lombok.EqualsAndHashCode;
  9 +import lombok.NoArgsConstructor;
  10 +import lombok.experimental.SuperBuilder;
  11 +
  12 +import java.io.Serializable;
  13 +
  14 +/**
  15 + * <p>
  16 + *
  17 + * </p>
  18 + *
  19 + * @author author
  20 + * @since 2024-12-22
  21 + */
  22 +@Data
  23 +@EqualsAndHashCode(callSuper = false)
  24 +@SuperBuilder
  25 +@AllArgsConstructor
  26 +@NoArgsConstructor
  27 +@TableName("order_cost_info")
  28 +@ApiModel(value="OrderCostDetail对象", description="")
  29 +public class QueryProjectLockFieldVO extends BasePageVO implements Serializable {
  30 +
  31 + private static final long serialVersionUID = 1L;
  32 +
  33 + private Long orderId;
  34 +
  35 + private String productionDepartmentPredictPrice;
  36 +
  37 + private String productionActualPrice;
  38 +
  39 + private String packetActualRmbTotalPrice;
  40 +
  41 +
  42 +}
src/main/java/com/order/erp/mapper/OrderCostFieldLockRecordMapper.java 0 → 100644
  1 +package com.order.erp.mapper;
  2 +
  3 +import com.order.erp.domain.model.OrderCostFieldLockRecord;
  4 +import com.baomidou.mybatisplus.core.mapper.BaseMapper;
  5 +
  6 +/**
  7 + * <p>
  8 + * Mapper 接口
  9 + * </p>
  10 + *
  11 + * @author author
  12 + * @since 2024-12-22
  13 + */
  14 +public interface OrderCostFieldLockRecordMapper extends BaseMapper<OrderCostFieldLockRecord> {
  15 +
  16 +}
src/main/java/com/order/erp/mapper/ProjectApplyMapper.java 0 → 100644
  1 +package com.order.erp.mapper;
  2 +
  3 +import com.order.erp.domain.model.ProjectApplyDO;
  4 +import com.baomidou.mybatisplus.core.mapper.BaseMapper;
  5 +
  6 +/**
  7 + * <p>
  8 + * 项目-字段锁定申请表 Mapper 接口
  9 + * </p>
  10 + *
  11 + * @author author
  12 + * @since 2024-12-22
  13 + */
  14 +public interface ProjectApplyMapper extends BaseMapper<ProjectApplyDO> {
  15 +
  16 +}
src/main/java/com/order/erp/mapper/ProjectFieldLockRecordMapper.java 0 → 100644
  1 +package com.order.erp.mapper;
  2 +
  3 +import com.order.erp.domain.model.ProjectFieldLockRecord;
  4 +import com.baomidou.mybatisplus.core.mapper.BaseMapper;
  5 +
  6 +/**
  7 + * <p>
  8 + * 项目-字段锁定记录表 Mapper 接口
  9 + * </p>
  10 + *
  11 + * @author author
  12 + * @since 2024-12-22
  13 + */
  14 +public interface ProjectFieldLockRecordMapper extends BaseMapper<ProjectFieldLockRecord> {
  15 +
  16 +}
src/main/java/com/order/erp/mapper/order/OrderCostInfoMapper.java 0 → 100644
  1 +package com.order.erp.mapper.order;
  2 +
  3 +import com.order.erp.domain.dto.order.OrderCostInfoDO;
  4 +import com.baomidou.mybatisplus.core.mapper.BaseMapper;
  5 +
  6 +/**
  7 + * <p>
  8 + * Mapper 接口
  9 + * </p>
  10 + *
  11 + * @author author
  12 + * @since 2024-12-22
  13 + */
  14 +public interface OrderCostInfoMapper extends BaseMapper<OrderCostInfoDO> {
  15 +
  16 +}
src/main/java/com/order/erp/mapper/order/ProjectBaseInfoMapper.java 0 → 100644
  1 +package com.order.erp.mapper.order;
  2 +
  3 +import com.order.erp.domain.dto.order.ProjectBaseInfoDO;
  4 +import com.baomidou.mybatisplus.core.mapper.BaseMapper;
  5 +
  6 +/**
  7 + * <p>
  8 + * Mapper 接口
  9 + * </p>
  10 + *
  11 + * @author author
  12 + * @since 2024-12-18
  13 + */
  14 +public interface ProjectBaseInfoMapper extends BaseMapper<ProjectBaseInfoDO> {
  15 +
  16 +}
src/main/java/com/order/erp/service/IOrderCostFieldLockRecordService.java 0 → 100644
  1 +package com.order.erp.service;
  2 +
  3 +import com.order.erp.domain.model.OrderCostFieldLockRecord;
  4 +import com.baomidou.mybatisplus.extension.service.IService;
  5 +
  6 +/**
  7 + * <p>
  8 + * 服务类
  9 + * </p>
  10 + *
  11 + * @author author
  12 + * @since 2024-12-22
  13 + */
  14 +public interface IOrderCostFieldLockRecordService extends IService<OrderCostFieldLockRecord> {
  15 +
  16 +}
src/main/java/com/order/erp/service/IProjectApplyService.java 0 → 100644
  1 +package com.order.erp.service;
  2 +
  3 +import com.order.erp.domain.model.ProjectApplyDO;
  4 +import com.baomidou.mybatisplus.extension.service.IService;
  5 +
  6 +/**
  7 + * <p>
  8 + * 项目-字段锁定申请表 服务类
  9 + * </p>
  10 + *
  11 + * @author author
  12 + * @since 2024-12-22
  13 + */
  14 +public interface IProjectApplyService extends IService<ProjectApplyDO> {
  15 +
  16 +}
src/main/java/com/order/erp/service/IProjectFieldLockRecordService.java 0 → 100644
  1 +package com.order.erp.service;
  2 +
  3 +import com.order.erp.domain.model.ProjectFieldLockRecord;
  4 +import com.baomidou.mybatisplus.extension.service.IService;
  5 +
  6 +/**
  7 + * <p>
  8 + * 项目-字段锁定记录表 服务类
  9 + * </p>
  10 + *
  11 + * @author author
  12 + * @since 2024-12-22
  13 + */
  14 +public interface IProjectFieldLockRecordService extends IService<ProjectFieldLockRecord> {
  15 +
  16 +}
src/main/java/com/order/erp/service/SystemSettingService.java
@@ -6,6 +6,8 @@ import com.order.erp.domain.dto.SystemSettingDO; @@ -6,6 +6,8 @@ import com.order.erp.domain.dto.SystemSettingDO;
6 import com.order.erp.domain.vo.SystemSettingQueryVO; 6 import com.order.erp.domain.vo.SystemSettingQueryVO;
7 import com.order.erp.domain.vo.SystemSettingVO; 7 import com.order.erp.domain.vo.SystemSettingVO;
8 8
  9 +import java.math.BigDecimal;
  10 +
9 /** 11 /**
10 * 系统配置(SystemSetting)表服务接口 12 * 系统配置(SystemSetting)表服务接口
11 * 13 *
@@ -37,6 +39,8 @@ public interface SystemSettingService extends IService&lt;SystemSettingDO&gt; { @@ -37,6 +39,8 @@ public interface SystemSettingService extends IService&lt;SystemSettingDO&gt; {
37 */ 39 */
38 ServerResult listByPage(SystemSettingQueryVO systemSettingQueryVO); 40 ServerResult listByPage(SystemSettingQueryVO systemSettingQueryVO);
39 41
  42 + BigDecimal getExchangeRate();
  43 +
40 /** 44 /**
41 * 新增数据 45 * 新增数据
42 * 46 *
src/main/java/com/order/erp/service/impl/OrderCostFieldLockRecordServiceImpl.java 0 → 100644
  1 +package com.order.erp.service.impl;
  2 +
  3 +import com.order.erp.domain.model.OrderCostFieldLockRecord;
  4 +import com.order.erp.mapper.OrderCostFieldLockRecordMapper;
  5 +import com.order.erp.service.IOrderCostFieldLockRecordService;
  6 +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
  7 +import org.springframework.stereotype.Service;
  8 +
  9 +/**
  10 + * <p>
  11 + * 服务实现类
  12 + * </p>
  13 + *
  14 + * @author author
  15 + * @since 2024-12-22
  16 + */
  17 +@Service
  18 +public class OrderCostFieldLockRecordServiceImpl extends ServiceImpl<OrderCostFieldLockRecordMapper, OrderCostFieldLockRecord> implements IOrderCostFieldLockRecordService {
  19 +
  20 +}
src/main/java/com/order/erp/service/impl/ProjectApplyServiceImpl.java 0 → 100644
  1 +package com.order.erp.service.impl;
  2 +
  3 +import com.order.erp.domain.model.ProjectApplyDO;
  4 +import com.order.erp.mapper.ProjectApplyMapper;
  5 +import com.order.erp.service.IProjectApplyService;
  6 +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
  7 +import org.springframework.stereotype.Service;
  8 +
  9 +/**
  10 + * <p>
  11 + * 项目-字段锁定申请表 服务实现类
  12 + * </p>
  13 + *
  14 + * @author author
  15 + * @since 2024-12-22
  16 + */
  17 +@Service
  18 +public class ProjectApplyServiceImpl extends ServiceImpl<ProjectApplyMapper, ProjectApplyDO> implements IProjectApplyService {
  19 +
  20 +}
src/main/java/com/order/erp/service/impl/ProjectFieldLockRecordServiceImpl.java 0 → 100644
  1 +package com.order.erp.service.impl;
  2 +
  3 +import com.order.erp.domain.model.ProjectFieldLockRecord;
  4 +import com.order.erp.mapper.ProjectFieldLockRecordMapper;
  5 +import com.order.erp.service.IProjectFieldLockRecordService;
  6 +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
  7 +import org.springframework.stereotype.Service;
  8 +
  9 +/**
  10 + * <p>
  11 + * 项目-字段锁定记录表 服务实现类
  12 + * </p>
  13 + *
  14 + * @author author
  15 + * @since 2024-12-22
  16 + */
  17 +@Service
  18 +public class ProjectFieldLockRecordServiceImpl extends ServiceImpl<ProjectFieldLockRecordMapper, ProjectFieldLockRecord> implements IProjectFieldLockRecordService {
  19 +
  20 +}
src/main/java/com/order/erp/service/impl/SystemSettingServiceImpl.java
@@ -24,7 +24,9 @@ import com.order.erp.service.SystemSettingService; @@ -24,7 +24,9 @@ import com.order.erp.service.SystemSettingService;
24 import lombok.extern.slf4j.Slf4j; 24 import lombok.extern.slf4j.Slf4j;
25 import org.springframework.beans.BeanUtils; 25 import org.springframework.beans.BeanUtils;
26 import org.springframework.stereotype.Service; 26 import org.springframework.stereotype.Service;
  27 +import springfox.documentation.annotations.Cacheable;
27 28
  29 +import java.math.BigDecimal;
28 import java.util.List; 30 import java.util.List;
29 import java.util.Objects; 31 import java.util.Objects;
30 import java.util.stream.Collectors; 32 import java.util.stream.Collectors;
@@ -110,6 +112,15 @@ public class SystemSettingServiceImpl extends ServiceImpl&lt;SystemSettingMapper, S @@ -110,6 +112,15 @@ public class SystemSettingServiceImpl extends ServiceImpl&lt;SystemSettingMapper, S
110 .eq(StringUtils.isNotBlank(queryVO.getRelationCode()), SystemSettingDO::getRelationCode, queryVO.getRelationCode()); 112 .eq(StringUtils.isNotBlank(queryVO.getRelationCode()), SystemSettingDO::getRelationCode, queryVO.getRelationCode());
111 } 113 }
112 114
  115 + @Override
  116 + public BigDecimal getExchangeRate(){
  117 + SystemSettingDO exchangeRate = this.lambdaQuery()
  118 + .eq(BaseDO::getEnableFlag, Constant.ENABLE_TEN)
  119 + .eq(SystemSettingDO::getSettingCode, "exchangeRate")
  120 + .one();
  121 + return BigDecimal.valueOf(Double.parseDouble(exchangeRate.getSettingValue()));
  122 + }
  123 +
113 124
114 /** 125 /**
115 * 新增数据 126 * 新增数据
src/main/java/com/order/erp/service/order/IOrderCostInfoService.java 0 → 100644
  1 +package com.order.erp.service.order;
  2 +
  3 +import com.order.erp.common.constant.ServerResult;
  4 +import com.order.erp.domain.dto.order.OrderCostInfoDO;
  5 +import com.baomidou.mybatisplus.extension.service.IService;
  6 +import com.order.erp.domain.vo.order.OrderBaseInfoQueryVO;
  7 +import com.order.erp.domain.vo.order.OrderCostInfoVO;
  8 +import com.order.erp.domain.vo.order.OrderCostInfolockFieldVO;
  9 +
  10 +/**
  11 + * <p>
  12 + * 服务类
  13 + * </p>
  14 + *
  15 + * @author author
  16 + * @since 2024-12-22
  17 + */
  18 +public interface IOrderCostInfoService extends IService<OrderCostInfoDO> {
  19 +
  20 + ServerResult edit(OrderCostInfoVO vo);
  21 +
  22 + ServerResult applyEditFileds(OrderCostInfolockFieldVO vo);
  23 +
  24 + ServerResult listInnerProfitDetailByPage(OrderBaseInfoQueryVO queryVO);
  25 +
  26 + ServerResult listBusinessProfitDetailByPage(OrderBaseInfoQueryVO queryVO);
  27 +}
src/main/java/com/order/erp/service/order/IProjectBaseInfoService.java 0 → 100644
  1 +package com.order.erp.service.order;
  2 +
  3 +import com.order.erp.common.constant.ServerResult;
  4 +import com.order.erp.domain.dto.order.ProjectBaseInfoDO;
  5 +import com.baomidou.mybatisplus.extension.service.IService;
  6 +import com.order.erp.domain.vo.order.*;
  7 +
  8 +import javax.servlet.http.HttpServletResponse;
  9 +
  10 +/**
  11 + * <p>
  12 + * 服务类
  13 + * </p>
  14 + *
  15 + * @author author
  16 + * @since 2024-12-18
  17 + */
  18 +public interface IProjectBaseInfoService extends IService<ProjectBaseInfoDO> {
  19 +
  20 + ServerResult edit(ProjectBaseInfoVO vo);
  21 +
  22 + ServerResult applyEditFileds(ProjectBaseInfoLockFieldVO vo);
  23 +
  24 + ServerResult pageProjectLockFieldApply(QueryProjectLockFieldVO vo);
  25 +
  26 + ServerResult audit(AuditVO vo);
  27 +
  28 + ServerResult listInnerProfitInfoByPage(OrderBaseInfoQueryVO queryVO);
  29 +
  30 + ServerResult listBusinessProfitInfoByPage(OrderBaseInfoQueryVO queryVO);
  31 +
  32 + void exportBusinessProfitInfo(HttpServletResponse response, String projectNoPrefix) throws Exception;
  33 +
  34 + void exportInnerProfitInfo(HttpServletResponse response, String projectNoPrefix) throws Exception;
  35 +}
src/main/java/com/order/erp/service/order/OrderProfitAnalysisService.java
@@ -4,10 +4,9 @@ import com.baomidou.mybatisplus.extension.service.IService; @@ -4,10 +4,9 @@ import com.baomidou.mybatisplus.extension.service.IService;
4 import com.order.erp.common.constant.ServerResult; 4 import com.order.erp.common.constant.ServerResult;
5 import com.order.erp.domain.dto.order.OrderProfitAnalysisDO; 5 import com.order.erp.domain.dto.order.OrderProfitAnalysisDO;
6 import com.order.erp.domain.vo.OrderProfitAnalysisVo; 6 import com.order.erp.domain.vo.OrderProfitAnalysisVo;
7 -import com.order.erp.domain.vo.order.OrderProfitAnalysisQueryVO;  
8 -import com.order.erp.domain.vo.order.OrderProfitAnalysisVO;  
9 -import com.order.erp.domain.vo.order.ProfitCalculateVO; 7 +import com.order.erp.domain.vo.order.*;
10 8
  9 +import javax.servlet.http.HttpServletResponse;
11 import java.util.List; 10 import java.util.List;
12 11
13 /** 12 /**
src/main/java/com/order/erp/service/order/impl/CalculateProfitServiceImpl.java
@@ -67,6 +67,10 @@ public class CalculateProfitServiceImpl { @@ -67,6 +67,10 @@ public class CalculateProfitServiceImpl {
67 */ 67 */
68 public ServerResult businessProfitRatioExport(HttpServletResponse response, BusinessProfitRatioQueryVO queryVO) throws IOException { 68 public ServerResult businessProfitRatioExport(HttpServletResponse response, BusinessProfitRatioQueryVO queryVO) throws IOException {
69 BusinessProfitRatioResultVO resultVO = buildBusinessProfitRatioResultVO(queryVO); 69 BusinessProfitRatioResultVO resultVO = buildBusinessProfitRatioResultVO(queryVO);
  70 + return writeBusinessProfitRatioResult(response, resultVO);
  71 + }
  72 +
  73 + private ServerResult<Object> writeBusinessProfitRatioResult(HttpServletResponse response, BusinessProfitRatioResultVO resultVO) throws IOException {
70 //开始 74 //开始
71 Workbook workbook = new XSSFWorkbook(); 75 Workbook workbook = new XSSFWorkbook();
72 Sheet sheet = workbook.createSheet("业务净利润分析表"); 76 Sheet sheet = workbook.createSheet("业务净利润分析表");
@@ -90,7 +94,7 @@ public class CalculateProfitServiceImpl { @@ -90,7 +94,7 @@ public class CalculateProfitServiceImpl {
90 94
91 // 第二行 95 // 第二行
92 createMergedCell(sheet, workbook, 4, 0, 4, 5, 0, 1, "项目号"); 96 createMergedCell(sheet, workbook, 4, 0, 4, 5, 0, 1, "项目号");
93 - createMergedCell(sheet, workbook, 4, 2, 4, 5, 2, 4, String.join(",",resultVO.getProjectNo())); 97 + createMergedCell(sheet, workbook, 4, 2, 4, 5, 2, 4, String.join(",", resultVO.getProjectNo()));
94 createMergedCell(sheet, workbook, 4, 5, 4, 5, 5, 6, "开始时间"); 98 createMergedCell(sheet, workbook, 4, 5, 4, 5, 5, 6, "开始时间");
95 createMergedCell(sheet, workbook, 4, 7, 4, 5, 7, 9, "结束时间"); 99 createMergedCell(sheet, workbook, 4, 7, 4, 5, 7, 9, "结束时间");
96 // 第三行 100 // 第三行
@@ -111,55 +115,55 @@ public class CalculateProfitServiceImpl { @@ -111,55 +115,55 @@ public class CalculateProfitServiceImpl {
111 createMergedCell(sheet, workbook, 10, 7, 10, 11, 7, 9, "备注"); 115 createMergedCell(sheet, workbook, 10, 7, 10, 11, 7, 9, "备注");
112 //第六行 116 //第六行
113 createMergedCell(sheet, workbook, 12, 0, 12, 13, 0, 4, "客户总金额计算"); 117 createMergedCell(sheet, workbook, 12, 0, 12, 13, 0, 4, "客户总金额计算");
114 - createMergedCell(sheet, workbook, 12, 5, 12, 13, 5, 6, "¥"+resultVO.getCustomerTotalPrice());  
115 - createMergedCell(sheet, workbook, 12, 7, 12, 13, 7, 9, "$"+resultVO.getCustomerTotalPriceUsd()); 118 + createMergedCell(sheet, workbook, 12, 5, 12, 13, 5, 6, "¥"+ resultVO.getCustomerTotalPrice());
  119 + createMergedCell(sheet, workbook, 12, 7, 12, 13, 7, 9, "$"+ resultVO.getCustomerTotalPriceUsd());
116 ////第七行 120 ////第七行
117 createMergedCell(sheet, workbook, 14, 0, 14, 15, 0, 4, "生产科总价合计"); 121 createMergedCell(sheet, workbook, 14, 0, 14, 15, 0, 4, "生产科总价合计");
118 - createMergedCell(sheet, workbook, 14, 5, 14, 15, 5, 6, "¥"+resultVO.getProductionDepartmentTotalPrice());  
119 - createMergedCell(sheet, workbook, 14, 7, 14, 15, 7, 9, "$"+resultVO.getProductionDepartmentTotalPriceUsd()); 122 + createMergedCell(sheet, workbook, 14, 5, 14, 15, 5, 6, "¥"+ resultVO.getProductionDepartmentTotalPrice());
  123 + createMergedCell(sheet, workbook, 14, 7, 14, 15, 7, 9, "$"+ resultVO.getProductionDepartmentTotalPriceUsd());
120 ////第八行 124 ////第八行
121 createMergedCell(sheet, workbook, 16, 0, 16, 17, 0, 4, "包装费用合计"); 125 createMergedCell(sheet, workbook, 16, 0, 16, 17, 0, 4, "包装费用合计");
122 - createMergedCell(sheet, workbook, 16, 5, 16, 17, 5, 6, "¥"+resultVO.getPacketTotalPrice());  
123 - createMergedCell(sheet, workbook, 16, 7, 16, 17, 7, 9, "$"+resultVO.getPacketTotalPriceUsd()); 126 + createMergedCell(sheet, workbook, 16, 5, 16, 17, 5, 6, "¥"+ resultVO.getPacketTotalPrice());
  127 + createMergedCell(sheet, workbook, 16, 7, 16, 17, 7, 9, "$"+ resultVO.getPacketTotalPriceUsd());
124 ////第九行 128 ////第九行
125 createMergedCell(sheet, workbook, 18, 0, 18, 19, 0, 4, "研发开发费合计"); 129 createMergedCell(sheet, workbook, 18, 0, 18, 19, 0, 4, "研发开发费合计");
126 - createMergedCell(sheet, workbook, 18, 5, 18, 19, 5, 6, "¥"+resultVO.getDevelopTotalPrice().setScale(2, RoundingMode.HALF_UP)); 130 + createMergedCell(sheet, workbook, 18, 5, 18, 19, 5, 6, "¥"+ resultVO.getDevelopTotalPrice().setScale(2, RoundingMode.HALF_UP));
127 createMergedCell(sheet, workbook, 18, 7, 18, 19, 7, 9, ""); 131 createMergedCell(sheet, workbook, 18, 7, 18, 19, 7, 9, "");
128 ////第十行 132 ////第十行
129 createMergedCell(sheet, workbook, 20, 0, 20, 21, 0, 4, "复制费用合计"); 133 createMergedCell(sheet, workbook, 20, 0, 20, 21, 0, 4, "复制费用合计");
130 - createMergedCell(sheet, workbook, 20, 5, 20, 21, 5, 6, "¥"+resultVO.getCopyTotalPrice().setScale(2, RoundingMode.HALF_UP)); 134 + createMergedCell(sheet, workbook, 20, 5, 20, 21, 5, 6, "¥"+ resultVO.getCopyTotalPrice().setScale(2, RoundingMode.HALF_UP));
131 createMergedCell(sheet, workbook, 20, 7, 20, 21, 7, 9, ""); 135 createMergedCell(sheet, workbook, 20, 7, 20, 21, 7, 9, "");
132 //第十一行 136 //第十一行
133 createMergedCell(sheet, workbook, 22, 0, 22, 23, 0, 4, "固定成本"); 137 createMergedCell(sheet, workbook, 22, 0, 22, 23, 0, 4, "固定成本");
134 - createMergedCell(sheet, workbook, 22, 5, 22, 23, 5, 6, "¥"+resultVO.getFixCost()); 138 + createMergedCell(sheet, workbook, 22, 5, 22, 23, 5, 6, "¥"+ resultVO.getFixCost());
135 createMergedCell(sheet, workbook, 22, 7, 22, 23, 7, 9, ""); 139 createMergedCell(sheet, workbook, 22, 7, 22, 23, 7, 9, "");
136 //第十二行 140 //第十二行
137 createMergedCell(sheet, workbook, 24, 0, 24, 25, 0, 4, "西班牙提成"); 141 createMergedCell(sheet, workbook, 24, 0, 24, 25, 0, 4, "西班牙提成");
138 - createMergedCell(sheet, workbook, 24, 5, 24, 25, 5, 6, "¥"+resultVO.getSpainRatioProfitPrice()); 142 + createMergedCell(sheet, workbook, 24, 5, 24, 25, 5, 6, "¥"+ resultVO.getSpainRatioProfitPrice());
139 createMergedCell(sheet, workbook, 24, 7, 24, 25, 7, 9, ""); 143 createMergedCell(sheet, workbook, 24, 7, 24, 25, 7, 9, "");
140 //第十三行 144 //第十三行
141 createMergedCell(sheet, workbook, 26, 0, 26, 27, 0, 4, "中国团队提成"); 145 createMergedCell(sheet, workbook, 26, 0, 26, 27, 0, 4, "中国团队提成");
142 - createMergedCell(sheet, workbook, 26, 5, 26, 27, 5, 6, "¥"+resultVO.getChinaRatioProfitPrice()); 146 + createMergedCell(sheet, workbook, 26, 5, 26, 27, 5, 6, "¥"+ resultVO.getChinaRatioProfitPrice());
143 createMergedCell(sheet, workbook, 26, 7, 26, 27, 7, 9, ""); 147 createMergedCell(sheet, workbook, 26, 7, 26, 27, 7, 9, "");
144 - //第十四行 148 + //第十四行
145 createMergedCell(sheet, workbook, 28, 0, 28, 29, 0, 4, "支出合计"); 149 createMergedCell(sheet, workbook, 28, 0, 28, 29, 0, 4, "支出合计");
146 - createMergedCell(sheet, workbook, 28, 5, 28, 29, 5, 6, "¥"+resultVO.getOutTotalPrice()); 150 + createMergedCell(sheet, workbook, 28, 5, 28, 29, 5, 6, "¥"+ resultVO.getOutTotalPrice());
147 createMergedCell(sheet, workbook, 28, 7, 28, 29, 7, 9, ""); 151 createMergedCell(sheet, workbook, 28, 7, 28, 29, 7, 9, "");
148 //第十五行 152 //第十五行
149 createMergedCell(sheet, workbook, 30, 0, 30, 31, 0, 4, "毛利润"); 153 createMergedCell(sheet, workbook, 30, 0, 30, 31, 0, 4, "毛利润");
150 - createMergedCell(sheet, workbook, 30, 5, 30, 31, 5, 6, "¥"+resultVO.getGrossProfit()); 154 + createMergedCell(sheet, workbook, 30, 5, 30, 31, 5, 6, "¥"+ resultVO.getGrossProfit());
151 createMergedCell(sheet, workbook, 30, 7, 30, 31, 7, 9, ""); 155 createMergedCell(sheet, workbook, 30, 7, 30, 31, 7, 9, "");
152 ////第十六行 156 ////第十六行
153 createMergedCell(sheet, workbook, 32, 0, 32, 33, 0, 4, "研发贸易净利润"); 157 createMergedCell(sheet, workbook, 32, 0, 32, 33, 0, 4, "研发贸易净利润");
154 - createMergedCell(sheet, workbook, 32, 5, 32, 33, 5, 6, "¥"+resultVO.getDevelopProfit()); 158 + createMergedCell(sheet, workbook, 32, 5, 32, 33, 5, 6, "¥"+ resultVO.getDevelopProfit());
155 createMergedCell(sheet, workbook, 32, 7, 32, 33, 7, 9, ""); 159 createMergedCell(sheet, workbook, 32, 7, 32, 33, 7, 9, "");
156 ////第十七行 160 ////第十七行
157 createMergedCell(sheet, workbook, 34, 0, 34, 35, 0, 4, "包装费用合计金额"); 161 createMergedCell(sheet, workbook, 34, 0, 34, 35, 0, 4, "包装费用合计金额");
158 - createMergedCell(sheet, workbook, 34, 5, 34, 35, 5, 6, "¥"+resultVO.getPacketTotalPrice()); 162 + createMergedCell(sheet, workbook, 34, 5, 34, 35, 5, 6, "¥"+ resultVO.getPacketTotalPrice());
159 createMergedCell(sheet, workbook, 34, 7, 34, 35, 7, 9, ""); 163 createMergedCell(sheet, workbook, 34, 7, 34, 35, 7, 9, "");
160 ////第十八行 164 ////第十八行
161 createMergedCell(sheet, workbook, 36, 0, 36, 37, 0, 4, "包装费用实际金额"); 165 createMergedCell(sheet, workbook, 36, 0, 36, 37, 0, 4, "包装费用实际金额");
162 - createMergedCell(sheet, workbook, 36, 5, 36, 37, 5, 6, "¥"+resultVO.getPacketActualTotalPrice().setScale(2, RoundingMode.HALF_UP)); 166 + createMergedCell(sheet, workbook, 36, 5, 36, 37, 5, 6, "¥"+ resultVO.getPacketActualTotalPrice().setScale(2, RoundingMode.HALF_UP));
163 createMergedCell(sheet, workbook, 36, 7, 36, 37, 7, 9, ""); 167 createMergedCell(sheet, workbook, 36, 7, 36, 37, 7, 9, "");
164 ////第十九行 168 ////第十九行
165 createMergedCell(sheet, workbook, 38, 0, 38, 39, 0, 4, "订单总数量"); 169 createMergedCell(sheet, workbook, 38, 0, 38, 39, 0, 4, "订单总数量");
@@ -167,27 +171,27 @@ public class CalculateProfitServiceImpl { @@ -167,27 +171,27 @@ public class CalculateProfitServiceImpl {
167 createMergedCell(sheet, workbook, 38, 7, 38, 39, 7, 9, ""); 171 createMergedCell(sheet, workbook, 38, 7, 38, 39, 7, 9, "");
168 ////第二十行 172 ////第二十行
169 createMergedCell(sheet, workbook, 40, 0, 40, 41, 0, 4, "实际跟单单价=实际跟单费用/件数"); 173 createMergedCell(sheet, workbook, 40, 0, 40, 41, 0, 4, "实际跟单单价=实际跟单费用/件数");
170 - createMergedCell(sheet, workbook, 40, 5, 40, 41, 5, 6, "¥"+resultVO.getActualRmbPrice()); 174 + createMergedCell(sheet, workbook, 40, 5, 40, 41, 5, 6, "¥"+ resultVO.getActualRmbPrice());
171 createMergedCell(sheet, workbook, 40, 7, 40, 41, 7, 9, ""); 175 createMergedCell(sheet, workbook, 40, 7, 40, 41, 7, 9, "");
172 //第二十一行 176 //第二十一行
173 createMergedCell(sheet, workbook, 42, 0, 42, 43, 0, 4, "实际跟单单价折算美金"); 177 createMergedCell(sheet, workbook, 42, 0, 42, 43, 0, 4, "实际跟单单价折算美金");
174 - createMergedCell(sheet, workbook, 42, 5, 42, 43, 5, 6, "$"+resultVO.getActualPrice()); 178 + createMergedCell(sheet, workbook, 42, 5, 42, 43, 5, 6, "$"+ resultVO.getActualPrice());
175 createMergedCell(sheet, workbook, 42, 7, 42, 43, 7, 9, ""); 179 createMergedCell(sheet, workbook, 42, 7, 42, 43, 7, 9, "");
176 //第二十二行 180 //第二十二行
177 createMergedCell(sheet, workbook, 44, 0, 44, 45, 0, 4, "包装费用收益"); 181 createMergedCell(sheet, workbook, 44, 0, 44, 45, 0, 4, "包装费用收益");
178 - createMergedCell(sheet, workbook, 44, 5, 44, 45, 5, 6, "¥"+resultVO.getPacketProfitPrice()); 182 + createMergedCell(sheet, workbook, 44, 5, 44, 45, 5, 6, "¥"+ resultVO.getPacketProfitPrice());
179 createMergedCell(sheet, workbook, 44, 7, 44, 45, 7, 9, ""); 183 createMergedCell(sheet, workbook, 44, 7, 44, 45, 7, 9, "");
180 //第二十三行 184 //第二十三行
181 createMergedCell(sheet, workbook, 46, 0, 46, 47, 0, 4, "实际汇率"); 185 createMergedCell(sheet, workbook, 46, 0, 46, 47, 0, 4, "实际汇率");
182 - createMergedCell(sheet, workbook, 46, 5, 46, 47, 5, 6, "¥"+resultVO.getActualRatio().setScale(2, RoundingMode.HALF_UP)); 186 + createMergedCell(sheet, workbook, 46, 5, 46, 47, 5, 6, "¥"+ resultVO.getActualRatio().setScale(2, RoundingMode.HALF_UP));
183 createMergedCell(sheet, workbook, 46, 7, 46, 47, 7, 9, ""); 187 createMergedCell(sheet, workbook, 46, 7, 46, 47, 7, 9, "");
184 //第二十四行 188 //第二十四行
185 createMergedCell(sheet, workbook, 48, 0, 48, 49, 0, 4, "汇率收益"); 189 createMergedCell(sheet, workbook, 48, 0, 48, 49, 0, 4, "汇率收益");
186 - createMergedCell(sheet, workbook, 48, 5, 48, 49, 5, 6, "¥"+resultVO.getActualRatioProfitPrice()); 190 + createMergedCell(sheet, workbook, 48, 5, 48, 49, 5, 6, "¥"+ resultVO.getActualRatioProfitPrice());
187 createMergedCell(sheet, workbook, 48, 7, 48, 49, 7, 9, ""); 191 createMergedCell(sheet, workbook, 48, 7, 48, 49, 7, 9, "");
188 //第二十五行 192 //第二十五行
189 createMergedCell(sheet, workbook, 50, 0, 50, 51, 0, 4, "综合收益"); 193 createMergedCell(sheet, workbook, 50, 0, 50, 51, 0, 4, "综合收益");
190 - createMergedCell(sheet, workbook, 50, 5, 50, 51, 5, 6, "¥"+resultVO.getTotalProfitPrice()); 194 + createMergedCell(sheet, workbook, 50, 5, 50, 51, 5, 6, "¥"+ resultVO.getTotalProfitPrice());
191 createMergedCell(sheet, workbook, 50, 7, 50, 51, 7, 9, ""); 195 createMergedCell(sheet, workbook, 50, 7, 50, 51, 7, 9, "");
192 response.setHeader("Content-Disposition", "attachment; filename=\"-.xlsx\""); 196 response.setHeader("Content-Disposition", "attachment; filename=\"-.xlsx\"");
193 workbook.write(response.getOutputStream()); 197 workbook.write(response.getOutputStream());
@@ -203,6 +207,10 @@ public class CalculateProfitServiceImpl { @@ -203,6 +207,10 @@ public class CalculateProfitServiceImpl {
203 */ 207 */
204 public ServerResult innerProfitRatioExport(HttpServletResponse response,InnerProfitRatioQueryVO queryVO) throws IOException { 208 public ServerResult innerProfitRatioExport(HttpServletResponse response,InnerProfitRatioQueryVO queryVO) throws IOException {
205 InnerProfitRatioResultVO resultVO = buildInnerProfitRatioResultVO(queryVO); 209 InnerProfitRatioResultVO resultVO = buildInnerProfitRatioResultVO(queryVO);
  210 + return writeInnerProfitRatioData(response, resultVO);
  211 + }
  212 +
  213 + private ServerResult<Object> writeInnerProfitRatioData(HttpServletResponse response, InnerProfitRatioResultVO resultVO) throws IOException {
206 Workbook workbook = new XSSFWorkbook(); 214 Workbook workbook = new XSSFWorkbook();
207 Sheet sheet = workbook.createSheet("内部生产净利润分析表"); 215 Sheet sheet = workbook.createSheet("内部生产净利润分析表");
208 Row row = sheet.createRow(0); 216 Row row = sheet.createRow(0);
@@ -270,7 +278,7 @@ public class CalculateProfitServiceImpl { @@ -270,7 +278,7 @@ public class CalculateProfitServiceImpl {
270 createMergedCell(sheet, workbook, 20, 4, 20, 21, 4, 5, "¥"+ resultVO.getInnerProduceTotalPrice()); 278 createMergedCell(sheet, workbook, 20, 4, 20, 21, 4, 5, "¥"+ resultVO.getInnerProduceTotalPrice());
271 createMergedCell(sheet, workbook, 20, 6, 20, 21, 6, 7, ""); 279 createMergedCell(sheet, workbook, 20, 6, 20, 21, 6, 7, "");
272 createMergedCell(sheet, workbook, 20, 8, 20, 21, 8, 10, ""); 280 createMergedCell(sheet, workbook, 20, 8, 20, 21, 8, 10, "");
273 - //第十一行 281 + //第十一行
274 createMergedCell(sheet, workbook, 22, 0, 22, 23, 0, 3, "内部生产净利润"); 282 createMergedCell(sheet, workbook, 22, 0, 22, 23, 0, 3, "内部生产净利润");
275 createMergedCell(sheet, workbook, 22, 4, 22, 23, 4, 5, "¥"+ resultVO.getInnerProduceTotalProfit()); 283 createMergedCell(sheet, workbook, 22, 4, 22, 23, 4, 5, "¥"+ resultVO.getInnerProduceTotalProfit());
276 createMergedCell(sheet, workbook, 22, 6, 22, 23, 6, 7, ""); 284 createMergedCell(sheet, workbook, 22, 6, 22, 23, 6, 7, "");
@@ -281,6 +289,7 @@ public class CalculateProfitServiceImpl { @@ -281,6 +289,7 @@ public class CalculateProfitServiceImpl {
281 workbook.close(); 289 workbook.close();
282 return ServerResult.success(); 290 return ServerResult.success();
283 } 291 }
  292 +
284 public void createMergedCell(Sheet sheet, Workbook workbook, int rowIndex, int colIndex, int startRow, int endRow, int startCol, int endCol, String value) { 293 public void createMergedCell(Sheet sheet, Workbook workbook, int rowIndex, int colIndex, int startRow, int endRow, int startCol, int endCol, String value) {
285 // 创建或获取当前行 294 // 创建或获取当前行
286 Row row = sheet.getRow(rowIndex); 295 Row row = sheet.getRow(rowIndex);
src/main/java/com/order/erp/service/order/impl/OrderBaseInfoServiceImpl.java
@@ -31,22 +31,19 @@ import com.order.erp.domain.dto.admin.AdminUserRoleDO; @@ -31,22 +31,19 @@ import com.order.erp.domain.dto.admin.AdminUserRoleDO;
31 import com.order.erp.domain.dto.order.*; 31 import com.order.erp.domain.dto.order.*;
32 import com.order.erp.domain.vo.ProducePdfVO; 32 import com.order.erp.domain.vo.ProducePdfVO;
33 import com.order.erp.domain.vo.order.*; 33 import com.order.erp.domain.vo.order.*;
34 -import com.order.erp.job.OrderOverTimeEventJob;  
35 import com.order.erp.mapper.order.OrderBaseInfoMapper; 34 import com.order.erp.mapper.order.OrderBaseInfoMapper;
36 import com.order.erp.service.SystemSettingService; 35 import com.order.erp.service.SystemSettingService;
37 import com.order.erp.service.admin.AdminUserRoleService; 36 import com.order.erp.service.admin.AdminUserRoleService;
38 import com.order.erp.service.admin.AdminUserService; 37 import com.order.erp.service.admin.AdminUserService;
39 import com.order.erp.service.order.*; 38 import com.order.erp.service.order.*;
40 -import freemarker.template.TemplateException;  
41 import lombok.extern.slf4j.Slf4j; 39 import lombok.extern.slf4j.Slf4j;
42 -import org.joda.time.DateTime;  
43 import org.springframework.beans.BeanUtils; 40 import org.springframework.beans.BeanUtils;
  41 +import org.springframework.beans.factory.annotation.Autowired;
44 import org.springframework.beans.factory.annotation.Value; 42 import org.springframework.beans.factory.annotation.Value;
45 import org.springframework.stereotype.Service; 43 import org.springframework.stereotype.Service;
46 import org.springframework.transaction.annotation.Transactional; 44 import org.springframework.transaction.annotation.Transactional;
47 45
48 import javax.annotation.Resource; 46 import javax.annotation.Resource;
49 -import javax.mail.MessagingException;  
50 import javax.servlet.http.HttpServletResponse; 47 import javax.servlet.http.HttpServletResponse;
51 import java.io.File; 48 import java.io.File;
52 import java.io.IOException; 49 import java.io.IOException;
@@ -56,7 +53,6 @@ import java.math.RoundingMode; @@ -56,7 +53,6 @@ import java.math.RoundingMode;
56 import java.net.URL; 53 import java.net.URL;
57 import java.text.DecimalFormat; 54 import java.text.DecimalFormat;
58 import java.time.LocalDate; 55 import java.time.LocalDate;
59 -import java.time.LocalDateTime;  
60 import java.time.Month; 56 import java.time.Month;
61 import java.util.*; 57 import java.util.*;
62 import java.util.concurrent.TimeUnit; 58 import java.util.concurrent.TimeUnit;
@@ -146,6 +142,8 @@ public class OrderBaseInfoServiceImpl extends ServiceImpl&lt;OrderBaseInfoMapper, O @@ -146,6 +142,8 @@ public class OrderBaseInfoServiceImpl extends ServiceImpl&lt;OrderBaseInfoMapper, O
146 142
147 @Resource 143 @Resource
148 private ProducePaymentCheckBillOrderService producePaymentCheckBillOrderService; 144 private ProducePaymentCheckBillOrderService producePaymentCheckBillOrderService;
  145 + @Autowired
  146 + private IOrderCostInfoService orderCostInfoService;
149 147
150 148
151 149
@@ -232,6 +230,8 @@ public class OrderBaseInfoServiceImpl extends ServiceImpl&lt;OrderBaseInfoMapper, O @@ -232,6 +230,8 @@ public class OrderBaseInfoServiceImpl extends ServiceImpl&lt;OrderBaseInfoMapper, O
232 230
233 // 填充发票信息 231 // 填充发票信息
234 fillInvoiceNo(resultVOList); 232 fillInvoiceNo(resultVOList);
  233 +
  234 + fillOrderCostDetils(resultVOList);
235 //第四版 start 235 //第四版 start
236 /* //需要填充生产科对账单号信息 236 /* //需要填充生产科对账单号信息
237 fillCheckNo(resultVOList); 237 fillCheckNo(resultVOList);
@@ -252,6 +252,29 @@ public class OrderBaseInfoServiceImpl extends ServiceImpl&lt;OrderBaseInfoMapper, O @@ -252,6 +252,29 @@ public class OrderBaseInfoServiceImpl extends ServiceImpl&lt;OrderBaseInfoMapper, O
252 return resultVOList; 252 return resultVOList;
253 } 253 }
254 254
  255 + private void fillOrderCostDetils(List<OrderInfoResultVO> resultVOList) {
  256 + if (CollectionUtils.isEmpty(resultVOList)) {
  257 + return;
  258 + }
  259 +
  260 + Set<Long> orderIds = resultVOList.stream().map(OrderInfoResultVO::getId).collect(Collectors.toSet());
  261 + List<OrderCostInfoDO> orderCostInfoDOS = orderCostInfoService.lambdaQuery()
  262 + .eq(BaseDO::getEnableFlag, Constant.ENABLE_TEN)
  263 + .in(OrderCostInfoDO::getOrderId, orderIds)
  264 + .list();
  265 +
  266 + if (CollectionUtils.isNotEmpty(orderCostInfoDOS)) {
  267 + Map<Long, OrderCostInfoDO> orderCostDetailDOMap = orderCostInfoDOS.stream().collect(Collectors.toMap(OrderCostInfoDO::getOrderId, Function.identity(), (v1, v2) -> v1));
  268 + resultVOList.forEach(result -> {
  269 + if (orderCostDetailDOMap.containsKey(result.getId())) {
  270 + OrderCostInfoDO orderCostInfoDO = orderCostDetailDOMap.get(result.getId());
  271 + OrderCostInfoVO orderCostInfoVO = BeanUtil.copyProperties(orderCostInfoDO, OrderCostInfoVO.class);
  272 + result.setOrderCostInfo(orderCostInfoVO);
  273 + }
  274 + });
  275 + }
  276 + }
  277 +
255 @Override 278 @Override
256 public void export(HttpServletResponse response, OrderBaseInfoQueryVO queryVO) throws IOException, Excel4JException { 279 public void export(HttpServletResponse response, OrderBaseInfoQueryVO queryVO) throws IOException, Excel4JException {
257 OrderLockFieldVO lockFieldVO = queryVO.getFieldVO(); 280 OrderLockFieldVO lockFieldVO = queryVO.getFieldVO();
@@ -1502,6 +1525,8 @@ end @@ -1502,6 +1525,8 @@ end
1502 .in(CollectionUtils.isNotEmpty(queryVO.getCheckNo()),OrderBaseInfoDO::getCheckNo,queryVO.getCheckNo()) 1525 .in(CollectionUtils.isNotEmpty(queryVO.getCheckNo()),OrderBaseInfoDO::getCheckNo,queryVO.getCheckNo())
1503 .eq(Objects.nonNull(queryVO.getInvoiceStatus()), OrderBaseInfoDO::getInvoiceStatus, queryVO.getInvoiceStatus()) 1526 .eq(Objects.nonNull(queryVO.getInvoiceStatus()), OrderBaseInfoDO::getInvoiceStatus, queryVO.getInvoiceStatus())
1504 .eq(Objects.nonNull(queryVO.getCheckNoStatus()), OrderBaseInfoDO::getCheckStatus, queryVO.getCheckNoStatus()) 1527 .eq(Objects.nonNull(queryVO.getCheckNoStatus()), OrderBaseInfoDO::getCheckStatus, queryVO.getCheckNoStatus())
  1528 + .in(CollUtil.isNotEmpty(queryVO.getIds()), OrderBaseInfoDO::getId, queryVO.getIds())
  1529 + .likeRight(StringUtils.isNotBlank(queryVO.getProjectNoLikeRight()), OrderBaseInfoDO::getProjectNo, queryVO.getProjectNoLikeRight())
1505 .orderByDesc(OrderBaseInfoDO::getId) 1530 .orderByDesc(OrderBaseInfoDO::getId)
1506 ; 1531 ;
1507 } 1532 }
src/main/java/com/order/erp/service/order/impl/OrderCostInfoServiceImpl.java 0 → 100644
  1 +package com.order.erp.service.order.impl;
  2 +
  3 +import cn.hutool.core.bean.BeanUtil;
  4 +import cn.hutool.core.collection.CollUtil;
  5 +import com.alibaba.fastjson.JSONObject;
  6 +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
  7 +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
  8 +import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
  9 +import com.fasterxml.jackson.core.JsonProcessingException;
  10 +import com.fasterxml.jackson.databind.ObjectMapper;
  11 +import com.order.erp.common.constant.Constant;
  12 +import com.order.erp.common.constant.ServerResult;
  13 +import com.order.erp.common.constant.ServerResultCode;
  14 +import com.order.erp.common.exception.BusinessException;
  15 +import com.order.erp.config.DataScope;
  16 +import com.order.erp.domain.ApplyStatusEnum;
  17 +import com.order.erp.domain.ApplyTypeEnum;
  18 +import com.order.erp.domain.ProjectApplyTypeEnum;
  19 +import com.order.erp.domain.dto.BaseDO;
  20 +import com.order.erp.domain.dto.order.OrderCostInfoDO;
  21 +import com.order.erp.domain.dto.order.OrderFieldLockApplyDO;
  22 +import com.order.erp.domain.model.OrderCostFieldLockRecord;
  23 +import com.order.erp.domain.vo.order.*;
  24 +import com.order.erp.mapper.order.OrderCostInfoMapper;
  25 +import com.order.erp.service.IOrderCostFieldLockRecordService;
  26 +import com.order.erp.service.order.IOrderCostInfoService;
  27 +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
  28 +import com.order.erp.service.order.OrderBaseInfoService;
  29 +import com.order.erp.service.order.OrderFieldLockApplyService;
  30 +import com.order.erp.service.order.OrderFieldLockRecordService;
  31 +import org.springframework.beans.BeanUtils;
  32 +import org.springframework.beans.factory.annotation.Autowired;
  33 +import org.springframework.stereotype.Service;
  34 +
  35 +import javax.annotation.Resource;
  36 +import java.math.BigDecimal;
  37 +import java.math.RoundingMode;
  38 +import java.util.List;
  39 +import java.util.Map;
  40 +import java.util.Objects;
  41 +import java.util.Set;
  42 +import java.util.stream.Collectors;
  43 +
  44 +/**
  45 + * <p>
  46 + * 服务实现类
  47 + * </p>
  48 + *
  49 + * @author author
  50 + * @since 2024-12-22
  51 + */
  52 +@Service
  53 +public class OrderCostInfoServiceImpl extends ServiceImpl<OrderCostInfoMapper, OrderCostInfoDO> implements IOrderCostInfoService {
  54 + @Autowired
  55 + private DataScope dataScope;
  56 + @Resource
  57 + private OrderFieldLockRecordService orderFieldLockRecordService;
  58 + @Resource
  59 + private OrderFieldLockApplyService orderFieldLockApplyService;
  60 + @Autowired
  61 + private OrderBaseInfoService orderBaseInfoService;
  62 + @Autowired
  63 + private IOrderCostFieldLockRecordService orderCostFieldLockRecordService;
  64 +
  65 + @Override
  66 + public ServerResult edit(OrderCostInfoVO vo) {
  67 + Long id = vo.getId();
  68 + OrderCostInfoDO byId = this.getById(id);
  69 + if (Objects.isNull(byId)) {
  70 + byId = BeanUtil.copyProperties(vo, OrderCostInfoDO.class);
  71 + }else {
  72 + BeanUtil.copyProperties(vo, byId);
  73 + }
  74 + return ServerResult.success(this.saveOrUpdate(byId));
  75 + }
  76 + @Override
  77 + public ServerResult applyEditFileds(OrderCostInfolockFieldVO vo) {
  78 + List<OrderFieldLockApplyDO> applyDOS = orderFieldLockApplyService.list(new LambdaQueryWrapper<OrderFieldLockApplyDO>()
  79 + .eq(BaseDO::getEnableFlag, Constant.ENABLE_TEN)
  80 + .eq(OrderFieldLockApplyDO::getOrderId, vo.getOrderId())
  81 + .eq(OrderFieldLockApplyDO::getApplyUserId, dataScope.getLoginUserId())
  82 + .eq(OrderFieldLockApplyDO::getType, ProjectApplyTypeEnum.FIELD_EDIT_APPLY.getType())
  83 + .eq(OrderFieldLockApplyDO::getStatus, ApplyStatusEnum.WAIT_AUDIT.getStatus()));
  84 + if (CollectionUtils.isNotEmpty(applyDOS)) {
  85 + throw new BusinessException(ServerResultCode.APPLY_UNLOCK_FIELD_EXIST);
  86 + }
  87 + Long orderId = vo.getOrderId();
  88 + vo.setOrderId(null);
  89 + OrderFieldLockApplyDO build = OrderFieldLockApplyDO.builder()
  90 + .orderId(orderId)
  91 + .applyUserId(dataScope.getLoginUserId())
  92 + .fields(JSONObject.toJSONString(vo))
  93 + .status(ApplyStatusEnum.WAIT_AUDIT.getStatus())
  94 + .type(ApplyTypeEnum.ORDER_COST_FIELD_EDIT_APPLY.getType())
  95 + .remark(ApplyTypeEnum.ORDER_COST_FIELD_EDIT_APPLY.getDesc())
  96 + .build();
  97 + orderFieldLockApplyService.save(build);
  98 + return ServerResult.success();
  99 + }
  100 +
  101 + @Override
  102 + public ServerResult<Page<InnerProfitDetailVO>> listInnerProfitDetailByPage(OrderBaseInfoQueryVO queryVO) {
  103 + ServerResult serverResult = orderBaseInfoService.listByPage(queryVO);
  104 + Page<OrderInfoResultVO> page = (Page<OrderInfoResultVO>) serverResult.getData();
  105 + List<OrderInfoResultVO> records = page.getRecords();
  106 + List<OrderCostFieldLockRecord> lockRecords = orderCostFieldLockRecordService
  107 + .lambdaQuery()
  108 + .func(query -> {
  109 + Set<Long> collect = records.stream().map(OrderInfoResultVO::getId).collect(Collectors.toSet());
  110 + if(CollUtil.isNotEmpty(collect)){
  111 + query.in(OrderCostFieldLockRecord::getOrderId,collect);
  112 +
  113 + }else {
  114 + query.apply("1!=1");
  115 + }
  116 + })
  117 + .list();
  118 + ObjectMapper objectMapper = new ObjectMapper();
  119 + Map<Long,OrderCostInfolockFieldVO> orderId2fieldMapMap = lockRecords.stream().collect(Collectors.toMap(OrderCostFieldLockRecord::getOrderId, record -> {
  120 + try {
  121 + return objectMapper.readValue(record.getFields(), OrderCostInfolockFieldVO.class);
  122 + } catch (JsonProcessingException e) {
  123 + throw new RuntimeException(e);
  124 + }
  125 + }));
  126 + List<InnerProfitDetailVO> innerProfitRatioResultVOs = records.stream().map(record -> {
  127 + InnerProfitDetailVO vo = InnerProfitDetailVO.builder()
  128 + .customerCode(record.getCustomerCode())
  129 + .projectNo(record.getProjectNo())
  130 + .productionDepartment(record.getProductionDepartment())
  131 + .innerNo(record.getInnerNo())
  132 + .picUrl(record.getPicUrl())
  133 + .orderCount(record.getOrderCount())
  134 + .productionDepartmentPrice(Objects.isNull(record.getProfitAnalysisInfo()) ? null : record.getProfitAnalysisInfo().getProductionDepartmentPrice())
  135 + .productionDepartmentTotalPrice(Objects.isNull(record.getProfitAnalysisInfo()) ? null : record.getProfitAnalysisInfo().getProductionDepartmentTotalPrice())
  136 + .productionDepartmentPredictPrice(Objects.isNull(record.getOrderCostInfo()) ? null : record.getOrderCostInfo().getProductionDepartmentPredictPrice())
  137 + .productionActualPrice(Objects.isNull(record.getOrderCostInfo()) ? null : record.getOrderCostInfo().getProductionActualPrice())
  138 + .build();
  139 +
  140 + if (Objects.nonNull(vo.getProductionDepartmentPredictPrice())
  141 + && Objects.nonNull(vo.getProductionActualPrice())
  142 + && vo.getProductionDepartmentPredictPrice().compareTo(BigDecimal.ZERO) != 0) {
  143 + //预算占比=实际发生费用/预算金额
  144 + vo.setPredictRatio(vo.getProductionActualPrice().divide(vo.getProductionDepartmentPredictPrice(), 4, RoundingMode.HALF_UP));
  145 + //预算占比与实际比占比差:1-预算占比
  146 + vo.setPredictAndActualRatio(new BigDecimal(1).subtract(vo.getPredictRatio()));
  147 + }
  148 + if (Objects.nonNull(vo.getProductionDepartmentTotalPrice())
  149 + && Objects.nonNull(vo.getProductionDepartmentPredictPrice())) {
  150 + //事前毛利润=生产总额-预算金额
  151 + vo.setBeforeGrossProfit(BigDecimal.valueOf(vo.getProductionDepartmentTotalPrice()).subtract(vo.getProductionDepartmentPredictPrice()));
  152 + if (Objects.nonNull(vo.getProductionDepartmentTotalPrice())
  153 + && vo.getProductionDepartmentTotalPrice().compareTo(0.0) != 0) {
  154 + //事前毛利润率=事前毛利润/生产总额
  155 + vo.setBeforeGrossProfitRate(vo.getBeforeGrossProfit().divide(BigDecimal.valueOf(vo.getProductionDepartmentTotalPrice()), 4, RoundingMode.HALF_UP));
  156 + }
  157 + }
  158 + if (Objects.nonNull(vo.getProductionDepartmentTotalPrice())
  159 + && Objects.nonNull(vo.getProductionActualPrice())) {
  160 + //事后毛利润=实际发生费用-生产总额
  161 + vo.setGrossProfit(BigDecimal.valueOf(vo.getProductionDepartmentTotalPrice()).subtract(vo.getProductionActualPrice()));
  162 + if (Objects.nonNull(vo.getProductionDepartmentTotalPrice())
  163 + && vo.getProductionDepartmentTotalPrice().compareTo(0.0) != 0) {
  164 + //事后毛利润率=事后毛利润/生产总额
  165 + vo.setGrossProfitRate(vo.getGrossProfit().divide(BigDecimal.valueOf(vo.getProductionDepartmentTotalPrice()), 4, RoundingMode.HALF_UP));
  166 + }
  167 + }
  168 + return vo;
  169 + }).collect(Collectors.toList());
  170 + Page<InnerProfitDetailVO> webVOPage = new Page<>();
  171 + webVOPage.setRecords(innerProfitRatioResultVOs);
  172 + BeanUtils.copyProperties(page, webVOPage, "records");
  173 + return ServerResult.success(webVOPage);
  174 + }
  175 +
  176 +
  177 + @Override
  178 + public ServerResult<Page<BusinessProfitDetailVO>> listBusinessProfitDetailByPage(OrderBaseInfoQueryVO queryVO) {
  179 + ServerResult serverResult = orderBaseInfoService.listByPage(queryVO);
  180 + Page<OrderInfoResultVO> page = (Page<OrderInfoResultVO>) serverResult.getData();
  181 + List<OrderInfoResultVO> records = page.getRecords();
  182 + List<OrderCostFieldLockRecord> lockRecords = orderCostFieldLockRecordService
  183 + .lambdaQuery()
  184 + .func(query -> {
  185 + Set<Long> collect = records.stream().map(OrderInfoResultVO::getId).collect(Collectors.toSet());
  186 + if(CollUtil.isNotEmpty(collect)){
  187 + query.in(OrderCostFieldLockRecord::getOrderId,collect);
  188 +
  189 + }else {
  190 + query.apply("1!=1");
  191 + }
  192 + })
  193 + .list();
  194 + ObjectMapper objectMapper = new ObjectMapper();
  195 + Map<Long,OrderCostInfolockFieldVO> orderId2fieldMapMap = lockRecords.stream().collect(Collectors.toMap(OrderCostFieldLockRecord::getOrderId,record -> {
  196 + try {
  197 + return objectMapper.readValue(record.getFields(), OrderCostInfolockFieldVO.class);
  198 + } catch (JsonProcessingException e) {
  199 + throw new RuntimeException(e);
  200 + }
  201 + }));
  202 + List<BusinessProfitDetailVO> innerProfitRatioResultVOs = records.stream().map(record -> {
  203 + BusinessProfitDetailVO vo = BusinessProfitDetailVO.builder()
  204 + .customerCode(record.getCustomerCode())
  205 + .projectNo(record.getProjectNo())
  206 + .productionDepartment(record.getProductionDepartment())
  207 + .innerNo(record.getInnerNo())
  208 + .picUrl(record.getPicUrl())
  209 + .orderCount(record.getOrderCount())
  210 + .packetPrice(Objects.isNull(record.getProfitAnalysisInfo()) ? null : record.getProfitAnalysisInfo().getPacketPrice())
  211 + .packetTotalPrice(Objects.isNull(record.getProfitAnalysisInfo()) ? null : record.getProfitAnalysisInfo().getPacketTotalPrice())
  212 + .packetActualRmbTotalPrice(Objects.isNull(record.getOrderCostInfo()) ? null : record.getOrderCostInfo().getPacketActualRmbTotalPrice())
  213 + .lockFields(orderId2fieldMapMap.get(record.getId()))
  214 + .build();
  215 + if (Objects.nonNull(vo.getPacketTotalPrice())) {
  216 + //包装费用合计 = 包装费合计*汇率
  217 + vo.setPacketRmbTotalPrice(BigDecimal.valueOf(vo.getPacketTotalPrice()).multiply((new BigDecimal("6.2")).setScale(4, RoundingMode.HALF_UP)).doubleValue());
  218 + }
  219 + if (Objects.nonNull(vo.getPacketActualRmbTotalPrice()) && Objects.nonNull(vo.getOrderCount())) {
  220 + //实际跟单单价 = 包装费用实际金额/数量
  221 + vo.setPacketActualRmbPrice(vo.getPacketActualRmbTotalPrice().divide(BigDecimal.valueOf(vo.getOrderCount()), 4, RoundingMode.HALF_UP));
  222 + //实际跟单单价折算美金$ = 人民币单价/汇率
  223 + vo.setPacketActualPrice(vo.getPacketActualRmbPrice().divide(new BigDecimal("6.2"), 4, RoundingMode.HALF_UP));
  224 + }
  225 + if (Objects.nonNull(vo.getPacketRmbTotalPrice()) && Objects.nonNull(vo.getPacketActualRmbPrice())) {
  226 + //包装费用收益¥ = 包装费用合计-包装费用实际金额
  227 + vo.setPacketProfitRmbPrice(BigDecimal.valueOf(vo.getPacketRmbTotalPrice()).subtract(vo.getPacketActualRmbTotalPrice()));
  228 + }
  229 + if (Objects.nonNull(vo.getPacketProfitRmbPrice()) && Objects.nonNull(vo.getPacketRmbTotalPrice())) {
  230 + //包装费用净利润率 = 包装费用收益/包装费用合计
  231 + vo.setPacketProfitRate(vo.getPacketProfitRmbPrice().divide(BigDecimal.valueOf(vo.getPacketRmbTotalPrice()), 4, RoundingMode.HALF_UP));
  232 + }
  233 + return vo;
  234 + }).collect(Collectors.toList());
  235 + Page<BusinessProfitDetailVO> webVOPage = new Page<>();
  236 + webVOPage.setRecords(innerProfitRatioResultVOs);
  237 + BeanUtils.copyProperties(page, webVOPage, "records");
  238 + return ServerResult.success(webVOPage);
  239 + }
  240 +
  241 +}
src/main/java/com/order/erp/service/order/impl/OrderFieldLockApplyServiceImpl.java
@@ -20,11 +20,14 @@ import com.order.erp.config.DataScope; @@ -20,11 +20,14 @@ import com.order.erp.config.DataScope;
20 import com.order.erp.domain.*; 20 import com.order.erp.domain.*;
21 import com.order.erp.domain.dto.BaseDO; 21 import com.order.erp.domain.dto.BaseDO;
22 import com.order.erp.domain.dto.order.*; 22 import com.order.erp.domain.dto.order.*;
  23 +import com.order.erp.domain.model.OrderCostFieldLockRecord;
23 import com.order.erp.domain.vo.order.*; 24 import com.order.erp.domain.vo.order.*;
24 import com.order.erp.mapper.order.OrderFieldLockApplyMapper; 25 import com.order.erp.mapper.order.OrderFieldLockApplyMapper;
  26 +import com.order.erp.service.IOrderCostFieldLockRecordService;
25 import com.order.erp.service.order.*; 27 import com.order.erp.service.order.*;
26 import lombok.extern.slf4j.Slf4j; 28 import lombok.extern.slf4j.Slf4j;
27 import org.springframework.beans.BeanUtils; 29 import org.springframework.beans.BeanUtils;
  30 +import org.springframework.beans.factory.annotation.Autowired;
28 import org.springframework.stereotype.Service; 31 import org.springframework.stereotype.Service;
29 import org.springframework.transaction.annotation.Transactional; 32 import org.springframework.transaction.annotation.Transactional;
30 33
@@ -49,6 +52,9 @@ public class OrderFieldLockApplyServiceImpl extends ServiceImpl&lt;OrderFieldLockAp @@ -49,6 +52,9 @@ public class OrderFieldLockApplyServiceImpl extends ServiceImpl&lt;OrderFieldLockAp
49 @Resource 52 @Resource
50 private OrderFieldLockRecordService fieldLockRecordService; 53 private OrderFieldLockRecordService fieldLockRecordService;
51 54
  55 + @Autowired
  56 + private IOrderCostFieldLockRecordService orderCostFieldLockRecordService;
  57 +
52 @Resource 58 @Resource
53 private OrderFieldLockApplyService applyService; 59 private OrderFieldLockApplyService applyService;
54 60
@@ -126,6 +132,10 @@ public class OrderFieldLockApplyServiceImpl extends ServiceImpl&lt;OrderFieldLockAp @@ -126,6 +132,10 @@ public class OrderFieldLockApplyServiceImpl extends ServiceImpl&lt;OrderFieldLockAp
126 if (ApplyTypeEnum.FIELD_EDIT_APPLY.getType() .equals(x.getType())) { 132 if (ApplyTypeEnum.FIELD_EDIT_APPLY.getType() .equals(x.getType())) {
127 resultVO.setFieldInfos(JSONObject.parseObject(fields, OrderLockFieldVO.class)); 133 resultVO.setFieldInfos(JSONObject.parseObject(fields, OrderLockFieldVO.class));
128 } 134 }
  135 + if(ApplyTypeEnum.ORDER_COST_FIELD_EDIT_APPLY.getType().equals(x.getType())){
  136 + OrderCostInfolockFieldVO orderCostInfolockFieldVO = JSONObject.parseObject(fields, OrderCostInfolockFieldVO.class);
  137 + resultVO.setFieldInfos(OrderLockFieldVO.builder().costInfolockFieldVO(orderCostInfolockFieldVO).build());
  138 + }
129 if (ApplyTypeEnum.ORDER_REPORT_APPLY.getType().equals(x.getType())) { 139 if (ApplyTypeEnum.ORDER_REPORT_APPLY.getType().equals(x.getType())) {
130 OrderLockFieldVO fieldVO = new OrderLockFieldVO(); 140 OrderLockFieldVO fieldVO = new OrderLockFieldVO();
131 fieldVO.setReportFields(JSONObject.parseObject(fields, OrderCompletionReportFieldVO.class)); 141 fieldVO.setReportFields(JSONObject.parseObject(fields, OrderCompletionReportFieldVO.class));
@@ -190,7 +200,7 @@ public class OrderFieldLockApplyServiceImpl extends ServiceImpl&lt;OrderFieldLockAp @@ -190,7 +200,7 @@ public class OrderFieldLockApplyServiceImpl extends ServiceImpl&lt;OrderFieldLockAp
190 } 200 }
191 } 201 }
192 return resultVO; 202 return resultVO;
193 - }).filter(result->result!=null).collect(Collectors.toList()); 203 + }).filter(Objects::nonNull).collect(Collectors.toList());
194 if (resultVOList != null && resultVOList.stream().noneMatch(x -> ApplyTypeEnum.INVOICE_BILL_APPLY.getType().equals(x.getType()) 204 if (resultVOList != null && resultVOList.stream().noneMatch(x -> ApplyTypeEnum.INVOICE_BILL_APPLY.getType().equals(x.getType())
195 || ApplyTypeEnum.DEPARTMENT_INVOICE_APPLY.getType().equals(x.getType()) 205 || ApplyTypeEnum.DEPARTMENT_INVOICE_APPLY.getType().equals(x.getType())
196 || ApplyTypeEnum.CHECK_BILL_APPLY.getType().equals(x.getType()))) { 206 || ApplyTypeEnum.CHECK_BILL_APPLY.getType().equals(x.getType()))) {
@@ -374,7 +384,7 @@ public class OrderFieldLockApplyServiceImpl extends ServiceImpl&lt;OrderFieldLockAp @@ -374,7 +384,7 @@ public class OrderFieldLockApplyServiceImpl extends ServiceImpl&lt;OrderFieldLockAp
374 } 384 }
375 Set<Long> orderIds = new HashSet<>(); 385 Set<Long> orderIds = new HashSet<>();
376 //由于下面是原始的代码,怕改出错了,所以我只对我需要的需求进行判断,我只针对我需要的这种情况,其他情况下就不走这种情况。 限制情况为跟单业务,对应收款,应付款,发票审核请求时。 386 //由于下面是原始的代码,怕改出错了,所以我只对我需要的需求进行判断,我只针对我需要的这种情况,其他情况下就不走这种情况。 限制情况为跟单业务,对应收款,应付款,发票审核请求时。
377 - if(queryVO.getType()==Constant.THIRTY || queryVO.getType()==4050){ 387 + if(Constant.THIRTY.equals(queryVO.getType()) ||Integer.valueOf(4050).equals(queryVO.getType())){
378 388
379 }else{ 389 }else{
380 /** 这部分代码是之前的,每台看懂,就先不修改了,保留*/ 390 /** 这部分代码是之前的,每台看懂,就先不修改了,保留*/
@@ -474,7 +484,14 @@ public class OrderFieldLockApplyServiceImpl extends ServiceImpl&lt;OrderFieldLockAp @@ -474,7 +484,14 @@ public class OrderFieldLockApplyServiceImpl extends ServiceImpl&lt;OrderFieldLockAp
474 484
475 } 485 }
476 } 486 }
477 - return queryWrapper; 487 + return queryWrapper
  488 + .func(Objects.nonNull(queryVO.getTypeIn()),query-> {
  489 + if(CollUtil.isNotEmpty(queryVO.getTypeIn())){
  490 + query.in(OrderFieldLockApplyDO::getType, queryVO.getTypeIn());
  491 + }else {
  492 + query.apply("1!=1");
  493 + }
  494 + });
478 } 495 }
479 496
480 /** 497 /**
@@ -815,6 +832,28 @@ public class OrderFieldLockApplyServiceImpl extends ServiceImpl&lt;OrderFieldLockAp @@ -815,6 +832,28 @@ public class OrderFieldLockApplyServiceImpl extends ServiceImpl&lt;OrderFieldLockAp
815 } 832 }
816 } 833 }
817 checkBillOrderService.updateById(invoiceInfoDO); 834 checkBillOrderService.updateById(invoiceInfoDO);
  835 + } else if (ApplyTypeEnum.ORDER_COST_FIELD_EDIT_APPLY.getType().equals(applyDO.getType())){
  836 + applyDO.setAuditUserId(auditUserId);
  837 + applyDO.setStatus(ApplyStatusEnum.AUDIT_PASS.getStatus());
  838 +
  839 + OrderCostFieldLockRecord recordDO = orderCostFieldLockRecordService.getOne(new LambdaQueryWrapper<OrderCostFieldLockRecord>()
  840 + .eq(BaseDO::getEnableFlag, Constant.ENABLE_TEN)
  841 + .eq(OrderCostFieldLockRecord::getOrderId, applyDO.getOrderId())
  842 + .eq(OrderCostFieldLockRecord::getUserId, applyDO.getApplyUserId())
  843 + .orderByDesc(OrderCostFieldLockRecord::getId)
  844 + .last("limit 1"));
  845 + if (Objects.isNull(recordDO)) {
  846 + recordDO = OrderCostFieldLockRecord.builder()
  847 + .orderId(applyDO.getOrderId())
  848 + .userId(applyDO.getApplyUserId())
  849 + .build();
  850 + }
  851 + recordDO.setFields(applyDO.getFields());
  852 + if (Objects.isNull(recordDO.getId())) {
  853 + orderCostFieldLockRecordService.save(recordDO);
  854 + } else {
  855 + orderCostFieldLockRecordService.updateById(recordDO);
  856 + }
818 } 857 }
819 858
820 OrderAuditLogDO auditLogDO = OrderAuditLogDO.builder().applyId(applyDO.getId()).orderId(applyDO.getOrderId()).optType(ApplyStatusEnum.AUDIT_PASS.getDesc()).build(); 859 OrderAuditLogDO auditLogDO = OrderAuditLogDO.builder().applyId(applyDO.getId()).orderId(applyDO.getOrderId()).optType(ApplyStatusEnum.AUDIT_PASS.getDesc()).build();
src/main/java/com/order/erp/service/order/impl/OrderProfitAnalysisServiceImpl.java
@@ -3,34 +3,55 @@ package com.order.erp.service.order.impl; @@ -3,34 +3,55 @@ package com.order.erp.service.order.impl;
3 import cn.hutool.core.bean.BeanUtil; 3 import cn.hutool.core.bean.BeanUtil;
4 import cn.hutool.core.collection.CollUtil; 4 import cn.hutool.core.collection.CollUtil;
5 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; 5 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
  6 +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
6 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; 7 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
7 import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; 8 import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
  9 +import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
8 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; 10 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
  11 +import com.fasterxml.jackson.core.JsonProcessingException;
  12 +import com.fasterxml.jackson.databind.ObjectMapper;
9 import com.order.erp.common.constant.Constant; 13 import com.order.erp.common.constant.Constant;
10 import com.order.erp.common.constant.ServerResult; 14 import com.order.erp.common.constant.ServerResult;
11 import com.order.erp.common.exception.BusinessException; 15 import com.order.erp.common.exception.BusinessException;
12 import com.order.erp.common.utils.ProfitUtils; 16 import com.order.erp.common.utils.ProfitUtils;
13 import com.order.erp.common.utils.StringUtils; 17 import com.order.erp.common.utils.StringUtils;
14 import com.order.erp.domain.dto.BaseDO; 18 import com.order.erp.domain.dto.BaseDO;
  19 +import com.order.erp.domain.dto.SystemSettingDO;
15 import com.order.erp.domain.dto.order.OrderBaseInfoDO; 20 import com.order.erp.domain.dto.order.OrderBaseInfoDO;
16 import com.order.erp.domain.dto.order.OrderProfitAnalysisDO; 21 import com.order.erp.domain.dto.order.OrderProfitAnalysisDO;
  22 +import com.order.erp.domain.dto.order.ProjectBaseInfoDO;
  23 +import com.order.erp.domain.model.OrderCostFieldLockRecord;
  24 +import com.order.erp.domain.model.ProjectFieldLockRecord;
17 import com.order.erp.domain.vo.OrderProfitAnalysisVo; 25 import com.order.erp.domain.vo.OrderProfitAnalysisVo;
18 -import com.order.erp.domain.vo.order.OrderProfitAnalysisQueryVO;  
19 -import com.order.erp.domain.vo.order.OrderProfitAnalysisVO;  
20 -import com.order.erp.domain.vo.order.ProfitCalculateVO; 26 +import com.order.erp.domain.vo.order.*;
21 import com.order.erp.mapper.order.OrderProfitAnalysisMapper; 27 import com.order.erp.mapper.order.OrderProfitAnalysisMapper;
  28 +import com.order.erp.service.IProjectFieldLockRecordService;
  29 +import com.order.erp.service.SystemSettingService;
  30 +import com.order.erp.service.impl.OrderCostFieldLockRecordServiceImpl;
  31 +import com.order.erp.service.order.IProjectBaseInfoService;
22 import com.order.erp.service.order.OrderBaseInfoService; 32 import com.order.erp.service.order.OrderBaseInfoService;
  33 +import com.order.erp.service.order.OrderFieldLockRecordService;
23 import com.order.erp.service.order.OrderProfitAnalysisService; 34 import com.order.erp.service.order.OrderProfitAnalysisService;
24 import lombok.extern.slf4j.Slf4j; 35 import lombok.extern.slf4j.Slf4j;
  36 +import org.apache.poi.ss.usermodel.*;
  37 +import org.apache.poi.ss.util.CellRangeAddress;
  38 +import org.apache.poi.xssf.usermodel.XSSFFont;
  39 +import org.apache.poi.xssf.usermodel.XSSFWorkbook;
25 import org.springframework.beans.BeanUtils; 40 import org.springframework.beans.BeanUtils;
  41 +import org.springframework.beans.factory.annotation.Autowired;
26 import org.springframework.stereotype.Service; 42 import org.springframework.stereotype.Service;
27 43
28 import javax.annotation.Resource; 44 import javax.annotation.Resource;
  45 +import javax.servlet.http.HttpServletResponse;
  46 +import java.io.OutputStream;
29 import java.math.BigDecimal; 47 import java.math.BigDecimal;
30 -import java.util.HashSet;  
31 -import java.util.List;  
32 -import java.util.Objects;  
33 -import java.util.Set; 48 +import java.math.RoundingMode;
  49 +import java.time.Duration;
  50 +import java.time.LocalDateTime;
  51 +import java.time.format.DateTimeFormatter;
  52 +import java.time.temporal.ChronoUnit;
  53 +import java.util.*;
  54 +import java.util.function.Function;
34 import java.util.stream.Collectors; 55 import java.util.stream.Collectors;
35 56
36 /** 57 /**
@@ -45,6 +66,16 @@ public class OrderProfitAnalysisServiceImpl extends ServiceImpl&lt;OrderProfitAnaly @@ -45,6 +66,16 @@ public class OrderProfitAnalysisServiceImpl extends ServiceImpl&lt;OrderProfitAnaly
45 66
46 @Resource 67 @Resource
47 private OrderBaseInfoService orderBaseInfoService; 68 private OrderBaseInfoService orderBaseInfoService;
  69 + @Autowired
  70 + private SystemSettingService systemSettingService;
  71 + @Autowired
  72 + private IProjectBaseInfoService projectProfitAnalysisService;
  73 + @Autowired
  74 + private IProjectFieldLockRecordService projectionFieldLockRecordService;
  75 + @Resource
  76 + private OrderFieldLockRecordService orderFieldLockRecordService;
  77 + @Autowired
  78 + OrderCostFieldLockRecordServiceImpl orderCostFieldLockRecordService;
48 79
49 /** 80 /**
50 * 通过ID查询单条数据 81 * 通过ID查询单条数据
@@ -108,6 +139,7 @@ public class OrderProfitAnalysisServiceImpl extends ServiceImpl&lt;OrderProfitAnaly @@ -108,6 +139,7 @@ public class OrderProfitAnalysisServiceImpl extends ServiceImpl&lt;OrderProfitAnaly
108 if (Objects.isNull(orderProfitAnalysisVO.getId())) { 139 if (Objects.isNull(orderProfitAnalysisVO.getId())) {
109 return ServerResult.fail("id 不能为空"); 140 return ServerResult.fail("id 不能为空");
110 } 141 }
  142 + orderProfitAnalysisVO.getId();
111 OrderProfitAnalysisDO orderProfitAnalysisDo = BeanUtil.copyProperties(orderProfitAnalysisVO, OrderProfitAnalysisDO.class); 143 OrderProfitAnalysisDO orderProfitAnalysisDo = BeanUtil.copyProperties(orderProfitAnalysisVO, OrderProfitAnalysisDO.class);
112 144
113 updateById(orderProfitAnalysisDo); 145 updateById(orderProfitAnalysisDo);
src/main/java/com/order/erp/service/order/impl/ProjectBaseInfoServiceImpl.java 0 → 100644
  1 +package com.order.erp.service.order.impl;
  2 +
  3 +import cn.hutool.core.bean.BeanUtil;
  4 +import cn.hutool.core.collection.CollUtil;
  5 +import com.alibaba.fastjson.JSONObject;
  6 +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
  7 +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
  8 +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
  9 +import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
  10 +import com.fasterxml.jackson.core.JsonProcessingException;
  11 +import com.fasterxml.jackson.databind.ObjectMapper;
  12 +import com.order.erp.common.constant.Constant;
  13 +import com.order.erp.common.constant.ServerResult;
  14 +import com.order.erp.common.constant.ServerResultCode;
  15 +import com.order.erp.common.exception.BusinessException;
  16 +import com.order.erp.config.DataScope;
  17 +import com.order.erp.domain.ApplyStatusEnum;
  18 +import com.order.erp.domain.ProjectApplyTypeEnum;
  19 +import com.order.erp.domain.dto.BaseDO;
  20 +import com.order.erp.domain.dto.SystemSettingDO;
  21 +import com.order.erp.domain.dto.order.OrderBaseInfoDO;
  22 +import com.order.erp.domain.dto.order.OrderCostInfoDO;
  23 +import com.order.erp.domain.dto.order.ProjectBaseInfoDO;
  24 +import com.order.erp.domain.model.ProjectApplyDO;
  25 +import com.order.erp.domain.model.ProjectFieldLockRecord;
  26 +import com.order.erp.domain.vo.order.*;
  27 +import com.order.erp.mapper.order.ProjectBaseInfoMapper;
  28 +import com.order.erp.service.IProjectFieldLockRecordService;
  29 +import com.order.erp.service.SystemSettingService;
  30 +import com.order.erp.service.impl.ProjectApplyServiceImpl;
  31 +import com.order.erp.service.order.IProjectBaseInfoService;
  32 +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
  33 +import com.order.erp.service.order.OrderBaseInfoService;
  34 +import com.order.erp.service.order.OrderProfitAnalysisService;
  35 +import org.apache.poi.ss.usermodel.*;
  36 +import org.apache.poi.ss.util.CellRangeAddress;
  37 +import org.apache.poi.xssf.usermodel.XSSFFont;
  38 +import org.apache.poi.xssf.usermodel.XSSFWorkbook;
  39 +import org.springframework.beans.BeanUtils;
  40 +import org.springframework.beans.factory.annotation.Autowired;
  41 +import org.springframework.stereotype.Service;
  42 +
  43 +import javax.servlet.http.HttpServletResponse;
  44 +import java.io.OutputStream;
  45 +import java.math.BigDecimal;
  46 +import java.math.RoundingMode;
  47 +import java.time.Duration;
  48 +import java.time.LocalDateTime;
  49 +import java.time.format.DateTimeFormatter;
  50 +import java.time.temporal.ChronoUnit;
  51 +import java.util.*;
  52 +import java.util.function.Function;
  53 +import java.util.stream.Collectors;
  54 +
  55 +/**
  56 + * <p>
  57 + * 服务实现类
  58 + * </p>
  59 + *
  60 + * @author author
  61 + * @since 2024-12-18
  62 + */
  63 +@Service
  64 +public class ProjectBaseInfoServiceImpl extends ServiceImpl<ProjectBaseInfoMapper, ProjectBaseInfoDO> implements IProjectBaseInfoService {
  65 + @Autowired
  66 + private ProjectApplyServiceImpl projectFieldLockApplyService;
  67 + @Autowired
  68 + private DataScope dataScope;
  69 + @Autowired
  70 + private IProjectFieldLockRecordService projectionFieldLockRecordService;
  71 + @Autowired
  72 + private OrderBaseInfoService orderBaseInfoService;
  73 + @Autowired
  74 + private OrderProfitAnalysisService projectProfitAnalysisService;
  75 + @Autowired
  76 + private SystemSettingService systemSettingService;
  77 +
  78 + @Override
  79 + public ServerResult edit(ProjectBaseInfoVO vo) {
  80 + Long id = vo.getId();
  81 + ProjectBaseInfoDO byId = this.getById(id);
  82 + if (Objects.isNull(byId)) {
  83 + byId = BeanUtil.copyProperties(vo, ProjectBaseInfoDO.class);
  84 + }else {
  85 + BeanUtil.copyProperties(vo, byId);
  86 + }
  87 + return ServerResult.success(this.saveOrUpdate(byId));
  88 + }
  89 + @Override
  90 + public ServerResult applyEditFileds(ProjectBaseInfoLockFieldVO vo) {
  91 + List<ProjectApplyDO> applyDOS = projectFieldLockApplyService.list(new LambdaQueryWrapper<ProjectApplyDO>()
  92 + .eq(BaseDO::getEnableFlag, Constant.ENABLE_TEN)
  93 + .eq(ProjectApplyDO::getProjectId, vo.getProjectId())
  94 + .eq(ProjectApplyDO::getApplyUserId, dataScope.getLoginUserId())
  95 + .eq(ProjectApplyDO::getStatus, ApplyStatusEnum.WAIT_AUDIT.getStatus()));
  96 + if (CollectionUtils.isNotEmpty(applyDOS)) {
  97 + throw new BusinessException(ServerResultCode.APPLY_UNLOCK_FIELD_EXIST);
  98 + }
  99 + Long projectId = vo.getProjectId();
  100 + vo.setProjectId(null);
  101 + ProjectApplyDO build = ProjectApplyDO.builder()
  102 + .projectId(projectId)
  103 + .applyUserId(dataScope.getLoginUserId())
  104 + .fields(JSONObject.toJSONString(vo))
  105 + .type(ProjectApplyTypeEnum.FIELD_EDIT_APPLY)
  106 + .status(ApplyStatusEnum.WAIT_AUDIT.getStatus())
  107 + .build();
  108 + projectFieldLockApplyService.save(build);
  109 + return ServerResult.success();
  110 + }
  111 +
  112 +
  113 +
  114 +
  115 + @Override
  116 + public ServerResult pageProjectLockFieldApply(QueryProjectLockFieldVO vo) {
  117 + Page<ProjectApplyDO> page = projectFieldLockApplyService.lambdaQuery()
  118 + .eq(BaseDO::getEnableFlag, Constant.ENABLE_TEN)
  119 + .eq(ProjectApplyDO::getType, ProjectApplyTypeEnum.FIELD_EDIT_APPLY.getType())
  120 + .eq(ProjectApplyDO::getStatus, ApplyStatusEnum.WAIT_AUDIT.getStatus())
  121 + .orderByDesc(ProjectApplyDO::getCreateTime)
  122 + .page(new Page<>(vo.getPage(), vo.getPageSize()));
  123 + List<ProjectApplyDO> records = page.getRecords();
  124 + if(CollectionUtils.isEmpty(records)){
  125 + return buildPageResult(page, Collections.emptyList());
  126 + }
  127 + List<Long> projectIds = records.stream().map(ProjectApplyDO::getProjectId).collect(Collectors.toList());
  128 + List<ProjectBaseInfoDO> projectBaseInfoDOS = this.listByIds(projectIds);
  129 + Map<Long,String> projectId2ProjectNoPrefixMap = projectBaseInfoDOS.stream().collect(Collectors.toMap(ProjectBaseInfoDO::getId, ProjectBaseInfoDO::getProjectNoPrefix));
  130 + List<ProjectApplyVO> collect = records.stream().map(e -> {
  131 + ProjectApplyVO projectApplyVO = BeanUtil.copyProperties(e, ProjectApplyVO.class);
  132 + projectApplyVO.setProjectNoPrefix(projectId2ProjectNoPrefixMap.get(e.getProjectId()));
  133 + return projectApplyVO;
  134 + }).collect(Collectors.toList());
  135 + return ServerResult.success(buildPageResult(page, collect));
  136 + }
  137 +
  138 + @Override
  139 + public ServerResult audit(AuditVO vo) {
  140 + ProjectApplyDO applyDO = projectFieldLockApplyService.getById(vo.getId());
  141 + applyDO.setAuditUserId(dataScope.getLoginUserId());
  142 +
  143 + if(ApplyStatusEnum.AUDIT_PASS.getStatus().equals(vo.getStatus())){
  144 + applyDO.setStatus(ApplyStatusEnum.AUDIT_PASS.getStatus());
  145 + ProjectFieldLockRecord recordDO = projectionFieldLockRecordService.getOne(new LambdaQueryWrapper<ProjectFieldLockRecord>()
  146 + .eq(BaseDO::getEnableFlag, Constant.ENABLE_TEN)
  147 + .eq(ProjectFieldLockRecord::getProjectId, applyDO.getProjectId())
  148 + .eq(ProjectFieldLockRecord::getUserId, applyDO.getApplyUserId())
  149 + .orderByDesc(ProjectFieldLockRecord::getId)
  150 + .last("limit 1"));
  151 + if (Objects.isNull(recordDO)) {
  152 + recordDO = ProjectFieldLockRecord.builder()
  153 + .projectId(applyDO.getProjectId())
  154 + .userId(applyDO.getApplyUserId())
  155 + .build();
  156 + }
  157 + recordDO.setFields(applyDO.getFields());
  158 + if (Objects.isNull(recordDO.getId())) {
  159 + projectionFieldLockRecordService.save(recordDO);
  160 + } else {
  161 + projectionFieldLockRecordService.updateById(recordDO);
  162 + }
  163 + }
  164 + projectFieldLockApplyService.updateById(applyDO);
  165 + return ServerResult.success();
  166 + }
  167 +
  168 +
  169 + @Override
  170 + public ServerResult<Page<InnerProfitInfoVO>> listInnerProfitInfoByPage(OrderBaseInfoQueryVO queryVO) {
  171 + Page<OrderBaseInfoDO> page = pageProjectNoPrefix(queryVO);
  172 + List<OrderInfoResultVO> orderInfoResultVOS = getOrderInfoResultVOS(page, queryVO);
  173 + List<InnerProfitInfoVO> innerProfitInfoVOs = buildInnerProfitInfos(orderInfoResultVOS);
  174 + return buildPageResult(page, innerProfitInfoVOs);
  175 + }
  176 +
  177 + @Override
  178 + public ServerResult<Page<BusinessProfitInfoVO>> listBusinessProfitInfoByPage(OrderBaseInfoQueryVO queryVO) {
  179 + Page<OrderBaseInfoDO> page = pageProjectNoPrefix(queryVO);
  180 + List<OrderInfoResultVO> orderInfoResultVOS = getOrderInfoResultVOS(page, queryVO);
  181 + List<BusinessProfitInfoVO> businessProfitInfoVOs = buildBusinessProfitInfos(orderInfoResultVOS);
  182 + return buildPageResult(page, businessProfitInfoVOs);
  183 + }
  184 +
  185 + /**
  186 + * 分页查询项目号前8位
  187 + */
  188 + private Page<OrderBaseInfoDO> pageProjectNoPrefix(OrderBaseInfoQueryVO queryVO) {
  189 + LambdaQueryWrapper<OrderBaseInfoDO> orderBaseInfoDOLambdaQueryWrapper = orderBaseInfoService.buildQueryByParam(queryVO).select(OrderBaseInfoDO::getId);
  190 + return orderBaseInfoService.page(new Page<>(queryVO.getPage(), queryVO.getPageSize()),
  191 + new QueryWrapper<OrderBaseInfoDO>()
  192 + .select("LEFT(project_no, 8) as project_no")
  193 + .func(!orderBaseInfoDOLambdaQueryWrapper.isEmptyOfWhere(), queryWrapper -> {
  194 + List<OrderBaseInfoDO> list = orderBaseInfoService.list(orderBaseInfoDOLambdaQueryWrapper);
  195 + List<Long> ids = list.stream().map(OrderBaseInfoDO::getId).collect(Collectors.toList());
  196 + if (CollUtil.isNotEmpty(ids)) {
  197 + queryWrapper.in("id", ids);
  198 + } else {
  199 + queryWrapper.ne("1", 1);
  200 + }
  201 + })
  202 + .groupBy("LEFT(project_no, 8)"));
  203 + }
  204 +
  205 + /**
  206 + * 查询订单列表
  207 + */
  208 + private List<OrderInfoResultVO> getOrderInfoResultVOS(Page<OrderBaseInfoDO> page, OrderBaseInfoQueryVO queryVO) {
  209 + List<String> projectNoPrefix = page.getRecords().stream()
  210 + .map(OrderBaseInfoDO::getProjectNo)
  211 + .map(x -> x.substring(0, 8))
  212 + .collect(Collectors.toList());
  213 +
  214 + List<OrderBaseInfoDO> orderBaseInfoDOS = orderBaseInfoService.list(orderBaseInfoService.buildQueryByParam(queryVO)
  215 + .and(CollUtil.isNotEmpty(projectNoPrefix),query -> {
  216 + for (int i = 0; i < projectNoPrefix.size(); i++) {
  217 + query.likeRight(OrderBaseInfoDO::getProjectNo, projectNoPrefix.get(i));
  218 + if (i != projectNoPrefix.size() - 1) {
  219 + query.or();
  220 + }
  221 + }
  222 + }))
  223 + ;
  224 +
  225 + return orderBaseInfoService.wrapperOrderResultList(true, orderBaseInfoDOS);
  226 + }
  227 +
  228 + /**
  229 + * 构建分页
  230 + */
  231 + private <T> ServerResult buildPageResult(Page<?> page, List<T> records) {
  232 + Page<T> webVOPage = new Page<>();
  233 + webVOPage.setRecords(records);
  234 + BeanUtils.copyProperties(page, webVOPage, "records");
  235 + return ServerResult.success(webVOPage);
  236 + }
  237 +
  238 + private List<InnerProfitInfoVO> buildInnerProfitInfos(List<OrderInfoResultVO> orderInfoResultVOS) {
  239 + Map<String, List<OrderInfoResultVO>> orderBaseInfoDOSGroupByProjectNoPre = orderInfoResultVOS.stream()
  240 + .collect(Collectors.groupingBy(
  241 + order -> order.getProjectNo().substring(0, 8)
  242 + ));
  243 + Set<String> collect = orderInfoResultVOS.stream()
  244 + .map(OrderBaseInfoVO::getCustomerCode)
  245 + .collect(Collectors.toSet());
  246 + List<SystemSettingDO> systemSettingDOS = systemSettingService.lambdaQuery()
  247 + .eq(BaseDO::getEnableFlag, Constant.ENABLE_TEN)
  248 + .eq(SystemSettingDO::getRelationCode, "ProduceSettingItem")
  249 + .in(SystemSettingDO::getSettingValue, collect)
  250 + .list();
  251 + Map<String, SystemSettingDO> systemSettingDOSMap = systemSettingDOS.stream()
  252 + .collect(Collectors.toMap(SystemSettingDO::getSettingValue, Function.identity(), (x, y) -> x));
  253 + List<InnerProfitInfoVO> innerProfitInfoVOs = orderBaseInfoDOSGroupByProjectNoPre.entrySet().stream().map(entry -> {
  254 + List<OrderInfoResultVO> details = entry.getValue();
  255 + InnerProfitInfoVO innerProfitInfoVO = InnerProfitInfoVO.builder()
  256 + .customerCode(details.get(0).getCustomerCode())
  257 + .projectNoPrefix(entry.getKey())
  258 + .productionDepartment(details.get(0).getProductionDepartment())
  259 + .build();
  260 +
  261 + //数量
  262 + details.stream()
  263 + .filter(vo -> Objects.nonNull(vo.getOrderCount()))
  264 + .mapToInt(OrderInfoResultVO::getOrderCount)
  265 + .reduce(Integer::sum)
  266 + .ifPresent(innerProfitInfoVO::setOrderCount);
  267 +
  268 + //生产科总价
  269 + details.stream()
  270 + .map(OrderInfoResultVO::getProfitAnalysisInfo)
  271 + .filter(Objects::nonNull)
  272 + .map(OrderProfitAnalysisVO::getProductionDepartmentTotalPrice)
  273 + .filter(Objects::nonNull)
  274 + .map(BigDecimal::valueOf)
  275 + .reduce(BigDecimal::add)
  276 + .ifPresent(price -> {
  277 + innerProfitInfoVO.setProductionDepartmentTotalPrice(price.doubleValue());
  278 + });
  279 +
  280 + //生产科预算金额
  281 + details.stream()
  282 + .map(OrderInfoResultVO::getOrderCostInfo)
  283 + .filter(Objects::nonNull)
  284 + .map(OrderCostInfoVO::getProductionDepartmentPredictPrice)
  285 + .filter(Objects::nonNull)
  286 + .reduce(BigDecimal::add)
  287 + .ifPresent(innerProfitInfoVO::setProductionDepartmentPredictPrice);
  288 + //实际发生费用
  289 + details.stream()
  290 + .map(OrderInfoResultVO::getOrderCostInfo)
  291 + .filter(Objects::nonNull)
  292 + .map(OrderCostInfoVO::getProductionActualPrice)
  293 + .filter(Objects::nonNull)
  294 + .reduce(BigDecimal::add)
  295 + .ifPresent(innerProfitInfoVO::setProductionActualPrice);
  296 +
  297 + if (Objects.nonNull(innerProfitInfoVO.getProductionDepartmentPredictPrice())
  298 + && Objects.nonNull(innerProfitInfoVO.getProductionActualPrice())) {
  299 + //预算占比=实际发生费用/预算金额
  300 + innerProfitInfoVO.setPredictRatio(innerProfitInfoVO.getProductionActualPrice().divide(innerProfitInfoVO.getProductionDepartmentPredictPrice(), 4, RoundingMode.HALF_UP));
  301 + if (innerProfitInfoVO.getProductionDepartmentPredictPrice().compareTo(BigDecimal.ZERO) != 0) {
  302 + //预算占比与实际比占比差:1-预算占比
  303 + innerProfitInfoVO.setPredictAndActualRatio(new BigDecimal(1).subtract(innerProfitInfoVO.getPredictRatio()));
  304 + }
  305 + }
  306 +
  307 + //事前毛利润 = 生产总额-预算金额
  308 + if (Objects.nonNull(innerProfitInfoVO.getProductionDepartmentTotalPrice())
  309 + && Objects.nonNull(innerProfitInfoVO.getProductionDepartmentPredictPrice())) {
  310 + innerProfitInfoVO.setBeforeGrossProfit(BigDecimal.valueOf(innerProfitInfoVO.getProductionDepartmentTotalPrice()).subtract(innerProfitInfoVO.getProductionDepartmentPredictPrice()));
  311 + //事前毛利润率 = 事前毛利/生产科总价
  312 + if (innerProfitInfoVO.getProductionDepartmentTotalPrice().compareTo(0.0) != 0) {
  313 + innerProfitInfoVO.setBeforeGrossProfitRate(innerProfitInfoVO.getBeforeGrossProfit().divide(BigDecimal.valueOf(innerProfitInfoVO.getProductionDepartmentTotalPrice()), 4, RoundingMode.HALF_UP));
  314 + }
  315 + }
  316 + //事后毛利率 = 总价-实际发生费用
  317 + if (Objects.nonNull(innerProfitInfoVO.getProductionDepartmentTotalPrice())
  318 + && Objects.nonNull(innerProfitInfoVO.getProductionActualPrice())) {
  319 + innerProfitInfoVO.setGrossProfit(BigDecimal.valueOf(innerProfitInfoVO.getProductionDepartmentTotalPrice()).subtract(innerProfitInfoVO.getProductionActualPrice()));
  320 + if (innerProfitInfoVO.getProductionDepartmentTotalPrice().compareTo(0.0) != 0) {
  321 + innerProfitInfoVO.setGrossProfitRate(innerProfitInfoVO.getGrossProfit().divide(BigDecimal.valueOf(innerProfitInfoVO.getProductionDepartmentTotalPrice()), 4, RoundingMode.HALF_UP));
  322 + }
  323 + }
  324 +
  325 + //hod时间差
  326 + LocalDateTime earliest = details.stream()
  327 + .map(OrderInfoResultVO::getOrderHodTime)
  328 + .map(hodTime -> LocalDateTime.parse(hodTime, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")))
  329 + .min(Comparator.naturalOrder())
  330 + .orElse(null);
  331 + LocalDateTime latest = details.stream()
  332 + .map(OrderInfoResultVO::getOrderHodTime)
  333 + .map(hodTime -> LocalDateTime.parse(hodTime, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")))
  334 + .max(Comparator.naturalOrder())
  335 + .orElse(null);
  336 + innerProfitInfoVO.setProduceStartTime(earliest);
  337 + innerProfitInfoVO.setProduceEndTime(latest);
  338 + SystemSettingDO systemSettingDO = systemSettingDOSMap.get(innerProfitInfoVO.getCustomerCode());
  339 + if (Objects.nonNull(systemSettingDO)) {
  340 + String relationValue = systemSettingDO.getRelationValue();
  341 + ObjectMapper objectMapper = new ObjectMapper();
  342 + try {
  343 + // 将 JSON 字符串解析为 List<Map<String, String>>
  344 + List<Map<String, String>> relations = objectMapper.readValue(relationValue, objectMapper.getTypeFactory().constructCollectionType(List.class, Map.class));
  345 + // 提取 fixCost 和 ratio 的 relationValue
  346 + String fixCostValue = null;
  347 + String ratioValue = null;
  348 +
  349 + for (Map<String, String> relation : relations) {
  350 + if ("fixCost".equals(relation.get("relationCode"))) {
  351 + fixCostValue = relation.get("relationValue");
  352 + } else if ("ratio".equals(relation.get("relationCode"))) {
  353 + ratioValue = relation.get("relationValue");
  354 + }
  355 + }
  356 + if (com.baomidou.mybatisplus.core.toolkit.StringUtils.isNotBlank(fixCostValue)
  357 + && Objects.nonNull(earliest)
  358 + && Objects.nonNull(latest)) {
  359 + Duration duration = Duration.between(earliest, latest);
  360 + //内部生产固定成本¥
  361 + innerProfitInfoVO.setInnerProductionFixedCost(BigDecimal.valueOf(duration.toDays() * Double.parseDouble(fixCostValue)));
  362 + }
  363 + if (com.baomidou.mybatisplus.core.toolkit.StringUtils.isNotBlank(ratioValue)
  364 + && Objects.nonNull(innerProfitInfoVO.getPredictRatio())
  365 + && innerProfitInfoVO.getPredictRatio().compareTo(BigDecimal.valueOf(1.05)) < 0) {
  366 + //内部生产提成¥
  367 + innerProfitInfoVO.setInnerProductionCommission(BigDecimal.valueOf(details.size()).multiply(BigDecimal.valueOf(Double.parseDouble(ratioValue))));
  368 + }
  369 + //内部生产净利润 = 总价-实际费用-固定成本-提成
  370 + if (Objects.nonNull(innerProfitInfoVO.getProductionDepartmentTotalPrice())
  371 + && Objects.nonNull(innerProfitInfoVO.getProductionActualPrice())
  372 + && Objects.nonNull(innerProfitInfoVO.getInnerProductionFixedCost())
  373 + && Objects.nonNull(innerProfitInfoVO.getInnerProductionCommission())) {
  374 + innerProfitInfoVO.setInnerProductionProfit(BigDecimal.valueOf(innerProfitInfoVO.getProductionDepartmentTotalPrice())
  375 + .subtract(innerProfitInfoVO.getProductionActualPrice())
  376 + .subtract(innerProfitInfoVO.getInnerProductionFixedCost())
  377 + .subtract(innerProfitInfoVO.getInnerProductionCommission()));
  378 + }
  379 + //内部生产净利润率 = 净利润/总价
  380 + if (Objects.nonNull(innerProfitInfoVO.getProductionDepartmentTotalPrice())
  381 + && Objects.nonNull(innerProfitInfoVO.getInnerProductionProfit())) {
  382 + innerProfitInfoVO.setInnerProductionProfitRate(innerProfitInfoVO.getInnerProductionProfit().divide(BigDecimal.valueOf(innerProfitInfoVO.getProductionDepartmentTotalPrice()), 4, RoundingMode.HALF_UP));
  383 + }
  384 + } catch (JsonProcessingException e) {
  385 + throw new RuntimeException(e);
  386 + }
  387 + }
  388 + return innerProfitInfoVO;
  389 + }).collect(Collectors.toList());
  390 + return innerProfitInfoVOs;
  391 + }
  392 +
  393 + private List<BusinessProfitInfoVO> buildBusinessProfitInfos(List<OrderInfoResultVO> orderInfoResultVOS) {
  394 + List<String> projectNoPrefix = orderInfoResultVOS.stream()
  395 + .map(OrderInfoResultVO::getProjectNo)
  396 + .map(projectNo -> projectNo.substring(0, 8))
  397 + .distinct()
  398 + .collect(Collectors.toList());
  399 + Map<String, List<OrderInfoResultVO>> orderBaseInfoDOSGroupByProjectNoPre = orderInfoResultVOS.stream()
  400 + .collect(Collectors.groupingBy(
  401 + order -> order.getProjectNo().substring(0, 8)
  402 + ));
  403 + List<ProjectBaseInfoDO> list = this.lambdaQuery()
  404 + .func(query -> {
  405 + if (CollUtil.isNotEmpty(projectNoPrefix)) {
  406 + query.in(ProjectBaseInfoDO::getProjectNoPrefix, projectNoPrefix);
  407 + } else {
  408 + query.apply("1!=1");
  409 + }
  410 + })
  411 + .list();
  412 + Map<String, ProjectBaseInfoDO> noPrefix2ProjectProfitAnalysisDOMap = list.stream().collect(Collectors.toMap(ProjectBaseInfoDO::getProjectNoPrefix, Function.identity()));
  413 + Map<Long,String> projectId2ProjectNoPrefixMap = list.stream().collect(Collectors.toMap(ProjectBaseInfoDO::getId, ProjectBaseInfoDO::getProjectNoPrefix));
  414 + Set<String> collect = orderInfoResultVOS.stream()
  415 + .map(OrderBaseInfoVO::getCustomerCode)
  416 + .collect(Collectors.toSet());
  417 + List<SystemSettingDO> systemSettingDOS = systemSettingService.lambdaQuery()
  418 + .eq(BaseDO::getEnableFlag, Constant.ENABLE_TEN)
  419 + .eq(SystemSettingDO::getRelationCode, "costSettingItem")
  420 + .in(SystemSettingDO::getSettingValue, collect)
  421 + .list();
  422 + Map<String, SystemSettingDO> systemSettingDOSMap = systemSettingDOS.stream()
  423 + .collect(Collectors.toMap(SystemSettingDO::getSettingValue, Function.identity(), (x, y) -> x));
  424 + ObjectMapper objectMapper = new ObjectMapper();
  425 + BigDecimal systemExchangeRate = systemSettingService.getExchangeRate();
  426 + List<ProjectFieldLockRecord> lockRecords = projectionFieldLockRecordService
  427 + .lambdaQuery()
  428 + .func(query -> {
  429 + Set<Long> projectIds = list.stream().map(ProjectBaseInfoDO::getId).collect(Collectors.toSet());
  430 + if(CollUtil.isNotEmpty(projectIds)){
  431 + query.in(ProjectFieldLockRecord::getProjectId,projectIds);
  432 +
  433 + }else {
  434 + query.apply("1!=1");
  435 + }
  436 + })
  437 + .list();
  438 + Map<String,ProjectBaseInfoLockFieldVO> prjectNo2LockRecordMap = lockRecords.stream()
  439 + .filter(record -> projectId2ProjectNoPrefixMap.containsKey(record.getProjectId()))
  440 + .collect(Collectors.toMap(record -> projectId2ProjectNoPrefixMap.get(record.getProjectId()), record -> {
  441 + try {
  442 + return objectMapper.readValue(record.getFields(), ProjectBaseInfoLockFieldVO.class);
  443 + } catch (JsonProcessingException e) {
  444 + throw new RuntimeException(e);
  445 + }
  446 + }));
  447 +
  448 + List<BusinessProfitInfoVO> businessProfitInfoVOs = orderBaseInfoDOSGroupByProjectNoPre.entrySet().stream().map(entry -> {
  449 + List<OrderInfoResultVO> details = entry.getValue();
  450 + BusinessProfitInfoVO businessProfitInfoVO = BusinessProfitInfoVO.builder()
  451 + .customerCode(details.get(0).getCustomerCode())
  452 + .projectNoPrefix(entry.getKey())
  453 + .lockFields(prjectNo2LockRecordMap.get(entry.getKey()))
  454 + .build();
  455 +
  456 + //客户总金额¥
  457 + details.stream()
  458 + .map(OrderInfoResultVO::getProfitAnalysisInfo)
  459 + .filter(Objects::nonNull)
  460 + .map(OrderProfitAnalysisVO::getCustomerRmbTotalPrice)
  461 + .filter(Objects::nonNull)
  462 + .map(BigDecimal::valueOf)
  463 + .reduce(BigDecimal::add)
  464 + .ifPresent(price -> businessProfitInfoVO.setCustomerRmbTotalPrice(price.doubleValue()));
  465 +
  466 + //客户总金额$
  467 + details.stream()
  468 + .map(OrderInfoResultVO::getProfitAnalysisInfo)
  469 + .filter(Objects::nonNull)
  470 + .map(OrderProfitAnalysisVO::getCustomerTotalPrice)
  471 + .filter(Objects::nonNull)
  472 + .map(BigDecimal::valueOf)
  473 + .reduce(BigDecimal::add)
  474 + .ifPresent(price -> businessProfitInfoVO.setCustomerTotalPrice(price.doubleValue()));
  475 +
  476 + //生产科总价¥
  477 + details.stream()
  478 + .map(OrderInfoResultVO::getProfitAnalysisInfo)
  479 + .filter(Objects::nonNull)
  480 + .map(OrderProfitAnalysisVO::getProductionDepartmentTotalPrice)
  481 + .filter(Objects::nonNull)
  482 + .map(BigDecimal::valueOf)
  483 + .reduce(BigDecimal::add)
  484 + .ifPresent(price -> businessProfitInfoVO.setProductionDepartmentTotalPrice(price.doubleValue()));
  485 +
  486 + //包装费用合计$
  487 + details.stream()
  488 + .map(OrderInfoResultVO::getProfitAnalysisInfo)
  489 + .filter(Objects::nonNull)
  490 + .map(OrderProfitAnalysisVO::getPacketTotalPrice)
  491 + .filter(Objects::nonNull)
  492 + .map(BigDecimal::valueOf)
  493 + .reduce(BigDecimal::add)
  494 + .ifPresent(price -> businessProfitInfoVO.setPacketTotalPrice(price.doubleValue()));
  495 +
  496 + //包装费用合计¥
  497 + businessProfitInfoVO.setPacketRmbTotalPrice(Optional.ofNullable(businessProfitInfoVO.getPacketTotalPrice())
  498 + .orElse(0.0) * 6.2);
  499 + //包装费用实际金额
  500 + details.stream()
  501 + .map(OrderInfoResultVO::getOrderCostInfo)
  502 + .filter(Objects::nonNull)
  503 + .map(OrderCostInfoVO::getPacketActualRmbTotalPrice)
  504 + .filter(Objects::nonNull)
  505 + .reduce(BigDecimal::add)
  506 + .ifPresent(packetActualRmbTotalPrice -> {
  507 + businessProfitInfoVO.setPacketActualRmbTotalPrice(packetActualRmbTotalPrice.setScale(4, RoundingMode.HALF_UP));
  508 + });
  509 + //订单数
  510 + details.stream()
  511 + .mapToInt(OrderInfoResultVO::getOrderCount)
  512 + .filter(Objects::nonNull)
  513 + .reduce(Integer::sum)
  514 + .ifPresent(businessProfitInfoVO::setOrderCount);
  515 + if (Objects.nonNull(businessProfitInfoVO.getOrderCount())
  516 + && Objects.nonNull(businessProfitInfoVO.getPacketActualRmbTotalPrice())
  517 + ) {
  518 + //实际跟单单价
  519 + businessProfitInfoVO.setActualOrderRmbPrice(businessProfitInfoVO.getPacketActualRmbTotalPrice().divide(new BigDecimal(businessProfitInfoVO.getOrderCount()), 4, RoundingMode.HALF_UP));
  520 + //折换成美金
  521 + businessProfitInfoVO.setActualOrderPrice(businessProfitInfoVO.getActualOrderRmbPrice().divide(BigDecimal.valueOf(6.2), 4, RoundingMode.HALF_UP));
  522 + }
  523 + if (Objects.nonNull(businessProfitInfoVO.getPacketActualRmbTotalPrice())
  524 + && Objects.nonNull(businessProfitInfoVO.getPacketRmbTotalPrice())) {
  525 + //包装费用收益¥
  526 + businessProfitInfoVO.setPacketProfitRmbPrice(BigDecimal.valueOf(businessProfitInfoVO.getPacketRmbTotalPrice()).subtract(businessProfitInfoVO.getPacketActualRmbTotalPrice()));
  527 + }
  528 +
  529 + //hod时间差
  530 + LocalDateTime earliest = details.stream()
  531 + .map(OrderInfoResultVO::getOrderHodTime)
  532 + .map(hodTime -> LocalDateTime.parse(hodTime, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")))
  533 + .min(Comparator.naturalOrder())
  534 + .orElse(null);
  535 + LocalDateTime latest = details.stream()
  536 + .map(OrderInfoResultVO::getOrderHodTime)
  537 + .map(hodTime -> LocalDateTime.parse(hodTime, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")))
  538 + .max(Comparator.naturalOrder())
  539 + .orElse(null);
  540 + businessProfitInfoVO.setProduceStartTime(earliest);
  541 + businessProfitInfoVO.setProduceEndTime(latest);
  542 + //研发复制费合计¥ 固定成本¥ 西班牙已发提成¥ 已发提成¥ 实际汇率¥
  543 + if (Objects.nonNull(noPrefix2ProjectProfitAnalysisDOMap.get(entry.getKey()))) {
  544 + ProjectBaseInfoDO projectBaseInfoDO = noPrefix2ProjectProfitAnalysisDOMap.get(entry.getKey());
  545 + //研发复制费用
  546 + businessProfitInfoVO.setDevelopmentCopyRmbTotalPrice(projectBaseInfoDO.getDevelopmentCopyRmbTotalPrice());
  547 + //西班牙已付提成
  548 + businessProfitInfoVO.setSpainPaidRmbCommission(projectBaseInfoDO.getSpainPaidRmbCommission());
  549 + //已付提成
  550 + businessProfitInfoVO.setPaidRmbCommission(projectBaseInfoDO.getPaidRmbCommission());
  551 + //实际汇率
  552 + businessProfitInfoVO.setActualExchangeRate(projectBaseInfoDO.getActualExchangeRate());
  553 + //项目开始时间
  554 + businessProfitInfoVO.setProjectStartTime(projectBaseInfoDO.getProjectStartTime());
  555 + //项目结束时间
  556 + businessProfitInfoVO.setProjectEndTime(projectBaseInfoDO.getProjectEndTime());
  557 + //生产开始时间
  558 + if (Objects.nonNull(projectBaseInfoDO.getProjectStartTime())
  559 + && Objects.nonNull(projectBaseInfoDO.getProjectEndTime())
  560 + && Objects.nonNull(systemSettingDOSMap.get(details.get(0).getCustomerCode()))) {
  561 +
  562 + //获取固定成本、提成比率、西班牙提成比例
  563 + long between = ChronoUnit.DAYS.between(projectBaseInfoDO.getProjectStartTime(), projectBaseInfoDO.getProjectEndTime());
  564 + SystemSettingDO systemSettingDO = systemSettingDOSMap.get(details.get(0).getCustomerCode());
  565 + String relationValue = systemSettingDO.getRelationValue();
  566 + List<Map<String, String>> relations = null;
  567 + try {
  568 + relations = objectMapper.readValue(relationValue, objectMapper.getTypeFactory().constructCollectionType(List.class, Map.class));
  569 + } catch (JsonProcessingException e) {
  570 + throw new RuntimeException(e);
  571 + }
  572 + String fixCostValue = null;
  573 + String ratio = null;
  574 + String spainRatio = null;
  575 + for (Map<String, String> relation : relations) {
  576 + if ("fixCost".equals(relation.get("relationCode"))) {
  577 + fixCostValue = relation.get("relationValue");
  578 + } else if ("ratio".equals(relation.get("relationCode"))) {
  579 + ratio = relation.get("relationValue");
  580 + } else if ("spainRatio".equals(relation.get("relationCode"))) {
  581 + spainRatio = relation.get("relationValue");
  582 + }
  583 + }
  584 + //固定成本
  585 + businessProfitInfoVO.setFixedCost(BigDecimal.valueOf(between * Double.parseDouble(fixCostValue)));
  586 + if (Objects.nonNull(spainRatio)
  587 + && Objects.nonNull(businessProfitInfoVO.getCustomerRmbTotalPrice())) {
  588 + //西班牙提成
  589 + businessProfitInfoVO.setSpainRmbCommission(BigDecimal.valueOf(businessProfitInfoVO.getCustomerRmbTotalPrice()).multiply(BigDecimal.valueOf(Double.parseDouble(spainRatio))));
  590 + }
  591 + if (Objects.nonNull(businessProfitInfoVO.getSpainRmbCommission())
  592 + && Objects.nonNull(projectBaseInfoDO.getSpainPaidRmbCommission())) {
  593 + //西班牙未发提成
  594 + businessProfitInfoVO.setSpainUnpaidRmbCommission(businessProfitInfoVO.getSpainRmbCommission().subtract(projectBaseInfoDO.getSpainPaidRmbCommission()));
  595 + }
  596 +
  597 + if (Objects.nonNull(ratio)
  598 + && Objects.nonNull(businessProfitInfoVO.getCustomerRmbTotalPrice())) {
  599 + //中国团队提成
  600 + businessProfitInfoVO.setRmbCommission(BigDecimal.valueOf(businessProfitInfoVO.getCustomerRmbTotalPrice()).multiply(BigDecimal.valueOf(Double.parseDouble(ratio))));
  601 + }
  602 + if (Objects.nonNull(businessProfitInfoVO.getRmbCommission())
  603 + && Objects.nonNull(projectBaseInfoDO.getPaidRmbCommission())) {
  604 + //未发提成
  605 + businessProfitInfoVO.setUnpaidRmbCommission(businessProfitInfoVO.getRmbCommission().subtract(projectBaseInfoDO.getPaidRmbCommission()));
  606 + }
  607 + }
  608 + if (Objects.nonNull(businessProfitInfoVO.getActualExchangeRate())
  609 + && Objects.nonNull(businessProfitInfoVO.getCustomerTotalPrice())) {
  610 + businessProfitInfoVO.setExchangeRateProfit(BigDecimal.valueOf(businessProfitInfoVO.getCustomerTotalPrice())
  611 + .multiply(businessProfitInfoVO.getActualExchangeRate().subtract(systemExchangeRate)));
  612 + }
  613 + }
  614 + //支出合计
  615 + businessProfitInfoVO.setRmbTotalExpense(Optional.ofNullable(businessProfitInfoVO.getSpainPaidRmbCommission()).orElse(BigDecimal.ZERO)
  616 + .add(Optional.ofNullable(businessProfitInfoVO.getPaidRmbCommission()).orElse(BigDecimal.ZERO))
  617 + .add(Optional.ofNullable(businessProfitInfoVO.getFixedCost()).orElse(BigDecimal.ZERO))
  618 + .add(Optional.ofNullable(businessProfitInfoVO.getDevelopmentCopyRmbTotalPrice()).orElse(BigDecimal.ZERO))
  619 + .add(BigDecimal.valueOf(Optional.ofNullable(businessProfitInfoVO.getPacketRmbTotalPrice()).orElse(0.0)))
  620 + .add(BigDecimal.valueOf(Optional.ofNullable(businessProfitInfoVO.getProductionDepartmentTotalPrice()).orElse(0.0))));
  621 + if (Objects.nonNull(businessProfitInfoVO.getCustomerRmbTotalPrice())
  622 + && Objects.nonNull(businessProfitInfoVO.getProductionDepartmentTotalPrice())
  623 + && Objects.nonNull(businessProfitInfoVO.getPacketRmbTotalPrice())) {
  624 + //毛利润
  625 + businessProfitInfoVO.setProfit(BigDecimal.valueOf(businessProfitInfoVO.getCustomerRmbTotalPrice())
  626 + .subtract(BigDecimal.valueOf(businessProfitInfoVO.getProductionDepartmentTotalPrice()))
  627 + .subtract(BigDecimal.valueOf(businessProfitInfoVO.getPacketRmbTotalPrice())));
  628 + }
  629 + if (Objects.nonNull(businessProfitInfoVO.getProfit())
  630 + && Objects.nonNull(businessProfitInfoVO.getCustomerRmbTotalPrice())) {
  631 + //毛利润率
  632 + businessProfitInfoVO.setProfitRate(businessProfitInfoVO.getProfit()
  633 + .divide(BigDecimal.valueOf(businessProfitInfoVO.getCustomerRmbTotalPrice()), 4, RoundingMode.HALF_UP));
  634 + }
  635 + if (Objects.nonNull(businessProfitInfoVO.getCustomerRmbTotalPrice())
  636 + && Objects.nonNull(businessProfitInfoVO.getRmbTotalExpense())) {
  637 + //研发贸易净利润
  638 + businessProfitInfoVO.setDevelopmentProfit(BigDecimal.valueOf(businessProfitInfoVO.getCustomerRmbTotalPrice())
  639 + .subtract(businessProfitInfoVO.getRmbTotalExpense())
  640 + );
  641 + //研发贸易净利润率
  642 + businessProfitInfoVO.setDevelopmentProfitRate(businessProfitInfoVO.getDevelopmentProfit()
  643 + .divide(BigDecimal.valueOf(businessProfitInfoVO.getCustomerRmbTotalPrice()), 4, RoundingMode.HALF_UP));
  644 + }
  645 + //综合收益
  646 + businessProfitInfoVO.setComprehensiveProfit(Optional.ofNullable(businessProfitInfoVO.getDevelopmentProfit()).orElse(BigDecimal.ZERO)
  647 + .add(Optional.ofNullable(businessProfitInfoVO.getExchangeRateProfit()).orElse(BigDecimal.ZERO))
  648 + .add(Optional.ofNullable(businessProfitInfoVO.getActualOrderRmbPrice()).orElse(BigDecimal.ZERO)));
  649 + return businessProfitInfoVO;
  650 + }).collect(Collectors.toList());
  651 + return businessProfitInfoVOs;
  652 + }
  653 +
  654 + @Override
  655 + public void exportBusinessProfitInfo(HttpServletResponse response, String projectNoPrefix) throws Exception {
  656 + ServerResult serverResult = listBusinessProfitInfoByPage(OrderBaseInfoQueryVO.builder().page(1).pageSize(1).projectNoLikeRight(projectNoPrefix).build());
  657 + Page<BusinessProfitInfoVO> page = (Page<BusinessProfitInfoVO>) serverResult.getData();
  658 + List<BusinessProfitInfoVO> orderInfoResultVOS = page.getRecords();
  659 + BusinessProfitInfoVO businessProfitInfoVO = orderInfoResultVOS.get(0);
  660 + exportBusinessProfitExcel(response, businessProfitInfoVO);
  661 + }
  662 + public void exportBusinessProfitExcel(HttpServletResponse response, BusinessProfitInfoVO businessProfitInfoVO) throws Exception {
  663 + DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
  664 + XSSFWorkbook workbook = new XSSFWorkbook();
  665 + Sheet sheet = workbook.createSheet("业务净利润分析");
  666 +
  667 + // 设置默认列宽
  668 + sheet.setDefaultColumnWidth(10);
  669 +
  670 + // 创建字体和样式
  671 + XSSFFont font = workbook.createFont();
  672 + font.setFontName("Arial");
  673 + font.setFontHeightInPoints((short) 10);
  674 +
  675 + CellStyle cellStyle = workbook.createCellStyle();
  676 + cellStyle.setAlignment(HorizontalAlignment.CENTER);
  677 + cellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
  678 + cellStyle.setFont(font);
  679 + cellStyle.setWrapText(true);
  680 +
  681 +
  682 + createMergedRow(sheet, cellStyle, 0, 3, 0, 9, "业务净利润分析表");
  683 + createMergedRow(sheet, cellStyle, 4, 5, 0, 1, "项目号");
  684 + createMergedRow(sheet, cellStyle, 4, 5, 2, 4, Optional.ofNullable(businessProfitInfoVO.getProjectNoPrefix()).orElse("-"));
  685 + createMergedRow(sheet, cellStyle, 4, 5, 5, 6, "开始时间");
  686 + createMergedRow(sheet, cellStyle, 4, 5, 7, 9, "结束时间");
  687 + createMergedRow(sheet, cellStyle, 6, 7, 0, 1, "");
  688 + createMergedRow(sheet, cellStyle, 6, 7, 2, 4, "项目开始时间");
  689 + createMergedRow(sheet, cellStyle, 6, 7, 5, 6, Optional.ofNullable(dateTimeFormatter.format(businessProfitInfoVO.getProjectStartTime())).orElse("-"));
  690 + createMergedRow(sheet, cellStyle, 6, 7, 7, 9, Optional.ofNullable(dateTimeFormatter.format(businessProfitInfoVO.getProjectEndTime())).orElse("-"));
  691 + createMergedRow(sheet, cellStyle, 8, 9, 0, 1, "");
  692 + createMergedRow(sheet, cellStyle, 8, 9, 2, 4, "生产进行时间");
  693 + createMergedRow(sheet, cellStyle, 8, 9, 5, 6, Optional.ofNullable(dateTimeFormatter.format(businessProfitInfoVO.getProduceStartTime())).orElse("-"));
  694 + createMergedRow(sheet, cellStyle, 8, 9, 7, 9, Optional.ofNullable(dateTimeFormatter.format(businessProfitInfoVO.getProduceEndTime())).orElse("-"));
  695 + createMergedRow(sheet, cellStyle, 10, 11, 0, 1, "客户编码");
  696 + createMergedRow(sheet, cellStyle, 10, 11, 2, 4, Optional.ofNullable(businessProfitInfoVO.getCustomerCode()).orElse("-"));
  697 + createMergedRow(sheet, cellStyle, 10, 11, 5, 6, "");
  698 + createMergedRow(sheet, cellStyle, 10, 11, 7, 9, "备注");
  699 + createMergedRow(sheet, cellStyle, 12, 13, 0, 4, "客户总金额计算");
  700 + createMergedRow(sheet, cellStyle, 12, 13, 5, 6, Optional.ofNullable(businessProfitInfoVO.getCustomerRmbTotalPrice()).map(price -> "¥" + price).orElse("-"));
  701 + createMergedRow(sheet, cellStyle, 12, 13, 7, 9, Optional.ofNullable(businessProfitInfoVO.getCustomerTotalPrice()).map(price -> "$" + price).orElse("-"));
  702 + createMergedRow(sheet, cellStyle, 14, 15, 0, 4, "生产科总价合计");
  703 + createMergedRow(sheet, cellStyle, 14, 15, 5, 6, Optional.ofNullable(businessProfitInfoVO.getProductionDepartmentTotalPrice()).map(price -> "¥" + price).orElse("-"));
  704 + createMergedRow(sheet, cellStyle, 14, 15, 7, 9,"");
  705 + createMergedRow(sheet, cellStyle, 16, 17, 0, 4, "包装费用合计");
  706 + createMergedRow(sheet, cellStyle, 16, 17, 5, 6, Optional.ofNullable(businessProfitInfoVO.getPacketRmbTotalPrice()).map(price -> "¥" + price).orElse("-"));
  707 + createMergedRow(sheet, cellStyle, 16, 17, 7, 9, Optional.ofNullable(businessProfitInfoVO.getPacketTotalPrice()).map(price -> "$" + price).orElse("-"));
  708 + createMergedRow(sheet, cellStyle, 18, 19, 0, 4, "研发复制费合计");
  709 + createMergedRow(sheet, cellStyle, 18, 19, 5, 6, Optional.ofNullable(businessProfitInfoVO.getDevelopmentCopyRmbTotalPrice()).map(price -> "¥" + price).orElse("-"));
  710 + createMergedRow(sheet, cellStyle, 18, 19, 7, 9,"");
  711 + createMergedRow(sheet, cellStyle, 20, 21, 0, 4, "固定成本");
  712 + createMergedRow(sheet, cellStyle, 20, 21, 5, 6, Optional.ofNullable(businessProfitInfoVO.getFixedCost()).map(price -> "¥" + price).orElse("-"));
  713 + createMergedRow(sheet, cellStyle, 20, 21, 7, 9,"");
  714 + createMergedRow(sheet, cellStyle, 22, 23, 0, 4, "西班牙提成");
  715 + createMergedRow(sheet, cellStyle, 22, 23, 5, 6, Optional.ofNullable(businessProfitInfoVO.getSpainRmbCommission()).map(price -> "¥" + price).orElse("-"));
  716 + createMergedRow(sheet, cellStyle, 22, 23, 7, 9,"");
  717 + createMergedRow(sheet, cellStyle, 24, 25, 0, 4, "中国团队提成");
  718 + createMergedRow(sheet, cellStyle, 24, 25, 5, 6, Optional.ofNullable(businessProfitInfoVO.getRmbCommission()).map(price -> "¥" + price).orElse("-"));
  719 + createMergedRow(sheet, cellStyle, 24, 25, 7, 9,"");
  720 + createMergedRow(sheet, cellStyle, 26, 27, 0, 4, "支出合计");
  721 + createMergedRow(sheet, cellStyle, 26, 27, 5, 6, Optional.ofNullable(businessProfitInfoVO.getRmbTotalExpense()).map(price -> "¥" + price).orElse("-"));
  722 + createMergedRow(sheet, cellStyle, 26, 27, 7, 9,"");
  723 + createMergedRow(sheet, cellStyle, 28, 29, 0, 4, "毛利润");
  724 + createMergedRow(sheet, cellStyle, 28, 29, 5, 6, Optional.ofNullable(businessProfitInfoVO.getProfit()).map(price -> "¥" + price).orElse("-"));
  725 + createMergedRow(sheet, cellStyle, 28, 29, 7, 9,"");
  726 + createMergedRow(sheet, cellStyle, 30, 31, 0, 4, "毛利率");
  727 + createMergedRow(sheet, cellStyle, 30, 31, 5, 6, Optional.ofNullable(businessProfitInfoVO.getProfitRate()).map(rate -> rate.multiply(new BigDecimal(100)) + "%").orElse("-"));
  728 + createMergedRow(sheet, cellStyle, 30, 31, 7, 9,"");
  729 + createMergedRow(sheet, cellStyle, 32, 33, 0, 4, "研发贸易净利润");
  730 + createMergedRow(sheet, cellStyle, 32, 33, 5, 6, Optional.ofNullable(businessProfitInfoVO.getDevelopmentProfit()).map(price -> "¥" + price).orElse("-"));
  731 + createMergedRow(sheet, cellStyle, 32, 33, 7, 9,"");
  732 + createMergedRow(sheet, cellStyle, 34, 35, 0, 4, "研发贸易净利润率");
  733 + createMergedRow(sheet, cellStyle, 34, 35, 5, 6, Optional.ofNullable(businessProfitInfoVO.getDevelopmentProfitRate()).map(rate -> rate.multiply(new BigDecimal(100)) + "%").orElse("-"));
  734 + createMergedRow(sheet, cellStyle, 34, 35, 7, 9,"");
  735 + createMergedRow(sheet, cellStyle, 36, 37, 0, 4, "包装费用合计金额");
  736 + createMergedRow(sheet, cellStyle, 36, 37, 5, 6, Optional.ofNullable(businessProfitInfoVO.getPacketRmbTotalPrice()).map(price -> "¥" + price).orElse("-"));
  737 + createMergedRow(sheet, cellStyle, 36, 37, 7, 9,"");
  738 + createMergedRow(sheet, cellStyle, 38, 39, 0, 4, "包装费用实际金额");
  739 + createMergedRow(sheet, cellStyle, 38, 39, 5, 6, Optional.ofNullable(businessProfitInfoVO.getPacketActualRmbTotalPrice()).map(price -> "¥" + price).orElse("-"));
  740 + createMergedRow(sheet, cellStyle, 38, 39, 7, 9,"");
  741 + createMergedRow(sheet, cellStyle, 40, 41, 0, 4, "订单总数量");
  742 + createMergedRow(sheet, cellStyle, 40, 41, 5, 6, Optional.ofNullable(businessProfitInfoVO.getOrderCount()).map(String::valueOf).orElse("-"));
  743 + createMergedRow(sheet, cellStyle, 40, 41, 7, 9,"");
  744 + createMergedRow(sheet, cellStyle, 42, 43, 0, 4, "实际跟单单价=实际跟单费用/件数");
  745 + createMergedRow(sheet, cellStyle, 42, 43, 5, 6, Optional.ofNullable(businessProfitInfoVO.getActualOrderRmbPrice()).map(price -> "¥" + price).orElse("-"));
  746 + createMergedRow(sheet, cellStyle, 42, 43, 7, 9,"");
  747 + createMergedRow(sheet, cellStyle, 44, 45, 0, 4, "实际跟单单价折算美金");
  748 + createMergedRow(sheet, cellStyle, 44, 45, 5, 6, Optional.ofNullable(businessProfitInfoVO.getActualOrderPrice()).map(price -> "$" + price).orElse("-"));
  749 + createMergedRow(sheet, cellStyle, 44, 45, 7, 9,"");
  750 + createMergedRow(sheet, cellStyle, 46, 47, 0, 4, "包装费用收益");
  751 + createMergedRow(sheet, cellStyle, 46, 47, 5, 6, Optional.ofNullable(businessProfitInfoVO.getPacketProfitRmbPrice()).map(price -> "¥" + price).orElse("-"));
  752 + createMergedRow(sheet, cellStyle, 46, 47, 7, 9,"");
  753 + createMergedRow(sheet, cellStyle, 48, 49, 0, 4, "包装费用净利润率");
  754 + createMergedRow(sheet, cellStyle, 48, 49, 5, 6, Optional.ofNullable(businessProfitInfoVO.getPacketProfitRate()).map(rate -> rate.multiply(new BigDecimal(100)) + "%").orElse("-"));
  755 + createMergedRow(sheet, cellStyle, 48, 49, 7, 9,"");
  756 + createMergedRow(sheet, cellStyle, 50, 51, 0, 4, "实际汇率");
  757 + createMergedRow(sheet, cellStyle, 50, 51, 5, 6, Optional.ofNullable(businessProfitInfoVO.getActualExchangeRate()).map(String::valueOf).orElse("-"));
  758 + createMergedRow(sheet, cellStyle, 50, 51, 7, 9,"");
  759 + createMergedRow(sheet, cellStyle, 52, 53, 0, 4, "汇率收益");
  760 + createMergedRow(sheet, cellStyle, 52, 53, 5, 6, Optional.ofNullable(businessProfitInfoVO.getExchangeRateProfit()).map(price -> "¥" + price).orElse("-"));
  761 + createMergedRow(sheet, cellStyle, 52, 53, 7, 9,"");
  762 + createMergedRow(sheet, cellStyle, 54, 55, 0, 4, "综合收益");
  763 + createMergedRow(sheet, cellStyle, 54, 55, 5, 6, Optional.ofNullable(businessProfitInfoVO.getComprehensiveProfit()).map(price -> "¥" + price).orElse("-"));
  764 + createMergedRow(sheet, cellStyle, 54, 55, 7, 9,"");
  765 +
  766 + // 设置响应头
  767 + response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
  768 + response.setHeader("Content-Disposition", "attachment;filename=BusinessProfitAnalysis.xlsx");
  769 + try (OutputStream out = response.getOutputStream()) {
  770 + workbook.write(out);
  771 + } finally {
  772 + workbook.close();
  773 + }
  774 + }
  775 +
  776 + @Override
  777 + public void exportInnerProfitInfo(HttpServletResponse response, String projectNoPrefix) throws Exception {
  778 + ServerResult serverResult = listInnerProfitInfoByPage(OrderBaseInfoQueryVO.builder().page(1).pageSize(1).projectNoLikeRight(projectNoPrefix).build());
  779 + Page<InnerProfitInfoVO> page = (Page<InnerProfitInfoVO>) serverResult.getData();
  780 + List<InnerProfitInfoVO> profitInfoVOS = page.getRecords();
  781 + InnerProfitInfoVO ProfitInfoVO = profitInfoVOS.get(0);
  782 + exportInnerProfitExcel(response, ProfitInfoVO);
  783 + }
  784 +
  785 + public void exportInnerProfitExcel(HttpServletResponse response, InnerProfitInfoVO vo) throws Exception {
  786 + DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
  787 + XSSFWorkbook workbook = new XSSFWorkbook();
  788 + Sheet sheet = workbook.createSheet("内部生产净利润分析");
  789 + sheet.setDefaultColumnWidth(10);
  790 +
  791 + // 设置字体和样式
  792 + XSSFFont font = workbook.createFont();
  793 + font.setFontName("Arial");
  794 + font.setFontHeightInPoints((short) 10);
  795 +
  796 + CellStyle cellStyle = workbook.createCellStyle();
  797 + cellStyle.setAlignment(HorizontalAlignment.CENTER);
  798 + cellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
  799 + cellStyle.setFont(font);
  800 + cellStyle.setWrapText(true);
  801 +
  802 + // 第一部分:表头
  803 + createMergedRow(sheet, cellStyle, 0, 3, 0, 9, "内部生产净利润分析表");
  804 +
  805 + // 第二部分:项目信息
  806 + createMergedRow(sheet, cellStyle, 4, 5, 0, 1, "项目号");
  807 + createMergedRow(sheet, cellStyle, 4, 5, 2, 3, Optional.ofNullable(vo.getProjectNoPrefix()).orElse("-"));
  808 + createMergedRow(sheet, cellStyle, 4, 5, 4, 5, "开始时间");
  809 + createMergedRow(sheet, cellStyle, 4, 5, 6, 7, "结束时间");
  810 + createMergedRow(sheet, cellStyle, 4, 5, 8, 9, "生产持续时间");
  811 +
  812 + String projectStartTime = Optional.ofNullable(vo.getProduceStartTime()).map(dateTimeFormatter::format).orElse("-");
  813 + String projectEndTime = Optional.ofNullable(vo.getProduceEndTime()).map(dateTimeFormatter::format).orElse("-");
  814 + String duration = (vo.getProduceStartTime() != null && vo.getProduceEndTime() != null)
  815 + ? String.valueOf(Duration.between(vo.getProduceStartTime(), vo.getProduceEndTime()).toDays())
  816 + : "-";
  817 + createMergedRow(sheet, cellStyle, 6, 7, 0, 1, "");
  818 + createMergedRow(sheet, cellStyle, 6, 7, 2, 3, "生产起止时间");
  819 + createMergedRow(sheet, cellStyle, 6, 7, 4, 5, projectStartTime);
  820 + createMergedRow(sheet, cellStyle, 6, 7, 6, 7, projectEndTime);
  821 + createMergedRow(sheet, cellStyle, 6, 7, 8, 9, duration);
  822 +
  823 + // 第三部分:客户和订单信息
  824 + createMergedRow(sheet, cellStyle, 8, 9, 0, 1, "客户编码");
  825 + createMergedRow(sheet, cellStyle, 8, 9, 2, 3, Optional.ofNullable(vo.getCustomerCode()).orElse("-"));
  826 + createMergedRow(sheet, cellStyle, 8, 9, 4, 5, "明细");
  827 + createMergedRow(sheet, cellStyle, 8, 9, 6, 7, "金额");
  828 + createMergedRow(sheet, cellStyle, 8, 9, 8, 9, "订单数量");
  829 +
  830 + // 第四部分:生产科总价合计
  831 + createMergedRow(sheet, cellStyle, 10, 11, 0, 3, "生产科总价合计");
  832 + createMergedRow(sheet, cellStyle, 10, 11, 4, 5, "¥" + Optional.ofNullable(vo.getProductionDepartmentTotalPrice()).orElse(0.0));
  833 + createMergedRow(sheet, cellStyle, 10, 11, 6, 7, "¥" + Optional.ofNullable(vo.getProductionDepartmentTotalPrice()).orElse(0.0));
  834 + createMergedRow(sheet, cellStyle, 10, 11, 8, 9, Optional.ofNullable(vo.getOrderCount()).map(String::valueOf).orElse("-"));
  835 +
  836 + // 第五部分:预算与实际
  837 + createMergedRow(sheet, cellStyle, 12, 13, 0, 3, "生产科预算金额");
  838 + createMergedRow(sheet, cellStyle, 12, 13, 4, 5, "¥" + Optional.ofNullable(vo.getProductionDepartmentPredictPrice()).map(String::valueOf).orElse("-"));
  839 + createMergedRow(sheet, cellStyle, 12, 13, 6, 7, "预算占比");
  840 + createMergedRow(sheet, cellStyle, 12, 13, 8, 9, "预算占比与实际占比差");
  841 +
  842 + createMergedRow(sheet, cellStyle, 14, 15, 0, 3, "实际发生费用");
  843 + createMergedRow(sheet, cellStyle, 14, 15, 4, 5, "¥" + Optional.ofNullable(vo.getProductionActualPrice()).orElse(BigDecimal.ZERO));
  844 + createMergedRow(sheet, cellStyle, 14, 15, 6, 7, Optional.ofNullable(vo.getPredictRatio()).map(r -> r.multiply(BigDecimal.valueOf(100)) + "%").orElse("-"));
  845 + createMergedRow(sheet, cellStyle, 14, 15, 8, 9, Optional.ofNullable(vo.getPredictAndActualRatio()).map(r -> r.multiply(BigDecimal.valueOf(100)) + "%").orElse("-"));
  846 +
  847 + // 第六部分:毛利润
  848 + createMergedRow(sheet, cellStyle, 16, 17, 0, 3, "内部生产毛利润");
  849 + createMergedRow(sheet, cellStyle, 16, 17, 4, 5, "¥" + Optional.ofNullable(vo.getBeforeGrossProfit()).orElse(BigDecimal.ZERO));
  850 + createMergedRow(sheet, cellStyle, 16, 16, 6, 7, "事前毛利润");
  851 + createMergedRow(sheet, cellStyle, 16, 16, 8, 9, "事前毛利率");
  852 + createMergedRow(sheet, cellStyle, 17, 17, 6, 7, Optional.ofNullable(vo.getBeforeGrossProfit()).orElse(BigDecimal.ZERO).toString());
  853 + createMergedRow(sheet, cellStyle, 17, 17, 8, 9, Optional.ofNullable(vo.getBeforeGrossProfitRate()).map(r -> r.multiply(BigDecimal.valueOf(100)) + "%").orElse("-"));
  854 +
  855 + // 第七部分:固定成本与净利润
  856 + createMergedRow(sheet, cellStyle, 18, 19, 0, 3, "内部生产固定成本");
  857 + createMergedRow(sheet, cellStyle, 18, 19, 4, 5, "¥" + Optional.ofNullable(vo.getInnerProductionFixedCost()).orElse(BigDecimal.ZERO));
  858 + createMergedRow(sheet, cellStyle, 18, 18, 6, 7, "事后毛利润");
  859 + createMergedRow(sheet, cellStyle, 18, 18, 8, 9, "事后毛利率");
  860 + createMergedRow(sheet, cellStyle, 19, 19, 6, 7, Optional.ofNullable(vo.getGrossProfit()).orElse(BigDecimal.ZERO).toString());
  861 + createMergedRow(sheet, cellStyle, 19, 19, 8, 9, Optional.ofNullable(vo.getGrossProfitRate()).map(r -> r.multiply(BigDecimal.valueOf(100)) + "%").orElse("-"));
  862 +
  863 + // 第八部分:提成与净利润
  864 + createMergedRow(sheet, cellStyle, 20, 21, 0, 3, "内部生产提成");
  865 + createMergedRow(sheet, cellStyle, 20, 21, 4, 5, "¥" + Optional.ofNullable(vo.getInnerProductionCommission()).orElse(BigDecimal.ZERO));
  866 + createMergedRow(sheet, cellStyle, 20, 21, 6, 7, "净利润");
  867 + createMergedRow(sheet, cellStyle, 20, 21, 8, 9, "");
  868 +
  869 + createMergedRow(sheet, cellStyle, 22, 23, 0, 3, "内部生产净利润");
  870 + createMergedRow(sheet, cellStyle, 22, 23, 4, 5, "¥" + Optional.ofNullable(vo.getInnerProductionProfit()).orElse(BigDecimal.ZERO));
  871 + createMergedRow(sheet, cellStyle, 22, 23, 6, 7, Optional.ofNullable(vo.getInnerProductionProfitRate()).map(r -> r.multiply(BigDecimal.valueOf(100)) + "%").orElse("-"));
  872 + createMergedRow(sheet, cellStyle, 22, 23, 8, 9, "");
  873 +
  874 + // 设置响应头
  875 + response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
  876 + response.setHeader("Content-Disposition", "attachment;filename=BusinessProfitAnalysis.xlsx");
  877 + try (OutputStream out = response.getOutputStream()) {
  878 + workbook.write(out);
  879 + } finally {
  880 + workbook.close();
  881 + }
  882 + }
  883 +
  884 + private void createMergedRow(Sheet sheet, CellStyle cellStyle, int startRow, int endRow, int startCol, int endCol, String value) {
  885 + for (int i = startRow; i <= endRow; i++) {
  886 + Row row = sheet.getRow(i);
  887 + if (row == null) {
  888 + row = sheet.createRow(i);
  889 + }
  890 + for (int j = startCol; j <= endCol; j++) {
  891 + Cell cell = row.createCell(j);
  892 + cell.setCellStyle(cellStyle);
  893 + if (i == startRow && j == startCol) {
  894 + cell.setCellValue(value);
  895 + }
  896 + }
  897 + }
  898 + sheet.addMergedRegion(new CellRangeAddress(startRow, endRow, startCol, endCol));
  899 + }
  900 +
  901 +}
src/main/resources/mapper/OrderCostFieldLockRecordMapper.xml 0 → 100644
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
  3 +<mapper namespace="com.order.erp.mapper.OrderCostFieldLockRecordMapper">
  4 +
  5 + <!-- 通用查询映射结果 -->
  6 + <resultMap id="BaseResultMap" type="com.order.erp.domain.model.OrderCostFieldLockRecord">
  7 + <id column="id" property="id" />
  8 + <result column="fields" property="fields" />
  9 + <result column="user_id" property="userId" />
  10 + <result column="order_id" property="orderId" />
  11 + <result column="enable_flag" property="enableFlag" />
  12 + <result column="create_time" property="createTime" />
  13 + <result column="create_by" property="createBy" />
  14 + <result column="modify_time" property="modifyTime" />
  15 + <result column="modify_by" property="modifyBy" />
  16 + <result column="version" property="version" />
  17 + </resultMap>
  18 +
  19 + <!-- 通用查询结果列 -->
  20 + <sql id="Base_Column_List">
  21 + id, fields, user_id, order_id, enable_flag, create_time, create_by, modify_time, modify_by, version
  22 + </sql>
  23 +
  24 +</mapper>
src/main/resources/mapper/OrderCostInfoMapper.xml 0 → 100644
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
  3 +<mapper namespace="com.order.erp.mapper.order.OrderCostInfoMapper">
  4 +
  5 + <!-- 通用查询映射结果 -->
  6 + <resultMap id="BaseResultMap" type="com.order.erp.domain.dto.order.OrderCostInfoDO">
  7 + <id column="id" property="id" />
  8 + <result column="production_department_predict_price" property="productionDepartmentPredictPrice" />
  9 + <result column="production_actual_price" property="productionActualPrice" />
  10 + <result column="packet_actual_rmb_total_price" property="packetActualRmbTotalPrice" />
  11 + </resultMap>
  12 +
  13 + <!-- 通用查询结果列 -->
  14 + <sql id="Base_Column_List">
  15 + id, production_department_predict_price, production_actual_price, packet_actual_rmb_total_price
  16 + </sql>
  17 +
  18 +</mapper>
src/main/resources/mapper/ProjectApplyMapper.xml 0 → 100644
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
  3 +<mapper namespace="com.order.erp.mapper.ProjectApplyMapper">
  4 +
  5 + <!-- 通用查询映射结果 -->
  6 + <resultMap id="BaseResultMap" type="com.order.erp.domain.model.ProjectApplyDO">
  7 + <id column="id" property="id" />
  8 + <result column="project_id" property="projectId" />
  9 + <result column="apply_user_id" property="applyUserId" />
  10 + <result column="audit_user_id" property="auditUserId" />
  11 + <result column="fields" property="fields" />
  12 + <result column="status" property="status" />
  13 + <result column="audit_remark" property="auditRemark" />
  14 + <result column="audit_role_codes" property="auditRoleCodes" />
  15 + <result column="apply_remark" property="applyRemark" />
  16 + <result column="enable_flag" property="enableFlag" />
  17 + <result column="create_time" property="createTime" />
  18 + <result column="create_by" property="createBy" />
  19 + <result column="modify_time" property="modifyTime" />
  20 + <result column="modify_by" property="modifyBy" />
  21 + <result column="version" property="version" />
  22 + </resultMap>
  23 +
  24 + <!-- 通用查询结果列 -->
  25 + <sql id="Base_Column_List">
  26 + id, project_id, apply_user_id, audit_user_id, fields, status, audit_remark, audit_role_codes, apply_remark, enable_flag, create_time, create_by, modify_time, modify_by, version
  27 + </sql>
  28 +
  29 +</mapper>
src/main/resources/mapper/ProjectFieldLockRecordMapper.xml 0 → 100644
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
  3 +<mapper namespace="com.order.erp.mapper.ProjectFieldLockRecordMapper">
  4 +
  5 + <!-- 通用查询映射结果 -->
  6 + <resultMap id="BaseResultMap" type="com.order.erp.domain.model.ProjectFieldLockRecord">
  7 + <id column="id" property="id" />
  8 + <result column="project_id" property="projectId" />
  9 + <result column="user_id" property="userId" />
  10 + <result column="fields" property="fields" />
  11 + <result column="enable_flag" property="enableFlag" />
  12 + <result column="create_time" property="createTime" />
  13 + <result column="create_by" property="createBy" />
  14 + <result column="modify_time" property="modifyTime" />
  15 + <result column="modify_by" property="modifyBy" />
  16 + <result column="version" property="version" />
  17 + </resultMap>
  18 +
  19 + <!-- 通用查询结果列 -->
  20 + <sql id="Base_Column_List">
  21 + id, project_id, user_id, fields, enable_flag, create_time, create_by, modify_time, modify_by, version
  22 + </sql>
  23 +
  24 +</mapper>