h-1.flutter.0/lib/models/purchase_entry_models.dart
2026-03-05 09:33:38 +09:00

288 lines
8.4 KiB
Dart

import 'package:flutter/foundation.dart';
enum PurchaseEntryStatus { draft, confirmed, settled }
extension PurchaseEntryStatusDisplay on PurchaseEntryStatus {
String get displayName {
switch (this) {
case PurchaseEntryStatus.draft:
return '下書き';
case PurchaseEntryStatus.confirmed:
return '確定';
case PurchaseEntryStatus.settled:
return '支払済み';
}
}
}
@immutable
class PurchaseLineItem {
const PurchaseLineItem({
required this.id,
required this.purchaseEntryId,
required this.description,
required this.quantity,
required this.unitPrice,
required this.lineTotal,
this.productId,
this.taxRate = 0,
});
final String id;
final String purchaseEntryId;
final String description;
final int quantity;
final int unitPrice;
final int lineTotal;
final String? productId;
final double taxRate;
Map<String, dynamic> toMap() => {
'id': id,
'purchase_entry_id': purchaseEntryId,
'product_id': productId,
'description': description,
'quantity': quantity,
'unit_price': unitPrice,
'tax_rate': taxRate,
'line_total': lineTotal,
};
factory PurchaseLineItem.fromMap(Map<String, dynamic> map) => PurchaseLineItem(
id: map['id'] as String,
purchaseEntryId: map['purchase_entry_id'] as String,
productId: map['product_id'] as String?,
description: map['description'] as String,
quantity: map['quantity'] as int? ?? 0,
unitPrice: map['unit_price'] as int? ?? 0,
taxRate: (map['tax_rate'] as num?)?.toDouble() ?? 0,
lineTotal: map['line_total'] as int? ?? 0,
);
PurchaseLineItem copyWith({
String? id,
String? purchaseEntryId,
String? description,
int? quantity,
int? unitPrice,
int? lineTotal,
String? productId,
double? taxRate,
}) {
return PurchaseLineItem(
id: id ?? this.id,
purchaseEntryId: purchaseEntryId ?? this.purchaseEntryId,
description: description ?? this.description,
quantity: quantity ?? this.quantity,
unitPrice: unitPrice ?? this.unitPrice,
lineTotal: lineTotal ?? this.lineTotal,
productId: productId ?? this.productId,
taxRate: taxRate ?? this.taxRate,
);
}
}
@immutable
class PurchaseEntry {
const PurchaseEntry({
required this.id,
required this.issueDate,
required this.status,
required this.createdAt,
required this.updatedAt,
this.supplierId,
this.supplierNameSnapshot,
this.subject,
this.amountTaxExcl = 0,
this.taxAmount = 0,
this.amountTaxIncl = 0,
this.notes,
this.items = const [],
});
final String id;
final String? supplierId;
final String? supplierNameSnapshot;
final String? subject;
final DateTime issueDate;
final PurchaseEntryStatus status;
final int amountTaxExcl;
final int taxAmount;
final int amountTaxIncl;
final String? notes;
final DateTime createdAt;
final DateTime updatedAt;
final List<PurchaseLineItem> items;
PurchaseEntry copyWith({
String? id,
String? supplierId,
String? supplierNameSnapshot,
String? subject,
DateTime? issueDate,
PurchaseEntryStatus? status,
int? amountTaxExcl,
int? taxAmount,
int? amountTaxIncl,
String? notes,
DateTime? createdAt,
DateTime? updatedAt,
List<PurchaseLineItem>? items,
}) {
return PurchaseEntry(
id: id ?? this.id,
supplierId: supplierId ?? this.supplierId,
supplierNameSnapshot: supplierNameSnapshot ?? this.supplierNameSnapshot,
subject: subject ?? this.subject,
issueDate: issueDate ?? this.issueDate,
status: status ?? this.status,
amountTaxExcl: amountTaxExcl ?? this.amountTaxExcl,
taxAmount: taxAmount ?? this.taxAmount,
amountTaxIncl: amountTaxIncl ?? this.amountTaxIncl,
notes: notes ?? this.notes,
createdAt: createdAt ?? this.createdAt,
updatedAt: updatedAt ?? this.updatedAt,
items: items ?? this.items,
);
}
Map<String, dynamic> toMap() => {
'id': id,
'supplier_id': supplierId,
'supplier_name_snapshot': supplierNameSnapshot,
'subject': subject,
'issue_date': issueDate.toIso8601String(),
'status': status.name,
'amount_tax_excl': amountTaxExcl,
'tax_amount': taxAmount,
'amount_tax_incl': amountTaxIncl,
'notes': notes,
'created_at': createdAt.toIso8601String(),
'updated_at': updatedAt.toIso8601String(),
};
factory PurchaseEntry.fromMap(Map<String, dynamic> map, {List<PurchaseLineItem> items = const []}) => PurchaseEntry(
id: map['id'] as String,
supplierId: map['supplier_id'] as String?,
supplierNameSnapshot: map['supplier_name_snapshot'] as String?,
subject: map['subject'] as String?,
issueDate: DateTime.parse(map['issue_date'] as String),
status: PurchaseEntryStatus.values.firstWhere(
(s) => s.name == map['status'],
orElse: () => PurchaseEntryStatus.draft,
),
amountTaxExcl: map['amount_tax_excl'] as int? ?? 0,
taxAmount: map['tax_amount'] as int? ?? 0,
amountTaxIncl: map['amount_tax_incl'] as int? ?? 0,
notes: map['notes'] as String?,
createdAt: DateTime.parse(map['created_at'] as String),
updatedAt: DateTime.parse(map['updated_at'] as String),
items: items,
);
PurchaseEntry recalcTotals() {
final subtotal = items.fold<int>(0, (sum, item) => sum + item.lineTotal);
final tax = items.fold<double>(0, (sum, item) => sum + item.lineTotal * item.taxRate).round();
return copyWith(
amountTaxExcl: subtotal,
taxAmount: tax,
amountTaxIncl: subtotal + tax,
);
}
}
@immutable
class PurchaseReceiptAllocationInput {
const PurchaseReceiptAllocationInput({required this.purchaseEntryId, required this.amount});
final String purchaseEntryId;
final int amount;
}
@immutable
class PurchaseReceipt {
const PurchaseReceipt({
required this.id,
required this.paymentDate,
required this.amount,
required this.createdAt,
required this.updatedAt,
this.supplierId,
this.method,
this.notes,
});
final String id;
final String? supplierId;
final DateTime paymentDate;
final String? method;
final int amount;
final String? notes;
final DateTime createdAt;
final DateTime updatedAt;
Map<String, dynamic> toMap() => {
'id': id,
'supplier_id': supplierId,
'payment_date': paymentDate.toIso8601String(),
'method': method,
'amount': amount,
'notes': notes,
'created_at': createdAt.toIso8601String(),
'updated_at': updatedAt.toIso8601String(),
};
factory PurchaseReceipt.fromMap(Map<String, dynamic> map) => PurchaseReceipt(
id: map['id'] as String,
supplierId: map['supplier_id'] as String?,
paymentDate: DateTime.parse(map['payment_date'] as String),
method: map['method'] as String?,
amount: map['amount'] as int? ?? 0,
notes: map['notes'] as String?,
createdAt: DateTime.parse(map['created_at'] as String),
updatedAt: DateTime.parse(map['updated_at'] as String),
);
PurchaseReceipt copyWith({
String? id,
String? supplierId,
DateTime? paymentDate,
String? method,
int? amount,
String? notes,
DateTime? createdAt,
DateTime? updatedAt,
}) {
return PurchaseReceipt(
id: id ?? this.id,
supplierId: supplierId ?? this.supplierId,
paymentDate: paymentDate ?? this.paymentDate,
method: method ?? this.method,
amount: amount ?? this.amount,
notes: notes ?? this.notes,
createdAt: createdAt ?? this.createdAt,
updatedAt: updatedAt ?? this.updatedAt,
);
}
}
@immutable
class PurchaseReceiptLink {
const PurchaseReceiptLink({required this.receiptId, required this.purchaseEntryId, required this.allocatedAmount});
final String receiptId;
final String purchaseEntryId;
final int allocatedAmount;
Map<String, dynamic> toMap() => {
'receipt_id': receiptId,
'purchase_entry_id': purchaseEntryId,
'allocated_amount': allocatedAmount,
};
factory PurchaseReceiptLink.fromMap(Map<String, dynamic> map) => PurchaseReceiptLink(
receiptId: map['receipt_id'] as String,
purchaseEntryId: map['purchase_entry_id'] as String,
allocatedAmount: map['allocated_amount'] as int? ?? 0,
);
}