| | |
| | | import com.ruoyi.outsourcing.mapper.OutsourcingOrderProductMapper; |
| | | import com.ruoyi.outsourcing.pojo.OutsourcingOrder; |
| | | import com.ruoyi.outsourcing.pojo.OutsourcingOrderProduct; |
| | | import com.ruoyi.sales.dto.SalesLedgerDto; |
| | | import com.ruoyi.sales.mapper.SalesLedgerMapper; |
| | | import com.ruoyi.sales.mapper.SalesLedgerProductMapper; |
| | | import com.ruoyi.sales.pojo.SalesLedger; |
| | | import com.ruoyi.sales.pojo.SalesLedgerProduct; |
| | | |
| | | import java.time.LocalDateTime; |
| | | import com.ruoyi.stock.dto.OilOutAvailableDto; |
| | |
| | | */ |
| | | private static final String OUT_CATEGORY_SALE = "销售"; |
| | | |
| | | /** |
| | | * 出库类别:代储。客户把自己的油寄存在我们的罐里,提走只是记录一笔,不扣库存、不进发货台账 |
| | | */ |
| | | private static final String OUT_CATEGORY_DEPOSIT = "代储"; |
| | | |
| | | /** |
| | | * 销售台账的销售类型:代储(卖存储位置)。这类台账没有产品明细,只有油库+储罐,见 SalesLedger.ledgerType |
| | | */ |
| | | private static final String LEDGER_TYPE_DEPOSIT = "代储"; |
| | | |
| | | /** |
| | | * 销售台账产品明细的行类型:销售。见 sales_ledger_product.type |
| | | */ |
| | | private static final Integer LEDGER_PRODUCT_TYPE_SALE = 1; |
| | | |
| | | private final StockOutRecordMapper stockOutRecordMapper; |
| | | private final IVehicleService vehicleService; |
| | | private final StockInventoryMapper stockInventoryMapper; |
| | |
| | | private final AccountInvoiceApplicationMapper accountInvoiceApplicationMapper; |
| | | private final OutsourcingOrderProductMapper outsourcingOrderProductMapper; |
| | | private final OutsourcingOrderMapper outsourcingOrderMapper; |
| | | private final SalesLedgerMapper salesLedgerMapper; |
| | | private final SalesLedgerProductMapper salesLedgerProductMapper; |
| | | |
| | | @Override |
| | | public IPage<StockOutRecordDto> listPage(Page page, StockOutRecordDto stockOutRecordDto) { |
| | |
| | | |
| | | @Override |
| | | public int add(StockOutRecordDto stockOutRecordDto) { |
| | | resolveSalesLedgerBinding(stockOutRecordDto); |
| | | if (OUT_CATEGORY_SALE.equals(stockOutRecordDto.getOutCategory())) { |
| | | // 销售类油品出库审批通过时要按批次扣减库存,批次不能为空 |
| | | if (StringUtils.isEmpty(stockOutRecordDto.getBatchNo())) { |
| | |
| | | throw new BaseException("该出库记录不存在,无法更新!!!"); |
| | | } |
| | | |
| | | resolveSalesLedgerBinding(stockOutRecordDto); |
| | | String[] ignoreProperties = {"id", "outbound_batches"};//排除id属性 |
| | | BeanUtils.copyProperties(stockOutRecordDto, stockOutRecord, ignoreProperties); |
| | | return stockOutRecordMapper.updateById(stockOutRecord); |
| | | } |
| | | |
| | | /** |
| | | * 绑定销售台账:客户一律以台账为准覆盖,避免出库记录与台账的客户对不上;出库类别按台账的销售类型自动定, |
| | | * 免得出现「绑了卖油台账却按代储不扣库存」这类矛盾数据。 |
| | | * <ul> |
| | | * <li>卖油(含 ledgerType 为空):出库类别置「销售」,并校验所选规格确实在该台账的销售明细里</li> |
| | | * <li>代储:出库类别置「代储」,带入台账的油库/储罐,跳过产品校验 —— |
| | | * 代储台账本身就是卖存储位置,没有产品明细</li> |
| | | * </ul> |
| | | * salesLedgerId 为空时整体跳过,不绑台账的出库行为与改动前完全一致 |
| | | */ |
| | | private void resolveSalesLedgerBinding(StockOutRecordDto stockOutRecordDto) { |
| | | if (stockOutRecordDto.getSalesLedgerId() == null) { |
| | | return; |
| | | } |
| | | SalesLedger salesLedger = salesLedgerMapper.selectById(stockOutRecordDto.getSalesLedgerId()); |
| | | if (salesLedger == null) { |
| | | throw new BaseException("所选销售台账不存在,销售台账id:" + stockOutRecordDto.getSalesLedgerId()); |
| | | } |
| | | stockOutRecordDto.setCustomerId(salesLedger.getCustomerId()); |
| | | stockOutRecordDto.setCustomerName(salesLedger.getCustomerName()); |
| | | if (LEDGER_TYPE_DEPOSIT.equals(salesLedger.getLedgerType())) { |
| | | stockOutRecordDto.setOutCategory(OUT_CATEGORY_DEPOSIT); |
| | | stockOutRecordDto.setOilDepotId(salesLedger.getOilDepotId()); |
| | | stockOutRecordDto.setOilDepotName(salesLedger.getOilDepotName()); |
| | | stockOutRecordDto.setTankId(salesLedger.getTankId()); |
| | | stockOutRecordDto.setTankNo(salesLedger.getTankNo()); |
| | | return; |
| | | } |
| | | stockOutRecordDto.setOutCategory(OUT_CATEGORY_SALE); |
| | | if (stockOutRecordDto.getProductModelId() == null) { |
| | | throw new BaseException("绑定销售台账时必须选择产品规格,销售合同号:" + salesLedger.getSalesContractNo()); |
| | | } |
| | | boolean belongsToLedger = salesLedgerProductMapper.selectList( |
| | | Wrappers.<SalesLedgerProduct>lambdaQuery() |
| | | .eq(SalesLedgerProduct::getSalesLedgerId, stockOutRecordDto.getSalesLedgerId()) |
| | | .eq(SalesLedgerProduct::getType, LEDGER_PRODUCT_TYPE_SALE)) |
| | | .stream() |
| | | .anyMatch(item -> stockOutRecordDto.getProductModelId().equals(item.getProductModelId())); |
| | | if (!belongsToLedger) { |
| | | throw new BaseException("所选产品不在该销售台账明细中,销售合同号:" + salesLedger.getSalesContractNo()); |
| | | } |
| | | } |
| | | |
| | | @Override |
| | |
| | | } |
| | | |
| | | @Override |
| | | public IPage<SalesLedger> listBindableSalesLedger(Page page, SalesLedgerDto salesLedgerDto) { |
| | | // 该查询用 /*data_scope*/ 跳过数据权限,而 MP 默认会把 count 语句优化成「SELECT COUNT(*) FROM sales_ledger |
| | | // WHERE ...」,优化后标记丢失,count 反而被追加权限条件,total 会比实际记录少。关掉 count 优化后 |
| | | // count 退化成「SELECT COUNT(*) FROM (原句) TOTAL」,标记原样保留 |
| | | page.setOptimizeCountSql(false); |
| | | return stockOutRecordMapper.bindableSalesLedgerPage(page, salesLedgerDto); |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public int releaseByRecordIds(List<Long> recordIds, String recordType) { |
| | | List<StockOutRecord> records = listByRecordIds(recordIds, recordType); |