/// 出荷ステータス定義。 enum ShipmentStatus { pending, picking, ready, shipped, delivered, cancelled, } extension ShipmentStatusX on ShipmentStatus { String get displayName { switch (this) { case ShipmentStatus.pending: return '未手配'; case ShipmentStatus.picking: return 'ピッキング中'; case ShipmentStatus.ready: return '出荷待ち'; case ShipmentStatus.shipped: return '出荷済み'; case ShipmentStatus.delivered: return '納品済み'; case ShipmentStatus.cancelled: return 'キャンセル'; } } static ShipmentStatus fromDbValue(String? value) { return ShipmentStatus.values.firstWhere( (status) => status.name == value, orElse: () => ShipmentStatus.pending, ); } } class ShipmentItem { ShipmentItem({ required this.id, required this.shipmentId, required this.description, required this.quantity, this.orderItemId, }); final String id; final String shipmentId; final String? orderItemId; final String description; final int quantity; Map toMap() => { 'id': id, 'shipment_id': shipmentId, 'order_item_id': orderItemId, 'description': description, 'quantity': quantity, }; factory ShipmentItem.fromMap(Map map) => ShipmentItem( id: map['id'] as String, shipmentId: map['shipment_id'] as String, orderItemId: map['order_item_id'] as String?, description: map['description'] as String, quantity: map['quantity'] as int? ?? 0, ); } class Shipment { Shipment({ required this.id, required this.status, required this.createdAt, required this.updatedAt, this.orderId, this.orderNumberSnapshot, this.customerNameSnapshot, this.scheduledShipDate, this.actualShipDate, this.carrierName, this.trackingNumber, this.trackingUrl, this.labelPdfPath, this.notes, this.pickingCompletedAt, this.items = const [], }); final String id; final String? orderId; final String? orderNumberSnapshot; final String? customerNameSnapshot; final DateTime? scheduledShipDate; final DateTime? actualShipDate; final ShipmentStatus status; final String? carrierName; final String? trackingNumber; final String? trackingUrl; final String? labelPdfPath; final String? notes; final DateTime? pickingCompletedAt; final DateTime createdAt; final DateTime updatedAt; final List items; Shipment copyWith({ String? id, String? orderId, String? orderNumberSnapshot, String? customerNameSnapshot, DateTime? scheduledShipDate, DateTime? actualShipDate, ShipmentStatus? status, String? carrierName, String? trackingNumber, String? trackingUrl, String? labelPdfPath, String? notes, DateTime? pickingCompletedAt, DateTime? createdAt, DateTime? updatedAt, List? items, }) { return Shipment( id: id ?? this.id, orderId: orderId ?? this.orderId, orderNumberSnapshot: orderNumberSnapshot ?? this.orderNumberSnapshot, customerNameSnapshot: customerNameSnapshot ?? this.customerNameSnapshot, scheduledShipDate: scheduledShipDate ?? this.scheduledShipDate, actualShipDate: actualShipDate ?? this.actualShipDate, status: status ?? this.status, carrierName: carrierName ?? this.carrierName, trackingNumber: trackingNumber ?? this.trackingNumber, trackingUrl: trackingUrl ?? this.trackingUrl, labelPdfPath: labelPdfPath ?? this.labelPdfPath, notes: notes ?? this.notes, pickingCompletedAt: pickingCompletedAt ?? this.pickingCompletedAt, createdAt: createdAt ?? this.createdAt, updatedAt: updatedAt ?? this.updatedAt, items: items ?? this.items, ); } Map toMap() => { 'id': id, 'order_id': orderId, 'order_number_snapshot': orderNumberSnapshot, 'customer_name_snapshot': customerNameSnapshot, 'scheduled_ship_date': scheduledShipDate?.toIso8601String(), 'actual_ship_date': actualShipDate?.toIso8601String(), 'status': status.name, 'carrier_name': carrierName, 'tracking_number': trackingNumber, 'tracking_url': trackingUrl, 'label_pdf_path': labelPdfPath, 'notes': notes, 'picking_completed_at': pickingCompletedAt?.toIso8601String(), 'created_at': createdAt.toIso8601String(), 'updated_at': updatedAt.toIso8601String(), }; factory Shipment.fromMap(Map map, {List items = const []}) { DateTime? parseNullable(String? value) => value == null ? null : DateTime.parse(value); return Shipment( id: map['id'] as String, orderId: map['order_id'] as String?, orderNumberSnapshot: map['order_number_snapshot'] as String?, customerNameSnapshot: map['customer_name_snapshot'] as String?, scheduledShipDate: parseNullable(map['scheduled_ship_date'] as String?), actualShipDate: parseNullable(map['actual_ship_date'] as String?), status: ShipmentStatusX.fromDbValue(map['status'] as String?), carrierName: map['carrier_name'] as String?, trackingNumber: map['tracking_number'] as String?, trackingUrl: map['tracking_url'] as String?, labelPdfPath: map['label_pdf_path'] as String?, notes: map['notes'] as String?, pickingCompletedAt: parseNullable(map['picking_completed_at'] as String?), createdAt: DateTime.parse(map['created_at'] as String), updatedAt: DateTime.parse(map['updated_at'] as String), items: items, ); } ShipmentStatus nextDefaultStatus() { switch (status) { case ShipmentStatus.pending: return ShipmentStatus.picking; case ShipmentStatus.picking: return ShipmentStatus.ready; case ShipmentStatus.ready: return ShipmentStatus.shipped; case ShipmentStatus.shipped: return ShipmentStatus.delivered; case ShipmentStatus.delivered: case ShipmentStatus.cancelled: return status; } } }