领域驱动设计 用DDD重构会计凭证生成(下)( 八 )

getFeeListByBillNo4Voucher(String billNo) {List resultList = expenseFeesService.getFeeListByBillNo(billNo);boolean isNeedHandleHistory = false;for (ExpenseFeesPO result : resultList) {if (null == result.getOccupyAmount()) {isNeedHandleHistory = true;break;}}if (isNeedHandleHistory) {newExpenseBillFormLogic.fillExpenseData(resultList);}return resultList;}}
以上是门面微服务中为一个类型的单据进行数据组织的代码 。也就是说 , 如果要新增一个凭证生成规则就得在门面微服务中创建一个上面的类 , 并且修改接下来的凭证微服务中的凭证生成方法 。
以下就是凭证微服务中原有的创建凭证的方法(仅就这个方法和其调用的方法而言 , 有大量可优化的地方 , 尤其是最扎眼也最让人难以忍受的那堆魔数) , 也就是负责接收门面微服务所发送的数据的方法 。
@Slf4j@Servicepublic class AccountDocumentCreateLogicImpl implements AccountDocumentCreateLogic {...@Override@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)public ResponseBuilder create(List adCreateRequestVos) {//验证请求log.info("凭证生成请求参数验证");AccountDocumentCheckUtil.checkCreateRequest(adCreateRequestVos);//校验是否已经存在凭证AdQueryVO adQueryVO = new AdQueryVO();adQueryVO.setBillNo(adCreateRequestVos.get(0).getBillNo());Integer count = adAccountDocumentService.getCount(adQueryVO);if (count > 0) {log.error("凭证生成调用时 , 系统已存在凭证 , 提示用户删除 , 单据编号:{}", adCreateRequestVos.get(0).getBillNo());throw new BizException("请刷新页面 , 先删除凭证");}//生成凭证log.info("凭证生成开始");this.saveAccountDocument(adCreateRequestVos);log.info("凭证生成结束");if ("3".equals(adCreateRequestVos.get(0).getBillTypeKind())|| BILL_TYPE_KIND_FINGERTIP.equals(adCreateRequestVos.get(0).getBillTypeKind())|| "19".equals(adCreateRequestVos.get(0).getBillTypeKind())) {ResponseBuilder responseBuilder = new ResponseBuilder();Integer pushType = BILL_TYPE_KIND_FINGERTIP.equals(adCreateRequestVos.get(0).getBillTypeKind()) ? 1 : 0;try {responseBuilder = pushVoucherLogic.pushVoucherByBillNo(adCreateRequestVos.get(0).getBillNo(), pushType, null, "");} catch (Exception e) {e.printStackTrace();log.error("其他异常 , 凭证推送失败:", e.getCause());}if ("1".equals(responseBuilder.getStatus()) && "9999".equals(responseBuilder.getErrorCode())) {log.error("凭证推送失败 , 未获取到凭证信息");throw new BizException(responseBuilder.getErrorMsg());}}//成功返回return ResponseBuilder.ok();}private void saveAccountDocument(List adCreateRequestVos) {//一级、二级部门名称集合查询 , 暂存在AdCreateRequestVO ,  要保存完adAccountDocument之后再暂存List depts = this.deptFacade.getDepts();AdAccountDocumentPO accountDocument;for (AdCreateRequestVO adCreateRequestVO : adCreateRequestVos) {accountDocument = this.adAccountDocumentService.populateAccountDocument(adCreateRequestVO);//保存凭证主数据log.info("保存凭证主信息 , {}", JSON.toJSONString(accountDocument));adAccountDocumentService.save(accountDocument);//暂存在AdCreateRequestVO ,  要保存完adAccountDocument之后再暂存adCreateRequestVO.setDepts(depts);//保存凭证数据boolean generateFlag = this.saveAccountDocumentInfo(adCreateRequestVO, accountDocument.getId());if (!generateFlag) {log.info("凭证规则未配置时 , 回滚凭证主信息, accountDocument.billNo = {}", accountDocument.getBillNo());throw new BizException("无凭证生成规则");}}}private boolean saveAccountDocumentInfo(AdCreateRequestVO vo, Long id) {//是否生成了分录boolean generateFlag = false;log.info("设置是否全额抵扣");this.setAllDeductible(vo);for (AdCreateAmountRequestVO amount : vo.getAmounts()) {log.info("凭证金额参数:{}", JSON.toJSONString(amount));//金额不等于0 , 需生成凭证if (amount.getAmountValue().compareTo(BigDecimal.ZERO) != 0) {//金额映射到凭证类型String voucherType = AmountTypeEnum.getVoucherType(amount.getAmountName());log.info("凭证规则获取参数:单据类型编码={} , 是否预付={} , 是否关联方交易={} , 根据金额转化的业务类型={}", vo.getBillTypeCode(), vo.getPrepayFlag(), vo.getRelatedParty(), voucherType);//查找凭证规则AdAccountRulePO rule = adAccountRuleService.getRule(vo.getBillTypeCode(), vo.getPrepayFlag(), vo.getRelatedParty(), voucherType);//凭证规则的配置决定凭证是否生成if (rule == null) {log.info("凭证规则未配置 , 不生成凭证 , 单据类型:{} , 是否预付:{} , 是否关联方交易={} , 凭证类型:{}", vo.getBillTypeCode(), vo.getPrepayFlag(), vo.getRelatedParty(), voucherType);throw new BizException(MessageFormat.format("凭证规则中缺少单据类型为[{0}],关联方交易为[{1}],是否预付为[{2}],凭证类型为[{3}]的配置", vo.getBillTypeCode(), vo.getRelatedParty(), vo.getPrepayFlag(), voucherType));}log.info("AdAccountRulePO -> {}", JSON.toJSONString(rule));generateFlag = true;AdAccountDocumentInfoPO accountDocumentInfo = this.adAccountDocumentInfoService.populateAccountDocumentInfo(vo, id, rule);// SAVE accountDocumentInfolog.info("凭证信息保存 , {}", JSON.toJSONString(accountDocumentInfo));adAccountDocumentInfoService.save(accountDocumentInfo);int entrySeq = 1;int detailNum = 0;//不用考虑规则配置科目列表为空的情况 , 规则配置处限制log.info("凭证规则借贷关系条数:{}", rule.getRuleSubjects().size());//存储每个费用行生成的分录对象 key:fee.idMap