Files
krow-worker-app/lib/models/shift.dart
2026-09-17 22:26:11 +05:30

96 lines
2.5 KiB
Dart

enum ShiftStatus { open, booked, active, completed, cancelled, noShow }
extension ShiftStatusX on ShiftStatus {
String get label => switch (this) {
ShiftStatus.open => 'Open',
ShiftStatus.booked => 'Confirmed',
ShiftStatus.active => 'In progress',
ShiftStatus.completed => 'Completed',
ShiftStatus.cancelled => 'Cancelled',
ShiftStatus.noShow => 'No show',
};
}
class Shift {
Shift({
required this.id,
required this.role,
required this.business,
required this.venue,
required this.address,
required this.start,
required this.end,
required this.rate,
required this.status,
this.breakMinutes = 30,
this.distanceMiles = 2.4,
this.manager,
this.clockIn,
this.clockOut,
this.requirements = const [],
});
final String id;
final String role;
final String business;
final String venue;
final String address;
final DateTime start;
final DateTime end;
final double rate;
final ShiftStatus status;
final int breakMinutes;
final double distanceMiles;
final String? manager;
final DateTime? clockIn;
final DateTime? clockOut;
final List<String> requirements;
/// Paid duration: the scheduled window less the unpaid break.
Duration get scheduledDuration =>
end.difference(start) - Duration(minutes: breakMinutes);
/// What was actually worked, once clocked out.
Duration? get workedDuration {
if (clockIn == null || clockOut == null) return null;
final d = clockOut!.difference(clockIn!) - Duration(minutes: breakMinutes);
return d.isNegative ? Duration.zero : d;
}
double get scheduledPay => rate * scheduledDuration.inMinutes / 60;
/// Gross, pre-tax. Falls back to the scheduled figure until clocked out.
double get pay {
if (status == ShiftStatus.cancelled || status == ShiftStatus.noShow) {
return 0;
}
final worked = workedDuration;
if (worked != null) return rate * worked.inMinutes / 60;
return scheduledPay;
}
String get logoLetter => business.isEmpty ? '?' : business[0].toUpperCase();
Shift copyWith({
ShiftStatus? status,
DateTime? clockIn,
DateTime? clockOut,
}) => Shift(
id: id,
role: role,
business: business,
venue: venue,
address: address,
start: start,
end: end,
rate: rate,
status: status ?? this.status,
breakMinutes: breakMinutes,
distanceMiles: distanceMiles,
manager: manager,
clockIn: clockIn ?? this.clockIn,
clockOut: clockOut ?? this.clockOut,
requirements: requirements,
);
}