Initial commit: Krow Worker App
This commit is contained in:
95
lib/models/shift.dart
Normal file
95
lib/models/shift.dart
Normal file
@@ -0,0 +1,95 @@
|
||||
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,
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user