From 34981c30a78e8bbd7791131059a9210f9928b62c Mon Sep 17 00:00:00 2001
From: 刘光辉 <347230014@qq.com>
Date: 星期四, 17 九月 2026 09:24:09 +0800
Subject: [PATCH] Merge remote-tracking branch 'origin/master' into master
---
jnpf-lims/jnpf-lims-biz/src/main/java/jnpf/limsService/impl/LimsHaocaiServiceImpl.java | 1266 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 1,266 insertions(+), 0 deletions(-)
diff --git a/jnpf-lims/jnpf-lims-biz/src/main/java/jnpf/limsService/impl/LimsHaocaiServiceImpl.java b/jnpf-lims/jnpf-lims-biz/src/main/java/jnpf/limsService/impl/LimsHaocaiServiceImpl.java
new file mode 100644
index 0000000..146d5aa
--- /dev/null
+++ b/jnpf-lims/jnpf-lims-biz/src/main/java/jnpf/limsService/impl/LimsHaocaiServiceImpl.java
@@ -0,0 +1,1266 @@
+package jnpf.limsService.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
+import jnpf.audit.sdk.annotation.AuditLog;
+import jnpf.base.ActionResult;
+import jnpf.base.BillRuleApi;
+import jnpf.base.UserInfo;
+import jnpf.base.service.SuperServiceImpl;
+import jnpf.exception.DataException;
+import jnpf.limsEntity.LimsHaocaiChukuEntity;
+import jnpf.limsEntity.LimsHaocaiChukuShenqingEntity;
+import jnpf.limsEntity.LimsHaocaiChukuShenqingZixiangEntity;
+import jnpf.limsEntity.LimsHaocaiChukuZixiangEntity;
+import jnpf.limsEntity.LimsHaocaiJiechuEntity;
+import jnpf.limsEntity.LimsHaocaiLogEntity;
+import jnpf.limsEntity.LimsHaocaiRukuEntity;
+import jnpf.limsEntity.LimsHaocaiRukuSubmitResult;
+import jnpf.limsEntity.LimsHaocaiRukuYanshouEntity;
+import jnpf.limsEntity.LimsHaocaiRukuZixiangEntity;
+import jnpf.limsEntity.LimsHaocaiXiaohuiShenqingEntity;
+import jnpf.limsEntity.LimsHaocaiXiaohuiShenqingZixiangEntity;
+import jnpf.limsEntity.LimsHaocaiYanshouShenqingEntity;
+import jnpf.limsMapper.LimsHaocaiChukuShenqingMapper;
+import jnpf.limsMapper.LimsHaocaiChukuShenqingZixiangMapper;
+import jnpf.limsMapper.LimsHaocaiChukuZixiangMapper;
+import jnpf.limsMapper.LimsHaocaiJiechuMapper;
+import jnpf.limsMapper.LimsHaocaiLogMapper;
+import jnpf.limsMapper.LimsHaocaiRukuMapper;
+import jnpf.limsMapper.LimsHaocaiRukuYanshouMapper;
+import jnpf.limsMapper.LimsHaocaiRukuZixiangMapper;
+import jnpf.limsMapper.LimsHaocaiXiaohuiShenqingMapper;
+import jnpf.limsMapper.LimsHaocaiXiaohuiShenqingZixiangMapper;
+import jnpf.limsMapper.LimsHaocaiYanshouShenqingMapper;
+import jnpf.limsService.LimsHaocaiService;
+import jnpf.util.RandomUtil;
+import jnpf.util.StringUtil;
+import jnpf.util.UserProvider;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * 鑰楁潗涓氬姟鏈嶅姟瀹炵幇銆傚瓙琛� lims_haocai_ruku_zixiang 涓嶅崟璁� service锛�
+ * 缁� Mapper 鐩存帴璇诲啓锛堝钩鍙� ProductServiceImpl 鍚屾妯″紡锛夈��
+ */
+@Slf4j
+@Service
+public class LimsHaocaiServiceImpl
+ extends SuperServiceImpl<LimsHaocaiRukuMapper, LimsHaocaiRukuEntity>
+ implements LimsHaocaiService {
+
+ /** 鏉$爜缂栫爜鐨勫崟鎹鍒� enCode锛坆ase_bill_rule锛孒C_ + YYYYMMDD + 6浣嶆祦姘达級 */
+ private static final String TIAOMA_BILL_RULE = "haocai_ruku_tiaoma";
+
+ /** 瀛愯〃鍒濆鐘舵�侊細鏈嚭搴� */
+ private static final String BIZ_STATUS_WEICHUKU = "weichuku";
+
+ /** 瀛愯〃鐘舵�侊細宸插嚭搴� */
+ private static final String BIZ_STATUS_YICHUKU = "yichuku";
+
+ /** 瀛愯〃鐘舵�侊細宸插紑鐡� */
+ private static final String BIZ_STATUS_YIKAIPING = "yikaiping";
+
+ /** 瀛愯〃鐘舵�侊細宸查攢姣� */
+ private static final String BIZ_STATUS_YIXIAOHUI = "yixiaohui";
+
+ /** 瀛愯〃鐘舵�侊細寰呴攢姣� */
+ private static final String BIZ_STATUS_DAIXIAOHUI = "daixiaohui";
+
+ /** 鐢抽娴佺▼鐘舵�侊細宸查�氳繃 */
+ private static final int FLOW_STATE_APPROVED = 2;
+
+ /** 鍊熷嚭鍗曠姸鎬侊細宸插�熷嚭 */
+ private static final String JIECHU_STATUS_LENT = "lent";
+
+ /** 鍊熷嚭鍗曠姸鎬侊細宸插綊杩� */
+ private static final String JIECHU_STATUS_RETURNED = "returned";
+
+ /** 鑰楁潗鏃ュ織鎿嶄綔绫诲瀷锛氬叆搴� */
+ private static final String LOG_ACTION_RUKU = "鑰楁潗鍏ュ簱";
+
+ /** 鑰楁潗鏃ュ織鎿嶄綔绫诲瀷锛氬�熷嚭 */
+ private static final String LOG_ACTION_JIECHU = "鑰楁潗鍊熷嚭";
+
+ /** 鑰楁潗鏃ュ織鎿嶄綔绫诲瀷锛氬綊杩� */
+ private static final String LOG_ACTION_GUIHUAN = "鑰楁潗褰掕繕";
+
+ /** 鑰楁潗鏃ュ織鎿嶄綔绫诲瀷锛氬嚭搴� */
+ private static final String LOG_ACTION_CHUKU = "鑰楁潗鍑哄簱";
+
+ /** 鑰楁潗鏃ュ織鎿嶄綔绫诲瀷锛氶攢姣� */
+ private static final String LOG_ACTION_XIAOHUI = "鑰楁潗閿�姣�";
+
+ /** 楠屾敹鐘舵�侊細宸查獙鏀� */
+ private static final String YANSHOU_STATUS_YIYANSHOU = "yiyanshou";
+
+ /** 楠屾敹鐘舵�侊細涓嶉�傜敤 */
+ private static final String YANSHOU_STATUS_NA = "na";
+
+ /** 鑰楁潗楠屾敹鐢宠鐘舵�侊細寰呴獙鏀� */
+ private static final String YANSHOU_SHENQING_STATUS_DAIYANSHOU = "daiyanshou";
+
+ /** 鑰楁潗楠屾敹鐢宠鐘舵�侊細楠屾敹涓� */
+ private static final String YANSHOU_SHENQING_STATUS_YANSHOUZHONG = "yanshouzhong";
+
+ /** 鑰楁潗楠屾敹鐢宠鐘舵�侊細宸查獙鏀� */
+ private static final String YANSHOU_SHENQING_STATUS_YIYANSHOU = "yiyanshou";
+
+ @Autowired
+ private BillRuleApi billRuleApi;
+
+ @Autowired
+ private LimsHaocaiRukuZixiangMapper zixiangMapper;
+
+ @Autowired
+ private LimsHaocaiJiechuMapper jiechuMapper;
+
+ @Autowired
+ private LimsHaocaiChukuShenqingMapper chukuShenqingMapper;
+
+ @Autowired
+ private LimsHaocaiChukuShenqingZixiangMapper chukuShenqingZixiangMapper;
+
+ @Autowired
+ private LimsHaocaiChukuZixiangMapper chukuZixiangMapper;
+
+ @Autowired
+ private LimsHaocaiLogMapper haocaiLogMapper;
+
+ @Autowired
+ private LimsHaocaiXiaohuiShenqingMapper xiaohuiShenqingMapper;
+
+ @Autowired
+ private LimsHaocaiXiaohuiShenqingZixiangMapper xiaohuiShenqingZixiangMapper;
+
+ @Autowired
+ private LimsHaocaiYanshouShenqingMapper yanshouShenqingMapper;
+
+ @Autowired
+ private LimsHaocaiRukuYanshouMapper rukuYanshouMapper;
+
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ @AuditLog(action = "RUKU_SUBMIT", label = "鑰楁潗鍏ュ簱鎻愪氦", bizType = "HAOCAI",
+ bizCodeExpr = "", bizCodeRequired = false, targetTable = "lims_haocai_ruku",
+ targetIdExpr = "#ruku.id", diff = true, entityClass = LimsHaocaiRukuEntity.class)
+ public LimsHaocaiRukuSubmitResult submitRuku(LimsHaocaiRukuEntity ruku) throws DataException {
+ BigDecimal shuliang = parseShuliang(ruku.getRukuShuliang());
+ BigDecimal rongliang = parseRongliang(ruku.getRongliang());
+ String yanshouZhuangtai = resolveYanshouZhuangtai(ruku);
+ ruku.setYanshouZhuangtai(yanshouZhuangtai);
+ ruku.setBizStatus(BIZ_STATUS_WEICHUKU);
+ if (!this.updateById(ruku)) {
+ throw new DataException("鍏ュ簱鍗曠姸鎬佹洿鏂板け璐ワ細" + ruku.getId());
+ }
+ if (isYanshouEnabled(ruku)) {
+ updateRukuYanshouRukuId(ruku);
+ }
+
+ boolean yigeTiaoma = "yes".equalsIgnoreCase(trimToEmpty(ruku.getShifouYigeTiaoma()));
+ int completeCount = calculateCompleteTiaomaCount(shuliang, ruku.getRukuShuliang());
+ BigDecimal fractionalQuantity = shuliang.remainder(BigDecimal.ONE);
+ int count = yigeTiaoma ? 1 : completeCount + (fractionalQuantity.signum() > 0 ? 1 : 0);
+ // 涓�涓潯鐮侊細鎬婚噺 = 鍏ュ簱鏁伴噺 脳 瀹归噺锛涘涓潯鐮侊細鏁存暟閮ㄥ垎姣忔潯涓哄閲忥紝灏忔暟閮ㄥ垎鎸夋瘮渚嬬敓鎴愭渶鍚庝竴鏉°��
+ BigDecimal singleTiaomaZongliang = rongliang.multiply(shuliang);
+
+ // 缂栧彿 = 鎵瑰彿 + "-" + 搴忓彿锛屽簭鍙锋寜鏈壒鎬绘潯鏁板姩鎬佽ˉ闆讹紙3鈫�1浣嶃��20鈫�2浣嶃��100鈫�3浣嶏級锛�
+ // 鏁伴噺澶氬ぇ閮借嚜閫傚簲锛涙壒鍙蜂负绌烘椂鍥為��鐢ㄤ富琛� id锛岄伩鍏嶇紪鍙风己鍓嶇紑
+ String bianhaoPrefix = trimToEmpty(ruku.getPihao());
+ if (bianhaoPrefix.isEmpty()) {
+ bianhaoPrefix = ruku.getId();
+ }
+ int width = String.valueOf(count).length();
+ List<String> tiaomaBianmaList = new ArrayList<>(count);
+ List<String> bianhaoList = new ArrayList<>(count);
+ for (int i = 1; i <= count; i++) {
+ String tiaomaBianma = nextTiaomaBianma();
+ String bianhao = bianhaoPrefix + "-" + String.format("%0" + width + "d", i);
+ BigDecimal zongliang = yigeTiaoma
+ ? singleTiaomaZongliang
+ : (i > completeCount ? rongliang.multiply(fractionalQuantity) : rongliang);
+ tiaomaBianmaList.add(tiaomaBianma);
+ bianhaoList.add(bianhao);
+ LimsHaocaiRukuZixiangEntity zixiang =
+ buildZixiang(ruku, tiaomaBianma, bianhao, toPlainString(zongliang), yanshouZhuangtai);
+ zixiangMapper.insert(zixiang);
+ haocaiLogMapper.insert(buildRukuLog(ruku, zixiang));
+ }
+
+ log.info("鑰楁潗鍏ュ簱鎻愪氦瀹屾垚锛歳ukuId={}, tiaomaList={}, count={}, rukuShuliang={}",
+ ruku.getId(), tiaomaBianmaList, count, ruku.getRukuShuliang());
+
+ LimsHaocaiRukuSubmitResult result = new LimsHaocaiRukuSubmitResult();
+ result.setTiaomaBianma(tiaomaBianmaList.isEmpty() ? null : tiaomaBianmaList.get(0));
+ result.setTiaomaBianmaList(tiaomaBianmaList);
+ result.setBianhaoList(bianhaoList);
+ result.setCount(count);
+ return result;
+ }
+
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ @AuditLog(action = "JIECHU_SUBMIT", label = "鑰楁潗鍊熷嚭鎻愪氦", bizType = "HAOCAI",
+ bizCodeExpr = "", bizCodeRequired = false, targetTable = "lims_haocai_jiechu",
+ targetIdExpr = "#jiechu.id", diff = true, entityClass = LimsHaocaiJiechuEntity.class)
+ public void submitJiechu(LimsHaocaiJiechuEntity jiechu) throws DataException {
+ String tiaomaBianma = trimToEmpty(jiechu == null ? null : jiechu.getTiaomaBianma());
+ if (tiaomaBianma.isEmpty()) {
+ throw new DataException("鏉$爜缂栫爜涓嶈兘涓虹┖");
+ }
+
+ List<LimsHaocaiRukuZixiangEntity> list = listRukuZixiangByTiaomaBianma(tiaomaBianma);
+ if (list == null || list.isEmpty()) {
+ throw new DataException("鏈壘鍒板搴旂殑鑰楁潗鍏ュ簱瀛愰」锛�" + tiaomaBianma);
+ }
+
+ LimsHaocaiRukuZixiangEntity zixiang = list.get(0);
+ String bizStatus = trimToEmpty(zixiang.getBizStatus());
+ if (BIZ_STATUS_YICHUKU.equalsIgnoreCase(bizStatus)) {
+ throw new DataException("璇ヨ�楁潗宸插嚭搴擄紝涓嶈兘閲嶅鍊熷嚭锛�" + tiaomaBianma);
+ }
+ if (!isBorrowableStatus(bizStatus)) {
+ throw new DataException("璇ヨ�楁潗鐘舵�佷笉鍏佽鍊熷嚭锛�" + bizStatus);
+ }
+
+ BigDecimal jiechuShuliang = parseRequiredDecimal(jiechu.getJiechuShuliang(),
+ "鍊熷嚭鏁伴噺涓嶈兘涓虹┖鎴栨牸寮忔棤鏁�");
+ BigDecimal shengyuliang = parseRequiredDecimal(zixiang.getShengyuliang(),
+ "鑰楁潗鍓╀綑閲忔棤鏁堬細" + tiaomaBianma);
+ if (jiechuShuliang.compareTo(BigDecimal.ZERO) <= 0) {
+ throw new DataException("鍊熷嚭鏁伴噺蹇呴』澶т簬0");
+ }
+ if (jiechuShuliang.compareTo(shengyuliang) != 0) {
+ throw new DataException("鑰楁潗鐘舵�佸凡鍙樺寲锛岃鍒锋柊鍚庨噸鏂版彁浜�");
+ }
+
+ LimsHaocaiRukuZixiangEntity update = new LimsHaocaiRukuZixiangEntity();
+ update.setId(zixiang.getId());
+ update.setBizStatus(BIZ_STATUS_YICHUKU);
+ update.setShengyuliang("0");
+ LambdaQueryWrapper<LimsHaocaiRukuZixiangEntity> wrapper = new LambdaQueryWrapper<>();
+ wrapper.eq(LimsHaocaiRukuZixiangEntity::getId, zixiang.getId());
+ wrapper.in(LimsHaocaiRukuZixiangEntity::getBizStatus, BIZ_STATUS_WEICHUKU, BIZ_STATUS_YIKAIPING);
+ wrapper.eq(LimsHaocaiRukuZixiangEntity::getShengyuliang, zixiang.getShengyuliang());
+ int updated = zixiangMapper.update(update, wrapper);
+ if (updated <= 0) {
+ throw new DataException("鑰楁潗鐘舵�佸凡鍙樺寲锛岃鍒锋柊鍚庨噸鏂版彁浜�");
+ }
+
+ updateRukuJieyuShuliang(zixiang, false, BIZ_STATUS_YICHUKU);
+ zixiang.setBizStatus(BIZ_STATUS_YICHUKU);
+ zixiang.setShengyuliang("0");
+ haocaiLogMapper.insert(buildJiechuLog(jiechu, zixiang));
+ log.info("鑰楁潗鍊熷嚭鎻愪氦瀹屾垚锛歵iaomaBianma={}, zixiangId={}", tiaomaBianma, zixiang.getId());
+ }
+
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ @AuditLog(action = "GUIHUAN_SUBMIT", label = "鑰楁潗褰掕繕鎻愪氦", bizType = "HAOCAI",
+ bizCodeExpr = "", bizCodeRequired = false, targetTable = "lims_haocai_jiechu",
+ targetIdExpr = "#guihuan.id", diff = true, entityClass = LimsHaocaiJiechuEntity.class)
+ public void submitGuihuan(LimsHaocaiJiechuEntity guihuan) throws DataException {
+ String tiaomaBianma = trimToEmpty(guihuan == null ? null : guihuan.getTiaomaBianma());
+ if (tiaomaBianma.isEmpty()) {
+ throw new DataException("鏉$爜缂栫爜涓嶈兘涓虹┖");
+ }
+
+ LimsHaocaiJiechuEntity lentRecord = getLentJiechuByTiaomaBianma(tiaomaBianma);
+ if (lentRecord == null) {
+ throw new DataException("鏈壘鍒板凡鍊熷嚭鐨勮�楁潗鍊熷嚭璁板綍锛�" + tiaomaBianma);
+ }
+
+ LimsHaocaiJiechuEntity jiechuUpdate = new LimsHaocaiJiechuEntity();
+ jiechuUpdate.setId(lentRecord.getId());
+ jiechuUpdate.setBizStatus(JIECHU_STATUS_RETURNED);
+ jiechuUpdate.setGuihuanRen(guihuan.getGuihuanRen());
+ jiechuUpdate.setGuihuanRiqi(guihuan.getGuihuanRiqi());
+ jiechuUpdate.setGuihuanRenSign(guihuan.getGuihuanRenSign());
+ LambdaQueryWrapper<LimsHaocaiJiechuEntity> jiechuWrapper = new LambdaQueryWrapper<>();
+ jiechuWrapper.eq(LimsHaocaiJiechuEntity::getId, lentRecord.getId());
+ jiechuWrapper.eq(LimsHaocaiJiechuEntity::getBizStatus, JIECHU_STATUS_LENT);
+ int jiechuUpdated = jiechuMapper.update(jiechuUpdate, jiechuWrapper);
+ if (jiechuUpdated <= 0) {
+ throw new DataException("璇ヨ�楁潗鍊熷嚭璁板綍鐘舵�佸凡鍙樺寲锛屼笉鑳介噸澶嶅綊杩橈細" + tiaomaBianma);
+ }
+
+ List<LimsHaocaiRukuZixiangEntity> list = listRukuZixiangByTiaomaBianma(tiaomaBianma);
+ if (list == null || list.isEmpty()) {
+ throw new DataException("鏈壘鍒板搴旂殑鑰楁潗鍏ュ簱瀛愰」锛�" + tiaomaBianma);
+ }
+
+ LimsHaocaiRukuZixiangEntity zixiang = list.get(0);
+ String restoreShuliang = trimToEmpty(lentRecord.getJiechuShuliang());
+ BigDecimal guihuanShuliang = parseRequiredDecimal(restoreShuliang,
+ "鍊熷嚭璁板綍鍊熷嚭鏁伴噺鏃犳晥锛�" + tiaomaBianma);
+ if (guihuanShuliang.compareTo(BigDecimal.ZERO) <= 0) {
+ throw new DataException("鍊熷嚭璁板綍鍊熷嚭鏁伴噺蹇呴』澶т簬0锛�" + tiaomaBianma);
+ }
+ BigDecimal zongliang = parseRequiredDecimal(zixiang.getZongliang(),
+ "鑰楁潗鎬婚噺鏃犳晥锛�" + tiaomaBianma);
+ if (guihuanShuliang.compareTo(zongliang) > 0) {
+ throw new DataException("褰掕繕鏁伴噺涓嶈兘澶т簬鑰楁潗鎬婚噺锛�" + tiaomaBianma);
+ }
+ LimsHaocaiRukuZixiangEntity zixiangUpdate = new LimsHaocaiRukuZixiangEntity();
+ zixiangUpdate.setId(zixiang.getId());
+ String newBizStatus = resolveAvailableBizStatus(guihuanShuliang, zixiang);
+ zixiangUpdate.setBizStatus(newBizStatus);
+ zixiangUpdate.setShengyuliang(toPlainString(guihuanShuliang));
+ LambdaQueryWrapper<LimsHaocaiRukuZixiangEntity> zixiangWrapper = new LambdaQueryWrapper<>();
+ zixiangWrapper.eq(LimsHaocaiRukuZixiangEntity::getId, zixiang.getId());
+ zixiangWrapper.eq(LimsHaocaiRukuZixiangEntity::getBizStatus, BIZ_STATUS_YICHUKU);
+ int zixiangUpdated = zixiangMapper.update(zixiangUpdate, zixiangWrapper);
+ if (zixiangUpdated <= 0) {
+ throw new DataException("璇ヨ�楁潗鎵规鐘舵�佷笉鍏佽褰掕繕锛�" + zixiang.getBizStatus());
+ }
+
+ zixiang.setShengyuliang(toPlainString(guihuanShuliang));
+ updateRukuJieyuShuliang(zixiang, guihuanShuliang, true, BIZ_STATUS_YICHUKU);
+ zixiang.setBizStatus(newBizStatus);
+ haocaiLogMapper.insert(buildGuihuanLog(guihuan, lentRecord, zixiang));
+ log.info("鑰楁潗褰掕繕鎻愪氦瀹屾垚锛歵iaomaBianma={}, jiechuId={}, zixiangId={}",
+ tiaomaBianma, lentRecord.getId(), zixiang.getId());
+ }
+
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ @AuditLog(action = "CHUKU_SUBMIT", label = "鑰楁潗鍑哄簱鎻愪氦", bizType = "HAOCAI",
+ bizCodeExpr = "", bizCodeRequired = false, targetTable = "lims_haocai_chuku",
+ targetIdExpr = "#chuku.id", diff = true, entityClass = LimsHaocaiChukuEntity.class)
+ public void submitChuku(LimsHaocaiChukuEntity chuku) throws DataException {
+ if (chuku == null) {
+ throw new DataException("鍑哄簱琛ㄥ崟鏁版嵁涓嶈兘涓虹┖");
+ }
+ String chukuId = trimToEmpty(chuku.getId());
+ if (chukuId.isEmpty()) {
+ throw new DataException("鍑哄簱鍗曚富閿�(f_id)涓嶈兘涓虹┖");
+ }
+ String shenlingDanhao = trimToEmpty(chuku.getShenlingDanhao());
+ if (shenlingDanhao.isEmpty()) {
+ throw new DataException("鐢抽鍗曞彿涓嶈兘涓虹┖");
+ }
+ List<LimsHaocaiChukuZixiangEntity> chukuZixiangList = listChukuZixiang(chukuId);
+ if (chukuZixiangList == null || chukuZixiangList.isEmpty()) {
+ throw new DataException("鍑哄簱瀛愰」涓嶈兘涓虹┖锛�" + chukuId);
+ }
+
+ LimsHaocaiChukuShenqingEntity shenqing = getApprovedChukuShenqingByDanhao(shenlingDanhao);
+ if (shenqing == null) {
+ throw new DataException("鐢抽鍗曚笉瀛樺湪鎴栨湭閫氳繃锛�" + shenlingDanhao);
+ }
+
+ int count = 0;
+ for (LimsHaocaiChukuZixiangEntity chukuZixiang : chukuZixiangList) {
+ submitChukuZixiang(chuku, shenqing, chukuZixiang);
+ count++;
+ }
+
+ log.info("鑰楁潗鍑哄簱鎻愪氦瀹屾垚锛歴henlingDanhao={}, count={}", shenlingDanhao, count);
+ }
+
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ @AuditLog(action = "XIAOHUI_SUBMIT", label = "鑰楁潗閿�姣佹彁浜�", bizType = "HAOCAI",
+ bizCodeExpr = "#xiaohuiDanhao", bizCodeRequired = false,
+ targetTable = "lims_haocai_ruku_zixiang",
+ targetIdExpr = "T(jnpf.limsService.support.LimsAuditTargetIds).firstHaocaiDestroyItem(#xiaohuiDanhao)",
+ diff = true, entityClass = LimsHaocaiRukuZixiangEntity.class)
+ public void submitXiaohui(String xiaohuiDanhao) throws DataException {
+ String danhao = trimToEmpty(xiaohuiDanhao);
+ if (danhao.isEmpty()) {
+ throw new DataException("閿�姣佸崟鍙蜂笉鑳戒负绌�");
+ }
+
+ LimsHaocaiXiaohuiShenqingEntity shenqing = getXiaohuiShenqingByDanhao(danhao);
+ if (shenqing == null) {
+ throw new DataException("閿�姣佺敵璇蜂笉瀛樺湪锛�" + danhao);
+ }
+
+ List<LimsHaocaiXiaohuiShenqingZixiangEntity> zixiangList = listXiaohuiZixiang(shenqing.getId());
+ if (zixiangList.isEmpty()) {
+ throw new DataException("閿�姣佺敵璇峰瓙椤逛笉鑳戒负绌猴細" + danhao);
+ }
+
+ int count = 0;
+ for (LimsHaocaiXiaohuiShenqingZixiangEntity xiaohuiZixiang : zixiangList) {
+ String tiaomaBianma = trimToEmpty(xiaohuiZixiang.getTiaomaBianma());
+ if (tiaomaBianma.isEmpty()) {
+ throw new DataException("閿�姣佺敵璇峰瓙椤规潯鐮佺紪鐮佷笉鑳戒负绌�");
+ }
+
+ LimsHaocaiRukuZixiangEntity rukuZixiang = getUniqueRukuZixiangByTiaomaBianma(tiaomaBianma);
+ if (rukuZixiang == null) {
+ throw new DataException("鏈壘鍒板搴旂殑鑰楁潗鍏ュ簱瀛愰」锛�" + tiaomaBianma);
+ }
+ if (BIZ_STATUS_YIXIAOHUI.equalsIgnoreCase(trimToEmpty(rukuZixiang.getBizStatus()))) {
+ throw new DataException("璇ヨ�楁潗宸查攢姣侊紝涓嶈兘閲嶅閿�姣侊細" + tiaomaBianma);
+ }
+
+ BigDecimal xiaohuiShuliang = parseRequiredDecimal(rukuZixiang.getShengyuliang(),
+ "鑰楁潗鍓╀綑閲忔棤鏁堬細" + tiaomaBianma);
+ if (xiaohuiShuliang.compareTo(BigDecimal.ZERO) < 0) {
+ throw new DataException("鑰楁潗鍓╀綑閲忎笉鑳藉皬浜�0锛�" + tiaomaBianma);
+ }
+
+ LimsHaocaiRukuZixiangEntity rukuZixiangUpdate = new LimsHaocaiRukuZixiangEntity();
+ rukuZixiangUpdate.setId(rukuZixiang.getId());
+ rukuZixiangUpdate.setBizStatus(BIZ_STATUS_YIXIAOHUI);
+ rukuZixiangUpdate.setShengyuliang("0");
+ int updated = zixiangMapper.updateById(rukuZixiangUpdate);
+ if (updated <= 0) {
+ throw new DataException("鑰楁潗閿�姣佸け璐ワ細" + tiaomaBianma);
+ }
+
+ updateRukuJieyuShuliang(rukuZixiang, BIZ_STATUS_YIXIAOHUI);
+ rukuZixiang.setBizStatus(BIZ_STATUS_YIXIAOHUI);
+ rukuZixiang.setShengyuliang("0");
+ haocaiLogMapper.insert(buildXiaohuiLog(shenqing, xiaohuiZixiang, rukuZixiang, xiaohuiShuliang));
+ markXiaohuiZixiangDestroyed(xiaohuiZixiang);
+ count++;
+ }
+
+ log.info("鑰楁潗閿�姣佹彁浜ゅ畬鎴愶細xiaohuiDanhao={}, xiaohuiShenqingId={}, count={}",
+ danhao, shenqing.getId(), count);
+ }
+
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ @AuditLog(action = "UPDATE", label = "鑰楁潗鎵归噺杞緟閿�姣�", bizType = "HAOCAI",
+ bizCodeExpr = "#result > 0 ? 'HAOCAI_RUKU_BATCH' : ''", targetTable = "lims_haocai_ruku_zixiang",
+ targetIdExpr = "T(jnpf.limsService.support.LimsAuditTargetIds).firstHaocaiRukuItem(#rukuIds)",
+ diff = true, entityClass = LimsHaocaiRukuZixiangEntity.class)
+ public int batchMarkRukuZixiangDaixiaohui(List<String> rukuIds) throws DataException {
+ List<String> ids = normalizeIds(rukuIds);
+ if (ids.isEmpty()) {
+ throw new DataException("鍏ュ簱鍗曚富閿暟缁勪笉鑳戒负绌�");
+ }
+ UserInfo userInfo = UserProvider.getUser();
+ String currentUserId = userInfo == null ? "" : trimToEmpty(userInfo.getUserId());
+ if (currentUserId.isEmpty()) {
+ throw new DataException("鏈幏鍙栧埌褰撳墠鐧诲綍鐢ㄦ埛");
+ }
+
+ LambdaQueryWrapper<LimsHaocaiRukuZixiangEntity> queryWrapper = new LambdaQueryWrapper<>();
+ queryWrapper.in(LimsHaocaiRukuZixiangEntity::getForeignId, ids);
+ queryWrapper.and(w -> w.isNull(LimsHaocaiRukuZixiangEntity::getDeleteMark)
+ .or()
+ .ne(LimsHaocaiRukuZixiangEntity::getDeleteMark, 1));
+ List<LimsHaocaiRukuZixiangEntity> zixiangList = zixiangMapper.selectList(queryWrapper);
+
+ List<String> zixiangIds = new ArrayList<>();
+ for (LimsHaocaiRukuZixiangEntity zixiang : zixiangList) {
+ BigDecimal shengyuliang = parseOptionalDecimal(zixiang.getShengyuliang());
+ if (shengyuliang != null && shengyuliang.compareTo(BigDecimal.ZERO) > 0) {
+ zixiangIds.add(zixiang.getId());
+ }
+ }
+ if (zixiangIds.isEmpty()) {
+ log.info("鑰楁潗鍏ュ簱鎵归噺杞緟閿�姣佹棤鍙洿鏂板瓙椤癸細rukuIds={}", ids);
+ return 0;
+ }
+
+ LimsHaocaiRukuZixiangEntity update = new LimsHaocaiRukuZixiangEntity();
+ update.setBizStatus(BIZ_STATUS_DAIXIAOHUI);
+ update.setZhuanxiaohuiRen(currentUserId);
+ LambdaQueryWrapper<LimsHaocaiRukuZixiangEntity> updateWrapper = new LambdaQueryWrapper<>();
+ updateWrapper.in(LimsHaocaiRukuZixiangEntity::getId, zixiangIds);
+ int updated = zixiangMapper.update(update, updateWrapper);
+ updateRukuBizStatus(ids, BIZ_STATUS_DAIXIAOHUI);
+ log.info("鑰楁潗鍏ュ簱鎵归噺杞緟閿�姣佸畬鎴愶細rukuIds={}, zixiangCount={}", ids, updated);
+ return updated;
+ }
+
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ @AuditLog(action = "XIAOHUI_START", label = "鑰楁潗閿�姣佺敵璇峰彂璧�", bizType = "HAOCAI",
+ bizCodeExpr = "#result > 0 ? #flowId : ''", targetTable = "lims_haocai_ruku_zixiang",
+ targetIdExpr = "T(jnpf.limsService.support.LimsAuditTargetIds).firstHaocaiDestroyItemByFlow(#flowId, #taskId)",
+ diff = true, entityClass = LimsHaocaiRukuZixiangEntity.class)
+ public int startXiaohuiShenqing(String flowId, String taskId) throws DataException {
+ String flow = trimToEmpty(flowId);
+ String task = trimToEmpty(taskId);
+ if (flow.isEmpty()) {
+ throw new DataException("娴佺▼id(flow_id)涓嶈兘涓虹┖");
+ }
+ if (task.isEmpty()) {
+ throw new DataException("娴佺▼浠诲姟id(task_id)涓嶈兘涓虹┖");
+ }
+ LimsHaocaiXiaohuiShenqingEntity shenqing = getXiaohuiShenqingByFlow(flow, task);
+ if (shenqing == null) {
+ throw new DataException("閿�姣佺敵璇蜂笉瀛樺湪锛歠low_id=" + flow + ", task_id=" + task);
+ }
+ String id = shenqing.getId();
+ String xiaohuiDanhao = trimToEmpty(shenqing.getXiaohuiDanhao());
+ if (xiaohuiDanhao.isEmpty()) {
+ throw new DataException("閿�姣佸崟鍙蜂笉鑳戒负绌猴細" + id);
+ }
+
+ List<LimsHaocaiXiaohuiShenqingZixiangEntity> xiaohuiZixiangList = listXiaohuiZixiang(id);
+ if (xiaohuiZixiangList == null || xiaohuiZixiangList.isEmpty()) {
+ throw new DataException("閿�姣佺敵璇峰瓙椤逛笉鑳戒负绌猴細" + xiaohuiDanhao);
+ }
+
+ int updated = 0;
+ for (LimsHaocaiXiaohuiShenqingZixiangEntity xiaohuiZixiang : xiaohuiZixiangList) {
+ String tiaomaBianma = trimToEmpty(xiaohuiZixiang.getTiaomaBianma());
+ if (tiaomaBianma.isEmpty()) {
+ throw new DataException("閿�姣佺敵璇峰瓙椤规潯鐮佷笉鑳戒负绌猴細" + xiaohuiDanhao);
+ }
+ LimsHaocaiRukuZixiangEntity update = new LimsHaocaiRukuZixiangEntity();
+ update.setBizStatus(BIZ_STATUS_DAIXIAOHUI);
+ update.setXiaohuiDanhao(xiaohuiDanhao);
+
+ LambdaQueryWrapper<LimsHaocaiRukuZixiangEntity> wrapper = new LambdaQueryWrapper<>();
+ wrapper.eq(LimsHaocaiRukuZixiangEntity::getTiaomaBianma, tiaomaBianma);
+ wrapper.and(w -> w.isNull(LimsHaocaiRukuZixiangEntity::getDeleteMark)
+ .or()
+ .ne(LimsHaocaiRukuZixiangEntity::getDeleteMark, 1));
+ int rowUpdated = zixiangMapper.update(update, wrapper);
+ if (rowUpdated <= 0) {
+ throw new DataException("鏈壘鍒板搴旂殑鑰楁潗鍏ュ簱瀛愰」锛�" + tiaomaBianma);
+ }
+ updated += rowUpdated;
+ }
+ log.info("鑰楁潗閿�姣佺敵璇峰彂璧峰畬鎴愶細xiaohuiShenqingId={}, xiaohuiDanhao={}, zixiangCount={}",
+ id, xiaohuiDanhao, updated);
+ return updated;
+ }
+
+ @Override
+ public List<LimsHaocaiRukuZixiangEntity> listRukuZixiangByTiaomaBianma(String tiaomaBianma) {
+ LambdaQueryWrapper<LimsHaocaiRukuZixiangEntity> wrapper = new LambdaQueryWrapper<>();
+ wrapper.eq(LimsHaocaiRukuZixiangEntity::getTiaomaBianma, trimToEmpty(tiaomaBianma));
+ wrapper.and(w -> w.isNull(LimsHaocaiRukuZixiangEntity::getDeleteMark)
+ .or()
+ .ne(LimsHaocaiRukuZixiangEntity::getDeleteMark, 1));
+ wrapper.orderByDesc(LimsHaocaiRukuZixiangEntity::getRukuShijian);
+ wrapper.orderByAsc(LimsHaocaiRukuZixiangEntity::getBianhao);
+ return zixiangMapper.selectList(wrapper);
+ }
+
+ @Override
+ public LimsHaocaiChukuShenqingZixiangEntity getChukuShenqingZixiangForChuku(String shenlingDanhao,
+ String tiaomaBianma) throws DataException {
+ String danhao = trimToEmpty(shenlingDanhao);
+ String tiaoma = trimToEmpty(tiaomaBianma);
+ if (danhao.isEmpty()) {
+ throw new DataException("鐢抽鍗曞彿涓嶈兘涓虹┖");
+ }
+ if (tiaoma.isEmpty()) {
+ throw new DataException("鏉$爜缂栫爜涓嶈兘涓虹┖");
+ }
+
+ LimsHaocaiRukuZixiangEntity rukuZixiang = getUniqueRukuZixiangByTiaomaBianma(tiaoma);
+ if (rukuZixiang == null) {
+ throw new DataException("鏈壘鍒板搴旂殑鑰楁潗鍏ュ簱瀛愰」锛�" + tiaoma);
+ }
+ if (!isChukuAvailableStatus(rukuZixiang.getBizStatus())) {
+ throw new DataException("璇ヨ�楁潗鐘舵�佷笉鍏佽鍑哄簱锛�" + trimToEmpty(rukuZixiang.getBizStatus()));
+ }
+ BigDecimal shengyuliang = parseRequiredDecimal(rukuZixiang.getShengyuliang(),
+ "鑰楁潗鍓╀綑閲忔棤鏁堬細" + tiaoma);
+ if (shengyuliang.compareTo(BigDecimal.ZERO) <= 0) {
+ throw new DataException("璇ヨ�楁潗鍓╀綑閲忎笉瓒筹紝鏃犳硶鍑哄簱锛�" + tiaoma);
+ }
+
+ LimsHaocaiChukuShenqingEntity shenqing = getApprovedChukuShenqingByDanhao(danhao);
+ if (shenqing == null) {
+ throw new DataException("鐢抽鍗曚笉瀛樺湪鎴栨湭閫氳繃锛�" + danhao);
+ }
+ LimsHaocaiChukuShenqingZixiangEntity chukuZixiang = getChukuShenqingZixiang(shenqing.getId(), tiaoma);
+ if (chukuZixiang == null) {
+ throw new DataException("鏉$爜缂栫爜涓嶅湪璇ョ敵棰嗗崟瀛愯〃涓細" + tiaoma);
+ }
+ if ("yes".equalsIgnoreCase(trimToEmpty(chukuZixiang.getShifouYichuku()))) {
+ throw new DataException("璇ョ敵棰嗗瓙椤瑰凡鍑哄簱锛屼笉鑳介噸澶嶅嚭搴擄細" + tiaoma);
+ }
+ chukuZixiang.setYongtu(shenqing.getYongtu());
+ chukuZixiang.setShifouShuangrenChuku(rukuZixiang.getShifouShuangrenChuku());
+ return chukuZixiang;
+ }
+
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ @AuditLog(action = "YANSHOU_SUBMIT", label = "鑰楁潗鍏ュ簱楠屾敹鎻愪氦", bizType = "HAOCAI",
+ bizCodeExpr = "#flowId", bizCodeRequired = false, targetTable = "lims_haocai_yanshou_shenqing",
+ targetIdExpr = "T(jnpf.limsService.support.LimsAuditTargetIds).haocaiAcceptanceRequestByFlow(#flowId, #taskId)",
+ diff = true, entityClass = LimsHaocaiYanshouShenqingEntity.class)
+ public void submitRukuYanshou(String flowId, String taskId) throws DataException {
+ String flow = trimToEmpty(flowId);
+ String task = trimToEmpty(taskId);
+ if (flow.isEmpty()) {
+ throw new DataException("娴佺▼id(flow_id)涓嶈兘涓虹┖");
+ }
+ if (task.isEmpty()) {
+ throw new DataException("娴佺▼浠诲姟id(task_id)涓嶈兘涓虹┖");
+ }
+
+ LimsHaocaiRukuYanshouEntity yanshou = getUniqueRukuYanshouByFlow(flow, task);
+ String shenqingId = trimToEmpty(yanshou.getShenqingId());
+ if (shenqingId.isEmpty()) {
+ throw new DataException("鑰楁潗鍏ュ簱楠屾敹璁板綍鏈叧鑱旈獙鏀剁敵璇凤細" + yanshou.getId());
+ }
+
+ LambdaUpdateWrapper<LimsHaocaiYanshouShenqingEntity> update = new LambdaUpdateWrapper<>();
+ update.eq(LimsHaocaiYanshouShenqingEntity::getId, shenqingId)
+ .and(w -> w.isNull(LimsHaocaiYanshouShenqingEntity::getDeleteMark)
+ .or().ne(LimsHaocaiYanshouShenqingEntity::getDeleteMark, 1))
+ .set(LimsHaocaiYanshouShenqingEntity::getYanshouId, yanshou.getId());
+ if (yanshouShenqingMapper.update(null, update) != 1) {
+ throw new DataException("鑰楁潗楠屾敹鐢宠涓嶅瓨鍦ㄦ垨宸插垹闄わ細" + shenqingId);
+ }
+ log.info("鑰楁潗鍏ュ簱楠屾敹鎻愪氦瀹屾垚锛歠lowId={}, taskId={}, yanshouId={}, shenqingId={}",
+ flow, task, yanshou.getId(), shenqingId);
+ }
+
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ @AuditLog(action = "YANSHOU_FINISH", label = "鑰楁潗鍏ュ簱楠屾敹瀹屾垚", bizType = "HAOCAI",
+ bizCodeExpr = "#flowId", bizCodeRequired = false, targetTable = "lims_haocai_yanshou_shenqing",
+ targetIdExpr = "T(jnpf.limsService.support.LimsAuditTargetIds).haocaiAcceptanceRequestByFlow(#flowId, #taskId)",
+ diff = true, entityClass = LimsHaocaiYanshouShenqingEntity.class)
+ public void finishRukuYanshou(String flowId, String taskId) throws DataException {
+ String flow = trimToEmpty(flowId);
+ String task = trimToEmpty(taskId);
+ if (flow.isEmpty()) {
+ throw new DataException("娴佺▼id(flow_id)涓嶈兘涓虹┖");
+ }
+ if (task.isEmpty()) {
+ throw new DataException("娴佺▼浠诲姟id(task_id)涓嶈兘涓虹┖");
+ }
+
+ LimsHaocaiRukuYanshouEntity yanshou = getUniqueRukuYanshouByFlow(flow, task);
+ String shenqingId = trimToEmpty(yanshou.getShenqingId());
+ if (shenqingId.isEmpty()) {
+ throw new DataException("鑰楁潗鍏ュ簱楠屾敹璁板綍鏈叧鑱旈獙鏀剁敵璇凤細" + yanshou.getId());
+ }
+
+ boolean approved = Integer.valueOf(FLOW_STATE_APPROVED).equals(yanshou.getFlowState());
+ LambdaUpdateWrapper<LimsHaocaiYanshouShenqingEntity> update = new LambdaUpdateWrapper<>();
+ update.eq(LimsHaocaiYanshouShenqingEntity::getId, shenqingId)
+ .and(w -> w.isNull(LimsHaocaiYanshouShenqingEntity::getDeleteMark)
+ .or().ne(LimsHaocaiYanshouShenqingEntity::getDeleteMark, 1));
+ if (approved) {
+ update.set(LimsHaocaiYanshouShenqingEntity::getBizStatus,
+ YANSHOU_SHENQING_STATUS_YIYANSHOU);
+ } else {
+ update.set(LimsHaocaiYanshouShenqingEntity::getBizStatus,
+ YANSHOU_SHENQING_STATUS_DAIYANSHOU)
+ .set(LimsHaocaiYanshouShenqingEntity::getShiyanYuan, null)
+ .set(LimsHaocaiYanshouShenqingEntity::getRenwuLingquShijian, null)
+ .set(LimsHaocaiYanshouShenqingEntity::getYanshouId, null);
+ }
+ if (yanshouShenqingMapper.update(null, update) != 1) {
+ throw new DataException("鑰楁潗楠屾敹鐢宠涓嶅瓨鍦ㄦ垨宸插垹闄わ細" + shenqingId);
+ }
+ log.info("鑰楁潗鍏ュ簱楠屾敹瀹屾垚澶勭悊鎴愬姛锛歠lowId={}, taskId={}, yanshouId={}, flowState={}, approved={}",
+ flow, task, yanshou.getId(), yanshou.getFlowState(), approved);
+ }
+
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ @AuditLog(action = "YANSHOU_CLAIM", label = "棰嗗彇鑰楁潗楠屾敹鐢宠", bizType = "HAOCAI",
+ bizCodeExpr = "#shenqingId", bizCodeRequired = false, targetTable = "lims_haocai_yanshou_shenqing",
+ targetIdExpr = "#shenqingId", diff = true,
+ entityClass = LimsHaocaiYanshouShenqingEntity.class)
+ public void lingquYanshouShenqing(String shenqingId) throws DataException {
+ String id = trimToEmpty(shenqingId);
+ if (id.isEmpty()) {
+ throw new DataException("鑰楁潗楠屾敹鐢宠涓婚敭(shenqing_id)涓嶈兘涓虹┖");
+ }
+
+ LimsHaocaiYanshouShenqingEntity shenqing = yanshouShenqingMapper.selectById(id);
+ if (shenqing == null || Integer.valueOf(1).equals(shenqing.getDeleteMark())) {
+ throw new DataException("鑰楁潗楠屾敹鐢宠涓嶅瓨鍦細" + id);
+ }
+ if (!YANSHOU_SHENQING_STATUS_DAIYANSHOU.equals(shenqing.getBizStatus())) {
+ throw new DataException("鑰楁潗楠屾敹鐢宠褰撳墠鐘舵�佷负銆�"
+ + yanshouShenqingStatusLabel(shenqing.getBizStatus()) + "銆戯紝浠呫�愬緟楠屾敹銆戠姸鎬佸彲棰嗗彇");
+ }
+
+ UserInfo userInfo = UserProvider.getUser();
+ if (userInfo == null || trimToEmpty(userInfo.getUserId()).isEmpty()) {
+ throw new DataException("褰撳墠鐧诲綍鐢ㄦ埛涓嶅瓨鍦�");
+ }
+ LambdaUpdateWrapper<LimsHaocaiYanshouShenqingEntity> update = new LambdaUpdateWrapper<>();
+ update.eq(LimsHaocaiYanshouShenqingEntity::getId, id)
+ .eq(LimsHaocaiYanshouShenqingEntity::getBizStatus, YANSHOU_SHENQING_STATUS_DAIYANSHOU)
+ .and(w -> w.isNull(LimsHaocaiYanshouShenqingEntity::getDeleteMark)
+ .or().ne(LimsHaocaiYanshouShenqingEntity::getDeleteMark, 1))
+ .set(LimsHaocaiYanshouShenqingEntity::getBizStatus, YANSHOU_SHENQING_STATUS_YANSHOUZHONG)
+ .set(LimsHaocaiYanshouShenqingEntity::getShiyanYuan, userInfo.getUserId())
+ .set(LimsHaocaiYanshouShenqingEntity::getRenwuLingquShijian, new Date());
+ if (yanshouShenqingMapper.update(null, update) != 1) {
+ throw new DataException("鑰楁潗楠屾敹鐢宠鐘舵�佸凡鍙樺寲锛岃鍒锋柊鍚庨噸鏂伴鍙�");
+ }
+ }
+
+ private LimsHaocaiRukuYanshouEntity getUniqueRukuYanshouByFlow(String flowId, String taskId)
+ throws DataException {
+ LambdaQueryWrapper<LimsHaocaiRukuYanshouEntity> query = new LambdaQueryWrapper<>();
+ query.eq(LimsHaocaiRukuYanshouEntity::getFlowId, flowId)
+ .eq(LimsHaocaiRukuYanshouEntity::getFlowTaskId, taskId)
+ .and(w -> w.isNull(LimsHaocaiRukuYanshouEntity::getDeleteMark)
+ .or().ne(LimsHaocaiRukuYanshouEntity::getDeleteMark, 1));
+ List<LimsHaocaiRukuYanshouEntity> list = rukuYanshouMapper.selectList(query);
+ if (list == null || list.isEmpty()) {
+ throw new DataException("鑰楁潗鍏ュ簱楠屾敹璁板綍涓嶅瓨鍦細flow_id=" + flowId + ", task_id=" + taskId);
+ }
+ if (list.size() > 1) {
+ throw new DataException("澶氫釜鑰楁潗鍏ュ簱楠屾敹璁板綍鍏宠仈鍚屼竴娴佺▼浠诲姟锛歵ask_id=" + taskId);
+ }
+ return list.get(0);
+ }
+
+ private LimsHaocaiRukuZixiangEntity buildZixiang(LimsHaocaiRukuEntity ruku,
+ String tiaomaBianma, String bianhao,
+ String zongliang, String yanshouZhuangtai) {
+ LimsHaocaiRukuZixiangEntity record = new LimsHaocaiRukuZixiangEntity();
+ record.setId(RandomUtil.uuId());
+ record.setForeignId(ruku.getId());
+ record.setRukuId(ruku.getId());
+ record.setTiaomaBianma(tiaomaBianma);
+ record.setBianhao(bianhao);
+ record.setZongliang(zongliang);
+ record.setShengyuliang(zongliang);
+ record.setBizStatus(BIZ_STATUS_WEICHUKU);
+ record.setYanshouZhuangtai(yanshouZhuangtai);
+ record.setMingcheng(ruku.getHaocaiMingcheng());
+ record.setFenlei(ruku.getHaocaiFenlei());
+ record.setGuige(ruku.getGuige());
+ record.setPihao(ruku.getPihao());
+ record.setDanwei(ruku.getRongliangDanwei());
+ record.setCunfangWeizhi(ruku.getCunfangWeizhi());
+ record.setYouxiaoqi(ruku.getYouxiaoqi());
+ record.setKaipingYouxiaoqi(ruku.getKaipingYouxiaoqi());
+ record.setKaipingYouxiaoqiDanwei(ruku.getKaipingYouxiaoqiDanwei());
+ record.setRukuShijian(ruku.getRukuShijian() != null ? ruku.getRukuShijian() : new Date());
+ record.setRukuRen(ruku.getRukuRen());
+ record.setShenheRen(ruku.getShenheRen());
+ record.setHaocaiId(ruku.getHaocaiId());
+ record.setShifouShuangrenChuku(ruku.getShifouShuangrenChuku());
+ return record;
+ }
+
+ private LimsHaocaiLogEntity buildRukuLog(LimsHaocaiRukuEntity ruku, LimsHaocaiRukuZixiangEntity zixiang) {
+ LimsHaocaiLogEntity record = new LimsHaocaiLogEntity();
+ record.setId(RandomUtil.uuId());
+ record.setFenlei(zixiang.getFenlei());
+ record.setTiaomaBianma(zixiang.getTiaomaBianma());
+ record.setBianhao(zixiang.getBianhao());
+ record.setMingcheng(zixiang.getMingcheng());
+ record.setGuige(zixiang.getGuige());
+ record.setPihao(zixiang.getPihao());
+ record.setChurukuShuliang(zixiang.getZongliang());
+ record.setShengyuShuliang(zixiang.getShengyuliang());
+ record.setDanwei(zixiang.getDanwei());
+ record.setCaozuoRen(zixiang.getRukuRen());
+ record.setFuheRen(zixiang.getShenheRen());
+ record.setCaozuoRiqi(zixiang.getRukuShijian());
+ record.setCaozuoLeixing(LOG_ACTION_RUKU);
+ record.setBeizhu(ruku.getBeizhu());
+ return record;
+ }
+
+ private LimsHaocaiLogEntity buildJiechuLog(LimsHaocaiJiechuEntity jiechu, LimsHaocaiRukuZixiangEntity zixiang) {
+ LimsHaocaiLogEntity record = new LimsHaocaiLogEntity();
+ record.setId(RandomUtil.uuId());
+ record.setFenlei(zixiang.getFenlei());
+ record.setTiaomaBianma(zixiang.getTiaomaBianma());
+ record.setBianhao(zixiang.getBianhao());
+ record.setMingcheng(zixiang.getMingcheng());
+ record.setGuige(zixiang.getGuige());
+ record.setPihao(zixiang.getPihao());
+ record.setChurukuShuliang(jiechu.getJiechuShuliang());
+ record.setShengyuShuliang(zixiang.getShengyuliang());
+ record.setDanwei(firstNotBlank(jiechu.getDanwei(), zixiang.getDanwei()));
+ record.setCaozuoRen(jiechu.getJiechuRen());
+ record.setCaozuoRiqi(jiechu.getJiechuRiqi() != null ? jiechu.getJiechuRiqi() : new Date());
+ record.setCaozuoLeixing(LOG_ACTION_JIECHU);
+ record.setBeizhu(jiechu.getYongtu());
+ return record;
+ }
+
+ private LimsHaocaiLogEntity buildGuihuanLog(LimsHaocaiJiechuEntity guihuan,
+ LimsHaocaiJiechuEntity lentRecord,
+ LimsHaocaiRukuZixiangEntity zixiang) {
+ LimsHaocaiLogEntity record = new LimsHaocaiLogEntity();
+ record.setId(RandomUtil.uuId());
+ record.setFenlei(zixiang.getFenlei());
+ record.setTiaomaBianma(zixiang.getTiaomaBianma());
+ record.setBianhao(zixiang.getBianhao());
+ record.setMingcheng(zixiang.getMingcheng());
+ record.setGuige(zixiang.getGuige());
+ record.setPihao(zixiang.getPihao());
+ record.setChurukuShuliang(lentRecord.getJiechuShuliang());
+ record.setShengyuShuliang(zixiang.getShengyuliang());
+ record.setDanwei(firstNotBlank(lentRecord.getDanwei(), zixiang.getDanwei()));
+ record.setCaozuoRen(firstNotBlank(guihuan.getGuihuanRen(), firstNotBlank(guihuan.getJiechuRen(), lentRecord.getJiechuRen())));
+ record.setCaozuoRiqi(guihuan.getGuihuanRiqi() != null ? guihuan.getGuihuanRiqi() : new Date());
+ record.setCaozuoLeixing(LOG_ACTION_GUIHUAN);
+ record.setBeizhu(firstNotBlank(guihuan.getYongtu(), lentRecord.getYongtu()));
+ return record;
+ }
+
+ private LimsHaocaiLogEntity buildChukuLog(LimsHaocaiChukuEntity chuku,
+ LimsHaocaiChukuZixiangEntity chukuZixiang,
+ LimsHaocaiRukuZixiangEntity rukuZixiang,
+ BigDecimal chukuliang) {
+ LimsHaocaiLogEntity record = new LimsHaocaiLogEntity();
+ record.setId(RandomUtil.uuId());
+ record.setFenlei(rukuZixiang.getFenlei());
+ record.setTiaomaBianma(rukuZixiang.getTiaomaBianma());
+ record.setBianhao(rukuZixiang.getBianhao());
+ record.setMingcheng(rukuZixiang.getMingcheng());
+ record.setGuige(rukuZixiang.getGuige());
+ record.setPihao(rukuZixiang.getPihao());
+ record.setChurukuShuliang(toPlainString(chukuliang));
+ record.setShengyuShuliang(rukuZixiang.getShengyuliang());
+ record.setDanwei(firstNotBlank(chukuZixiang.getDanwei(), rukuZixiang.getDanwei()));
+ record.setCaozuoRen(chuku.getChukuRen());
+ record.setFuheRen(chuku.getFuheRen());
+ record.setCaozuoRiqi(chuku.getChukuRiqi() != null ? chuku.getChukuRiqi() : new Date());
+ record.setCaozuoLeixing(LOG_ACTION_CHUKU);
+ record.setBeizhu(chukuZixiang.getYongtu());
+ return record;
+ }
+
+ private LimsHaocaiLogEntity buildXiaohuiLog(LimsHaocaiXiaohuiShenqingEntity shenqing,
+ LimsHaocaiXiaohuiShenqingZixiangEntity xiaohuiZixiang,
+ LimsHaocaiRukuZixiangEntity rukuZixiang,
+ BigDecimal xiaohuiShuliang) {
+ LimsHaocaiLogEntity record = new LimsHaocaiLogEntity();
+ record.setId(RandomUtil.uuId());
+ record.setFenlei(rukuZixiang.getFenlei());
+ record.setTiaomaBianma(rukuZixiang.getTiaomaBianma());
+ record.setBianhao(rukuZixiang.getBianhao());
+ record.setMingcheng(rukuZixiang.getMingcheng());
+ record.setGuige(rukuZixiang.getGuige());
+ record.setPihao(rukuZixiang.getPihao());
+ record.setChurukuShuliang(toPlainString(xiaohuiShuliang));
+ record.setShengyuShuliang(rukuZixiang.getShengyuliang());
+ record.setDanwei(rukuZixiang.getDanwei());
+ record.setCaozuoRen(shenqing.getShenqingRen());
+ record.setCaozuoRiqi(shenqing.getShenqingRiqi() != null ? shenqing.getShenqingRiqi() : new Date());
+ record.setCaozuoLeixing(LOG_ACTION_XIAOHUI);
+ record.setBeizhu(firstNotBlank(xiaohuiZixiang.getYuanyin(), firstNotBlank(shenqing.getYuanyin(), shenqing.getFangfa())));
+ return record;
+ }
+
+ private LimsHaocaiJiechuEntity getLentJiechuByTiaomaBianma(String tiaomaBianma) {
+ LambdaQueryWrapper<LimsHaocaiJiechuEntity> wrapper = new LambdaQueryWrapper<>();
+ wrapper.eq(LimsHaocaiJiechuEntity::getTiaomaBianma, trimToEmpty(tiaomaBianma));
+ wrapper.eq(LimsHaocaiJiechuEntity::getBizStatus, JIECHU_STATUS_LENT);
+ wrapper.and(w -> w.isNull(LimsHaocaiJiechuEntity::getDeleteMark)
+ .or()
+ .ne(LimsHaocaiJiechuEntity::getDeleteMark, 1));
+ wrapper.orderByDesc(LimsHaocaiJiechuEntity::getJiechuRiqi);
+ return jiechuMapper.selectList(wrapper).stream().findFirst().orElse(null);
+ }
+
+ private void submitChukuZixiang(LimsHaocaiChukuEntity chuku,
+ LimsHaocaiChukuShenqingEntity shenqing,
+ LimsHaocaiChukuZixiangEntity chukuZixiang) throws DataException {
+ String tiaomaBianma = trimToEmpty(chukuZixiang == null ? null : chukuZixiang.getTiaomaBianma());
+ if (tiaomaBianma.isEmpty()) {
+ throw new DataException("鍑哄簱瀛愰」鏉$爜缂栫爜涓嶈兘涓虹┖");
+ }
+
+ BigDecimal chukuliang = parseRequiredDecimal(chukuZixiang.getChukuliang(),
+ "鏈鍑哄簱閲忎笉鑳戒负绌烘垨鏍煎紡鏃犳晥锛�" + tiaomaBianma);
+ if (chukuliang.compareTo(BigDecimal.ZERO) <= 0) {
+ throw new DataException("鏈鍑哄簱閲忓繀椤诲ぇ浜�0锛�" + tiaomaBianma);
+ }
+
+ LimsHaocaiRukuZixiangEntity rukuZixiang = getUniqueRukuZixiangByTiaomaBianma(tiaomaBianma);
+ if (rukuZixiang == null) {
+ throw new DataException("鏈壘鍒板搴旂殑鑰楁潗鍏ュ簱瀛愰」锛�" + tiaomaBianma);
+ }
+ String bizStatus = trimToEmpty(rukuZixiang.getBizStatus());
+ if (!isChukuAvailableStatus(bizStatus)) {
+ throw new DataException("璇ヨ�楁潗鐘舵�佷笉鍏佽鍑哄簱锛�" + bizStatus);
+ }
+
+ BigDecimal shengyuliang = parseRequiredDecimal(rukuZixiang.getShengyuliang(),
+ "鑰楁潗鍓╀綑閲忔棤鏁堬細" + tiaomaBianma);
+ if (chukuliang.compareTo(shengyuliang) > 0) {
+ throw new DataException("鏈鍑哄簱閲忎笉鑳藉ぇ浜庡墿浣欓噺锛�" + tiaomaBianma);
+ }
+
+ LimsHaocaiChukuShenqingZixiangEntity shenqingZixiang =
+ getChukuShenqingZixiang(shenqing.getId(), tiaomaBianma);
+ if (shenqingZixiang == null) {
+ throw new DataException("鏉$爜缂栫爜涓嶅湪璇ョ敵棰嗗崟瀛愯〃涓細" + tiaomaBianma);
+ }
+ if ("yes".equalsIgnoreCase(trimToEmpty(shenqingZixiang.getShifouYichuku()))) {
+ throw new DataException("璇ョ敵棰嗗瓙椤瑰凡鍑哄簱锛屼笉鑳介噸澶嶅嚭搴擄細" + tiaomaBianma);
+ }
+
+ BigDecimal newShengyuliang = shengyuliang.subtract(chukuliang);
+ String newBizStatus = newShengyuliang.compareTo(BigDecimal.ZERO) == 0
+ ? BIZ_STATUS_YICHUKU
+ : BIZ_STATUS_YIKAIPING;
+
+ LimsHaocaiRukuZixiangEntity rukuZixiangUpdate = new LimsHaocaiRukuZixiangEntity();
+ rukuZixiangUpdate.setId(rukuZixiang.getId());
+ rukuZixiangUpdate.setShengyuliang(toPlainString(newShengyuliang));
+ rukuZixiangUpdate.setBizStatus(newBizStatus);
+ LambdaQueryWrapper<LimsHaocaiRukuZixiangEntity> rukuZixiangWrapper = new LambdaQueryWrapper<>();
+ rukuZixiangWrapper.eq(LimsHaocaiRukuZixiangEntity::getId, rukuZixiang.getId());
+ rukuZixiangWrapper.in(LimsHaocaiRukuZixiangEntity::getBizStatus, BIZ_STATUS_WEICHUKU, BIZ_STATUS_YIKAIPING);
+ rukuZixiangWrapper.eq(LimsHaocaiRukuZixiangEntity::getShengyuliang, rukuZixiang.getShengyuliang());
+ int rukuZixiangUpdated = zixiangMapper.update(rukuZixiangUpdate, rukuZixiangWrapper);
+ if (rukuZixiangUpdated <= 0) {
+ throw new DataException("鑰楁潗鐘舵�佸凡鍙樺寲锛岃鍒锋柊鍚庨噸鏂版彁浜わ細" + tiaomaBianma);
+ }
+
+ markChukuShenqingZixiangOut(shenqingZixiang);
+ updateRukuJieyuShuliang(rukuZixiang, chukuliang, false, BIZ_STATUS_YICHUKU);
+ rukuZixiang.setShengyuliang(toPlainString(newShengyuliang));
+ rukuZixiang.setBizStatus(newBizStatus);
+ haocaiLogMapper.insert(buildChukuLog(chuku, chukuZixiang, rukuZixiang, chukuliang));
+ }
+
+ private List<LimsHaocaiXiaohuiShenqingZixiangEntity> listXiaohuiZixiang(String foreignId) {
+ LambdaQueryWrapper<LimsHaocaiXiaohuiShenqingZixiangEntity> wrapper = new LambdaQueryWrapper<>();
+ wrapper.eq(LimsHaocaiXiaohuiShenqingZixiangEntity::getForeignId, foreignId);
+ wrapper.and(w -> w.isNull(LimsHaocaiXiaohuiShenqingZixiangEntity::getDeleteMark)
+ .or()
+ .ne(LimsHaocaiXiaohuiShenqingZixiangEntity::getDeleteMark, 1));
+ return xiaohuiShenqingZixiangMapper.selectList(wrapper);
+ }
+
+ private List<LimsHaocaiChukuZixiangEntity> listChukuZixiang(String foreignId) {
+ LambdaQueryWrapper<LimsHaocaiChukuZixiangEntity> wrapper = new LambdaQueryWrapper<>();
+ wrapper.eq(LimsHaocaiChukuZixiangEntity::getForeignId, foreignId);
+ wrapper.and(w -> w.isNull(LimsHaocaiChukuZixiangEntity::getDeleteMark)
+ .or()
+ .ne(LimsHaocaiChukuZixiangEntity::getDeleteMark, 1));
+ return chukuZixiangMapper.selectList(wrapper);
+ }
+
+ private void markXiaohuiZixiangDestroyed(LimsHaocaiXiaohuiShenqingZixiangEntity xiaohuiZixiang) throws DataException {
+ LimsHaocaiXiaohuiShenqingZixiangEntity update = new LimsHaocaiXiaohuiShenqingZixiangEntity();
+ update.setId(xiaohuiZixiang.getId());
+ update.setShifouYixiaohui("yes");
+ int updated = xiaohuiShenqingZixiangMapper.updateById(update);
+ if (updated <= 0) {
+ throw new DataException("閿�姣佺敵璇峰瓙椤圭姸鎬佹洿鏂板け璐ワ細" + xiaohuiZixiang.getTiaomaBianma());
+ }
+ }
+
+ private void markChukuShenqingZixiangOut(LimsHaocaiChukuShenqingZixiangEntity shenqingZixiang) throws DataException {
+ LimsHaocaiChukuShenqingZixiangEntity update = new LimsHaocaiChukuShenqingZixiangEntity();
+ update.setId(shenqingZixiang.getId());
+ update.setShifouYichuku("yes");
+ LambdaQueryWrapper<LimsHaocaiChukuShenqingZixiangEntity> wrapper = new LambdaQueryWrapper<>();
+ wrapper.eq(LimsHaocaiChukuShenqingZixiangEntity::getId, shenqingZixiang.getId());
+ wrapper.and(w -> w.isNull(LimsHaocaiChukuShenqingZixiangEntity::getShifouYichuku)
+ .or()
+ .ne(LimsHaocaiChukuShenqingZixiangEntity::getShifouYichuku, "yes"));
+ int updated = chukuShenqingZixiangMapper.update(update, wrapper);
+ if (updated <= 0) {
+ throw new DataException("鐢抽瀛愰」宸插嚭搴擄紝涓嶈兘閲嶅鍑哄簱锛�" + shenqingZixiang.getTiaomaBianma());
+ }
+ }
+
+ private LimsHaocaiXiaohuiShenqingEntity getXiaohuiShenqingByDanhao(String xiaohuiDanhao) {
+ LambdaQueryWrapper<LimsHaocaiXiaohuiShenqingEntity> wrapper = new LambdaQueryWrapper<>();
+ wrapper.eq(LimsHaocaiXiaohuiShenqingEntity::getXiaohuiDanhao, trimToEmpty(xiaohuiDanhao));
+ wrapper.and(w -> w.isNull(LimsHaocaiXiaohuiShenqingEntity::getDeleteMark)
+ .or()
+ .ne(LimsHaocaiXiaohuiShenqingEntity::getDeleteMark, 1));
+ return xiaohuiShenqingMapper.selectList(wrapper).stream().findFirst().orElse(null);
+ }
+
+ private LimsHaocaiXiaohuiShenqingEntity getXiaohuiShenqingByFlow(String flowId, String taskId) {
+ LambdaQueryWrapper<LimsHaocaiXiaohuiShenqingEntity> wrapper = new LambdaQueryWrapper<>();
+ wrapper.eq(LimsHaocaiXiaohuiShenqingEntity::getFlowId, trimToEmpty(flowId));
+ wrapper.eq(LimsHaocaiXiaohuiShenqingEntity::getFlowTaskId, trimToEmpty(taskId));
+ wrapper.and(w -> w.isNull(LimsHaocaiXiaohuiShenqingEntity::getDeleteMark)
+ .or()
+ .ne(LimsHaocaiXiaohuiShenqingEntity::getDeleteMark, 1));
+ return xiaohuiShenqingMapper.selectList(wrapper).stream().findFirst().orElse(null);
+ }
+
+ private LimsHaocaiChukuShenqingEntity getApprovedChukuShenqingByDanhao(String shenlingDanhao) {
+ LambdaQueryWrapper<LimsHaocaiChukuShenqingEntity> wrapper = new LambdaQueryWrapper<>();
+ wrapper.eq(LimsHaocaiChukuShenqingEntity::getShenlingDanhao, trimToEmpty(shenlingDanhao));
+ wrapper.eq(LimsHaocaiChukuShenqingEntity::getFlowState, FLOW_STATE_APPROVED);
+ wrapper.and(w -> w.isNull(LimsHaocaiChukuShenqingEntity::getDeleteMark)
+ .or()
+ .ne(LimsHaocaiChukuShenqingEntity::getDeleteMark, 1));
+ return chukuShenqingMapper.selectList(wrapper).stream().findFirst().orElse(null);
+ }
+
+ private LimsHaocaiChukuShenqingZixiangEntity getChukuShenqingZixiang(String foreignId, String tiaomaBianma) {
+ LambdaQueryWrapper<LimsHaocaiChukuShenqingZixiangEntity> wrapper = new LambdaQueryWrapper<>();
+ wrapper.eq(LimsHaocaiChukuShenqingZixiangEntity::getForeignId, trimToEmpty(foreignId));
+ wrapper.eq(LimsHaocaiChukuShenqingZixiangEntity::getTiaomaBianma, trimToEmpty(tiaomaBianma));
+ wrapper.and(w -> w.isNull(LimsHaocaiChukuShenqingZixiangEntity::getDeleteMark)
+ .or()
+ .ne(LimsHaocaiChukuShenqingZixiangEntity::getDeleteMark, 1));
+ return chukuShenqingZixiangMapper.selectList(wrapper).stream().findFirst().orElse(null);
+ }
+
+ private LimsHaocaiRukuZixiangEntity getUniqueRukuZixiangByTiaomaBianma(String tiaomaBianma) {
+ List<LimsHaocaiRukuZixiangEntity> list = listRukuZixiangByTiaomaBianma(tiaomaBianma);
+ return list == null || list.isEmpty() ? null : list.get(0);
+ }
+
+ private void updateRukuJieyuShuliang(LimsHaocaiRukuZixiangEntity rukuZixiang,
+ String zeroBizStatus) throws DataException {
+ updateRukuJieyuShuliang(rukuZixiang, false, zeroBizStatus);
+ }
+
+ private void updateRukuJieyuShuliang(LimsHaocaiRukuZixiangEntity rukuZixiang,
+ boolean increase,
+ String zeroBizStatus) throws DataException {
+ BigDecimal changeAmount = parseRequiredDecimal(rukuZixiang.getShengyuliang(),
+ "鑰楁潗鍓╀綑閲忔棤鏁堬細" + rukuZixiang.getTiaomaBianma());
+ updateRukuJieyuShuliang(rukuZixiang, changeAmount, increase, zeroBizStatus);
+ }
+
+ private void updateRukuJieyuShuliang(LimsHaocaiRukuZixiangEntity rukuZixiang,
+ BigDecimal changeAmount,
+ boolean increase,
+ String zeroBizStatus) throws DataException {
+ String id = trimToEmpty(rukuZixiang.getRukuId());
+ if (id.isEmpty()) {
+ throw new DataException("鑰楁潗鍏ュ簱涓昏〃涓婚敭涓嶈兘涓虹┖");
+ }
+ LimsHaocaiRukuEntity ruku = this.getById(id);
+ if (ruku == null || Integer.valueOf(1).equals(ruku.getDeleteMark())) {
+ throw new DataException("鑰楁潗鍏ュ簱涓昏〃涓嶅瓨鍦細" + id);
+ }
+ BigDecimal jieyuShuliang = parseOptionalDecimal(ruku.getJieyuShuliang());
+ if (jieyuShuliang == null) {
+ jieyuShuliang = parseOptionalDecimal(ruku.getRukuShuliang());
+ }
+ if (jieyuShuliang == null) {
+ throw new DataException("鍏ュ簱涓昏〃缁撲綑鏁伴噺鏃犳晥锛�" + id);
+ }
+ BigDecimal changeShuliang = calculateJieyuChangeShuliang(ruku, rukuZixiang, changeAmount);
+ BigDecimal newJieyuShuliang = increase
+ ? jieyuShuliang.add(changeShuliang)
+ : jieyuShuliang.subtract(changeShuliang);
+ if (newJieyuShuliang.compareTo(BigDecimal.ZERO) < 0) {
+ newJieyuShuliang = BigDecimal.ZERO;
+ }
+
+ LimsHaocaiRukuEntity update = new LimsHaocaiRukuEntity();
+ update.setId(id);
+ update.setJieyuShuliang(toPlainString(newJieyuShuliang));
+ update.setBizStatus(resolveRukuBizStatus(ruku, newJieyuShuliang, zeroBizStatus));
+ this.updateById(update);
+ }
+
+ private void updateRukuBizStatus(List<String> rukuIds, String bizStatus) {
+ if (rukuIds == null || rukuIds.isEmpty()) {
+ return;
+ }
+ LimsHaocaiRukuEntity update = new LimsHaocaiRukuEntity();
+ update.setBizStatus(bizStatus);
+ LambdaQueryWrapper<LimsHaocaiRukuEntity> wrapper = new LambdaQueryWrapper<>();
+ wrapper.in(LimsHaocaiRukuEntity::getId, rukuIds);
+ wrapper.and(w -> w.isNull(LimsHaocaiRukuEntity::getDeleteMark)
+ .or()
+ .ne(LimsHaocaiRukuEntity::getDeleteMark, 1));
+ this.update(update, wrapper);
+ }
+
+ private String resolveRukuBizStatus(LimsHaocaiRukuEntity ruku,
+ BigDecimal jieyuShuliang,
+ String zeroBizStatus) throws DataException {
+ if (jieyuShuliang.compareTo(BigDecimal.ZERO) <= 0) {
+ return zeroBizStatus;
+ }
+ BigDecimal rukuShuliang = parseRequiredDecimal(ruku.getRukuShuliang(),
+ "鍏ュ簱涓昏〃鍏ュ簱鏁伴噺鏃犳晥锛�" + ruku.getId());
+ if (jieyuShuliang.compareTo(rukuShuliang) >= 0) {
+ return BIZ_STATUS_WEICHUKU;
+ }
+ return BIZ_STATUS_YIKAIPING;
+ }
+
+ private BigDecimal calculateJieyuChangeShuliang(LimsHaocaiRukuEntity ruku,
+ LimsHaocaiRukuZixiangEntity rukuZixiang) throws DataException {
+ BigDecimal changeAmount = parseRequiredDecimal(rukuZixiang.getShengyuliang(),
+ "鑰楁潗鍓╀綑閲忔棤鏁堬細" + rukuZixiang.getTiaomaBianma());
+ return calculateJieyuChangeShuliang(ruku, rukuZixiang, changeAmount);
+ }
+
+ private BigDecimal calculateJieyuChangeShuliang(LimsHaocaiRukuEntity ruku,
+ LimsHaocaiRukuZixiangEntity rukuZixiang,
+ BigDecimal changeAmount) throws DataException {
+ BigDecimal zongliang = parseRequiredDecimal(rukuZixiang.getZongliang(),
+ "鑰楁潗鎬婚噺鏃犳晥锛�" + rukuZixiang.getTiaomaBianma());
+ if (zongliang.compareTo(BigDecimal.ZERO) <= 0) {
+ throw new DataException("鑰楁潗鎬婚噺蹇呴』澶т簬0锛�" + rukuZixiang.getTiaomaBianma());
+ }
+ if (changeAmount.compareTo(BigDecimal.ZERO) < 0) {
+ throw new DataException("鑰楁潗鍙樺寲閲忎笉鑳藉皬浜�0锛�" + rukuZixiang.getTiaomaBianma());
+ }
+ BigDecimal ratio = changeAmount.divide(zongliang, 8, java.math.RoundingMode.HALF_UP);
+ if ("yes".equalsIgnoreCase(trimToEmpty(ruku.getShifouYigeTiaoma()))) {
+ BigDecimal rukuShuliang = parseRequiredDecimal(ruku.getRukuShuliang(),
+ "鍏ュ簱涓昏〃鍏ュ簱鏁伴噺鏃犳晥锛�" + ruku.getId());
+ return ratio.multiply(rukuShuliang).stripTrailingZeros();
+ }
+ return ratio.stripTrailingZeros();
+ }
+
+ private boolean isChukuAvailableStatus(String bizStatus) {
+ String status = trimToEmpty(bizStatus);
+ return BIZ_STATUS_WEICHUKU.equalsIgnoreCase(status)
+ || BIZ_STATUS_YIKAIPING.equalsIgnoreCase(status);
+ }
+
+ private boolean isBorrowableStatus(String bizStatus) {
+ return isChukuAvailableStatus(bizStatus);
+ }
+
+ private String resolveAvailableBizStatus(BigDecimal shengyuliang,
+ LimsHaocaiRukuZixiangEntity rukuZixiang) throws DataException {
+ BigDecimal zongliang = parseRequiredDecimal(rukuZixiang.getZongliang(),
+ "鑰楁潗鎬婚噺鏃犳晥锛�" + rukuZixiang.getTiaomaBianma());
+ if (shengyuliang.compareTo(zongliang) >= 0) {
+ return BIZ_STATUS_WEICHUKU;
+ }
+ return BIZ_STATUS_YIKAIPING;
+ }
+
+ private String resolveYanshouZhuangtai(LimsHaocaiRukuEntity ruku) {
+ return isYanshouEnabled(ruku)
+ ? YANSHOU_STATUS_YIYANSHOU
+ : YANSHOU_STATUS_NA;
+ }
+
+ private boolean isYanshouEnabled(LimsHaocaiRukuEntity ruku) {
+ return ruku != null && "yes".equalsIgnoreCase(trimToEmpty(ruku.getShifouQiyongYanshou()));
+ }
+
+ private void updateRukuYanshouRukuId(LimsHaocaiRukuEntity ruku) throws DataException {
+ String yanshouId = trimToEmpty(ruku.getYanshouId());
+ if (yanshouId.isEmpty()) {
+ throw new DataException("鍚敤楠屾敹鐨勫叆搴撳崟蹇呴』鍏宠仈楠屾敹璁板綍涓婚敭(yanshou_id)锛�" + ruku.getId());
+ }
+
+ LambdaUpdateWrapper<LimsHaocaiRukuYanshouEntity> update = new LambdaUpdateWrapper<>();
+ update.eq(LimsHaocaiRukuYanshouEntity::getId, yanshouId)
+ .and(w -> w.isNull(LimsHaocaiRukuYanshouEntity::getDeleteMark)
+ .or().ne(LimsHaocaiRukuYanshouEntity::getDeleteMark, 1))
+ .set(LimsHaocaiRukuYanshouEntity::getRukuId, ruku.getId());
+ if (rukuYanshouMapper.update(null, update) != 1) {
+ throw new DataException("鑰楁潗鍏ュ簱楠屾敹璁板綍涓嶅瓨鍦ㄦ垨宸插垹闄わ細" + yanshouId);
+ }
+ }
+
+ private String yanshouShenqingStatusLabel(String status) {
+ String value = trimToEmpty(status);
+ if (YANSHOU_SHENQING_STATUS_DAIYANSHOU.equals(value)) {
+ return "寰呴獙鏀�";
+ }
+ if (YANSHOU_SHENQING_STATUS_YANSHOUZHONG.equals(value)) {
+ return "楠屾敹涓�";
+ }
+ return value.isEmpty() ? "鏈缃�" : value;
+ }
+
+ /**
+ * 鍙栨潯鐮佸彿銆侭illRuleApi 閰嶄簡闈欐�� fallback锛圠009锛夛細system 鏈嶅姟涓嶅彲鐢ㄦ椂
+ * 闈欓粯杩斿洖绌� ActionResult 鑰屼笉鎶涘紓甯革紝蹇呴』鏄惧紡鏍¢獙鍙栧彿缁撴灉锛岀┖鍙风珛鍗冲け璐ュ洖婊氥��
+ */
+ private String nextTiaomaBianma() throws DataException {
+ ActionResult<String> result = billRuleApi.getBillNumber(TIAOMA_BILL_RULE);
+ String tiaoma = result == null ? null : result.getData();
+ if (StringUtil.isEmpty(tiaoma)) {
+ throw new DataException("鏉$爜鍙栧彿澶辫触锛氬崟鎹鍒橻" + TIAOMA_BILL_RULE + "]涓嶅彲鐢紝璇风‘璁よ鍒欏凡閰嶇疆涓旂郴缁熸湇鍔″湪绾�");
+ }
+ return tiaoma;
+ }
+
+ private BigDecimal parseShuliang(String rukuShuliang) throws DataException {
+ try {
+ BigDecimal shuliang = new BigDecimal(trimToEmpty(rukuShuliang));
+ if (shuliang.compareTo(BigDecimal.ZERO) <= 0) {
+ throw new DataException("鍏ュ簱鏁伴噺蹇呴』澶т簬0锛�" + rukuShuliang);
+ }
+ return shuliang;
+ } catch (NumberFormatException e) {
+ throw new DataException("鍏ュ簱鏁伴噺鏃犳晥锛�" + rukuShuliang);
+ }
+ }
+
+ private int calculateCompleteTiaomaCount(BigDecimal shuliang, String originalQuantity)
+ throws DataException {
+ try {
+ return shuliang.setScale(0, RoundingMode.DOWN).intValueExact();
+ } catch (ArithmeticException e) {
+ throw new DataException("鍏ュ簱鏁伴噺杩囧ぇ锛�" + originalQuantity);
+ }
+ }
+
+ private BigDecimal parseRongliang(String rongliang) throws DataException {
+ try {
+ return new BigDecimal(trimToEmpty(rongliang));
+ } catch (NumberFormatException e) {
+ throw new DataException("瀹归噺鏃犳晥锛�" + rongliang);
+ }
+ }
+
+ private BigDecimal parseRequiredDecimal(String value, String errorMessage) throws DataException {
+ BigDecimal decimal = parseOptionalDecimal(value);
+ if (decimal == null) {
+ throw new DataException(errorMessage);
+ }
+ return decimal;
+ }
+
+ private BigDecimal parseOptionalDecimal(String value) {
+ String text = trimToEmpty(value);
+ if (text.isEmpty()) {
+ return null;
+ }
+ try {
+ return new BigDecimal(text);
+ } catch (NumberFormatException e) {
+ return null;
+ }
+ }
+
+ private List<String> normalizeIds(List<String> ids) {
+ List<String> result = new ArrayList<>();
+ if (ids == null) {
+ return result;
+ }
+ for (String id : ids) {
+ String value = trimToEmpty(id);
+ if (!value.isEmpty() && !result.contains(value)) {
+ result.add(value);
+ }
+ }
+ return result;
+ }
+
+ private String trimToEmpty(String value) {
+ return value == null ? "" : value.trim();
+ }
+
+ private String firstNotBlank(String first, String second) {
+ String value = trimToEmpty(first);
+ return value.isEmpty() ? second : value;
+ }
+
+ private String toPlainString(BigDecimal value) {
+ return value.stripTrailingZeros().toPlainString();
+ }
+}
--
Gitblit v1.8.0