EnakPoint & EnakCoin wallet, PIN, outlet, order, community, reward
- Wallet EnakPoint & EnakCoin: beranda, riwayat, saldo kedaluwarsa, kode bayar, tukar EnakCoin, transfer - PIN (buat, ganti, lupa), outlet, riwayat order, game spin - Halaman community, webview, coming soon, dan ikon menu beranda baru - Redesign Reward Saya: kartu tiket, filter chip, detail kode + QR - Hapus customer point loader, menu, dan checkout lama - Base URL ke enaklo-pos-api.altru.id Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
5954510b93
commit
f5e3075205
@@ -0,0 +1,88 @@
|
||||
part of '../wallet.dart';
|
||||
|
||||
/// Order milik customer di daftar riwayat (§4.5).
|
||||
@freezed
|
||||
abstract class CustomerOrder with _$CustomerOrder {
|
||||
const CustomerOrder._();
|
||||
|
||||
const factory CustomerOrder({
|
||||
required String id,
|
||||
required String orderNumber,
|
||||
required String outletName,
|
||||
required String orderType,
|
||||
required String status,
|
||||
required String paymentStatus,
|
||||
required int totalAmount,
|
||||
required int itemCount,
|
||||
required bool isVoid,
|
||||
required bool isRefund,
|
||||
required int pointsEarned,
|
||||
required int coinsEarned,
|
||||
DateTime? createdAt,
|
||||
}) = _CustomerOrder;
|
||||
|
||||
bool get isDineIn => orderType == 'dine_in';
|
||||
}
|
||||
|
||||
@freezed
|
||||
abstract class CustomerOrderPage with _$CustomerOrderPage {
|
||||
const factory CustomerOrderPage({
|
||||
required List<CustomerOrder> items,
|
||||
required int page,
|
||||
required int totalPages,
|
||||
}) = _CustomerOrderPage;
|
||||
}
|
||||
|
||||
/// Detail order: field [order] ditambah rincian item dan pembayaran.
|
||||
@freezed
|
||||
abstract class CustomerOrderDetail with _$CustomerOrderDetail {
|
||||
const factory CustomerOrderDetail({
|
||||
required CustomerOrder order,
|
||||
String? tableNumber,
|
||||
required int subtotal,
|
||||
required int discountAmount,
|
||||
required int taxAmount,
|
||||
required int refundAmount,
|
||||
required List<CustomerOrderItem> items,
|
||||
required List<CustomerOrderPayment> payments,
|
||||
}) = _CustomerOrderDetail;
|
||||
}
|
||||
|
||||
@freezed
|
||||
abstract class CustomerOrderItem with _$CustomerOrderItem {
|
||||
const CustomerOrderItem._();
|
||||
|
||||
const factory CustomerOrderItem({
|
||||
required String id,
|
||||
required String productName,
|
||||
String? variantName,
|
||||
required int quantity,
|
||||
|
||||
/// Hanya untuk item timbangan, mis. 4,2 [unitName].
|
||||
double? weight,
|
||||
String? unitName,
|
||||
required int unitPrice,
|
||||
required int totalPrice,
|
||||
required int refundQuantity,
|
||||
}) = _CustomerOrderItem;
|
||||
|
||||
bool get isWeighted => weight != null;
|
||||
}
|
||||
|
||||
@freezed
|
||||
abstract class CustomerOrderPayment with _$CustomerOrderPayment {
|
||||
const CustomerOrderPayment._();
|
||||
|
||||
const factory CustomerOrderPayment({
|
||||
required String id,
|
||||
required String methodName,
|
||||
required String methodType,
|
||||
required int amount,
|
||||
required int refundAmount,
|
||||
|
||||
/// Hanya pada pembayaran EnakPoint.
|
||||
int? pointsUsed,
|
||||
}) = _CustomerOrderPayment;
|
||||
|
||||
bool get isPoint => methodType == 'point';
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
part of '../wallet.dart';
|
||||
|
||||
@freezed
|
||||
abstract class ExchangePreview with _$ExchangePreview {
|
||||
const factory ExchangePreview({
|
||||
required int coinAmount,
|
||||
required int pointAmount,
|
||||
required int coinBalance,
|
||||
required int coins,
|
||||
required int points,
|
||||
required bool valid,
|
||||
String? reason,
|
||||
}) = _ExchangePreview;
|
||||
}
|
||||
|
||||
@freezed
|
||||
abstract class ExchangeResult with _$ExchangeResult {
|
||||
const factory ExchangeResult({
|
||||
required int coins,
|
||||
required int points,
|
||||
required int coinBalance,
|
||||
required int pointBalance,
|
||||
required List<WalletLot> lots,
|
||||
required bool replayed,
|
||||
}) = _ExchangeResult;
|
||||
}
|
||||
|
||||
/// Bagian saldo dengan tanggal kedaluwarsanya sendiri.
|
||||
@freezed
|
||||
abstract class WalletLot with _$WalletLot {
|
||||
const factory WalletLot({required int amount, DateTime? expiresAt}) =
|
||||
_WalletLot;
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
part of '../wallet.dart';
|
||||
|
||||
/// Outlet aktif di organisasi customer, tempat saldo berlaku (§4.4).
|
||||
@freezed
|
||||
abstract class Outlet with _$Outlet {
|
||||
const factory Outlet({
|
||||
required String id,
|
||||
required String name,
|
||||
String? address,
|
||||
|
||||
/// Kasir di outlet ini menerima pembayaran EnakPoint.
|
||||
required bool acceptsPointPayment,
|
||||
|
||||
/// Belanja di outlet ini memberi EnakPoint.
|
||||
required bool earnsPoints,
|
||||
|
||||
/// Belanja di outlet ini memberi EnakCoin.
|
||||
required bool earnsCoins,
|
||||
}) = _Outlet;
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
part of '../wallet.dart';
|
||||
|
||||
@freezed
|
||||
abstract class PaymentCode with _$PaymentCode {
|
||||
const factory PaymentCode({
|
||||
required String code,
|
||||
required String qrPayload,
|
||||
required DateTime expiresAt,
|
||||
}) = _PaymentCode;
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
part of '../wallet.dart';
|
||||
|
||||
@freezed
|
||||
abstract class PinStatus with _$PinStatus {
|
||||
const PinStatus._();
|
||||
|
||||
const factory PinStatus({
|
||||
required bool hasPin,
|
||||
DateTime? lockedUntil,
|
||||
DateTime? transferBlockedUntil,
|
||||
}) = _PinStatus;
|
||||
|
||||
bool get isLocked =>
|
||||
lockedUntil != null && lockedUntil!.isAfter(DateTime.now());
|
||||
}
|
||||
|
||||
@freezed
|
||||
abstract class PinOtp with _$PinOtp {
|
||||
const factory PinOtp({
|
||||
required PinOtpPurpose purpose,
|
||||
required String otpToken,
|
||||
DateTime? expiresAt,
|
||||
}) = _PinOtp;
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
part of '../wallet.dart';
|
||||
|
||||
/// Penerima transfer; [name] dan [phoneNumber] sudah disamarkan oleh server.
|
||||
@freezed
|
||||
abstract class TransferRecipient with _$TransferRecipient {
|
||||
const factory TransferRecipient({
|
||||
required String name,
|
||||
required String phoneNumber,
|
||||
}) = _TransferRecipient;
|
||||
}
|
||||
|
||||
@freezed
|
||||
abstract class TransferResult with _$TransferResult {
|
||||
const factory TransferResult({
|
||||
required WalletCurrency currency,
|
||||
required int amount,
|
||||
required TransferRecipient recipient,
|
||||
required List<WalletLot> lots,
|
||||
required int balance,
|
||||
required bool replayed,
|
||||
}) = _TransferResult;
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
part of '../wallet.dart';
|
||||
|
||||
enum WalletCurrency {
|
||||
point('POINT', 'EnakPoint'),
|
||||
coin('COIN', 'EnakCoin');
|
||||
|
||||
const WalletCurrency(this.apiValue, this.label);
|
||||
|
||||
final String apiValue;
|
||||
final String label;
|
||||
|
||||
static WalletCurrency fromApi(String? value) =>
|
||||
value == coin.apiValue ? coin : point;
|
||||
}
|
||||
|
||||
enum WalletTransactionType {
|
||||
earn('EARN', 'Dari belanja'),
|
||||
earnReversal('EARN_REVERSAL', 'Dibatalkan (order di-void/refund)'),
|
||||
payment('PAYMENT', 'Bayar pesanan'),
|
||||
paymentRefund('PAYMENT_REFUND', 'Pengembalian pembayaran'),
|
||||
exchangeOut('EXCHANGE_OUT', 'Ditukar ke EnakPoint'),
|
||||
exchangeIn('EXCHANGE_IN', 'Hasil tukar EnakCoin'),
|
||||
transferOut('TRANSFER_OUT', 'Transfer keluar'),
|
||||
transferIn('TRANSFER_IN', 'Transfer masuk'),
|
||||
gameSpend('GAME_SPEND', 'Main game'),
|
||||
expire('EXPIRE', 'Kedaluwarsa'),
|
||||
adjustment('ADJUSTMENT', 'Koreksi'),
|
||||
migration('MIGRATION', 'Saldo awal'),
|
||||
unknown('', 'Transaksi');
|
||||
|
||||
const WalletTransactionType(this.apiValue, this.label);
|
||||
|
||||
final String apiValue;
|
||||
final String label;
|
||||
|
||||
/// Tipe yang bisa dipilih di filter riwayat.
|
||||
static List<WalletTransactionType> get filterable =>
|
||||
values.where((e) => e != unknown).toList();
|
||||
|
||||
static WalletTransactionType fromApi(String? value) =>
|
||||
values.firstWhere((e) => e.apiValue == value, orElse: () => unknown);
|
||||
}
|
||||
|
||||
enum PinOtpPurpose {
|
||||
setup('pin_setup'),
|
||||
reset('pin_reset');
|
||||
|
||||
const PinOtpPurpose(this.apiValue);
|
||||
|
||||
final String apiValue;
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
part of '../wallet.dart';
|
||||
|
||||
@freezed
|
||||
abstract class WalletExpiring with _$WalletExpiring {
|
||||
const factory WalletExpiring({
|
||||
required List<ExpiringAmount> point,
|
||||
required List<ExpiringAmount> coin,
|
||||
}) = _WalletExpiring;
|
||||
|
||||
factory WalletExpiring.empty() => const WalletExpiring(point: [], coin: []);
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
part of '../wallet.dart';
|
||||
|
||||
@freezed
|
||||
abstract class WalletSummary with _$WalletSummary {
|
||||
const factory WalletSummary({
|
||||
required int pointBalance,
|
||||
required int coinBalance,
|
||||
required int pointValue,
|
||||
required int pointDiscountValue,
|
||||
ExpiringAmount? nearestExpiringPoint,
|
||||
ExpiringAmount? nearestExpiringCoin,
|
||||
required List<WalletTransaction> recentTransactions,
|
||||
}) = _WalletSummary;
|
||||
|
||||
factory WalletSummary.empty() => const WalletSummary(
|
||||
pointBalance: 0,
|
||||
coinBalance: 0,
|
||||
pointValue: 0,
|
||||
pointDiscountValue: 0,
|
||||
recentTransactions: [],
|
||||
);
|
||||
}
|
||||
|
||||
/// Jumlah saldo yang akan hangus pada [date] (tanggal WIB, berlaku sampai
|
||||
/// 23:59:59 WIB di tanggal itu).
|
||||
@freezed
|
||||
abstract class ExpiringAmount with _$ExpiringAmount {
|
||||
const factory ExpiringAmount({required int amount, required DateTime date}) =
|
||||
_ExpiringAmount;
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
part of '../wallet.dart';
|
||||
|
||||
@freezed
|
||||
abstract class WalletTransaction with _$WalletTransaction {
|
||||
const WalletTransaction._();
|
||||
|
||||
const factory WalletTransaction({
|
||||
required String id,
|
||||
required WalletCurrency currency,
|
||||
required WalletTransactionType type,
|
||||
required int amount,
|
||||
required int balanceAfter,
|
||||
required String description,
|
||||
String? groupId,
|
||||
DateTime? expiresAt,
|
||||
DateTime? createdAt,
|
||||
}) = _WalletTransaction;
|
||||
|
||||
bool get isIncoming => amount > 0;
|
||||
}
|
||||
|
||||
@freezed
|
||||
abstract class WalletTransactionPage with _$WalletTransactionPage {
|
||||
const factory WalletTransactionPage({
|
||||
required List<WalletTransaction> items,
|
||||
required int page,
|
||||
required int totalPages,
|
||||
required int totalCount,
|
||||
}) = _WalletTransactionPage;
|
||||
}
|
||||
Reference in New Issue
Block a user