<?php
/**
 * 供应商数据模型
 * Created by PhpStorm.
 * User: XiaoMing
 * Date: 2019/11/11
 * Time: 14:33
 */

namespace JinDouYun\Model\Purchase;

use JinDouYun\Controller\Common\Logger;
use JinDouYun\Model\GoodsManage\MGoodsBasic;
use JinDouYun\Model\Order\MSupplierOrderDetails;
use Mall\Framework\Core\StatusCode;
use Mall\Framework\Core\ErrorCode;
use Mall\Framework\Core\ResultWrapper;

use JinDouYun\Cache\SupplierCache;
use JinDouYun\Cache\OverviewCache;

use JinDouYun\Model\SysAreaChina\MSysAreaChina;
use JinDouYun\Model\UserCenter\MUserCenterRegister;
use JinDouYun\Model\Enterprise\MEnterprise;

use JinDouYun\Dao\Purchase\DSupplier;

class MSupplier
{
    private $objDSupplier;

    private $objOverviewCache;

    private $onlineUserId;

    private $onlineEnterpriseId;

    private $objSupplierCache;


    /**
     * MSupplier constructor.
     * @param $onlineUserId
     * @param $onlineEnterpriseId
     * @throws \Exception
     */
    public function __construct($onlineUserId, $onlineEnterpriseId)
    {
        $this->onlineUserId = $onlineUserId;
        $this->onlineEnterpriseId = $onlineEnterpriseId;

        $this->objDSupplier = new DSupplier('stock');
        $this->objOverviewCache = new OverviewCache();
        $this->objSupplierCache = new SupplierCache();

        $this->objDSupplier->setTable($this->objDSupplier->get_Table() . '_' . $this->onlineEnterpriseId);
    }

    /**
     * 添加供应商
     * @param $params
     * @return ResultWrapper
     */
    public function addSupplier($params)
    {
        $objMEnterprise = new MEnterprise();
        $modelResult = $objMEnterprise->createAppid($this->onlineUserId);
        $params['token'] = $modelResult['token'];
        $this->objDSupplier->beginTransaction();
        $dbResult = $this->objDSupplier->insert($params);
        if ($dbResult === false) {
            $this->objDSupplier->rollBack();
            return ResultWrapper::fail($this->objDSupplier->error(), ErrorCode::$dberror);
        }
        //缓存token
        $this->objSupplierCache->setSupplierToken($this->onlineEnterpriseId, $dbResult, $params['token']);
        $code = createCode(StatusCode::$code['supplier']['prefix'], $dbResult, StatusCode::$code['supplier']['length']);
        $dbResult = $this->objDSupplier->update(['code' => $code], ['id' => $dbResult]);
        if ($dbResult === false) {
            $this->objDSupplier->rollBack();
            return ResultWrapper::fail($this->objDSupplier->error(), ErrorCode::$dberror);
        }
        $this->objDSupplier->commit();
        return ResultWrapper::success($dbResult);
    }

    /**
     * 添加供应商为用户
     * @param $params
     * @return ResultWrapper
     */
    public function addSupplierUserCenter($params)
    {
        // 获取供应商信息
        $dbResult = $this->objDSupplier->get(['id' => $params['id']]);
        if($dbResult === false){
            return ResultWrapper::fail($this->objDSupplier->error(), ErrorCode::$dberror);
        }
        $supplier = $dbResult;
        unset($dbResult);
        if(empty($supplier)){
            return ResultWrapper::fail('供应商不存在', ErrorCode::$paramError);
        }

        // 添加user_center数据
        $objMUserCenterRegister = new MUserCenterRegister();
        $modelResult = $objMUserCenterRegister->addUser($supplier['mobile'], StatusCode::$roleType['supplier'], $this->onlineEnterpriseId);
        if(!$modelResult->isSuccess()){
            return ResultWrapper::fail($modelResult->getData(), $modelResult->getErrorCode());
        }
        $return = $modelResult->getData();
        unset($modelResult);

        // 判断是否已经存在
        $dbResult = $this->objDSupplier->get(['userCenterId' => $return['userCenterId']]);
        if($dbResult === false){
            return ResultWrapper::fail($this->objDSupplier->error(), ErrorCode::$dberror);
        }
        if(!empty($dbResult)){
            return ResultWrapper::fail('该手机号已经是供应商', ErrorCode::$paramError);
        }

        // 生成供应商token
        if(empty($supplier['token'])){
            $objMEnterprise = new MEnterprise();
            $modelResult = $objMEnterprise->createAppid($this->onlineUserId);
            $token = $modelResult['token'];
            $this->objSupplierCache->setSupplierToken($this->onlineEnterpriseId, $supplier['id'], $token);
            $update['token'] = $token;
        }

        // 绑定供应商和user_centerid
        $update = [
            'userCenterId' => $return['userCenterId'],
            'updateTime' => time(),
        ];
        $dbResult = $this->objDSupplier->update($update, ['id' => $supplier['id']]);
        if($dbResult === false){
            return ResultWrapper::fail($this->objDSupplier->error(), ErrorCode::$dberror);
        }
        return ResultWrapper::success($return['title']);
    }

    /**
     * 获取供应商信息
     * @param $id
     * @return ResultWrapper
     */
    public function getSupplierInfoById($id)
    {
        $dbResult = $this->objDSupplier->get($id);

        if ($dbResult === false) {
            return ResultWrapper::fail($this->objDSupplier->error(), ErrorCode::$dberror);
        }
        $formatResult = self::format($dbResult);
        if (!empty($formatResult)) {
            $dbResult = $formatResult[0];
        }
        return ResultWrapper::success($dbResult);
    }

    /**
     * 获取供应商信息
     * @param $userCenterId
     * @return ResultWrapper
     */
    public function getSupplierByUserCenterId($userCenterId)
    {
        $dbResult = $this->objDSupplier->get(['userCenterId' => $userCenterId]);
        if ($dbResult === false) {
            return ResultWrapper::fail($this->objDSupplier->error(), ErrorCode::$dberror);
        }
        return ResultWrapper::success($dbResult);
    }

    /**
     * 编辑供应商信息
     * @param $params
     * @return ResultWrapper
     */
    public function editSupplier($params)
    {
        if (empty($params['id'])) {
            return ResultWrapper::fail('没有id', ErrorCode::$paramError);
        }

        $id = $params['id'];
        unset($params['id']);

        $dbResult = $this->objDSupplier->update($params, $id);

        if ($dbResult === false) {
            return ResultWrapper::fail($this->objDSupplier->error(), ErrorCode::$dberror);
        }
        return ResultWrapper::success($dbResult);
    }

    /**
     * 供应商显示/隐藏
     * @param $params
     * @return ResultWrapper
     */
    public function updateEnableStatus($params)
    {
        $dbResult = $this->objDSupplier->update(['enableStatus' => $params['enableStatus']], $params['id']);
        if ($dbResult === false) {
            return ResultWrapper::fail($this->objDSupplier->error(), ErrorCode::$dberror);
        }
        return ResultWrapper::success($dbResult);
    }

    /**
     * 删除供应商
     * @param $id
     * @return ResultWrapper
     */
    public function delSupplier($id)
    {
        $dbResult = $this->objDSupplier->update(['deleteStatus' => StatusCode::$delete], $id);

        if ($dbResult === false) {
            return ResultWrapper::fail($this->objDSupplier->error(), ErrorCode::$dberror);
        }
        return ResultWrapper::success($dbResult);
    }

    /**
     * 供应商列表
     * @param $selectParams
     * @return ResultWrapper
     */
    public function getAllSupplier($selectParams)
    {
        $limit = $selectParams['limit'];
        unset($selectParams['limit']);
        $offset = $selectParams['offset'];
        unset($selectParams['offset']);

        $where = 'deleteStatus=' . StatusCode::$standard;
        if (isset($selectParams['enableStatus'])) {
            $where .= ' AND enableStatus = ' . $selectParams['enableStatus'];
        }

        if (isset($selectParams['keyword'])) {
            $where .= ' AND (realName LIKE "%'. $selectParams['keyword'] .'%" OR title LIKE "%' . $selectParams['keyword'] . '%" OR code LIKE "%' . $selectParams['keyword'] . '%")';
        }

        $dbResult = $this->objDSupplier->select($where, '*', 'createTime desc', $limit, $offset);

        if ($dbResult === false) {
            return ResultWrapper::fail($this->objDSupplier->error(), ErrorCode::$dberror);
        }
        $total = $this->objDSupplier->count($where);

        $return = [
            'data'  => self::format($dbResult),
            'total' => ($total) ? intval($total) : 0,
        ];

        return ResultWrapper::success($return);
    }

    /**
     * 处理省市区
     * @param $data
     * @param bool $flag
     * @return mixed
     */
    private function format($data)
    {
        if (isset($data['id'])) {
            $dimension = $data;
            unset($data);
            $data[] = $dimension;
        }

        $objMSysAreaChina = new MSysAreaChina();
        foreach ($data as $key => $val) {
            $data[$key]['code'] = createCode(StatusCode::$code['supplier']['prefix'], $val['id'], StatusCode::$code['supplier']['length']);
            $areaName = $objMSysAreaChina->getNameByCode([
                $val['provinceCode'],
                $val['cityCode'],
                $val['districtCode']
            ]);
            $data[$key]['area']['provinceName'] = isset($areaName[$val['provinceCode']]) ? $areaName[$val['provinceCode']] : '';
            $data[$key]['area']['cityName'] = isset($areaName[$val['cityCode']]) ? $areaName[$val['cityCode']] : '';
            $data[$key]['area']['districtName'] = isset($areaName[$val['districtCode']]) ? $areaName[$val['districtCode']] : '';
            $data[$key]['area']['address'] = $val['address'];
        }

        return $data;
    }

    /**
     * 通过采购单id获取采购单下的商品
     * @param $ids
     * @return ResultWrapper
     */
    public function getSupplierNameByIds($ids)
    {
        if (empty($ids)){
            return ResultWrapper::success([]);
        }
        $dbResult = $this->objDSupplier->select(['id' => $ids], 'id,title');

        if ($dbResult === false) {
            Logger::logs(E_USER_ERROR,'sql error',__CLASS__,__LINE__,$this->objDSupplier->error());
            return ResultWrapper::fail($this->objDSupplier->error(), ErrorCode::$dberror);
        }

        return ResultWrapper::success($dbResult);
    }

    /**
     * 查询所有正常供应商数量
     */
    public function getAllSupplierNum()
    {
        $sql = "select count(id) as count from " . $this->objDSupplier->get_Table() . " where enableStatus = " . StatusCode::$standard . " and deleteStatus = " . StatusCode::$standard;
        $dbResult = [];
        $dbResult = $this->objDSupplier->query($sql);
        if ($dbResult === false) {
            return ResultWrapper::fail($this->objDSupplier->error(), ErrorCode::$dberror);
        }
        $returnData = array_shift($dbResult);
        return ResultWrapper::success($returnData['count']);
    }

    /**
     * 获取供应商余额
     *
     * @param array $selectParams 过滤条件
     *
     * @param $isExport
     * @return ResultWrapper
     */
    public function getSupplierMoney($selectParams, $isExport)
    {
        $limit = $selectParams['limit'];
        unset($selectParams['limit']);
        $offset = $selectParams['offset'];
        unset($selectParams['offset']);
        $selectParams['deleteStatus'] = StatusCode::$standard;

        if($isExport){
            $dbResult = $this->objDSupplier->exportSelect($selectParams, '*', 'createTime desc');
        }else{
            $dbResult = $this->objDSupplier->select($selectParams, 'id AS supplierId,title,money', 'createTime desc', $limit, $offset);
        }
        if ($dbResult === false) {
            return ResultWrapper::fail($this->objDSupplier->error(), ErrorCode::$dberror);
        }
        if($isExport){
            self::export($dbResult);
        }else{
            foreach ($dbResult as $key => $value) {
                $dbResult[$key]['openingBalance'] = $value['money'];
                $dbResult[$key]['interimBalance'] = 0;
                $dbResult[$key]['endingBalance'] = $value['money'];
                unset($dbResult[$key]['money']);
            }
        }


        $total = $this->objDSupplier->count($selectParams);

        $return = [
            'data'  => $dbResult,
            'total' => ($total) ? intval($total) : 0,
        ];

        return ResultWrapper::success($return);
    }

    /**
     * 导出方法
     *
     * @param $exportData
     */
    private static function export($exportData)
    {
        //导出到本地
        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 ($exportData as $v) {
            //循环数据
            $num++;
            if ($num == $limit) {
                ob_flush();//释放内存
                flush();
            }

            $rows['title'] = $v['title'];
            $rows['openingBalance'] = $v['money'];
            $rows['purchase'] = 0;//采购金额
            $rows['payment'] = 0;//付款金额
            $rows['endingBalance'] = $v['money'];

            foreach ($rows as $kk => $vv) {
                $rs[$kk] = mb_convert_encoding($vv, 'GBK', 'utf-8');  //转译编码
            }
            fputcsv($fp, $rs);
            $rows = [];
        }
        exit;
    }

    /**
     * 获取总的应付金额
     */
    public function getTotalShouldPay()
    {
        $result = $this->objOverviewCache->getAggregateStatistics($this->onlineEnterpriseId, 'totalShouldPay');
        return $result ? $result : 0;
    }

    /**
     * 今日供应商排行
     * @param int $ranking
     * @param null $shopId
     * @return array
     */
    public function todaySupplierRanking($ranking = 1, $shopId = null)
    {
        if ($ranking == 1) {
            $result = $this->objOverviewCache->getRanking($this->onlineEnterpriseId, 'supplierRanking', $shopId);
        } else {
            $result = $this->objOverviewCache->getSalesMoneyRanking($this->onlineEnterpriseId, 'supplierRanking', $shopId);
        }

        if (empty($result)) {
            return [];
        }

        //拼接supplierId
        $supplierIds = [];
        $i = 1;
        foreach ($result as $supplierId => $v) {
            $supplierIds[] = $supplierId;
            $i++;
            if ($i >= 8) {
                break;
            }
        }

        $supplierResult = self::getSupplierNameByIds($supplierIds);
        $supplierNameData = [];
        if ($supplierResult->isSuccess()) {
            $supplierResult = $supplierResult->getData();
            foreach ($supplierResult as $supplierData) {
                $supplierNameData[$supplierData['id']] = $supplierData['title'];
            }
        }

        //拼接返回数据
        $return = [];
        $i = 1;
        foreach ($result as $supplierId => $v) {
            $rank = [];
            $rank['id'] = $i;
            $rank['supplierName'] = isset($supplierNameData[$supplierId]) ? $supplierNameData[$supplierId] : '';
            $rank['numberOrMoney'] = $v;
            $return[] = $rank;

            $i++;
            if ($i >= 8) {
                break;
            }
        }
        return $return;
    }

    /**
     * Doc: (des="根据供应商id获取数据")
     * User: XMing
     * Date: 2020/12/16
     * Time: 6:12 下午
     * @param int $id
     * @return ResultWrapper
     */
    public function getSupplierById(int $id): ResultWrapper
    {
        $dbResult = $this->objDSupplier->get($id);
        if ($dbResult === false) {
            return ResultWrapper::fail($this->objDSupplier->error(), ErrorCode::$dberror);
        }
        if (empty($dbResult)){
            return ResultWrapper::fail('未获取到供应商数据',ErrorCode::$paramError);
        }
        return ResultWrapper::success($dbResult);
    }

    public static function supplierMap(array $params): array
    {
        $map = [];
        foreach ($params as $param) {
            $map[$param['id']] = $param;
        }
        return $map;
    }

    public function getWithdrawal($id): ResultWrapper
    {
        if (empty($id)){
            return ResultWrapper::fail('供应商id为空',ErrorCode::$paramError);
        }
        $supplier = $this->objDSupplier->get($id);
        if ($supplier === false) {
            return ResultWrapper::fail($this->objDSupplier->error(), ErrorCode::$dberror);
        }
        $ret = [
            'id' => $id,
            'title' => getArrayItem($supplier,'title',''),
            'money' => getArrayItem($supplier,'money',0),
            'waitAuditWithdraw' => getArrayItem($supplier,'waitAuditWithdraw',0),
            'auditWithdraw' => getArrayItem($supplier,'auditWithdraw',0),
            'withdraw' => getArrayItem($supplier,'withdraw',0),
        ];
        return ResultWrapper::success($ret);
    }

    /**
     * Doc: (des="")
     * User: XMing
     * Date: 2020/12/26
     * Time: 4:41 下午
     * @param int|null $supplierId
     * @return ResultWrapper
     * @throws \Exception
     */
    public function statistics($supplierId)
    {
        $supplier = $this->objDSupplier->get($supplierId);
        if ($supplier === false){
            return ResultWrapper::fail($this->objDSupplier->error(),ErrorCode::$dberror);
        }
        if (empty($supplier)){
            return ResultWrapper::fail('没有获取到指定的供应商',ErrorCode::$paramError);
        }
        $objMSupplierOrderDetails = new MSupplierOrderDetails($this->onlineEnterpriseId,$this->onlineUserId);
        $orderTotalResult = $objMSupplierOrderDetails->getTotalBySupplierId($supplierId);
        if (!$orderTotalResult->isSuccess()){
            return ResultWrapper::fail($orderTotalResult->getData(),$orderTotalResult->getErrorCode());
        }

        $objMGoodsBasic = new MGoodsBasic($this->onlineUserId,$this->onlineEnterpriseId);
        $materielNumResult = $objMGoodsBasic->getTotalBySupplierId($supplierId);
        if (!$materielNumResult->isSuccess()){
            return ResultWrapper::fail($materielNumResult->getData(),$materielNumResult->getErrorCode());
        }
        $ret = [
            'money' => getArrayItem($supplier,'money','0.00'),
            'subOrderNum' => $orderTotalResult->getData(),
            'materielNum' => $materielNumResult->getData(),
        ];
        return ResultWrapper::success($ret);
    }
}