package com.sifang.modules.supply.order.dao;


import com.jfinal.kit.StrKit;
import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.Record;
import com.sifang.modules.flowable.utils.FormUtils;
import com.sifang.modules.flowpath.dao.BondApplyDao;
import com.sifang.modules.site.siteInfo.service.SiteEmployeeService;
import com.sifang.modules.sunshine.SystemSetting.utils.StringUtil;
import com.sifang.modules.supply.order.entity.CrmSupplyMaterialDeliverOrder;
import com.sifang.modules.sys.common.entity.User;
import com.sifang.modules.sys.common.persistence.BaseDao;
import com.sifang.modules.sys.common.persistence.Parameter;
import com.sifang.modules.sys.dao.UserDao;
import com.sifang.modules.sys.util.LayuiPage;
import com.sifang.modules.sys.util.SqlBuilder;
import org.hibernate.SQLQuery;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

@Repository
public class SupplyOrderAuditDao extends BaseDao<CrmSupplyMaterialDeliverOrder> {

    @Autowired
    UserDao userDao;

    @Autowired
    SiteEmployeeService siteEmployeeService;

    Logger logger = LoggerFactory.getLogger(getClass());

    //待审批订单
    public List<Record> listData(LayuiPage<Record> page, Map<String, String> map, User user,String formKey){
        SqlBuilder builder = new SqlBuilder();
        builder.line(" SELECT o.id,o.number,o.type,o.trader_id,t.name AS traderName,o.in_warehouse_id,DATE_FORMAT(o.create_time,'%Y-%m-%d %H:%i:%s') AS createTime,o.remarks,o.audit_remark, ")
                .line(" o.status as orderStatus,o.task_id, w.name AS inWarehouseName,w.person_in_charge,w.mobile AS deliverMobile,CONCAT(w.`province`,w.`city`,w.`area`,w.`address`) AS warehouseAddress ")
                .line(" ,ifnull(o.order_examine_status,0) as  order_examine_status,o.process_def_id,pattern,deliver_name,o.task_name,o.send_status ")
                .line(" ,DATE_FORMAT(o.receive_time,'%Y-%m-%d %H:%i:%s') as receiveTime ,allocation_remark,s.name as supplyName ,o.create_by ,ifnull(o.purchase_order_examine_status,0) as purchase_order_examine_status ")
                .line(" ,(case when  k.`ASSIGNEE_`='"+user.getId()+"' then 1 else 0 end) as audit,p.name AS qqProjectName")
                .line(" ,(case when FIND_IN_SET(?,o.operate_user_ids) then 1 else 0 end ) as lookAuth ",user.getId())
                .line(" FROM `crm_supply_material_deliver_order` o ")
                .line(" LEFT JOIN crm_trader t ON t.id=o.`trader_id` ")
                .line(" LEFT JOIN crm_supply_material_project p ON p.code=o.qq_project_code ")
                .line(" LEFT JOIN crm_supply_supplier s ON s.id=o.`supply_id` ")
                .line(" LEFT JOIN `crm_supply_warehouse` w ON w.id=o.`in_warehouse_id` ");
        builder.line(" LEFT JOIN `act_ru_task` k ON o.`process_instance_id`=k.PROC_INST_ID_ AND k.FORM_KEY_=? and k.ASSIGNEE_ =? ",formKey,user.getId());
        builder .line(" WHERE o.`status` not in('0','8','c')  ");
      /*  builder.inst(" AND (o.order_examine_status='3' OR k.OWNER_ in ",user.getRoleIds().split(","));
        builder.line(" OR k.`ASSIGNEE_`= ?  ",user.getId());
        builder.line("  OR o.`create_by`= ?  ",user.getId());
        builder.line("  OR FIND_IN_SET(?,o.operate_user_ids) ) ",user.getId());*/
        appendDeliverOrderCondition(builder, map,user);
        builder.line("order by o.create_time desc");
        if (page != null) {
            builder.limit(page.getPage(), page.getLimit());
        }
        List<Record> list= Db.find(builder.build(), builder.params());
        return list;
    }


    //订单数量
    public long listCount(Map<String, String> map,User user,String formKey){
        SqlBuilder builder = new SqlBuilder();
        builder.line("  SELECT COUNT(o.id) ")
                .line(" FROM `crm_supply_material_deliver_order` o ")
                .line(" LEFT JOIN crm_trader t ON t.id=o.`trader_id` ")
                .line(" LEFT JOIN crm_supply_supplier s ON s.id=o.`supply_id` ")
                .line(" LEFT JOIN `crm_supply_warehouse` w ON w.id=o.`in_warehouse_id` ")
                .line(" LEFT JOIN `act_ru_task` k ON o.`process_instance_id`=k.PROC_INST_ID_ AND k.FORM_KEY_=? and k.ASSIGNEE_ =? ",formKey,user.getId())
                .line(" WHERE o.`status` not in('0','8','c')   ");
      /*  builder.inst(" AND (o.order_examine_status='3' OR k.OWNER_ in ",user.getRoleIds().split(","));
        builder.line(" OR k.`ASSIGNEE_`= ?  ",user.getId());
        builder.line("  OR o.`create_by`= ?  ",user.getId());
        builder.line("  OR FIND_IN_SET(?,o.operate_user_ids) ) ",user.getId());*/
        appendDeliverOrderCondition(builder, map,user);
        return Db.queryLong(builder.build(), builder.params());
    }


    //待审批订单(采购订单)
    public List<Record> purchaseListData(LayuiPage<Record> page, Map<String, String> map, User user){
        SqlBuilder builder = new SqlBuilder();
        builder.line(" SELECT o.id,o.number,o.type,o.trader_id,t.name AS traderName,o.in_warehouse_id,DATE_FORMAT(o.create_time,'%Y-%m-%d %H:%i:%s') AS createTime,o.remarks,o.audit_remark, ")
                .line(" o.status as orderStatus,o.task_id, w.name AS inWarehouseName,w.person_in_charge,w.mobile AS deliverMobile,CONCAT(w.`province`,w.`city`,w.`area`,w.`address`) AS warehouseAddress ")
                .line(" ,ifnull(o.order_examine_status,0) as  order_examine_status,o.process_def_id,pattern,deliver_name,ou.name as outWarehouseName,o.task_name ")
                .line(" ,DATE_FORMAT(o.allocation_time,'%Y-%m-%d %H:%i:%s') as allocationTime ,allocation_remark,s.name as supplyName ,o.create_by ,ifnull(o.purchase_order_examine_status,0) as purchase_order_examine_status ")
                .line(",(case when  k.`ASSIGNEE_`='"+user.getId()+"' then 1 else 0 end) as audit ")
                .line(" ,(case when FIND_IN_SET(?,o.purchase_operate_user_ids) or FIND_IN_SET(?,o.operate_user_ids) then 1 else 0 end ) as lookAuth ",user.getId(),user.getId())
                .line(" FROM `crm_supply_material_deliver_order` o ")
                .line(" LEFT JOIN crm_trader t ON t.id=o.`trader_id` ")
                .line(" LEFT JOIN crm_supply_supplier s ON s.id=o.`supply_id` ")
                .line(" LEFT JOIN `crm_supply_warehouse` w ON w.id=o.`in_warehouse_id` ")
                .line(" LEFT JOIN `crm_supply_warehouse` ou ON ou.id=o.`out_warehouse_id` ");
        builder.line(" LEFT JOIN `act_ru_task` k ON o.`purchase_process_instance_id`=k.PROC_INST_ID_ AND k.FORM_KEY_='09'  and k.ASSIGNEE_ =? ",user.getId());
        builder.line(" WHERE o.`status`<>'0'  ");
        appendDeliverOrderCondition(builder, map,null);
        builder.line("order by o.create_time desc");
        if (page != null) {
            builder.limit(page.getPage(), page.getLimit());
        }
        List<Record> list= Db.find(builder.build(), builder.params());
        return list;
    }


    //订单数量(采购订单)
    public long purchaseListCount(Map<String, String> map,User user){
        SqlBuilder builder = new SqlBuilder();
        builder.line("  SELECT COUNT(o.id) ")
                .line(" FROM `crm_supply_material_deliver_order` o ")
                .line(" LEFT JOIN `act_ru_task` k ON o.`purchase_process_instance_id`=k.PROC_INST_ID_ AND k.FORM_KEY_='09' ")
                .line(" WHERE o.`status`<>'0' ");
        appendDeliverOrderCondition(builder, map,null);
        return Db.queryLong(builder.build(), builder.params());
    }

    private void appendDeliverOrderCondition(SqlBuilder builder, Map<String, String> map,User user) {

        if (StringUtil.checkParamsValid(map.get("number"))) {
            builder.like("and o.number like ?", map.get("number").trim());
        }
        if (StringUtil.checkParamsValid(map.get("status"))) {
            if("-1".equals(map.get("status"))){
                builder.line(" and o.status='1' and o.order_examine_status='0' ");
            }else if("1".equals(map.get("status"))){
                builder.line(" and o.status='1' and o.order_examine_status <> '0' ");
            }else {
                builder.inst("and o.status in ", map.get("status").split(","));
            }
        }
        if (StringUtil.checkParamsValid(map.get("types"))) {
            builder.inst("and o.type in ", map.get("types").split(","));
        }
        if (StringUtil.checkParamsValid(map.get("type"))) {
            builder.line("and o.type = ?", map.get("type"));
        }
        if (StringUtil.checkParamsValid(map.get("pattern"))) {
            builder.line("and o.pattern = ?", map.get("pattern"));
        }
        if (StringUtil.checkParamsValid(map.get("qqProjectCode"))) {
            builder.line("and o.qq_project_code = ?", map.get("qqProjectCode"));
        }
        if (StringUtil.checkParamsValid(map.get("traderId"))) {
            builder.inst("and o.trader_id in ", map.get("traderId").split(","));
        }

        if (StringUtil.checkParamsValid(map.get("supplyId"))) {
            builder.line("and o.supply_id = ?", map.get("supplyId"));
        }
        if (StringUtil.checkParamsValid(map.get("remarks"))) {
            builder.like("and o.remarks like ?", map.get("remarks").trim());
        }

        if (StringUtil.checkParamsValid(map.get("createTimeMin"))) {
            builder.line("and o.create_time >= concat(?, ' 00：00：00')", map.get("createTimeMin").trim());
        }
        if (StringUtil.checkParamsValid(map.get("createTimeMax"))) {
            builder.line("and o.create_time <= concat(?, ' 23：59：59')", map.get("createTimeMax").trim());
        }

        if (StringUtil.checkParamsValid(map.get("receiveTimeMin"))) {
            builder.line("and o.receive_time >= concat(?, ' 00：00：00')", map.get("receiveTimeMin").trim());
        }
        if (StringUtil.checkParamsValid(map.get("receiveTimeMax"))) {
            builder.line("and o.receive_time <= concat(?, ' 23：59：59')", map.get("receiveTimeMax").trim());
        }
        if (StringUtil.checkParamsValid(map.get("confirmTimeSta"))) {
            builder.line("and o.allocation_time >= concat(?, ' 00：00：00')", map.get("confirmTimeSta").trim());
        }
        if (StringUtil.checkParamsValid(map.get("confirmTimeEnd"))) {
            builder.line("and o.allocation_time <= concat(?, ' 23：59：59')", map.get("confirmTimeEnd").trim());
        }

        if(user!=null){
            long  checkRo= userDao.isDefaultPlatRole(user.getId());
            if (checkRo>0) {
                List<Record> employeeRole = siteEmployeeService.findEmployeeByUserId(user.getId());
                List<String> provinceList = appendColumns(employeeRole, "provices");
                List<String> cityList = appendColumns(employeeRole, "city");
                List<String> numberList = appendColumns(employeeRole, "project_number");
                List<String> traderList = appendColumns(employeeRole, "trader_id");
                logger.info("appendConditions :  count :{}  ,  employeeRole :{}  ，provinceList:{},cityList:{},numberList:{}",checkRo,employeeRole,provinceList,cityList,numberList);
                if (!provinceList.isEmpty()) {
                    builder.inst("and t.province in ", provinceList);
                }
                if (!cityList.isEmpty()) {
                    builder.inst("and t.city in ", cityList);
                }

                if (!traderList.isEmpty()) {
                    builder.inst("and o.trader_id in ", traderList);
                }
            }
        }

    }

    public Record orderDetail(String id){
        StringBuffer sb=new StringBuffer();
        sb.append("  SELECT o.id,o.number,o.type,o.trader_id,t.name AS traderName,o.apply_order_id,o.in_warehouse_id,DATE_FORMAT(o.create_time,'%Y-%m-%d %H:%i:%s') AS createTime,o.remarks,o.audit_remark,");
        sb.append(" o.status,o.task_id,o.predict_amount, w.name AS inWarehouseName,w.person_in_charge,w.mobile AS deliverMobile,CONCAT(w.`province`,w.`city`,w.`area`,w.`address`) AS warehouseAddress ");
        sb.append(" ,o.process_instance_id,o.audit_remark,o.order_examine_status,s.name as supplyName,o.supply_id,o.purchase_order_examine_status,o.purchase_process_instance_id,o.pattern,w.imgs as warehouseImg ");
        sb.append(" ,o.process_def_id,o.task_name,o.insurance_files,o.safety_files, w.`province`,w.`city`,w.`area`,w.`address`,o.qq_project_code,o.file_url,p.name AS qqProjectName  FROM `crm_supply_material_deliver_order` o  ");
        sb.append(" LEFT JOIN crm_trader t ON t.id=o.`trader_id` ");
        sb.append(" LEFT JOIN crm_supply_supplier s ON s.id=o.`supply_id` ");//
        sb.append(" LEFT JOIN crm_supply_material_project p ON p.code=o.qq_project_code ");
        sb.append("  LEFT JOIN `crm_supply_warehouse` w ON w.id=o.`in_warehouse_id` ");
        sb.append(" where o.id=? ");
        return Db.findFirst(sb.toString(),id);
    }

    public List<Record> getOrderDetail(String id,String type){
        StringBuffer sb=new StringBuffer();
        sb.append(" SELECT d.id,d.material_id,d.material_type,d.material_spec,d.apply_amount,d.sales_price,d.purchase_price,d.out_amount,m.code,m.material_name,m.material_brand, m.unit_name,m.material_type_id,m.unit,m.remarks ");
        sb.append(" FROM `crm_supply_material_deliver_order_detail` d");
        sb.append(" LEFT JOIN `crm_supply_material` m ON d.material_id=m.id");
        sb.append(" WHERE d.main_id=? and d.status='0'  ");
        if("0".equals(type)){
            sb.append(" AND (m.material_attribute IS NULL OR m.`material_attribute`='0') ");
        }else {
            sb.append(" and m.material_attribute='1' ");
        }
        return Db.find(sb.toString(),id);
    }
    public List<Record> getOrderMaterials(String id){
        StringBuffer sb=new StringBuffer();
        sb.append(" SELECT d.id,d.material_id,d.material_type,d.material_spec,m.min_apply_amount,d.apply_amount,d.purchase_price,d.out_amount,m.code,m.material_name,m.material_brand,a.coefficient ");
        sb.append(" ,ifnull(d.sales_price,0) as sales_price,m.unit_name as material_unit ");
        sb.append(" FROM `crm_supply_material_deliver_order_detail` d");
        sb.append(" LEFT JOIN `crm_supply_material` m ON d.material_id=m.id");
        sb.append(" left join crm_price_coefficient_apply a on a.material_type_id=m.material_type_id  AND a.status='3' ");
        sb.append(" WHERE d.main_id=? and d.status='0'");
        return Db.find(sb.toString(),id);
    }

    //平台/代理商 根据物料类型 规格 获取库存信息
    //type 物料类型的名称  spec 规格  from 1 平台库存信息  3 代理商库存信息
    public List<Record> getPlateMaterialsStock(String type ,String spec,String from,String traderId,String qqProjectCode){
        StringBuffer sb=new StringBuffer();
        sb.append(" SELECT  any_value(m.id) as id,any_value(m.code) as code,any_value(m.material_name) as material_name ");
        sb.append(" ,any_value(m.material_type_id) as material_type_id,any_value(t.name) AS typeName,any_value(m.material_brand) as material_brand,any_value(m.material_specs) as material_specs ");
        sb.append("   ,IFNULL(SUM(s.warning) ,0)AS warning,any_value(s.cost_price) AS cost_price  ");
        sb.append(" ,any_value(ifnull(s.bd_sale_price,m.customer_price)) AS bd_sale_price ,any_value(ifnull(p.price,0)) AS qq_price ");
        sb.append(" FROM `crm_supply_material` m ");
        sb.append(" LEFT JOIN `crm_supply_material_type` t ON t.id=m.material_type_id ");
        sb.append(" LEFT JOIN crm_supply_material_project_price p on p.qq_material_code = m.qq_code");
        sb.append(" LEFT JOIN `crm_supply_material_warehouse_stocks` s ON s.material_id=m.id AND s.type=? ");
        sb.append(" WHERE t.name=? AND t.status='1' AND m.material_specs=? and p.`status`='0'   and p.qq_project_code= ? ");
        if(StringUtil.isNotBlank(traderId)){
            sb.append("  AND s.`ascription_id`='"+traderId+"' ");
        }
        sb.append(" GROUP BY m.id  ORDER BY m.id ");
        return Db.find(sb.toString(),from,type,spec,qqProjectCode);
    }

    public List<Record> getPlateMaterialsStock2(String type ,String spec,String province, String city,String qqProjectCode){
        StringBuffer sb=new StringBuffer();
        sb.append(" SELECT a.*,IFNULL(s.warning ,0)AS warning,s.cost_price,IFNULL(s.bd_sale_price,a.customer_price) AS bd_sale_price  FROM (");
        sb.append(" SELECT  any_value(m.id) as id,any_value(m.code) as code,any_value(m.material_name) as material_name,any_value(m.customer_price) customer_price,any_value(m.unit_name) unit_name ");
        sb.append(" ,any_value(m.material_type_id) as material_type_id,any_value(t.name) AS typeName,any_value(m.material_brand) as material_brand,any_value(m.material_specs) as material_specs ");
        sb.append(" ,any_value(p.price) as qq_price ,any_value(m.min_apply_amount) as min_apply_amount ");
        sb.append(" FROM `crm_supply_material` m ");
        sb.append(" LEFT JOIN `crm_supply_material_type` t ON t.id=m.material_type_id ");
        sb.append(" LEFT JOIN crm_supply_material_project_price p on p.qq_material_code = m.qq_code");
        sb.append(" WHERE t.name=? AND t.status='1' AND m.material_specs= ? and m.status='1' and p.`status`='0'   and p.qq_project_code= ? ");
        sb.append(" GROUP BY m.id  ORDER BY m.id ");
        sb.append("  ) a ");
        sb.append(" LEFT JOIN( ");
        sb.append(" SELECT ws.* FROM crm_supply_material_warehouse_stocks ws ");
        sb.append(" LEFT JOIN `crm_supply_warehouse` w ON ws.warehouse_id=w.id AND w.type='1' ");
        sb.append(" WHERE w.status='0' ");
        if (StringUtil.isNotBlank(province)) {
            sb.append(" and (w.province in (" + StringUtil.joinInSql(province.split(",")) + ")");
        }
        if (StringUtil.isNotBlank(city)) {
            sb.append(" or w.city in (" + StringUtil.joinInSql(city.split(",")) + ") )");
        }
        sb.append(" ) s ON  s.material_id=a.id AND s.type='1' ");


        return Db.find(sb.toString(),type,spec,qqProjectCode);
    }

    public void changeDetailStatus(String id){
        Db.update(" UPDATE `crm_supply_material_deliver_order_detail` d SET STATUS='0' WHERE main_id=? ADN (material_id IS NULL  OR material_id='') ",id);
    }

    public void deleteOrderDetail(String id){
        SQLQuery sqlQuery = getSession().createSQLQuery("UPDATE `crm_supply_material_deliver_order_detail` d SET STATUS='1' WHERE main_id=:applyId");
        sqlQuery.setParameter("applyId", id);
        sqlQuery.executeUpdate();
    }

    //删除明细
    public void deleteDetails(String id){
        SQLQuery sqlQuery = getSession().createSQLQuery("DELETE FROM `crm_supply_material_deliver_order_detail` WHERE main_id=:applyId");
        sqlQuery.setParameter("applyId", id);
        sqlQuery.executeUpdate();
    }

    public List<Record> getBySpecVsType(String type ,String spec){
        StringBuffer sb=new StringBuffer();
        sb.append(" SELECT a.*,IFNULL(s.warning ,0)AS warning,s.cost_price,IFNULL(s.bd_sale_price,a.customer_price) AS bd_sale_price  ");
        sb.append(" FROM ( SELECT  any_value(m.id) AS id,any_value(m.code) AS code,any_value(m.material_name) AS material_name,any_value(m.customer_price) customer_price,any_value(m.unit_name) unit_name, ");
        sb.append(" any_value(m.material_type_id) AS material_type_id,any_value(t.name) AS typeName,any_value(m.material_brand) AS material_brand,any_value(m.material_specs) AS material_specs  ");
        sb.append(" FROM `crm_supply_material` m  ");
        sb.append(" LEFT JOIN `crm_supply_material_type` t ON t.id=m.material_type_id  ");
        sb.append("  WHERE t.name=? AND t.status='1' AND m.material_specs=? AND m.status='1'  GROUP BY m.id  ORDER BY m.id   ) a ");
        sb.append("  LEFT JOIN(  SELECT any_value(ws.bd_sale_price)  AS bd_sale_price,any_value(ws.material_id)  AS material_id,any_value(ws.cost_price)  AS cost_price,SUM(IFNULL(ws.warning,0)) AS warning ");
        sb.append(" FROM crm_supply_material_warehouse_stocks ws   WHERE  ws.`type`='1' GROUP BY ws.`material_id`) s  ");
        sb.append("   ON  s.material_id=a.id  ");
        return Db.find(sb.toString(),type,spec);
    }

    public List<String> appendColumns(List<Record> records, String column) {
        List<String> ret = new ArrayList<>();
        for (Record record : records) {
            String value = record.getStr(column);
            if (StrKit.notBlank(value)) {
                ret.addAll(Arrays.asList(value.split(",")));
            }
        }
        return ret;
    }



}
