package com.patzn.lims.consume.service.impl;

import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.patzn.cloud.commons.api.RestAssert;
import com.patzn.cloud.commons.toolkit.BigDecimalUtils;
import com.patzn.lims.consume.dto.LmsChemicalStockDTO;
import com.patzn.lims.consume.entity.LmsChemical;
import com.patzn.lims.consume.entity.LmsChemicalRelDelivery;
import com.patzn.lims.consume.entity.LmsChemicalStock;
import com.patzn.lims.consume.entity.LmsChemicalUserecord;
import com.patzn.lims.consume.enums.DeliveryRelStateEnum;
import com.patzn.lims.consume.enums.PurchaseRelStateEnum;
import com.patzn.lims.consume.mapper.LmsChemicalRelDeliveryMapper;
import com.patzn.lims.consume.service.ILmsChemicalDeliveryOrderService;
import com.patzn.lims.consume.service.ILmsChemicalRelDeliveryService;
import com.patzn.lims.consume.service.ILmsChemicalService;
import com.patzn.lims.consume.service.ILmsChemicalStockService;
import com.patzn.lims.consume.vo.LmsChemicalRelDeliveryVO;
import com.patzn.lims.core.api.PtAssert;
import com.patzn.lims.core.web.Account;
import com.patzn.lims.core.web.BaseServiceImpl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.patzn.lims.core.web.LoginHelper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

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

/**
 * <p>
 * 试验耗材采购关联表 服务实现类
 * </p>
 *
 * @author wwd
 * @since 2020-03-25
 */
@Service
public class LmsChemicalRelDeliveryServiceImpl extends BaseServiceImpl<LmsChemicalRelDeliveryMapper, LmsChemicalRelDelivery> implements ILmsChemicalRelDeliveryService {

    @Autowired
    private ILmsChemicalStockService lmsChemicalStockService;
    @Autowired
    private ILmsChemicalService lmsChemicalService;
    @Autowired
    private ILmsChemicalDeliveryOrderService lmsChemicalDeliveryOrderService;
    @Override
    public Page<LmsChemicalRelDelivery> page(Page<LmsChemicalRelDelivery> page, LmsChemicalRelDelivery lmsChemicalRelDelivery) {
        QueryWrapper<LmsChemicalRelDelivery> wrapper = Wrappers.<LmsChemicalRelDelivery>query(lmsChemicalRelDelivery);
        return this.page(page, wrapper);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean saveOutOrder(LmsChemicalRelDelivery chemicalRelDelivery) {
        if (null == chemicalRelDelivery.getStockId()
                || null == chemicalRelDelivery.getQuantity()) {
            return false;
        }
        LmsChemicalStock chemicalStock = lmsChemicalStockService.getById(chemicalRelDelivery.getStockId());
        if (null == chemicalStock) {
            PtAssert.fail("耗材库存异常，刷新重试。");
        }
        if (BigDecimalUtils.greaterThan(chemicalRelDelivery.getQuantity(), chemicalStock.getStock())) {
            PtAssert.fail("出库数量大于库存数量，请重新输入。");
        }
        LmsChemical chemical = lmsChemicalService.getById(chemicalStock.getChemicalId());
        if (null == chemical) {
            PtAssert.fail("耗材不存在，刷新重试。");
        }
        LmsChemicalRelDelivery lcrd = baseMapper.selectChemicalRelDeliveryByAdd(chemical.getId(), LoginHelper.getAccount().getUserId(), chemicalRelDelivery.getStockId());
        if (null == lcrd) {
            //获取
            chemicalRelDelivery.setChemicalId(chemical.getId());
            chemicalRelDelivery.setChemicalNum(chemical.getNum());
            chemicalRelDelivery.setChemicalName(chemical.getName());
            chemicalRelDelivery.setSpec(chemical.getSpec());
            chemicalRelDelivery.setPrice(chemical.getUnitPrice());
            chemicalRelDelivery.setManufacturer(chemical.getManufacturer());
            chemicalRelDelivery.setStockId(chemicalStock.getId());
            chemicalRelDelivery.setSupplierId(chemicalStock.getSupplierId());
            chemicalRelDelivery.setSupplier(chemicalStock.getSupplier());
            //保存耗材转化单位
            chemicalRelDelivery.setUnit(chemical.getUnit());
            chemicalRelDelivery.setState(DeliveryRelStateEnum.NORMAL.getValue());
            //批次号
            chemicalRelDelivery.setBatchNum(chemicalStock.getBatchNum());
            chemicalRelDelivery.setValidDate(chemicalStock.getValidDate());
            // 待出库
            chemicalRelDelivery.setStatus(0);
            //供應商
            chemicalRelDelivery.setSupplier(chemicalStock.getSupplier());
            chemicalRelDelivery.setProductCode(chemicalStock.getProductCode());
            super.save(chemicalRelDelivery);
        } else {
            lcrd.setQuantity(chemicalRelDelivery.getQuantity() == null ? BigDecimalUtils.add(chemicalRelDelivery.getQuantity(), BigDecimal.ONE) : chemicalRelDelivery.getQuantity());
            super.updateById(lcrd);
        }
        return true;
    }


    @Override
    public Page<LmsChemicalRelDeliveryVO> pageTempBySql(Page<LmsChemicalRelDeliveryVO> page, LmsChemicalRelDeliveryVO lmsChemicalRelDelivery) {
        return page.setRecords(baseMapper.selectTempPage(page, lmsChemicalRelDelivery));
    }


    @Override
    public int updateOrderStatus(Long orderId, Long uid) {
        LmsChemicalRelDelivery lcrd = new LmsChemicalRelDelivery();
        lcrd.setOrderId(orderId);
        // 改为采购状态
        lcrd.setStatus(1);
        return baseMapper.update(lcrd, Wrappers.<LmsChemicalRelDelivery>query().eq("uid", uid).eq("status", 0));
    }



    @Override
    public boolean updateWaitApprovalId(Long id, BigDecimal quantity) {
        if (BigDecimalUtils.lessThan(quantity, BigDecimal.ONE)) {
            RestAssert.fail("出库数量不能小于 1 请重新输入。");
        }
        LmsChemicalRelDelivery tempRel = new LmsChemicalRelDelivery();
        tempRel.setId(id);
        tempRel.setQuantity(quantity);
        return super.updateById(tempRel);
    }


    @Override
    public Page<LmsChemicalRelDeliveryVO> getPageByOrderId(Page<LmsChemicalRelDeliveryVO> page, LmsChemicalRelDelivery lmsChemicalRelDelivery) {
        QueryWrapper<LmsChemicalRelDelivery> wrapper = Wrappers.<LmsChemicalRelDelivery>query();

        // 指定出库单 ID , 用户 ID 不作为查询条件
        if (null != lmsChemicalRelDelivery.getOrderId()) {
            lmsChemicalRelDelivery.setUid(null);
        }
        wrapper.setEntity(lmsChemicalRelDelivery);
        lmsChemicalRelDelivery.setState(0);
        //判斷是否有為空
        if (this.count(wrapper) == 0) {
            return page;
        }
        lmsChemicalRelDelivery.setState(null);
        return page.setRecords(baseMapper.getRelDelivery(lmsChemicalRelDelivery));
    }


    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean removeAllStock(Account account, Long orderId, LmsChemicalUserecord userecord) {
        RestAssert.fail(null == userecord || null == userecord.getRegdate(), "出库时间不能为空，请确认！");
        List<LmsChemicalRelDelivery> relList = super.list(Wrappers.<LmsChemicalRelDelivery>query().eq("order_id", orderId));
        if (CollectionUtils.isEmpty(relList)) {
            return false;
        }
        relList.forEach(r -> {
            if (1 != r.getState()) {
                removeStock(account, r, new LmsChemicalStock().setStock(BigDecimalUtils.sub(r.getQuantity(), r.getAlreadyQuantity())).setCtime(userecord.getRegdate()));
            }
        });
        return lmsChemicalDeliveryOrderService.finishById(account, orderId, "快速出库");
    }

    @Override
    public boolean finishByOrderId(Long orderId) {
        LmsChemicalRelDelivery lcrd = new LmsChemicalRelDelivery();
        lcrd.setState(PurchaseRelStateEnum.FINISH.getValue());
        return super.update(lcrd, Wrappers.<LmsChemicalRelDelivery>query().eq("order_id", orderId));
    }

    private boolean removeStock(Account account, LmsChemicalRelDelivery lcrd, LmsChemicalStock chemicalStock) {
        // 正常、调整 允许出库
        BigDecimal stock = chemicalStock.getStock();
        //如果出庫為零不操作
        if (BigDecimalUtils.equalThan(stock, BigDecimal.ZERO)) {
            return true;
        }
        if (null == lcrd || BigDecimalUtils.greaterThan(stock, lcrd.getQuantity())
                || BigDecimalUtils.greaterThan(BigDecimalUtils.add(stock, lcrd.getAlreadyQuantity()), lcrd.getQuantity())) {
            RestAssert.fail("出库数量不能大于申请使用量，请重新输入。");
        }
        if (DeliveryRelStateEnum.NORMAL.getValue() == lcrd.getState()
                || DeliveryRelStateEnum.ADJUST.getValue() == lcrd.getState()) {
            // 设置出库信息
            LmsChemicalStockDTO dto = new LmsChemicalStockDTO();
            dto.setId(lcrd.getStockId());
            dto.setType(1);
            dto.setStock(stock);
            dto.setRegdate(chemicalStock.getCtime());
            dto.setOrderId(lcrd.getOrderId());
            StringBuilder remark = new StringBuilder();
            if (null != chemicalStock.getRemark()) {
                remark.append(chemicalStock.getRemark() + "-");
            }
            remark.append("已出库：" + stock + "【" + account.getUserName() + "】");
            // 修改订单行入库量
            LmsChemicalRelDelivery tempLcrd = new LmsChemicalRelDelivery();
            tempLcrd.setId(lcrd.getId());
            tempLcrd.setAlreadyQuantity(BigDecimalUtils.add(stock, lcrd.getAlreadyQuantity()));
            // 保存库存，修改订单行入库量
            if (BigDecimalUtils.equalThan(BigDecimalUtils.add(stock, lcrd.getAlreadyQuantity()), lcrd.getQuantity())) {
                finishById(account, lcrd.getId(), remark.toString());
            }
            return lmsChemicalStockService.updateDTOById(dto) && super.updateById(tempLcrd);
        }
        RestAssert.fail("该出单行，不允许入库操作。");
        return false;
    }

    @Override
    public boolean finishById(Account account, Long id, String remark) {
        LmsChemicalRelDelivery lcrd = getById(id);
        LmsChemicalRelDelivery rel = new LmsChemicalRelDelivery();
        rel.setId(lcrd.getId());
        rel.setState(DeliveryRelStateEnum.FINISH.getValue());
        // 结束订单行，叠加备注
        StringBuffer newRemark = new StringBuffer();
        if (null != lcrd.getRemark()) {
            newRemark.append(lcrd.getRemark()).append(" | ");
        }
        newRemark.append(remark).append("-结束【").append(account.getUserName()).append("】");
        rel.setRemark(newRemark.toString());
        boolean result = super.updateById(rel);
        //遍歷是否單據整個單據結束
        if (0 == unfinishByOrderId(lcrd.getOrderId())) {
            //修改狀態
            return lmsChemicalDeliveryOrderService.finishById(account, lcrd.getOrderId(), newRemark.toString());

        }
        return result;
    }

    private int unfinishByOrderId(Long orderId) {
        LmsChemicalRelDelivery lcrd = new LmsChemicalRelDelivery();
        lcrd.setState(PurchaseRelStateEnum.FINISH.getValue());
        return super.count(Wrappers.<LmsChemicalRelDelivery>query().eq("order_id", orderId)
                .in("state", new Integer[]{DeliveryRelStateEnum.NORMAL.getValue(), DeliveryRelStateEnum.ADJUST.getValue()}));
    }
}
