| | |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | |
| | | import java.math.BigDecimal; |
| | | import java.time.LocalDate; |
| | | import java.time.LocalDateTime; |
| | | import java.time.YearMonth; |
| | | import java.time.format.DateTimeFormatter; |
| | |
| | | |
| | | @Override |
| | | public StatementAccountVo getAccountStatementDetailsByMonth(StatementAccountDto statementAccountDto) { |
| | | //对账月份转换成开始日期和结束日期区间 |
| | | //对账期间支持按日(yyyy-MM-dd)或按月(yyyy-MM),转换成开始日期和结束日期区间 |
| | | String statementMonth = statementAccountDto.getStatementMonth(); |
| | | if (statementMonth != null && statementMonth.length() == 10) { |
| | | LocalDate day = LocalDate.parse(statementMonth, DateTimeFormatter.ofPattern("yyyy-MM-dd")); |
| | | statementAccountDto.setStartDate(day); |
| | | statementAccountDto.setEndDate(day); |
| | | } else { |
| | | DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM"); |
| | | YearMonth yearMonth = YearMonth.parse(statementAccountDto.getStatementMonth(), formatter); |
| | | YearMonth yearMonth = YearMonth.parse(statementMonth, formatter); |
| | | statementAccountDto.setStartDate(yearMonth.atDay(1)); |
| | | statementAccountDto.setEndDate(yearMonth.atEndOfMonth()); |
| | | } |
| | | if (statementAccountDto.getAccountType() == 1){ |
| | | //应收对账--Customer |
| | | return getAccountStatementDetailsByCustomerAndMonth(statementAccountDto); |
| | |
| | | |
| | | @Override |
| | | public boolean addAccountStatement(StatementAccountVo statementAccountVo) { |
| | | //同一客户或者同一供应商,一个月份只能有一个对账单 |
| | | //同一客户或者同一供应商,同一对账期间只能有一个对账单 |
| | | List<AccountStatement> accountStatements = accountStatementMapper.selectList(Wrappers.<AccountStatement>lambdaQuery() |
| | | .eq(AccountStatement::getStatementMonth, statementAccountVo.getStatementMonth()) |
| | | .eq(AccountStatement::getAccountType, statementAccountVo.getAccountType()) |
| | | .eq(AccountStatement::getCustomerId, statementAccountVo.getCustomerId())); |
| | | if (CollectionUtils.isNotEmpty(accountStatements)){ |
| | | throw new ServiceException("同一客户或者同一供应商,一个月份只能有一个对账单"); |
| | | throw new ServiceException("同一客户或者同一供应商,同一对账期间只能有一个对账单"); |
| | | } |
| | | AccountStatement accountStatement = new AccountStatement(); |
| | | BeanUtils.copyProperties(statementAccountVo, accountStatement); |
| | |
| | | accountStatementDetails.setRemark("产品退货,原因:"+salesReturnVo.getReturnReason()); |
| | | accountStatementDetailsList.add(accountStatementDetails); |
| | | }); |
| | | //期初余额=上个月的期末余额 |
| | | statementAccountVo.setOpeningBalance(BigDecimal.ZERO); |
| | | List<AccountStatement> accountStatements = accountStatementMapper.selectList(Wrappers.<AccountStatement>lambdaQuery() |
| | | .eq(AccountStatement::getAccountType, 1) |
| | | .eq(AccountStatement::getCustomerId, statementAccountDto.getCustomerId()) |
| | | .eq(AccountStatement::getStatementMonth, |
| | | YearMonth.parse(statementAccountDto.getStatementMonth()).minusMonths(1).toString())); |
| | | if (CollectionUtils.isNotEmpty(accountStatements)){ |
| | | statementAccountVo.setOpeningBalance(accountStatements.get(accountStatements.size() - 1).getClosingBalance()); |
| | | } |
| | | //期初余额=上一期(上一月/上一天)对账单的期末余额 |
| | | statementAccountVo.setOpeningBalance(getPreviousClosingBalance(1, statementAccountDto.getCustomerId(), statementAccountDto.getStatementMonth())); |
| | | //本期应收=出库-退货金额累计 |
| | | statementAccountVo.setCurrentPlan(salesOutboundVos.stream().map(SalesOutboundVo::getOutboundAmount).reduce(BigDecimal.ZERO, BigDecimal::add) |
| | | .subtract(salesReturnVos.stream().map(SalesReturnVo::getRefundAmount).reduce(BigDecimal.ZERO, BigDecimal::add))); |
| | |
| | | accountStatementDetails.setRemark("产品退货,退货方式:"+purchaseReturnVo.getReturnType()); |
| | | accountStatementDetailsList.add(accountStatementDetails); |
| | | }); |
| | | //期初余额=上个月的期末余额 |
| | | statementAccountVo.setOpeningBalance(BigDecimal.ZERO); |
| | | List<AccountStatement> accountStatements = accountStatementMapper.selectList(Wrappers.<AccountStatement>lambdaQuery() |
| | | .eq(AccountStatement::getAccountType, 2) |
| | | .eq(AccountStatement::getCustomerId, statementAccountDto.getCustomerId()) |
| | | .eq(AccountStatement::getStatementMonth, |
| | | YearMonth.parse(statementAccountDto.getStatementMonth()).minusMonths(1).toString())); |
| | | if (CollectionUtils.isNotEmpty(accountStatements)){ |
| | | statementAccountVo.setOpeningBalance(accountStatements.get(accountStatements.size() - 1).getClosingBalance()); |
| | | } |
| | | //期初余额=上一期(上一月/上一天)对账单的期末余额 |
| | | statementAccountVo.setOpeningBalance(getPreviousClosingBalance(2, statementAccountDto.getCustomerId(), statementAccountDto.getStatementMonth())); |
| | | //本期应付=入库-退货金额累计 |
| | | statementAccountVo.setCurrentPlan(purchaseInboundVos.stream().map(PurchaseInboundVo::getInboundAmount).reduce(BigDecimal.ZERO, BigDecimal::add) |
| | | .subtract(purchaseReturnVos.stream().map(PurchaseReturnVo::getTotalAmount).reduce(BigDecimal.ZERO, BigDecimal::add))); |
| | |
| | | return statementAccountVo; |
| | | } |
| | | |
| | | /** |
| | | * 取同一客户/供应商在当前对账期间之前最近一期对账单的期末余额,作为本期期初余额。 |
| | | * 支持按月(yyyy-MM)和按日(yyyy-MM-dd)两种对账期间。 |
| | | */ |
| | | private BigDecimal getPreviousClosingBalance(Integer accountType, Long customerId, String statementMonth) { |
| | | AccountStatement previous = accountStatementMapper.selectOne(Wrappers.<AccountStatement>lambdaQuery() |
| | | .eq(AccountStatement::getAccountType, accountType) |
| | | .eq(AccountStatement::getCustomerId, customerId) |
| | | .lt(AccountStatement::getStatementMonth, statementMonth) |
| | | .orderByDesc(AccountStatement::getStatementMonth) |
| | | .last("LIMIT 1")); |
| | | return previous == null || previous.getClosingBalance() == null |
| | | ? BigDecimal.ZERO : previous.getClosingBalance(); |
| | | } |
| | | |
| | | private String genStatementAccountNo() { |
| | | return "DZ" + LocalDateTime.now().format(CODE_TIME_FORMATTER) + new Random().nextInt(10); |
| | | } |