import 'package:meta/meta.dart'; /// 入出庫区分。 enum InventoryMovementType { receipt, issue, adjustment, } extension InventoryMovementTypeX on InventoryMovementType { String get displayName { switch (this) { case InventoryMovementType.receipt: return '入庫'; case InventoryMovementType.issue: return '出庫'; case InventoryMovementType.adjustment: return '棚卸/調整'; } } /// 在庫増減に与える係数。 int get deltaSign { switch (this) { case InventoryMovementType.receipt: return 1; case InventoryMovementType.issue: return -1; case InventoryMovementType.adjustment: return 1; // 調整は quantityDelta をそのまま使うため符号 1 とする } } } @immutable class InventoryMovement { const InventoryMovement({ required this.id, required this.productId, required this.productNameSnapshot, required this.type, required this.quantity, required this.quantityDelta, required this.createdAt, this.reference, this.notes, }); final String id; final String productId; final String productNameSnapshot; final InventoryMovementType type; final int quantity; final int quantityDelta; final DateTime createdAt; final String? reference; final String? notes; Map toMap() => { 'id': id, 'product_id': productId, 'product_name_snapshot': productNameSnapshot, 'movement_type': type.name, 'quantity': quantity, 'quantity_delta': quantityDelta, 'reference': reference, 'notes': notes, 'created_at': createdAt.toIso8601String(), }; factory InventoryMovement.fromMap(Map map) { InventoryMovementType parseType(String? value) { return InventoryMovementType.values.firstWhere( (type) => type.name == value, orElse: () => InventoryMovementType.adjustment, ); } return InventoryMovement( id: map['id'] as String, productId: map['product_id'] as String, productNameSnapshot: map['product_name_snapshot'] as String? ?? '-', type: parseType(map['movement_type'] as String?), quantity: map['quantity'] as int? ?? 0, quantityDelta: map['quantity_delta'] as int? ?? 0, reference: map['reference'] as String?, notes: map['notes'] as String?, createdAt: DateTime.parse(map['created_at'] as String), ); } } @immutable class InventorySummary { const InventorySummary({ required this.productId, required this.productName, required this.stockQuantity, this.category, this.defaultUnitPrice, this.lastMovementAt, }); final String productId; final String productName; final int stockQuantity; final String? category; final int? defaultUnitPrice; final DateTime? lastMovementAt; InventorySummary copyWith({ int? stockQuantity, DateTime? lastMovementAt, }) { return InventorySummary( productId: productId, productName: productName, stockQuantity: stockQuantity ?? this.stockQuantity, category: category, defaultUnitPrice: defaultUnitPrice, lastMovementAt: lastMovementAt ?? this.lastMovementAt, ); } }