hash_id}: Menambah {$quantity} stok ke Gudang.", performedOn: $product, warehouse: $purchase->warehouse, quantityChange: $quantity, previousStock: $previousStock, newStock: $newStock, extraProperties: [ 'purchase_id' => $purchase->id, 'purchase_hash' => $purchase->hash_id, ], causedBy: $causedBy ); } /** * Log distribution activity (Warehouse to Outlet). * This logs two events: Out from Warehouse, In to Outlet. */ public static function distribution( Restock $restock, Model $product, int $quantity, int $warehousePreviousStock, int $warehouseNewStock, int $outletPreviousStock, int $outletNewStock, ?Model $causedBy = null ): void { // Log Warehouse Out self::logWarehouse( logName: self::LOG_DISTRIBUTION, event: 'decrease', description: "Restock #{$restock->hash_id}: Memindahkan {$quantity} stok dari Gudang ke Outlet.", performedOn: $product, warehouse: $restock->warehouse, quantityChange: -1 * abs($quantity), previousStock: $warehousePreviousStock, newStock: $warehouseNewStock, extraProperties: [ 'restock_id' => $restock->id, 'restock_hash' => $restock->hash_id, 'target_outlet_id' => $restock->outlet_id, ], causedBy: $causedBy ); // Log Outlet In self::logOutlet( logName: self::LOG_DISTRIBUTION, event: 'increase', description: "Restock #{$restock->hash_id}: Menerima {$quantity} stok dari Gudang.", performedOn: $product, outlet: $restock->outlet, quantityChange: abs($quantity), previousStock: $outletPreviousStock, newStock: $outletNewStock, extraProperties: [ 'restock_id' => $restock->id, 'restock_hash' => $restock->hash_id, 'source_warehouse_id' => $restock->warehouse_id, ], causedBy: $causedBy ); } /** * Log sale activity (Outlet to Customer). */ public static function sale( Order $order, Model $product, int $quantity, int $previousStock, int $newStock, ?Model $causedBy = null ): void { self::logOutlet( logName: self::LOG_SALE, event: 'decrease', description: "Pesanan #{$order->hash_id}: Menjual {$quantity} item.", performedOn: $product, outlet: $order->outlet, quantityChange: -1 * abs($quantity), previousStock: $previousStock, newStock: $newStock, extraProperties: [ 'order_id' => $order->id, 'order_hash' => $order->hash_id, ], causedBy: $causedBy ?? $order->user ); } /** * Log stock opname activity (Adjustment in Outlet). */ public static function stockOpname( StockOpname $stockOpname, Model $product, int $quantityChange, int $previousStock, int $newStock, ?string $note = null, ?Model $causedBy = null ): void { $event = $quantityChange > 0 ? 'increase' : 'decrease'; self::logOutlet( logName: self::LOG_STOCK_OPNAME, event: $event, description: "Stock Opname #{$stockOpname->hash_id}: Penyesuaian stok sebesar {$quantityChange}.", performedOn: $product, outlet: $stockOpname->outlet, quantityChange: $quantityChange, previousStock: $previousStock, newStock: $newStock, extraProperties: [ 'stock_opname_id' => $stockOpname->id, 'stock_opname_hash' => $stockOpname->hash_id, 'note' => $note, ], causedBy: $causedBy ); } /** * Log transfer activity (Outlet to Outlet). * This logs two events: Out from Source Outlet, In to Destination Outlet. */ public static function transfer( StockTransfer $stockTransfer, Model $product, int $quantity, int $sourcePreviousStock, int $sourceNewStock, int $destinationPreviousStock, int $destinationNewStock, ?Model $causedBy = null ): void { // Log Source Outlet Out self::logOutlet( logName: self::LOG_TRANSFER, event: 'decrease', description: "Transfer Stok #{$stockTransfer->hash_id}: Memindahkan {$quantity} stok dari Outlet Asal ke Outlet Tujuan.", performedOn: $product, outlet: $stockTransfer->sourceOutlet, quantityChange: -1 * abs($quantity), previousStock: $sourcePreviousStock, newStock: $sourceNewStock, extraProperties: [ 'stock_transfer_id' => $stockTransfer->id, 'stock_transfer_hash' => $stockTransfer->hash_id, 'destination_outlet_id' => $stockTransfer->destination_outlet_id, ], causedBy: $causedBy ); // Log Destination Outlet In self::logOutlet( logName: self::LOG_TRANSFER, event: 'increase', description: "Transfer Stok #{$stockTransfer->hash_id}: Menerima {$quantity} stok dari Outlet Asal.", performedOn: $product, outlet: $stockTransfer->destinationOutlet, quantityChange: abs($quantity), previousStock: $destinationPreviousStock, newStock: $destinationNewStock, extraProperties: [ 'stock_transfer_id' => $stockTransfer->id, 'stock_transfer_hash' => $stockTransfer->hash_id, 'source_outlet_id' => $stockTransfer->source_outlet_id, ], causedBy: $causedBy ); } /** * Generic log method that delegates to logOutlet or logWarehouse. */ public static function log( string $logName, string $event, string $description, Model $performedOn, ?Model $outlet = null, ?Warehouse $warehouse = null, int $quantityChange = 0, int $previousStock = 0, int $newStock = 0, array $extraProperties = [], ?Model $causedBy = null ): void { if ($warehouse) { self::logWarehouse( logName: $logName, event: $event, description: $description, performedOn: $performedOn, warehouse: $warehouse, quantityChange: $quantityChange, previousStock: $previousStock, newStock: $newStock, extraProperties: $extraProperties, causedBy: $causedBy ); return; } if ($outlet) { self::logOutlet( logName: $logName, event: $event, description: $description, performedOn: $performedOn, outlet: $outlet, quantityChange: $quantityChange, previousStock: $previousStock, newStock: $newStock, extraProperties: $extraProperties, causedBy: $causedBy ); } } /** * Log stock related activity for Outlet. */ public static function logOutlet( string $logName, string $event, string $description, Model $performedOn, Model $outlet, int $quantityChange, int $previousStock, int $newStock, array $extraProperties = [], ?Model $causedBy = null ): void { $causedBy = $causedBy ?: auth()->user(); $properties = array_merge([ 'outlet_id' => $outlet->getKey(), 'quantity_change' => $quantityChange, 'previous_stock' => $previousStock, 'new_stock' => $newStock, 'location_type' => 'outlet', 'location_name' => $outlet->name ?? 'Outlet Tidak Diketahui', ], $extraProperties); activity($logName) ->performedOn($performedOn) ->causedBy($causedBy) ->withProperties($properties) ->event($event) ->log($description); } /** * Log stock related activity for Warehouse. */ public static function logWarehouse( string $logName, string $event, string $description, Model $performedOn, Warehouse $warehouse, int $quantityChange, int $previousStock, int $newStock, array $extraProperties = [], ?Model $causedBy = null ): void { $causedBy = $causedBy ?: auth()->user(); $properties = array_merge([ 'warehouse_id' => $warehouse->getKey(), 'quantity_change' => $quantityChange, 'previous_stock' => $previousStock, 'new_stock' => $newStock, 'location_type' => 'warehouse', 'location_name' => $warehouse->name ?? 'Gudang Tidak Diketahui', ], $extraProperties); activity($logName) ->performedOn($performedOn) ->causedBy($causedBy) ->withProperties($properties) ->event($event) ->log($description); } }