package com.sifang.modules.supply.stock;

import com.sifang.modules.sunshine.SystemSetting.utils.BusinessException;
import com.sifang.modules.supply.setting.dao.CrmSupplyWarehouseDao;
import com.sifang.modules.supply.setting.entity.CrmSupplyWarehouse;
import com.sifang.modules.supply.stock.dao.SupplyMaterialDao;
import com.sifang.modules.supply.stock.entity.SupplyMaterial;
import com.sifang.modules.supply.stock.service.SupplyMaterialKeepService;
import com.sifang.modules.supply.warehouse.dao.SupplyMaterialBatchDao;
import com.sifang.modules.supply.warehouse.entity.SupplyMaterialBatch;
import com.sifang.modules.sys.common.persistence.Parameter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;

/**
 * 先进先出的库存管理方式实现
 */
@Component
public class FIFOStockImpl implements IStock{

    @Autowired
    private SupplyMaterialBatchDao supplyMaterialBatchDao;

    @Autowired
    private SupplyMaterialDao materialDao;

    @Autowired
    private CrmSupplyWarehouseDao warehouseDao;

    @Autowired
    private SupplyMaterialKeepService keepService;

    @Override
    public void deliverForBatch(StockUnit uint, KeepUnit keepUnit, BigDecimal amount,String deliveryMethodName) {
        List<SupplyMaterialBatch> batches = findCanDeliverBatchList(uint);
        deliverForBatch(uint, keepUnit, batches, amount,deliveryMethodName);
    }

    private List<SupplyMaterialBatch> findCanDeliverBatchList(StockUnit uint) {
        return supplyMaterialBatchDao.find("FROM SupplyMaterialBatch WHERE materialId =:p1 AND warehouseId =:p2 and remaining > 0 ORDER BY createTime ASC", new Parameter(uint.getMaterialId(), uint.getWarehouseId()));
    }

    private void deliverForBatch(StockUnit unit, KeepUnit keepUnit, List<SupplyMaterialBatch> batches, BigDecimal amount,String deliveryMethodName) {
        BigDecimal waitDeliver = amount;
        BigDecimal realAmount = BigDecimal.ZERO;
        for (SupplyMaterialBatch batch : batches) {
            BigDecimal canDeliver = batch.getAmount().subtract(batch.getSoldNum());
            boolean canBreak = false;
            if (canDeliver.compareTo(waitDeliver) < 0) {//本批次全部出库, 寻找下一个批次出库
                batch.setSoldNum(batch.getAmount());
                batch.setRemaining(BigDecimal.ZERO);
                batch.setNewestKeepTime(new Date());
                batch.setUpdateTime(new Date());
                supplyMaterialBatchDao.save(batch);
                waitDeliver = waitDeliver.subtract(canDeliver);
                realAmount = canDeliver;
            } else if (canDeliver.compareTo(waitDeliver) >= 0) {//本批次部分出库, 停止寻找下一个批次
                batch.setSoldNum(batch.getSoldNum().add(waitDeliver));
                batch.setRemaining(batch.getRemaining().subtract(waitDeliver));
                batch.setNewestKeepTime(new Date());
                batch.setUpdateTime(new Date());
                supplyMaterialBatchDao.save(batch);
                realAmount = waitDeliver;
                waitDeliver = BigDecimal.ZERO;
                canBreak = true;
            }
            keepUnit.setAmount(realAmount);
            keepService.createKeep(keepUnit, batch,deliveryMethodName);
            if (canBreak) {
                break;
            }
        }
        if (waitDeliver.compareTo(BigDecimal.ZERO) > 0) {
            SupplyMaterial material = materialDao.get(unit.getMaterialId());
            CrmSupplyWarehouse warehouse = warehouseDao.get(unit.getWarehouseId());

//            String info = String.format("物料【%s】编码【%s】仓库【%s】"
//                    , material.getMaterialName(), material.getCode(), warehouse.getName());

            throw new BusinessException("库存批次数量不足");
        }
    }
}
