so-manager-dev.com/app/Models/EarningsSummary.php
2025-09-19 19:01:21 +09:00

299 lines
9.3 KiB
PHP
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?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'
);
}
}