second commit
This commit is contained in:
123
lib/domain/entities/customer.dart
Normal file
123
lib/domain/entities/customer.dart
Normal file
@@ -0,0 +1,123 @@
|
||||
import 'package:equatable/equatable.dart';
|
||||
|
||||
import '../../core/constants/app_constants.dart';
|
||||
|
||||
enum Gender {
|
||||
male('Male'),
|
||||
female('Female'),
|
||||
other('Other'),
|
||||
unspecified('Prefer not to say');
|
||||
|
||||
const Gender(this.label);
|
||||
|
||||
final String label;
|
||||
}
|
||||
|
||||
/// Loyalty tier, derived from lifetime spend.
|
||||
enum MembershipTier {
|
||||
bronze('Bronze', 0, 0.0),
|
||||
silver('Silver', 10000, 0.02),
|
||||
gold('Gold', 50000, 0.05),
|
||||
platinum('Platinum', 150000, 0.08);
|
||||
|
||||
const MembershipTier(this.label, this.threshold, this.discountRate);
|
||||
|
||||
final String label;
|
||||
|
||||
/// Lifetime spend in rupees required to reach this tier.
|
||||
final double threshold;
|
||||
|
||||
/// Automatic bill discount granted to members of this tier.
|
||||
final double discountRate;
|
||||
|
||||
static MembershipTier forSpend(double lifetimeSpend) {
|
||||
return MembershipTier.values.lastWhere(
|
||||
(t) => lifetimeSpend >= t.threshold,
|
||||
orElse: () => MembershipTier.bronze,
|
||||
);
|
||||
}
|
||||
|
||||
MembershipTier? get next {
|
||||
final i = index;
|
||||
return i < MembershipTier.values.length - 1
|
||||
? MembershipTier.values[i + 1]
|
||||
: null;
|
||||
}
|
||||
}
|
||||
|
||||
/// A registered shopper. A `null` customer on a sale means walk-in.
|
||||
class Customer extends Equatable {
|
||||
const Customer({
|
||||
required this.id,
|
||||
required this.name,
|
||||
required this.mobile,
|
||||
this.email,
|
||||
this.gender = Gender.unspecified,
|
||||
this.dateOfBirth,
|
||||
this.loyaltyPoints = 0,
|
||||
this.lifetimeSpend = 0,
|
||||
this.visitCount = 0,
|
||||
this.createdAt,
|
||||
this.lastVisitAt,
|
||||
});
|
||||
|
||||
final String id;
|
||||
final String name;
|
||||
final String mobile;
|
||||
final String? email;
|
||||
final Gender gender;
|
||||
final DateTime? dateOfBirth;
|
||||
final int loyaltyPoints;
|
||||
final double lifetimeSpend;
|
||||
final int visitCount;
|
||||
final DateTime? createdAt;
|
||||
final DateTime? lastVisitAt;
|
||||
|
||||
MembershipTier get tier => MembershipTier.forSpend(lifetimeSpend);
|
||||
|
||||
/// Cash value of the points currently held.
|
||||
double get redeemableValue =>
|
||||
loyaltyPoints * AppConstants.loyaltyPointValue;
|
||||
|
||||
/// Rupees of additional spend needed to reach the next tier.
|
||||
double? get spendToNextTier {
|
||||
final next = tier.next;
|
||||
if (next == null) return null;
|
||||
return (next.threshold - lifetimeSpend).clamp(0, double.infinity);
|
||||
}
|
||||
|
||||
bool get isBirthdayToday {
|
||||
final dob = dateOfBirth;
|
||||
if (dob == null) return false;
|
||||
final now = DateTime.now();
|
||||
return dob.month == now.month && dob.day == now.day;
|
||||
}
|
||||
|
||||
Customer copyWith({
|
||||
String? name,
|
||||
String? email,
|
||||
Gender? gender,
|
||||
DateTime? dateOfBirth,
|
||||
int? loyaltyPoints,
|
||||
double? lifetimeSpend,
|
||||
int? visitCount,
|
||||
DateTime? lastVisitAt,
|
||||
}) {
|
||||
return Customer(
|
||||
id: id,
|
||||
name: name ?? this.name,
|
||||
mobile: mobile,
|
||||
email: email ?? this.email,
|
||||
gender: gender ?? this.gender,
|
||||
dateOfBirth: dateOfBirth ?? this.dateOfBirth,
|
||||
loyaltyPoints: loyaltyPoints ?? this.loyaltyPoints,
|
||||
lifetimeSpend: lifetimeSpend ?? this.lifetimeSpend,
|
||||
visitCount: visitCount ?? this.visitCount,
|
||||
createdAt: createdAt,
|
||||
lastVisitAt: lastVisitAt ?? this.lastVisitAt,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
List<Object?> get props => [id, name, mobile, loyaltyPoints, lifetimeSpend];
|
||||
}
|
||||
Reference in New Issue
Block a user