userCenterId = $userCenterId; $this->enterpriseId = $enterpriseId; parent::__construct($enterpriseId, $userCenterId); $this->objDCustomerBalance = new DCustomerBalance('finance'); $this->objDCustomerBalanceIndex = new DCustomerBalanceIndex('finance'); $this->objDCustomer = new DCustomer('default'); $this->objMCustomer = new MCustomer($enterpriseId, $userCenterId); $this->objOverviewCache = new OverviewCache(); $this->objDCustomerBalanceIndex->setTable('qianniao_customer_balance_index_' . $enterpriseId); $this->objDCustomer->setTable('qianniao_customer_' . $enterpriseId); } /** * 添加客户余额 * @param int $customerId * @param int $changedMoney * @return ResultWrapper * @throws \Exception */ public function addCustomerBalance($customerId, $changedMoney) { $tableName = $this->objDCustomerBalance->getTableName('qianniao_customer_balance_' . $this->enterpriseId, $customerId, $this->cutTable); $this->objDCustomerBalance->setTable($tableName); //获取客户目前的余额 $money = $this->objDCustomer->get_field('money', $customerId); //新增一条客户余额 $balanceData = [ 'customerId' => $customerId, 'openingBalance' => $money, 'interimBalance' => $changedMoney, 'endingBalance' => bcadd($money, $changedMoney, 4), 'createTime' => time(), 'updateTime' => time() ]; $detailId = $this->objDCustomerBalance->insert($balanceData); if ($detailId === false) { return ResultWrapper::fail($this->objDCustomerBalance->error(), ErrorCode::$dberror); } //新增一条客户余额索引数据 $indexData = [ 'customerId' => $customerId, 'detailId' => $detailId, 'createTime' => time(), 'updateTime' => time() ]; $indexId = $this->objDCustomerBalanceIndex->insert($indexData); if ($indexId === false) { return ResultWrapper::fail($this->objDCustomerBalanceIndex->error(), ErrorCode::$dberror); } //更新客户的最新余额 $result = self::updateCustomerBalance($customerId, $changedMoney); if ($result->isSuccess() === false) { return ResultWrapper::fail($result->getData(), $result->getErrorCode()); } return ResultWrapper::success($result->getData()); } /** * 获取某一日期的余额 * @param $time * @return int * @throws \Exception */ public function getShouldReceiveMoneyByTime($time, $customerId) { $tableName = $this->objDCustomerBalanceIndex->get_Table(); $sql = "select * from $tableName where createTime <= $time AND customerId = $customerId order by id desc limit 1"; $result = $this->objDCustomerBalanceIndex->query($sql); if (empty($result)) { //没有发生过应收应付 return 0; } $data = array_shift($result); $tableName = $this->objDCustomerBalance->getTableName('qianniao_customer_balance_' . $this->enterpriseId, $customerId, $this->cutTable); $this->objDCustomerBalance->setTable($tableName); return $this->objDCustomerBalance->get_field('endingBalance', $data['detailId']); } /** * 获取所有客户余额数据 * @param array $selectParams 过滤条件 * @return ResultWrapper * @throws \Exception */ public function getAllCustomerBalance($selectParams,$export = 0) { $limit = $selectParams['limit']; unset($selectParams['limit']); $offset = $selectParams['offset']; unset($selectParams['offset']); if($export){ $limit = null; $offset = null; } $customerId = $selectParams['customerId']; unset($selectParams['customerId']); $tag = $selectParams['tag']; unset($selectParams['tag']); $start = $selectParams['start']; unset($selectParams['start']); $end = $selectParams['end']; unset($selectParams['end']); //默认进来不筛选,查出客户当前的余额 if (!$start && !$end) { $where = ['limit' => $limit, 'offset' => $offset]; if ($customerId) { $where['id'] = $customerId; } if (!empty($tag)) { $where['tag'] = $tag; } $result = $this->objMCustomer->getCustomerMoney($where); if ($result->isSuccess() === false) { return ResultWrapper::fail($result->getData(), $result->getErrorCode()); } // if (!$start && !$end)情况下导出 if($export){ self::exportCustomerBalance($result->getData()['data']); exit; } return ResultWrapper::success($result->getData()); } //期初余额 $startResult = self::getShouldReceiveMoneyByTime($start, $customerId); //期末余额 $endResult = self::getShouldReceiveMoneyByTime($end, $customerId); // 销售金额 / 收款金额 $saleResult = self::getSaleMoneyByTime($start,$end,$customerId); $customerName = $this->objDCustomer->get($customerId); $return = [ 'data' => [ [ 'customerId' => $customerId, 'name' => $customerName['name'], 'memberBalance' => $customerName['memberBalance'], 'openingBalance' => $startResult, 'saleMoney'=>$saleResult['saleMoney'], 'collectionMoney'=>$saleResult['collectionMoney'], 'endingBalance' => $endResult ] ], 'total' => 1, ]; //导出 if($export){ self::exportCustomerBalance($return['data']); exit; } return ResultWrapper::success($return); } private function format($data) { $customerIds = []; foreach ($data as $k => $v) { $customerIds[] = $v['customerId']; } $customerInfo = $this->objMCustomer->getCustomer(array_unique($customerIds)); $customerData = $customerInfo->getData(); foreach ($data as $k => $v) { $data[$k]['customerName'] = isset($customerData[$v['customerId']]) ? $customerData[$v['customerId']]['name'] : ''; } return $data; } /** * 修改客户余额 * @param $customerId * @param $changedMoney * @return ResultWrapper */ public function updateCustomerBalance($customerId, $changedMoney) { $dbResult = $this->objDCustomer->set_inc('money', $customerId, $changedMoney); if ($dbResult === false) { return ResultWrapper::fail($this->objDCustomer->error(), ErrorCode::$dberror); } //修改应收款总金额 $this->objOverviewCache->saveAggregateStatistics($this->enterpriseId, 'totalShouldReceive', $changedMoney); return ResultWrapper::success($dbResult); } /** * 修改客户付款总额 * @param $customerId * @param $money * @return ResultWrapper */ public function updateCustomerTotalPayMoney($customerId, $money) { $dbResult = $this->objDCustomer->set_inc('totalPayMoney', $customerId, $money); if ($dbResult === false) { return ResultWrapper::fail($this->objDCustomer->error(), ErrorCode::$dberror); } return ResultWrapper::success($dbResult); } /** * 获取客户余额 * @param $customerId * @return ResultWrapper */ public function getCustomerBalance($customerId, $field = 'money') { $money = $this->objDCustomer->get_field($field, $customerId); return $money ? $money : 0; } /** * 导出方法 * @param $result * @return void * @throws Exception */ public function exportCustomerBalance($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['name'] = isset($v['name']) ? $v['name'] : '';//客户名称 $rows['openingBalance'] = isset($v['openingBalance']) ? $v['openingBalance'] : '';//初期余额 $rows['interimBalance1'] = isset($v['interimBalance']) ? $v['interimBalance'] : '';//销售金额 $rows['interimBalance2'] = isset($v['interimBalance']) ? $v['interimBalance'] : '';//收款金额 $rows['endingBalance'] = isset($v['endingBalance']) ? $v['endingBalance'] : '';//期末金额$rows['openingBalance']+$rows['interimBalance']-$rows['interimBalance'];//期末金额 应该是期初+销售-收款=期末 $rows['interimBalance3'] = isset($v['interimBalance']) ? $v['interimBalance'] : '';//会员余额 foreach ($rows as $kk => $vv) { $rs[$kk] = mb_convert_encoding($vv, 'GBK', 'utf-8'); //转译编码 } fputcsv($fp, $rs); $rows = []; } } /** * 根据时间获取销售金额,收款金额 */ public function getSaleMoneyByTime($start,$end,$customerId) { $saleMoney = 0;// 销售金额 $collectionMoney = 0;// 收款金额 $objReceiveTable = new DReceive('finance'); $objReceivedTable = new DReceived('finance'); $objReceiveIndexTable = new DReceiveReceiptIndex('finance'); $objReceiveIndexTable->setTable('qianniao_receive_receipt_index_'.$this->enterpriseId); $objReceivedIndexTable = new DReceivedIndex('finance'); $objReceivedIndexTable->setTable('qianniao_received_index_'.$this->enterpriseId); $receiveIndexSql = 'select * from '.$objReceiveIndexTable->get_Table().' WHERE createTime BETWEEN '.$start.' AND '.$end .' AND customerId='.$customerId .' AND offsetStatus='.StatusCode::$standard; $receiveIndexDate = $objReceiveIndexTable->query($receiveIndexSql); if($receiveIndexDate === false){ return ResultWrapper::fail($objReceiveIndexTable->error(), ErrorCode::$dberror); } if(!empty($receiveIndexDate)){ foreach ($receiveIndexDate as $receiveKey => $receiveValue){ $suffix = date('Y', $receiveValue['createTime']) . '_' . ceil(date('m', $receiveValue['createTime']) / 3); $objReceiveTable->setTable('qianniao_receive_receipt_' . $this->enterpriseId . '_' . $suffix); $receiveDate = $objReceiveTable->get($receiveValue['id']); $saleMoney = bcadd($saleMoney,$receiveDate['receiveMoney'],2); } } $receivedIndexSql = 'select * from '.$objReceivedIndexTable->get_Table().' WHERE createTime BETWEEN '.$start.' AND '.$end.' AND customerId='.$customerId .' AND offsetStatus='.StatusCode::$standard; $receivedIndexDate = $objReceivedIndexTable->query($receivedIndexSql); if($receiveIndexDate === false){ return ResultWrapper::fail($objReceiveIndexTable->error(), ErrorCode::$dberror); } if(!empty($receivedIndexDate)){ foreach ($receivedIndexDate as $receivedKey => $receivedValue){ $objReceivedTable->setTable('qianniao_received_' . $this->enterpriseId . '_' . date('Y', $receivedValue['createTime']) . '_' . ceil(date('m', $receivedValue['createTime']) / 3)); $receivedDate = $objReceivedTable->get($receivedValue['id']); $collectionMoney = bcadd($collectionMoney,isset($receivedDate['totalFinalMoney']) ? $receivedDate['totalFinalMoney'] :0,2); } } return [ 'saleMoney'=>$saleMoney, 'collectionMoney'=>$collectionMoney ]; } }