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,153 @@
import 'package:flutter_test/flutter_test.dart';
import 'package:superport_v2/features/inventory/transactions/domain/entities/stock_transaction.dart';
import 'package:superport_v2/features/inventory/transactions/presentation/services/transaction_detail_sync_service.dart';
StockTransactionLine _buildLine({
int? id,
int productId = 1,
int lineNo = 1,
int quantity = 1,
double unitPrice = 1000,
String? note,
}) {
return StockTransactionLine(
id: id,
lineNo: lineNo,
product: StockTransactionProduct(
id: productId,
code: 'P$productId',
name: '제품$productId',
),
quantity: quantity,
unitPrice: unitPrice,
note: note,
);
}
StockTransactionCustomer _buildCustomer({
int? id,
int customerId = 1,
String code = 'C1',
String name = '고객1',
String? note,
}) {
return StockTransactionCustomer(
id: id,
customer: StockTransactionCustomerSummary(
id: customerId,
code: code,
name: name,
),
note: note,
);
}
void main() {
const service = TransactionDetailSyncService();
group('TransactionDetailSyncService', () {
test('buildLinePlan는 생성/수정/삭제 계획을 정확히 산출한다', () {
final currentLines = [
_buildLine(
id: 10,
productId: 1,
lineNo: 1,
quantity: 2,
unitPrice: 1000,
),
_buildLine(
id: 11,
productId: 2,
lineNo: 2,
quantity: 4,
unitPrice: 2000,
),
_buildLine(
id: 12,
productId: 3,
lineNo: 3,
quantity: 6,
unitPrice: 3000,
),
];
final drafts = [
TransactionLineDraft(
id: 10,
lineNo: 1,
productId: 1,
quantity: 3,
unitPrice: 1000,
note: null,
),
TransactionLineDraft(
id: 11,
lineNo: 2,
productId: 4,
quantity: 4,
unitPrice: 2200,
note: '교체',
),
TransactionLineDraft(
lineNo: 3,
productId: 5,
quantity: 1,
unitPrice: 500,
note: null,
),
];
final plan = service.buildLinePlan(
drafts: drafts,
currentLines: currentLines,
);
expect(plan.createdLines.length, 2);
final createdProductIds = plan.createdLines.map((line) => line.productId);
expect(createdProductIds, containsAll(<int>[4, 5]));
expect(plan.updatedLines.length, 1);
final update = plan.updatedLines.first;
expect(update.id, 10);
expect(update.quantity, 3);
expect(update.unitPrice, isNull);
expect(update.note, isNull);
expect(plan.deletedLineIds.length, 2);
expect(plan.deletedLineIds, containsAll(<int>[11, 12]));
});
test('buildCustomerPlan은 고객 추가/수정/삭제를 구분한다', () {
final currentCustomers = [
_buildCustomer(
id: 20,
customerId: 100,
code: 'C100',
name: '고객 100',
note: '메모',
),
_buildCustomer(id: 21, customerId: 200, code: 'C200', name: '고객 200'),
];
final drafts = [
TransactionCustomerDraft(id: 20, customerId: 100, note: '메모 수정'),
TransactionCustomerDraft(customerId: 300, note: null),
];
final plan = service.buildCustomerPlan(
drafts: drafts,
currentCustomers: currentCustomers,
);
expect(plan.createdCustomers.length, 1);
expect(plan.createdCustomers.first.customerId, 300);
expect(plan.updatedCustomers.length, 1);
expect(plan.updatedCustomers.first.id, 20);
expect(plan.updatedCustomers.first.note, '메모 수정');
expect(plan.deletedCustomerIds.length, 1);
expect(plan.deletedCustomerIds.first, 21);
});
});
}