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

namespace JinDouYun\Model\Finance;

use JinDouYun\Dao\Finance\DPaid;
use JinDouYun\Dao\Finance\DPaidOffset;
use JinDouYun\Model\MBaseModel;
use Mall\Framework\Core\ErrorCode;
use Mall\Framework\Core\StatusCode;
use Mall\Framework\Core\ResultWrapper;

use JinDouYun\Dao\Finance\DPay;
use JinDouYun\Dao\Finance\DPayReceiptIndex;

use JinDouYun\Model\Finance\MSupplierBalanceDetail;
use JinDouYun\Model\Finance\MSupplierBalance;

class MPay extends MBaseModel
{

    private $objDPay;
    private $objDPaid;
    private $objDPaidOffset;
    private $objDPayReceiptIndex;
    private $objMSupplierBalanceDetail;
    private $objMSupplierBalance;
    private $enterpriseId;
    private $userCenterId;

    public function __construct($enterpriseId, $userCenterId)
    {
        parent::__construct($enterpriseId, $userCenterId);
        $this->enterpriseId = $enterpriseId;
        $this->userCenterId = $userCenterId;
        $this->objMSupplierBalanceDetail = new MSupplierBalanceDetail($enterpriseId, $userCenterId);
        $this->objMSupplierBalance = new MSupplierBalance($enterpriseId, $userCenterId);
        $this->objDPay = new DPay('finance');
        $this->objDPayReceiptIndex = new DPayReceiptIndex('finance');
        $this->objDPaid = new DPaid('finance');
        $this->objDPaidOffset = new DPaidOffset('finance');
        $this->objDPaidOffset->setTable('qianniao_paid_offset_'.$enterpriseId);
        $this->objDPay->setTable('qianniao_pay_receipt_' . $enterpriseId . '_' . date('Y') . '_' . ceil(date('m') / 3));
        $this->objDPayReceiptIndex->setTable('qianniao_pay_receipt_index_' . $enterpriseId);

        //$this->objDPay->setSearchIndex('should_pay_receipt_search')->setType('should_pay_receipt');
    }

    /**
     * 临时财务脚本解决索引表id重复问题
     */
    public function tmp1()
    {
        // 查询应付索引表
        $result = $this->objDPayReceiptIndex->select('id > 273');
        if ($result === false) {
            return ResultWrapper::fail($this->objDPayReceiptIndex->error(), ErrorCode::$dberror);
        }

        foreach ($result as $key => $value){
            $suffix = date('Y', $value['createTime']) . '_' . ceil(date('m', $value['createTime']) / 3);
            $this->objDPay->setTable('qianniao_pay_receipt_' . $this->enterpriseId . '_' . $suffix);
            echo 'qianniao_pay_receipt_' . $this->enterpriseId . '_' . $suffix.PHP_EOL;
            $dbResult = $this->objDPay->get($value['payReceiptId']);
            if ($dbResult === false) {
                return ResultWrapper::fail($this->objDPay->error(), ErrorCode::$dberror);
            }
            if(empty($dbResult)){
                return ResultWrapper::fail($value['payReceiptId'].'对应应付不存在', ErrorCode::$contentNotExists);
            }

            // 把应付单id改成索引表的自增id
            $dbResult = $this->objDPay->update(['id'=>$value['id']], $value['payReceiptId']);
            if ($dbResult === false) {
                return ResultWrapper::fail($this->objDPay->error(), ErrorCode::$dberror);
            }

            // 把索引表应付id改成空
            $result = $this->objDPayReceiptIndex->update(['payReceiptId'=>0], $value['id']);
            if ($result === false) {
                return ResultWrapper::fail($this->objDPayReceiptIndex->error(), ErrorCode::$dberror);
            }

            echo $value['id'].'操作完成'.PHP_EOL;
        }

        return ResultWrapper::success('全部更新完成');
    }

    /**
     * 添加应付单
     *
     * @param array $params 应付单数据
     *
     * @return ResultWrapper
     */
    public function addPay($params)
    {
        $this->objDPay->beginTransaction();
        // 生成编号
        $dbResult =  $this->objDPay->get('createTime >='.strtotime(date('Ymd'.'0:0:0')), 'no', 'createTime desc');
        if ($dbResult === false) {
            return ResultWrapper::fail($this->objDPay->error(), ErrorCode::$dberror);
        }
        if(empty($dbResult)){
            $params['no'] = createSerialNumberByDate('');
        }else{
            $params['no'] =createSerialNumberByDate($dbResult['no']);
        }

        //索引表数据
        $indexData = [
            'payReceiptId'  => 0,
            'customerId'    => $params['customerId'],
            'sourceNo'      => $params['sourceNo'],
            'auditStatus'   => $params['auditStatus'],
            'offsetStatus'   => ($params['PayMoney']<0) ? 5 : 4,
            'financeTypeId' => $params['financeTypeId'],
            'financeType'   => $params['financeType'],
            'shopId'        => $params['shopId'],
            'createTime'    => $params['createTime'],
            'updateTime'    => $params['updateTime'],
        ];
        $payReceiptId = $this->objDPayReceiptIndex->insert($indexData);
        if ($payReceiptId === false) {
            $this->objDPay->rollBack();
            return ResultWrapper::fail($this->objDPayReceiptIndex->error(), ErrorCode::$dberror);
        }

        $params['offsetStatus'] = ($params['PayMoney']<0) ? 5 : 4;
        $params['id'] = $payReceiptId;
        $payId = $this->objDPay->insert($params);
        if ($payId === false) {
            $this->objDPay->rollBack();
            return ResultWrapper::fail($this->objDPay->error(), ErrorCode::$dberror);
        }

        $this->objDPay->commit();

//        $_id = self::createEsDocumentId($payId, $params['createTime']);
//        $esData = $params;
//        $esData['id'] = $payId;
//        $esData['enterpriseId'] = $this->enterpriseId;
//        $result = $this->objDPay->addUpSearchIndexDocument($esData, $_id);
//        if (isset($result['_shards']) && isset($result['_shards']['successful']) && $result['_shards']['successful'] == 1) {
//            //echo "es操作成功";die;
//        }else {
//            file_put_contents('/www/wwwroot/logs/api.junhailan.com/elasticsearch.log',date('Y-m-d H:i:s').'生成应付单es错误,错误原因'.var_export($result,true).PHP_EOL,FILE_APPEND);
//        }

        return ResultWrapper::success($payId);
    }

    private function createEsDocumentId($payId, $time)
    {
        $t = date('Y', $time) . '_' . ceil(date('m', $time) / 3);
        return 'EnterpriseId_' . $this->enterpriseId . '_' . $t .'_payId_' . $payId;
    }

    public function getPayInfo($params)
    {
        $suffix = date('Y', $params['createTime']) . '_' . ceil(date('m', $params['createTime']) / 3);
        $this->objDPay->setTable('qianniao_pay_receipt_' . $this->enterpriseId . '_' . $suffix);
        unset($params['createTime']);

        $dbResult = $this->objDPay->get($params);
        if ($dbResult === false) {
            return ResultWrapper::fail($this->objDPay->error(), ErrorCode::$dberror);
        }
        if(!empty($dbResult)){
            //渲染前缀
            $dbResult['no'] = StatusCode::$noPrefix[18] . '-' . $dbResult['no'];
            $dbResult['purchaseNo'] = StatusCode::$noPrefix[2] . '-' . $dbResult['purchaseNo'];
            $dbResult['supplierCode'] = createCode(StatusCode::$code['supplier']['prefix'], $dbResult['supplierId'], StatusCode::$code['supplier']['length']);
        }
        return ResultWrapper::success($dbResult);

    }

    /**
     * 修改应付单核销状态
     */
    public function updateOffsetStatus($id,$offsetMoney,$createTime)
    {
        $suffix = date('Y', $createTime) . '_' . ceil(date('m', $createTime) / 3);
        $this->objDPay->setTable('qianniao_pay_receipt_' . $this->enterpriseId . '_' . $suffix);
        $shouldPayData = $this->objDPay->get($id);
        if ($shouldPayData === false) {
            $this->objDPay->rollBack();
            return ResultWrapper::fail($this->objDPay->error(), ErrorCode::$dberror);
        }
        if( empty($shouldPayData) ){
            return ResultWrapper::fail('要审核的单据不存在', ErrorCode::$contentNotExists);
        }

//        $notOffsetMoney = bcsub($shouldPayData['payMoney'], $offsetMoney, 4);
        $updateData = [
            'offsetMoney'    => bcadd($shouldPayData['offsetMoney'],abs($offsetMoney),4),
            'notOffsetMoney' => bcsub($shouldPayData['notOffsetMoney'], abs($offsetMoney),4),
            'offsetStatus'  => StatusCode::$delete
        ];
        switch (true)
        {
            case $updateData['notOffsetMoney'] == 0;
                $updateData['offsetStatus'] = StatusCode::$standard;
                break;
            case $updateData['notOffsetMoney'] == $shouldPayData['payMoney'];
                $updateData['offsetStatus'] = StatusCode::$delete;
                break;
            case $updateData['notOffsetMoney'] > 0 && $updateData['notOffsetMoney'] < $shouldPayData['payMoney'];
                $updateData['offsetStatus'] = StatusCode::$partion;
                break;
        }
        $beginTransactionStatus = $this->objDPay->beginTransaction();
        unset($dbResult);
        $dbResult = $this->objDPay->update($updateData, $id);
        if ($dbResult === false) {
            $this->objDPay->rollBack();
            return ResultWrapper::fail($this->objDPay->error(), ErrorCode::$dberror);
        }

        //修改索引表状态
        unset($dbResult);
        $dbResult = $this->objDPayReceiptIndex->update(['offsetStatus' => $updateData['offsetStatus']], ['payReceiptId' => $id, 'createTime'=>$createTime]);
        if ($dbResult === false) {
            $this->objDPay->rollBack();
            return ResultWrapper::fail($this->objDPayReceiptIndex->error(), ErrorCode::$dberror);
        }
        if($beginTransactionStatus){
            $this->objDPay->commit();
        }

        return ResultWrapper::success($dbResult);
    }

    /**
     * 应付单启用和禁用
     * @param array $params
     * @return ResultWrapper
     * @throws \Exception
     */
    public function updatePayStatus($params)
    {
        $suffix = date('Y', $params['createTime']) . '_' . ceil(date('m', $params['createTime']) / 3);
        $this->objDPay->setTable('qianniao_pay_receipt_' . $this->enterpriseId . '_' . $suffix);

        $shouldPayData = $this->objDPay->get($params['id']);
        if ($shouldPayData === false) {
            return ResultWrapper::fail($this->objDPay->error(), ErrorCode::$dberror);
        }
        if( empty($shouldPayData) ){
            return ResultWrapper::fail('要审核的单据不存在', ErrorCode::$contentNotExists);
        }
        if( $shouldPayData['auditStatus'] == StatusCode::$auditStatus['auditPass'] ){
            return ResultWrapper::fail('该单据已经审核过了', ErrorCode::$notAllowAccess);
        }

        $this->objDPay->beginTransaction();
        $dbResult = $this->objDPay->update(['auditStatus' => StatusCode::$auditStatus['auditPass']], $params['id']);
        if ($dbResult === false) {
            $this->objDPay->rollBack();
            return ResultWrapper::fail($this->objDPay->error(), ErrorCode::$dberror);
        }

        //修改索引表状态
        $dbResult = $this->objDPayReceiptIndex->update(['auditStatus' => StatusCode::$auditStatus['auditPass']], ['payReceiptId' => $params['id']]);
        if ($dbResult === false) {
            $this->objDPay->rollBack();
            return ResultWrapper::fail($this->objDPayReceiptIndex->error(), ErrorCode::$dberror);
        }

        //供应商余额明细
        $supplierMoney = $this->objMSupplierBalance->getSupplierBalance($shouldPayData['supplierId']);
        //自动核销
        $autoOffset = self::autoOffset($supplierMoney,$params['id'],$params['createTime']);
        if (!$autoOffset->isSuccess()) {
            $this->objDPay->rollBack();
            return ResultWrapper::fail($autoOffset->getData(), $autoOffset->getErrorCode());
        }
        $detailData = [
            'supplierId'       => $shouldPayData['supplierId'],
            'receiptTime'      => $shouldPayData['createTime'],//'单据日期',
            'no'               => $shouldPayData['no'],//'单据编号',
            'financeType'      => $shouldPayData['financeType'],//'财务类型名称',
            'financeTypeId'    => $shouldPayData['financeTypeId'],//'财务类型id',
            'sourceNo'         => $shouldPayData['sourceNo'],
            'salesAmount'      => bcadd($shouldPayData['payMoney'], $shouldPayData['discountMoney'], 4),
            'discountMoney'    => $shouldPayData['discountMoney'],// '优惠金额',
            'supplierAmount'   => 0.00,
            'shouldPayAmount'  => $shouldPayData['payMoney'],//实际应付金额
            'actualPaidAmount' => 0.00,
            'shouldPayBalance' => bcadd($supplierMoney,$shouldPayData['payMoney'],2),//应付款余额
            'remark'           => '应付单审核通过,应付供应商'.$shouldPayData['payMoney'].'元',//'备注',
            'createTime'       => time(),//'创建日期',
            'updateTime'       => time(),//'修改日期',
        ];

        //供应商余额明细
        $result = $this->objMSupplierBalanceDetail->addSupplierBalanceDetail($detailData);
        if ($result->isSuccess() === false) {
            $this->objDPay->rollBack();
            return ResultWrapper::fail($result->getData(), $result->getErrorCode());
        }

        //供应商余额
        //$changedMoney = $shouldPayData['payMoney'] > 0 ? $shouldPayData['payMoney'] : -1*$shouldPayData['payMoney'];
        $changedMoney = $shouldPayData['payMoney'];
        $result = $this->objMSupplierBalance->addSupplierBalance($shouldPayData['supplierId'], $changedMoney);
        if ($result->isSuccess() === false) {
            $this->objDPay->rollBack();
            return ResultWrapper::fail($result->getData(), $result->getErrorCode());
        }

        $this->objDPay->commit();

        /*
        $_id = self::createEsDocumentId($params['id'], $params['createTime']);
        $this->objDPay->esupdateTypeFieldVaule(['auditStatus'=>StatusCode::$auditStatus['auditPass']], $_id);
        */
        return ResultWrapper::success($dbResult);

    }

    /**
     * 获取所有应付单数据
     * @param array $selectParams 过滤条件
     * @return ResultWrapper
     * @throws \Exception
     */
    public function getAllPay($selectParams, $isExport = false)
    {
   
            $limit = $selectParams['limit'];
            $offset = $selectParams['offset'];
            unset($selectParams['limit']);
            unset($selectParams['offset']);
            // 导出动作
            if($isExport){
                $limit = 9999;
                $offset = 0;
            }
            $whereSql = '';
            if (isset($selectParams['supplierId']) && !empty($selectParams['supplierId'])) {
                $where = empty($whereSql) ? ' WHERE ' : ' AND ';
                $whereSql .= $where . ' supplierId = ' . $selectParams['supplierId'];
            }
            // 原单据搜索
            if (isset($selectParams['sourceNo']) && !empty($selectParams['sourceNo'])) {
                $tmpNo = explode('-',$selectParams['sourceNo']);
                if(count($tmpNo) == 3){
                    $where = empty($whereSql) ? ' WHERE ' : ' AND ';
                    $whereSql .= $where . ' sourceNo like "%' . $tmpNo[1].'-'.$tmpNo[2].'%"';
                }else{
                    $where = empty($whereSql) ? ' WHERE ' : ' AND ';
                    $whereSql .= $where . ' sourceNo like "%' . $selectParams['sourceNo'].'%"';
                }

            }

            if (isset($selectParams['offsetStatus']) && !empty($selectParams['offsetStatus'])) {
//                if(is_array($selectParams['offsetStatus'])){
                    // 数组转字符串
                    $selectParams['offsetStatus'] = implode(',',$selectParams['offsetStatus']);
                    $where = empty($whereSql) ? ' WHERE ' : ' AND ';
                    $whereSql .= $where . ' offsetStatus in( ' . $selectParams['offsetStatus'].')';
//                }

            }
            if (isset($selectParams['payReceiptIds']) && !empty($selectParams['payReceiptIds'])) {
                $where = empty($whereSql) ? ' WHERE ' : ' AND ';
                $whereSql .= $where . ' payReceiptId in (' . implode(',', $selectParams['payReceiptIds']).')';
            }
            if (isset($selectParams['auditStatus']) && !empty($selectParams['auditStatus'])) {
                $where = empty($whereSql) ? ' WHERE ' : ' AND ';
                $whereSql .= $where . ' auditStatus = ' . $selectParams['auditStatus'];
            }
            if (isset($selectParams['warehouseId']) && !empty($selectParams['warehouseId'])) {
                $where = empty($whereSql) ? ' WHERE ' : ' AND ';
                $whereSql .= $where . ' warehouseId = ' . $selectParams['warehouseId'];
            }
            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'];
            }

            $sql = 'SELECT * FROM ' .$this->objDPayReceiptIndex->get_Table().$whereSql . ' ORDER BY createTime DESC LIMIT ' . $offset . ' , ' . $limit;
            $PayReceiptIndexResult = $this->objDPayReceiptIndex->query($sql);

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

        $tableSuffix = [];
        foreach ($PayReceiptIndexResult as $PayReceiptIndex) {
            $k = date('Y', $PayReceiptIndex['createTime']) . '_' . ceil(date('m', $PayReceiptIndex['createTime']) / 3);
            $tableSuffix[$k][] = $PayReceiptIndex['id'];

        }

        $PayReceiptResult = [];
        foreach ($tableSuffix as $suffix => $payReceiptIds) {
            $this->objDPay->setTable('qianniao_pay_receipt_' . $this->enterpriseId . '_' . $suffix);

            if($isExport){
                $dbResult = $this->objDPay->exportSelect($payReceiptIds, '*', 'createTime desc');
                $tmpArray = [];
                foreach($dbResult as $key => $value){
                    $tmpArray[] = $value;
                }
                $dbResult = $tmpArray;
            }else{
                $dbResult = $this->objDPay->select(['id'=>$payReceiptIds], '*', 'createTime desc');
                //$dbResult = $this->objDPay->select(['supplierId' => $selectParams['supplierId']], '*', 'createTime desc');
            }
            if ($dbResult === false) {
                return ResultWrapper::fail($this->objDPay->error(), ErrorCode::$dberror);
            }

            if(!empty($dbResult)){
                //渲染前缀
                foreach ($dbResult as $key => $value){
                    $dbResult[$key]['no'] = StatusCode::$noPrefix[18] . '-' . $value['no'];
                    $dbResult[$key]['sourceNo'] = StatusCode::$noPrefix[3] . '-' . $value['sourceNo'];
                    $dbResult[$key]['purchaseNo'] = StatusCode::$noPrefix[2] . '-' . $value['purchaseNo'];
                }
                $PayReceiptResult = array_merge($PayReceiptResult, self::format($dbResult));
            }
        }

        

        //$total = $this->objDPayReceiptIndex->count($selectParams);
        $totalSql = 'SELECT COUNT(1) as count FROM ' .$this->objDPayReceiptIndex->get_Table() . $whereSql;
        $dbTotalResult = $this->objDPayReceiptIndex->query($totalSql);
        if ($dbTotalResult === false) {
            return ResultWrapper::fail($this->objDPayReceiptIndex->error(), ErrorCode::$dberror);
        }
        if(empty($dbTotalResult)){
            return ResultWrapper::success([]);
        }

        $return = [
            'data'  => $PayReceiptResult,
            'total' => ($dbTotalResult[0]['count']) ? intval($dbTotalResult[0]['count']) : 0,
        ];
        if($isExport){
            self::export($return['data']);
        }
        return ResultWrapper::success($return);
    }

    /**
     * 审核成功调用(预充余额)
     * @param array $params
     * @return ResultWrapper
     * @throws \Exception
     */

    public function autoOffset($supplierMoney, $payId, $createTime)
    {
        $suffix = date('Y', $createTime) . '_' . ceil(date('m', $createTime) / 3);
        $this->objDPay->setTable('qianniao_pay_receipt_' . $this->enterpriseId . '_' . $suffix);
        $this->objDPaid->setTable('qianniao_paid_' . $this->enterpriseId . '_' . date('Y', $createTime) . '_' . ceil(date('m', $createTime) / 3));
        //根据id查出客户id(查询客户表有无预付款)
        $shouldPayData = $this->objDPay->get($payId);
        if ($shouldPayData === false) {
            return ResultWrapper::fail($this->objDPay->error(), ErrorCode::$dberror);
        }
        if (empty($shouldPayData)) {
            return ResultWrapper::fail('应收单id'.$payId.'数据为空', ErrorCode::$dberror);
        }
        $offsetMoney = 0;
        $notOffsetMoney = 0;
        $offsetStatus = 5;
        if ($supplierMoney < 0 && $shouldPayData['payMoney'] > 0){//说明供应商是预收款进行自动核销
            switch (true)
            {
                case bcsub(abs($supplierMoney),$shouldPayData['payMoney'],4) > 0;//说明预收款完全核销应收单金额
                    $offsetMoney = $shouldPayData['payMoney'];
                    break;
                case bcsub(abs($supplierMoney),$shouldPayData['payMoney'],4) == 0;//说明预收款刚好完全核销
                    $offsetMoney = $shouldPayData['payMoney'];
                    break;
                case bcsub(abs($supplierMoney),$shouldPayData['payMoney'],4) < 0;//说明预收款不够核销应收单金额
                    $offsetMoney = abs($supplierMoney);
                    $notOffsetMoney = bcadd($supplierMoney,$shouldPayData['payMoney'],4);
                    $offsetStatus = StatusCode::$partion;
            }
            //更新应付单核销状态
            $updateOffsetStatus = $this->objDPay->update(['offsetMoney'=>$offsetMoney,'notOffsetMoney'=>$notOffsetMoney,'offsetStatus'=>$offsetStatus],['id'=>$payId]);
            if ($updateOffsetStatus === false) {
                $this->objDPay->rollBack();
                return ResultWrapper::fail($this->objDPay->error(), ErrorCode::$dberror);
            }
            //更新应付单索引表核销状态
            unset($dbResult);
            $dbResult = $this->objDPayReceiptIndex->update(['offsetStatus' => $offsetStatus], ['payReceiptId' => $payId,'createTime'=>$createTime]);
            if ($dbResult === false) {
                $this->objDPay->rollBack();
                return ResultWrapper::fail($this->objDPayReceiptIndex->error(), ErrorCode::$dberror);
            }
            unset($dbResult);
            //查询付款单,找到能核销的
            $dbResult = $this->objDPaid->query('select * from '.$this->objDPaid->get_Table().' where supplierId='.$shouldPayData['supplierId'].' and offsetStatus != '. StatusCode::$standard.' order by createTime asc');
            if ($dbResult === false) {
                return ResultWrapper::fail($this->objDPaid->error(), ErrorCode::$dberror);
            }
            $paidOffsetMoney = $shouldPayData['payMoney'];
            foreach ($dbResult as $key => $value){
                if($paidOffsetMoney<=0){
                    break;
                }
                switch (true){
                    case bcsub($value['notOffsetMoney'],$shouldPayData['payMoney'],2)>0: // 说明收款单能完全核销应收
                        $paidOffset = [
                            'offsetMoney' => bcadd($paidOffsetMoney,$value['offsetMoney'],2),
                            'notOffsetMoney' => bcsub($value['notOffsetMoney'],$paidOffsetMoney,2),
                            'offsetStatus' => StatusCode::$partion,
                        ];
                        $paidOffsetMoney = abs(bcsub($paidOffsetMoney,$paidOffset['offsetMoney'],2));
                        break;
                    case bcsub($value['notOffsetMoney'],$shouldPayData['payMoney'],2) == 0: // 说明收款单能完全核销应收
                        $paidOffset = [
                            'offsetMoney' => $value['totalFinalMoney'],
                            'notOffsetMoney' => 0,
                            'offsetStatus' => StatusCode::$standard,
                        ];
                        $paidOffsetMoney = abs(bcsub($value['totalFinalMoney'],$paidOffset['offsetMoney'],2));
                        break;
                    case bcsub($value['notOffsetMoney'],$shouldPayData['payMoney'],2) < 0: // 说明收款单不能完全核销应收
                        $paidOffset = [
                            'offsetMoney' => $value['totalFinalMoney'],
                            'notOffsetMoney' => 0,
                            'offsetStatus' => StatusCode::$standard,
                        ];
                        $paidOffsetMoney = abs(bcsub($value['totalFinalMoney'],$paidOffset['offsetMoney'],2));
                }
                // 更新核销
                $updatePaidOffset = $this->objDPaid->update($paidOffset,['id'=>$value['id']]);
                if ($updatePaidOffset === false) {
                    $this->objDPay->rollBack();
                    return ResultWrapper::fail($this->objDPaid->error(), ErrorCode::$dberror);
                }
                //记录核销明细
                $updateOffset = [
                    'payReceiptId' => $payId,
                    'paidId' => $value['id'],
                    'offsetMoney' => $offsetMoney,
                    'payCreateTime' => $shouldPayData['createTime'],
//                    'type'  => StatusCode::$delete
                ];
                $result = $this->objDPaidOffset->insert($updateOffset);
                if ($result === false) {
                    $this->objDPay->rollBack();
                    return ResultWrapper::fail($this->objDPaidOffset->error(), ErrorCode::$dberror);
                }


            }


        }
        //报错修改
        //return ResultWrapper::success($dbResult);
        return ResultWrapper::success(null);
    }


    /**
     * 导出方法
     *
     * @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['no'] = $v['no'];
            $rows['sourceNo'] = $v['sourceNo'];
            $rows['supplierName'] = $v['supplierName'];
            $rows['createTime'] = date('Y-m-d H:i:s', $v['createTime']);
            $rows['discountMoney'] = $v['discountMoney'];
            $rows['payMoney'] = $v['payMoney'];
            $rows['shopName'] = $v['shopName'];
            $rows['receiptTypeName'] = $v['receiptTypeId'] ? '采购订单' : '采购退货单';
            $rows['auditStatus'] = StatusCode::$auditStatus[$v['auditStatus']];

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

    public function format($data)
    {
        foreach ($data as $k => $v) {
            $data[$k]['supplierCode'] = createCode(StatusCode::$code['supplier']['prefix'], $v['supplierId'], StatusCode::$code['supplier']['length']);
        }
        return $data;
    }

    //搜索的where条件拼接
    public function setWhere($selectParams)
    {
        $defaultDSL = [
            'from' => $selectParams['offset'],
            'size' => $selectParams['limit'],
            'sort' => [
                'createTime' => [
                    'order' => 'desc'
                ],
            ],
        ];

        $dsl = [];
        $dsl['query']['bool']['must'][] = [
            'term' => ['enterpriseId' => $this->enterpriseId],
        ];

        if (isset($selectParams['keyword'])) {
            if (!empty($selectParams['keyword'])) {
                $dsl['query']['bool']['must'][] = [
                    'multi_match' => [
                        'fields'    => ['no', 'sourceNo', 'customerName'],
                        'query'     => $selectParams['keyword'],
                        'fuzziness' => 'AUTO',
                    ]
                ];
            }
        }

        if (!empty($selectParams['shopId'])) {
            $dsl['query']['bool']['must'][] = [
                'term' => ['shopId' => $selectParams['shopId']],
            ];
        }

        if (!empty($selectParams['start']) && !empty($selectParams['end'])) {
            $dsl['query']['bool']['must'][] = [
                'range' => [
                    'createTime' => [
                        'gte' => $selectParams['start'],
                        'lte' => strtotime(date('Y-m-d',$selectParams['end']).'23:59:59'),
                    ]
                ]
            ];
        } else {
            if (!empty($selectParams['start'])) {
                $dsl['query']['bool']['must'][] = [
                    'range' => [
                        'createTime' => [
                            'gte' => $selectParams['start'],
                        ]
                    ]
                ];
            }

            if (!empty($selectParams['end'])) {
                $dsl['query']['bool']['must'][] = [
                    'range' => [
                        'createTime' => [
                            'lte' => strtotime(date('Y-m-d',$selectParams['end']).'23:59:59'),
                        ]
                    ]
                ];
            }
        }

        if (isset($selectParams['receiptTypeId'])) {
            if (!empty($selectParams['receiptTypeId'])) {
                $dsl['query']['bool']['filter'][] =
                    ['term' => ['receiptTypeId' => $selectParams['receiptTypeId']]];
            }
        }

        if (isset($selectParams['auditStatus'])) {
            if (!empty($selectParams['auditStatus'])) {
                $dsl['query']['bool']['filter'][] =
                    ['term' => ['auditStatus' => $selectParams['auditStatus']]];
            }
        }

        $dsl = array_merge($defaultDSL, $dsl);
        return $dsl;
    }

    public function search($selectParams)
    {
        $is_export = $selectParams['isExport'];
        unset($selectParams['isExport']);

        if($is_export){
            unset($selectParams['limit']);
            unset($selectParams['offset']);
        }

        $dsl = $this->setWhere($selectParams);

        //导出
        if ($is_export) self::exportSearch($dsl);

        $result = $this->objDPay->getSearchQueryDsl($dsl);

        if (isset($result['status']) && $result['status'] == 400) {
            if ($result['error']['reason'] == 'all shards failed') {
                return ResultWrapper::success([
                    'data'  => [],
                    'total' => 0
                ]);
            }
            return ResultWrapper::fail('获取应付数据失败' . $result['error']['reason'], ErrorCode::$apiNotResult);
        }

        if (!isset($result['hits']) || $result['hits']['total'] == 0) {
            return ResultWrapper::success([
                'data'  => [],
                'total' => 0
            ]);
        }
        $total = $result['hits']['total'];
        $dbResult = $result['hits']['hits'];

        $list = [];
        foreach ($dbResult as $key => &$value) {
            $data = [];
            $data = $value['_source'];
            $list[] = $data;
        }

        $return = [
            'data'  => self::format($list),
            'total' => ($total) ? intval($total) : 0,
        ];
        return ResultWrapper::success($return);
    }

    /**
     * 检索导出(ES)
     *
     * @param $dsl
     * @return ResultWrapper
     * @throws \Exception
     */
    private function exportSearch($dsl)
    {
        $result = $this->objDPay->getScrollSearchQueryDsl($dsl);
        if (isset($result['status']) && $result['status'] == 400) {
            return ResultWrapper::fail('获取数据失败' . $result['error']['reason'], ErrorCode::$apiNotResult);
        }

        if (!isset($result['hits']) && $result['hits']['total'] == 0) {
            return ResultWrapper::fail('导出数据为空' . $result['error']['reason'], ErrorCode::$apiNotResult);
        }
        $dbResult = $result['hits']['hits'];

        $list = [];
        foreach ($dbResult as $key => &$value) {
            $list[] = $value['_source'];
        }
        self::export($list);
    }

    /**
     * 查询所有未审核的应付单
     */
    public function getAllAuditingPay()
    {
        $condition = [
            'deleteStatus' => StatusCode::$standard,
            'auditStatus'  => StatusCode::$auditStatus['auditing'],
        ];
        $result = $this->objDPayReceiptIndex->select($condition);
        if ($result === false) {
            return ResultWrapper::fail($this->objDPayReceiptIndex->error(), ErrorCode::$dberror);
        }
        if(empty($result)){
            return ResultWrapper::success([]);
        }
        return ResultWrapper::success($result);
    }
}