<?php

namespace common\models\forms;

use common\helpers\Cache;
use common\helpers\Date;
use common\helpers\user\Balance;
use common\helpers\user\Info;
use common\helpers\user\Status;
use common\components\Model;
use common\helpers\Form;
use common\models\InvoiceAudit;
use common\models\Period;
use common\models\RegInfoAudit;
use common\models\User;
use common\models\UserInfo;
use common\models\Withdraw;
use yii\base\Exception;

/**
 * 点位绑定表单
 */
class InvoiceAuditForm extends Model {
    public $id;
    public $withdrawId;
    public $invoiceCode;
    public $invoiceNum;
    public $invoiceDate;
    public $amount;
    public $taxRate;
    public $purchaserName;
    public $purchaserRegisterNum;
    public $purchaserAddress;
    public $purchaserBank;
    public $sellerName;
    public $sellerRegisterNum;
    public $sellerAddress;
    public $sellerBank;
    public $itemName;
    public $invoiceRemark;
    public $createRemark;
    public $auditStatus;

    private $_uid;
    private $_model;
    private $_withdrawModel;

    /**
     * @inheritdoc
     */
    public function rules() {
        return [
            [['id', 'withdrawId', 'invoiceCode', 'invoiceNum', 'invoiceDate', 'amount', 'taxRate', 'purchaserName', 'purchaserRegisterNum', 'purchaserAddress', 'purchaserBank', 'sellerName', 'sellerRegisterNum', 'sellerAddress', 'sellerBank', 'itemName', 'invoiceRemark', 'createRemark'], 'trim'],
            [['id', 'withdrawId', 'invoiceCode', 'invoiceNum', 'invoiceDate', 'amount', 'purchaserName', 'purchaserRegisterNum', 'purchaserAddress', 'purchaserBank', 'sellerName', 'sellerRegisterNum', 'sellerAddress', 'sellerBank', 'itemName'], 'required'],
            [['id'], 'initModel'],
            [['withdrawId'], 'initWithdrawModel'],
            [['itemName'], 'isItemName'],
            //[['invoiceNum'], 'isInvoiceNum'],
            [['auditStatus'], 'isAuditStatus'],

        ];
    }

    /**
     * 指定校验场景
     * @return array
     */
    public function scenarios() {
        $parentScenarios = parent::scenarios();
        $customScenarios = [
            'addByAdmin' => ['withdrawId', 'invoiceCode', 'invoiceNum', 'invoiceDate', 'amount', 'taxRate', 'purchaserName', 'purchaserRegisterNum', 'purchaserAddress', 'purchaserBank', 'sellerName', 'sellerRegisterNum', 'sellerAddress', 'sellerBank', 'itemName', 'invoiceRemark', 'createRemark'],
            'editByAdmin' => ['id', 'withdrawId', 'invoiceCode', 'invoiceNum', 'invoiceDate', 'amount', 'taxRate', 'purchaserName', 'purchaserRegisterNum', 'purchaserAddress', 'purchaserBank', 'sellerName', 'sellerRegisterNum', 'sellerAddress', 'sellerBank', 'itemName', 'invoiceRemark', 'createRemark'],
            'audit' => ['id', 'withdrawId', 'invoiceCode', 'invoiceNum', 'invoiceDate', 'amount', 'taxRate', 'purchaserName', 'purchaserRegisterNum', 'purchaserAddress', 'purchaserBank', 'sellerName', 'sellerRegisterNum', 'sellerAddress', 'sellerBank', 'itemName', 'invoiceRemark', 'createRemark', 'auditStatus'],
        ];
        return array_merge($parentScenarios, $customScenarios);
    }

    public function attributeLabels() {
        return [
            'id' => '发票id',
            'withdrawId' => '提现id',
            'invoiceCode' => '发票代码',
            'invoiceNum' => '发票号码',
            'invoiceDate' => '开票日期',
            'amount' => '提现金额',
            'taxRate' => '税率',
            'purchaserName' => '购买方名称',
            'purchaserRegisterNum' => '购买方纳税人识别号',
            'purchaserAddress' => '购买方地址电话',
            'purchaserBank' => '购买方开户行及账号',
            'sellerName' => '销售方名称',
            'sellerRegisterNum' => '销售方纳税人识别号',
            'sellerAddress' => '销售方地址电话',
            'sellerBank' => '销售方地址电话',
            'itemName' => '货物或应税劳务服务名称',
            'invoiceRemark' => '发票备注',
            'createRemark' => '备注',
        ];
    }

    /**
     * 初始化model
     * @param $attributes
     */
    public function initModel($attributes) {
        $this->_model = InvoiceAudit::findOne(['ID' => $this->id]);
        if (!$this->_model) {
            $this->addError($attributes, 'The data does not exist'); // 数据不存在
        }
        if ($this->_model->AUDIT_STATUS != \Yii::$app->params['auditStatus']['un']['value']) {
            $this->addError($attributes, '本数据已经被处理过了');
        }
    }

    /**
     * 初始化withdrawModel
     * @param $attributes
     */
    public function initWithdrawModel($attributes) {
        $this->_withdrawModel = Withdraw::findOne(['ID' => $this->withdrawId]);
        if (!$this->_withdrawModel) {
            $this->addError($attributes, 'The data does not exist'); // 数据不存在
        }
        if ($this->_withdrawModel->AUDIT_STATUS != Withdraw::STATUS_APPLIED) {
            $this->addError($attributes, '已审核的提现无法修改发票信息');
        }
        if ($this->amount != $this->_withdrawModel->AMOUNT) {
            $this->addError($attributes, '上传发票金额与提现金额不一致');
        }
        if (InvoiceAudit::find()->where('INVOICE_NUM=:INVOICE_NUM AND WITHDRAW_ID!=:WITHDRAW_ID AND AUDIT_STATUS=:AUDIT_STATUS', [':INVOICE_NUM' => $this->invoiceNum, ':WITHDRAW_ID' => $this->withdrawId, ':AUDIT_STATUS' => \Yii::$app->params['auditStatus']['true']['value']])->exists()) {
            $this->addError($attributes, '该发票的发票号码【'.$this->invoiceNum.'】已被使用');
        }
    }

    /**
     * 审核状态是否正确
     * @param $attributes
     */
    public function isAuditStatus($attributes) {
        if (!array_key_exists($this->auditStatus, \Yii::$app->params['auditStatus'])) {
            $this->addError($attributes, '无效的审核状态');
        }
    }

    /**
     * 货物或应税劳务服务名称是否正确
     * @param $attributes
     */
    public function isItemName($attributes) {
        $configName = Cache::getSystemConfig()['invoiceItemName']['VALUE'];
        if ($this->itemName != $configName) {
            $this->addError($attributes, '上传发票中货物或应税劳务服务名称与后台预置信息【' . $configName . '】不一致');
        }
    }

    /**
     * 添加
     * @return RegInfoAudit|null
     * @throws \yii\db\Exception
     */
    public function addByAdmin() {
        if (!$this->validate()) {
            return null;
        }
        $transaction = \Yii::$app->db->beginTransaction();
        try {
            // 添加会员合作点位
            $invoiceModel = new InvoiceAudit();
            $invoiceModel->USER_ID = $this->_withdrawModel->USER_ID;
            $invoiceModel->WITHDRAW_ID = $this->withdrawId;
            $invoiceModel->INVOICE_CODE = $this->invoiceCode;
            $invoiceModel->INVOICE_NUM = $this->invoiceNum;
            $invoiceModel->INVOICE_DATE = $this->invoiceDate ? Date::convert(Date::utcToTime($this->invoiceDate), 'Y年m月d日') : 0;
            $invoiceModel->AMOUNT = $this->amount;
            $invoiceModel->TAX_RATE = $this->taxRate;
            $invoiceModel->PURCHASER_NAME = $this->purchaserName;
            $invoiceModel->PURCHASER_REGISTER_NUM = $this->purchaserRegisterNum;
            $invoiceModel->PURCHASER_ADDRESS = $this->purchaserAddress;
            $invoiceModel->PURCHASER_BANK = $this->purchaserBank;
            $invoiceModel->SELLER_NAME = $this->sellerName;
            $invoiceModel->SELLER_REGISTER_NUM = $this->sellerRegisterNum;
            $invoiceModel->SELLER_ADDRESS = $this->sellerAddress;
            $invoiceModel->SELLER_BANK = $this->sellerBank;
            $invoiceModel->ITEM_NAME = $this->itemName;
            $invoiceModel->INVOICE_REMARK = $this->invoiceRemark;
            $invoiceModel->CREATE_REMARK = $this->createRemark;
            $invoiceModel->CREATE_ADMIN = \Yii::$app->user->id;
            $invoiceModel->CREATED_AT = Date::nowTime();
            if (!$invoiceModel->save()) {
                throw new Exception(Form::formatErrorsForApi($invoiceModel->getErrors()));
            }
            //写入提现表
            $withdrawModel = $this->_withdrawModel;
            $withdrawModel->INVOICE_ID = $invoiceModel->ID;
            $withdrawModel->UPDATE_ADMIN = \Yii::$app->user->id;
            $withdrawModel->UPDATED_AT = Date::nowTime();
            if ($withdrawModel->AUDIT_STATUS == Withdraw::STATUS_APPLIED) {
//                $withdrawModel->AUDIT_STATUS = Withdraw::STATUS_INVOICED;
                $withdrawModel->AUDIT_ADMIN = \Yii::$app->user->id;
                $withdrawModel->AUDITED_AT = Date::nowTime();
            }
            if (!$withdrawModel->save()) {
                throw new Exception(Form::formatErrorsForApi($withdrawModel->getErrors()));
            }
            $transaction->commit();
        } catch (Exception $e) {
            $transaction->rollBack();
            $this->addError('addByAdmin', $e->getMessage());
            return null;
        }
        return $invoiceModel;
    }

    /**
     * 修改操作
     * @return null
     * @throws \yii\db\Exception
     */
    public function editByAdmin() {
        if (!$this->validate()) {
            return null;
        }
        $transaction = \Yii::$app->db->beginTransaction();
        try {
            $invoiceModel = $this->_model;
            $invoiceModel->USER_ID = $this->_withdrawModel->USER_ID;
            $invoiceModel->WITHDRAW_ID = $this->withdrawId;
            $invoiceModel->INVOICE_CODE = $this->invoiceCode;
            $invoiceModel->INVOICE_NUM = $this->invoiceNum;
            $invoiceModel->INVOICE_DATE = $this->invoiceDate ? Date::convert(Date::utcToTime($this->invoiceDate), 'Y年m月d日') : 0;
            $invoiceModel->AMOUNT = $this->amount;
            $invoiceModel->TAX_RATE = $this->taxRate;
            $invoiceModel->PURCHASER_NAME = $this->purchaserName;
            $invoiceModel->PURCHASER_REGISTER_NUM = $this->purchaserRegisterNum;
            $invoiceModel->PURCHASER_ADDRESS = $this->purchaserAddress;
            $invoiceModel->PURCHASER_BANK = $this->purchaserBank;
            $invoiceModel->SELLER_NAME = $this->sellerName;
            $invoiceModel->SELLER_REGISTER_NUM = $this->sellerRegisterNum;
            $invoiceModel->SELLER_ADDRESS = $this->sellerAddress;
            $invoiceModel->SELLER_BANK = $this->sellerBank;
            $invoiceModel->ITEM_NAME = $this->itemName;
            $invoiceModel->INVOICE_REMARK = $this->invoiceRemark;
            $invoiceModel->CREATE_REMARK = $this->createRemark;
            $invoiceModel->CREATE_ADMIN = \Yii::$app->user->id;
            $invoiceModel->CREATED_AT = Date::nowTime();
            if (!$invoiceModel->save()) {
                throw new Exception(Form::formatErrorsForApi($invoiceModel->getErrors()));
            }
            //写入提现表
            $withdrawModel = $this->_withdrawModel;
            $withdrawModel->INVOICE_ID = $invoiceModel->ID;
            $withdrawModel->UPDATE_ADMIN = \Yii::$app->user->id;
            $withdrawModel->UPDATED_AT = Date::nowTime();
            if ($withdrawModel->AUDIT_STATUS == Withdraw::STATUS_APPLIED) {
//                $withdrawModel->AUDIT_STATUS = Withdraw::STATUS_INVOICED;
                $withdrawModel->AUDIT_ADMIN = \Yii::$app->user->id;
                $withdrawModel->AUDITED_AT = Date::nowTime();
            }
            if (!$withdrawModel->save()) {
                throw new Exception(Form::formatErrorsForApi($withdrawModel->getErrors()));
            }
            $transaction->commit();
        } catch (Exception $e) {
            $transaction->rollBack();
            $this->addError('editByAdmin', $e->getMessage());
            return null;
        }
        return $invoiceModel;
    }

    /**
     * 审核操作
     * @return null
     * @throws \yii\db\Exception
     */
    public function audit() {
        if (!$this->validate()) {
            return null;
        }
        $transaction = \Yii::$app->db->beginTransaction();
        try {
            $invoiceModel = $this->_model;
            $withdrawModel = $this->_withdrawModel;
            if ($this->auditStatus == 'reject') {
                $invoiceModel->AUDIT_STATUS = \Yii::$app->params['auditStatus']['reject']['value'];

                $withdrawModel->AUDIT_STATUS = Withdraw::STATUS_APPLIED;
                $withdrawModel->AUDIT_ADMIN = \Yii::$app->user->id;
                $withdrawModel->AUDITED_AT = Date::nowTime();
            } elseif ($this->auditStatus == 'true') {
                $invoiceModel->INVOICE_CODE = $this->invoiceCode;
                $invoiceModel->INVOICE_NUM = $this->invoiceNum;
                $invoiceModel->INVOICE_DATE = $this->invoiceDate ? Date::convert(Date::utcToTime($this->invoiceDate), 'Y年m月d日') : 0;
                $invoiceModel->AMOUNT = $this->amount;
                $invoiceModel->TAX_RATE = $this->taxRate;
                $invoiceModel->PURCHASER_NAME = $this->purchaserName;
                $invoiceModel->PURCHASER_REGISTER_NUM = $this->purchaserRegisterNum;
                $invoiceModel->PURCHASER_ADDRESS = $this->purchaserAddress;
                $invoiceModel->PURCHASER_BANK = $this->purchaserBank;
                $invoiceModel->SELLER_NAME = $this->sellerName;
                $invoiceModel->SELLER_REGISTER_NUM = $this->sellerRegisterNum;
                $invoiceModel->SELLER_ADDRESS = $this->sellerAddress;
                $invoiceModel->SELLER_BANK = $this->sellerBank;
                $invoiceModel->ITEM_NAME = $this->itemName;
                $invoiceModel->INVOICE_REMARK = $this->invoiceRemark;
                $invoiceModel->AUDIT_STATUS = \Yii::$app->params['auditStatus']['true']['value'];
                //能否自动流转
                $userInfo = UserInfo::findOneAsArray('USER_ID=:USER_ID', [':USER_ID' => $withdrawModel->USER_ID], 'REG_TYPE,SHOULD_REG_TYPE');
                if ($userInfo['REG_TYPE'] == $userInfo['SHOULD_REG_TYPE']) {
                    $withdrawModel->AUDIT_STATUS = Withdraw::STATUS_AUDITED;
                    $withdrawModel->AUDIT_ADMIN = \Yii::$app->user->id;
                    $withdrawModel->AUDITED_AT = Date::nowTime();
                }
            }
            $invoiceModel->AUDIT_ADMIN = \Yii::$app->user->id;
            $invoiceModel->CREATE_REMARK = $this->createRemark;
            $invoiceModel->AUDITED_AT = Date::nowTime();

            if (!$invoiceModel->save()) {
                throw new Exception(Form::formatErrorsForApi($invoiceModel->getErrors()));
            }
            if (!$withdrawModel->save()) {
                throw new Exception(Form::formatErrorsForApi($withdrawModel->getErrors()));
            }
            $transaction->commit();
        } catch (Exception $e) {
            $transaction->rollBack();
            $this->addError('audit', $e->getMessage());
            return null;
        }
        return $invoiceModel;
    }

    /**
     * 删除
     * @param $selected
     * @throws Exception
     */
    public static function delete($selected) {
        foreach ($selected as $select) {
            $withdraw = Withdraw::findOneAsArray('INVOICE_ID=:INVOICE_ID', [':INVOICE_ID' => $select], 'SN,AUDIT_STATUS');
            if ($withdraw['AUDIT_STATUS'] != Withdraw::STATUS_APPLIED) {
                throw new Exception('发票所属提现流水号' . $withdraw['SN'] . '非 未传发票/待审核 状态，无法删除');
            }
        }
    }
}
