package com.junmp.jyzb.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.junmp.junmpProcess.dto.StartProcessInstanceDTO;
import com.junmp.junmpProcess.service.IFlowInstanceService;
import com.junmp.jyzb.api.bean.dto.StocktakeDto;
import com.junmp.jyzb.api.bean.query.StocktakeReq;
import com.junmp.jyzb.api.bean.req.UpdateStocktakeReq;
import com.junmp.jyzb.api.exception.enums.OrderExceptionEnum;
import com.junmp.jyzb.entity.OrderMain;
import com.junmp.jyzb.entity.OrderNum;
import com.junmp.jyzb.entity.Stocktake;
import com.junmp.jyzb.service.OrderNumService;
import com.junmp.jyzb.service.StocktakeService;
import com.junmp.jyzb.mapper.StocktakeMapper;
import com.junmp.jyzb.utils.DateTimeUtil;
import com.junmp.v2.common.exception.base.ServiceException;
import com.junmp.v2.common.util.BeanPlusUtil;
import com.junmp.v2.db.api.factory.PageFactory;
import com.junmp.v2.db.api.factory.PageResultFactory;
import com.junmp.v2.db.api.page.PageResult;
import com.junmp.v2.dict.entity.SysDict;
import com.junmp.v2.dict.entity.SysDictItem;
import com.junmp.v2.dict.service.SysDictItemService;
import com.junmp.v2.dict.service.SysDictService;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;

/**
* @author lxh专属坐骑
* @description 针对表【bussiness_stocktake】的数据库操作Service实现
* @createDate 2023-09-20 14:48:50
*/
@Service
public class StocktakeServiceImpl extends ServiceImpl<StocktakeMapper, Stocktake>
    implements StocktakeService{

    @Resource
    private SysDictItemService sysDictItemService;

    @Resource
    private OrderNumService orderNumService;

    @Resource
    private IFlowInstanceService FlowInstanceService;

    @Resource
    private SysDictService sysDictService;

    //盘库申请
    @Override
    @Transactional(rollbackFor = Exception.class)
    public String AddStocktakeOrder(UpdateStocktakeReq req) {
        Stocktake stocktake = new Stocktake();
        BeanPlusUtil.copyProperties(req,stocktake);
        //设置单号
        if (ObjectUtil.isNull(stocktake.getOrderCode())){
            OrderNum orderNum = setOrderCode(req.getBussinessType(),req.getOrgId());
            String codeValue=String.format("%04d",orderNum.getNum());
            stocktake.setOrderCode(orderNum.getBussinessType()+orderNum.getYear()+
                    String.format("%02d",LocalDateTime.now().getMonth().getValue())+
                    String.format("%02d",LocalDateTime.now().getDayOfMonth())+codeValue);
        }
        stocktake.setCreateTime(DateTimeUtil.getCurrentDateTime());
        stocktake.setApplyTime(DateTimeUtil.getCurrentDateTime());

        //执行工作流
        if (req.getExamineState().equals("working"))
        {
            StartProcessInstanceDTO startProcessInstanceDTO=new StartProcessInstanceDTO();
            startProcessInstanceDTO.setProcessDefinitionId(req.getProcessDefinitionId());
            startProcessInstanceDTO.setOrderId(stocktake.getId());
            startProcessInstanceDTO.setTypeOrder("stocktakeOrder");
            startProcessInstanceDTO.setUserId(req.getUserId());
            String ProcessInstanceId= FlowInstanceService.startProcessInstanceById(startProcessInstanceDTO);
            stocktake.setProcessId(ProcessInstanceId);

            String assigns= FlowInstanceService.GetNextAssign(ProcessInstanceId);//这里需要手动更新审核人信息
            stocktake.setCurrentAssign(assigns);
            updateById(stocktake);

        }
        this.save(stocktake);
        return stocktake.getId();
    }

    public String AddInvOrder(UpdateStocktakeReq req) {
        Stocktake stocktake = new Stocktake();
        BeanPlusUtil.copyProperties(req,stocktake);
        //设置单号
        if (ObjectUtil.isNull(stocktake.getOrderCode())){
            OrderNum orderNum = setOrderCode(req.getBussinessType(),req.getOrgId());
            String codeValue=String.format("%04d",orderNum.getNum());
            stocktake.setOrderCode(orderNum.getBussinessType()+orderNum.getYear()+
                    String.format("%02d",LocalDateTime.now().getMonth().getValue())+
                    String.format("%02d",LocalDateTime.now().getDayOfMonth())+codeValue);
        }
        stocktake.setCreateTime(DateTimeUtil.getCurrentDateTime());
        stocktake.setApplyTime(DateTimeUtil.getCurrentDateTime());

        //执行工作流
        if (req.getExamineState().equals("working"))
        {
            StartProcessInstanceDTO startProcessInstanceDTO=new StartProcessInstanceDTO();
            startProcessInstanceDTO.setProcessDefinitionId(req.getProcessDefinitionId());
            startProcessInstanceDTO.setOrderId(stocktake.getId());
            startProcessInstanceDTO.setTypeOrder("stocktakeOrder");
            startProcessInstanceDTO.setUserId(req.getUserId());
            String ProcessInstanceId= FlowInstanceService.startProcessInstanceById(startProcessInstanceDTO);
            stocktake.setProcessId(ProcessInstanceId);

            String assigns= FlowInstanceService.GetNextAssign(ProcessInstanceId);//这里需要手动更新审核人信息
            stocktake.setCurrentAssign(assigns);
            updateById(stocktake);

        }
        this.save(stocktake);
        return stocktake.getId();
    }

    //盘库单据查询
    @Override
    public PageResult<Stocktake> ShowStocktakeOrderPage(StocktakeReq req) {
        //(如果传其他不是数据库字段参数或者排序规则不是deac或者asc可能会出现错误)
        if (ObjectUtil.isNotNull(req.getColumn()) && !req.getColumn().trim().isEmpty() &&
                (req.getOrder().equalsIgnoreCase("desc") || req.getOrder().equalsIgnoreCase("asc"))
                && ObjectUtil.isNotNull(req.getOrder())&& !req.getOrder().trim().isEmpty()){
            req.setColumn(req.getColumn().replaceAll("[A-Z]","_$0").toLowerCase());
            req.setOrder(req.getOrder().toLowerCase());
        }
        LambdaQueryWrapper<Stocktake> eq = new LambdaQueryWrapper<Stocktake>()
                .eq(ObjectUtil.isNotNull(req.getOrderState()),Stocktake::getOrderState,req.getOrderState())
                .eq(ObjectUtil.isNotNull(req.getOrgId()),Stocktake::getOrgId,req.getOrgId())
                .eq(ObjectUtil.isNotNull(req.getLocationId()),Stocktake::getLocationId,req.getLocationId())
                .ge(ObjectUtil.isNotNull(req.getStartTime()),Stocktake::getCreateTime,req.getStartTime())
                .le(ObjectUtil.isNotNull(req.getEndTime()),Stocktake::getCreateTime,req.getEndTime())
                .last("order by "+req.getColumn()+" "+req.getOrder());
        Page<Stocktake> page = page(PageFactory.getDefaultPage(req.getPageNo(), req.getPageSize()), eq);
        return PageResultFactory.createPageResult(page);
    }


    //更新盘库单据（未进入工作流时才能进行修改）
    @Override
    public boolean UpdateStocktakeOrder(UpdateStocktakeReq req) {
        Stocktake stocktake = getById(req.getId());
        if (!stocktake.getExamineState().equals("none"))
        {
            throw new ServiceException(OrderExceptionEnum.ORDER_CAN_NOT_UPDATE);
        }
        BeanPlusUtil.copyProperties(req,stocktake);
        stocktake.setUpdateTime(DateTimeUtil.getCurrentDateTime());
        return updateById(stocktake);
    }


    /**
     * 设置单据单号
     * 通用方法，根据组织机构id以及业务单据类型来进行设置
     * @param
     */
    public OrderNum setOrderCode(String bussinessType,Long orgId){
        //设置采购单号，需要先判断该组织机构的采购单号是否存在，如果存在则将数量进行增加，如果不存在则新增一条对应的数据
        OrderNum orderNum = new OrderNum();
        orderNum.setYear(LocalDateTime.now().getYear());
        orderNum.setBussinessType(bussinessType);
        orderNum.setOrgId(orgId);
        //将业务类型转为中文简写
        Long sysDictId = sysDictService.getOne(new LambdaQueryWrapper<SysDict>()
                .eq(SysDict::getDictCode, "busstype_chinese")).getDictId();

        String itemValue = sysDictItemService.getOne(new LambdaQueryWrapper<SysDictItem>()
                .eq(SysDictItem::getItemText, bussinessType)
                .eq(SysDictItem::getDictId,sysDictId)).getItemValue();
        orderNum.setBussinessType(itemValue);
        OrderNum one = orderNumService.getOne(new LambdaQueryWrapper<OrderNum>()
                .eq(OrderNum::getOrgId, orderNum.getOrgId())
                .eq(OrderNum::getBussinessType, orderNum.getBussinessType())
                .eq(OrderNum::getYear, orderNum.getYear()));
        //设置num的数量
        if (ObjectUtil.isNull(one)){
            orderNum.setNum(1);
            orderNumService.save(orderNum);
            return orderNum;
        }else {
            one.setNum(one.getNum()+1);
            orderNumService.updateById(one);
            return one;
        }
    }
}




