feat: legacy mobile apps created
This commit is contained in:
@@ -0,0 +1,17 @@
|
||||
import 'package:json_annotation/json_annotation.dart';
|
||||
import 'package:krow/core/data/models/skill.dart';
|
||||
|
||||
part 'business_skill.g.dart';
|
||||
|
||||
@JsonSerializable(fieldRename: FieldRename.snake)
|
||||
class BusinessSkill {
|
||||
Skill? skill;
|
||||
|
||||
BusinessSkill({this.skill});
|
||||
|
||||
factory BusinessSkill.fromJson(Map<String, dynamic> json) {
|
||||
return _$BusinessSkillFromJson(json);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() => _$BusinessSkillToJson(this);
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
import 'package:json_annotation/json_annotation.dart';
|
||||
|
||||
part 'cancellation_reason.g.dart';
|
||||
|
||||
@JsonEnum(fieldRename: FieldRename.snake)
|
||||
enum CancellationReason {
|
||||
sickLeave,
|
||||
vacation,
|
||||
other,
|
||||
health,
|
||||
transportation,
|
||||
personal,
|
||||
scheduleConflict,
|
||||
}
|
||||
|
||||
@JsonSerializable(fieldRename: FieldRename.snake)
|
||||
class CancellationReasonModel {
|
||||
final String type;
|
||||
final CancellationReason? reason;
|
||||
final String? details;
|
||||
|
||||
CancellationReasonModel({
|
||||
required this.type,
|
||||
required this.reason,
|
||||
required this.details,
|
||||
});
|
||||
|
||||
factory CancellationReasonModel.fromJson(Map<String, dynamic> json) {
|
||||
return _$CancellationReasonModelFromJson(json);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() => _$CancellationReasonModelToJson(this);
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
import 'package:json_annotation/json_annotation.dart';
|
||||
import 'package:krow/features/shifts/data/models/event_tag.dart';
|
||||
|
||||
part 'event.g.dart';
|
||||
|
||||
@JsonSerializable(fieldRename: FieldRename.snake)
|
||||
class Event {
|
||||
String? id;
|
||||
Business? business;
|
||||
String? name;
|
||||
String? date;
|
||||
String? additionalInfo;
|
||||
List<Addon>? addons;
|
||||
List<EventTag>? tags;
|
||||
|
||||
|
||||
Event({
|
||||
this.business,
|
||||
this.name,
|
||||
this.date,
|
||||
this.additionalInfo,
|
||||
this.addons,
|
||||
this.tags,
|
||||
});
|
||||
|
||||
factory Event.fromJson(Map<String, dynamic> json) {
|
||||
return _$EventFromJson(json);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() => _$EventToJson(this);
|
||||
}
|
||||
|
||||
@JsonSerializable(fieldRename: FieldRename.snake)
|
||||
class Business {
|
||||
String? name;
|
||||
String? avatar;
|
||||
|
||||
Business({this.name, this.avatar});
|
||||
|
||||
factory Business.fromJson(Map<String, dynamic> json) {
|
||||
return _$BusinessFromJson(json);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() => _$BusinessToJson(this);
|
||||
}
|
||||
|
||||
@JsonSerializable(fieldRename: FieldRename.snake)
|
||||
class Addon {
|
||||
String? name;
|
||||
|
||||
Addon({this.name});
|
||||
|
||||
factory Addon.fromJson(Map<String, dynamic> json) {
|
||||
return Addon(
|
||||
name: json['name'],
|
||||
);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
return {
|
||||
'name': name,
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
import 'package:json_annotation/json_annotation.dart';
|
||||
import 'package:krow/core/data/models/staff/full_address_model.dart';
|
||||
import 'package:krow/features/shifts/data/models/event.dart';
|
||||
import 'package:krow/features/shifts/data/models/shift_contact.dart';
|
||||
|
||||
part 'event_shift.g.dart';
|
||||
|
||||
@JsonSerializable(fieldRename: FieldRename.snake)
|
||||
class Shift {
|
||||
String? id;
|
||||
String? name;
|
||||
String? address;
|
||||
FullAddress? fullAddress;
|
||||
List<Contact>? contacts;
|
||||
Event? event;
|
||||
|
||||
Shift({
|
||||
this.id,
|
||||
this.name,
|
||||
this.address,
|
||||
this.event,
|
||||
this.contacts,
|
||||
this.fullAddress,
|
||||
});
|
||||
|
||||
factory Shift.fromJson(Map<String, dynamic> json) {
|
||||
return _$ShiftFromJson(json);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() => _$ShiftToJson(this);
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
import 'package:json_annotation/json_annotation.dart';
|
||||
|
||||
part 'event_tag.g.dart';
|
||||
|
||||
@JsonSerializable()
|
||||
class EventTag{
|
||||
final String id;
|
||||
final String name;
|
||||
final String? slug;
|
||||
|
||||
EventTag({required this.name, required this.id, required this.slug});
|
||||
|
||||
factory EventTag.fromJson(Map<String, dynamic> json) {
|
||||
return _$EventTagFromJson(json);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() => _$EventTagToJson(this);
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
import 'package:json_annotation/json_annotation.dart';
|
||||
import 'package:krow/features/shifts/data/models/business_skill.dart';
|
||||
import 'package:krow/features/shifts/data/models/event_shift.dart';
|
||||
|
||||
part 'position.g.dart';
|
||||
|
||||
@JsonSerializable(fieldRename: FieldRename.snake)
|
||||
class Position {
|
||||
String? id;
|
||||
String? startTime;
|
||||
String? endTime;
|
||||
Shift? shift;
|
||||
BusinessSkill? businessSkill;
|
||||
double? rate;
|
||||
@JsonKey(name: 'break')
|
||||
int? breakMinutes;
|
||||
|
||||
Position({
|
||||
this.id,
|
||||
this.startTime,
|
||||
this.endTime,
|
||||
this.shift,
|
||||
this.businessSkill,
|
||||
});
|
||||
|
||||
factory Position.fromJson(Map<String, dynamic> json) =>
|
||||
_$PositionFromJson(json);
|
||||
|
||||
Map<String, dynamic> toJson() => _$PositionToJson(this);
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
|
||||
part 'shift_contact.g.dart';
|
||||
|
||||
@JsonSerializable(fieldRename: FieldRename.snake)
|
||||
class Contact {
|
||||
final String id;
|
||||
final String firstName;
|
||||
final String? avatar;
|
||||
final String lastName;
|
||||
final String title;
|
||||
final AuthInfo authInfo;
|
||||
|
||||
Contact({
|
||||
required this.id,
|
||||
required this.firstName,
|
||||
required this.lastName,
|
||||
required this.title,
|
||||
required this.avatar,
|
||||
required this.authInfo,
|
||||
});
|
||||
|
||||
factory Contact.fromJson(Map<String, dynamic> json) {
|
||||
return _$ContactFromJson(json);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() => _$ContactToJson(this);
|
||||
}
|
||||
|
||||
@JsonSerializable(fieldRename: FieldRename.snake)
|
||||
class AuthInfo {
|
||||
final String email;
|
||||
final String phone;
|
||||
|
||||
AuthInfo({
|
||||
required this.email,
|
||||
required this.phone,
|
||||
});
|
||||
|
||||
factory AuthInfo.fromJson(Map<String, dynamic> json) {
|
||||
return _$AuthInfoFromJson(json);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() => _$AuthInfoToJson(this);
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
import 'package:json_annotation/json_annotation.dart';
|
||||
import 'package:krow/features/shifts/data/models/cancellation_reason.dart';
|
||||
import 'package:krow/features/shifts/data/models/position.dart';
|
||||
|
||||
part 'staff_shift.g.dart';
|
||||
|
||||
@JsonEnum(fieldRename: FieldRename.snake)
|
||||
enum EventShiftRoleStaffStatus {
|
||||
assigned,
|
||||
confirmed,
|
||||
ongoing,
|
||||
completed,
|
||||
canceledByStaff,
|
||||
canceledByBusiness,
|
||||
canceledByAdmin,
|
||||
requestedReplace,
|
||||
declineByStaff,
|
||||
}
|
||||
|
||||
@JsonSerializable(fieldRename: FieldRename.snake)
|
||||
class StaffShift {
|
||||
String id;
|
||||
DateTime? statusUpdatedAt;
|
||||
EventShiftRoleStaffStatus status;
|
||||
Position? position;
|
||||
DateTime? startAt;
|
||||
DateTime? endAt;
|
||||
DateTime? clockIn;
|
||||
DateTime? clockOut;
|
||||
DateTime? breakIn;
|
||||
DateTime? breakOut;
|
||||
List<CancellationReasonModel>? cancelReason;
|
||||
StaffRating? rating;
|
||||
|
||||
|
||||
// Staff? staff;
|
||||
|
||||
StaffShift({
|
||||
required this.id,
|
||||
required this.status,
|
||||
this.statusUpdatedAt,
|
||||
this.position,
|
||||
this.startAt,
|
||||
this.endAt,
|
||||
this.clockIn,
|
||||
this.clockOut,
|
||||
this.breakIn,
|
||||
this.breakOut,
|
||||
this.rating,
|
||||
// this.staff
|
||||
});
|
||||
|
||||
factory StaffShift.fromJson(Map<String, dynamic> json) {
|
||||
return _$StaffShiftFromJson(json);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() => _$StaffShiftToJson(this);
|
||||
}
|
||||
|
||||
@JsonSerializable(fieldRename: FieldRename.snake)
|
||||
class StaffRating{
|
||||
final String id;
|
||||
final double rating;
|
||||
|
||||
factory StaffRating.fromJson(Map<String, dynamic> json) {
|
||||
return _$StaffRatingFromJson(json);
|
||||
}
|
||||
|
||||
StaffRating({required this.id, required this.rating});
|
||||
|
||||
Map<String, dynamic> toJson() => _$StaffRatingToJson(this);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,124 @@
|
||||
import 'package:graphql_flutter/graphql_flutter.dart';
|
||||
import 'package:injectable/injectable.dart';
|
||||
import 'package:krow/core/application/clients/api/api_client.dart';
|
||||
import 'package:krow/core/application/clients/api/api_exception.dart';
|
||||
import 'package:krow/core/data/models/pagination_wrapper/pagination_wrapper.dart';
|
||||
import 'package:krow/features/shifts/data/models/staff_shift.dart';
|
||||
import 'package:krow/features/shifts/data/shifts_gql.dart';
|
||||
|
||||
@Injectable()
|
||||
class ShiftsApiProvider {
|
||||
final ApiClient _client;
|
||||
|
||||
ShiftsApiProvider({required ApiClient client}) : _client = client;
|
||||
|
||||
Future<PaginationWrapper> fetchShifts(String status, {String? after}) async {
|
||||
final QueryResult result = await _client.query(
|
||||
schema: getShiftsQuery,
|
||||
body: {'status': status, 'first': 100, 'after': after},
|
||||
);
|
||||
|
||||
if (result.hasException) {
|
||||
throw Exception(result.exception.toString());
|
||||
}
|
||||
|
||||
return PaginationWrapper.fromJson(
|
||||
result.data!['staff_shifts'],
|
||||
(json) => StaffShift.fromJson(json),
|
||||
);
|
||||
}
|
||||
|
||||
Future<PaginationWrapper> getMissBreakFinishedShift() async {
|
||||
final QueryResult result = await _client.query(
|
||||
schema: staffNoBreakShifts,
|
||||
body: {'first': 100},
|
||||
);
|
||||
|
||||
if (result.hasException) {
|
||||
throw Exception(result.exception.toString());
|
||||
}
|
||||
return PaginationWrapper.fromJson(
|
||||
result.data!['staff_no_break_shifts'],
|
||||
(json) => StaffShift.fromJson(json),
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> confirmShift(String id) async {
|
||||
final QueryResult result =
|
||||
await _client.mutate(schema: acceptShiftMutation, body: {'id': id});
|
||||
if (result.hasException) {
|
||||
throw parseBackendError(result.exception);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> clockInShift(String id) async {
|
||||
final QueryResult result =
|
||||
await _client.mutate(schema: trackStaffClockin, body: {'id': id});
|
||||
if (result.hasException) {
|
||||
throw parseBackendError(result.exception);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> completeShift(String id,
|
||||
{String? breakIn, String? breakOut, bool isPast = false}) async {
|
||||
final QueryResult result = await _client.mutate(
|
||||
schema: isPast ? trackStaffBreak : completeShiftMutation,
|
||||
body: {'id': id, 'break_in': breakIn, 'break_out': breakOut});
|
||||
if (result.hasException) {
|
||||
throw parseBackendError(result.exception);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> completeShiftNoBreak(String id,
|
||||
{String? reason, String? additionalReason}) async {
|
||||
final QueryResult result = await _client.mutate(
|
||||
schema: submitNoBreakStaffShiftMutation,
|
||||
body: {'id': id, 'reason': reason, 'details': additionalReason});
|
||||
if (result.hasException) {
|
||||
throw parseBackendError(result.exception);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> declineShift(String id,
|
||||
{String? reason, String? additionalReason}) async {
|
||||
final QueryResult result = await _client.mutate(
|
||||
schema: declineStaffShiftMutation,
|
||||
body: {
|
||||
'position_id': id,
|
||||
'reason': reason,
|
||||
'details': additionalReason
|
||||
});
|
||||
if (result.hasException) {
|
||||
throw parseBackendError(result.exception);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> cancelShift(String id,
|
||||
{String? reason, String? additionalReason}) async {
|
||||
final QueryResult result = await _client.mutate(
|
||||
schema: cancelStaffShiftMutation,
|
||||
body: {
|
||||
'position_id': id,
|
||||
'reason': reason,
|
||||
'details': additionalReason
|
||||
});
|
||||
if (result.hasException) {
|
||||
throw parseBackendError(result.exception);
|
||||
}
|
||||
}
|
||||
|
||||
Future<StaffShift> getShiftById(String id) async {
|
||||
final QueryResult result = await _client.query(
|
||||
schema: getShiftPositionQuery,
|
||||
body: {'id': id},
|
||||
);
|
||||
|
||||
if (result.hasException) {
|
||||
throw parseBackendError(result.exception);
|
||||
}
|
||||
if (result.data == null || result.data!['staff_shift'] == null) {
|
||||
throw Exception('No data found');
|
||||
}
|
||||
return StaffShift.fromJson(result.data!['staff_shift']);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,207 @@
|
||||
import 'package:krow/core/application/clients/api/gql.dart';
|
||||
|
||||
const String _shiftFields = '''
|
||||
id
|
||||
status
|
||||
status_updated_at
|
||||
start_at
|
||||
end_at
|
||||
clock_in
|
||||
clock_out
|
||||
break_in
|
||||
break_out
|
||||
...position
|
||||
cancel_reason {
|
||||
type
|
||||
reason
|
||||
details
|
||||
}
|
||||
rating {
|
||||
id
|
||||
rating
|
||||
}
|
||||
''';
|
||||
|
||||
const String getShiftsQuery = '''
|
||||
$_positionFragment
|
||||
|
||||
query GetShifts (\$status: EventShiftPositionStaffStatusInput!, \$first: Int!, \$after: String) {
|
||||
staff_shifts(status: \$status, first: \$first, after: \$after) {
|
||||
pageInfo {
|
||||
hasNextPage
|
||||
}
|
||||
edges {
|
||||
node {
|
||||
$_shiftFields
|
||||
}
|
||||
cursor
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
''';
|
||||
|
||||
const String staffNoBreakShifts = '''
|
||||
$_positionFragment
|
||||
|
||||
query staffNoBreakShifts (\$first: Int!) {
|
||||
staff_no_break_shifts(first: \$first) {
|
||||
pageInfo{
|
||||
}
|
||||
edges {
|
||||
|
||||
node {
|
||||
$_shiftFields
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
''';
|
||||
|
||||
const String getShiftPositionQuery = '''
|
||||
$_positionFragment
|
||||
query GetShiftPosition (\$id: ID!) {
|
||||
staff_shift(id: \$id) {
|
||||
$_shiftFields
|
||||
}
|
||||
}
|
||||
''';
|
||||
|
||||
const String acceptShiftMutation = '''
|
||||
$_positionFragment
|
||||
|
||||
mutation AcceptShift(\$id: ID!) {
|
||||
accept_shift(position_id: \$id) {
|
||||
$_shiftFields
|
||||
}
|
||||
}
|
||||
''';
|
||||
|
||||
const String trackStaffClockin = '''
|
||||
mutation TrackStaffClockin(\$id: ID!) {
|
||||
track_staff_clockin(position_staff_id: \$id) {
|
||||
|
||||
}
|
||||
}
|
||||
''';
|
||||
|
||||
const String completeShiftMutation = '''
|
||||
mutation CompleteShift(\$id: ID!, \$break_in: DateTime, \$break_out: DateTime) {
|
||||
track_staff_clockout(position_staff_id: \$id, break_in: \$break_in, break_out: \$break_out) {
|
||||
}
|
||||
}
|
||||
''';
|
||||
|
||||
const String trackStaffBreak = '''
|
||||
mutation trackStaffBreak(\$id: ID!, \$break_in: DateTime!, \$break_out: DateTime!) {
|
||||
track_staff_break(position_staff_id: \$id, break_in: \$break_in, break_out: \$break_out) {
|
||||
}
|
||||
}
|
||||
''';
|
||||
|
||||
const String submitNoBreakStaffShiftMutation = '''
|
||||
mutation SubmitNoBreakStaffShift(\$id: ID!, \$reason: NoBreakShiftPenaltyLogReason, \$details: String) {
|
||||
submit_no_break_staff_shift(position_staff_id: \$id, reason: \$reason, details: \$details) {
|
||||
}
|
||||
}
|
||||
''';
|
||||
|
||||
const String cancelStaffShiftMutation = '''
|
||||
|
||||
mutation cancelStaffShiftMutation(\$position_id: ID!, \$reason: CancelShiftPenaltyLogReason, \$details: String) {
|
||||
cancel_staff_shift(position_staff_id: \$position_id, reason: \$reason, details: \$details) {
|
||||
}
|
||||
}
|
||||
''';
|
||||
|
||||
const String declineStaffShiftMutation = '''
|
||||
mutation DeclineStaffShift(\$position_id: ID!,\$reason: DeclineShiftPenaltyLogReason, \$details: String) {
|
||||
decline_shift(position_id: \$position_id, reason: \$reason, details: \$details) {
|
||||
}
|
||||
}
|
||||
''';
|
||||
|
||||
const _positionFragment = '''
|
||||
$skillFragment
|
||||
|
||||
fragment position on EventShiftPositionStaff {
|
||||
position {
|
||||
id
|
||||
start_time
|
||||
end_time
|
||||
rate
|
||||
break
|
||||
...shift
|
||||
...business_skill
|
||||
}
|
||||
}
|
||||
|
||||
fragment shift on EventShiftPosition {
|
||||
shift {
|
||||
id
|
||||
name
|
||||
address
|
||||
...FullAddress
|
||||
...contacts
|
||||
event {
|
||||
id
|
||||
date
|
||||
name
|
||||
...business
|
||||
additional_info
|
||||
tags{
|
||||
id
|
||||
name
|
||||
slug
|
||||
}
|
||||
addons{
|
||||
name
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fragment business_skill on EventShiftPosition {
|
||||
business_skill {
|
||||
skill {
|
||||
...SkillFragment
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fragment business on Event {
|
||||
business {
|
||||
name
|
||||
avatar
|
||||
}
|
||||
}
|
||||
|
||||
fragment contacts on EventShift {
|
||||
contacts {
|
||||
id
|
||||
first_name
|
||||
last_name
|
||||
avatar
|
||||
title
|
||||
auth_info {
|
||||
email
|
||||
phone
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fragment FullAddress on EventShift {
|
||||
full_address {
|
||||
street_number
|
||||
zip_code
|
||||
latitude
|
||||
longitude
|
||||
formatted_address
|
||||
street
|
||||
region
|
||||
city
|
||||
country
|
||||
}
|
||||
}
|
||||
''';
|
||||
@@ -0,0 +1,155 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:injectable/injectable.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:krow/features/shifts/data/models/staff_shift.dart';
|
||||
import 'package:krow/features/shifts/data/shifts_api_provider.dart';
|
||||
import 'package:krow/features/shifts/domain/shift_entity.dart';
|
||||
import 'package:krow/features/shifts/domain/shifts_repository.dart';
|
||||
import 'package:krow/features/shifts/presentation/dialogs/complete_dialog/shift_complete_dialog.dart';
|
||||
|
||||
@Singleton(as: ShiftsRepository)
|
||||
class ShiftsRepositoryImpl extends ShiftsRepository {
|
||||
final ShiftsApiProvider _apiProvider;
|
||||
StreamController<EventShiftRoleStaffStatus>? _statusController;
|
||||
|
||||
ShiftsRepositoryImpl({required ShiftsApiProvider apiProvider})
|
||||
: _apiProvider = apiProvider;
|
||||
|
||||
@override
|
||||
Stream<EventShiftRoleStaffStatus> get statusStream {
|
||||
_statusController ??=
|
||||
StreamController<EventShiftRoleStaffStatus>.broadcast();
|
||||
return _statusController!.stream;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<List<ShiftEntity>> getShifts(
|
||||
{String? lastItemId, required ShiftStatusFilterType statusFilter}) async {
|
||||
var paginationWrapper = await _apiProvider
|
||||
.fetchShifts(statusFilterToGqlString(statusFilter), after: lastItemId);
|
||||
return paginationWrapper.edges.map((e) {
|
||||
return ShiftEntity.fromStaffShift(
|
||||
e.node,
|
||||
cursor: (paginationWrapper.pageInfo?.hasNextPage??false) ? e.cursor : null,
|
||||
);
|
||||
}).toList();
|
||||
}
|
||||
|
||||
statusFilterToGqlString(ShiftStatusFilterType statusFilter) {
|
||||
return statusFilter.name;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> confirmShift(ShiftEntity shiftViewModel) async {
|
||||
var result = await _apiProvider.confirmShift(shiftViewModel.id);
|
||||
_statusController?.add(EventShiftRoleStaffStatus.assigned);
|
||||
_statusController?.add(EventShiftRoleStaffStatus.confirmed);
|
||||
return result;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> clockInShift(ShiftEntity shiftViewModel) async {
|
||||
// try {
|
||||
await _apiProvider.clockInShift(shiftViewModel.id);
|
||||
_statusController?.add(EventShiftRoleStaffStatus.assigned);
|
||||
_statusController?.add(EventShiftRoleStaffStatus.ongoing);
|
||||
// } catch (e) {
|
||||
// _statusController?.add(EventShiftRoleStaffStatus.assigned);
|
||||
// _statusController?.add(EventShiftRoleStaffStatus.ongoing);
|
||||
// rethrow;
|
||||
// }
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> completeShift(
|
||||
ShiftEntity shiftViewModel, ClockOutDetails clockOutDetails, bool isPast) async {
|
||||
if (clockOutDetails.reason != null) {
|
||||
_apiProvider.completeShiftNoBreak(
|
||||
shiftViewModel.id,
|
||||
reason: clockOutDetails.reason,
|
||||
additionalReason: clockOutDetails.additionalReason,
|
||||
);
|
||||
} else {
|
||||
var breakInTime =
|
||||
DateFormat('H:mm').parse(clockOutDetails.breakStartTime!);
|
||||
var start = DateTime(
|
||||
shiftViewModel.startDate.year,
|
||||
shiftViewModel.startDate.month,
|
||||
shiftViewModel.startDate.day,
|
||||
breakInTime.hour,
|
||||
breakInTime.minute);
|
||||
var breakOutTime =
|
||||
DateFormat('H:mm').parse(clockOutDetails.breakEndTime!);
|
||||
var end = DateTime(
|
||||
shiftViewModel.startDate.year,
|
||||
shiftViewModel.startDate.month,
|
||||
shiftViewModel.startDate.day,
|
||||
breakOutTime.hour,
|
||||
breakOutTime.minute);
|
||||
_apiProvider.completeShift(
|
||||
shiftViewModel.id,
|
||||
isPast: isPast,
|
||||
breakIn: DateFormat('yyyy-MM-dd HH:mm:ss').format(start),
|
||||
breakOut: DateFormat('yyyy-MM-dd HH:mm:ss').format(end),
|
||||
);
|
||||
}
|
||||
_statusController?.add(EventShiftRoleStaffStatus.ongoing);
|
||||
_statusController?.add(EventShiftRoleStaffStatus.completed);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> forceClockOut(String id) async {
|
||||
await _apiProvider.completeShift(id);
|
||||
_statusController?.add(EventShiftRoleStaffStatus.assigned);
|
||||
_statusController?.add(EventShiftRoleStaffStatus.confirmed);
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_statusController?.close();
|
||||
_statusController = null;
|
||||
}
|
||||
|
||||
@override
|
||||
declineShift(
|
||||
ShiftEntity shiftViewModel, String? reason, String? additionalReason) {
|
||||
_apiProvider.declineShift(
|
||||
shiftViewModel.id,
|
||||
reason: reason,
|
||||
additionalReason: additionalReason,
|
||||
);
|
||||
_statusController?.add(EventShiftRoleStaffStatus.assigned);
|
||||
_statusController?.add(EventShiftRoleStaffStatus.canceledByStaff);
|
||||
}
|
||||
|
||||
@override
|
||||
cancelShift(
|
||||
ShiftEntity shiftViewModel, String? reason, String? additionalReason) {
|
||||
_apiProvider.cancelShift(
|
||||
shiftViewModel.id,
|
||||
reason: reason,
|
||||
additionalReason: additionalReason,
|
||||
);
|
||||
_statusController?.add(EventShiftRoleStaffStatus.assigned);
|
||||
_statusController?.add(EventShiftRoleStaffStatus.canceledByStaff);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<ShiftEntity?> getShiftById(String id) async {
|
||||
return ShiftEntity.fromStaffShift(
|
||||
cursor: '', await _apiProvider.getShiftById(id));
|
||||
}
|
||||
|
||||
@override
|
||||
Future<List<ShiftEntity>> getMissBreakFinishedShift() async{
|
||||
var paginationWrapper = await _apiProvider
|
||||
.getMissBreakFinishedShift();
|
||||
return paginationWrapper.edges.map((e) {
|
||||
return ShiftEntity.fromStaffShift(
|
||||
e.node,
|
||||
cursor: (paginationWrapper.pageInfo?.hasNextPage??false) ? e.cursor : null,
|
||||
);
|
||||
}).toList();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user