<?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\DSupplierBalanceDetail;
use JinDouYun\Dao\Finance\DSupplierBalanceDetailIndex;

class MSupplierBalanceDetail extends MBaseModel
{

    private $objDSupplierBalanceDetail;
    private $objDSupplierBalanceDetailIndex;
    private $objMSupplierBalance;
    private $enterpriseId;
    private $userCenterId;

    public function __construct($enterpriseId, $userCenterId)
    {
        $this->userCenterId = $userCenterId;
        $this->enterpriseId = $enterpriseId;
        parent::__construct($enterpriseId, $userCenterId);
        $this->objDSupplierBalanceDetail = new DSupplierBalanceDetail('finance');
        $this->objDSupplierBalanceDetailIndex = new DSupplierBalanceDetailIndex('finance');
        $this->objMSupplierBalance = new MSupplierBalance($enterpriseId, $userCenterId);
        $this->objDSupplierBalanceDetail->setTable('qianniao_supplier_balance_detail_' . $enterpriseId . '_' . date('Y') . '_' . ceil(date('m') / 3));
        $this->objDSupplierBalanceDetailIndex->setTable('qianniao_supplier_balance_detail_index_' . $enterpriseId);
    }

    /**
     * 添加供应商余额明细
     *
     * @param array $params 供应商余额明细数据
     *
     * @return ResultWrapper
     */
    public function addSupplierBalanceDetail($params)
    {
        $beginTransactionStatus =  $this->objDSupplierBalanceDetail->beginTransaction();
        $SupplierBalanceDetailId = $this->objDSupplierBalanceDetail->insert($params);

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

        //添加索引表
        $indexData = [
            'detailId'    => $SupplierBalanceDetailId,
            'supplierId'  => $params['supplierId'],
            'receiptTime' => $params['receiptTime'],
            'no'          => $params['no'],
            'createTime'  => $params['createTime'],
            'updateTime'  => $params['updateTime'],
        ];
        $result = $this->objDSupplierBalanceDetailIndex->insert($indexData);

        if ($result === false) {
            $this->objDSupplierBalanceDetail->rollBack();
            return ResultWrapper::fail($this->objDSupplierBalanceDetailIndex->error(), ErrorCode::$dberror);
        }
        if($beginTransactionStatus){
            $this->objDSupplierBalanceDetail->commit();
        }
        return ResultWrapper::success($SupplierBalanceDetailId);

    }

    /**
     * 获取所有供应商余额明细数据
     * @param array $selectParams 过滤条件
     * @return ResultWrapper
     * @throws \Exception
     */
    public function getAllSupplierBalanceDetail($selectParams,$export = 0)
    {
        $limit = $selectParams['limit'];
        unset($selectParams['limit']);
        $offset = $selectParams['offset'];
        unset($selectParams['offset']);
        $sort = $selectParams['sort'];
        unset($selectParams['sort']);
        if($export){
            $limit = null;
            $offset = null;
        }
        if (!in_array($sort,['ASC','DESC'])){
            return ResultWrapper::fail('sort参数异常',ErrorCode::$paramError);
        }

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

        $where = "supplierId = " . $supplierId . ' AND createTime>=' . $start . ' AND createTime<=' . $end;
        $supplierBalanceDetailIndexResult = $this->objDSupplierBalanceDetailIndex->select($where, '*', 'createTime asc', $limit, $offset);

        $tableSuffix = [];
        foreach ($supplierBalanceDetailIndexResult as $supplierBalanceDetailIndex) {
            $k = date('Y', $supplierBalanceDetailIndex['createTime']) . '_' . ceil(date('m', $supplierBalanceDetailIndex['createTime']) / 3);
            $tableSuffix[$k][] = $supplierBalanceDetailIndex['detailId'];
        }

        $detailResult = [];
        $orderSort = 'createTime '.$sort;
        foreach ($tableSuffix as $suffix => $detailIds) {
            $this->objDSupplierBalanceDetail->setTable('qianniao_supplier_balance_detail_' . $this->enterpriseId . '_' . $suffix);
            $dbResult = $this->objDSupplierBalanceDetail->select($detailIds, '*', $orderSort);
            if ($dbResult === false) {
                return ResultWrapper::fail($this->objDSupplierBalanceDetail->error(), ErrorCode::$dberror);
            }
            //如果是采购付款，采购预付 ，
            foreach ($dbResult as $v => $k){
                $dbResult[$v]['salesAmount'] = $k['financeType'] == '采购付款' || $k['financeType'] == '采购预付' ? '--' : $k['salesAmount'];
                $dbResult[$v]['discountMoney'] = $k['financeType'] == '采购付款' || $k['financeType'] == '采购预付'  ? '--' : $k['discountMoney'];
                $dbResult[$v]['shouldPayAmount'] = $k['financeType'] == '采购付款' || $k['financeType'] == '采购预付'  ? '--' : $k['shouldPayAmount'];
            }
            $detailResult = array_merge($detailResult, $dbResult);
        }

        $total = $this->objDSupplierBalanceDetailIndex->count($where);

        //期初余额
        $start = $this->objMSupplierBalance->getShouldPayMoneyByTime($start, $supplierId);
        //期末余额
        $end = $this->objMSupplierBalance->getShouldPayMoneyByTime($end, $supplierId);

        //应付款余额总计
        $shouldPayTotal = $this->objMSupplierBalance->getSupplierBalance($supplierId);
        //实际付款金额总计
        $actualPayTotal = $this->objMSupplierBalance->getSupplierBalance($supplierId, 'totalReceiveMoney');

        $return = [
            'data'           => $detailResult,
            'total'          => ($total) ? intval($total) : 0,
            'openingBalance' => $start ? $start : 0,
            'endingBalance'  => $end ? $end : 0,
            'shouldPayTotal' => $shouldPayTotal ? $shouldPayTotal : 0,
            'actualPayTotal' => $actualPayTotal ? $actualPayTotal : 0,
        ];
        //导出
        if($export){
            self::exportSupplierBalanceDetail($detailResult);
            exit;
        }
        return ResultWrapper::success($return);
    }
    
    /**
     * 导出方法
     * @param $result
     * @return void
     * @throws Exception
     */
    public function exportSupplierBalanceDetail($result)
    {
        //导出到本地
        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 ($result as $v) {                           //循环数据
            $num++;
            if ($num == $limit) {
                ob_flush();         //释放内存
                flush();
            }
            $rows['receiptTime'] = isset($v['receiptTime']) ? date("Y-m-d",$v['receiptTime']) : '';//订单日期
            $rows['no'] = isset($v['no']) ? $v['no'] : '';//订单编号
            $rows['sourceNo'] = isset($v['sourceNo']) ? $v['sourceNo'] : '';//原订单销货号
            $rows['financeType'] = isset($v['financeType']) ? $v['financeType'] : '';//业务类别
            $rows['salesAmount'] = isset($v['salesAmount']) ? $v['salesAmount'] : '';//采购金额
            $rows['discountMoney'] = isset($v['discountMoney']) ? $v['discountMoney'] : '';//优惠金额
            $rows['shouldPayAmount'] = isset($v['shouldPayAmount']) ? $v['shouldPayAmount'] : '';//应付金额
            $rows['actualPaidAmount'] = isset($v['actualPaidAmount']) ? $v['actualPaidAmount'] : '';//实付金额
            $rows['shouldPayBalance'] = isset($v['shouldPayBalance']) ? $v['shouldPayBalance'] : '';//应付余额
            $rows['remark'] = isset($v['remark']) ? $v['remark'] : '';//备注
    
            foreach ($rows as $kk => $vv) {
                $rs[$kk] = mb_convert_encoding($vv, 'GBK', 'utf-8');  //转译编码
            }
            fputcsv($fp, $rs);
            
            $rows = [];
        }
    }

}