123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250 |
- <?php
- namespace Modules\ContentManage\Services\CpManage;
- use Illuminate\Support\Facades\DB;
- use Modules\Common\Support\Trace\CustomizeLogger;
- use Modules\Common\Support\Trace\TraceContext;
- class BookSettlement
- {
- private $settlementResult = [];
- private $bid;
- // 初始的结算模式信息
- private $initialSettlementModeInfo = null;
- private $month;
- private $lastMonthLastDate;
- private $currentMonthLastDate;
- private $currentMonthFirstDate;
- private $settlementModeInfos = null;
- private $finalAmounts = null;
- private $logger;
- /**
- * @var TraceContext
- */
- public $traceContext;
- public function __construct($bid, $month)
- {
- $this->bid = $bid;
- $this->month = $month;
- $this->currentMonthFirstDate = $this->month . '-01';
- $this->lastMonthLastDate = date_sub(date_create($this->currentMonthFirstDate),
- date_interval_create_from_date_string('1 day'))->format('Y-m-d');
- $this->currentMonthLastDate = date_sub(date_add(date_create($this->month),
- date_interval_create_from_date_string('1 month')),
- date_interval_create_from_date_string('1 day'))->format('Y-m-d');
- $this->logger = CustomizeLogger::getLogger('bookMonthSettlement', 'debug');
- $this->traceContext = app(TraceContext::class);
- }
- private function initSettlementModeInfo() {
- $record = DB::table('book_settlement_mode_history')
- ->where(['bid' => $this->bid, 'is_enabled' => 1])
- ->where('effective_date', '<', $this->currentMonthFirstDate)
- ->orderBy('id', 'desc')
- ->first();
- if(!$record) {
- $bookInfo = DB::table('books')
- ->where(['id' => $this->bid])
- ->select('id', 'settlement_type', 'bottomline')
- ->first();
- $modeInfo = [
- 'settlement_mode' => $bookInfo->settlement_type,
- 'bottomline' => $bookInfo->bottomline,
- 'effective_date' => '2000-01-01',
- 'total_amount' => 0,
- 'change_reason' => 'manual',
- ];
- } else {
- $modeInfo = [
- 'settlement_mode' => $record->settlement_mode,
- 'bottomline' => $record->bottomline,
- 'effective_date' => $record->effective_date,
- 'total_amount' => $record->total_amount,
- 'change_reason' => $record->change_reason,
- ];
- }
- if('bottomline' == $modeInfo['settlement_mode']) {
- if('manual' == $modeInfo['change_reason']) {
- $modeInfo['total_amount'] = $this->getBookTotalAmount($modeInfo['effective_date']);
- }
- if($modeInfo['total_amount'] >= $modeInfo['bottomline']) {
- $modeInfo['settlement_mode'] = 'out_bottomline';
- }
- }
- $this->logger->debug('初始结算状态', [
- 'traceInfo' => $this->traceContext->getTraceInfo(),
- 'modeInfo' => $modeInfo]);
- return $modeInfo;
- }
- private function getBookTotalAmount($effectiveDate) {
- return DB::table('cp_subscribe_statistic_data')
- ->where([
- ['settlement_date', '>=', $effectiveDate],
- ['settlement_date', '<=', $this->lastMonthLastDate],
- ['bid' , '=', $this->bid],
- ])->sum('yesterday_final_amount');
- }
- private function getInitialSettlementModeInfo(){
- if(is_null($this->initialSettlementModeInfo)) {
- $this->initialSettlementModeInfo = $this->initSettlementModeInfo();
- }
- return $this->initialSettlementModeInfo;
- }
- /**
- * 获取本月可用结算模式
- * @return null
- */
- private function getSettlementModes() {
- if(is_null($this->settlementModeInfos)) {
- $initSettlementMode = $this->getInitialSettlementModeInfo();
- $this->settlementModeInfos[$initSettlementMode['effective_date']] = $initSettlementMode;
- $historyList = DB::table('book_settlement_mode_history')
- ->whereBetween('effective_date', [$this->currentMonthFirstDate, $this->currentMonthLastDate])
- ->where(['is_enabled' => 1, 'bid' => $this->bid])
- ->orderBy('id', 'asc')
- ->get();
- foreach ($historyList as $history) {
- $this->settlementModeInfos[$history->effective_date] = [
- 'settlement_mode' => $history->settlement_mode,
- 'bottomline' => $history->bottomline,
- 'effective_date' => $history->effective_date,
- 'total_amount' => $history->total_amount
- ];
- }
- }
- return $this->settlementModeInfos;
- }
- /**
- * 获取本月每日原始应结算金额明细
- * @return \Illuminate\Support\Collection
- */
- private function getFinalAmounts() {
- if (is_null($this->finalAmounts)) {
- $this->finalAmounts = DB::table('cp_subscribe_statistic_data')
- ->whereBetween('settlement_date', [$this->currentMonthFirstDate, $this->currentMonthLastDate])
- ->select('yesterday_final_amount', 'settlement_date', 'bid')
- ->where(['bid' => $this->bid])
- ->get()->keyBy('settlement_date');
- }
- return $this->finalAmounts;
- }
- /**
- * 获取 {month} 中各天的应结算金额
- * @return array
- * <pre>
- * [
- * "2023-03-01"=> 2.5,
- * "2023-03-02"=> 2.5,
- * ...
- * "2023-03-30"=> 2.5,
- * "2023-03-31"=> 2.5,
- * ]
- * </pre>
- */
- public function detail() {
- $this->logger->debug('开始处理书籍', [
- 'traceInfo' => $this->traceContext->getTraceInfo(),
- 'bid' => $this->bid, 'month' => $this->month,
- ]);
- $date = $this->currentMonthFirstDate;
- $settlementModes = $this->getSettlementModes();
- $this->logger->debug('结算状态集合', ['traceInfo' => $this->traceContext->getTraceInfo(),
- 'settlementModeInfos' => $settlementModes]);
- $finalAmounts = $this->getFinalAmounts();
- $this->logger->debug('原始应结算金额', ['traceInfo' => $this->traceContext->getTraceInfo(),
- 'sourceFinalAmounts' => $finalAmounts->toArray()]);
- while ($date <= $this->currentMonthLastDate) {
- $this->logger->debug('开始处理日期:'. $date, ['traceInfo' => $this->traceContext->getTraceInfo(),
- 'date' => $date]);
- $nextDate = date_add(date_create($date), date_interval_create_from_date_string('1 day'))
- ->format('Y-m-d');
- if($finalAmounts->has($date)) {
- $currentSettlementMode = null;
- ksort($settlementModes);
- foreach ($settlementModes as $settlementMode) {
- if($date >= $settlementMode['effective_date']) {
- $currentSettlementMode = $settlementMode;
- }
- }
- $sourceFinalAmount = $finalAmounts->get($date)->yesterday_final_amount;
- $this->logger->debug('该天有原始应结算金额数据', ['traceInfo' => $this->traceContext->getTraceInfo(),
- 'sourceFinalAmount' => $sourceFinalAmount]);
- $this->logger->debug('该日期可用的结算模式', ['traceInfo' => $this->traceContext->getTraceInfo(),
- 'settlementMode' => $currentSettlementMode]);
- if('bottomline' == $currentSettlementMode['settlement_mode']) {
- $settlementModes[$currentSettlementMode['effective_date']]['total_amount'] += $sourceFinalAmount;
- if($settlementModes[$currentSettlementMode['effective_date']]['total_amount'] >
- $settlementModes[$currentSettlementMode['effective_date']]['bottomline']) {
- $this->settlementResult[$date] = $settlementModes[$currentSettlementMode['effective_date']]['total_amount'] -
- $settlementModes[$currentSettlementMode['effective_date']]['bottomline'];
- $this->logger->debug('当前原始应结算金额累计超出书籍保底金额',
- ['traceInfo' => $this->traceContext->getTraceInfo(),
- 'currentSettlementMode' => $settlementModes[$currentSettlementMode['effective_date']],
- 'realFinalAmount' => $this->settlementResult[$date]]);
- if(!key_exists($nextDate, $settlementModes)) {
- $this->logger->debug('下一天没有对应结算模式故可增加一个超保底结算模式,保证下一天按超保底结算',
- ['traceInfo' => $this->traceContext->getTraceInfo(), 'nextDate' => $nextDate]);
- $settlementModes[$nextDate] = [
- 'settlement_mode' => 'out_bottomline',
- 'effective_date' => $nextDate,
- 'total_amount' => 0,
- 'bottomline' => 0,
- ];
- }
- } else {
- $this->logger->debug('当前原始应结算金额没有超出书籍保底金额',
- ['traceInfo' => $this->traceContext->getTraceInfo(), 'realFinalAmount' => 0]);
- $this->settlementResult[$date] = 0;
- }
- }
- elseif ('buyout' == $currentSettlementMode['settlement_mode']) {
- $this->logger->debug('当前书籍结算模式为买断,故该天最终结算0',
- ['traceInfo' => $this->traceContext->getTraceInfo(), 'realFinalAmount' => 0]);
- $this->settlementResult[$date] = 0;
- }
- else {
- $this->logger->debug('其他的结算模式,应结算金额保持不变',
- ['traceInfo' => $this->traceContext->getTraceInfo(), 'realFinalAmount' => $sourceFinalAmount]);
- $this->settlementResult[$date] = $sourceFinalAmount;
- }
- } else {
- $this->settlementResult[$date] = 0;
- }
- $date = $nextDate;
- }
- ksort($settlementModes);
- $lastMonthLastDateSettlementMode = \last($settlementModes);
- $now = date('Y-m-d H:i:s');
- if('out_bottomline' == $lastMonthLastDateSettlementMode['settlement_mode']) {
- $this->logger->debug('入库保存本月最后一个结算模式', ['traceInfo' => $this->traceContext->getTraceInfo(),
- 'lastMonthLastDateSettlementMode' => $lastMonthLastDateSettlementMode]);
- DB::table('book_settlement_mode_history')
- ->insert([
- 'bid' => $this->bid,
- 'effective_date' => $this->currentMonthLastDate,
- 'settlement_mode' => $lastMonthLastDateSettlementMode['settlement_mode'],
- 'bottomline' => $lastMonthLastDateSettlementMode['bottomline'],
- 'total_amount' => $lastMonthLastDateSettlementMode['total_amount'],
- 'change_reason' => 'auto',
- 'created_at' => $now,
- 'updated_at' => $now
- ]);
- }
- return $this->settlementResult;
- }
- }
|