solving problem adding checkin time
This commit is contained in:
@@ -1,16 +1,16 @@
|
||||
# Basic Usage
|
||||
|
||||
```dart
|
||||
ExampleConnector.instance.CreateStaff(createStaffVariables).execute();
|
||||
ExampleConnector.instance.UpdateStaff(updateStaffVariables).execute();
|
||||
ExampleConnector.instance.DeleteStaff(deleteStaffVariables).execute();
|
||||
ExampleConnector.instance.listStaffAvailabilities(listStaffAvailabilitiesVariables).execute();
|
||||
ExampleConnector.instance.listStaffAvailabilitiesByStaffId(listStaffAvailabilitiesByStaffIdVariables).execute();
|
||||
ExampleConnector.instance.getStaffAvailabilityByKey(getStaffAvailabilityByKeyVariables).execute();
|
||||
ExampleConnector.instance.listStaffAvailabilitiesByDay(listStaffAvailabilitiesByDayVariables).execute();
|
||||
ExampleConnector.instance.createStaffAvailabilityStats(createStaffAvailabilityStatsVariables).execute();
|
||||
ExampleConnector.instance.updateStaffAvailabilityStats(updateStaffAvailabilityStatsVariables).execute();
|
||||
ExampleConnector.instance.deleteStaffAvailabilityStats(deleteStaffAvailabilityStatsVariables).execute();
|
||||
ExampleConnector.instance.createTaskComment(createTaskCommentVariables).execute();
|
||||
ExampleConnector.instance.updateTaskComment(updateTaskCommentVariables).execute();
|
||||
ExampleConnector.instance.deleteTaskComment(deleteTaskCommentVariables).execute();
|
||||
ExampleConnector.instance.createTaxForm(createTaxFormVariables).execute();
|
||||
ExampleConnector.instance.updateTaxForm(updateTaxFormVariables).execute();
|
||||
ExampleConnector.instance.deleteTaxForm(deleteTaxFormVariables).execute();
|
||||
ExampleConnector.instance.createUserConversation(createUserConversationVariables).execute();
|
||||
ExampleConnector.instance.updateUserConversation(updateUserConversationVariables).execute();
|
||||
ExampleConnector.instance.markConversationAsRead(markConversationAsReadVariables).execute();
|
||||
ExampleConnector.instance.incrementUnreadForUser(incrementUnreadForUserVariables).execute();
|
||||
|
||||
```
|
||||
|
||||
@@ -23,7 +23,7 @@ Optional fields can be discovered based on classes that have `Optional` object t
|
||||
This is an example of a mutation with an optional field:
|
||||
|
||||
```dart
|
||||
await ExampleConnector.instance.searchInvoiceTemplatesByOwnerAndName({ ... })
|
||||
await ExampleConnector.instance.listStaffAvailabilitiesByDay({ ... })
|
||||
.offset(...)
|
||||
.execute();
|
||||
```
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -7,7 +7,7 @@ class UpdateApplicationStatusVariablesBuilder {
|
||||
Optional<ApplicationStatus> _status = Optional.optional((data) => ApplicationStatus.values.byName(data), enumSerializer);
|
||||
Optional<Timestamp> _checkInTime = Optional.optional((json) => json['checkInTime'] = Timestamp.fromJson(json['checkInTime']), defaultSerializer);
|
||||
Optional<Timestamp> _checkOutTime = Optional.optional((json) => json['checkOutTime'] = Timestamp.fromJson(json['checkOutTime']), defaultSerializer);
|
||||
String roleId;
|
||||
Optional<String> _roleId = Optional.optional(nativeFromJson, nativeToJson);
|
||||
|
||||
final FirebaseDataConnect _dataConnect; UpdateApplicationStatusVariablesBuilder shiftId(String? t) {
|
||||
_shiftId.value = t;
|
||||
@@ -29,8 +29,12 @@ class UpdateApplicationStatusVariablesBuilder {
|
||||
_checkOutTime.value = t;
|
||||
return this;
|
||||
}
|
||||
UpdateApplicationStatusVariablesBuilder roleId(String? t) {
|
||||
_roleId.value = t;
|
||||
return this;
|
||||
}
|
||||
|
||||
UpdateApplicationStatusVariablesBuilder(this._dataConnect, {required this.id,required this.roleId,});
|
||||
UpdateApplicationStatusVariablesBuilder(this._dataConnect, {required this.id,});
|
||||
Deserializer<UpdateApplicationStatusData> dataDeserializer = (dynamic json) => UpdateApplicationStatusData.fromJson(jsonDecode(json));
|
||||
Serializer<UpdateApplicationStatusVariables> varsSerializer = (UpdateApplicationStatusVariables vars) => jsonEncode(vars.toJson());
|
||||
Future<OperationResult<UpdateApplicationStatusData, UpdateApplicationStatusVariables>> execute() {
|
||||
@@ -38,7 +42,7 @@ class UpdateApplicationStatusVariablesBuilder {
|
||||
}
|
||||
|
||||
MutationRef<UpdateApplicationStatusData, UpdateApplicationStatusVariables> ref() {
|
||||
UpdateApplicationStatusVariables vars= UpdateApplicationStatusVariables(id: id,shiftId: _shiftId,staffId: _staffId,status: _status,checkInTime: _checkInTime,checkOutTime: _checkOutTime,roleId: roleId,);
|
||||
UpdateApplicationStatusVariables vars= UpdateApplicationStatusVariables(id: id,shiftId: _shiftId,staffId: _staffId,status: _status,checkInTime: _checkInTime,checkOutTime: _checkOutTime,roleId: _roleId,);
|
||||
return _dataConnect.mutation("updateApplicationStatus", dataDeserializer, varsSerializer, vars);
|
||||
}
|
||||
}
|
||||
@@ -121,12 +125,11 @@ class UpdateApplicationStatusVariables {
|
||||
late final Optional<ApplicationStatus>status;
|
||||
late final Optional<Timestamp>checkInTime;
|
||||
late final Optional<Timestamp>checkOutTime;
|
||||
final String roleId;
|
||||
late final Optional<String>roleId;
|
||||
@Deprecated('fromJson is deprecated for Variable classes as they are no longer required for deserialization.')
|
||||
UpdateApplicationStatusVariables.fromJson(Map<String, dynamic> json):
|
||||
|
||||
id = nativeFromJson<String>(json['id']),
|
||||
roleId = nativeFromJson<String>(json['roleId']) {
|
||||
id = nativeFromJson<String>(json['id']) {
|
||||
|
||||
|
||||
|
||||
@@ -150,6 +153,9 @@ class UpdateApplicationStatusVariables {
|
||||
checkOutTime.value = json['checkOutTime'] == null ? null : Timestamp.fromJson(json['checkOutTime']);
|
||||
|
||||
|
||||
roleId = Optional.optional(nativeFromJson, nativeToJson);
|
||||
roleId.value = json['roleId'] == null ? null : nativeFromJson<String>(json['roleId']);
|
||||
|
||||
}
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
@@ -192,7 +198,9 @@ class UpdateApplicationStatusVariables {
|
||||
if(checkOutTime.state == OptionalState.set) {
|
||||
json['checkOutTime'] = checkOutTime.toJson();
|
||||
}
|
||||
json['roleId'] = nativeToJson<String>(roleId);
|
||||
if(roleId.state == OptionalState.set) {
|
||||
json['roleId'] = roleId.toJson();
|
||||
}
|
||||
return json;
|
||||
}
|
||||
|
||||
|
||||
@@ -45,7 +45,7 @@ class ViewOrdersRepositoryImpl implements IViewOrdersRepository {
|
||||
'Your Company';
|
||||
|
||||
return result.data.shiftRoles.map((dc.ListShiftRolesByBusinessAndDateRangeShiftRoles shiftRole) {
|
||||
final DateTime? shiftDate = shiftRole.shift.date?.toDateTime();
|
||||
final DateTime? shiftDate = shiftRole.shift.date?.toDateTime().toLocal();
|
||||
final String dateStr = shiftDate == null
|
||||
? ''
|
||||
: DateFormat('yyyy-MM-dd').format(shiftDate);
|
||||
|
||||
@@ -215,13 +215,31 @@ class ClockInRepositoryImpl implements ClockInRepositoryInterface {
|
||||
app ??= (await _getTodaysApplications(staffId))
|
||||
.firstWhere((a) => a.shiftId == shiftId);
|
||||
|
||||
await _dataConnect
|
||||
.updateApplicationStatus(
|
||||
id: app.id,
|
||||
roleId: app.shiftRole.id,
|
||||
)
|
||||
.checkInTime(_fromDateTime(DateTime.now()))
|
||||
.execute();
|
||||
final Timestamp checkInTs = _fromDateTime(DateTime.now());
|
||||
print(
|
||||
'ClockIn request: appId=${app.id} shiftId=$shiftId '
|
||||
'checkInTime=${checkInTs.toJson()}',
|
||||
);
|
||||
try {
|
||||
await _dataConnect
|
||||
.updateApplicationStatus(
|
||||
id: app.id,
|
||||
)
|
||||
.checkInTime(checkInTs)
|
||||
.execute();
|
||||
} catch (e) {
|
||||
print('ClockIn updateApplicationStatus error: $e');
|
||||
print('ClockIn error type: ${e.runtimeType}');
|
||||
try {
|
||||
final dynamic err = e;
|
||||
final dynamic details =
|
||||
err.details ?? err.response ?? err.data ?? err.message;
|
||||
if (details != null) {
|
||||
print('ClockIn error details: $details');
|
||||
}
|
||||
} catch (_) {}
|
||||
rethrow;
|
||||
}
|
||||
|
||||
return getAttendanceStatus();
|
||||
}
|
||||
@@ -236,10 +254,10 @@ class ClockInRepositoryImpl implements ClockInRepositoryInterface {
|
||||
_getActiveApplication(apps);
|
||||
if (app == null) throw Exception('No active shift found to clock out');
|
||||
|
||||
await _dataConnect.updateApplicationStatus(
|
||||
id: app.id,
|
||||
roleId: app.shiftRole.id,
|
||||
)
|
||||
await _dataConnect
|
||||
.updateApplicationStatus(
|
||||
id: app.id,
|
||||
)
|
||||
.status(dc.ApplicationStatus.CHECKED_OUT)
|
||||
.checkOutTime(_fromDateTime(DateTime.now()))
|
||||
.execute();
|
||||
|
||||
@@ -52,7 +52,7 @@ class ShiftsRepositoryImpl implements ShiftsRepositoryInterface {
|
||||
return user.uid;
|
||||
}
|
||||
|
||||
DateTime? _toDateTime(dynamic t) {
|
||||
DateTime? _toDateTime(dynamic t, {String? debugKey}) {
|
||||
if (t == null) return null;
|
||||
DateTime? dt;
|
||||
if (t is Timestamp) {
|
||||
@@ -72,7 +72,13 @@ class ShiftsRepositoryImpl implements ShiftsRepositoryInterface {
|
||||
}
|
||||
|
||||
if (dt != null) {
|
||||
return DateTimeUtils.toDeviceTime(dt);
|
||||
final local = DateTimeUtils.toDeviceTime(dt);
|
||||
if (debugKey != null && debugKey.isNotEmpty) {
|
||||
print(
|
||||
'ShiftDate convert: key=$debugKey raw=$t parsed=${dt.toIso8601String()} local=${local.toIso8601String()}',
|
||||
);
|
||||
}
|
||||
return local;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@@ -255,10 +261,20 @@ class ShiftsRepositoryImpl implements ShiftsRepositoryInterface {
|
||||
|
||||
final List<Shift> mappedShifts = [];
|
||||
for (final sr in allShiftRoles) {
|
||||
print(
|
||||
'FindShifts raw: shiftId=${sr.shiftId} roleId=${sr.roleId} '
|
||||
'start=${sr.startTime?.toJson()} end=${sr.endTime?.toJson()} '
|
||||
'shiftDate=${sr.shift.date?.toJson()}',
|
||||
);
|
||||
final DateTime? shiftDate = _toDateTime(sr.shift.date);
|
||||
final startDt = _toDateTime(sr.startTime);
|
||||
final endDt = _toDateTime(sr.endTime);
|
||||
final createdDt = _toDateTime(sr.createdAt);
|
||||
print(
|
||||
'FindShifts local: shiftId=${sr.shiftId} roleId=${sr.roleId} '
|
||||
'start=${startDt?.toIso8601String()} end=${endDt?.toIso8601String()} '
|
||||
'shiftDate=${shiftDate?.toIso8601String()}',
|
||||
);
|
||||
mappedShifts.add(
|
||||
Shift(
|
||||
id: sr.shiftId,
|
||||
@@ -588,7 +604,7 @@ class ShiftsRepositoryImpl implements ShiftsRepositoryInterface {
|
||||
}
|
||||
|
||||
await _dataConnect
|
||||
.updateApplicationStatus(id: appId, roleId: roleId)
|
||||
.updateApplicationStatus(id: appId)
|
||||
.status(newStatus)
|
||||
.execute();
|
||||
}
|
||||
|
||||
@@ -30,6 +30,7 @@ class ShiftsBloc extends Bloc<ShiftsEvent, ShiftsState> {
|
||||
}) : super(ShiftsInitial()) {
|
||||
on<LoadShiftsEvent>(_onLoadShifts);
|
||||
on<LoadHistoryShiftsEvent>(_onLoadHistoryShifts);
|
||||
on<LoadAvailableShiftsEvent>(_onLoadAvailableShifts);
|
||||
on<LoadShiftsForRangeEvent>(_onLoadShiftsForRange);
|
||||
on<FilterAvailableShiftsEvent>(_onFilterAvailableShifts);
|
||||
}
|
||||
@@ -53,15 +54,14 @@ class ShiftsBloc extends Bloc<ShiftsEvent, ShiftsState> {
|
||||
final pendingResult = await getPendingAssignments();
|
||||
final cancelledResult = await getCancelledShifts();
|
||||
|
||||
// Initial available with defaults
|
||||
final availableResult = await getAvailableShifts(const GetAvailableShiftsArguments());
|
||||
|
||||
emit(ShiftsLoaded(
|
||||
myShifts: myShiftsResult,
|
||||
pendingShifts: pendingResult,
|
||||
cancelledShifts: cancelledResult,
|
||||
availableShifts: _filterPastShifts(availableResult),
|
||||
availableShifts: const [],
|
||||
historyShifts: const [],
|
||||
availableLoading: false,
|
||||
availableLoaded: false,
|
||||
historyLoading: false,
|
||||
historyLoaded: false,
|
||||
searchQuery: '',
|
||||
@@ -93,6 +93,28 @@ class ShiftsBloc extends Bloc<ShiftsEvent, ShiftsState> {
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _onLoadAvailableShifts(
|
||||
LoadAvailableShiftsEvent event,
|
||||
Emitter<ShiftsState> emit,
|
||||
) async {
|
||||
final currentState = state;
|
||||
if (currentState is! ShiftsLoaded) return;
|
||||
if (currentState.availableLoading || currentState.availableLoaded) return;
|
||||
|
||||
emit(currentState.copyWith(availableLoading: true));
|
||||
try {
|
||||
final availableResult =
|
||||
await getAvailableShifts(const GetAvailableShiftsArguments());
|
||||
emit(currentState.copyWith(
|
||||
availableShifts: _filterPastShifts(availableResult),
|
||||
availableLoading: false,
|
||||
availableLoaded: true,
|
||||
));
|
||||
} catch (_) {
|
||||
emit(currentState.copyWith(availableLoading: false));
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _onLoadShiftsForRange(
|
||||
LoadShiftsForRangeEvent event,
|
||||
Emitter<ShiftsState> emit,
|
||||
@@ -110,15 +132,15 @@ class ShiftsBloc extends Bloc<ShiftsEvent, ShiftsState> {
|
||||
|
||||
final pendingResult = await getPendingAssignments();
|
||||
final cancelledResult = await getCancelledShifts();
|
||||
final availableResult =
|
||||
await getAvailableShifts(const GetAvailableShiftsArguments());
|
||||
|
||||
emit(ShiftsLoaded(
|
||||
myShifts: myShiftsResult,
|
||||
pendingShifts: pendingResult,
|
||||
cancelledShifts: cancelledResult,
|
||||
availableShifts: _filterPastShifts(availableResult),
|
||||
availableShifts: const [],
|
||||
historyShifts: const [],
|
||||
availableLoading: false,
|
||||
availableLoaded: false,
|
||||
historyLoading: false,
|
||||
historyLoaded: false,
|
||||
searchQuery: '',
|
||||
@@ -135,6 +157,10 @@ class ShiftsBloc extends Bloc<ShiftsEvent, ShiftsState> {
|
||||
) async {
|
||||
final currentState = state;
|
||||
if (currentState is ShiftsLoaded) {
|
||||
if (!currentState.availableLoaded && !currentState.availableLoading) {
|
||||
add(LoadAvailableShiftsEvent());
|
||||
return;
|
||||
}
|
||||
// Optimistic update or loading indicator?
|
||||
// Since it's filtering, we can just reload available.
|
||||
|
||||
|
||||
@@ -12,6 +12,8 @@ class LoadShiftsEvent extends ShiftsEvent {}
|
||||
|
||||
class LoadHistoryShiftsEvent extends ShiftsEvent {}
|
||||
|
||||
class LoadAvailableShiftsEvent extends ShiftsEvent {}
|
||||
|
||||
class LoadShiftsForRangeEvent extends ShiftsEvent {
|
||||
final DateTime start;
|
||||
final DateTime end;
|
||||
|
||||
@@ -18,6 +18,8 @@ class ShiftsLoaded extends ShiftsState {
|
||||
final List<Shift> cancelledShifts;
|
||||
final List<Shift> availableShifts;
|
||||
final List<Shift> historyShifts;
|
||||
final bool availableLoading;
|
||||
final bool availableLoaded;
|
||||
final bool historyLoading;
|
||||
final bool historyLoaded;
|
||||
final String searchQuery;
|
||||
@@ -29,6 +31,8 @@ class ShiftsLoaded extends ShiftsState {
|
||||
required this.cancelledShifts,
|
||||
required this.availableShifts,
|
||||
required this.historyShifts,
|
||||
required this.availableLoading,
|
||||
required this.availableLoaded,
|
||||
required this.historyLoading,
|
||||
required this.historyLoaded,
|
||||
required this.searchQuery,
|
||||
@@ -41,6 +45,8 @@ class ShiftsLoaded extends ShiftsState {
|
||||
List<Shift>? cancelledShifts,
|
||||
List<Shift>? availableShifts,
|
||||
List<Shift>? historyShifts,
|
||||
bool? availableLoading,
|
||||
bool? availableLoaded,
|
||||
bool? historyLoading,
|
||||
bool? historyLoaded,
|
||||
String? searchQuery,
|
||||
@@ -52,6 +58,8 @@ class ShiftsLoaded extends ShiftsState {
|
||||
cancelledShifts: cancelledShifts ?? this.cancelledShifts,
|
||||
availableShifts: availableShifts ?? this.availableShifts,
|
||||
historyShifts: historyShifts ?? this.historyShifts,
|
||||
availableLoading: availableLoading ?? this.availableLoading,
|
||||
availableLoaded: availableLoaded ?? this.availableLoaded,
|
||||
historyLoading: historyLoading ?? this.historyLoading,
|
||||
historyLoaded: historyLoaded ?? this.historyLoaded,
|
||||
searchQuery: searchQuery ?? this.searchQuery,
|
||||
@@ -66,6 +74,8 @@ class ShiftsLoaded extends ShiftsState {
|
||||
cancelledShifts,
|
||||
availableShifts,
|
||||
historyShifts,
|
||||
availableLoading,
|
||||
availableLoaded,
|
||||
historyLoading,
|
||||
historyLoaded,
|
||||
searchQuery,
|
||||
|
||||
@@ -32,6 +32,9 @@ class _ShiftsPageState extends State<ShiftsPage> {
|
||||
if (_activeTab == 'history') {
|
||||
_bloc.add(LoadHistoryShiftsEvent());
|
||||
}
|
||||
if (_activeTab == 'find') {
|
||||
_bloc.add(LoadAvailableShiftsEvent());
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -61,6 +64,12 @@ class _ShiftsPageState extends State<ShiftsPage> {
|
||||
final List<Shift> availableJobs = (state is ShiftsLoaded)
|
||||
? state.availableShifts
|
||||
: [];
|
||||
final bool availableLoading = (state is ShiftsLoaded)
|
||||
? state.availableLoading
|
||||
: false;
|
||||
final bool availableLoaded = (state is ShiftsLoaded)
|
||||
? state.availableLoaded
|
||||
: false;
|
||||
final List<Shift> pendingAssignments = (state is ShiftsLoaded)
|
||||
? state.pendingShifts
|
||||
: [];
|
||||
@@ -122,6 +131,7 @@ class _ShiftsPageState extends State<ShiftsPage> {
|
||||
UiIcons.search,
|
||||
availableJobs
|
||||
.length, // Passed unfiltered count as badge? Or logic inside? Pass availableJobs.
|
||||
showCount: availableLoaded,
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
_buildTab(
|
||||
@@ -147,6 +157,7 @@ class _ShiftsPageState extends State<ShiftsPage> {
|
||||
cancelledShifts,
|
||||
availableJobs,
|
||||
historyShifts,
|
||||
availableLoading,
|
||||
historyLoading,
|
||||
),
|
||||
),
|
||||
@@ -164,6 +175,7 @@ class _ShiftsPageState extends State<ShiftsPage> {
|
||||
List<Shift> cancelledShifts,
|
||||
List<Shift> availableJobs,
|
||||
List<Shift> historyShifts,
|
||||
bool availableLoading,
|
||||
bool historyLoading,
|
||||
) {
|
||||
switch (_activeTab) {
|
||||
@@ -175,6 +187,9 @@ class _ShiftsPageState extends State<ShiftsPage> {
|
||||
initialDate: _selectedDate,
|
||||
);
|
||||
case 'find':
|
||||
if (availableLoading) {
|
||||
return const Center(child: CircularProgressIndicator());
|
||||
}
|
||||
return FindShiftsTab(availableJobs: availableJobs);
|
||||
case 'history':
|
||||
if (historyLoading) {
|
||||
@@ -201,6 +216,9 @@ class _ShiftsPageState extends State<ShiftsPage> {
|
||||
if (id == 'history') {
|
||||
_bloc.add(LoadHistoryShiftsEvent());
|
||||
}
|
||||
if (id == 'find') {
|
||||
_bloc.add(LoadAvailableShiftsEvent());
|
||||
}
|
||||
},
|
||||
child: Container(
|
||||
padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 8),
|
||||
|
||||
@@ -170,8 +170,21 @@ class _FindShiftsTabState extends State<FindShiftsTab> {
|
||||
...filteredJobs.map(
|
||||
(shift) => Padding(
|
||||
padding: const EdgeInsets.only(bottom: 12),
|
||||
child: MyShiftCard(
|
||||
shift: shift,
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
'Debug shiftId: ${shift.id}',
|
||||
style: const TextStyle(
|
||||
fontSize: 10,
|
||||
color: Color(0xFF94A3B8),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 4),
|
||||
MyShiftCard(
|
||||
shift: shift,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
@@ -27,7 +27,7 @@ mutation updateApplicationStatus(
|
||||
$status: ApplicationStatus
|
||||
$checkInTime: Timestamp
|
||||
$checkOutTime: Timestamp
|
||||
$roleId: UUID!
|
||||
$roleId: UUID
|
||||
) @auth(level: USER) {
|
||||
application_update(
|
||||
id: $id
|
||||
|
||||
Reference in New Issue
Block a user