feat: remove subtotal from restock model, migration, and related components
This commit is contained in:
parent
e61f6fce7e
commit
5c1343d575
@ -225,8 +225,8 @@ ### `purchase_items` → PurchaseItem
|
||||
- Relations: purchase(BelongsTo→Purchase), rawMaterialPrice(BelongsTo→RawMaterialPrice,withTrashed), user(BelongsTo→User)
|
||||
|
||||
### `restocks` → Restock
|
||||
`id` `created_by_id`(FK→users) `subtotal`(ubig) `total`(ubig) `notes`(100,null) `stock_type`(enum,default:good) `created_at` `updated_at` `deleted_at`
|
||||
- Casts: stock_type(ProductStockQuality), subtotal(int), total(int)
|
||||
`id` `created_by_id`(FK→users) `total`(ubig) `notes`(100,null) `stock_type`(enum,default:good) `created_at` `updated_at` `deleted_at`
|
||||
- Casts: stock_type(ProductStockQuality), total(int)
|
||||
- Scopes: good(), reject()
|
||||
- Relations: createdBy(BelongsTo→User), restockItems(HasMany→RestockItem)
|
||||
|
||||
|
||||
@ -18,7 +18,7 @@
|
||||
use Spatie\MediaLibrary\InteractsWithMedia;
|
||||
use Spatie\MediaLibrary\MediaCollections\Models\Media;
|
||||
|
||||
#[Appends(['stock_type_label', 'formatted_subtotal', 'formatted_total'])]
|
||||
#[Appends(['stock_type_label', 'formatted_total'])]
|
||||
#[Guarded(['id'])]
|
||||
class Restock extends Model implements HasMedia
|
||||
{
|
||||
@ -28,7 +28,6 @@ protected function casts(): array
|
||||
{
|
||||
return [
|
||||
'stock_type' => ProductStockQuality::class,
|
||||
'subtotal' => 'integer',
|
||||
'total' => 'integer',
|
||||
];
|
||||
}
|
||||
@ -40,13 +39,6 @@ protected function stockTypeLabel(): Attribute
|
||||
);
|
||||
}
|
||||
|
||||
protected function formattedSubtotal(): Attribute
|
||||
{
|
||||
return Attribute::make(
|
||||
get: fn () => 'Rp '.number_format($this->subtotal, 0, ',', '.'),
|
||||
);
|
||||
}
|
||||
|
||||
protected function formattedTotal(): Attribute
|
||||
{
|
||||
return Attribute::make(
|
||||
|
||||
@ -16,7 +16,7 @@ public function migrate(): array
|
||||
$results['retail_stock_histories'] = $this->migrateTable('retail_stock_histories');
|
||||
$results['stok_opnames'] = $this->migrateTable('stok_opnames');
|
||||
$results['stok_opname_items'] = $this->migrateTable('stok_opname_items');
|
||||
$results['restocks'] = $this->migrateTable('restocks');
|
||||
$results['restocks'] = $this->migrateTableWithoutColumns('restocks', ['subtotal']);
|
||||
$results['restock_items'] = $this->migrateTable('restock_items');
|
||||
$results['stock_mutations'] = $this->migrateTable('stock_mutations', function ($row) {
|
||||
$fields = ['quantity', 'stock_before', 'stock_after'];
|
||||
|
||||
@ -26,7 +26,7 @@ public function __construct(
|
||||
public function paginated(int $perPage = 25, string $search = '', string $sort = 'created_at', string $direction = 'desc'): LengthAwarePaginator
|
||||
{
|
||||
$paginator = Restock::query()
|
||||
->select(['id', 'created_by_id', 'subtotal', 'total', 'notes', 'stock_type', 'created_at'])
|
||||
->select(['id', 'created_by_id', 'total', 'notes', 'stock_type', 'created_at'])
|
||||
->with([
|
||||
'createdBy:id',
|
||||
'createdBy.userProfile:id,user_id,full_name',
|
||||
@ -66,15 +66,14 @@ public function store(array $data): Restock
|
||||
{
|
||||
return DB::transaction(function () use ($data) {
|
||||
$now = now();
|
||||
$subtotal = 0;
|
||||
$total = 0;
|
||||
$stockType = $data['stock_type'] ?? ProductStockQuality::GOOD->value;
|
||||
|
||||
$itemRows = $this->buildItemRows($data['items'], $stockType, $now, $subtotal);
|
||||
$itemRows = $this->buildItemRows($data['items'], $stockType, $now, $total);
|
||||
|
||||
$restock = Restock::create([
|
||||
'created_by_id' => auth()->id(),
|
||||
'subtotal' => $subtotal,
|
||||
'total' => $subtotal,
|
||||
'total' => $total,
|
||||
'notes' => $data['notes'] ?? null,
|
||||
'stock_type' => $stockType,
|
||||
]);
|
||||
@ -90,7 +89,7 @@ public function store(array $data): Restock
|
||||
NotificationService::notify(
|
||||
roles: [Role::OWNER, Role::DEVELOPER, Role::ADMIN_TOKO],
|
||||
title: 'Restock Baru',
|
||||
body: 'Restock '.($stockType === ProductStockQuality::GOOD->value ? 'produk' : 'reject').' sebesar Rp '.number_format($subtotal, 0, ',', '.').' berhasil dicatat oleh '.auth()->user()->full_name.'.',
|
||||
body: 'Restock '.($stockType === ProductStockQuality::GOOD->value ? 'produk' : 'reject').' sebesar Rp '.number_format($total, 0, ',', '.').' berhasil dicatat oleh '.auth()->user()->full_name.'.',
|
||||
url: route('admin.manage.restocks.index'),
|
||||
);
|
||||
|
||||
@ -110,10 +109,10 @@ public function update(Restock $restock, array $data): Restock
|
||||
$restock->restockItems()->delete();
|
||||
|
||||
$now = now();
|
||||
$subtotal = 0;
|
||||
$total = 0;
|
||||
$stockType = $data['stock_type'] ?? $restock->stock_type->value;
|
||||
|
||||
$itemRows = $this->buildItemRows($data['items'], $stockType, $now, $subtotal);
|
||||
$itemRows = $this->buildItemRows($data['items'], $stockType, $now, $total);
|
||||
|
||||
foreach ($itemRows as &$row) {
|
||||
$row['restock_id'] = $restock->id;
|
||||
@ -121,8 +120,7 @@ public function update(Restock $restock, array $data): Restock
|
||||
DB::table('restock_items')->insert($itemRows);
|
||||
|
||||
$restock->update([
|
||||
'subtotal' => $subtotal,
|
||||
'total' => $subtotal,
|
||||
'total' => $total,
|
||||
'notes' => $data['notes'] ?? null,
|
||||
'stock_type' => $stockType,
|
||||
]);
|
||||
@ -150,7 +148,7 @@ public function destroy(Restock $restock): bool
|
||||
});
|
||||
}
|
||||
|
||||
private function buildItemRows(array $items, string $stockType, $now, int &$subtotal): array
|
||||
private function buildItemRows(array $items, string $stockType, $now, int &$total): array
|
||||
{
|
||||
$priceType = $stockType === ProductStockQuality::REJECT->value
|
||||
? PriceType::REJECT
|
||||
@ -168,11 +166,11 @@ private function buildItemRows(array $items, string $stockType, $now, int &$subt
|
||||
return [$variant->id => $price?->price ?? 0];
|
||||
});
|
||||
|
||||
return collect($items)->map(function ($item) use ($now, $prices, &$subtotal) {
|
||||
return collect($items)->map(function ($item) use ($now, $prices, &$total) {
|
||||
$quantity = (int) $item['quantity'];
|
||||
$unitPrice = (int) ($prices[$item['product_variant_id']] ?? 0);
|
||||
$itemSubtotal = $unitPrice * $quantity;
|
||||
$subtotal += $itemSubtotal;
|
||||
$total += $itemSubtotal;
|
||||
|
||||
return [
|
||||
'restock_id' => null,
|
||||
|
||||
@ -14,7 +14,6 @@ public function up(): void
|
||||
|
||||
$table->foreignId('created_by_id')->constrained('users')->cascadeOnDelete();
|
||||
|
||||
$table->unsignedBigInteger('subtotal');
|
||||
$table->unsignedBigInteger('total');
|
||||
$table->string('notes', 100)->nullable();
|
||||
$table->enum('stock_type', ProductStockQuality::values())->default(ProductStockQuality::GOOD->value);
|
||||
|
||||
@ -21,7 +21,6 @@ export type RestockItem = {
|
||||
export type Restock = {
|
||||
id: number;
|
||||
created_by_id: number;
|
||||
subtotal: number;
|
||||
total: number;
|
||||
notes: string | null;
|
||||
stock_type: RestockStockType;
|
||||
|
||||
@ -120,12 +120,6 @@ export function RestockCardRow({
|
||||
</span>
|
||||
{formatNumber(totalQty)}
|
||||
</span>
|
||||
<span>
|
||||
<span className="text-muted-foreground">
|
||||
Sub:{' '}
|
||||
</span>
|
||||
{formatCurrency(restock.subtotal)}
|
||||
</span>
|
||||
<span className="font-semibold">
|
||||
<span className="font-normal text-muted-foreground">
|
||||
Total:{' '}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user