286 lines
9.2 KiB
PHP
286 lines
9.2 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
|
|
{
|
|
public function list(array $filters = [])
|
|
{
|
|
$serialized = TechnicianMaterial::query()
|
|
->select([
|
|
'id',
|
|
'user_id',
|
|
'barcode_id',
|
|
'inventory_item_id',
|
|
'material_name',
|
|
'serial_number',
|
|
'status',
|
|
'assigned_at',
|
|
'assigned_by',
|
|
'created_at',
|
|
'updated_at',
|
|
DB::raw('NULL as unit'),
|
|
DB::raw('NULL as qty_received'),
|
|
DB::raw('NULL as qty_used'),
|
|
DB::raw('NULL as qty_remaining'),
|
|
DB::raw("'serialized' as type"),
|
|
]);
|
|
|
|
$consumable = TechnicianConsumable::query()
|
|
->select([
|
|
'id',
|
|
'user_id',
|
|
'barcode_id',
|
|
'inventory_item_id',
|
|
'material_name',
|
|
DB::raw('NULL as serial_number'),
|
|
'status',
|
|
'assigned_at',
|
|
'assigned_by',
|
|
'created_at',
|
|
'updated_at',
|
|
'unit',
|
|
'qty_received',
|
|
'qty_used',
|
|
'qty_remaining',
|
|
DB::raw("'consumable' as type"),
|
|
]);
|
|
|
|
if (!empty($filters['user_id'])) {
|
|
$serialized->where('user_id', $filters['user_id']);
|
|
$consumable->where('user_id', $filters['user_id']);
|
|
}
|
|
|
|
$query = $serialized->unionAll($consumable);
|
|
|
|
return DB::query()
|
|
->fromSub($query, 'materials')
|
|
->orderByDesc('created_at')
|
|
->paginate($filters['per_page'] ?? 15);
|
|
}
|
|
/*
|
|
|--------------------------------------------------------------------------
|
|
| 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,
|
|
];
|
|
});
|
|
}
|
|
} |