feat: clients.is_active CHAR(1) → TINYINT(1) Boolean 마이그레이션
- DB: CHAR(1) 'Y'/'N' → TINYINT(1) 0/1 컬럼 타입 변경 - Model: boolean 캐스트 추가, scopeActive() 수정 - Service: toggle(), index() Boolean 로직 적용 - FormRequest: 'in:Y,N' → 'boolean' 검증 규칙 변경 - Swagger: is_active type string → boolean 변경
This commit is contained in:
@@ -51,7 +51,7 @@ public function rules(): array
|
||||
'bad_debt_progress' => 'nullable|in:협의중,소송중,회수완료,대손처리',
|
||||
// 기타
|
||||
'memo' => 'nullable|string',
|
||||
'is_active' => 'nullable|in:Y,N',
|
||||
'is_active' => 'nullable|boolean',
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,7 +51,7 @@ public function rules(): array
|
||||
'bad_debt_progress' => 'nullable|in:협의중,소송중,회수완료,대손처리',
|
||||
// 기타
|
||||
'memo' => 'nullable|string',
|
||||
'is_active' => 'nullable|in:Y,N',
|
||||
'is_active' => 'nullable|boolean',
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -76,7 +76,7 @@ public function orders()
|
||||
// 스코프
|
||||
public function scopeActive($query)
|
||||
{
|
||||
return $query->where('is_active', 'Y');
|
||||
return $query->where('is_active', true);
|
||||
}
|
||||
|
||||
public function scopeCode($query, string $code)
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
namespace App\Services;
|
||||
|
||||
use App\Models\Orders\Client;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
|
||||
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||
|
||||
@@ -30,7 +29,7 @@ public function index(array $params)
|
||||
}
|
||||
|
||||
if ($onlyActive !== null) {
|
||||
$query->where('is_active', $onlyActive ? 'Y' : 'N');
|
||||
$query->where('is_active', (bool) $onlyActive);
|
||||
}
|
||||
|
||||
$query->orderBy('client_code')->orderBy('id');
|
||||
@@ -51,49 +50,9 @@ public function show(int $id)
|
||||
}
|
||||
|
||||
/** 생성 */
|
||||
public function store(array $params)
|
||||
public function store(array $data)
|
||||
{
|
||||
$tenantId = $this->tenantId();
|
||||
$uid = $this->apiUserId();
|
||||
|
||||
$v = Validator::make($params, [
|
||||
'client_code' => 'required|string|max:50',
|
||||
'name' => 'required|string|max:100',
|
||||
'client_type' => 'nullable|in:매입,매출,매입매출',
|
||||
'contact_person' => 'nullable|string|max:50',
|
||||
'phone' => 'nullable|string|max:30',
|
||||
'mobile' => 'nullable|string|max:20',
|
||||
'fax' => 'nullable|string|max:20',
|
||||
'email' => 'nullable|email|max:80',
|
||||
'address' => 'nullable|string|max:255',
|
||||
'manager_name' => 'nullable|string|max:50',
|
||||
'manager_tel' => 'nullable|string|max:20',
|
||||
'system_manager' => 'nullable|string|max:50',
|
||||
'account_id' => 'nullable|string|max:50',
|
||||
'account_password' => 'nullable|string|max:255',
|
||||
'purchase_payment_day' => 'nullable|string|max:20',
|
||||
'sales_payment_day' => 'nullable|string|max:20',
|
||||
'business_no' => 'nullable|string|max:20',
|
||||
'business_type' => 'nullable|string|max:50',
|
||||
'business_item' => 'nullable|string|max:100',
|
||||
'tax_agreement' => 'nullable|boolean',
|
||||
'tax_amount' => 'nullable|numeric|min:0',
|
||||
'tax_start_date' => 'nullable|date',
|
||||
'tax_end_date' => 'nullable|date',
|
||||
'bad_debt' => 'nullable|boolean',
|
||||
'bad_debt_amount' => 'nullable|numeric|min:0',
|
||||
'bad_debt_receive_date' => 'nullable|date',
|
||||
'bad_debt_end_date' => 'nullable|date',
|
||||
'bad_debt_progress' => 'nullable|in:협의중,소송중,회수완료,대손처리',
|
||||
'memo' => 'nullable|string',
|
||||
'is_active' => 'nullable|in:Y,N',
|
||||
]);
|
||||
|
||||
if ($v->fails()) {
|
||||
throw new BadRequestHttpException($v->errors()->first());
|
||||
}
|
||||
|
||||
$data = $v->validated();
|
||||
|
||||
// client_code 중복 검사
|
||||
$exists = Client::where('tenant_id', $tenantId)
|
||||
@@ -104,72 +63,32 @@ public function store(array $params)
|
||||
}
|
||||
|
||||
$data['tenant_id'] = $tenantId;
|
||||
$data['is_active'] = $data['is_active'] ?? 'Y';
|
||||
$data['is_active'] = $data['is_active'] ?? true;
|
||||
|
||||
return Client::create($data);
|
||||
}
|
||||
|
||||
/** 수정 */
|
||||
public function update(int $id, array $params)
|
||||
public function update(int $id, array $data)
|
||||
{
|
||||
$tenantId = $this->tenantId();
|
||||
$uid = $this->apiUserId();
|
||||
|
||||
$client = Client::where('tenant_id', $tenantId)->find($id);
|
||||
if (! $client) {
|
||||
throw new NotFoundHttpException(__('error.not_found'));
|
||||
}
|
||||
|
||||
$v = Validator::make($params, [
|
||||
'client_code' => 'sometimes|required|string|max:50',
|
||||
'name' => 'sometimes|required|string|max:100',
|
||||
'client_type' => 'nullable|in:매입,매출,매입매출',
|
||||
'contact_person' => 'nullable|string|max:50',
|
||||
'phone' => 'nullable|string|max:30',
|
||||
'mobile' => 'nullable|string|max:20',
|
||||
'fax' => 'nullable|string|max:20',
|
||||
'email' => 'nullable|email|max:80',
|
||||
'address' => 'nullable|string|max:255',
|
||||
'manager_name' => 'nullable|string|max:50',
|
||||
'manager_tel' => 'nullable|string|max:20',
|
||||
'system_manager' => 'nullable|string|max:50',
|
||||
'account_id' => 'nullable|string|max:50',
|
||||
'account_password' => 'nullable|string|max:255',
|
||||
'purchase_payment_day' => 'nullable|string|max:20',
|
||||
'sales_payment_day' => 'nullable|string|max:20',
|
||||
'business_no' => 'nullable|string|max:20',
|
||||
'business_type' => 'nullable|string|max:50',
|
||||
'business_item' => 'nullable|string|max:100',
|
||||
'tax_agreement' => 'nullable|boolean',
|
||||
'tax_amount' => 'nullable|numeric|min:0',
|
||||
'tax_start_date' => 'nullable|date',
|
||||
'tax_end_date' => 'nullable|date',
|
||||
'bad_debt' => 'nullable|boolean',
|
||||
'bad_debt_amount' => 'nullable|numeric|min:0',
|
||||
'bad_debt_receive_date' => 'nullable|date',
|
||||
'bad_debt_end_date' => 'nullable|date',
|
||||
'bad_debt_progress' => 'nullable|in:협의중,소송중,회수완료,대손처리',
|
||||
'memo' => 'nullable|string',
|
||||
'is_active' => 'nullable|in:Y,N',
|
||||
]);
|
||||
|
||||
if ($v->fails()) {
|
||||
throw new BadRequestHttpException($v->errors()->first());
|
||||
}
|
||||
|
||||
$payload = $v->validated();
|
||||
|
||||
// client_code 변경 시 중복 검사
|
||||
if (isset($payload['client_code']) && $payload['client_code'] !== $client->client_code) {
|
||||
if (isset($data['client_code']) && $data['client_code'] !== $client->client_code) {
|
||||
$exists = Client::where('tenant_id', $tenantId)
|
||||
->where('client_code', $payload['client_code'])
|
||||
->where('client_code', $data['client_code'])
|
||||
->exists();
|
||||
if ($exists) {
|
||||
throw new BadRequestHttpException(__('error.duplicate_code'));
|
||||
}
|
||||
}
|
||||
|
||||
$client->update($payload);
|
||||
$client->update($data);
|
||||
|
||||
return $client->refresh();
|
||||
}
|
||||
@@ -203,7 +122,6 @@ public function toggle(int $id)
|
||||
throw new NotFoundHttpException(__('error.not_found'));
|
||||
}
|
||||
|
||||
// Model에서 is_active가 boolean으로 캐스팅되므로 boolean으로 토글
|
||||
$client->is_active = ! $client->is_active;
|
||||
$client->save();
|
||||
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
* @OA\Property(property="bad_debt_end_date", type="string", format="date", nullable=true, example="2025-06-01", description="채권 만료일"),
|
||||
* @OA\Property(property="bad_debt_progress", type="string", enum={"협의중", "소송중", "회수완료", "대손처리"}, nullable=true, description="진행 상태"),
|
||||
* @OA\Property(property="memo", type="string", nullable=true, example="특이사항 메모", description="메모"),
|
||||
* @OA\Property(property="is_active", type="string", enum={"Y", "N"}, example="Y"),
|
||||
* @OA\Property(property="is_active", type="boolean", example=true, description="활성 여부"),
|
||||
* @OA\Property(property="created_at", type="string", example="2025-10-01 12:00:00"),
|
||||
* @OA\Property(property="updated_at", type="string", example="2025-10-01 12:00:00")
|
||||
* )
|
||||
@@ -116,7 +116,7 @@
|
||||
* @OA\Property(property="bad_debt_end_date", type="string", format="date", nullable=true, example="2025-06-01", description="채권 만료일"),
|
||||
* @OA\Property(property="bad_debt_progress", type="string", enum={"협의중", "소송중", "회수완료", "대손처리"}, nullable=true, description="진행 상태"),
|
||||
* @OA\Property(property="memo", type="string", nullable=true, example="특이사항 메모", description="메모"),
|
||||
* @OA\Property(property="is_active", type="string", enum={"Y", "N"}, example="Y")
|
||||
* @OA\Property(property="is_active", type="boolean", example=true, description="활성 여부")
|
||||
* )
|
||||
*
|
||||
* @OA\Schema(
|
||||
@@ -153,7 +153,7 @@
|
||||
* @OA\Property(property="bad_debt_end_date", type="string", format="date", nullable=true, description="채권 만료일"),
|
||||
* @OA\Property(property="bad_debt_progress", type="string", enum={"협의중", "소송중", "회수완료", "대손처리"}, nullable=true, description="진행 상태"),
|
||||
* @OA\Property(property="memo", type="string", nullable=true, description="메모"),
|
||||
* @OA\Property(property="is_active", type="string", enum={"Y", "N"})
|
||||
* @OA\Property(property="is_active", type="boolean", description="활성 여부")
|
||||
* )
|
||||
*/
|
||||
class ClientApi
|
||||
@@ -257,12 +257,15 @@ public function update() {}
|
||||
* @OA\Delete(
|
||||
* path="/api/v1/clients/{id}",
|
||||
* tags={"Client"},
|
||||
* summary="거래처 삭제(soft)",
|
||||
* summary="거래처 삭제",
|
||||
* description="주문이 존재하는 거래처는 삭제할 수 없습니다.",
|
||||
* security={{"ApiKeyAuth":{}},{"BearerAuth":{}}},
|
||||
*
|
||||
* @OA\Parameter(name="id", in="path", required=true, @OA\Schema(type="integer")),
|
||||
*
|
||||
* @OA\Response(response=200, description="삭제 성공", @OA\JsonContent(ref="#/components/schemas/ApiResponse"))
|
||||
* @OA\Response(response=200, description="삭제 성공", @OA\JsonContent(ref="#/components/schemas/ApiResponse")),
|
||||
* @OA\Response(response=400, description="주문 존재로 삭제 불가", @OA\JsonContent(ref="#/components/schemas/ErrorResponse")),
|
||||
* @OA\Response(response=404, description="데이터 없음", @OA\JsonContent(ref="#/components/schemas/ErrorResponse"))
|
||||
* )
|
||||
*/
|
||||
public function destroy() {}
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
/**
|
||||
* clients 테이블 is_active 컬럼을 CHAR(1) 'Y'/'N'에서 TINYINT(1) 0/1로 변환
|
||||
*
|
||||
* 프로젝트 표준:
|
||||
* - DB: tinyint(1) with 0/1
|
||||
* - Model: 'is_active' => 'boolean' cast
|
||||
* - API: true/false
|
||||
*/
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
// 1. 'Y' → 1, 'N' → 0 으로 데이터 변환 (임시로 숫자 문자열)
|
||||
DB::statement("UPDATE clients SET is_active = '1' WHERE is_active = 'Y'");
|
||||
DB::statement("UPDATE clients SET is_active = '0' WHERE is_active = 'N' OR is_active = '' OR is_active IS NULL");
|
||||
|
||||
// 2. 컬럼 타입 변경: CHAR(1) → TINYINT(1)
|
||||
DB::statement("
|
||||
ALTER TABLE clients
|
||||
MODIFY COLUMN is_active TINYINT(1) NOT NULL DEFAULT 1 COMMENT '활성여부(1=활성,0=비활성)'
|
||||
");
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
// 1. 컬럼 타입 복구: TINYINT(1) → CHAR(1)
|
||||
DB::statement("
|
||||
ALTER TABLE clients
|
||||
MODIFY COLUMN is_active CHAR(1) NOT NULL DEFAULT 'Y' COMMENT '활성여부(Y/N)'
|
||||
");
|
||||
|
||||
// 2. 1 → 'Y', 0 → 'N' 으로 데이터 복구
|
||||
DB::statement("UPDATE clients SET is_active = 'Y' WHERE is_active = '1' OR is_active = 1");
|
||||
DB::statement("UPDATE clients SET is_active = 'N' WHERE is_active = '0' OR is_active = 0");
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user