File "Payment.php"
Full Path: /var/www/html/back/app/Models/Payment.php
File size: 7.18 KB
MIME-type: text/x-php
Charset: utf-8
<?php
declare(strict_types=1);
namespace App\Models;
use App\BaseClasses\BasePaymentStatusModel;
use App\Domain\Payment\Enums\PaymentStatusEnum;
use App\Domain\Payment\Enums\PaymentTypeEnum;
use App\Domain\Payment\PaymentLogService;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\MorphMany;
use Illuminate\Support\Carbon;
use Spatie\MediaLibrary\HasMedia;
use Spatie\MediaLibrary\InteractsWithMedia;
/**
* @property int $id
* @property int $creator_id
* @property int $model_id
* @property string $name
* @property string $status
* @property string $payment_type
* @property string|Carbon $payment_date
* @property float $amount
* @property int $organization_id
* @property int $account_id
* @property int $contragent_id
* @property Carbon $created_at
* @property Carbon $updated_at
* @property Organization $organization
* @property Counterparty $contragent
* @property Account $account
* @property User $creator
* @property Collection|PaymentDistribution[] $distributions
* @property Collection|PaymentLog[] $logs
* @property string[] $availableStatuses
* @property Collection|Media[] $files
*/
class Payment extends Model implements HasMedia
{
use HasFactory;
use InteractsWithMedia;
protected $fillable = [
'model_id',
'user_id',
'name',
'status',
'payment_type',
'payment_date',
'amount',
'organization_id',
'counterparty_id',
'account_id',
'external_id',
'purpose_of_payment_1c',
'note_1c',
'account_debit_1c',
'actual_date',
'current_balance',
'cash_account_id'
];
protected $appends = [
'availableStatuses', 'articleTitle', 'projectTitle'
];
protected $casts = [
'amount' => 'decimal:2',
];
// protected function casts(): array
// {
// return [
// 'status' => PaymentStatusEnum::class,
// 'payment_type' => PaymentTypeEnum::class,
// ];
// }
public static function paymentsByArticleIDQuery($articleID)
{
return
Payment::query()->with([
'distributions',
'distributions.article',
]);
}
public function fillWithLogs(): Payment
{
$this->setRelation('logs', $this->logs->map(fn($log) => PaymentLogService::readableArrayFromRecord($log)));
return $this;
}
public function fillWithDistribution(): self
{
//ЛИМИТЫ (сумма) минус ПЛАТЕЖИ (сумма) минус ТЕКУЩИЙ ПЛАТЕЖТ = ОСТАТОК
$data = [];
foreach ($this->distributions as $i => $distribution) {
if (empty($distribution->article) || (empty($distribution->article->articleProjectLinks()))) {
continue;
}
$distribution->article->articleProjectLinks
->each(function (ArticleToProject $projectLink) use (&$data, $distribution, $i): void {
$limit = $projectLink->amount_limit;
$payments = static::paymentsByArticleIDQuery($projectLink->article_id)
->where('status', PaymentStatusEnum::STATUS_PAID->value)->get()->sum('distributions.amount');
if (!isset($data[$i])) {
$data[$i] = [
'limits' => $limit,
'sum' => $payments,
];
} else {
$data[$i]['sum'] += $payments;
$data[$i]['limits'] += $limit;
}
});
$this->distributions[$i]->attributes['current_limits'] = [
'limits' => $data[$i]['limits'] ?? 0,
'sum' => $data[$i]['sum'] ?? 0,
'delta' => (($data[$i]['limits'] ?? 0) - ($data[$i]['sum'] ?? 0)),
];
}
return $this;
}
public function getArticleTitleAttribute(): string
{
$titles = [];
/** @var PaymentDistribution $distribution */
foreach ($this->distributions()->get() as $distribution) {
if (!empty($distribution->article)) {
$titles[] = $distribution->article->name;
}
}
$titles = array_unique($titles);
return (count($titles) > 1) ? 'Несколько статей' : $titles[0] ?? '';
}
public function getProjectTitleAttribute(): string
{
$titles = [];
/** @var PaymentDistribution $distribution */
foreach ($this->distributions()->get() as $distribution) {
if (!empty($distribution->project)) {
$titles[] = $distribution->project->short_description;
}
}
$titles = array_unique($titles);
return (count($titles) > 1) ? 'Несколько проектов' : $titles[0] ?? '';
}
public function files(): MorphMany
{
return $this->media();
}
public function organization(): BelongsTo
{
return $this->belongsTo(Organization::class);
}
public function contragent(): BelongsTo
{
return $this->belongsTo(Counterparty::class, 'counterparty_id');
}
public function creator(): BelongsTo
{
return $this->belongsTo(User::class, 'user_id');
}
public function account(): BelongsTo
{
return $this->belongsTo(Account::class, 'account_id');
}
public function distributions(): HasMany
{
return $this->hasMany(PaymentDistribution::class);
}
public function logs()
{
return $this->hasMany(PaymentLog::class);
}
/**
* @throws \Exception
*/
public function getCurrentStatusModel(): BasePaymentStatusModel
{
return BasePaymentStatusModel::getModelFromStatus(
PaymentStatusEnum::tryFrom($this->status),
PaymentTypeEnum::tryFrom($this->payment_type)
);
}
/**
* @throws \Exception
*/
public function getAvailableStatusesAttribute(): array
{
$result = [];
foreach (BasePaymentStatusModel::getModelFromStatus(
PaymentStatusEnum::tryFrom($this->status),
PaymentTypeEnum::tryFrom($this->payment_type)
)->getAvailableStatuses() as $status) {
$enum = PaymentStatusEnum::from($status);
$result[$status] = [
'name' => $enum->title(),
'status' => $enum->value,
];
};
return $result;
}
public function getLastCommentAttribute(): ?string
{
$comment = $this->logs()->orderBy('id', 'DESC')->first();
return $comment ? $comment->comment : null;
}
public function getLastStatusAttribute(): ?array
{
$status = $this->logs()->where('status', '!=', $this->status)->orderBy('id', 'DESC')->first();
return $status ? [
'title' => PaymentStatusEnum::from($status->status)->title(),
'name' => $status->status,
] : null;
}
}