Files
2026-06-23 16:04:37 +07:00

232 lines
7.5 KiB
PHP

<?php
namespace App\Services\Material;
use App\Models\TechnicianMaterial;
use App\Models\TechnicianConsumable;
use App\Models\MaterialMovement;
use Carbon\Carbon;
use DB;
class MaterialService
{
/*
|--------------------------------------------------------------------------
| ASSIGN MATERIAL (AUTO DETECT TYPE)
|--------------------------------------------------------------------------
*/
public function assign($data)
{
return DB::transaction(function () use ($data) {
$type = $data['type'];
// type dari API Gudang: serialized / consumable
/*
|--------------------------------------------------------------------------
| SERIALIZED (ONT, Router, dll)
|--------------------------------------------------------------------------
*/
if ($type === 'serialized') {
$material = TechnicianMaterial::create([
'user_id' => $data['user_id'],
'barcode_id' => $data['barcode_id'],
'material_name' => $data['material_name'],
'serial_number' => $data['serial_number'] ?? null,
'status' => 'assigned',
'assigned_at' => now(),
'assigned_by' => auth()->id(),
]);
MaterialMovement::create([
'barcode_id' => $data['barcode_id'],
'user_id' => $data['user_id'],
'to_user_id' => $data['user_id'],
'movement_type' => 'assign',
'created_by' => auth()->id(),
'created_at' => now(),
]);
return $material;
}
/*
|--------------------------------------------------------------------------
| CONSUMABLE (FO, kabel, dll)
|--------------------------------------------------------------------------
*/
$material = TechnicianConsumable::create([
'user_id' => $data['user_id'],
'barcode_id' => $data['barcode_id'],
'material_name' => $data['material_name'],
'unit' => $data['unit'] ?? 'meter',
'qty_received' => $data['qty'] ?? 0,
'qty_remaining' => $data['qty'] ?? 0,
'qty_used' => 0,
'status' => 'assigned',
'assigned_at' => now(),
'assigned_by' => auth()->id(),
]);
MaterialMovement::create([
'barcode_id' => $data['barcode_id'],
'user_id' => $data['user_id'],
'to_user_id' => $data['user_id'],
'movement_type' => 'assign',
'qty' => $data['qty'] ?? 0,
'created_by' => auth()->id(),
'created_at' => now(),
]);
return $material;
});
}
/*
|--------------------------------------------------------------------------
| TRANSFER MATERIAL
|--------------------------------------------------------------------------
*/
public function transfer($data)
{
return DB::transaction(function () use ($data) {
$barcode = $data['barcode_id'];
// cek serialized dulu
$serialized = TechnicianMaterial::where('barcode_id', $barcode)->first();
if ($serialized) {
$serialized->update([
'user_id' => $data['to_user_id']
]);
MaterialMovement::create([
'barcode_id' => $barcode,
'from_user_id' => $data['from_user_id'],
'to_user_id' => $data['to_user_id'],
'movement_type' => 'transfer',
'created_by' => auth()->id(),
'created_at' => now(),
]);
return $serialized;
}
// kalau bukan serialized → consumable
$consumable = TechnicianConsumable::where('barcode_id', $barcode)->first();
$consumable->update([
'user_id' => $data['to_user_id']
]);
MaterialMovement::create([
'barcode_id' => $barcode,
'from_user_id' => $data['from_user_id'],
'to_user_id' => $data['to_user_id'],
'movement_type' => 'transfer',
'qty' => $consumable->qty_remaining,
'created_by' => auth()->id(),
'created_at' => now(),
]);
return $consumable;
});
}
/*
|--------------------------------------------------------------------------
| RETURN MATERIAL
|--------------------------------------------------------------------------
*/
public function return($data)
{
return DB::transaction(function () use ($data) {
$barcode = $data['barcode_id'];
$serialized = TechnicianMaterial::where('barcode_id', $barcode)->first();
if ($serialized) {
$serialized->update([
'user_id' => null,
'status' => 'returned'
]);
MaterialMovement::create([
'barcode_id' => $barcode,
'user_id' => $data['user_id'],
'from_user_id' => $data['user_id'],
'movement_type' => 'return',
'created_by' => auth()->id(),
'created_at' => now(),
]);
return $serialized;
}
$consumable = TechnicianConsumable::where('barcode_id', $barcode)->first();
$consumable->update([
'user_id' => null,
'status' => 'returned'
]);
MaterialMovement::create([
'barcode_id' => $barcode,
'user_id' => $data['user_id'],
'from_user_id' => $data['user_id'],
'movement_type' => 'return',
'qty' => $consumable->qty_remaining,
'created_by' => auth()->id(),
'created_at' => now(),
]);
return $consumable;
});
}
public function listByUser($userId)
{
$serialized = TechnicianMaterial::where('user_id', $userId)
->get()
->map(function ($item) {
$item->type = 'serialized';
return $item;
});
$consumable = TechnicianConsumable::where('user_id', $userId)
->get()
->map(function ($item) {
$item->type = 'consumable';
return $item;
});
return $serialized
->concat($consumable)
->values();
}
public function history($barcodeId)
{
return MaterialMovement::where('barcode_id', $barcodeId)
->orderBy('created_at', 'desc')
->get()
->map(function ($item) {
return [
'barcode_id' => $item->barcode_id,
'type' => $item->movement_type,
'from_user_id' => $item->from_user_id,
'to_user_id' => $item->to_user_id,
'ticket_id' => $item->ticket_id,
'qty' => $item->qty,
'description' => $item->description,
'created_at' => $item->created_at,
];
});
}
}