<?php
/**
 * 供应商余额管理模块
 * Created by PhpStorm.
 * User: wxj
 * Date: 2019/10/30
 * Time: 14:02
 */

namespace JinDouYun\Model\Finance;


use Mall\Framework\Core\ErrorCode;
use Mall\Framework\Core\StatusCode;
use Mall\Framework\Core\ResultWrapper;

use JinDouYun\Model\MBaseModel;
use JinDouYun\Dao\Finance\DSupplierBalance;
use JinDouYun\Dao\Finance\DSupplierBalanceIndex;
use JinDouYun\Dao\Purchase\DSupplier;
use JinDouYun\Model\Purchase\MSupplier;
use JinDouYun\Cache\OverviewCache;

class MSupplierBalance extends MBaseModel
{

    private $objDSupplierBalance;
    private $objDSupplierBalanceIndex;
    private $objDSupplier;
    private $objMSupplier;
    private $objOverviewCache;
    private $enterpriseId;
    private $userCenterId;
    private $cutTable = 200000;

    public function __construct($enterpriseId, $userCenterId)
    {
        $this->userCenterId = $userCenterId;
        $this->enterpriseId = $enterpriseId;
        parent::__construct($enterpriseId, $userCenterId);
        $this->objDSupplierBalance = new DSupplierBalance('finance');
        $this->objDSupplierBalanceIndex = new DSupplierBalanceIndex('finance');
        $this->objDSupplier = new DSupplier('stock');
        $this->objMSupplier = new MSupplier($userCenterId, $enterpriseId);
        $this->objOverviewCache = new OverviewCache();

        $this->objDSupplierBalanceIndex->setTable('qianniao_supplier_balance_index_' . $enterpriseId);
        $this->objDSupplier->setTable('qianniao_supplier_' . $enterpriseId);
    }

    /**
     * 添加供应商余额
     * @param $supplierId
     * @param $changedMoney
     * @return ResultWrapper
     * @throws \Exception
     */
    public function addSupplierBalance($supplierId, $changedMoney)
    {
        $tableName = $this->objDSupplierBalance->getTableName('qianniao_supplier_balance_' . $this->enterpriseId, $supplierId, $this->cutTable);
        $this->objDSupplierBalance->setTable($tableName);

        //获取供应商目前的余额
        $money = $this->objDSupplier->get_field('money', $supplierId);

        //新增一条供应商余额信息
        $balanceData = [
            'supplierId'     => $supplierId,
            'openingBalance' => $money,
            'interimBalance' => $changedMoney,
            'endingBalance'  => bcadd($money, $changedMoney, 4),
            'createTime'     => time(),
            'updateTime'     => time()
        ];
        $detailId = $this->objDSupplierBalance->insert($balanceData);
        if ($detailId === false) {
            return ResultWrapper::fail($this->objDSupplierBalance->error(), ErrorCode::$dberror);
        }

        //新增一条供应商余额索引数据
        $indexData = [
            'supplierId' => $supplierId,
            'detailId'   => $detailId,
            'createTime' => time(),
            'updateTime' => time()
        ];
        $indexId = $this->objDSupplierBalanceIndex->insert($indexData);
        if ($indexId == false) {
            return ResultWrapper::fail($this->objDSupplierBalanceIndex->error(), ErrorCode::$dberror);
        }
        //更新供应商的最新余额
        $result = self::updateSupplierBalance($supplierId, $changedMoney);
        if ($result->isSuccess() === false) {
            return ResultWrapper::fail($result->getData(), $result->getErrorCode());
        }

        return ResultWrapper::success($result->getData());

    }

    /**
     * 获取所有供应商余额数据
     *
     * @param array $selectParams 过滤条件
     *
     * @return ResultWrapper
     */
    public function getAllSupplierBalance($selectParams)
    {
        $limit = $selectParams['limit'];
        unset($selectParams['limit']);
        $offset = $selectParams['offset'];
        unset($selectParams['offset']);

        $supplierId = $selectParams['supplierId'];
        unset($selectParams['supplierId']);
        $start = $selectParams['start'];
        unset($selectParams['start']);
        $end = $selectParams['end'];
        unset($selectParams['end']);

        $isExport = isset($selectParams['isExport']) ? $selectParams['isExport'] : false;

        //默认进来不筛选,查出供应商当前的余额
        if (!$start && !$end) {
            $where = ['limit' => $limit, 'offset' => $offset];
            if ($supplierId) {
                $where['id'] = $supplierId;
            }
            $result = $this->objMSupplier->getSupplierMoney($where, $isExport);
            if ($result->isSuccess() == false) {
                return ResultWrapper::fail($result->getData(), $result->getErrorCode());
            }
            return ResultWrapper::success($result->getData());
        }

        if($isExport){
            ResultWrapper::fail('有筛选条件不支持导出', ErrorCode::$paramError);
        }

        //期初余额
        $startResult = self::getShouldPayMoneyByTime($start, $supplierId);
        //期末余额
        $endResult = self::getShouldPayMoneyByTime($end, $supplierId);
        $supplierName = $this->objDSupplier->get_field('title', $supplierId);
        $return = [
            'data'  => [
                [
                    'supplierId'     => $supplierId,
                    'title'   => $supplierName,
                    'openingBalance' => $startResult,
                    'interimBalance' => $endResult - $startResult,
                    'endingBalance'  => $endResult
                ]
            ],
            'total' => 1,
        ];

        return ResultWrapper::success($return);

    }

    /**
     * 获取某一日期的余额
     * @param $time
     * @param $supplierId
     * @return int
     * @throws \Exception
     */
    public function getShouldPayMoneyByTime($time, $supplierId)
    {
        $tableName = $this->objDSupplierBalanceIndex->get_Table();
        $sql = "select * from $tableName where createTime <= $time AND supplierId = $supplierId order by id desc limit 1";
        $result = $this->objDSupplierBalanceIndex->query($sql);
        if (empty($result)) {
            //没有发生过应付
            return 0;
        }
        $data = array_shift($result);
        $tableName = $this->objDSupplierBalance->getTableName('qianniao_supplier_balance_' . $this->enterpriseId, $supplierId, $this->cutTable);
        $this->objDSupplierBalance->setTable($tableName);
        return $this->objDSupplierBalance->get_field('endingBalance', $data['detailId']);
    }

    /**
     * 修改供应商余额
     * @param $supplierId
     * @param $changedMoney
     * @return ResultWrapper
     */
    public function updateSupplierBalance($supplierId, $changedMoney)
    {
        $dbResult = $this->objDSupplier->set_inc('money', $supplierId, $changedMoney);
        if ($dbResult === false) {
            return ResultWrapper::fail($this->objDSupplier->error(), ErrorCode::$dberror);
        }
        //修改应付款总金额
        $this->objOverviewCache->saveAggregateStatistics($this->enterpriseId, 'totalShouldPay', $changedMoney);
        return ResultWrapper::success($dbResult);
    }

    /**
     * 修改供应商总收款金额
     * @param $supplierId
     * @param $money
     * @return ResultWrapper
     */
    public function updateSupplierTotalReceiveMoney($supplierId, $money)
    {
        $dbResult = $this->objDSupplier->set_inc('totalReceiveMoney', $supplierId, $money);
        if ($dbResult === false) {
            return ResultWrapper::fail($this->objDSupplier->error(), ErrorCode::$dberror);
        }
        return ResultWrapper::success($dbResult);
    }

    /**
     * 获取供应商余额
     * @param $supplierId
     * @param string $field
     * @return int|mixed
     */
    public function getSupplierBalance($supplierId, $field = 'money')
    {
        $money = $this->objDSupplier->get_field($field, $supplierId);
        return $money ? $money : 0;
    }


    public function getSupplier($id)
    {
        $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);

    }

    /**
     * Doc: (des="")
     * User: XMing
     * Date: 2020/12/18
     * Time: 5:56 下午
     * @param $update
     * @param $id
     * @return ResultWrapper
     */
    public function updateSupplier($update,$id): ResultWrapper
    {
        $dbResult = $this->objDSupplier->update($update,$id);
        if ($dbResult === false) {
            return ResultWrapper::fail($this->objDSupplier->error(), ErrorCode::$dberror);
        }
        return ResultWrapper::success($dbResult);
    }
}