refactor: 인벤토리 테이블 스펙과 도메인 계층 정비

This commit is contained in:
JiWoong Sul
2025-10-14 18:09:26 +09:00
parent 8d3b2c1e20
commit 1325109fba
32 changed files with 5550 additions and 290 deletions

View File

@@ -0,0 +1,202 @@
/// 재고 트랜잭션 생성 입력 모델.
class StockTransactionCreateInput {
StockTransactionCreateInput({
this.transactionNo,
required this.transactionTypeId,
required this.transactionStatusId,
required this.warehouseId,
required this.transactionDate,
required this.createdById,
this.note,
this.expectedReturnDate,
this.lines = const [],
this.customers = const [],
});
final String? transactionNo;
final int transactionTypeId;
final int transactionStatusId;
final int warehouseId;
final DateTime transactionDate;
final int createdById;
final String? note;
final DateTime? expectedReturnDate;
final List<TransactionLineCreateInput> lines;
final List<TransactionCustomerCreateInput> customers;
Map<String, dynamic> toPayload() {
return {
if (transactionNo != null && transactionNo!.trim().isNotEmpty)
'transaction_no': transactionNo,
'transaction_type_id': transactionTypeId,
'transaction_status_id': transactionStatusId,
'warehouse_id': warehouseId,
'transaction_date': transactionDate.toIso8601String(),
'created_by_id': createdById,
if (note != null && note!.trim().isNotEmpty) 'note': note,
if (expectedReturnDate != null)
'expected_return_date': expectedReturnDate!.toIso8601String(),
if (lines.isNotEmpty)
'lines': lines.map((line) => line.toJson()).toList(growable: false),
if (customers.isNotEmpty)
'customers': customers
.map((customer) => customer.toJson())
.toList(growable: false),
};
}
}
/// 재고 트랜잭션 수정 입력 모델.
class StockTransactionUpdateInput {
StockTransactionUpdateInput({
required this.transactionStatusId,
this.note,
this.expectedReturnDate,
});
final int transactionStatusId;
final String? note;
final DateTime? expectedReturnDate;
Map<String, dynamic> toPayload() {
return {
'transaction_status_id': transactionStatusId,
if (note != null && note!.trim().isNotEmpty) 'note': note,
if (expectedReturnDate != null)
'expected_return_date': expectedReturnDate!.toIso8601String(),
};
}
}
/// 재고 트랜잭션 라인 추가 입력 모델.
class TransactionLineCreateInput {
TransactionLineCreateInput({
required this.lineNo,
required this.productId,
required this.quantity,
required this.unitPrice,
this.note,
});
final int lineNo;
final int productId;
final int quantity;
final double unitPrice;
final String? note;
Map<String, dynamic> toJson() {
return {
'line_no': lineNo,
'product_id': productId,
'quantity': quantity,
'unit_price': unitPrice,
if (note != null && note!.trim().isNotEmpty) 'note': note,
};
}
}
/// 재고 트랜잭션 라인 수정 입력 모델.
class TransactionLineUpdateInput {
TransactionLineUpdateInput({
required this.id,
this.lineNo,
this.quantity,
this.unitPrice,
this.note,
});
final int id;
final int? lineNo;
final int? quantity;
final double? unitPrice;
final String? note;
Map<String, dynamic> toJson() {
return {
'id': id,
if (lineNo != null) 'line_no': lineNo,
if (quantity != null) 'quantity': quantity,
if (unitPrice != null) 'unit_price': unitPrice,
if (note != null && note!.trim().isNotEmpty) 'note': note,
};
}
}
/// 재고 트랜잭션 고객 연결 추가 입력 모델.
class TransactionCustomerCreateInput {
TransactionCustomerCreateInput({required this.customerId, this.note});
final int customerId;
final String? note;
Map<String, dynamic> toJson() {
return {
'customer_id': customerId,
if (note != null && note!.trim().isNotEmpty) 'note': note,
};
}
}
/// 재고 트랜잭션 고객 연결 수정 입력 모델.
class TransactionCustomerUpdateInput {
TransactionCustomerUpdateInput({required this.id, this.note});
final int id;
final String? note;
Map<String, dynamic> toJson() {
return {
'id': id,
if (note != null && note!.trim().isNotEmpty) 'note': note,
};
}
}
/// 재고 트랜잭션 목록 조회 필터 모델.
class StockTransactionListFilter {
StockTransactionListFilter({
this.page = 1,
this.pageSize = 20,
this.query,
this.transactionTypeId,
this.transactionStatusId,
this.warehouseId,
this.customerId,
this.from,
this.to,
this.sort,
this.order,
this.include = const ['lines', 'customers', 'approval'],
});
final int page;
final int pageSize;
final String? query;
final int? transactionTypeId;
final int? transactionStatusId;
final int? warehouseId;
final int? customerId;
final DateTime? from;
final DateTime? to;
final String? sort;
final String? order;
final List<String> include;
Map<String, dynamic> toQuery() {
return {
'page': page,
'page_size': pageSize,
if (query != null && query!.trim().isNotEmpty) 'q': query,
if (transactionTypeId != null) 'transaction_type_id': transactionTypeId,
if (transactionStatusId != null)
'transaction_status_id': transactionStatusId,
if (warehouseId != null) 'warehouse_id': warehouseId,
if (customerId != null) 'customer_id': customerId,
if (from != null) 'from': from!.toIso8601String(),
if (to != null) 'to': to!.toIso8601String(),
if (sort != null && sort!.trim().isNotEmpty) 'sort': sort,
if (order != null && order!.trim().isNotEmpty) 'order': order,
if (include.isNotEmpty) 'include': include.join(','),
};
}
}

View File

@@ -0,0 +1,84 @@
import 'package:superport_v2/core/common/models/paginated_result.dart';
import '../entities/stock_transaction.dart';
import '../entities/stock_transaction_input.dart';
/// 재고 트랜잭션 저장소 인터페이스.
abstract class StockTransactionRepository {
/// 재고 트랜잭션 목록을 조회한다.
Future<PaginatedResult<StockTransaction>> list({
StockTransactionListFilter? filter,
});
/// 재고 트랜잭션 단건을 조회한다.
Future<StockTransaction> fetchDetail(
int id, {
List<String> include = const ['lines', 'customers', 'approval'],
});
/// 재고 트랜잭션을 생성한다.
Future<StockTransaction> create(StockTransactionCreateInput input);
/// 재고 트랜잭션을 수정한다.
Future<StockTransaction> update(int id, StockTransactionUpdateInput input);
/// 재고 트랜잭션을 삭제한다.
Future<void> delete(int id);
/// 삭제된 재고 트랜잭션을 복구한다.
Future<StockTransaction> restore(int id);
/// 재고 트랜잭션을 상신(submit)한다.
Future<StockTransaction> submit(int id);
/// 재고 트랜잭션을 완료 처리한다.
Future<StockTransaction> complete(int id);
/// 재고 트랜잭션을 승인 처리한다.
Future<StockTransaction> approve(int id);
/// 재고 트랜잭션을 반려 처리한다.
Future<StockTransaction> reject(int id);
/// 재고 트랜잭션을 취소 처리한다.
Future<StockTransaction> cancel(int id);
}
/// 재고 트랜잭션 라인 저장소 인터페이스.
abstract class TransactionLineRepository {
/// 라인을 추가한다.
Future<List<StockTransactionLine>> addLines(
int transactionId,
List<TransactionLineCreateInput> lines,
);
/// 라인 정보를 일괄 수정한다.
Future<List<StockTransactionLine>> updateLines(
int transactionId,
List<TransactionLineUpdateInput> lines,
);
/// 단일 라인을 삭제한다.
Future<void> deleteLine(int lineId);
/// 삭제된 라인을 복구한다.
Future<StockTransactionLine> restoreLine(int lineId);
}
/// 재고 트랜잭션 고객 연결 저장소 인터페이스.
abstract class TransactionCustomerRepository {
/// 고객 연결을 추가한다.
Future<List<StockTransactionCustomer>> addCustomers(
int transactionId,
List<TransactionCustomerCreateInput> customers,
);
/// 고객 연결 정보를 수정한다.
Future<List<StockTransactionCustomer>> updateCustomers(
int transactionId,
List<TransactionCustomerUpdateInput> customers,
);
/// 고객 연결을 삭제한다.
Future<void> deleteCustomer(int customerLinkId);
}