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

import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.Record;
import com.sifang.modules.site.siteInfo.service.SiteEmployeeService;
import com.sifang.modules.sunshine.SystemSetting.utils.StringUtil;
import com.sifang.modules.supply.order.entity.CrmSupplyMaterialApply;
import com.sifang.modules.supply.order.entity.CrmSupplyMaterialDeliverOrder;
import com.sifang.modules.sys.common.persistence.BaseDao;
import com.sifang.modules.sys.dao.UserDao;
import com.sifang.modules.sys.util.CrmUtils;
import com.sifang.modules.sys.util.LayuiPage;
import com.sifang.modules.sys.util.SqlBuilder;
import org.hibernate.Query;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

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

/**
 * @author hongzq
 */
@Repository
public class MaterialDeliverDao extends BaseDao<CrmSupplyMaterialDeliverOrder> {

    @Autowired
    UserDao userDao;

    @Autowired
    SiteEmployeeService siteEmployeeService;

    @Autowired
    SupplyOrderAuditDao supplyOrderAuditDao;

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

    public List<Record> allOrderList(LayuiPage<Record> page, Map<String, String> map) {
        SqlBuilder builder = new SqlBuilder();
        builder.line("select o.id as deliverOrderId, o.type, o.number as deliverOrderNumber, o.status as deliverOrderStatus, o.out_warehouse_id, w.name as outWarehouseName, o.deliver_method_name, o.place_name")
                .line(",a.in_warehouse_id ,w2.name as inWarehouseName, IFNULL(a.mobile,w2.mobile) as mobile,IFNULL(a.person_in_charge,w2.person_in_charge) as person_in_charge,concat(a.province,a.city,a.area,a.address) as address, concat(w2.province,w2.city,w2.area,w2.address) as w_address")
                .line(",o.relate_no, o.deliver_remark, o.remarks, o.create_time, o.deliver_time, o.warehouse_fail_reason, o.audit_time,a.audit_time as auditTime")
                .line(",o.express_no, o.deliver_invoice, o.deliver_method_id, o.deliver_driver, o.deliver_mobile, o.deliver_car_num")
                .line(",o.receive_time, o.deliver_id, o.deliver_name, o.audit_remark, o.receive_remark, o.receive_invoice, o.place_time")
                .line(",o.material_type_amount, o.total_apply_amount, o.total_deliver_amount")
                .line(", a.id as applyOrderId,a.remark as applyOrderRemarks, a.creator as applyOrderCreator, a.number as applyOrderNumber, a.create_time as applyOrderCreateTime")
                .line(",t.name as applyOrderTrader")
                .line(", if(o.id is null, concat('apply-', a.status), concat('deliver-', o.status)) as mergeStatus")
                .line(", if(o.id is null, a.material_type_amount, o.material_type_amount) as material_type_amount")
                .line(", if(o.id is null, a.total_apply_amount, o.total_apply_amount) as total_apply_amount")
                .line(", if(o.id is null, 0, o.total_deliver_amount) as total_deliver_amount")
                .line(",a.order_time, a.project_code")
                .line("from crm_supply_material_apply a")
                .line("left join crm_supply_material_deliver_order o on o.apply_order_id=a.id and o.status <> '0'")
                .line("left join crm_trader t on a.trader_id=t.id")
                .line("left join crm_supply_warehouse w on o.out_warehouse_id=w.id")
                .line("left join crm_supply_warehouse w2 on a.in_warehouse_id=w2.id")
                .line("where a.status in ('1', '2', '3', '4', '5', '9')");
        appendDeliverOrderCondition(builder, map);
        builder.line("order by a.create_time desc");
        if (page != null) {
            builder.limit(page.getPage(), page.getLimit());
        }
        return Db.find(builder.build(), builder.params());
    }

    public Long countAllOrderList(Map<String, String> map) {
        SqlBuilder builder = new SqlBuilder();
        builder.line("select count(1)")
                .line("from crm_supply_material_apply a")
                .line("left join crm_supply_material_deliver_order o on o.apply_order_id=a.id and o.status <> '0'")
                .line("left join crm_trader t on a.trader_id=t.id")
                .line("left join crm_supply_warehouse w on o.out_warehouse_id=w.id")
                .line("left join crm_supply_warehouse w2 on a.in_warehouse_id=w2.id")
                .line("where a.status in ('1', '2', '3', '4', '5', '9')");
        appendDeliverOrderCondition(builder, map);
        return Db.queryLong(builder.build(), builder.params());
    }


    public List<Record> deliverOrderList(LayuiPage<Record> page, Map<String, String> map) {
        SqlBuilder builder = new SqlBuilder();
        builder.line("select o.id, o.type, o.pattern, o.number, o.project_code,o.apply_order_id, o.status,o.send_status, o.out_warehouse_id, ")
                .line("w.name as outWarehouseName, o.deliver_method_name, o.place_name,w2.ascription_name,o.insurance_files,o.safety_files,")
                .line("w2.name as inWarehouseName, w2.mobile, w2.person_in_charge,w2.type as ascriptionType, ")
                .line("CONCAT_WS('',w2.province,w2.city,w2.area,w2.address) as w_address")
                .line(",CONCAT_WS('',o.province,o.city,o.area,o.address) as receive_address")
                .line(",o.relate_no, o.deliver_remark, o.remarks, o.create_time, o.deliver_time, o.warehouse_fail_reason, o.audit_time,")
                .line("o.allocation_time, o.allocation_remark,p.name  as qqProjectName,")
                .line("o.express_no, o.deliver_invoice, o.deliver_method_id, o.deliver_driver, o.deliver_mobile, o.deliver_car_num")
                .line(",o.receive_time, o.deliver_id, o.deliver_name, o.audit_remark, o.receive_remark, o.receive_invoice, DATE_FORMAT(o.place_time,'%Y-%m-%d') as place_time")
                .line(",o.material_type_amount, o.total_apply_amount, o.total_deliver_amount, o.creator,o.place_by,o.purchase_order_examine_status")
                .line(",o.apply_order_id as applyOrderId, o.project_code,o.total_deliver_amount,o.total_in_amount")
                .line(",t.name as applyOrderTrader,t.id as traderId, s.name as supply_name,o.delivery_voucher ,o.task_name ")
                .line(",(CASE ")
                .line(" WHEN o.audit_time < (NOW()-INTERVAL 120 HOUR) THEN 5 ")
                .line(" WHEN o.audit_time < (NOW()-INTERVAL 96 HOUR) THEN 4 ")
                .line(" WHEN o.audit_time < (NOW()-INTERVAL 72 HOUR) THEN 3 ")
                .line(" WHEN o.audit_time < (NOW()-INTERVAL 48 HOUR) THEN 2 ")
                .line("  WHEN o.audit_time < (NOW()-INTERVAL 24 HOUR) THEN 1 ")
                .line(" ELSE 0 END )AS dayCount  ")
                .line("from crm_supply_material_deliver_order o")
                .line("left join crm_trader t on o.trader_id=t.id")
                .line(" left join crm_supply_material_project p on p.code = o.qq_project_code ")
                .line("left join crm_supply_warehouse w on o.out_warehouse_id=w.id")
                .line("left join crm_supply_warehouse w2 on o.in_warehouse_id=w2.id")
                .line("left join crm_supply_supplier s on o.supply_id=s.id")
                .line("where o.status <> '0'");
        appendDeliverOrderCondition(builder, map);
        builder.line("order by o.place_time desc");
        if (page != null) {
            builder.limit(page.getPage(), page.getLimit());
        }
        return Db.find(builder.build(), builder.params());
    }

    public Long countDeliverOrderList(Map<String, String> map) {
        SqlBuilder builder = new SqlBuilder();
        builder.line("select count(1)")
                .line("from crm_supply_material_deliver_order o")
                .line("left join crm_supply_warehouse w2 on o.in_warehouse_id=w2.id")
                .line("left join crm_trader t on o.trader_id=t.id")
                .line("where o.status <> '0'");
        appendDeliverOrderCondition(builder, map);
        return Db.queryLong(builder.build(), builder.params());
    }

    private void appendDeliverOrderCondition(SqlBuilder builder, Map<String, String> map) {
        if ("1".equals(map.get("supplyOrder"))) {
            builder.line("and o.deliver_id <> 'a'");
        }
        if ("1".equals(map.get("inStockOnly"))) {
            //收货单，只查询待入库的和审核未通过的
            builder.line("and o.status = '6'");
        }
        if ("1" .equals(map.get("waitDeliverQuery"))) {
            builder.line("and o.status in ('5', '9')");
        }
        // 此参数用于指定订单状态，如待发货订单列表，则传5
        if (StringUtil.checkParamsValid(map.get("fixedStatus"))) {
            String fixedStatus=map.get("fixedStatus");
            if(fixedStatus.indexOf("7") != -1){
                fixedStatus+=",11";
            }
            builder.inst(" and o.status in ", fixedStatus.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 ("1".equals(map.get("patternFlag"))){
            builder.line(" and o.pattern <> '1' ");
        }
        if (StringUtil.checkParamsValid(map.get("creator"))) {
            builder.like("and o.creator=? ", map.get("creator").trim());
        }
        if (StringUtil.checkParamsValid(map.get("excludeStatus"))) {
            builder.inst("and o.status not in ", map.get("excludeStatus").split(","));
        }
        if (StringUtil.checkParamsValid(map.get("number"))) {
            builder.like("and o.number like ?", map.get("number").trim());
        }


        if (StringUtil.checkParamsValid(map.get("mergeStatus"))) {
            String status = map.get("mergeStatus").split("-")[1];
            if (map.get("mergeStatus").startsWith("apply")) {
                builder.line("and a.status = ?", status);
            } else if (map.get("mergeStatus").startsWith("deliver")) {
                builder.line("and o.status = ?", status);
            }
        }

        if (StringUtil.checkParamsValid(map.get("personInCharge"))) {
            builder.like("and w2.person_in_charge like ?", map.get("personInCharge").trim());
        }
        if (StringUtil.checkParamsValid(map.get("relateNo"))) {
            builder.like("and o.relate_no like ?", map.get("relateNo").trim());
        }
        if (StringUtil.checkParamsValid(map.get("status"))) {
            builder.inst("and o.status in", map.get("status").split(","));
        }
        if (StringUtil.checkParamsValid(map.get("statusList"))) {
            builder.inst("and o.status in", map.get("statusList").split(","));
        }
        if (StringUtil.checkParamsValid(map.get("deliverId"))) {
            builder.line("and o.deliver_id = ?", map.get("deliverId"));
        }
        if (StringUtil.checkParamsValid(map.get("deliverName"))) {
            builder.like("and o.deliver_name like ?", map.get("deliverName").trim());
        }
        if (StringUtil.checkParamsValid(map.get("inAscriptionId"))) {
            builder.line("and w2.ascription_id = ?", map.get("inAscriptionId"));
        }
        if (StringUtil.checkParamsValid(map.get("inWarehouseId"))) {
            builder.inst("and o.in_warehouse_id in ", map.get("inWarehouseId").split(","));
        }
        if (StringUtil.checkParamsValid(map.get("outWarehouseId"))) {
            builder.inst("and o.out_warehouse_id in ", map.get("outWarehouseId").split(","));
        }
        if (StringUtil.checkParamsValid(map.get("id"))) {
            builder.line("and o.id = ?", map.get("id"));
        }
        if (StringUtil.checkParamsValid(map.get("deliverMethodId"))) {
            builder.line("and o.deliver_method_id = ?", map.get("deliverMethodId"));
        }
        if (StringUtil.checkParamsValid(map.get("expressNo"))) {
            builder.like("and o.express_no like ?", map.get("expressNo").trim());
        }
        if (StringUtil.checkParamsValid(map.get("placeName"))) {
            builder.like("and o.place_name like ?", map.get("placeName").trim());
        }

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

        if (StringUtil.checkParamsValid(map.get("deliverRemark"))) {
            builder.like("and o.deliver_remark like ?", map.get("deliverRemark").trim());
        }
        if (StringUtil.checkParamsValid(map.get("allocationRemark"))) {
            builder.like("and o.allocation_remark like ?", map.get("allocationRemark").trim());
        }
        if (StringUtil.checkParamsValid(map.get("mobile"))) {
            builder.like("and w2.mobile like ?", map.get("mobile").trim());
        }
        if (StringUtil.checkParamsValid(map.get("address"))) {
            builder.like("and concat(w2.province, w2.city, w2.area, w2.address) like ?", map.get("address").trim());
        }
        if (StringUtil.checkParamsValid(map.get("createTimeMin"))) {
            builder.line("and o.create_time >= ?", map.get("createTimeMin"));
        }
        if (StringUtil.checkParamsValid(map.get("createTimeMax"))) {
            builder.line("and o.create_time <= ?", map.get("createTimeMax"));
        }

        if (StringUtil.checkParamsValid(map.get("deliverTimeMin"))) {
            builder.line("and o.deliver_time >= ?", map.get("deliverTimeMin"));
        }
        if (StringUtil.checkParamsValid(map.get("deliverTimeMax"))) {
            builder.line("and o.deliver_time <= ?", map.get("deliverTimeMax"));
        }
        if (StringUtil.checkParamsValid(map.get("receiveTimeMin"))) {
            builder.line("and o.receive_time >= ?", map.get("receiveTimeMin"));
        }
        if (StringUtil.checkParamsValid(map.get("receiveTimeMax"))) {
            builder.line("and o.receive_time <= ?", map.get("receiveTimeMax"));
        }
        if (StringUtil.checkParamsValid(map.get("auditTimeMin"))) {
            builder.line("and o.audit_time >= ?", map.get("auditTimeMin"));
        }
        if (StringUtil.checkParamsValid(map.get("auditTimeMax"))) {
            builder.line("and o.audit_time <= ?", map.get("auditTimeMax"));
        }

        if (StringUtil.checkParamsValid(map.get("supplierId"))) {
            builder.inst("and o.supply_id in", map.get("supplierId").split(","));
        }
        if (StringUtil.checkParamsValid(map.get("traderId"))) {
            builder.inst("and o.trader_id in", map.get("traderId").split(","));
        }
        if (StringUtil.checkParamsValid(map.get("placeTimeMin"))) {
            builder.line("and o.place_time >= ?", map.get("placeTimeMin"));
        }
        if (StringUtil.checkParamsValid(map.get("placeTimeMax"))) {
            builder.line("and o.place_time <= ?", map.get("placeTimeMax"));
        }


        if(StringUtil.isNotBlank(map.get("userId"))){
            long  checkRo= userDao.isDefaultPlatRole(map.get("userId"));
            if (checkRo>0) {
                List<Record> employeeRole = siteEmployeeService.findEmployeeByUserId(map.get("userId"));
                List<String> provinceList = supplyOrderAuditDao.appendColumns(employeeRole, "provices");
                List<String> cityList = supplyOrderAuditDao.appendColumns(employeeRole, "city");
                List<String> numberList = supplyOrderAuditDao.appendColumns(employeeRole, "project_number");
                List<String> traderList = supplyOrderAuditDao.appendColumns(employeeRole, "trader_id");
                logger.info("MaterialDeliverDao,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 statisticOrder(List<String> ascriptionId) {
        SqlBuilder sql = new SqlBuilder();
        sql.line("SELECT COUNT(CASE WHEN o.`status` = '1' THEN 0 END) AS dfh,");
        sql.line("COUNT(CASE WHEN o.`status` = '2' THEN 0 END) AS drk");
        sql.line("FROM crm_supply_material_deliver_order o  WHERE 1=1");
        sql.inst("and o.`deliver_id` in ",ascriptionId);
        return Db.findFirst(sql.build(),sql.params());
    }

    // 供应链端 统计 待供应链发货
    public Record statisticOrderForSupplyChainDgylfh() {
        return Db.findFirst("SELECT COUNT(*) AS dgylfh FROM crm_supply_material_deliver_order o WHERE o.status = '1' AND o.deliver_id = 'a'");
    }
    // 供应链端 统计 待供应商发货
    public Record statisticOrderForSupplyChainDgysfh() {
        return Db.findFirst("SELECT COUNT(*) AS dgysfh FROM crm_supply_material_deliver_order o WHERE o.status = '1' and o.deliver_id <> 'a'");
    }
    // 供应链端 统计 待代理商入库
    public Record statisticOrderForSupplyChainDjxsrk() {
        long a = Db.queryLong("select count(*) from crm_supply_material_deliver_order o WHERE o.status = '2' AND o.deliver_id = 'a'");
        long b = Db.queryLong("SELECT COUNT(*) FROM crm_supply_material_deliver_order o WHERE o.status = '2' and o.deliver_id <> 'a'");
        return new Record().set("djxsrk", a+b);
    }
    // 供应链端 统计 待供应链入库
    public Record statisticOrderForSupplyChainDgylrk() {
        return Db.findFirst("SELECT COUNT(*) AS dgylrk FROM crm_supply_material_deliver_order o " +
                "left join crm_supply_warehouse w ON o.in_warehouse_id = w.id" +
                " WHERE o.status = '2' and w.ascription_id = 'a'");
    }

    // 代理商端 统计 待入库
    public Record statisticOrderForTraderDrk() {
        return Db.findFirst("SELECT COUNT(*) AS drk FROM crm_supply_material_deliver_order o " +
                "left join crm_supply_warehouse w ON o.in_warehouse_id = w.id" +
                " WHERE o.status = '2' and w.ascription_id = ?", CrmUtils.getAscription().getAscriptionId());
    }

    // 代理商端 统计 待审核
    public Record statisticOrderForTraderDsh() {
        return Db.findFirst("SELECT COUNT(*) AS dsh FROM crm_supply_material_deliver_order o " +
                "left join crm_supply_warehouse w ON o.in_warehouse_id = w.id" +
                " WHERE o.status = '5' and w.ascription_id = ?", CrmUtils.getAscription().getAscriptionId());
    }

    @SuppressWarnings("unchecked")
    public List<CrmSupplyMaterialDeliverOrder> findByIds(List<String> ids) {
        Query query = getSession().createQuery("from CrmSupplyMaterialDeliverOrder where id in (:ids)");
        query.setParameterList("ids", ids);
        return (List<CrmSupplyMaterialDeliverOrder>) query.list();
    }

    public Record findOrderCount(String traderId){
        SqlBuilder sql = new SqlBuilder();
        sql.line("select");
        sql.line("count(CASE WHEN a.status ='5' THEN 0 END) as dfhdd,");
        sql.line("count(CASE WHEN a.status ='6' THEN 0 END) as dqsdd");
        sql.line("FROM `crm_supply_material_deliver_order`a WHERE a.`trader_id` = ?",traderId);
        return Db.findFirst(sql.build(),sql.params());
    }

    public Record findOrderRunturn(String traderId){
        SqlBuilder sql = new SqlBuilder();
        sql.line("select count(*) as thdd from `crm_supply_material_return_order` WHERE `trader_id` = ? and `status` in('1','2','3')",traderId);
        return Db.findFirst(sql.build(),sql.params());
    }


    public BigDecimal findMaxPurchasePrice(String materialType,String materialSpec){
        SqlBuilder sql = new SqlBuilder();
        sql.line(" SELECT IFNULL(MAX(b.purchase_price),0) AS purchasePrice   from crm_supply_material_deliver_order  a")
                .line("  left JOIN crm_supply_material_deliver_order_detail b ON b.main_id = a.id  ")
                .line("  where a.type = '6'   and b.material_type = ? and b.material_spec = ? ",materialType,materialSpec);
        return Db.queryBigDecimal(sql.build(),sql.params());
    }

    /**
     * 查找成本价 取最近一次企企同步的下单成本价
     */
    public Record findPurchasePrice(String materialId){
        SqlBuilder sql = new SqlBuilder();
        sql.line(" SELECT IFNULL(b.purchase_price,0) AS purchasePrice   from crm_supply_material_deliver_order  a")
                .line("  left JOIN crm_supply_material_deliver_order_detail b ON b.main_id = a.id  ")
                .line("  where a.type = '6'  and b.material_id = ? ",materialId)
                .line(" ORDER BY a.create_time desc ");
        System.out.println(sql.build()+"materialId-->"+materialId);
        return Db.findFirst(sql.build(),sql.params());
    }

    public BigDecimal findMaterialCount(String warehouseId,String materialId,String status){
        SqlBuilder sql = new SqlBuilder();
        sql.line(" select IFNULL(sum(apply_amount),0) as  totalApplyAmount from  crm_supply_material_deliver_order_detail d   ")
                .line(" left join  crm_supply_material_deliver_order o on o.id = d.main_id ")
                .inst(" and o.`status` in  ",status.split(","))
                .line(" where o.in_warehouse_id= ? and d.material_id = ? ",warehouseId,materialId);
        return Db.queryBigDecimal(sql.build(),sql.params());
    }


    /**
     * 查找最新版本号
     */
    public Integer findMaxVersion(String number){
        SqlBuilder builder = new SqlBuilder();
        builder.line(" select max(version) as version from crm_supply_material_deliver_order o ")
                .line(" where o.status <> '0' ")
                .line(" and o.number like ?","%"+number+"%");
        return Db.queryInt(builder.build(),builder.params());
    }

}
