sample about material
This commit is contained in:
@@ -0,0 +1,70 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Material;
|
||||
|
||||
use App\Http\Controllers\ApiController;
|
||||
use App\Http\Requests\Material\AssignMaterialRequest;
|
||||
use App\Http\Requests\Material\TransferMaterialRequest;
|
||||
use App\Http\Requests\Material\ReturnMaterialRequest;
|
||||
use App\Http\Resources\Material\MaterialResource;
|
||||
use App\Services\Material\MaterialService;
|
||||
|
||||
class MaterialController extends ApiController
|
||||
{
|
||||
protected $service;
|
||||
|
||||
public function __construct(MaterialService $service)
|
||||
{
|
||||
$this->service = $service;
|
||||
}
|
||||
|
||||
public function assign(AssignMaterialRequest $request)
|
||||
{
|
||||
$result = $this->service->assign($request->validated());
|
||||
|
||||
return $this->created(
|
||||
new MaterialResource($result),
|
||||
'Material berhasil di-assign'
|
||||
);
|
||||
}
|
||||
|
||||
public function transfer(TransferMaterialRequest $request)
|
||||
{
|
||||
$result = $this->service->transfer($request->validated());
|
||||
|
||||
return $this->updated(
|
||||
new MaterialResource($result),
|
||||
'Material berhasil di-transfer'
|
||||
);
|
||||
}
|
||||
|
||||
public function return(ReturnMaterialRequest $request)
|
||||
{
|
||||
$result = $this->service->return($request->validated());
|
||||
|
||||
return $this->updated(
|
||||
new MaterialResource($result),
|
||||
'Material berhasil direturn'
|
||||
);
|
||||
}
|
||||
|
||||
public function listByUser($user_id)
|
||||
{
|
||||
$data = $this->service->listByUser($user_id);
|
||||
|
||||
return $this->success(
|
||||
\App\Http\Resources\Material\MaterialResource::collection($data),
|
||||
'List material user berhasil diambil'
|
||||
);
|
||||
}
|
||||
|
||||
public function history($barcode_id)
|
||||
{
|
||||
$data = $this->service->history($barcode_id);
|
||||
|
||||
return $this->success(
|
||||
$data,
|
||||
'History material berhasil diambil'
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Requests\Material;
|
||||
|
||||
use Illuminate\Contracts\Validation\ValidationRule;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class AssignMaterialRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*/
|
||||
public function authorize(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array<string, ValidationRule|array<mixed>|string>
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'user_id' => 'required|integer',
|
||||
'barcode_id' => 'required|string',
|
||||
'material_name' => 'required|string',
|
||||
|
||||
'type' => 'required|in:serialized,consumable',
|
||||
|
||||
'serial_number' => 'nullable|string',
|
||||
'qty' => 'nullable|numeric',
|
||||
'unit' => 'nullable|string',
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Requests\Material;
|
||||
|
||||
use Illuminate\Contracts\Validation\ValidationRule;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class ReturnMaterialRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*/
|
||||
public function authorize(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array<string, ValidationRule|array<mixed>|string>
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'barcode_id' => 'required|string',
|
||||
'user_id' => 'required|integer',
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Requests\Material;
|
||||
|
||||
use Illuminate\Contracts\Validation\ValidationRule;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class TransferMaterialRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*/
|
||||
public function authorize(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array<string, ValidationRule|array<mixed>|string>
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'barcode_id' => 'required|string',
|
||||
'from_user_id' => 'required|integer',
|
||||
'to_user_id' => 'required|integer',
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Resources\Material;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\Resources\Json\JsonResource;
|
||||
|
||||
class MaterialResource extends JsonResource
|
||||
{
|
||||
public function toArray($request)
|
||||
{
|
||||
return [
|
||||
// universal
|
||||
'barcode_id' => $this->barcode_id,
|
||||
'material_name' => $this->material_name,
|
||||
'user_id' => $this->user_id,
|
||||
|
||||
// detect type model
|
||||
'type' => $this->detectType(),
|
||||
|
||||
// serialized only
|
||||
'serial_number' => $this->when(
|
||||
$this->isSerialized(),
|
||||
$this->serial_number
|
||||
),
|
||||
|
||||
// consumable only
|
||||
'qty' => $this->when(
|
||||
$this->isConsumable(),
|
||||
[
|
||||
'received' => $this->qty_received ?? null,
|
||||
'used' => $this->qty_used ?? null,
|
||||
'remaining' => $this->qty_remaining ?? null,
|
||||
'unit' => $this->unit ?? null,
|
||||
]
|
||||
),
|
||||
|
||||
// status (beda logic tapi tetap dipakai keduanya)
|
||||
'status' => $this->status ?? null,
|
||||
|
||||
// optional tracking info
|
||||
'assigned_at' => $this->assigned_at ?? null,
|
||||
];
|
||||
}
|
||||
|
||||
private function detectType(): string
|
||||
{
|
||||
// kalau punya qty field → consumable
|
||||
if (isset($this->qty_received) || isset($this->qty_remaining)) {
|
||||
return 'consumable';
|
||||
}
|
||||
|
||||
return 'serialized';
|
||||
}
|
||||
|
||||
private function isSerialized(): bool
|
||||
{
|
||||
return !isset($this->qty_received);
|
||||
}
|
||||
|
||||
private function isConsumable(): bool
|
||||
{
|
||||
return isset($this->qty_received);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class MaterialMovement extends Model
|
||||
{
|
||||
protected $table = 'material_movements';
|
||||
|
||||
public $timestamps = false;
|
||||
|
||||
protected $fillable = [
|
||||
'barcode_id',
|
||||
'user_id',
|
||||
'from_user_id',
|
||||
'to_user_id',
|
||||
'ticket_id',
|
||||
'movement_type',
|
||||
'qty',
|
||||
'description',
|
||||
'created_by',
|
||||
'created_at'
|
||||
];
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class TechnicianConsumable extends Model
|
||||
{
|
||||
protected $table = 'technician_consumables';
|
||||
|
||||
protected $fillable = [
|
||||
'user_id',
|
||||
'barcode_id',
|
||||
'inventory_item_id',
|
||||
'material_name',
|
||||
'unit',
|
||||
'qty_received',
|
||||
'qty_used',
|
||||
'qty_remaining',
|
||||
'status',
|
||||
'assigned_at',
|
||||
'assigned_by'
|
||||
];
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class TechnicianMaterial extends Model
|
||||
{
|
||||
protected $table = 'technician_materials';
|
||||
|
||||
protected $fillable = [
|
||||
'user_id',
|
||||
'barcode_id',
|
||||
'inventory_item_id',
|
||||
'material_name',
|
||||
'serial_number',
|
||||
'status',
|
||||
'assigned_at',
|
||||
'assigned_by',
|
||||
];
|
||||
}
|
||||
@@ -0,0 +1,232 @@
|
||||
<?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,
|
||||
];
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('technician_materials', function (Blueprint $table) {
|
||||
$table->id();
|
||||
|
||||
$table->unsignedBigInteger('user_id');
|
||||
|
||||
$table->string('barcode_id')->unique();
|
||||
$table->unsignedBigInteger('inventory_item_id')->nullable();
|
||||
|
||||
$table->string('material_name');
|
||||
$table->string('serial_number')->nullable();
|
||||
|
||||
$table->enum('status', [
|
||||
'assigned',
|
||||
'used',
|
||||
'returned',
|
||||
'lost',
|
||||
'damaged'
|
||||
])->default('assigned');
|
||||
|
||||
$table->dateTime('assigned_at');
|
||||
$table->unsignedBigInteger('assigned_by')->nullable();
|
||||
|
||||
$table->timestamps();
|
||||
|
||||
$table->index('user_id');
|
||||
$table->index('barcode_id');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('technician_materials');
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('technician_consumables', function (Blueprint $table) {
|
||||
$table->id();
|
||||
|
||||
$table->unsignedBigInteger('user_id');
|
||||
|
||||
$table->string('barcode_id')->unique();
|
||||
$table->unsignedBigInteger('inventory_item_id')->nullable();
|
||||
|
||||
$table->string('material_name');
|
||||
$table->string('unit')->default('meter');
|
||||
|
||||
$table->decimal('qty_received', 10, 2)->default(0);
|
||||
$table->decimal('qty_used', 10, 2)->default(0);
|
||||
$table->decimal('qty_remaining', 10, 2)->default(0);
|
||||
|
||||
$table->dateTime('assigned_at');
|
||||
$table->unsignedBigInteger('assigned_by')->nullable();
|
||||
|
||||
$table->timestamps();
|
||||
|
||||
$table->index('user_id');
|
||||
$table->index('barcode_id');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('technician_consumables');
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('ticket_consumables', function (Blueprint $table) {
|
||||
$table->id();
|
||||
|
||||
$table->unsignedBigInteger('ticket_id');
|
||||
$table->unsignedBigInteger('user_id');
|
||||
|
||||
$table->unsignedBigInteger('technician_consumable_id');
|
||||
|
||||
$table->string('barcode_id');
|
||||
$table->string('material_name');
|
||||
|
||||
$table->decimal('qty_used', 10, 2);
|
||||
$table->string('unit')->default('meter');
|
||||
|
||||
$table->dateTime('used_at');
|
||||
|
||||
$table->timestamps();
|
||||
|
||||
$table->index('ticket_id');
|
||||
$table->index('user_id');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('ticket_consumables');
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,51 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('material_movements', function (Blueprint $table) {
|
||||
$table->id();
|
||||
|
||||
$table->string('barcode_id');
|
||||
|
||||
$table->unsignedBigInteger('user_id')->nullable();
|
||||
$table->unsignedBigInteger('from_user_id')->nullable();
|
||||
$table->unsignedBigInteger('to_user_id')->nullable();
|
||||
|
||||
$table->unsignedBigInteger('ticket_id')->nullable();
|
||||
|
||||
$table->enum('movement_type', [
|
||||
'assign',
|
||||
'transfer',
|
||||
'use',
|
||||
'return',
|
||||
'lost',
|
||||
'damaged'
|
||||
]);
|
||||
|
||||
$table->decimal('qty', 10, 2)->nullable();
|
||||
|
||||
$table->text('description')->nullable();
|
||||
|
||||
$table->unsignedBigInteger('created_by')->nullable();
|
||||
|
||||
$table->dateTime('created_at');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('material_movements');
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,71 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
Schema::table('ticket_materials', function (Blueprint $table) {
|
||||
|
||||
if (!Schema::hasColumn('ticket_materials', 'user_id')) {
|
||||
$table->unsignedBigInteger('user_id')->nullable();
|
||||
}
|
||||
|
||||
if (!Schema::hasColumn('ticket_materials', 'technician_material_id')) {
|
||||
$table->unsignedBigInteger('technician_material_id')->nullable();
|
||||
}
|
||||
|
||||
if (!Schema::hasColumn('ticket_materials', 'barcode_id')) {
|
||||
$table->string('barcode_id')->nullable();
|
||||
}
|
||||
|
||||
if (!Schema::hasColumn('ticket_materials', 'serial_number')) {
|
||||
$table->string('serial_number')->nullable();
|
||||
}
|
||||
|
||||
if (!Schema::hasColumn('ticket_materials', 'used_at')) {
|
||||
$table->dateTime('used_at')->nullable();
|
||||
}
|
||||
|
||||
if (!Schema::hasColumn('ticket_materials', 'ticket_log_id')) {
|
||||
$table->unsignedBigInteger('ticket_log_id')->nullable();
|
||||
}
|
||||
|
||||
if (!Schema::hasColumn('ticket_materials', 'qty')) {
|
||||
$table->decimal('qty', 12, 2)->default(1);
|
||||
}
|
||||
|
||||
if (!Schema::hasColumn('ticket_materials', 'notes')) {
|
||||
$table->text('notes')->nullable();
|
||||
}
|
||||
|
||||
if (!Schema::hasColumn('ticket_materials', 'created_at')) {
|
||||
$table->timestamp('created_at')->nullable();
|
||||
}
|
||||
|
||||
if (!Schema::hasColumn('ticket_materials', 'updated_at')) {
|
||||
$table->timestamp('updated_at')->nullable();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('ticket_materials', function (Blueprint $table) {
|
||||
|
||||
$table->dropColumn([
|
||||
'user_id',
|
||||
'technician_material_id',
|
||||
'barcode_id',
|
||||
'serial_number',
|
||||
'used_at',
|
||||
'ticket_log_id',
|
||||
'qty',
|
||||
'notes'
|
||||
]);
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::table('technician_consumables', function (Blueprint $table) {
|
||||
|
||||
// kalau sebelumnya status belum ada
|
||||
$table->enum('status', [
|
||||
'assigned',
|
||||
'used',
|
||||
'returned',
|
||||
'lost',
|
||||
'damaged'
|
||||
])->default('assigned')->after('qty_remaining');
|
||||
|
||||
$table->index('status');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('technician_consumables', function (Blueprint $table) {
|
||||
$table->dropIndex(['status']);
|
||||
$table->dropColumn('status');
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -6,6 +6,7 @@ use App\Http\Controllers\AuthController;
|
||||
use App\Http\Controllers\Ticket\TicketController;
|
||||
use App\Http\Controllers\Ticket\TicketTypeController;
|
||||
use App\Http\Controllers\Ticket\TicketWorkflowController;
|
||||
use App\Http\Controllers\Material\MaterialController;
|
||||
|
||||
Route::post('/login', [AuthController::class, 'login']);
|
||||
|
||||
@@ -55,5 +56,16 @@ Route::middleware('auth:sanctum')->group(function () {
|
||||
|
||||
Route::post('/escalate', 'escalate');
|
||||
});
|
||||
|
||||
Route::prefix('materials')->group(function () {
|
||||
|
||||
Route::post('/assign', [MaterialController::class, 'assign']);
|
||||
Route::post('/transfer', [MaterialController::class, 'transfer']);
|
||||
Route::post('/return', [MaterialController::class, 'return']);
|
||||
|
||||
Route::get('/user/{user_id}', [MaterialController::class, 'listByUser']);
|
||||
Route::get('/history/{barcode_id}', [MaterialController::class, 'history']);
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user