|
|
@@ -0,0 +1,343 @@ |
|
|
|
|
|
<?php |
|
|
|
|
|
|
|
|
|
|
|
namespace App\Console\Commands; |
|
|
|
|
|
|
|
|
|
|
|
use App\Logic\SMS\SMSManager; |
|
|
|
|
|
use App\Models\Contract; |
|
|
|
|
|
use App\Models\ReceiptIssuingOrder; |
|
|
|
|
|
use App\Models\SMSSendOrder; |
|
|
|
|
|
use App\Models\UseByKeySummary; |
|
|
|
|
|
use App\Models\UseSummary; |
|
|
|
|
|
use App\Util\DateUtil; |
|
|
|
|
|
use App\Util\DBUtil; |
|
|
|
|
|
use Exception; |
|
|
|
|
|
use Illuminate\Support\Carbon; |
|
|
|
|
|
use Illuminate\Support\Collection; |
|
|
|
|
|
use Illuminate\Support\Facades\DB; |
|
|
|
|
|
use LogicException; |
|
|
|
|
|
|
|
|
|
|
|
class SummaryUse extends BaseCommand |
|
|
|
|
|
{ |
|
|
|
|
|
|
|
|
|
|
|
const COMMAND = "summary:use {--contractId=} {--yyyymm=}"; |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
* The name and signature of the console command. |
|
|
|
|
|
* |
|
|
|
|
|
* @var string |
|
|
|
|
|
*/ |
|
|
|
|
|
protected $signature = self::COMMAND; |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
* The console command description. |
|
|
|
|
|
* |
|
|
|
|
|
* @var string |
|
|
|
|
|
*/ |
|
|
|
|
|
protected $description = '利用実績を集計する'; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static public function getCommand() |
|
|
|
|
|
{ |
|
|
|
|
|
return self::COMMAND; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private string $targetYYYYMM = ""; |
|
|
|
|
|
private ?Carbon $targetDate = null; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
* Create a new command instance. |
|
|
|
|
|
* |
|
|
|
|
|
* @return void |
|
|
|
|
|
*/ |
|
|
|
|
|
public function __construct(private SMSManager $manager) |
|
|
|
|
|
{ |
|
|
|
|
|
parent::__construct(); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
* Execute the console command. |
|
|
|
|
|
* |
|
|
|
|
|
* @return int |
|
|
|
|
|
*/ |
|
|
|
|
|
public function service(): int |
|
|
|
|
|
{ |
|
|
|
|
|
$this->setTargetYYYYMM(); |
|
|
|
|
|
$this->outputInfo(sprintf("対象集計年月: %s", $this->targetYYYYMM)); |
|
|
|
|
|
|
|
|
|
|
|
$db = DBUtil::instance(); |
|
|
|
|
|
try { |
|
|
|
|
|
$db->beginTransaction(); |
|
|
|
|
|
foreach ($this->getTargetContractIds() as $contractId) { |
|
|
|
|
|
$this->handleTarget($contractId); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
$db->commit(); |
|
|
|
|
|
} catch (Exception $e) { |
|
|
|
|
|
$db->rollBack(); |
|
|
|
|
|
throw $e; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return self::RESULTCODE_SUCCESS; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private function handleTarget(string $contractId) |
|
|
|
|
|
{ |
|
|
|
|
|
// 集計対象のモデルを取得 |
|
|
|
|
|
$model = $this->getModel($contractId); |
|
|
|
|
|
|
|
|
|
|
|
// 集計 |
|
|
|
|
|
$summaryByKeys = $this->summary($model); |
|
|
|
|
|
|
|
|
|
|
|
// 保存 |
|
|
|
|
|
$this->save($model, $summaryByKeys); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private function getTargetContractIds(): array |
|
|
|
|
|
{ |
|
|
|
|
|
if ($this->option('contractId')) { |
|
|
|
|
|
|
|
|
|
|
|
return [$this->option('contractId')]; |
|
|
|
|
|
} |
|
|
|
|
|
return Contract::pluck(Contract::COL_NAME_ID)->toArray(); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private function setTargetYYYYMM() |
|
|
|
|
|
{ |
|
|
|
|
|
$yyyyMM = $this->option('yyyymm'); |
|
|
|
|
|
|
|
|
|
|
|
// デフォルト判定 |
|
|
|
|
|
if ($yyyyMM === null) { |
|
|
|
|
|
// デフォルトは先月とする |
|
|
|
|
|
$this->targetDate = DateUtil::now()->addMonth(-1)->setDay(1)->setTime(0, 0); |
|
|
|
|
|
$this->targetYYYYMM = $this->targetDate->format('Ym'); |
|
|
|
|
|
return; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// フォーマットチェック |
|
|
|
|
|
if (!preg_match("/^\d{6}$/", $yyyyMM)) { |
|
|
|
|
|
throw new Exception('YYYYMM不正'); |
|
|
|
|
|
} |
|
|
|
|
|
// 日付チェック |
|
|
|
|
|
$tmpDate = Carbon::createFromFormat('Ym', $yyyyMM); |
|
|
|
|
|
if (!$tmpDate->isValid()) { |
|
|
|
|
|
throw new Exception('YYYYMM 日付不正'); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
$this->targetDate = $tmpDate->setDay(1)->setTime(0, 0);; |
|
|
|
|
|
$this->targetYYYYMM = $this->targetDate->format('Ym');; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private function getModel(string $contractId): UseSummary |
|
|
|
|
|
{ |
|
|
|
|
|
$model = UseSummary::whereContractId($contractId) |
|
|
|
|
|
->whereSummaryYyyymm($this->targetYYYYMM) |
|
|
|
|
|
->firstOrNew([ |
|
|
|
|
|
UseSummary::COL_NAME_CONTRACT_ID => $contractId, |
|
|
|
|
|
UseSummary::COL_NAME_SUMMARY_YYYYMM => $this->targetYYYYMM, |
|
|
|
|
|
]); |
|
|
|
|
|
|
|
|
|
|
|
$currentYYYYMM = intval(DateUtil::now()->format('Ym')); |
|
|
|
|
|
$targetYYYYMM = intval($this->targetYYYYMM); |
|
|
|
|
|
if ($targetYYYYMM < $currentYYYYMM) { |
|
|
|
|
|
$model->is_fixed = true; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return $model; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
* Undocumented function |
|
|
|
|
|
* |
|
|
|
|
|
* @param UseSummary $model |
|
|
|
|
|
* @return Collection<string,UseByKeySummary> |
|
|
|
|
|
*/ |
|
|
|
|
|
private function summary(UseSummary $model): Collection |
|
|
|
|
|
{ |
|
|
|
|
|
|
|
|
|
|
|
$from = $this->targetDate->clone()->setTime(0, 0); |
|
|
|
|
|
$to = $this->targetDate->clone()->addMonth()->setTime(0, 0); |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
* @var Collection<string,UseByKeySummary> |
|
|
|
|
|
*/ |
|
|
|
|
|
$summaryByKeys = collect(); |
|
|
|
|
|
|
|
|
|
|
|
$makeKey = function (?string $key1, ?string $key2) { |
|
|
|
|
|
return sprintf("%s-%s", $key1 ?? "NULL", $key2 ?? "NULL"); |
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
$targetOrders = ReceiptIssuingOrder::getBuilder() |
|
|
|
|
|
->where(ReceiptIssuingOrder::COL_NAME_CONTRACT_ID, $model->contract_id) |
|
|
|
|
|
->where(ReceiptIssuingOrder::COL_NAME_ORDER_DATETIME, ">=", $from) |
|
|
|
|
|
->where(ReceiptIssuingOrder::COL_NAME_ORDER_DATETIME, "<", $to); |
|
|
|
|
|
|
|
|
|
|
|
// 領収証発行依頼件数の取得 |
|
|
|
|
|
$receiptIssuingOrders = DB::table($targetOrders, 'target_orders') |
|
|
|
|
|
->groupBy( |
|
|
|
|
|
ReceiptIssuingOrder::COL_NAME_CONTRACT_ID, |
|
|
|
|
|
ReceiptIssuingOrder::COL_NAME_SUMMARY_KEY1, |
|
|
|
|
|
ReceiptIssuingOrder::COL_NAME_SUMMARY_KEY2, |
|
|
|
|
|
) |
|
|
|
|
|
->select([ |
|
|
|
|
|
ReceiptIssuingOrder::COL_NAME_CONTRACT_ID, |
|
|
|
|
|
ReceiptIssuingOrder::COL_NAME_SUMMARY_KEY1, |
|
|
|
|
|
ReceiptIssuingOrder::COL_NAME_SUMMARY_KEY2, |
|
|
|
|
|
DB::raw(sprintf("count(*) as count")), |
|
|
|
|
|
]) |
|
|
|
|
|
->get(); |
|
|
|
|
|
$model->receipt_order_count = 0; |
|
|
|
|
|
foreach ($receiptIssuingOrders as $ele) { |
|
|
|
|
|
|
|
|
|
|
|
$key1 = data_get($ele, ReceiptIssuingOrder::COL_NAME_SUMMARY_KEY1); |
|
|
|
|
|
$key2 = data_get($ele, ReceiptIssuingOrder::COL_NAME_SUMMARY_KEY2); |
|
|
|
|
|
$count = data_get($ele, 'count'); |
|
|
|
|
|
|
|
|
|
|
|
$model->receipt_order_count += $count; |
|
|
|
|
|
|
|
|
|
|
|
$key = $makeKey($key1, $key2); |
|
|
|
|
|
|
|
|
|
|
|
$summaryByKey = $this->getUseByKeyModel($model, $key1, $key2); |
|
|
|
|
|
|
|
|
|
|
|
$summaryByKeys->put($key, $summaryByKey); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// SMS送信実績の取得 |
|
|
|
|
|
$SMSs = SMSSendOrder::getBuilder() |
|
|
|
|
|
->where(SMSSendOrder::COL_NAME_CONTRACT_ID, $model->contract_id) |
|
|
|
|
|
->whereNotNull(SMSSendOrder::COL_NAME_SEND_DATETIME) |
|
|
|
|
|
->where(SMSSendOrder::COL_NAME_SEND_DATETIME, ">=", $from) |
|
|
|
|
|
->where(SMSSendOrder::COL_NAME_SEND_DATETIME, "<", $to) |
|
|
|
|
|
->where(SMSSendOrder::COL_NAME_DONE, true) |
|
|
|
|
|
->groupBy( |
|
|
|
|
|
ReceiptIssuingOrder::COL_NAME_CONTRACT_ID, |
|
|
|
|
|
ReceiptIssuingOrder::COL_NAME_SUMMARY_KEY1, |
|
|
|
|
|
ReceiptIssuingOrder::COL_NAME_SUMMARY_KEY2 |
|
|
|
|
|
) |
|
|
|
|
|
->select([ |
|
|
|
|
|
ReceiptIssuingOrder::COL_NAME_CONTRACT_ID, |
|
|
|
|
|
ReceiptIssuingOrder::COL_NAME_SUMMARY_KEY1, |
|
|
|
|
|
ReceiptIssuingOrder::COL_NAME_SUMMARY_KEY2, |
|
|
|
|
|
DB::raw(sprintf("count(*) as count")), |
|
|
|
|
|
DB::raw(sprintf("sum(%s) as cost", SMSSendOrder::COL_NAME_COST)), |
|
|
|
|
|
]) |
|
|
|
|
|
->get(); |
|
|
|
|
|
|
|
|
|
|
|
$model->sms_send_count = 0; |
|
|
|
|
|
$model->sms_send_cost = 0; |
|
|
|
|
|
foreach ($SMSs as $ele) { |
|
|
|
|
|
$key1 = data_get($ele, SMSSendOrder::COL_NAME_SUMMARY_KEY1); |
|
|
|
|
|
$key2 = data_get($ele, SMSSendOrder::COL_NAME_SUMMARY_KEY2); |
|
|
|
|
|
$count = data_get($ele, 'count'); |
|
|
|
|
|
$cost = data_get($ele, 'cost'); |
|
|
|
|
|
|
|
|
|
|
|
$model->sms_send_count += $count; |
|
|
|
|
|
$model->sms_send_cost += $cost; |
|
|
|
|
|
|
|
|
|
|
|
$key = $makeKey($key1, $key2); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
$summaryByKey = $summaryByKeys->get($key); |
|
|
|
|
|
if (!$summaryByKey instanceof UseByKeySummary) { |
|
|
|
|
|
$summaryByKey = $this->getUseByKeyModel($model, $key1, $key2); |
|
|
|
|
|
$summaryByKeys->put($key, $summaryByKey); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
$summaryByKey->fill([ |
|
|
|
|
|
UseByKeySummary::COL_NAME_SMS_SEND_COUNT => $count, |
|
|
|
|
|
UseByKeySummary::COL_NAME_SMS_SEND_COST => $cost, |
|
|
|
|
|
]); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return $summaryByKeys; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
* @param UseSummary $model |
|
|
|
|
|
* @param Collection<UseByKeySummary> $summaryByKeys |
|
|
|
|
|
* @return void |
|
|
|
|
|
*/ |
|
|
|
|
|
private function save(UseSummary $model, Collection $summaryByKeys) |
|
|
|
|
|
{ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
$contract = $model->contract; |
|
|
|
|
|
|
|
|
|
|
|
if (!$contract) { |
|
|
|
|
|
throw new Exception("契約不正"); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
$this->outputInfo( |
|
|
|
|
|
sprintf( |
|
|
|
|
|
"集計完了:%s 領収証発行依頼:%d件 SMS送信件数:%d件 SMSコスト:%d円", |
|
|
|
|
|
$contract->name, |
|
|
|
|
|
$model->receipt_order_count, |
|
|
|
|
|
$model->sms_send_count, |
|
|
|
|
|
$model->sms_send_cost, |
|
|
|
|
|
) |
|
|
|
|
|
); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
$model->save(); |
|
|
|
|
|
|
|
|
|
|
|
$deleteTargets = UseByKeySummary::whereContractId($model->contract_id) |
|
|
|
|
|
->whereSummaryYyyymm($this->targetYYYYMM) |
|
|
|
|
|
->get(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
foreach ($summaryByKeys as $summary) { |
|
|
|
|
|
|
|
|
|
|
|
if (!($summary instanceof UseByKeySummary)) { |
|
|
|
|
|
throw new LogicException("モデル不正"); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
$summary->save(); |
|
|
|
|
|
|
|
|
|
|
|
$deleteTargets = $deleteTargets->reject(function ($ele) use ($summary) { |
|
|
|
|
|
return $ele->summary_key1 === $summary->summary_key1 && $ele->summary_key2 === $summary->summary_key2; |
|
|
|
|
|
}); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
foreach ($deleteTargets as $ele) { |
|
|
|
|
|
$ele->delete(); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private function getUseByKeyModel(UseSummary $model, ?string $key1, ?string $key2): UseByKeySummary |
|
|
|
|
|
{ |
|
|
|
|
|
|
|
|
|
|
|
$query = UseByKeySummary::whereContractId($model->contract_id) |
|
|
|
|
|
->whereSummaryYyyymm($this->targetYYYYMM); |
|
|
|
|
|
if ($key1 === null) { |
|
|
|
|
|
$query->whereNull(UseByKeySummary::COL_NAME_SUMMARY_KEY1); |
|
|
|
|
|
} else { |
|
|
|
|
|
$query->whereSummaryKey1($key1); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if ($key2 === null) { |
|
|
|
|
|
$query->whereNull(UseByKeySummary::COL_NAME_SUMMARY_KEY2); |
|
|
|
|
|
} else { |
|
|
|
|
|
$query->whereSummaryKey2($key2); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
$summary = $query->firstOrNew([ |
|
|
|
|
|
UseByKeySummary::COL_NAME_CONTRACT_ID => $model->contract_id, |
|
|
|
|
|
UseByKeySummary::COL_NAME_SUMMARY_YYYYMM => $this->targetYYYYMM, |
|
|
|
|
|
UseByKeySummary::COL_NAME_SUMMARY_KEY1 => $key1, |
|
|
|
|
|
UseByKeySummary::COL_NAME_SUMMARY_KEY2 => $key2, |
|
|
|
|
|
]); |
|
|
|
|
|
|
|
|
|
|
|
$currentYYYYMM = intval(DateUtil::now()->format('Ym')); |
|
|
|
|
|
$targetYYYYMM = intval($this->targetYYYYMM); |
|
|
|
|
|
if ($targetYYYYMM < $currentYYYYMM) { |
|
|
|
|
|
$summary->is_fixed = true; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return $summary; |
|
|
|
|
|
} |
|
|
|
|
|
} |