package com.fjhx.wms.service.stock.impl;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fjhx.item.service.product.ProductInfoService;
import com.fjhx.wms.entity.stock.dto.StockCheckDto;
import com.fjhx.wms.entity.stock.dto.StockCheckSelectDto;
import com.fjhx.wms.entity.stock.po.StockCheck;
import com.fjhx.wms.entity.stock.po.StockCheckDetails;
import com.fjhx.wms.entity.stock.vo.StockCheckDetailsVo;
import com.fjhx.wms.entity.stock.vo.StockCheckVo;
import com.fjhx.wms.mapper.stock.StockCheckMapper;
import com.fjhx.wms.service.stock.StockCheckDetailsService;
import com.fjhx.wms.service.stock.StockCheckService;
import com.fjhx.wms.service.warehouse.WarehouseService;
import com.fjhx.wms.utils.CodeEnum;
import com.ruoyi.common.constant.StatusConstant;
import com.ruoyi.common.utils.wrapper.IWrapper;
import com.ruoyi.system.utils.UserUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Objects;


/**
 * <p>
 * 库存盘点 服务实现类
 * </p>
 *
 * @author
 * @since 2023-03-22
 */
@Service
public class StockCheckServiceImpl extends ServiceImpl<StockCheckMapper, StockCheck> implements StockCheckService {

    @Autowired
    private StockCheckDetailsService stockCheckDetailsService;

    @Autowired
    private ProductInfoService productInfoService;

    @Autowired
    private WarehouseService warehouseService;

    @Override
    public Page<StockCheckVo> getPage(StockCheckSelectDto dto) {
        IWrapper<StockCheck> wrapper = getWrapper();
        wrapper.like("sc", StockCheckVo::getCreateTime, dto.getKeyword());
        wrapper.eq("sc", StockCheck::getResult, dto.getResult());
        wrapper.orderByDesc("sc", StockCheck::getId);
        Page<StockCheckVo> page = this.baseMapper.getPage(dto.getPage(), wrapper);
        List<StockCheckVo> records = page.getRecords();
        if (records.size() == 0) {
            return page;
        }

        // 根据id赋值操作人名称
        UserUtil.assignmentNickName(page.getRecords(), StockCheckVo::getCreateUser, StockCheckVo::setUserName);

        // 赋值仓库名称
        warehouseService.attributeAssign(records, StockCheck::getWarehouseId, (item, warehouse) -> {
            item.setWarehouseName(warehouse.getName());
        });

        return page;
    }

    @Override
    public StockCheckVo detail(Long id) {
        StockCheckVo stockCheckVo = baseMapper.detail(id);

        List<StockCheckDetailsVo> list = stockCheckVo.getList();
        if(ObjectUtil.isEmpty(list)){
            return stockCheckVo;
        }
        productInfoService.attributeAssign(list, StockCheckDetails::getProductId, (item, product) -> {
            item.setProductCode(product.getCode());
            item.setProductName(product.getName());
            item.setProductUnit(product.getUnit());
        });
        return stockCheckVo;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void add(StockCheckDto stockCheckDto) {

        long stockCheckId = IdWorker.getId();
        List<StockCheckDetails> list = stockCheckDto.getList();
        int totalNum = 0, normalNum = 0, anomalyNum = 0;

        for (StockCheckDetails stockCheckDetails : list) {

            totalNum++;

            if (Objects.equals(stockCheckDetails.getQuantity(), stockCheckDetails.getCheckQuantity())) {
                normalNum++;
            } else {
                anomalyNum++;
            }

            stockCheckDetails.setStockCheckId(stockCheckId);
        }

        stockCheckDto.setId(stockCheckId);
        stockCheckDto.setCode(CodeEnum.CHECK_CODE.getCode());
        stockCheckDto.setResult(anomalyNum > 0 ? StatusConstant.YES : StatusConstant.NO);
        stockCheckDto.setTotalNum(totalNum);
        stockCheckDto.setNormalNum(normalNum);
        stockCheckDto.setAnomalyNum(anomalyNum);

        // 保存盘点记录以及明细
        save(stockCheckDto);
        stockCheckDetailsService.saveBatch(list);
    }

}
