<?php
include_once __DIR__."/getData.inc.php"; //类外调用方法
include_once __DIR__."/getBasic.inc.php"; //类外调用方法
class getFinance
{
    private $url = "http://api.waditu.com";
    private $token;
    public $ts_code = '002273.SZ';
    public $httpjsonStr;
    public $finDate;
    public $preFinDate;
    public $param = array();
    private $unitFactor = 100000000;

    function __construct()
    {
        $this->token = TUSHARE_API_TOKEN;
        $this->param['token'] = $this->token;
    }
    /**
     * PHP发送Json对象数据
     *
     * @param $url 请求url
     * @param $jsonStr 发送的json字符串,来自$param转换
     * @return array
     */
    function http_post_json()
    {
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_URL, $this->url);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $this->httpjsonStr);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_HTTPHEADER, array(
                'Content-Type: application/json; charset=utf-8',
                'Content-Length: ' . strlen($this->httpjsonStr)
            )
        );
        $response = curl_exec($ch);
        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        curl_close($ch);

        return array($httpCode, $response);
    }
    /**
     * @param $ts_code
     * @param $finDate 财报日期 如一季报日期：20220331
     */
    function getFinanceData()
    {
        $this->ts_code = ts_code_conv($this->ts_code);
        $balance = $this->getBalance();
        $pre_balance = $this->getPreBalance();
        $income = $this->getIncome();
        $cash = $this->getCashflow();

        $data = array();
        $data['ts_code'] = $this->ts_code;
        $data['period'] = $this->finDate;
        $data['--运营数据--'] = ''; //空行
        $data['现金额-亿'] = $cash['c_cash_equ_end_period'][0] / $this->unitFactor;
        $data['现金占比率'] = $cash['c_cash_equ_end_period'][0] / $balance['total_assets'][0];
        $data['存货-亿'] = $balance['inventories'][0] / $this->unitFactor;
        $data['存货占比率'] = $balance['inventories'][0] / $balance['total_assets'][0];

        #应收账票
        $tmp = 0;
        if ($balance['accounts_receiv'][0]) $tmp += $balance['accounts_receiv'][0];
        if ($balance['notes_receiv'][0]) $tmp += $balance['notes_receiv'][0];
        $data['应收账票-亿'] = $tmp / $this->unitFactor;
        $data['应收账票占比率'] = $tmp / $balance['total_assets'][0];

        #预付款
        $tmp = 0;
        if ($balance['prepayment'][0]) $tmp += $balance['prepayment'][0];
        $data['预付款-亿'] = $tmp / $this->unitFactor;
        #预付占比
        $data['预付款占比率'] = $tmp / $balance['total_assets'][0];

        #运营占比
        $tmp = 0;
        if ($cash['c_cash_equ_end_period'][0]) $tmp += $cash['c_cash_equ_end_period'][0];
        if ($balance['inventories'][0]) $tmp += $balance['inventories'][0];
        if ($balance['accounts_receiv'][0]) $tmp += $balance['accounts_receiv'][0];
        if ($balance['notes_receiv'][0]) $tmp += $balance['notes_receiv'][0];
        if ($balance['prepayment'][0]) $tmp += $balance['prepayment'][0];
        $data['运营占比率'] = $tmp / $balance['total_assets'][0];


        $data['--资产分布--'] = ''; //空行

        if ($balance['fix_assets'][0]) $tmp = $balance['fix_assets'][0] / $this->unitFactor;
        else $tmp = "";
        $data['固定资产-亿'] = $tmp;
        if ($balance['fix_assets'][0]) $tmp = $balance['fix_assets'][0] / $balance['total_assets'][0];
        else  $tmp = "";
        $data['固定资产占比率'] = $tmp;
        $data['无形资产-亿'] = $balance['intan_assets'][0] / $this->unitFactor;
        $data['无形资产占率'] = $balance['intan_assets'][0] / $balance['total_assets'][0];

        $tmp = 0;
        if ($balance['lt_eqt_invest'][0]) $tmp = $balance['lt_eqt_invest'][0];
        $data['股权投资-亿'] = $tmp / $this->unitFactor;
        $data['股权投资占比率'] = $tmp / $balance['total_assets'][0];

        $tmp = 0;
        if ($balance['fix_assets'][0]) $tmp += $balance['fix_assets'][0];
        if ($balance['intan_assets'][0]) $tmp += $balance['intan_assets'][0];
        if ($balance['lt_eqt_invest'][0]) $tmp += $balance['lt_eqt_invest'][0];
        $data['投资占比率'] = $tmp / $balance['total_assets'][0];

        $data['--负债分布--'] = ''; //空行
        $tmp = 0;
        if ($balance['acct_payable'][0]) $tmp += $balance['acct_payable'][0];
        if ($balance['notes_payable'][0]) $tmp += $balance['notes_payable'][0];
        if ($balance['adv_receipts'][0]) $tmp += $balance['adv_receipts'][0];
        #tmp = balance['acct_payable'][0]+balance['notes_payable'][0]+balance['adv_receipts'][0]
        $data['经营负债-亿'] = $tmp / $this->unitFactor;
        $data['经营负债占比率'] = $tmp / $balance['total_assets'][0];
        $tmp = 0;
        if ($balance['st_borr'][0]) $tmp += $balance['st_borr'][0];
        if ($balance['lt_borr'][0]) $tmp += $balance['lt_borr'][0];
        if ($balance['bond_payable'][0]) $tmp += $balance['bond_payable'][0];
        $data['金融负债-亿'] = $tmp / $this->unitFactor;
        $data['金融负债占比率'] = $tmp / $balance['total_assets'][0];
        $zcfz = ($balance['total_cur_liab'][0] + $balance['total_ncl'][0]) / $balance['total_assets'][0];
        $data['资产负债率'] = $zcfz;

        $data['--运营能力--'] = ''; //空行

        $totalDays=$this->getTotalDays();
        @$days_1 = $totalDays / ($income['oper_cost'][0] / (($pre_balance['inventories'][0] + $balance['inventories'][0]) / 2));
        if(is_nan($days_1)) $days_1=0;  //solve  division by zero warning
        //echo "\$days_1:".$days_1;
        $data['存货周转天数'] = $days_1;
        if(!$pre_balance['accounts_receiv'][0])  $days_2 = 0;
        elseif(!$balance['accounts_receiv'][0])  $days_2 = 0;
        else $days_2 = $totalDays/($income['revenue'][0]/(($pre_balance['accounts_receiv'][0]+$balance['accounts_receiv'][0])/2));
        $data['应收周转天数']    = $days_2;
        $data['营业周期']       = $days_1+$days_2;

        $data['--管理费分布--'] = ''; //空行

        $tmp = ($income['revenue'][0]-$income['oper_cost'][0])/$income['revenue'][0];
        $data['毛利额'] = ($income['revenue'][0]-$income['oper_cost'][0])/$this->unitFactor;;
        $data['毛利率'] = $tmp;
        $data['营业税金率'] = $income['biz_tax_surchg'][0]/$income['revenue'][0];
        $data['销售费用率'] = $income['sell_exp'][0]/$income['revenue'][0];
        $data['研发费用率'] = $income['rd_exp'][0]/$income['revenue'][0];
        $data['管理费用率'] = $income['admin_exp'][0]/$income['revenue'][0];
        $data['净利润']    = $income['n_income'][0]/$this->unitFactor;
        $data['净利润率']   = $income['n_income'][0]/$income['revenue'][0];

        $data['--权益及回报率--'] = ''; //空行
        $data['总资产-亿']     = $balance['total_assets'][0]/$this->unitFactor;
        $data['销售收入-亿']   =$income['revenue'][0]/$this->unitFactor;
        $data['总资产周转率'] = $income['revenue'][0]/$balance['total_assets'][0];
        $zchb = $income['n_income'][0]/$balance['total_assets'][0];
        $data['总资产回报率']=$zchb;
        $data['权益乘数']=1/(1-$zcfz);
        $data['净资产回报率']=$zchb*(1/(1-$zcfz));
        foreach ($data as $key=>$val){
            if(is_numeric($val)) {
                if(mb_substr($key,-1,1)=='率') $rt[$key]= round($val*100,2).'%'; //最后一个字为率，则去百分比%
                else $rt[$key]= round($val,2);
            }
            else $rt[$key]=$val;

        }
        return $rt;
    }
    function getFinanceJson()
    {
        $d = $this->getFinanceData();
        return json_encode($d);
    }
    function getBalance()
    {
        $this->param['api_name']='balancesheet';

        ## 资产负债表
        $fields  = 'ts_code';
        $fields .= ',end_date';          #=$finDate
        $fields .= ',total_assets';      #总资产

        $fields .= ',fix_assets';        #固定资产
        $fields .= ',intan_assets';      #无形资产
        $fields .= ',lt_eqt_invest';     #长期股权投资

        $fields .= ',inventories';       #存货
        $fields .= ',accounts_receiv';   #应收账款
        $fields .= ',notes_receiv';      #应收票据
        $fields .= ',prepayment';        #预付款

        $fields .= ',acct_payable';      #应付账款
        $fields .= ',notes_payable';     #应付票据
        $fields .= ',adv_receipts';      #预收款
        $fields .= ',st_borr';           #短期借款
        $fields .= ',lt_borr';           #长期借款
        $fields .= ',bond_payable';      #应付债券
        $fields .= ',total_cur_liab';    #流动负债合计
        $fields .= ',total_ncl';         #非流动负债合计

        $this->param['params'] = array('ts_code' => ts_code_conv($this->ts_code),
            'period'=>$this->finDate);
        $this->param['fields']=$fields;
        $this->httpjsonStr=json_encode($this->param);
        list($returnCode, $returnContent) = $this->http_post_json();

        $arr = json_decode($returnContent,true);
        return  $this->mergeArr($arr['data']);
    }

    /**
     *  #期初的日期: 上一年的年底的数据
     * @return mixed
     */
    function getPreBalance()
    {
        $this->param['api_name']='balancesheet';
        $this->preFinDate=(substr($this->finDate,0,4)-1).'1231'; //上一年的年底日期；
        ## 资产负债表
        $fields  = 'ts_code';
        $fields .= ',end_date';          #=$finDate
        $fields .= ',inventories';       #存货
        $fields .= ',accounts_receiv';   #应收账款
        $fields .= ',notes_receiv';      #应收票据

        $this->param['params'] = array('ts_code' => ts_code_conv($this->ts_code),
            'period'=>$this->preFinDate);
        $this->param['fields']=$fields;

        $this->httpjsonStr=json_encode($this->param);

        list($returnCode, $returnContent) = $this->http_post_json();
        $arr = json_decode($returnContent,true);
        return   $this->mergeArr($arr['data']);
    }

    function getIncome()
    {
        $this->param['api_name']='income';

        #利润表
        #销售毛利率=(营业收入-营业成本)/营业收入   注意非总收入和总成本
        $fields  = 'ts_code';
        $fields .= ',end_date';         #=period
        $fields .= ',revenue';          #营业收入
        $fields .= ',oper_cost';        #营业成本
        $fields .= ',biz_tax_surchg';   #营业税金及附加
        $fields .= ',sell_exp';         #销售费用
        $fields .= ',fin_exp';          #财务费用
        $fields .= ',admin_exp';        #管理费用
        $fields .= ',n_income';         #净利润
        $fields .= ',rd_exp';           #研发费用

        $this->param['params'] = array('ts_code' => ts_code_conv($this->ts_code),
            'period'=>$this->finDate);
        $this->param['fields']=$fields;
        $this->httpjsonStr=json_encode($this->param);
        list($returnCode, $returnContent) = $this->http_post_json();
        $arr = json_decode($returnContent,true);
        return  $this->mergeArr($arr['data']);
    }

    function getCashflow()
    {
        $this->param['api_name']='cashflow';

        #现金流量表
        $fields  = 'ts_code';
        $fields .= ',end_date';             #=period
        $fields .= ',c_cash_equ_end_period';#期末现金及现金等价物余额
        $fields .= ',end_bal_cash';         #现金的期末余额

        $this->param['params'] = array('ts_code' => ts_code_conv($this->ts_code),
            'period'=>$this->finDate);
        $this->param['fields']=$fields;
        $this->httpjsonStr=json_encode($this->param);
        list($returnCode, $returnContent) = $this->http_post_json();

        //echo $returnContent;
        $arr = json_decode($returnContent,true);
        return  $this->mergeArr($arr['data']);
    }

    /**
     * Array ( [fields] => Array ( [0] => ts_code [1] => end_date [2] => notes_receiv [3] => accounts_receiv [4] => inventories )
     *          [items] => Array ( [0] => Array ( [0] => 002223.SZ [1] => 20201231 [2] => [3] => 546811497.99 [4] => 968427866.64 )
     *                             [1] => Array ( [0] => 002223.SZ [1] => 20201231 [2] => [3] => 546811497.99 [4] => 968427866.64 ) )
     * transfor to:
     * Array (ts_code=>array([0]=>002273.SZ [1]=>002273.SZ) notes_receiv=>array([0]=>546811497.99 [1]=>546811497.99)... )
     * @param $data
     */
    function mergeArr($data)
    {
        $rt = array();
        for($i=0;$i<count($data['fields']);$i++){
            for($j=0;$j<count($data['items']);$j++)
                $rt[$data['fields'][$i]][]=$data['items'][$j][$i];
        }
        return $rt;
    }

    /**
     * 根据当前财报日期，获取营业周期的基本天数
     * 天数按会计算法？90/180/270/360
     */
    function getTotalDays(){
        if($this->finDate) $dateCut=substr($this->finDate,4,4);
        switch ($dateCut){
            case '0331':
                return 90;
            case '0630':
                return 180;
            case '0930':
                return 270;
            case '1231':
                return 360;
        }

    }
}
?>