<?php
/**
 * 客户类型调价单
 * Created by PhpStorm.
 * User: XiaoMing
 * Date: 2020/4/8
 * Time: 17:50
 */

namespace JinDouYun\Model\Price;

use JinDouYun\Cache\PageCache;
use JinDouYun\Cache\PriceCache;
use JinDouYun\Dao\Price\DCustomerPriceEffective;
use JinDouYun\Dao\Price\DCustomerTypePriceAdjustment;
use JinDouYun\Dao\Price\DCustomerTypePriceEffective;
use JinDouYun\Dao\System\DCustomerSource;
use JinDouYun\Model\GoodsManage\MSku;
use JinDouYun\Model\MBaseModel;
use Mall\Framework\Core\ErrorCode;
use Mall\Framework\Core\ResultWrapper;
use Mall\Framework\Core\StatusCode;

class MCustomerTypePriceAdjustment extends MBaseModel
{
    private $onlineUserId;

    private $onlineEnterpriseId;

    private $objDCustomerTypePriceAdjustment;

    private $objPriceCache;

    /**
     * MCustomerTypePriceAdjustment constructor.
     * @param $onlineUserId
     * @param $onlineEnterpriseId
     * @throws \Exception
     */
    public function __construct($onlineUserId, $onlineEnterpriseId)
    {
        $this->onlineUserId = $onlineUserId;
        $this->onlineEnterpriseId = $onlineEnterpriseId;
        parent::__construct($this->onlineEnterpriseId, $this->onlineUserId);
        $this->objPriceCache = new PriceCache($this->onlineEnterpriseId);
        $this->objDCustomerTypePriceAdjustment = new DCustomerTypePriceAdjustment();
        $this->objDCustomerTypePriceAdjustment->setTable($this->objDCustomerTypePriceAdjustment->get_Table() . '_' . $this->onlineEnterpriseId . '_' . date('Y') . '_' . ceil(date('m') / 3));
    }

    /**
     * c
     * @param $sheetData
     * @return ResultWrapper
     */
    public function add($sheetData)
    {
        // 保存调单价数据
        $no = createOrderSn(StatusCode::$source['manage'], StatusCode::$orderType['customerTypePriceAdjustment'], $this->onlineUserId);
        foreach ($sheetData as $key => $value) {
            unset($sheetData[$key]['effective']);
            $sheetData[$key]['no'] = $no;
        }

        $dbResult = $this->objDCustomerTypePriceAdjustment->insert($sheetData, true);
        if ($dbResult === false) {
            return ResultWrapper::fail($this->objDCustomerTypePriceAdjustment->error(), ErrorCode::$dberror);
        }

        if (is_array($dbResult)) {
            foreach ($dbResult as $key => $id) {
                if (isset($sheetData[$key])) {
                    $sheetData[$key]['id'] = $id;
                }
            }
        }
        return ResultWrapper::success($dbResult);
    }

    /**
     *
     * 获取所有调价单
     */
    public function getAll($params,$export = 0)
    {
        $pageData = pageToOffset($params['page'], $params['pageSize']);
        if($export){
            $pageData['limit'] = null;
            $pageData['offset'] = null;
        }
        $condition = null;

        if ($params['keyword']) {
            $condition = " (goodsName like '%" . $params['keyword'] . "%' or goodsCode like '%" . $params['keyword'] . "%' or no like '%" . $params['keyword'] . "%') ";
        }

        if ($params['startTime'] && $params['endTime']) {
            if ($condition !== null) {
                $condition .= ' and ';
            }
            $condition .= " createTime >= " . $params['startTime'] . " and createTime <=" . $params['endTime'];
        }

        if ($params['effectiveStatus']) {
            if ($condition !== null) {
                $condition .= ' and ';
            }
            $condition .= " effectiveStatus = " . $params['effectiveStatus'];
        }
        if (isset($params['goodsId']) && !empty($params['goodsId'])) {
            if ($condition !== null) {
                $condition .= ' and ';
            }
            $condition .= " goodsId = " . $params['goodsId'];
        }
        
        if (isset($params['shopId']) && !empty($params['shopId'])){
            if ($condition !== null) {
                $condition .= ' and ';
            }
            $condition .= " shopId = " . $params['shopId'];
        }

        $condition = parent::getShopIdQueryParams($condition);
        $total = $this->objDCustomerTypePriceAdjustment->count($condition);

        $dbResult = $this->objDCustomerTypePriceAdjustment->select($condition, '*', 'id desc', $pageData['limit'], $pageData['offset']);
        if ($dbResult === false) {
            return ResultWrapper::fail($this->objDCustomerTypePriceAdjustment->error(), ErrorCode::$dberror);
        }
        
        $return = [
            'data'  => self::format($dbResult),
            'total' => $total,
        ];
        //类型调价单导出
        if($export){
            self::exportPriceSheet($return['data']);
            exit;
        }
        
        return ResultWrapper::success($return);
    }

    /**
     * 格式化返回数据
     */
    public function format($data)
    {
        $skuIds = [];
        foreach ($data as $key => &$val) {
            if (!is_array($val['salePrice'])) {
                $val['salePrice'] = json_decode($val['salePrice'], true);
            }
            $val['salePrice'] = array_values($val['salePrice']);
            foreach ($val['salePrice'] as $row){
                $skuIds[] = $row['skuId'];
            }
        }

        $objMSku = new MSku($this->onlineUserId,$this->onlineEnterpriseId);
        $skuResult = $objMSku->getSpecNameBySkuId($skuIds);
        $allSkuData = [];
        if ($skuResult->isSuccess()){
            $allSkuData = $skuResult->getData();
        }

        foreach ($data as &$value){
            foreach ($value['salePrice'] as &$row){
                $row['unitName'] = isset($allSkuData[$row['skuId']]) ? $allSkuData[$row['skuId']]['unitName'] : '';
                $row['specGroup'] = isset($allSkuData[$row['skuId']]) ? $allSkuData[$row['skuId']]['specGroup'] : [];
                if (empty($row['specGroup'])){
                    $value['specType'] = StatusCode::$specType['single'];
                }else{
                    $value['specType'] = StatusCode::$specType['multiple'];
                }
            }
        }
        return $data;
    }

    /**
     * 生效操作
     * @param $id
     * @param $params
     * @return ResultWrapper
     * @throws \Exception
     */
    public function effective($id, $params)
    {
        // 计算客户类型调价单分表
        $tableName = 'qianniao_customerTypePriceAdjustmentSheet_' . $this->onlineEnterpriseId . '_' . date('Y', $params['createTime']) . '_' . ceil(date('m', $params['createTime']) / 3);
        $this->objDCustomerTypePriceAdjustment->setTable($tableName);

        $priceAdjustment = $this->objDCustomerTypePriceAdjustment->get($id);
        if ($priceAdjustment === false) {
            return ResultWrapper::fail($this->objDCustomerTypePriceAdjustment->error(), ErrorCode::$dberror);
        }

        if (empty($priceAdjustment)) {
            return ResultWrapper::fail('要生效的调价单不存在', ErrorCode::$contentNotExists);
        }

        $this->objDCustomerTypePriceAdjustment->beginTransaction();

        // 将调价单变更为生效状态
        $dbResult = $this->objDCustomerTypePriceAdjustment->update(
            [
                'effectiveStatus'   => StatusCode::$auditStatus['auditPass'],
                'effectiveUserName' => $params['effectiveUserName'],
                'effectiveUserId'   => $params['effectiveUserId'],
            ]
            , $id);
        if ($dbResult === false) {
            $this->objDCustomerTypePriceAdjustment->rollBack();
            return ResultWrapper::fail($this->objDCustomerTypePriceAdjustment->error(), ErrorCode::$dberror);
        }

        // 记录最后生效数据
        unset($dbResult);
        $objDCustomerPriceEffective = new DCustomerTypePriceEffective();
        $objDCustomerPriceEffective->setTable('qianniao_customerTypePriceEffective_' . $this->onlineEnterpriseId);
        $data = [
            'no'           => $priceAdjustment['no'],
            'goodsId'      => $priceAdjustment['goodsId'],
            'shopId'       => $priceAdjustment['shopId'],
            'salePrice'    => $priceAdjustment['salePrice'],
            'startTime'    => $priceAdjustment['startTime'],
            'endTime'      => $priceAdjustment['endTime'],
            'customerType' => $priceAdjustment['customerType'],
        ];

        $dbResult = $objDCustomerPriceEffective->replace($data);
        if ($dbResult === false) {
            $this->objDCustomerTypePriceAdjustment->rollBack();
            return ResultWrapper::fail($objDCustomerPriceEffective->error(), ErrorCode::$dberror);
        }

        //删除缓存
        $this->objPriceCache->delCustomerTypeAdj($priceAdjustment['goodsId'],$priceAdjustment['customerType']);
        // 每编辑一件商品需要清除一下小程序商品首页的缓存;
        $objPageCache = new PageCache();
        $objPageCache->delPage();
        $this->objDCustomerTypePriceAdjustment->commit();
        return ResultWrapper::success($dbResult);
    }

    /**
     * 获取指定客户类型的可用的调价单
     * @param int $shopId  店铺id
     * @param int $customerType  客户类型
     * @param array $goodsIds 店铺下商品集合
     * @return ResultWrapper
     */
    public function getCustomerTypePriceByIds($shopId, $customerType, $goodsIds)
    {
        $objDCustomerTypePriceEffective = new DCustomerTypePriceEffective();
        $objDCustomerTypePriceEffective->setTable('qianniao_customerTypePriceEffective_' . $this->onlineEnterpriseId);

        $where = 'shopId = ' . $shopId . ' and customerType = ' . $customerType. ' and goodsId in ('.implode(',', $goodsIds).')';

        $dbResult = $objDCustomerTypePriceEffective->select($where, 'goodsId,salePrice', 'endTime desc');
        if ($dbResult === false) {
            return ResultWrapper::fail($objDCustomerTypePriceEffective->error(), ErrorCode::$dberror);
        }
        return ResultWrapper::success($dbResult);
    }


    /**
     * 获取指定商品的最后生效的客户类型调价数据
     * @param $params
     * @return ResultWrapper
     */
    public function getCustomerTypePriceByGoodsIds($params)
    {
        $pageData = pageToOffset($params['page'], $params['pageSize']);
        $objDCustomerTypePriceEffective = new DCustomerTypePriceEffective();
        $objDCustomerTypePriceEffective->setTable('qianniao_customerTypePriceEffective_' . $this->onlineEnterpriseId);
        $conditon = [
            'goodsId' => $params['goodsId'],
        ];
        
        $dbResult = $objDCustomerTypePriceEffective->select($conditon, 'id,customerType,salePrice', 'id desc',$pageData['limit'],$pageData['offset']);
        if ($dbResult === false) {
            return ResultWrapper::fail($objDCustomerTypePriceEffective->error(), ErrorCode::$dberror);
        }
        $count = $objDCustomerTypePriceEffective->count($conditon);
        if ($count === false) {
            return ResultWrapper::fail($objDCustomerTypePriceEffective->error(), ErrorCode::$dberror);
        }
        $data = self::formatCustomerType($dbResult);
        if(!$data->isSuccess()){
            return ResultWrapper::fail($objDCustomerTypePriceEffective->error(), ErrorCode::$dberror);
        }
   
        $dbResult = $data->getData();
        foreach ($dbResult as $key =>$value){
            $dbResult[$key]['salePrice'] = json_decode($value['salePrice']);
        }
        $return = [
            'data'  => $dbResult,
            'total' => $count,
        ];
        return ResultWrapper::success($return);
    }
    
    /**
     * 类型调价单导出方法
     * @param $priceSheetData
     */
    private static function exportPriceSheet($priceSheetData)
    {
        //导出到本地
        header("Content-type:application/vnd.ms-excel");
        header("Content-Disposition:filename=调价单明细表记录.csv");
        header('Cache-Control: max-age=0');
        $fp = fopen('php://output', 'a');
        
        $head = ['调价单编码','客户类型','商品编码', '商品名称', '调价时间', '调整规格','调整市场价格','调整人','相关店铺', '状态'];       //定义标题
        
        foreach ($head as $i => $v) {
            $head[$i] = mb_convert_encoding($v, 'GBK', 'utf-8');     //将中文标题转换编码，否则乱码
        }
        fputcsv($fp, $head);
        $limit = 10000;
        $num = 0;//计数器
        foreach ($priceSheetData as $v) {
            //调整规格与价格
            $price = '';
            $unitName = '';
            if(!empty($v['salePrice'])){
                foreach ($v['salePrice'] as $key =>$value){
                    $price = $value['price'];
                    $unitName = $value['unitName'];
                }
            }
            
            //循环数据
            $num++;
            if ($num == $limit) {
                ob_flush();//释放内存
                flush();
            }
            $rows['no'] = isset($v['no']) ? $v['no'] : '';//调价单编码
            $rows['customerName'] = isset($v['customerName']) ? $v['customerName'] : '';//客户类型
            $rows['goodsCode'] = isset($v['goodsCode']) ? $v['goodsCode'] : '';//商品编码
            $rows['goodsName'] = isset($v['goodsName']) ? $v['goodsName'] : '';//商品名称
            $rows['createTime'] = isset($v['createTime']) ? date('Y-m-d H:i:s',$v['createTime']) : '';//调价时间
            $rows['unitName'] = $unitName;//调整规格
            $rows['price'] = $price;//调整市场价格
            //$rows['ladderPrice'] = isset($v['ladderPrice']) ? $v['ladderPrice'] : "否";//阶梯价
            //$rows['salePrice'] = isset($v['salePrice']) ? $v['salePrice'] : '';//销售价
            $rows['createUserName'] = isset($v['createUserName']) ? $v['createUserName'] : '';//调整人
            $rows['shopName'] = isset($v['shopName']) ? $v['shopName'] : '';//相关店铺
            $rows['effectiveStatus'] =  $v['effectiveStatus'] === 2 ? '生效' : '未生效';//状态
            foreach ($rows as $kk => $vv) {
                $rs[$kk] = mb_convert_encoding($vv, 'GBK', 'utf-8');  //转译编码
            }
            fputcsv($fp, $rs);
            $rows = [];
        }
        exit;
    }
    
    /**
     * 删除指定商品的最后生效的客户类型调价数据
     * @param array $id
     * @return ResultWrapper
     */
    public function delCustomerTypePrice($params)
    {
        $objDCustomerTypePriceEffective = new DCustomerTypePriceEffective();
        $objDCustomerTypePriceEffective->setTable('qianniao_customerTypePriceEffective_' . $this->onlineEnterpriseId);

        $dbResult = $objDCustomerTypePriceEffective->select($params['id']);
        if ($dbResult === false) {
            return ResultWrapper::fail($objDCustomerTypePriceEffective->error(), ErrorCode::$dberror);
        }
        if(empty($dbResult)){
            return ResultWrapper::fail('要作废的调价单不存在', ErrorCode::$contentNotExists);
        }
        foreach ($dbResult  as $key => $value){
            $value['salePrice'] = json_decode($value['salePrice'], true);
            foreach ($value['salePrice'] as $k => $v){
                if($v['skuId'] == $params['skuId']){
                    unset($value['salePrice'][$k]);
                    continue;
                }
            }
            $value['salePrice'] = json_encode( $value['salePrice']);

            $updateDbResult = $objDCustomerTypePriceEffective->update(['salePrice'=>$value['salePrice']], $value['id']);
            if ($updateDbResult === false) {
                return ResultWrapper::fail($objDCustomerTypePriceEffective->error(), ErrorCode::$dberror);
            }
        }

        
        return ResultWrapper::success($updateDbResult);
        
    }
    /**
     * 格式化客户类型名称
     * @return array
     */
    public function formatCustomerType($data)
    {
        //根据客户类型id进行渲染类型名称
        $customerTypeIdBindCustomerTypeName = [];
        $customerTypeIds = [];
        foreach ($data as $k => $v){
            if(!empty($v['customerType'])){   //客户类型id  ”customerType“
                $customerTypeIds[] = $v['customerType'];
            }
        }
        if(!empty($customerTypeIds)){
            $objDCustomerSource = new DCustomerSource();
            $customerSourceData = $objDCustomerSource->select($customerTypeIds, 'id,name');
            if($customerSourceData == false){
                return ResultWrapper::fail($objDCustomerSource->error(), ErrorCode::$dberror);
            }
            if(!empty($customerSourceData)){
                foreach ($customerSourceData as $k => $v){
                    $customerTypeIdBindCustomerTypeName[$v['id']] = $v['name'];
                }
            }
            // 循环主数据，进行对应的字段映射操作
            foreach ($data as $key => $value){
                $data[$key]['customerTypeName'] = isset($customerTypeIdBindCustomerTypeName[$value['customerType']]) ? $customerTypeIdBindCustomerTypeName[$value['customerType']] :'';
            }
        }
        return  ResultWrapper::success($data);
    }

}