feat : 자재관리, 수입관리, 로트관리 모델링 추가

This commit is contained in:
2025-07-28 18:47:00 +09:00
parent 1233058eda
commit d9d01c2aaf
13 changed files with 366 additions and 0 deletions

23
app/Models/Lot.php Normal file
View File

@@ -0,0 +1,23 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class Lot extends Model
{
use SoftDeletes;
// 자재 마스터
public function material()
{
return $this->belongsTo(Material::class, 'material_id');
}
// 판매 기록
public function sales()
{
return $this->hasMany(LotSale::class, 'lot_id');
}
}

18
app/Models/LotSale.php Normal file
View File

@@ -0,0 +1,18 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class LotSale extends Model
{
use SoftDeletes;
// 로트 정보
public function lot()
{
return $this->belongsTo(Lot::class, 'lot_id');
}
}

35
app/Models/Material.php Normal file
View File

@@ -0,0 +1,35 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class Material extends Model
{
use SoftDeletes;
// 자재(품목) 마스터
protected $fillable = [
'name', // 자재명(품명)
'specification', // 규격
'material_code', // 자재코드
'unit', // 단위
'is_inspection', // 검사대상 여부(Y/N)
'search_tag', // 검색 태그
'remarks', // 비고
];
// 자재 입고 내역
public function receipts()
{
return $this->hasMany(MaterialReceipt::class, 'material_id');
}
// 로트 관리
public function lots()
{
return $this->hasMany(Lot::class, 'material_id');
}
}

View File

@@ -0,0 +1,23 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class MaterialInspection extends Model
{
use SoftDeletes;
// 입고 내역
public function receipt()
{
return $this->belongsTo(MaterialReceipt::class, 'receipt_id');
}
// 검사 항목
public function items()
{
return $this->hasMany(MaterialInspectionItem::class, 'inspection_id');
}
}

View File

@@ -0,0 +1,17 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class MaterialInspectionItem extends Model
{
use SoftDeletes;
// 검사 내역
public function inspection()
{
return $this->belongsTo(MaterialInspection::class, 'inspection_id');
}
}

View File

@@ -0,0 +1,29 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class MaterialReceipt extends Model
{
use SoftDeletes;
protected $fillable = [
'material_id', 'receipt_date', 'lot_number', 'received_qty', 'unit',
'supplier_name', 'manufacturer_name', 'purchase_price_excl_vat',
'weight_kg', 'status_code', 'is_inspection', 'inspection_date', 'remarks'
];
// 자재 마스터
public function material()
{
return $this->belongsTo(Material::class, 'material_id');
}
// 수입검사 내역
public function inspections()
{
return $this->hasMany(MaterialInspection::class, 'receipt_id');
}
}

View File

@@ -0,0 +1,28 @@
<?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::create('materials', function (Blueprint $table) {
$table->id()->comment('자재 PK');
$table->string('name', 100)->comment('자재명(품명)');
$table->string('specification', 100)->nullable()->comment('규격');
$table->string('material_code', 50)->unique()->comment('자재코드');
$table->string('unit', 10)->comment('단위');
$table->char('is_inspection', 1)->default('N')->comment('검사대상 여부(Y/N)');
$table->text('search_tag')->nullable()->comment('검색 태그');
$table->text('remarks')->nullable()->comment('비고');
$table->timestamps();
$table->softDeletes();
});
}
public function down(): void
{
Schema::dropIfExists('materials');
}
};

View File

@@ -0,0 +1,27 @@
<?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::create('lot_sales', function (Blueprint $table) {
$table->id()->comment('로트별 판매기록 PK');
$table->unsignedBigInteger('lot_id')->comment('로트ID');
$table->date('sale_date')->comment('판매일');
$table->string('author', 50)->nullable()->comment('등록자');
$table->string('workplace_name', 60)->nullable()->comment('작업장명');
$table->text('remarks')->nullable()->comment('비고');
$table->timestamps();
$table->softDeletes();
$table->index('lot_id', 'idx_sales_lot_id');
});
}
public function down(): void
{
Schema::dropIfExists('lot_sales');
}
};

View File

@@ -0,0 +1,31 @@
<?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::create('lots', function (Blueprint $table) {
$table->id()->comment('로트관리 PK');
$table->string('lot_number', 30)->unique()->comment('로트번호');
$table->unsignedBigInteger('material_id')->comment('자재ID');
$table->string('specification', 100)->nullable()->comment('규격');
$table->string('length', 20)->nullable()->comment('길이');
$table->integer('quantity')->comment('수량');
$table->string('raw_lot_number', 30)->nullable()->comment('원자재 로트번호');
$table->string('fabric_lot', 30)->nullable()->comment('원단 로트');
$table->string('author', 50)->nullable()->comment('작성자');
$table->text('remarks')->nullable()->comment('비고');
$table->timestamps();
$table->softDeletes();
$table->index('material_id', 'idx_lots_material_id');
});
}
public function down(): void
{
Schema::dropIfExists('lots');
}
};

View File

@@ -0,0 +1,25 @@
<?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::create('material_inspection_items', function (Blueprint $table) {
$table->id()->comment('검사항목 PK');
$table->unsignedBigInteger('inspection_id')->comment('수입검사ID');
$table->string('item_name', 100)->comment('검사항목명');
$table->char('is_checked', 1)->default('N')->comment('체크여부(Y/N)');
$table->timestamps();
$table->softDeletes();
$table->index('inspection_id', 'idx_items_inspection_id');
});
}
public function down(): void
{
Schema::dropIfExists('material_inspection_items');
}
};

View File

@@ -0,0 +1,30 @@
<?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::create('material_inspections', function (Blueprint $table) {
$table->id()->comment('수입검사 PK');
$table->unsignedBigInteger('receipt_id')->comment('자재입고ID');
$table->date('inspection_date')->comment('검사일자');
$table->string('inspector_name', 50)->nullable()->comment('검사자');
$table->string('approver_name', 50)->nullable()->comment('결재자');
$table->string('judgment_code', 30)->comment('종합판정(common_codes)');
$table->string('status_code', 30)->comment('상태코드(common_codes)');
$table->text('result_file_path')->nullable()->comment('성적서 PDF 경로');
$table->text('remarks')->nullable()->comment('비고');
$table->timestamps();
$table->softDeletes();
$table->index('receipt_id', 'idx_inspections_receipt_id');
});
}
public function down(): void
{
Schema::dropIfExists('material_inspections');
}
};

View File

@@ -0,0 +1,35 @@
<?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::create('material_receipts', function (Blueprint $table) {
$table->id()->comment('자재입고 PK');
$table->unsignedBigInteger('material_id')->comment('자재ID');
$table->date('receipt_date')->comment('입고일');
$table->string('lot_number', 30)->comment('로트번호');
$table->decimal('received_qty', 12, 2)->comment('입고수량');
$table->string('unit', 10)->comment('단위');
$table->string('supplier_name', 100)->nullable()->comment('납품업체');
$table->string('manufacturer_name', 100)->nullable()->comment('제조사');
$table->decimal('purchase_price_excl_vat', 12, 2)->nullable()->comment('구매단가(부가세 제외)');
$table->decimal('weight_kg', 12, 2)->nullable()->comment('총 무게(kg)');
$table->string('status_code', 30)->comment('상태코드(common_codes)');
$table->char('is_inspection', 1)->default('N')->comment('검사대상 여부(Y/N)');
$table->date('inspection_date')->nullable()->comment('검사일자');
$table->text('remarks')->nullable()->comment('비고');
$table->timestamps();
$table->softDeletes();
$table->index('material_id', 'idx_receipts_material_id');
});
}
public function down(): void
{
Schema::dropIfExists('material_receipts');
}
};

View File

@@ -0,0 +1,45 @@
<?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('material_receipts', function (Blueprint $table) {
$table->foreign('material_id', 'fk_receipts_material_id')->references('id')->on('materials');
});
Schema::table('material_inspections', function (Blueprint $table) {
$table->foreign('receipt_id', 'fk_inspections_receipt_id')->references('id')->on('material_receipts')->onDelete('cascade');
});
Schema::table('material_inspection_items', function (Blueprint $table) {
$table->foreign('inspection_id', 'fk_items_inspection_id')->references('id')->on('material_inspections')->onDelete('cascade');
});
Schema::table('lots', function (Blueprint $table) {
$table->foreign('material_id', 'fk_lots_material_id')->references('id')->on('materials');
});
Schema::table('lot_sales', function (Blueprint $table) {
$table->foreign('lot_id', 'fk_sales_lot_id')->references('id')->on('lots');
});
}
public function down(): void
{
Schema::table('material_receipts', function (Blueprint $table) {
$table->dropForeign('fk_receipts_material_id');
});
Schema::table('material_inspections', function (Blueprint $table) {
$table->dropForeign('fk_inspections_receipt_id');
});
Schema::table('material_inspection_items', function (Blueprint $table) {
$table->dropForeign('fk_items_inspection_id');
});
Schema::table('lots', function (Blueprint $table) {
$table->dropForeign('fk_lots_material_id');
});
Schema::table('lot_sales', function (Blueprint $table) {
$table->dropForeign('fk_sales_lot_id');
});
}
};