76 lines
2.4 KiB
PHP
76 lines
2.4 KiB
PHP
<?php
|
|
|
|
namespace App\Integrations\Whmcs\Transformers;
|
|
|
|
use App\Integrations\Whmcs\DTOs\OrderItemData;
|
|
use App\Integrations\Whmcs\Support\OrderIdResolver;
|
|
use App\Integrations\Whmcs\Support\ProductIdResolver;
|
|
use Illuminate\Support\Facades\DB;
|
|
|
|
class OrderItemTransformer
|
|
{
|
|
/** WHMCS tblhosting.billingcycle label => [billing_cycle, months] */
|
|
private const CYCLES = [
|
|
'Monthly' => ['monthly', 1],
|
|
'Quarterly' => ['quarterly', 3],
|
|
'Semi-Annually' => ['semi_annually', 6],
|
|
'Annually' => ['annually', 12],
|
|
'Biennially' => ['biennially', 24],
|
|
'Triennially' => ['triennially', 36],
|
|
];
|
|
|
|
public function __construct(
|
|
private OrderIdResolver $orders,
|
|
private ProductIdResolver $products,
|
|
) {
|
|
}
|
|
|
|
public function transform(array|object $row): OrderItemData
|
|
{
|
|
$row = (array) $row;
|
|
[$billingCycle, $months] = self::CYCLES[$row['billingcycle']] ?? ['one_time', 0];
|
|
|
|
$productId = $this->products->resolve((int) $row['packageid']);
|
|
|
|
return new OrderItemData(
|
|
legacyId: (int) $row['id'],
|
|
orderId: $this->orders->resolve((int) $row['orderid']),
|
|
productId: $productId,
|
|
productPricingId: $productId ? $this->productPricingId($productId, $billingCycle) : null,
|
|
serverName: $row['domain'] ?: null,
|
|
domainName: $row['domain'] ?: null,
|
|
billingCycle: $billingCycle,
|
|
months: $months,
|
|
quantity: (int) ($row['qty'] ?: 1),
|
|
price: $this->price($row),
|
|
createdAt: $this->nullableDate($row['created_at'] ?? null),
|
|
updatedAt: $this->nullableDate($row['updated_at'] ?? null),
|
|
);
|
|
}
|
|
|
|
/** One-time services carry their price in firstpaymentamount, not the (0.00) recurring amount. */
|
|
private function price(array $row): int
|
|
{
|
|
$amount = (float) $row['amount'];
|
|
|
|
return (int) round($amount > 0 ? $amount : (float) $row['firstpaymentamount']);
|
|
}
|
|
|
|
private function productPricingId(int $productId, string $billingCycle): ?int
|
|
{
|
|
return DB::table('product_pricings')
|
|
->where('product_id', $productId)
|
|
->where('billing_cycle', $billingCycle)
|
|
->value('id');
|
|
}
|
|
|
|
private function nullableDate(?string $value): ?string
|
|
{
|
|
if (! $value || (int) substr($value, 0, 4) < 1970) {
|
|
return null;
|
|
}
|
|
|
|
return $value;
|
|
}
|
|
}
|