All checks were successful
Deploy preview (main_go) / deploy (push) Successful in 14s
- SHJ-9: 日次売上集計処理 - SHJ-10: 年次月次売上集計処理 - SHJ-6: サーバ死活監視処理 - 各種モデルサービスコマンド追加 - earnings_summary, device, hardware_check_log, print_job_log テーブル用SQL追加
299 lines
9.3 KiB
PHP
299 lines
9.3 KiB
PHP
<?php
|
||
|
||
namespace App\Models;
|
||
|
||
use Illuminate\Database\Eloquent\Model;
|
||
use Carbon\Carbon;
|
||
|
||
/**
|
||
* 売上集計結果モデル - earnings_summaryテーブル
|
||
*
|
||
* SHJ-9で作成される日次・月次・年次の売上集計データを管理
|
||
*/
|
||
class EarningsSummary extends Model
|
||
{
|
||
/**
|
||
* テーブル名
|
||
*
|
||
* @var string
|
||
*/
|
||
protected $table = 'earnings_summary';
|
||
|
||
/**
|
||
* プライマリキー
|
||
*
|
||
* @var string
|
||
*/
|
||
protected $primaryKey = 'earnings_summary_id';
|
||
|
||
/**
|
||
* 一括代入可能な属性
|
||
*
|
||
* @var array
|
||
*/
|
||
protected $fillable = [
|
||
'park_id', // 駐輪場ID
|
||
'summary_type', // 集計区分
|
||
'summary_start_date', // 集計開始日
|
||
'summary_end_date', // 集計終了日
|
||
'earnings_date', // 売上日
|
||
'psection_id', // 車種区分ID
|
||
'usertype_subject1', // 規格
|
||
'enable_months', // 期間(月数)
|
||
'regular_new_count', // 期間件数
|
||
'regular_new_amount', // 期間金額
|
||
'regular_new_reduction_count', // 期間成免件数
|
||
'regular_new_reduction_amount', // 期間成免金額
|
||
'regular_update_count', // 更新件数
|
||
'regular_update_amount', // 更新金額
|
||
'regular_update_reduction_count', // 更新成免件数
|
||
'regular_update_reduction_amount', // 更新成免金額
|
||
'turnsum_count', // 残金件数
|
||
'turnsum', // 残金
|
||
'refunds', // 解時返戻金
|
||
'other_income', // 分別収入
|
||
'other_spending', // 分別支出
|
||
'reissue_count', // 発行件数
|
||
'reissue_amount', // 発行金額
|
||
'summary_note', // 計備考
|
||
'created_at', // 登録日時
|
||
'updated_at', // 更新日時
|
||
'operator_id' // 新法・ページID
|
||
];
|
||
|
||
/**
|
||
* キャストする属性
|
||
*
|
||
* @var array
|
||
*/
|
||
protected $casts = [
|
||
'earnings_summary_id' => 'integer',
|
||
'park_id' => 'integer',
|
||
'psection_id' => 'integer',
|
||
'enable_months' => 'integer',
|
||
'regular_new_count' => 'integer',
|
||
'regular_new_amount' => 'decimal:2',
|
||
'regular_new_reduction_count' => 'integer',
|
||
'regular_new_reduction_amount' => 'decimal:2',
|
||
'regular_update_count' => 'integer',
|
||
'regular_update_amount' => 'decimal:2',
|
||
'regular_update_reduction_count' => 'integer',
|
||
'regular_update_reduction_amount' => 'decimal:2',
|
||
'turnsum_count' => 'integer',
|
||
'turnsum' => 'decimal:2',
|
||
'refunds' => 'decimal:2',
|
||
'other_income' => 'decimal:2',
|
||
'other_spending' => 'decimal:2',
|
||
'reissue_count' => 'integer',
|
||
'reissue_amount' => 'decimal:2',
|
||
'operator_id' => 'integer',
|
||
'summary_start_date' => 'date',
|
||
'summary_end_date' => 'date',
|
||
'earnings_date' => 'date',
|
||
'created_at' => 'datetime',
|
||
'updated_at' => 'datetime'
|
||
];
|
||
|
||
/**
|
||
* 日付属性
|
||
*
|
||
* @var array
|
||
*/
|
||
protected $dates = [
|
||
'summary_start_date',
|
||
'summary_end_date',
|
||
'earnings_date',
|
||
'created_at',
|
||
'updated_at'
|
||
];
|
||
|
||
/**
|
||
* 集計タイプの定数
|
||
*/
|
||
const TYPE_DAILY = '日次';
|
||
const TYPE_MONTHLY = '月次';
|
||
const TYPE_YEARLY = '年次';
|
||
|
||
/**
|
||
* 駐輪場との関連
|
||
*
|
||
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
|
||
*/
|
||
public function park()
|
||
{
|
||
return $this->belongsTo(Park::class, 'park_id', 'park_id');
|
||
}
|
||
|
||
/**
|
||
* 車種区分との関連
|
||
*
|
||
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
|
||
*/
|
||
public function psection()
|
||
{
|
||
return $this->belongsTo(Psection::class, 'psection_id', 'psection_id');
|
||
}
|
||
|
||
/**
|
||
* 指定期間の売上集計データを取得
|
||
*
|
||
* @param int $parkId 駐輪場ID
|
||
* @param string $startDate 開始日
|
||
* @param string $endDate 終了日
|
||
* @param string|null $summaryType 集計タイプ
|
||
* @return \Illuminate\Database\Eloquent\Collection
|
||
*/
|
||
public static function getEarningsByPeriod(int $parkId, string $startDate, string $endDate, ?string $summaryType = null)
|
||
{
|
||
$query = self::where('park_id', $parkId)
|
||
->whereBetween('earnings_date', [$startDate, $endDate]);
|
||
|
||
if ($summaryType) {
|
||
$query->where('summary_type', $summaryType);
|
||
}
|
||
|
||
return $query->with(['park', 'psection'])
|
||
->orderBy('earnings_date')
|
||
->orderBy('psection_id')
|
||
->get();
|
||
}
|
||
|
||
/**
|
||
* 駐輪場別の売上合計を取得
|
||
*
|
||
* @param int $parkId 駐輪場ID
|
||
* @param string $startDate 開始日
|
||
* @param string $endDate 終了日
|
||
* @return array 売上合計データ
|
||
*/
|
||
public static function getEarningsTotalByPark(int $parkId, string $startDate, string $endDate): array
|
||
{
|
||
$result = self::where('park_id', $parkId)
|
||
->whereBetween('earnings_date', [$startDate, $endDate])
|
||
->selectRaw('
|
||
SUM(regular_new_count) as total_new_count,
|
||
SUM(regular_new_amount) as total_new_amount,
|
||
SUM(regular_update_count) as total_update_count,
|
||
SUM(regular_update_amount) as total_update_amount,
|
||
SUM(turnsum_count) as total_turnsum_count,
|
||
SUM(turnsum) as total_turnsum,
|
||
SUM(refunds) as total_refunds,
|
||
SUM(reissue_count) as total_reissue_count,
|
||
SUM(reissue_amount) as total_reissue_amount
|
||
')
|
||
->first();
|
||
|
||
return $result ? $result->toArray() : [];
|
||
}
|
||
|
||
/**
|
||
* 最新の集計日を取得
|
||
*
|
||
* @param int|null $parkId 駐輪場ID(省略時は全体)
|
||
* @param string|null $summaryType 集計タイプ
|
||
* @return string|null 最新集計日
|
||
*/
|
||
public static function getLatestEarningsDate(?int $parkId = null, ?string $summaryType = null): ?string
|
||
{
|
||
$query = self::query();
|
||
|
||
if ($parkId) {
|
||
$query->where('park_id', $parkId);
|
||
}
|
||
|
||
if ($summaryType) {
|
||
$query->where('summary_type', $summaryType);
|
||
}
|
||
|
||
$latest = $query->max('earnings_date');
|
||
|
||
return $latest ? Carbon::parse($latest)->format('Y-m-d') : null;
|
||
}
|
||
|
||
/**
|
||
* 期間の売上データを削除
|
||
*
|
||
* @param int $parkId 駐輪場ID
|
||
* @param string $startDate 開始日
|
||
* @param string $endDate 終了日
|
||
* @param string|null $summaryType 集計タイプ
|
||
* @return int 削除件数
|
||
*/
|
||
public static function deleteEarningsByPeriod(int $parkId, string $startDate, string $endDate, ?string $summaryType = null): int
|
||
{
|
||
$query = self::where('park_id', $parkId)
|
||
->where('summary_start_date', $startDate)
|
||
->where('summary_end_date', $endDate);
|
||
|
||
if ($summaryType) {
|
||
$query->where('summary_type', $summaryType);
|
||
}
|
||
|
||
return $query->delete();
|
||
}
|
||
|
||
/**
|
||
* 売上集計データの作成
|
||
*
|
||
* @param array $data 売上データ
|
||
* @return EarningsSummary 作成されたモデル
|
||
*/
|
||
public static function createEarningsSummary(array $data): EarningsSummary
|
||
{
|
||
$defaultData = [
|
||
'regular_new_count' => 0,
|
||
'regular_new_amount' => 0.00,
|
||
'regular_new_reduction_count' => 0,
|
||
'regular_new_reduction_amount' => 0.00,
|
||
'regular_update_count' => 0,
|
||
'regular_update_amount' => 0.00,
|
||
'regular_update_reduction_count' => 0,
|
||
'regular_update_reduction_amount' => 0.00,
|
||
'turnsum_count' => 0,
|
||
'turnsum' => 0.00,
|
||
'refunds' => 0.00,
|
||
'other_income' => 0.00,
|
||
'other_spending' => 0.00,
|
||
'reissue_count' => 0,
|
||
'reissue_amount' => 0.00,
|
||
'operator_id' => 0
|
||
];
|
||
|
||
$mergedData = array_merge($defaultData, $data);
|
||
|
||
return self::create($mergedData);
|
||
}
|
||
|
||
/**
|
||
* 売上合計の計算
|
||
*
|
||
* @return float 売上合計
|
||
*/
|
||
public function getTotalEarningsAttribute(): float
|
||
{
|
||
return $this->regular_new_amount +
|
||
$this->regular_update_amount +
|
||
$this->turnsum +
|
||
$this->reissue_amount +
|
||
$this->other_income -
|
||
$this->other_spending -
|
||
$this->refunds;
|
||
}
|
||
|
||
/**
|
||
* 文字列表現
|
||
*
|
||
* @return string
|
||
*/
|
||
public function __toString(): string
|
||
{
|
||
return sprintf(
|
||
'EarningsSummary[ID:%d, Park:%d, Type:%s, Date:%s]',
|
||
$this->earnings_summary_id,
|
||
$this->park_id,
|
||
$this->summary_type,
|
||
$this->earnings_date ? $this->earnings_date->format('Y-m-d') : 'N/A'
|
||
);
|
||
}
|
||
}
|