70 lines
2.0 KiB
PHP
70 lines
2.0 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Support;
|
|
|
|
use App\Helpers\OrderHelper;
|
|
use App\Models\Addon;
|
|
use App\Models\Service;
|
|
|
|
class RenewalPricing
|
|
{
|
|
/** @return list<int> */
|
|
public static function validMonths(string $billingCycle): array
|
|
{
|
|
$cycleMonths = OrderHelper::cycleToMonths($billingCycle);
|
|
|
|
if ($cycleMonths > 24) {
|
|
return [$cycleMonths];
|
|
}
|
|
|
|
$maxMultiple = intdiv(24, $cycleMonths);
|
|
|
|
return array_map(static fn (int $n): int => $n * $cycleMonths, range(1, $maxMultiple));
|
|
}
|
|
|
|
public static function addonTotal(Service $service, int $cycles): int
|
|
{
|
|
return (int) array_sum(array_column(self::addonInvoiceItems($service, $cycles, 0), 'total_price'));
|
|
}
|
|
|
|
/** @return list<array<string, mixed>> */
|
|
public static function addonInvoiceItems(Service $service, int $cycles, int $months): array
|
|
{
|
|
$meta = array_filter(
|
|
(array) ($service->orderItem?->addons_meta ?? []),
|
|
static fn ($entry): bool => is_array($entry) && (int) ($entry['qty'] ?? 0) > 0,
|
|
);
|
|
|
|
if ($meta === []) {
|
|
return [];
|
|
}
|
|
|
|
$currentPrices = Addon::whereIn('id', array_column($meta, 'addon_id'))->pluck('price', 'id');
|
|
|
|
$items = [];
|
|
foreach ($meta as $entry) {
|
|
$qty = (int) $entry['qty'];
|
|
$unitPrice = (int) ($currentPrices[$entry['addon_id'] ?? null] ?? $entry['price'] ?? 0);
|
|
$totalPrice = $unitPrice * $qty * $cycles;
|
|
|
|
if ($totalPrice <= 0) {
|
|
continue;
|
|
}
|
|
|
|
$items[] = [
|
|
'product_id' => $service->product_id,
|
|
'type' => 'addon',
|
|
'description' => 'Addon: ' . ($entry['name'] ?? strtoupper((string) ($entry['code'] ?? ''))) . ' x' . $qty,
|
|
'months' => $months,
|
|
'quantity' => $qty,
|
|
'unit_price' => $unitPrice * $cycles,
|
|
'total_price' => $totalPrice,
|
|
];
|
|
}
|
|
|
|
return $items;
|
|
}
|
|
}
|