<?php
/**
 * Created by PhpStorm.
 * User: Gss
 * Date: 2021/3/8 0008
 * Time: 15:31
 */

namespace JinDouYun\Model\Finance;

use JinDouYun\Controller\Market\VipCard;
use Mall\Framework\Core\ErrorCode;
use Mall\Framework\Core\StatusCode;
use Mall\Framework\Core\ResultWrapper;

use JinDouYun\Dao\Finance\DExpenseSingle;
use JinDouYun\Dao\Finance\DExpenseSingleAccount;

use JinDouYun\Model\Finance\MAccount;
use JinDouYun\Model\Finance\MAccountDetail;

class MExpenseSingle
{
    private $objDExpenseSingle;
    private $objDExpenseSingleAccount;
    private $objMAccount;
    private $objMAccountDetail;
    private $objMCustomerBalanceDetail;
    private $objMCustomerBalance;
    private $objMSupplierBalanceDetail;
    private $objMSupplierBalance;
    private $enterpriseId;
    private $userCenterId;

    public function __construct($enterpriseId, $userCenterId)
    {
        $this->userCenterId = $userCenterId;
        $this->enterpriseId = $enterpriseId;

        $this->objDExpenseSingle = new DExpenseSingle('finance');
        $this->objDExpenseSingleAccount = new DExpenseSingleAccount('finance');
        $this->objMAccount = new MAccount($enterpriseId, $userCenterId);
        $this->objMAccountDetail = new MAccountDetail($enterpriseId, $userCenterId);
        $this->objMCustomerBalanceDetail = new MCustomerBalanceDetail($enterpriseId, $userCenterId);
        $this->objMCustomerBalance = new MCustomerBalance($enterpriseId, $userCenterId);
        $this->objMSupplierBalanceDetail = new MSupplierBalanceDetail($enterpriseId, $userCenterId);
        $this->objMSupplierBalance = new MSupplierBalance($enterpriseId, $userCenterId);

        $this->objDExpenseSingle->setTable('qianniao_expense_single_' . $enterpriseId);
        $this->objDExpenseSingleAccount->setTable('qianniao_expense_single_account_' . $enterpriseId);
    }

    /**
     * 新增费用单
     */
    public function addExpenseSingle($params)
    {
        $expenseSingleAccountDate = $params['expenseSingleAccountDate'];
        unset($params['expenseSingleAccountDate']);

        // 生成编号
        $dbResult =  $this->objDExpenseSingle->get('createTime >='.strtotime(date('Ymd'.'0:0:0')), 'no', 'createTime desc');
        if ($dbResult === false) {
            return ResultWrapper::fail($this->objDExpenseSingle->error(), ErrorCode::$dberror);
        }
        if(empty($dbResult)){
            $params['no'] = createSerialNumberByDate('');
        }else{
            $params['no'] = createSerialNumberByDate($dbResult['no']);
        }

        //开启事务
        $beginTransactionStatus = $this->objDExpenseSingle->beginTransaction();
        $expenseSingleId = $this->objDExpenseSingle->insert($params);

        if ($expenseSingleId === false) {
            $this->objDExpenseSingle->rollBack();
            return ResultWrapper::fail($this->objDExpenseSingle->error(), ErrorCode::$dberror);
        }
        foreach ($expenseSingleAccountDate as $key => $value){
            $expenseSingleAccountDate[$key]['expenseSingleId'] = $expenseSingleId;
        }
        $expenseSingleAccountId = $this->objDExpenseSingleAccount->insert($expenseSingleAccountDate,true);
        if ($expenseSingleAccountId === false) {
            $this->objDExpenseSingle->rollBack();
            return ResultWrapper::fail($this->objDExpenseSingleAccount->error(), ErrorCode::$dberror);
        }
        if($beginTransactionStatus){
            $this->objDExpenseSingle->commit();
        }
        return ResultWrapper::success($expenseSingleId);
    }

    /**
     * 获取指定的费用单
     */
    public function getExpenseSingleInfo($expenseSingleId)
    {
        $dbResult = $this->objDExpenseSingle->get($expenseSingleId);
        if($dbResult === false){
            return ResultWrapper::fail($this->objDExpenseSingle->error(), ErrorCode::$dberror);
        }
        if(empty($dbResult)){
            return ResultWrapper::success([]);
        }
        //渲染前缀
        $dbResult['no'] = StatusCode::$noPrefix[28] . '-' . $dbResult['no'];

        $dbResultAccount = $this->objDExpenseSingleAccount->select(['expenseSingleId'=>$expenseSingleId,'deleteStatus'=>StatusCode::$standard]);
        if($dbResultAccount === false){
            return ResultWrapper::fail($this->objDExpenseSingleAccount->error(), ErrorCode::$dberror);
        }
        if(!empty($dbResultAccount)){
            $dbResult['accountList'] = $dbResultAccount;
        }
        return ResultWrapper::success($dbResult);
    }

    /**
     * 编辑指定的费用单
     */
    public function editExpenseSingle($params)
    {
        $updateExpenseSingleId = $params['id'];
        unset($params['id']);

        unset($params['createTime']);
        $expenseSingleAccountDate = $params['expenseSingleAccountDate'];
        unset($params['expenseSingleAccountDate']);
        //累计金额
        $params['totalCollectionAmount'] = 0;
        $params['totalPreferentialAmount'] = 0;
        $params['totalActualAmount'] = 0;
        foreach ($expenseSingleAccountDate as $account) {
            $account['preferentialAmount'] = !empty($account['preferentialAmount']) ? $account['preferentialAmount'] : 0;
            $params['totalCollectionAmount'] += $account['amount'];
            $params['totalPreferentialAmount'] += $account['preferentialAmount'];
            $params['totalActualAmount'] += ($account['amount'] - $account['preferentialAmount']);
        }
        //开启事务
        $beginTransactionStatus = $this->objDExpenseSingle->beginTransaction();
        $receiptRequisitionId = $this->objDExpenseSingle->update($params, $updateExpenseSingleId);
        if($receiptRequisitionId === false){
            $this->objDExpenseSingle->rollBack();
            return ResultWrapper::fail($this->objDExpenseSingle->error(), ErrorCode::$dberror);
        }
        foreach ($expenseSingleAccountDate as $key => $value){
            $id = getArrayItem($value, 'id', 0);
            if($id){
                $dbResult = $this->objDExpenseSingleAccount->update($value,$id);
            }else{
                $value['expenseSingleId'] = $updateExpenseSingleId;
                $dbResult = $this->objDExpenseSingleAccount->insert($value);
            }
        }
        if ($dbResult === false) {
            $this->objDExpenseSingle->rollBack();
            return ResultWrapper::fail($this->objDExpenseSingleAccount->error(), ErrorCode::$dberror);
        }
        if($beginTransactionStatus){
            $this->objDExpenseSingle->commit();
        }
        return ResultWrapper::success($receiptRequisitionId);
    }

    /**
     * 删除指定的费用单
     */
    public function delExpenseSingle($expenseSingleId)
    {
        if (empty($expenseSingleId)) {
            return ResultWrapper::fail('参数错误', ErrorCode::$paramError);
        }
        $beginTransactionStatus = $this->objDExpenseSingle->beginTransaction();
        $dbResult = $this->objDExpenseSingle->update( ['deleteStatus'=>StatusCode::$delete], $expenseSingleId);
        if($dbResult === false){
            $this->objDExpenseSingle->rollBack();
            return ResultWrapper::fail($this->objDExpenseSingle->error(), ErrorCode::$dberror);
        }
        unset($dbResult);
        $dbResult = $this->objDExpenseSingleAccount->update( ['deleteStatus'=>StatusCode::$delete], ['expenseSingleId'=>$expenseSingleId]);
        if($dbResult === false){
            $this->objDExpenseSingle->rollBack();
            return ResultWrapper::fail($this->objDExpenseSingleAccount->error(), ErrorCode::$dberror);
        }

        if($beginTransactionStatus){
            $this->objDExpenseSingle->commit();
        }
        return ResultWrapper::success($expenseSingleId);
    }

    /**
     * 获取所有的费用单
     */
    public function getAllExpenseSingle($selectParams)
    {
        $limit = $selectParams['limit'];
        unset($selectParams['limit']);
        $offset = $selectParams['offset'];
        unset($selectParams['offset']);
        $selectParams['deleteStatus'] = StatusCode::$standard;

        $returnData = [
            'data'  => [],
            'total' => 0,
        ];

        $whereSql = '';
        if (isset($selectParams['currentUnitId']) && !empty($selectParams['currentUnitId'])) {
            $where = empty($whereSql) ? ' WHERE ' : ' AND ';
            $whereSql .= $where . ' currentUnitId = ' . $selectParams['currentUnitId'];
        }
        if (isset($selectParams['payType']) && !empty($selectParams['payType'])) {
            $where = empty($whereSql) ? ' WHERE ' : ' AND ';
            $whereSql .= $where . ' payType = ' . $selectParams['payType'];
        }
        if (isset($selectParams['consumeTypeId']) && !empty($selectParams['consumeTypeId'])) {
            $where = empty($whereSql) ? ' WHERE ' : ' AND ';
            $whereSql .= $where . ' consumeTypeId = ' . $selectParams['consumeTypeId'];
        }
        if (isset($selectParams['auditStatus']) && !empty($selectParams['auditStatus'])) {
            $where = empty($whereSql) ? ' WHERE ' : ' AND ';
            $whereSql .= $where . ' auditStatus = ' . $selectParams['auditStatus'];
        }
        if ( (isset($selectParams['start']) && !empty($selectParams['start']))&&(isset($selectParams['end']) && !empty($selectParams['end'])) ) {
            $where = empty($whereSql) ? ' WHERE ' : '  AND ';
            $whereSql .= $where . ' createTime BETWEEN ' . $selectParams['start'] . ' AND '. $selectParams['end'];
        }
        $where = empty($whereSql) ? ' WHERE ' : ' AND ';
        $whereSql .= $where . 'deleteStatus = ' . StatusCode::$standard;
        $sql = 'SELECT * FROM ' .$this->objDExpenseSingle->get_Table().$whereSql . ' ORDER BY createTime DESC LIMIT ' . $offset . ' , ' . $limit;
        $dbResult = $this->objDExpenseSingle->query($sql);
        if ($dbResult === false) {
            return ResultWrapper::fail($this->objDExpenseSingle->error(), ErrorCode::$dberror);
        }
        if(empty($dbResult)){
            return ResultWrapper::success($returnData);
        }
        //渲染前缀
        foreach ($dbResult as $key => $value){
            $dbResult[$key]['no'] = StatusCode::$noPrefix[28] . '-' . $value['no'];
        }

        $totalSql = 'SELECT COUNT(1) as count FROM ' .$this->objDExpenseSingle->get_Table() . $whereSql;
        $dbTotalResult = $this->objDExpenseSingle->query($totalSql);

        if ($dbTotalResult === false) {
            return ResultWrapper::fail($this->objDExpenseSingle->error(), ErrorCode::$dberror);
        }
        if(empty($dbTotalResult)){
            return ResultWrapper::success([]);
        }
        $return = [
            'data'  => $dbResult,
            'total' => $dbTotalResult[0]['count']
        ];
        return ResultWrapper::success($return);
    }

    /**
     * 审核费用单
     */
    public function updateExpenseStatus($params)
    {
        $dbResult = $this->objDExpenseSingle->get($params['id']);
        if ($dbResult === false) {
            return ResultWrapper::fail($this->objDExpenseSingle->error(), ErrorCode::$dberror);
        }

        if(empty($dbResult)){
            return ResultWrapper::fail('要审核的单据不存在', ErrorCode::$contentNotExists);
        }

        if ($dbResult['auditStatus'] === StatusCode::$auditStatus['auditPass']) {
            return ResultWrapper::fail('单据已审核', ErrorCode::$actionIsDo);
        }

        $beginTransactionStatus = $this->objDExpenseSingle->beginTransaction();
        //修改审核状态
        $updateDbResult = $this->objDExpenseSingle->update(['auditStatus' => StatusCode::$auditStatus['auditPass']], $params['id']);
        if ($updateDbResult === false) {
            $this->objDExpenseSingle->rollBack();
            return ResultWrapper::fail($this->objDExpenseSingle->error(), ErrorCode::$dberror);
        }

        //计算费用金额
        $accountDbResult = $this->objDExpenseSingleAccount->select(['expenseSingleId'=>$params['id']]);
        if( $accountDbResult === false ){
            return ResultWrapper::fail($this->objDExpenseSingleAccount->error(), ErrorCode::$dberror);
        }
        if( empty($accountDbResult) ){
            return ResultWrapper::success($updateDbResult);
        }

        foreach ($accountDbResult as $key => $value){
            $accountResult = $this->objMAccount->getAccountInfo($value['accountId']);
            if(!$accountResult->isSuccess()) {
                $this->objDExpenseSingle->rollBack();
                return ResultWrapper::fail($accountResult->getData(), $accountResult->getErrorCode());
            }
            $accountInfo = $accountResult->getData();
            if(empty($accountInfo)){
                continue;
            }

            //账户明细
            $accountDetail = [
                'accountId'=> $accountInfo['id'],
                'accountCode'=> $accountInfo['accountCode'],
                'accountName'=> $accountInfo['name'],
                'accountNumber'=> $accountInfo['accountNumber'],
                'sourceNo'=>StatusCode::$noPrefix['28'].'-'.$dbResult['no'],
                'sourceId'=>$dbResult['id'],
                'financeType'=> ($dbResult['payType'] == StatusCode::$standard) ? StatusCode::$systemFinanceType[7] :StatusCode::$systemFinanceType[8],
                'beginBalance'=>$accountInfo['money'],
                'shopId'=>$dbResult['shopId'],
                'shopName'=>$dbResult['shopName'],
                'income'=>($dbResult['payType'] == StatusCode::$standard) ? $value['amount'] : 0,
                'expend'=>($dbResult['payType'] == StatusCode::$delete) ? $value['amount'] : 0,
                'endBalance'=>($dbResult['payType'] == StatusCode::$standard) ? bcadd($accountInfo['money'],$value['amount'],4)  : bcsub($accountInfo['money'],$value['amount'],4),
                'contactUnit'=>$dbResult['currentUnit'],
                'supplierId'=>0,
                'customerId'=>0,
                'operatorId'=>$this->userCenterId,
                'receiveOrPayPerson'=>$dbResult['manager'],
                'remark'=>'费用单审核通过',
                'createTime'=>time(),
                'updateTime'=>time(),
            ];

            $result = $this->objMAccountDetail->addAccountDetail($accountDetail);
            if ($result->isSuccess() === false) {
                $this->objDExpenseSingle->rollBack();
                return ResultWrapper::fail($result->getData(), $result->getErrorCode());
            }

            //给账户减钱
            $changedMoney = ($dbResult['payType'] == StatusCode::$standard) ? abs($value['amount'])  : -1 * $value['amount'];
            $result = $this->objMAccount->updateMoney($value['accountId'], $changedMoney);
            if ($result->isSuccess() === false) {
                $this->objDExpenseSingle->rollBack();
                return ResultWrapper::fail($result->getData(), $result->getErrorCode());
            }
        }

        //往来
//        switch ($dbResult['type']){
//            case StatusCode::$partion://员工 不需要操作
//                break;
//            case StatusCode::$delete://客户
//                // 获取客户往来余额
//                $customerBalance = $this->objMCustomerBalance->getCustomerBalance($dbResult['currentUnitId']);
//                if($dbResult['payType'] == StatusCode::$standard){//收入
//                    $detailData = [
//                        'customerId'             => $dbResult['currentUnitId'],//'客户id',
//                        'receiptTime'            => $dbResult['createTime'],//'单据日期',
//                        'sourceId'               => $dbResult['id'],//'单据编号',
//                        'sourceNo'               => $dbResult['no'],//'单据编号',
//                        'financeType'            => '费用单',//'财务类型名称',
//                        'financeTypeId'          => '',//'财务类型id',
//                        'originNo'               => '',//'源订单销货号',
//                        'originId'               => 0,//'源订单销货号',
//                        'salesAmount'            => $dbResult['totalCollectionAmount'],//总金额
//                        'discountMoney'          => $dbResult['totalPreferentialAmount'],// '优惠金额',
//                        'customerAmount'         => $dbResult['totalActualAmount'],// '客户承担金额',
//                        'receivableAmount'       => $dbResult['totalActualAmount'],// '应收金额',
//                        'actualReceivableAmount' => $dbResult['totalActualAmount'],//'实际收款金额',
//                        'receivableBalance'      => bcsub($customerBalance , $dbResult['totalActualAmount'], 4),//'应收后余额',
//                        'remark'                 => '费用单审核通过，本次优惠后实收' . $dbResult['totalActualAmount'] . '元，优惠'.$dbResult['totalPreferentialAmount'].'元',//'备注',
//                        'createTime'             => time(),//'创建日期',
//                        'updateTime'             => time(),//'修改日期',
//                    ];
//                    // 添加客户往来余额明细，修改客户往来余额
//                    $result = $this->objMCustomerBalanceDetail->addCustomerBalanceDetail($detailData);
//                    if (!$result->isSuccess()) {
//                        $this->objDExpenseSingle->rollBack();
//                        return ResultWrapper::fail($result->getData(), $result->getErrorCode());
//                    }
//
//                    // 编辑客户往来余额
//                    $changedMoney = $dbResult['payType'] ==StatusCode::$standard ? -1 * $dbResult['totalActualAmount'] : abs($dbResult['totalActualAmount']);
//                    $result = $this->objMCustomerBalance->addCustomerBalance($dbResult['currentUnitId'], $changedMoney);
//                    if (!$result->isSuccess()) {
//                        $this->objDExpenseSingle->rollBack();
//                        return ResultWrapper::fail($result->getData(), $result->getErrorCode());
//                    }
//                }else{
//                    $detailData = [
//                        'customerId'             => $dbResult['currentUnitId'],//'客户id',
//                        'receiptTime'            => $dbResult['createTime'],//'单据日期',
//                        'sourceId'               => $dbResult['id'],//'单据编号',
//                        'sourceNo'               => $dbResult['no'],//'单据编号',
//                        'financeType'            => '费用单',//'财务类型名称',
//                        'financeTypeId'          => '',//'财务类型id',
//                        'originNo'               => '',//'源订单销货号',
//                        'originId'               => 0,//'源订单销货号',
//                        'salesAmount'            => $dbResult['totalCollectionAmount'],//总金额
//                        'discountMoney'          => $dbResult['totalPreferentialAmount'],// '优惠金额',
//                        'customerAmount'         => $dbResult['totalActualAmount'],// '客户承担金额',
//                        'receivableAmount'       => $dbResult['totalActualAmount'],// '应收金额',
//                        'actualReceivableAmount' => $dbResult['totalActualAmount'],//'实际收款金额',
//                        'receivableBalance'      => bcadd($customerBalance , $dbResult['totalActualAmount'], 4),
//                        'remark'                 => '费用单审核通过，本次优惠后实收' . $dbResult['totalActualAmount'] . '元，优惠'.$dbResult['totalPreferentialAmount'].'元',//'备注',
//                        'createTime'             => time(),//'创建日期',
//                        'updateTime'             => time(),//'修改日期',
//                    ];
//                    // 添加客户往来余额明细，修改客户往来余额
//                    $result = $this->objMCustomerBalanceDetail->addCustomerBalanceDetail($detailData);
//                    if (!$result->isSuccess()) {
//                        $this->objDExpenseSingle->rollBack();
//                        return ResultWrapper::fail($result->getData(), $result->getErrorCode());
//                    }
//
//                    // 编辑客户往来余额
//                    $changedMoney = $dbResult['payType'] ==StatusCode::$standard ? -1 * $dbResult['totalActualAmount'] : abs($dbResult['totalActualAmount']);
//                    $result = $this->objMCustomerBalance->addCustomerBalance($dbResult['currentUnitId'], $changedMoney);
//                    if (!$result->isSuccess()) {
//                        $this->objDExpenseSingle->rollBack();
//                        return ResultWrapper::fail($result->getData(), $result->getErrorCode());
//                    }
//                }
//                break;
//            case StatusCode::$standard:// 供应商
//                $supplierMoney = $this->objMSupplierBalance->getSupplierBalance($dbResult['currentUnitId']);
//                if($dbResult['payType'] == StatusCode::$standard){//5收入
//                    $detailData = [
//                        'supplierId'       => $dbResult['currentUnitId'],
//                        'receiptTime'      => $dbResult['createTime'],//'单据日期',
//                        'no'               => $dbResult['no'],//'单据编号',
//                        'financeType'      => '费用单',//'财务类型名称',
//                        'financeTypeId'    => '',//'财务类型id',
//                        'sourceNo'         => $dbResult['no'],//'源订单销货号',
//                        'salesAmount'      => $dbResult['totalCollectionAmount'],
//                        'discountMoney'    => $dbResult['totalPreferentialAmount'],// '优惠金额',
//                        'supplierAmount'   => $dbResult['totalActualAmount'],//供应商承担金额
//                        'shouldPayAmount'  => $dbResult['totalActualAmount'],
//                        'actualPaidAmount' => $dbResult['totalActualAmount'],//'实际付款金额',
//                        'shouldPayBalance' => bcsub($supplierMoney,$dbResult['totalMoney'],2), //'应付款余额' 当前余额 - 付款金额
//                        'remark'           => '付款单审核通过，本次付给供应商'.$dbResult['totalActualAmount'].'元,优惠'. $dbResult['totalPreferentialAmount'] .'元',//'备注',
//                        'createTime'       => time(),//'创建日期',
//                        'updateTime'       => time(),//'修改日期',
//                    ];
//
//                    //供应商余额明细
//                    $result = $this->objMSupplierBalanceDetail->addSupplierBalanceDetail($detailData);
//                    if (!$result->isSuccess()) {
//                        $this->objDExpenseSingle->rollBack();
//                        return ResultWrapper::fail($result->getData(), $result->getErrorCode());
//                    }
//
//                    //供应商余额
//                    $result = $this->objMSupplierBalance->addSupplierBalance($dbResult['currentUnitId'], -1*$dbResult['totalActualAmount']);
//                    if (!$result->isSuccess()) {
//                        $this->objDExpenseSingle->rollBack();
//                        return ResultWrapper::fail($result->getData(), $result->getErrorCode());
//                    }
//                }else{
//                    $detailData = [
//                        'supplierId'       => $dbResult['currentUnitId'],
//                        'receiptTime'      => $dbResult['createTime'],//'单据日期',
//                        'no'               => $dbResult['no'],//'单据编号',
//                        'financeType'      => '费用单',//'财务类型名称',
//                        'financeTypeId'    => '',//'财务类型id',
//                        'sourceNo'         => $dbResult['no'],//'源订单销货号',
//                        'salesAmount'      => $dbResult['totalCollectionAmount'],
//                        'discountMoney'    => $dbResult['totalPreferentialAmount'],// '优惠金额',
//                        'supplierAmount'   => $dbResult['totalActualAmount'],//供应商承担金额
//                        'shouldPayAmount'  => $dbResult['totalActualAmount'],
//                        'actualPaidAmount' => $dbResult['totalActualAmount'],//'实际付款金额',
//                        'shouldPayBalance' => bcadd($supplierMoney,$dbResult['totalCollectionAmount'],2), //'应付款余额' 当前余额 - 付款金额
//                        'remark'           => '付款单审核通过，本次付给供应商'.$dbResult['totalActualAmount'].'元,优惠'. $dbResult['totalPreferentialAmount'] .'元',//'备注',
//                        'createTime'       => time(),//'创建日期',
//                        'updateTime'       => time(),//'修改日期',
//                    ];
//
//                    //供应商余额明细
//                    $result = $this->objMSupplierBalanceDetail->addSupplierBalanceDetail($detailData);
//                    if (!$result->isSuccess()) {
//                        $this->objDExpenseSingle->rollBack();
//                        return ResultWrapper::fail($result->getData(), $result->getErrorCode());
//                    }
//
//                    //供应商余额
//                    $result = $this->objMSupplierBalance->addSupplierBalance($dbResult['currentUnitId'], abs($dbResult['totalActualAmount']));
//                    if (!$result->isSuccess()) {
//                        $this->objDExpenseSingle->rollBack();
//                        return ResultWrapper::fail($result->getData(), $result->getErrorCode());
//                    }
//                }
//        }

        if($beginTransactionStatus){
            $this->objDExpenseSingle->commit();
        }

        return ResultWrapper::success($updateDbResult);
    }
}