store/app/Support/OwnerVerification/VerificationChangeFormatter.php
Yoga Pangestu cf5b300895
Some checks are pending
linter / quality (push) Waiting to run
tests / ci (8.3) (push) Waiting to run
tests / ci (8.4) (push) Waiting to run
tests / ci (8.5) (push) Waiting to run
Refactor product status management: replace is_active with status enum
- Updated the OwnerVerificationRequest model to change pendingToggleIsActive to pendingToggleStatus, reflecting the new status structure.
- Refactored the Product model to replace is_active with status, utilizing the ProductStatus enum for better clarity and type safety.
- Modified the ProductService to accommodate the new status field, including pagination and creation logic.
- Adjusted the AnalysisService to filter products based on their status.
- Updated the VerificationChangeFormatter to handle the new status field.
- Created a migration to remove is_active from the products table and add status with appropriate default values.
- Refactored the ProductSeeder to use the new status field.
- Updated frontend components and types to reflect the changes from is_active to status.
- Adjusted tests to ensure they validate the new status logic correctly.
2026-07-18 16:34:34 +07:00

210 lines
7.2 KiB
PHP

<?php
namespace App\Support\OwnerVerification;
use App\Enums\PriceType;
use App\Enums\ProductStatus;
class VerificationChangeFormatter
{
/**
* @var list<string>
*/
private const HIDDEN_FIELDS = [
'category_ids',
'unit',
'variant_name',
'product_name',
];
/**
* @param array{old?: array<string, mixed>|null, new?: array<string, mixed>|null} $payload
* @return list<array{field: string, old: mixed, new: mixed}>
*/
public static function format(array $payload): array
{
$old = $payload['old'] ?? null;
$new = $payload['new'] ?? null;
if (! is_array($old) && ! is_array($new)) {
return [];
}
$fields = array_unique(array_merge(
array_keys(is_array($old) ? $old : []),
array_keys(is_array($new) ? $new : []),
));
$changes = [];
foreach ($fields as $field) {
if (in_array($field, self::HIDDEN_FIELDS, true)) {
continue;
}
$oldValue = is_array($old) ? ($old[$field] ?? null) : null;
$newValue = is_array($new) ? ($new[$field] ?? null) : null;
if ($oldValue === $newValue) {
continue;
}
$changes[] = [
'field' => self::label((string) $field),
'old' => self::presentValue($field, $oldValue),
'new' => self::presentValue($field, $newValue),
];
}
return $changes;
}
private static function label(string $field): string
{
return match ($field) {
'name' => 'Nama',
'description' => 'Deskripsi',
'category_names' => 'Kategori',
'supplier_name' => 'Supplier',
'supplier_id' => 'Supplier',
'subtotal' => 'Subtotal',
'discount' => 'Diskon',
'total' => 'Total',
'notes' => 'Keterangan',
'items' => 'Item Belanja',
'has_photos' => 'Foto Bukti',
'unit' => 'Satuan',
'unit_label' => 'Satuan',
'status' => 'Status',
'variants' => 'Varian',
'prices' => 'Varian Harga',
'quantity' => 'Perubahan Stok Ecer',
'stock' => 'Stok Bagus',
'retail_stock' => 'Stok Ecer',
'variant_name' => 'Varian',
'product_name' => 'Produk',
'tiktok_shop_platform_commission' => 'TikTok Shop - Komisi Platform',
'tiktok_shop_logistics_service_fee' => 'TikTok Shop - Biaya Logistik',
'tiktok_shop_dynamic_commission' => 'TikTok Shop - Komisi Dinamis',
'tiktok_shop_order_processing_fee' => 'TikTok Shop - Biaya Proses Pesanan',
'tiktok_shop_affiliate' => 'TikTok Shop - Komisi Affiliate',
'tiktok_shop_pre_order_service_fee' => 'TikTok Shop - Biaya Pre Order',
'shopee_admin_fee' => 'Shopee - Biaya Admin',
'shopee_program_fee' => 'Shopee - Biaya Program',
'shopee_shipping_savings' => 'Shopee - Hemat Biaya Kirim',
'shopee_premium' => 'Shopee - Premi',
'shopee_service_fee' => 'Shopee - Biaya Layanan',
'shopee_order_processing_fee' => 'Shopee - Biaya Proses Pesanan',
'shopee_ams_commission_fee' => 'Shopee - Komisi AMS',
'shopee_pre_order' => 'Shopee - Pre Order',
'shopee_live_extra' => 'Shopee - Live Extra',
default => ucfirst(str_replace('_', ' ', $field)),
};
}
private static function presentValue(string $field, mixed $value): mixed
{
if ($value === null) {
return null;
}
if ($field === 'status') {
$status = ProductStatus::tryFrom((string) $value);
return $status?->label() ?? $value;
}
$marketplaceKeys = [
'tiktok_shop_platform_commission',
'tiktok_shop_logistics_service_fee',
'tiktok_shop_dynamic_commission',
'tiktok_shop_order_processing_fee',
'tiktok_shop_affiliate',
'tiktok_shop_pre_order_service_fee',
'shopee_admin_fee',
'shopee_program_fee',
'shopee_shipping_savings',
'shopee_premium',
'shopee_service_fee',
'shopee_order_processing_fee',
'shopee_ams_commission_fee',
'shopee_pre_order',
'shopee_live_extra',
];
if (in_array($field, $marketplaceKeys, true)) {
if (! is_array($value) || ! isset($value['scope'], $value['value_type'], $value['value'])) {
return is_array($value) ? json_encode($value) : (string) $value;
}
$val = $value['value'];
$formattedValue = $value['value_type'] === 'percent'
? rtrim(rtrim(number_format($val, 2, ',', '.'), '0'), ',').'%'
: 'Rp '.number_format($val, 0, ',', '.');
$scopeStr = $value['scope'] === 'item' ? 'per Item' : 'per Transaksi';
return "{$formattedValue} ({$scopeStr})";
}
if ($field === 'variants' && is_array($value)) {
return collect($value)
->map(function (array $variant) {
$pricesStr = '';
if (! empty($variant['prices'])) {
$priceParts = [];
foreach ($variant['prices'] as $type => $price) {
$label = PriceType::tryFrom($type)?->label() ?? $type;
$priceParts[] = "{$label}: Rp ".number_format((int) $price, 0, ',', '.');
}
$pricesStr = ' ('.implode(', ', $priceParts).')';
}
return [
'name' => ($variant['name'] ?? '-').$pricesStr,
'stock' => (int) ($variant['stock'] ?? 0),
];
})
->values()
->all();
}
if ($field === 'prices' && is_array($value)) {
return collect($value)
->map(fn (array $price) => [
'variant' => $price['variant'] ?? '-',
'stock' => (int) ($price['stock'] ?? 0),
'price' => (int) ($price['price'] ?? 0),
])
->values()
->all();
}
if ($field === 'items' && is_array($value)) {
return collect($value)
->map(fn (array $item) => [
'raw_material_name' => $item['raw_material_name'] ?? '-',
'variant' => $item['variant'] ?? '-',
'quantity' => (int) ($item['quantity'] ?? 0),
'subtotal' => (int) ($item['subtotal'] ?? 0),
])
->values()
->all();
}
if ($field === 'has_photos') {
return (bool) $value ? 'Ada' : 'Tidak ada';
}
if ($field === 'category_names' && is_array($value)) {
return implode(', ', $value);
}
if (in_array($field, ['quantity', 'stock', 'retail_stock'], true)) {
return (int) $value;
}
return $value;
}
}