|
|
|
<?php
|
|
|
|
// +----------------------------------------------------------------------
|
|
|
|
// | Description: 商业智能-员工业绩分析
|
|
|
|
// +----------------------------------------------------------------------
|
|
|
|
// | Author: Michael_xu | gengxiaoxu@5kcrm.com
|
|
|
|
// +----------------------------------------------------------------------
|
|
|
|
|
|
|
|
namespace app\bi\controller;
|
|
|
|
|
|
|
|
use app\admin\controller\ApiCommon;
|
|
|
|
use app\bi\traits\SortTrait;
|
|
|
|
use app\crm\model\Contract as ContractModel;
|
|
|
|
use app\crm\model\Receivables as ReceivablesModel;
|
|
|
|
use think\Db;
|
|
|
|
use think\Hook;
|
|
|
|
use think\Request;
|
|
|
|
use app\bi\logic\ExcelLogic;
|
|
|
|
class Contract extends ApiCommon
|
|
|
|
{
|
|
|
|
use SortTrait;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 用于判断权限
|
|
|
|
* @permission 无限制
|
|
|
|
* @allow 登录用户可访问
|
|
|
|
* @other 其他根据系统设置
|
|
|
|
**/
|
|
|
|
public function _initialize()
|
|
|
|
{
|
|
|
|
$action = [
|
|
|
|
'permission' => [''],
|
|
|
|
'allow' => [
|
|
|
|
'analysis',
|
|
|
|
'summary',
|
|
|
|
'invoice',
|
|
|
|
'excelexport'
|
|
|
|
]
|
|
|
|
];
|
|
|
|
Hook::listen('check_auth', $action);
|
|
|
|
$request = Request::instance();
|
|
|
|
$a = strtolower($request->action());
|
|
|
|
if (!in_array($a, $action['permission'])) {
|
|
|
|
parent::_initialize();
|
|
|
|
}
|
|
|
|
if (!checkPerByAction('bi', 'contract', 'read')) {
|
|
|
|
header('Content-Type:application/json; charset=utf-8');
|
|
|
|
exit(json_encode(['code' => 102, 'error' => '无权操作']));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 合同数量分析/金额分析/回款金额分析
|
|
|
|
*
|
|
|
|
* @param string $param
|
|
|
|
* @return array|\think\response\Json
|
|
|
|
* @throws \think\db\exception\DataNotFoundException
|
|
|
|
* @throws \think\db\exception\ModelNotFoundException
|
|
|
|
* @throws \think\exception\DbException
|
|
|
|
*/
|
|
|
|
public function analysis($param='')
|
|
|
|
{
|
|
|
|
$userModel = new \app\admin\model\User();
|
|
|
|
$adminModel = new \app\admin\model\Admin();
|
|
|
|
if ($param['excel_type'] != 1) {
|
|
|
|
$param = $this->param;
|
|
|
|
}
|
|
|
|
$perUserIds = $userModel->getUserByPer('bi', 'contract', 'read'); // 权限范围内userIds
|
|
|
|
$whereArr = $adminModel->getWhere($param, '', $perUserIds); // 统计条件
|
|
|
|
$userIds = $whereArr['userIds'];
|
|
|
|
|
|
|
|
$year = !empty($param['year']) ? $param['year'] : date('Y');
|
|
|
|
$start_time = strtotime(date(($year - 1) . '-01-01'));
|
|
|
|
$end_time = strtotime('+2 year', $start_time) - 1;
|
|
|
|
$time = getTimeArray($start_time, $end_time);
|
|
|
|
|
|
|
|
if ($param['type'] == 'back' || $param['excel_type'] == 'back') {
|
|
|
|
$model = new ReceivablesModel;
|
|
|
|
$time_field = 'return_time';
|
|
|
|
} else {
|
|
|
|
$model = new ContractModel;
|
|
|
|
$time_field = 'order_date';
|
|
|
|
}
|
|
|
|
if ($param['type'] == 'count' || $param['$excel_type'] == 'count') {
|
|
|
|
$field['COUNT(*)'] = 'total';
|
|
|
|
} else {
|
|
|
|
$field['SUM(`money`)'] = 'total';
|
|
|
|
}
|
|
|
|
$between_time = [date('Y-m-d', $time['between'][0]), date('Y-m-d', $time['between'][1])];
|
|
|
|
$field["SUBSTR(`{$time_field}`, 1, 7)"] = 'type';
|
|
|
|
$sql = $model->field($field)
|
|
|
|
->where([
|
|
|
|
'owner_user_id' => ['IN', $userIds],
|
|
|
|
'check_status' => 2,
|
|
|
|
$time_field => ['BETWEEN', $between_time]
|
|
|
|
])
|
|
|
|
->group('type')
|
|
|
|
->fetchSql()
|
|
|
|
->select();
|
|
|
|
$res = queryCache($sql);
|
|
|
|
$res = array_column($res, null, 'type');
|
|
|
|
|
|
|
|
$data = [];
|
|
|
|
for ($i = 12; $i < 24; $i++) {
|
|
|
|
$k = $time['list'][$i]['type'];
|
|
|
|
$k2 = $time['list'][$i - 1]['type'];
|
|
|
|
$k3 = $time['list'][$i - 12]['type'];
|
|
|
|
$item['month'] = ($i - 11) < 10 ? $param['year']. '0' . $i - 11 : $param['year'] . $i - 11;
|
|
|
|
|
|
|
|
$item['thisMonth'] = $res[$k] ? $res[$k]['total'] : 0; # 本月
|
|
|
|
$item['lastMonthGrowth'] = $res[$k2] ? $res[$k2]['total'] : 0; # 上月
|
|
|
|
$item['lastYearGrowth'] = $res[$k3] ? $res[$k3]['total'] : 0; # 上年本月
|
|
|
|
|
|
|
|
# 环比
|
|
|
|
$item['chain_ratio'] = $item['thisMonth'] && $item['lastMonthGrowth'] ? round(($item['thisMonth'] / $item['lastMonthGrowth']) * 100, 4) : 0;
|
|
|
|
# 同比
|
|
|
|
$item['year_on_year'] = $item['thisMonth'] && $item['lastYearGrowth'] ? round(($item['thisMonth'] / $item['lastYearGrowth']) * 100, 4) : 0;
|
|
|
|
|
|
|
|
$data[] = $item;
|
|
|
|
}
|
|
|
|
//导出使用
|
|
|
|
if (!empty($param['excel_type'])) {
|
|
|
|
return $data;
|
|
|
|
}
|
|
|
|
return resultArray(['data' => $data]);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 合同汇总表
|
|
|
|
*
|
|
|
|
* @return \think\response\Json
|
|
|
|
* @throws \think\db\exception\DataNotFoundException
|
|
|
|
* @throws \think\db\exception\ModelNotFoundException
|
|
|
|
* @throws \think\exception\DbException
|
|
|
|
*/
|
|
|
|
public function summary($param='')
|
|
|
|
{
|
|
|
|
$userModel = new \app\admin\model\User();
|
|
|
|
$adminModel = new \app\admin\model\Admin();
|
|
|
|
if($param['excel_type']!=1){
|
|
|
|
$param = $this->param;
|
|
|
|
}
|
|
|
|
|
|
|
|
$perUserIds = $userModel->getUserByPer('bi', 'contract', 'read'); //权限范围内userIds
|
|
|
|
$whereArr = $adminModel->getWhere($param, '', $perUserIds); //统计条件
|
|
|
|
$userIds = $whereArr['userIds'];
|
|
|
|
|
|
|
|
if (empty($param['type']) && empty($param['start_time'])) {
|
|
|
|
$param['type'] = 'month';
|
|
|
|
}
|
|
|
|
|
|
|
|
$sortField = !empty($param['sort_field']) ? $param['sort_field'] : '';
|
|
|
|
$sortValue = !empty($param['sort_value']) ? $param['sort_value'] : '';
|
|
|
|
unset($param['sort_field']);
|
|
|
|
unset($param['sort_value']);
|
|
|
|
|
|
|
|
$year = !empty($param['year']) ? $param['year'] : date('Y');
|
|
|
|
$start_time = strtotime($year . '-01-01');
|
|
|
|
$end_time = strtotime('+1 year', $start_time) - 1;
|
|
|
|
$time = getTimeArray($start_time, $end_time);
|
|
|
|
$ax = 7;
|
|
|
|
if ($time['time_format'] == '%Y-%m-%d') {
|
|
|
|
$ax = 10;
|
|
|
|
}
|
|
|
|
$between_time = [date('Y-m-d', $time['between'][0]), date('Y-m-d', $time['between'][1])];
|
|
|
|
$sql = ContractModel::field([
|
|
|
|
'SUBSTR(`order_date`, 1, ' . $ax . ')' => 'type',
|
|
|
|
'COUNT(*)' => 'count',
|
|
|
|
'SUM(`money`)' => 'money'
|
|
|
|
])
|
|
|
|
->where([
|
|
|
|
'owner_user_id' => ['IN', $userIds],
|
|
|
|
'check_status' => 2,
|
|
|
|
'order_date' => ['BETWEEN', $between_time]
|
|
|
|
])
|
|
|
|
->group('type')
|
|
|
|
->fetchSql()
|
|
|
|
->select();
|
|
|
|
$contract_data = queryCache($sql);
|
|
|
|
$contract_data = array_column($contract_data, null, 'type');
|
|
|
|
$sql = ReceivablesModel::field([
|
|
|
|
'SUBSTR(`return_time`, 1, ' . $ax . ')' => 'type',
|
|
|
|
'SUM(`money`)' => 'money'
|
|
|
|
])
|
|
|
|
->where([
|
|
|
|
'owner_user_id' => ['IN', $userIds],
|
|
|
|
'check_status' => 2,
|
|
|
|
'return_time' => ['BETWEEN', $between_time]
|
|
|
|
])
|
|
|
|
->group('type')
|
|
|
|
->fetchSql()
|
|
|
|
->select();
|
|
|
|
$receivables_data = queryCache($sql);
|
|
|
|
$receivables_data = array_column($receivables_data, null, 'type');
|
|
|
|
|
|
|
|
$items = [];
|
|
|
|
$count_zong = 0;
|
|
|
|
$money_zong = 0;
|
|
|
|
$back_zong = 0;
|
|
|
|
foreach ($time['list'] as $val) {
|
|
|
|
$item = ['type' => $val['type']];
|
|
|
|
$count_zong += $item['count'] = $contract_data[$val['type']]['count'] ?: 0;
|
|
|
|
$money_zong += $item['money'] = $contract_data[$val['type']]['money'] ?: 0;
|
|
|
|
$back_zong += $item['back'] = $receivables_data[$val['type']]['money'] ?: 0;
|
|
|
|
$items[] = $item;
|
|
|
|
}
|
|
|
|
$data = [
|
|
|
|
'list' => $items,
|
|
|
|
'count_zong' => $count_zong,
|
|
|
|
'money_zong' => $money_zong,
|
|
|
|
'back_zong' => $back_zong,
|
|
|
|
'w_back_zong' => $money_zong - $back_zong,
|
|
|
|
];
|
|
|
|
|
|
|
|
if (!empty($data['list'])) $data['list'] = $this->sortCommon($data['list'], $sortField, $sortValue);
|
|
|
|
//导出使用
|
|
|
|
if (!empty($param['excel_type'])) return $data;
|
|
|
|
return resultArray(['data' => $data]);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 发票统计分析
|
|
|
|
*
|
|
|
|
* @return \think\response\Json
|
|
|
|
* @throws \think\db\exception\DataNotFoundException
|
|
|
|
* @throws \think\db\exception\ModelNotFoundException
|
|
|
|
* @throws \think\exception\DbException
|
|
|
|
*/
|
|
|
|
public function invoice($param='')
|
|
|
|
{
|
|
|
|
$userModel = new \app\admin\model\User();
|
|
|
|
$adminModel = new \app\admin\model\Admin();
|
|
|
|
if($param['excel_type']!=1){
|
|
|
|
$param = $this->param;
|
|
|
|
}
|
|
|
|
$perUserIds = $userModel->getUserByPer('bi', 'contract', 'read'); //权限范围内userIds
|
|
|
|
$whereArr = $adminModel->getWhere($param, '', $perUserIds); //统计条件
|
|
|
|
$userIds = $whereArr['userIds'];
|
|
|
|
if (empty($param['type']) && empty($param['start_time'])) {
|
|
|
|
$param['type'] = 'month';
|
|
|
|
}
|
|
|
|
|
|
|
|
$sortField = !empty($param['sort_field']) ? $param['sort_field'] : '';
|
|
|
|
$sortValue = !empty($param['sort_value']) ? $param['sort_value'] : '';
|
|
|
|
unset($param['sort_field']);
|
|
|
|
unset($param['sort_value']);
|
|
|
|
|
|
|
|
$time = getTimeArray();
|
|
|
|
$ax = 7;
|
|
|
|
if ($time['time_format'] == '%Y-%m-%d') {
|
|
|
|
$ax = 10;
|
|
|
|
}
|
|
|
|
$between_time = [date('Y-m-d', $time['between'][0]), date('Y-m-d', $time['between'][1])];
|
|
|
|
$sql = Db::name('crm_invoice')->field([
|
|
|
|
'SUBSTR(`invoice_date`, 1, ' . $ax . ')' => 'type',
|
|
|
|
'SUM(`invoice_money`)' => 'money'
|
|
|
|
])
|
|
|
|
->where([
|
|
|
|
'owner_user_id' => ['IN', $userIds],
|
|
|
|
'check_status' => 2,
|
|
|
|
'invoice_status' => 1,
|
|
|
|
'invoice_date' => ['BETWEEN', $between_time]
|
|
|
|
])
|
|
|
|
->group('type')
|
|
|
|
->fetchSql()
|
|
|
|
->select();
|
|
|
|
$invoice_data = queryCache($sql);
|
|
|
|
$invoice_data = array_column($invoice_data, null, 'type');
|
|
|
|
|
|
|
|
$sql = ReceivablesModel::field([
|
|
|
|
'SUBSTR(`return_time`, 1, ' . $ax . ')' => 'type',
|
|
|
|
'SUM(`money`)' => 'money'
|
|
|
|
])
|
|
|
|
->where([
|
|
|
|
'owner_user_id' => ['IN', $userIds],
|
|
|
|
'check_status' => 2,
|
|
|
|
'return_time' => ['BETWEEN', $between_time]
|
|
|
|
])
|
|
|
|
->group('type')
|
|
|
|
->fetchSql()
|
|
|
|
->select();
|
|
|
|
$receivables_data = queryCache($sql);
|
|
|
|
$receivables_data = array_column($receivables_data, null, 'type');
|
|
|
|
|
|
|
|
$items = [];
|
|
|
|
$invoiceCount = 0;
|
|
|
|
$receivablesCount = 0;
|
|
|
|
foreach ($time['list'] as $val) {
|
|
|
|
$receivablesModel = !empty($receivables_data[$val['type']]['money']) ? $receivables_data[$val['type']]['money'] : 0;
|
|
|
|
$invoiceModel = !empty($invoice_data[$val['type']]['money']) ? $invoice_data[$val['type']]['money'] : 0;
|
|
|
|
|
|
|
|
$items[] = [
|
|
|
|
'type' => $val['type'],
|
|
|
|
'receivables_money' => $receivablesModel,
|
|
|
|
'invoice_money' => $invoiceModel,
|
|
|
|
'not_invoice' => $receivablesModel - $invoiceModel > 0 ? $receivablesModel - $invoiceModel : 0,
|
|
|
|
'not_receivables' => $invoiceModel - $receivablesModel > 0 ? $invoiceModel - $receivablesModel : 0
|
|
|
|
];
|
|
|
|
|
|
|
|
$invoiceCount += $invoiceModel;
|
|
|
|
$receivablesCount += $receivablesModel;
|
|
|
|
|
|
|
|
}
|
|
|
|
$data = [
|
|
|
|
'list' => $items,
|
|
|
|
'receivables_count' => $receivablesCount,
|
|
|
|
'invoice_count' => $invoiceCount
|
|
|
|
];
|
|
|
|
|
|
|
|
if (!empty($data['list'])) $data['list'] = $this->sortCommon($data['list'], $sortField, $sortValue);
|
|
|
|
//导出使用
|
|
|
|
if (!empty($param['excel_type'])) return $data;
|
|
|
|
return resultArray(['data' => $data]);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 导出
|
|
|
|
* @param $type
|
|
|
|
* @param $types
|
|
|
|
*/
|
|
|
|
public function excelExport()
|
|
|
|
{
|
|
|
|
|
|
|
|
$param = $this->param;
|
|
|
|
$excel_type = $param['excel_type'];
|
|
|
|
$type=[];
|
|
|
|
$type['excel_types']=$param['excel_types'];
|
|
|
|
|
|
|
|
switch ($param['excel_types']) {
|
|
|
|
case 'analysis':
|
|
|
|
if ($param['type'] == 'count') {
|
|
|
|
$type['type'] = '合同数量分析';
|
|
|
|
|
|
|
|
} elseif ($param['type'] == 'back') {
|
|
|
|
$type['type'] = '回款金额分析';
|
|
|
|
} else {
|
|
|
|
$type['type'] = '金额分析';
|
|
|
|
}
|
|
|
|
$list = $this->analysis($param);
|
|
|
|
break;
|
|
|
|
case 'summary':
|
|
|
|
$list = $this->summary($excel_type);
|
|
|
|
$list=$list['list'];
|
|
|
|
$type['type'] = '合同汇总表';
|
|
|
|
break;
|
|
|
|
case 'invoice':
|
|
|
|
$list = $this->invoice($excel_type);
|
|
|
|
$list=$list['list'];
|
|
|
|
$type['type'] = '发票统计分析表';
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if(empty($list)){
|
|
|
|
return resultArray(['data'=>'数据不存在']);
|
|
|
|
}
|
|
|
|
$excelLogic = new ExcelLogic();
|
|
|
|
$data = $excelLogic->contractExcel($type, $list);
|
|
|
|
return $data;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|