update and correction of create order
This commit is contained in:
@@ -1,16 +1,16 @@
|
||||
# Basic Usage
|
||||
|
||||
```dart
|
||||
ExampleConnector.instance.getStaffDocumentByKey(getStaffDocumentByKeyVariables).execute();
|
||||
ExampleConnector.instance.listStaffDocumentsByStaffId(listStaffDocumentsByStaffIdVariables).execute();
|
||||
ExampleConnector.instance.listStaffDocumentsByDocumentType(listStaffDocumentsByDocumentTypeVariables).execute();
|
||||
ExampleConnector.instance.listStaffDocumentsByStatus(listStaffDocumentsByStatusVariables).execute();
|
||||
ExampleConnector.instance.createTeam(createTeamVariables).execute();
|
||||
ExampleConnector.instance.updateTeam(updateTeamVariables).execute();
|
||||
ExampleConnector.instance.deleteTeam(deleteTeamVariables).execute();
|
||||
ExampleConnector.instance.listInvoiceTemplates(listInvoiceTemplatesVariables).execute();
|
||||
ExampleConnector.instance.getInvoiceTemplateById(getInvoiceTemplateByIdVariables).execute();
|
||||
ExampleConnector.instance.listInvoiceTemplatesByOwnerId(listInvoiceTemplatesByOwnerIdVariables).execute();
|
||||
ExampleConnector.instance.createCustomRateCard(createCustomRateCardVariables).execute();
|
||||
ExampleConnector.instance.updateCustomRateCard(updateCustomRateCardVariables).execute();
|
||||
ExampleConnector.instance.deleteCustomRateCard(deleteCustomRateCardVariables).execute();
|
||||
ExampleConnector.instance.listShiftsForCoverage(listShiftsForCoverageVariables).execute();
|
||||
ExampleConnector.instance.listApplicationsForCoverage(listApplicationsForCoverageVariables).execute();
|
||||
ExampleConnector.instance.listShiftsForDailyOpsByBusiness(listShiftsForDailyOpsByBusinessVariables).execute();
|
||||
ExampleConnector.instance.listShiftsForDailyOpsByVendor(listShiftsForDailyOpsByVendorVariables).execute();
|
||||
ExampleConnector.instance.listApplicationsForDailyOps(listApplicationsForDailyOpsVariables).execute();
|
||||
ExampleConnector.instance.listShiftsForForecastByBusiness(listShiftsForForecastByBusinessVariables).execute();
|
||||
ExampleConnector.instance.listShiftsForForecastByVendor(listShiftsForForecastByVendorVariables).execute();
|
||||
|
||||
```
|
||||
|
||||
@@ -23,8 +23,8 @@ 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.updateMessage({ ... })
|
||||
.conversationId(...)
|
||||
await ExampleConnector.instance.UpdateUser({ ... })
|
||||
.email(...)
|
||||
.execute();
|
||||
```
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,404 @@
|
||||
part of 'generated.dart';
|
||||
|
||||
class ListShiftRolesByBusinessAndOrderVariablesBuilder {
|
||||
String businessId;
|
||||
String orderId;
|
||||
Optional<int> _offset = Optional.optional(nativeFromJson, nativeToJson);
|
||||
Optional<int> _limit = Optional.optional(nativeFromJson, nativeToJson);
|
||||
|
||||
final FirebaseDataConnect _dataConnect; ListShiftRolesByBusinessAndOrderVariablesBuilder offset(int? t) {
|
||||
_offset.value = t;
|
||||
return this;
|
||||
}
|
||||
ListShiftRolesByBusinessAndOrderVariablesBuilder limit(int? t) {
|
||||
_limit.value = t;
|
||||
return this;
|
||||
}
|
||||
|
||||
ListShiftRolesByBusinessAndOrderVariablesBuilder(this._dataConnect, {required this.businessId,required this.orderId,});
|
||||
Deserializer<ListShiftRolesByBusinessAndOrderData> dataDeserializer = (dynamic json) => ListShiftRolesByBusinessAndOrderData.fromJson(jsonDecode(json));
|
||||
Serializer<ListShiftRolesByBusinessAndOrderVariables> varsSerializer = (ListShiftRolesByBusinessAndOrderVariables vars) => jsonEncode(vars.toJson());
|
||||
Future<QueryResult<ListShiftRolesByBusinessAndOrderData, ListShiftRolesByBusinessAndOrderVariables>> execute() {
|
||||
return ref().execute();
|
||||
}
|
||||
|
||||
QueryRef<ListShiftRolesByBusinessAndOrderData, ListShiftRolesByBusinessAndOrderVariables> ref() {
|
||||
ListShiftRolesByBusinessAndOrderVariables vars= ListShiftRolesByBusinessAndOrderVariables(businessId: businessId,orderId: orderId,offset: _offset,limit: _limit,);
|
||||
return _dataConnect.query("listShiftRolesByBusinessAndOrder", dataDeserializer, varsSerializer, vars);
|
||||
}
|
||||
}
|
||||
|
||||
@immutable
|
||||
class ListShiftRolesByBusinessAndOrderShiftRoles {
|
||||
final String id;
|
||||
final String shiftId;
|
||||
final String roleId;
|
||||
final int count;
|
||||
final int? assigned;
|
||||
final Timestamp? startTime;
|
||||
final Timestamp? endTime;
|
||||
final double? hours;
|
||||
final EnumValue<BreakDuration>? breakType;
|
||||
final double? totalValue;
|
||||
final Timestamp? createdAt;
|
||||
final ListShiftRolesByBusinessAndOrderShiftRolesRole role;
|
||||
final ListShiftRolesByBusinessAndOrderShiftRolesShift shift;
|
||||
ListShiftRolesByBusinessAndOrderShiftRoles.fromJson(dynamic json):
|
||||
|
||||
id = nativeFromJson<String>(json['id']),
|
||||
shiftId = nativeFromJson<String>(json['shiftId']),
|
||||
roleId = nativeFromJson<String>(json['roleId']),
|
||||
count = nativeFromJson<int>(json['count']),
|
||||
assigned = json['assigned'] == null ? null : nativeFromJson<int>(json['assigned']),
|
||||
startTime = json['startTime'] == null ? null : Timestamp.fromJson(json['startTime']),
|
||||
endTime = json['endTime'] == null ? null : Timestamp.fromJson(json['endTime']),
|
||||
hours = json['hours'] == null ? null : nativeFromJson<double>(json['hours']),
|
||||
breakType = json['breakType'] == null ? null : breakDurationDeserializer(json['breakType']),
|
||||
totalValue = json['totalValue'] == null ? null : nativeFromJson<double>(json['totalValue']),
|
||||
createdAt = json['createdAt'] == null ? null : Timestamp.fromJson(json['createdAt']),
|
||||
role = ListShiftRolesByBusinessAndOrderShiftRolesRole.fromJson(json['role']),
|
||||
shift = ListShiftRolesByBusinessAndOrderShiftRolesShift.fromJson(json['shift']);
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
if(identical(this, other)) {
|
||||
return true;
|
||||
}
|
||||
if(other.runtimeType != runtimeType) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final ListShiftRolesByBusinessAndOrderShiftRoles otherTyped = other as ListShiftRolesByBusinessAndOrderShiftRoles;
|
||||
return id == otherTyped.id &&
|
||||
shiftId == otherTyped.shiftId &&
|
||||
roleId == otherTyped.roleId &&
|
||||
count == otherTyped.count &&
|
||||
assigned == otherTyped.assigned &&
|
||||
startTime == otherTyped.startTime &&
|
||||
endTime == otherTyped.endTime &&
|
||||
hours == otherTyped.hours &&
|
||||
breakType == otherTyped.breakType &&
|
||||
totalValue == otherTyped.totalValue &&
|
||||
createdAt == otherTyped.createdAt &&
|
||||
role == otherTyped.role &&
|
||||
shift == otherTyped.shift;
|
||||
|
||||
}
|
||||
@override
|
||||
int get hashCode => Object.hashAll([id.hashCode, shiftId.hashCode, roleId.hashCode, count.hashCode, assigned.hashCode, startTime.hashCode, endTime.hashCode, hours.hashCode, breakType.hashCode, totalValue.hashCode, createdAt.hashCode, role.hashCode, shift.hashCode]);
|
||||
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
Map<String, dynamic> json = {};
|
||||
json['id'] = nativeToJson<String>(id);
|
||||
json['shiftId'] = nativeToJson<String>(shiftId);
|
||||
json['roleId'] = nativeToJson<String>(roleId);
|
||||
json['count'] = nativeToJson<int>(count);
|
||||
if (assigned != null) {
|
||||
json['assigned'] = nativeToJson<int?>(assigned);
|
||||
}
|
||||
if (startTime != null) {
|
||||
json['startTime'] = startTime!.toJson();
|
||||
}
|
||||
if (endTime != null) {
|
||||
json['endTime'] = endTime!.toJson();
|
||||
}
|
||||
if (hours != null) {
|
||||
json['hours'] = nativeToJson<double?>(hours);
|
||||
}
|
||||
if (breakType != null) {
|
||||
json['breakType'] =
|
||||
breakDurationSerializer(breakType!)
|
||||
;
|
||||
}
|
||||
if (totalValue != null) {
|
||||
json['totalValue'] = nativeToJson<double?>(totalValue);
|
||||
}
|
||||
if (createdAt != null) {
|
||||
json['createdAt'] = createdAt!.toJson();
|
||||
}
|
||||
json['role'] = role.toJson();
|
||||
json['shift'] = shift.toJson();
|
||||
return json;
|
||||
}
|
||||
|
||||
ListShiftRolesByBusinessAndOrderShiftRoles({
|
||||
required this.id,
|
||||
required this.shiftId,
|
||||
required this.roleId,
|
||||
required this.count,
|
||||
this.assigned,
|
||||
this.startTime,
|
||||
this.endTime,
|
||||
this.hours,
|
||||
this.breakType,
|
||||
this.totalValue,
|
||||
this.createdAt,
|
||||
required this.role,
|
||||
required this.shift,
|
||||
});
|
||||
}
|
||||
|
||||
@immutable
|
||||
class ListShiftRolesByBusinessAndOrderShiftRolesRole {
|
||||
final String id;
|
||||
final String name;
|
||||
final double costPerHour;
|
||||
ListShiftRolesByBusinessAndOrderShiftRolesRole.fromJson(dynamic json):
|
||||
|
||||
id = nativeFromJson<String>(json['id']),
|
||||
name = nativeFromJson<String>(json['name']),
|
||||
costPerHour = nativeFromJson<double>(json['costPerHour']);
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
if(identical(this, other)) {
|
||||
return true;
|
||||
}
|
||||
if(other.runtimeType != runtimeType) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final ListShiftRolesByBusinessAndOrderShiftRolesRole otherTyped = other as ListShiftRolesByBusinessAndOrderShiftRolesRole;
|
||||
return id == otherTyped.id &&
|
||||
name == otherTyped.name &&
|
||||
costPerHour == otherTyped.costPerHour;
|
||||
|
||||
}
|
||||
@override
|
||||
int get hashCode => Object.hashAll([id.hashCode, name.hashCode, costPerHour.hashCode]);
|
||||
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
Map<String, dynamic> json = {};
|
||||
json['id'] = nativeToJson<String>(id);
|
||||
json['name'] = nativeToJson<String>(name);
|
||||
json['costPerHour'] = nativeToJson<double>(costPerHour);
|
||||
return json;
|
||||
}
|
||||
|
||||
ListShiftRolesByBusinessAndOrderShiftRolesRole({
|
||||
required this.id,
|
||||
required this.name,
|
||||
required this.costPerHour,
|
||||
});
|
||||
}
|
||||
|
||||
@immutable
|
||||
class ListShiftRolesByBusinessAndOrderShiftRolesShift {
|
||||
final String id;
|
||||
final String title;
|
||||
final Timestamp? date;
|
||||
final String orderId;
|
||||
final String? location;
|
||||
final String? locationAddress;
|
||||
final ListShiftRolesByBusinessAndOrderShiftRolesShiftOrder order;
|
||||
ListShiftRolesByBusinessAndOrderShiftRolesShift.fromJson(dynamic json):
|
||||
|
||||
id = nativeFromJson<String>(json['id']),
|
||||
title = nativeFromJson<String>(json['title']),
|
||||
date = json['date'] == null ? null : Timestamp.fromJson(json['date']),
|
||||
orderId = nativeFromJson<String>(json['orderId']),
|
||||
location = json['location'] == null ? null : nativeFromJson<String>(json['location']),
|
||||
locationAddress = json['locationAddress'] == null ? null : nativeFromJson<String>(json['locationAddress']),
|
||||
order = ListShiftRolesByBusinessAndOrderShiftRolesShiftOrder.fromJson(json['order']);
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
if(identical(this, other)) {
|
||||
return true;
|
||||
}
|
||||
if(other.runtimeType != runtimeType) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final ListShiftRolesByBusinessAndOrderShiftRolesShift otherTyped = other as ListShiftRolesByBusinessAndOrderShiftRolesShift;
|
||||
return id == otherTyped.id &&
|
||||
title == otherTyped.title &&
|
||||
date == otherTyped.date &&
|
||||
orderId == otherTyped.orderId &&
|
||||
location == otherTyped.location &&
|
||||
locationAddress == otherTyped.locationAddress &&
|
||||
order == otherTyped.order;
|
||||
|
||||
}
|
||||
@override
|
||||
int get hashCode => Object.hashAll([id.hashCode, title.hashCode, date.hashCode, orderId.hashCode, location.hashCode, locationAddress.hashCode, order.hashCode]);
|
||||
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
Map<String, dynamic> json = {};
|
||||
json['id'] = nativeToJson<String>(id);
|
||||
json['title'] = nativeToJson<String>(title);
|
||||
if (date != null) {
|
||||
json['date'] = date!.toJson();
|
||||
}
|
||||
json['orderId'] = nativeToJson<String>(orderId);
|
||||
if (location != null) {
|
||||
json['location'] = nativeToJson<String?>(location);
|
||||
}
|
||||
if (locationAddress != null) {
|
||||
json['locationAddress'] = nativeToJson<String?>(locationAddress);
|
||||
}
|
||||
json['order'] = order.toJson();
|
||||
return json;
|
||||
}
|
||||
|
||||
ListShiftRolesByBusinessAndOrderShiftRolesShift({
|
||||
required this.id,
|
||||
required this.title,
|
||||
this.date,
|
||||
required this.orderId,
|
||||
this.location,
|
||||
this.locationAddress,
|
||||
required this.order,
|
||||
});
|
||||
}
|
||||
|
||||
@immutable
|
||||
class ListShiftRolesByBusinessAndOrderShiftRolesShiftOrder {
|
||||
final String? vendorId;
|
||||
final Timestamp? date;
|
||||
final String? location;
|
||||
ListShiftRolesByBusinessAndOrderShiftRolesShiftOrder.fromJson(dynamic json):
|
||||
|
||||
vendorId = json['vendorId'] == null ? null : nativeFromJson<String>(json['vendorId']),
|
||||
date = json['date'] == null ? null : Timestamp.fromJson(json['date']),
|
||||
location = json['location'] == null ? null : nativeFromJson<String>(json['location']);
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
if(identical(this, other)) {
|
||||
return true;
|
||||
}
|
||||
if(other.runtimeType != runtimeType) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final ListShiftRolesByBusinessAndOrderShiftRolesShiftOrder otherTyped = other as ListShiftRolesByBusinessAndOrderShiftRolesShiftOrder;
|
||||
return vendorId == otherTyped.vendorId &&
|
||||
date == otherTyped.date &&
|
||||
location == otherTyped.location;
|
||||
|
||||
}
|
||||
@override
|
||||
int get hashCode => Object.hashAll([vendorId.hashCode, date.hashCode, location.hashCode]);
|
||||
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
Map<String, dynamic> json = {};
|
||||
if (vendorId != null) {
|
||||
json['vendorId'] = nativeToJson<String?>(vendorId);
|
||||
}
|
||||
if (date != null) {
|
||||
json['date'] = date!.toJson();
|
||||
}
|
||||
if (location != null) {
|
||||
json['location'] = nativeToJson<String?>(location);
|
||||
}
|
||||
return json;
|
||||
}
|
||||
|
||||
ListShiftRolesByBusinessAndOrderShiftRolesShiftOrder({
|
||||
this.vendorId,
|
||||
this.date,
|
||||
this.location,
|
||||
});
|
||||
}
|
||||
|
||||
@immutable
|
||||
class ListShiftRolesByBusinessAndOrderData {
|
||||
final List<ListShiftRolesByBusinessAndOrderShiftRoles> shiftRoles;
|
||||
ListShiftRolesByBusinessAndOrderData.fromJson(dynamic json):
|
||||
|
||||
shiftRoles = (json['shiftRoles'] as List<dynamic>)
|
||||
.map((e) => ListShiftRolesByBusinessAndOrderShiftRoles.fromJson(e))
|
||||
.toList();
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
if(identical(this, other)) {
|
||||
return true;
|
||||
}
|
||||
if(other.runtimeType != runtimeType) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final ListShiftRolesByBusinessAndOrderData otherTyped = other as ListShiftRolesByBusinessAndOrderData;
|
||||
return shiftRoles == otherTyped.shiftRoles;
|
||||
|
||||
}
|
||||
@override
|
||||
int get hashCode => shiftRoles.hashCode;
|
||||
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
Map<String, dynamic> json = {};
|
||||
json['shiftRoles'] = shiftRoles.map((e) => e.toJson()).toList();
|
||||
return json;
|
||||
}
|
||||
|
||||
ListShiftRolesByBusinessAndOrderData({
|
||||
required this.shiftRoles,
|
||||
});
|
||||
}
|
||||
|
||||
@immutable
|
||||
class ListShiftRolesByBusinessAndOrderVariables {
|
||||
final String businessId;
|
||||
final String orderId;
|
||||
late final Optional<int>offset;
|
||||
late final Optional<int>limit;
|
||||
@Deprecated('fromJson is deprecated for Variable classes as they are no longer required for deserialization.')
|
||||
ListShiftRolesByBusinessAndOrderVariables.fromJson(Map<String, dynamic> json):
|
||||
|
||||
businessId = nativeFromJson<String>(json['businessId']),
|
||||
orderId = nativeFromJson<String>(json['orderId']) {
|
||||
|
||||
|
||||
|
||||
|
||||
offset = Optional.optional(nativeFromJson, nativeToJson);
|
||||
offset.value = json['offset'] == null ? null : nativeFromJson<int>(json['offset']);
|
||||
|
||||
|
||||
limit = Optional.optional(nativeFromJson, nativeToJson);
|
||||
limit.value = json['limit'] == null ? null : nativeFromJson<int>(json['limit']);
|
||||
|
||||
}
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
if(identical(this, other)) {
|
||||
return true;
|
||||
}
|
||||
if(other.runtimeType != runtimeType) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final ListShiftRolesByBusinessAndOrderVariables otherTyped = other as ListShiftRolesByBusinessAndOrderVariables;
|
||||
return businessId == otherTyped.businessId &&
|
||||
orderId == otherTyped.orderId &&
|
||||
offset == otherTyped.offset &&
|
||||
limit == otherTyped.limit;
|
||||
|
||||
}
|
||||
@override
|
||||
int get hashCode => Object.hashAll([businessId.hashCode, orderId.hashCode, offset.hashCode, limit.hashCode]);
|
||||
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
Map<String, dynamic> json = {};
|
||||
json['businessId'] = nativeToJson<String>(businessId);
|
||||
json['orderId'] = nativeToJson<String>(orderId);
|
||||
if(offset.state == OptionalState.set) {
|
||||
json['offset'] = offset.toJson();
|
||||
}
|
||||
if(limit.state == OptionalState.set) {
|
||||
json['limit'] = limit.toJson();
|
||||
}
|
||||
return json;
|
||||
}
|
||||
|
||||
ListShiftRolesByBusinessAndOrderVariables({
|
||||
required this.businessId,
|
||||
required this.orderId,
|
||||
required this.offset,
|
||||
required this.limit,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ class UpdateOrderVariablesBuilder {
|
||||
Optional<String> _businessId = Optional.optional(nativeFromJson, nativeToJson);
|
||||
Optional<String> _location = Optional.optional(nativeFromJson, nativeToJson);
|
||||
Optional<OrderStatus> _status = Optional.optional((data) => OrderStatus.values.byName(data), enumSerializer);
|
||||
Optional<Timestamp> _date = Optional.optional((json) => json['date'] = Timestamp.fromJson(json['date']), defaultSerializer);
|
||||
Optional<Timestamp> _startDate = Optional.optional((json) => json['startDate'] = Timestamp.fromJson(json['startDate']), defaultSerializer);
|
||||
Optional<Timestamp> _endDate = Optional.optional((json) => json['endDate'] = Timestamp.fromJson(json['endDate']), defaultSerializer);
|
||||
Optional<double> _total = Optional.optional(nativeFromJson, nativeToJson);
|
||||
@@ -36,6 +37,10 @@ class UpdateOrderVariablesBuilder {
|
||||
_status.value = t;
|
||||
return this;
|
||||
}
|
||||
UpdateOrderVariablesBuilder date(Timestamp? t) {
|
||||
_date.value = t;
|
||||
return this;
|
||||
}
|
||||
UpdateOrderVariablesBuilder startDate(Timestamp? t) {
|
||||
_startDate.value = t;
|
||||
return this;
|
||||
@@ -97,7 +102,7 @@ class UpdateOrderVariablesBuilder {
|
||||
}
|
||||
|
||||
MutationRef<UpdateOrderData, UpdateOrderVariables> ref() {
|
||||
UpdateOrderVariables vars= UpdateOrderVariables(id: id,vendorId: _vendorId,businessId: _businessId,location: _location,status: _status,startDate: _startDate,endDate: _endDate,total: _total,eventName: _eventName,assignedStaff: _assignedStaff,shifts: _shifts,requested: _requested,hub: _hub,recurringDays: _recurringDays,permanentDays: _permanentDays,notes: _notes,detectedConflicts: _detectedConflicts,poReference: _poReference,);
|
||||
UpdateOrderVariables vars= UpdateOrderVariables(id: id,vendorId: _vendorId,businessId: _businessId,location: _location,status: _status,date: _date,startDate: _startDate,endDate: _endDate,total: _total,eventName: _eventName,assignedStaff: _assignedStaff,shifts: _shifts,requested: _requested,hub: _hub,recurringDays: _recurringDays,permanentDays: _permanentDays,notes: _notes,detectedConflicts: _detectedConflicts,poReference: _poReference,);
|
||||
return _dataConnect.mutation("updateOrder", dataDeserializer, varsSerializer, vars);
|
||||
}
|
||||
}
|
||||
@@ -179,6 +184,7 @@ class UpdateOrderVariables {
|
||||
late final Optional<String>businessId;
|
||||
late final Optional<String>location;
|
||||
late final Optional<OrderStatus>status;
|
||||
late final Optional<Timestamp>date;
|
||||
late final Optional<Timestamp>startDate;
|
||||
late final Optional<Timestamp>endDate;
|
||||
late final Optional<double>total;
|
||||
@@ -215,6 +221,10 @@ class UpdateOrderVariables {
|
||||
status.value = json['status'] == null ? null : OrderStatus.values.byName(json['status']);
|
||||
|
||||
|
||||
date = Optional.optional((json) => json['date'] = Timestamp.fromJson(json['date']), defaultSerializer);
|
||||
date.value = json['date'] == null ? null : Timestamp.fromJson(json['date']);
|
||||
|
||||
|
||||
startDate = Optional.optional((json) => json['startDate'] = Timestamp.fromJson(json['startDate']), defaultSerializer);
|
||||
startDate.value = json['startDate'] == null ? null : Timestamp.fromJson(json['startDate']);
|
||||
|
||||
@@ -282,6 +292,7 @@ class UpdateOrderVariables {
|
||||
businessId == otherTyped.businessId &&
|
||||
location == otherTyped.location &&
|
||||
status == otherTyped.status &&
|
||||
date == otherTyped.date &&
|
||||
startDate == otherTyped.startDate &&
|
||||
endDate == otherTyped.endDate &&
|
||||
total == otherTyped.total &&
|
||||
@@ -298,7 +309,7 @@ class UpdateOrderVariables {
|
||||
|
||||
}
|
||||
@override
|
||||
int get hashCode => Object.hashAll([id.hashCode, vendorId.hashCode, businessId.hashCode, location.hashCode, status.hashCode, startDate.hashCode, endDate.hashCode, total.hashCode, eventName.hashCode, assignedStaff.hashCode, shifts.hashCode, requested.hashCode, hub.hashCode, recurringDays.hashCode, permanentDays.hashCode, notes.hashCode, detectedConflicts.hashCode, poReference.hashCode]);
|
||||
int get hashCode => Object.hashAll([id.hashCode, vendorId.hashCode, businessId.hashCode, location.hashCode, status.hashCode, date.hashCode, startDate.hashCode, endDate.hashCode, total.hashCode, eventName.hashCode, assignedStaff.hashCode, shifts.hashCode, requested.hashCode, hub.hashCode, recurringDays.hashCode, permanentDays.hashCode, notes.hashCode, detectedConflicts.hashCode, poReference.hashCode]);
|
||||
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
@@ -316,6 +327,9 @@ class UpdateOrderVariables {
|
||||
if(status.state == OptionalState.set) {
|
||||
json['status'] = status.toJson();
|
||||
}
|
||||
if(date.state == OptionalState.set) {
|
||||
json['date'] = date.toJson();
|
||||
}
|
||||
if(startDate.state == OptionalState.set) {
|
||||
json['startDate'] = startDate.toJson();
|
||||
}
|
||||
@@ -364,6 +378,7 @@ class UpdateOrderVariables {
|
||||
required this.businessId,
|
||||
required this.location,
|
||||
required this.status,
|
||||
required this.date,
|
||||
required this.startDate,
|
||||
required this.endDate,
|
||||
required this.total,
|
||||
|
||||
@@ -48,6 +48,7 @@ class OrderRepositoryMock {
|
||||
return <OrderItem>[
|
||||
OrderItem(
|
||||
id: '1',
|
||||
orderId: 'order_1',
|
||||
title: 'Server - Wedding',
|
||||
clientName: 'Grand Plaza Hotel',
|
||||
status: 'filled',
|
||||
@@ -75,6 +76,7 @@ class OrderRepositoryMock {
|
||||
),
|
||||
OrderItem(
|
||||
id: '2',
|
||||
orderId: 'order_2',
|
||||
title: 'Bartender - Private Event',
|
||||
clientName: 'Taste of the Town',
|
||||
status: 'open',
|
||||
@@ -101,6 +103,7 @@ class OrderRepositoryMock {
|
||||
),
|
||||
OrderItem(
|
||||
id: '3',
|
||||
orderId: 'order_3',
|
||||
title: 'Event Staff',
|
||||
clientName: 'City Center',
|
||||
status: 'in_progress',
|
||||
@@ -125,6 +128,7 @@ class OrderRepositoryMock {
|
||||
),
|
||||
OrderItem(
|
||||
id: '4',
|
||||
orderId: 'order_4',
|
||||
title: 'Coat Check',
|
||||
clientName: 'The Met Museum',
|
||||
status: 'completed',
|
||||
|
||||
@@ -10,7 +10,7 @@ class OneTimeOrderPosition extends Equatable {
|
||||
required this.count,
|
||||
required this.startTime,
|
||||
required this.endTime,
|
||||
this.lunchBreak = 30,
|
||||
this.lunchBreak = 'NO_BREAK',
|
||||
this.location,
|
||||
});
|
||||
/// The job role or title required.
|
||||
@@ -25,8 +25,8 @@ class OneTimeOrderPosition extends Equatable {
|
||||
/// The scheduled end time (e.g., "05:00 PM").
|
||||
final String endTime;
|
||||
|
||||
/// The duration of the lunch break in minutes. Defaults to 30.
|
||||
final int lunchBreak;
|
||||
/// The break duration enum value (e.g., NO_BREAK, MIN_15, MIN_30).
|
||||
final String lunchBreak;
|
||||
|
||||
/// Optional specific location for this position, if different from the order's main location.
|
||||
final String? location;
|
||||
@@ -47,7 +47,7 @@ class OneTimeOrderPosition extends Equatable {
|
||||
int? count,
|
||||
String? startTime,
|
||||
String? endTime,
|
||||
int? lunchBreak,
|
||||
String? lunchBreak,
|
||||
String? location,
|
||||
}) {
|
||||
return OneTimeOrderPosition(
|
||||
|
||||
@@ -8,6 +8,7 @@ class OrderItem extends Equatable {
|
||||
/// Creates an [OrderItem].
|
||||
const OrderItem({
|
||||
required this.id,
|
||||
required this.orderId,
|
||||
required this.title,
|
||||
required this.clientName,
|
||||
required this.status,
|
||||
@@ -27,6 +28,9 @@ class OrderItem extends Equatable {
|
||||
/// Unique identifier of the order.
|
||||
final String id;
|
||||
|
||||
/// Parent order identifier.
|
||||
final String orderId;
|
||||
|
||||
/// Title or name of the role.
|
||||
final String title;
|
||||
|
||||
@@ -72,6 +76,7 @@ class OrderItem extends Equatable {
|
||||
@override
|
||||
List<Object?> get props => <Object?>[
|
||||
id,
|
||||
orderId,
|
||||
title,
|
||||
clientName,
|
||||
status,
|
||||
|
||||
@@ -118,6 +118,7 @@ class ClientCreateOrderRepositoryImpl
|
||||
.startTime(_toTimestamp(start))
|
||||
.endTime(_toTimestamp(normalizedEnd))
|
||||
.hours(hours)
|
||||
.breakType(_breakDurationFromValue(position.lunchBreak))
|
||||
.totalValue(totalValue)
|
||||
.execute();
|
||||
}
|
||||
@@ -148,6 +149,17 @@ class ClientCreateOrderRepositoryImpl
|
||||
return total;
|
||||
}
|
||||
|
||||
dc.BreakDuration _breakDurationFromValue(String value) {
|
||||
switch (value) {
|
||||
case 'MIN_15':
|
||||
return dc.BreakDuration.MIN_15;
|
||||
case 'MIN_30':
|
||||
return dc.BreakDuration.MIN_30;
|
||||
default:
|
||||
return dc.BreakDuration.NO_BREAK;
|
||||
}
|
||||
}
|
||||
|
||||
DateTime _parseTime(DateTime date, String time) {
|
||||
if (time.trim().isEmpty) {
|
||||
throw Exception('Shift time is missing.');
|
||||
|
||||
@@ -230,7 +230,7 @@ class OneTimeOrderPositionCard extends StatelessWidget {
|
||||
border: Border.all(color: UiColors.border),
|
||||
),
|
||||
child: DropdownButtonHideUnderline(
|
||||
child: DropdownButton<int>(
|
||||
child: DropdownButton<String>(
|
||||
isExpanded: true,
|
||||
value: position.lunchBreak,
|
||||
icon: const Icon(
|
||||
@@ -238,16 +238,23 @@ class OneTimeOrderPositionCard extends StatelessWidget {
|
||||
size: 18,
|
||||
color: UiColors.iconSecondary,
|
||||
),
|
||||
onChanged: (int? val) {
|
||||
onChanged: (String? val) {
|
||||
if (val != null) {
|
||||
onUpdated(position.copyWith(lunchBreak: val));
|
||||
}
|
||||
},
|
||||
items: <int>[0, 15, 30, 45, 60].map((int mins) {
|
||||
return DropdownMenuItem<int>(
|
||||
value: mins,
|
||||
items: <String>['NO_BREAK', 'MIN_15', 'MIN_30'].map((
|
||||
String value,
|
||||
) {
|
||||
final String label = switch (value) {
|
||||
'NO_BREAK' => 'No Break',
|
||||
'MIN_15' => '15 min',
|
||||
_ => '30 min',
|
||||
};
|
||||
return DropdownMenuItem<String>(
|
||||
value: value,
|
||||
child: Text(
|
||||
mins == 0 ? 'No Break' : '$mins mins',
|
||||
label,
|
||||
style: UiTypography.body2r.textPrimary,
|
||||
),
|
||||
);
|
||||
|
||||
@@ -62,6 +62,7 @@ class ViewOrdersRepositoryImpl implements IViewOrdersRepository {
|
||||
|
||||
return domain.OrderItem(
|
||||
id: _shiftRoleKey(shiftRole.shiftId, shiftRole.roleId),
|
||||
orderId: shiftRole.shift.order.id,
|
||||
title: '${shiftRole.role.name} - ${shiftRole.shift.title}',
|
||||
clientName: businessName,
|
||||
status: status,
|
||||
|
||||
@@ -133,6 +133,7 @@ class ViewOrdersCubit extends Cubit<ViewOrdersState> {
|
||||
filled >= order.workersNeeded ? 'filled' : order.status;
|
||||
return OrderItem(
|
||||
id: order.id,
|
||||
orderId: order.orderId,
|
||||
title: order.title,
|
||||
clientName: order.clientName,
|
||||
status: status,
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
import 'package:core_localization/core_localization.dart';
|
||||
import 'package:design_system/design_system.dart';
|
||||
import 'package:firebase_auth/firebase_auth.dart' as firebase;
|
||||
import 'package:firebase_data_connect/firebase_data_connect.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:krow_data_connect/krow_data_connect.dart' as dc;
|
||||
import 'package:krow_domain/krow_domain.dart';
|
||||
|
||||
/// A rich card displaying details of a client order/shift.
|
||||
@@ -619,6 +622,25 @@ class _ViewOrderCardState extends State<ViewOrderCard> {
|
||||
}
|
||||
}
|
||||
|
||||
class _RoleOption {
|
||||
const _RoleOption({
|
||||
required this.id,
|
||||
required this.name,
|
||||
required this.costPerHour,
|
||||
});
|
||||
|
||||
final String id;
|
||||
final String name;
|
||||
final double costPerHour;
|
||||
}
|
||||
|
||||
class _ShiftRoleKey {
|
||||
const _ShiftRoleKey({required this.shiftId, required this.roleId});
|
||||
|
||||
final String shiftId;
|
||||
final String roleId;
|
||||
}
|
||||
|
||||
/// A sophisticated bottom sheet for editing an existing order,
|
||||
/// following the Unified Order Flow prototype and matching OneTimeOrderView.
|
||||
class _OrderEditSheet extends StatefulWidget {
|
||||
@@ -639,8 +661,15 @@ class _OrderEditSheetState extends State<_OrderEditSheet> {
|
||||
|
||||
late List<Map<String, dynamic>> _positions;
|
||||
|
||||
final dc.ExampleConnector _dataConnect = dc.ExampleConnector.instance;
|
||||
final firebase.FirebaseAuth _firebaseAuth = firebase.FirebaseAuth.instance;
|
||||
|
||||
List<Vendor> _vendors = const <Vendor>[];
|
||||
Vendor? _selectedVendor;
|
||||
List<_RoleOption> _roles = const <_RoleOption>[];
|
||||
|
||||
String? _shiftId;
|
||||
List<_ShiftRoleKey> _originalShiftRoles = const <_ShiftRoleKey>[];
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
@@ -652,47 +681,19 @@ class _OrderEditSheetState extends State<_OrderEditSheet> {
|
||||
|
||||
_positions = <Map<String, dynamic>>[
|
||||
<String, dynamic>{
|
||||
'role': widget.order.title,
|
||||
'shiftId': null,
|
||||
'roleId': '',
|
||||
'roleName': '',
|
||||
'originalRoleId': null,
|
||||
'count': widget.order.workersNeeded,
|
||||
'start_time': widget.order.startTime,
|
||||
'end_time': widget.order.endTime,
|
||||
'lunch_break': 0,
|
||||
'lunch_break': 'NO_BREAK',
|
||||
'location': null,
|
||||
},
|
||||
];
|
||||
|
||||
// Mock vendors initialization
|
||||
_vendors = const <Vendor>[
|
||||
Vendor(
|
||||
id: 'v1',
|
||||
name: 'Elite Staffing',
|
||||
rates: <String, double>{
|
||||
'Server': 25.0,
|
||||
'Bartender': 30.0,
|
||||
'Cook': 28.0,
|
||||
'Busser': 18.0,
|
||||
'Host': 20.0,
|
||||
'Barista': 22.0,
|
||||
'Dishwasher': 17.0,
|
||||
'Event Staff': 19.0,
|
||||
},
|
||||
),
|
||||
Vendor(
|
||||
id: 'v2',
|
||||
name: 'Premier Workforce',
|
||||
rates: <String, double>{
|
||||
'Server': 22.0,
|
||||
'Bartender': 28.0,
|
||||
'Cook': 25.0,
|
||||
'Busser': 16.0,
|
||||
'Host': 18.0,
|
||||
'Barista': 20.0,
|
||||
'Dishwasher': 15.0,
|
||||
'Event Staff': 18.0,
|
||||
},
|
||||
),
|
||||
];
|
||||
_selectedVendor = _vendors.first;
|
||||
_loadOrderDetails();
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -702,16 +703,396 @@ class _OrderEditSheetState extends State<_OrderEditSheet> {
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
void _addPosition() {
|
||||
Future<void> _loadOrderDetails() async {
|
||||
final String? businessId =
|
||||
dc.ClientSessionStore.instance.session?.business?.id;
|
||||
if (businessId == null || businessId.isEmpty) {
|
||||
await _firebaseAuth.signOut();
|
||||
return;
|
||||
}
|
||||
|
||||
if (widget.order.orderId.isEmpty) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
final QueryResult<
|
||||
dc.ListShiftRolesByBusinessAndOrderData,
|
||||
dc.ListShiftRolesByBusinessAndOrderVariables> result = await _dataConnect
|
||||
.listShiftRolesByBusinessAndOrder(
|
||||
businessId: businessId,
|
||||
orderId: widget.order.orderId,
|
||||
)
|
||||
.execute();
|
||||
|
||||
final List<dc.ListShiftRolesByBusinessAndOrderShiftRoles> shiftRoles =
|
||||
result.data.shiftRoles;
|
||||
if (shiftRoles.isEmpty) {
|
||||
return;
|
||||
}
|
||||
|
||||
final dc.ListShiftRolesByBusinessAndOrderShiftRolesShift firstShift =
|
||||
shiftRoles.first.shift;
|
||||
final DateTime? orderDate = firstShift.order.date?.toDateTime();
|
||||
final String dateText = orderDate == null
|
||||
? widget.order.date
|
||||
: DateFormat('yyyy-MM-dd').format(orderDate);
|
||||
final String location = firstShift.order.location ??
|
||||
firstShift.locationAddress ??
|
||||
firstShift.location ??
|
||||
widget.order.locationAddress;
|
||||
|
||||
_dateController.text = dateText;
|
||||
_globalLocationController.text = location;
|
||||
_shiftId = shiftRoles.first.shiftId;
|
||||
|
||||
final List<Map<String, dynamic>> positions =
|
||||
shiftRoles.map((dc.ListShiftRolesByBusinessAndOrderShiftRoles role) {
|
||||
return <String, dynamic>{
|
||||
'shiftId': role.shiftId,
|
||||
'roleId': role.roleId,
|
||||
'roleName': role.role.name,
|
||||
'originalRoleId': role.roleId,
|
||||
'count': role.count,
|
||||
'start_time': _formatTimeForField(role.startTime),
|
||||
'end_time': _formatTimeForField(role.endTime),
|
||||
'lunch_break': _breakValueFromDuration(role.breakType),
|
||||
'location': null,
|
||||
};
|
||||
}).toList();
|
||||
|
||||
if (positions.isEmpty) {
|
||||
positions.add(_emptyPosition());
|
||||
}
|
||||
|
||||
final List<_ShiftRoleKey> originalShiftRoles =
|
||||
shiftRoles
|
||||
.map(
|
||||
(dc.ListShiftRolesByBusinessAndOrderShiftRoles role) =>
|
||||
_ShiftRoleKey(shiftId: role.shiftId, roleId: role.roleId),
|
||||
)
|
||||
.toList();
|
||||
|
||||
await _loadVendorsAndSelect(firstShift.order.vendorId);
|
||||
|
||||
if (mounted) {
|
||||
setState(() {
|
||||
_positions.add(<String, dynamic>{
|
||||
'role': '',
|
||||
_positions = positions;
|
||||
_originalShiftRoles = originalShiftRoles;
|
||||
});
|
||||
}
|
||||
} catch (_) {
|
||||
// Keep current state on failure.
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _loadVendorsAndSelect(String? selectedVendorId) async {
|
||||
try {
|
||||
final QueryResult<dc.ListVendorsData, void> result =
|
||||
await _dataConnect.listVendors().execute();
|
||||
final List<Vendor> vendors = result.data.vendors
|
||||
.map(
|
||||
(dc.ListVendorsVendors vendor) => Vendor(
|
||||
id: vendor.id,
|
||||
name: vendor.companyName,
|
||||
rates: const <String, double>{},
|
||||
),
|
||||
)
|
||||
.toList();
|
||||
|
||||
Vendor? selectedVendor;
|
||||
if (selectedVendorId != null && selectedVendorId.isNotEmpty) {
|
||||
for (final Vendor vendor in vendors) {
|
||||
if (vendor.id == selectedVendorId) {
|
||||
selectedVendor = vendor;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
selectedVendor ??= vendors.isNotEmpty ? vendors.first : null;
|
||||
|
||||
if (mounted) {
|
||||
setState(() {
|
||||
_vendors = vendors;
|
||||
_selectedVendor = selectedVendor;
|
||||
});
|
||||
}
|
||||
|
||||
if (selectedVendor != null) {
|
||||
await _loadRolesForVendor(selectedVendor.id);
|
||||
}
|
||||
} catch (_) {
|
||||
if (mounted) {
|
||||
setState(() {
|
||||
_vendors = const <Vendor>[];
|
||||
_selectedVendor = null;
|
||||
_roles = const <_RoleOption>[];
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _loadRolesForVendor(String vendorId) async {
|
||||
try {
|
||||
final QueryResult<dc.ListRolesByVendorIdData, dc.ListRolesByVendorIdVariables>
|
||||
result = await _dataConnect
|
||||
.listRolesByVendorId(vendorId: vendorId)
|
||||
.execute();
|
||||
final List<_RoleOption> roles = result.data.roles
|
||||
.map(
|
||||
(dc.ListRolesByVendorIdRoles role) => _RoleOption(
|
||||
id: role.id,
|
||||
name: role.name,
|
||||
costPerHour: role.costPerHour,
|
||||
),
|
||||
)
|
||||
.toList();
|
||||
if (mounted) {
|
||||
setState(() => _roles = roles);
|
||||
}
|
||||
} catch (_) {
|
||||
if (mounted) {
|
||||
setState(() => _roles = const <_RoleOption>[]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Map<String, dynamic> _emptyPosition() {
|
||||
return <String, dynamic>{
|
||||
'shiftId': _shiftId,
|
||||
'roleId': '',
|
||||
'roleName': '',
|
||||
'originalRoleId': null,
|
||||
'count': 1,
|
||||
'start_time': '09:00',
|
||||
'end_time': '17:00',
|
||||
'lunch_break': 0,
|
||||
'lunch_break': 'NO_BREAK',
|
||||
'location': null,
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
String _formatTimeForField(Timestamp? value) {
|
||||
if (value == null) return '';
|
||||
try {
|
||||
return DateFormat('HH:mm').format(value.toDateTime());
|
||||
} catch (_) {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
String _breakValueFromDuration(dc.EnumValue<dc.BreakDuration>? breakType) {
|
||||
final dc.BreakDuration? value =
|
||||
breakType is dc.Known<dc.BreakDuration> ? breakType.value : null;
|
||||
switch (value) {
|
||||
case dc.BreakDuration.MIN_15:
|
||||
return 'MIN_15';
|
||||
case dc.BreakDuration.MIN_30:
|
||||
return 'MIN_30';
|
||||
case dc.BreakDuration.NO_BREAK:
|
||||
case null:
|
||||
return 'NO_BREAK';
|
||||
}
|
||||
}
|
||||
|
||||
dc.BreakDuration _breakDurationFromValue(String value) {
|
||||
switch (value) {
|
||||
case 'MIN_15':
|
||||
return dc.BreakDuration.MIN_15;
|
||||
case 'MIN_30':
|
||||
return dc.BreakDuration.MIN_30;
|
||||
default:
|
||||
return dc.BreakDuration.NO_BREAK;
|
||||
}
|
||||
}
|
||||
|
||||
_RoleOption? _roleById(String roleId) {
|
||||
for (final _RoleOption role in _roles) {
|
||||
if (role.id == roleId) {
|
||||
return role;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
double _rateForRole(String roleId) {
|
||||
return _roleById(roleId)?.costPerHour ?? 0;
|
||||
}
|
||||
|
||||
DateTime _parseDate(String value) {
|
||||
try {
|
||||
return DateFormat('yyyy-MM-dd').parse(value);
|
||||
} catch (_) {
|
||||
return DateTime.now();
|
||||
}
|
||||
}
|
||||
|
||||
DateTime _parseTime(DateTime date, String time) {
|
||||
if (time.trim().isEmpty) {
|
||||
throw Exception('Shift time is missing.');
|
||||
}
|
||||
|
||||
DateTime parsed;
|
||||
try {
|
||||
parsed = DateFormat.Hm().parse(time);
|
||||
} catch (_) {
|
||||
parsed = DateFormat.jm().parse(time);
|
||||
}
|
||||
|
||||
return DateTime(
|
||||
date.year,
|
||||
date.month,
|
||||
date.day,
|
||||
parsed.hour,
|
||||
parsed.minute,
|
||||
);
|
||||
}
|
||||
|
||||
Timestamp _toTimestamp(DateTime date) {
|
||||
final int millis = date.millisecondsSinceEpoch;
|
||||
final int seconds = millis ~/ 1000;
|
||||
final int nanos = (millis % 1000) * 1000000;
|
||||
return Timestamp(nanos, seconds);
|
||||
}
|
||||
|
||||
double _calculateTotalCost() {
|
||||
double total = 0;
|
||||
for (final Map<String, dynamic> pos in _positions) {
|
||||
final String roleId = pos['roleId']?.toString() ?? '';
|
||||
if (roleId.isEmpty) {
|
||||
continue;
|
||||
}
|
||||
final DateTime date = _parseDate(_dateController.text);
|
||||
final DateTime start = _parseTime(date, pos['start_time'].toString());
|
||||
final DateTime end = _parseTime(date, pos['end_time'].toString());
|
||||
final DateTime normalizedEnd =
|
||||
end.isBefore(start) ? end.add(const Duration(days: 1)) : end;
|
||||
final double hours = normalizedEnd.difference(start).inMinutes / 60.0;
|
||||
final double rate = _rateForRole(roleId);
|
||||
final int count = pos['count'] as int;
|
||||
total += rate * hours * count;
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
Future<void> _saveOrderChanges() async {
|
||||
if (_shiftId == null || _shiftId!.isEmpty) {
|
||||
return;
|
||||
}
|
||||
|
||||
final String? businessId =
|
||||
dc.ClientSessionStore.instance.session?.business?.id;
|
||||
if (businessId == null || businessId.isEmpty) {
|
||||
await _firebaseAuth.signOut();
|
||||
return;
|
||||
}
|
||||
|
||||
final DateTime orderDate = _parseDate(_dateController.text);
|
||||
final String location = _globalLocationController.text;
|
||||
|
||||
int totalWorkers = 0;
|
||||
double shiftCost = 0;
|
||||
|
||||
final List<_ShiftRoleKey> remainingOriginal =
|
||||
List<_ShiftRoleKey>.from(_originalShiftRoles);
|
||||
|
||||
for (final Map<String, dynamic> pos in _positions) {
|
||||
final String roleId = pos['roleId']?.toString() ?? '';
|
||||
if (roleId.isEmpty) {
|
||||
continue;
|
||||
}
|
||||
|
||||
final String shiftId = pos['shiftId']?.toString() ?? _shiftId!;
|
||||
final int count = pos['count'] as int;
|
||||
final DateTime start = _parseTime(orderDate, pos['start_time'].toString());
|
||||
final DateTime end = _parseTime(orderDate, pos['end_time'].toString());
|
||||
final DateTime normalizedEnd =
|
||||
end.isBefore(start) ? end.add(const Duration(days: 1)) : end;
|
||||
final double hours = normalizedEnd.difference(start).inMinutes / 60.0;
|
||||
final double rate = _rateForRole(roleId);
|
||||
final double totalValue = rate * hours * count;
|
||||
final String lunchBreak = pos['lunch_break'] as String;
|
||||
|
||||
totalWorkers += count;
|
||||
shiftCost += totalValue;
|
||||
|
||||
final String? originalRoleId = pos['originalRoleId']?.toString();
|
||||
remainingOriginal.removeWhere(
|
||||
(_ShiftRoleKey key) =>
|
||||
key.shiftId == shiftId && key.roleId == originalRoleId,
|
||||
);
|
||||
|
||||
if (originalRoleId != null && originalRoleId.isNotEmpty) {
|
||||
if (originalRoleId != roleId) {
|
||||
await _dataConnect
|
||||
.deleteShiftRole(shiftId: shiftId, roleId: originalRoleId)
|
||||
.execute();
|
||||
await _dataConnect
|
||||
.createShiftRole(
|
||||
shiftId: shiftId,
|
||||
roleId: roleId,
|
||||
count: count,
|
||||
)
|
||||
.startTime(_toTimestamp(start))
|
||||
.endTime(_toTimestamp(normalizedEnd))
|
||||
.hours(hours)
|
||||
.breakType(_breakDurationFromValue(lunchBreak))
|
||||
.totalValue(totalValue)
|
||||
.execute();
|
||||
} else {
|
||||
await _dataConnect
|
||||
.updateShiftRole(shiftId: shiftId, roleId: roleId)
|
||||
.count(count)
|
||||
.startTime(_toTimestamp(start))
|
||||
.endTime(_toTimestamp(normalizedEnd))
|
||||
.hours(hours)
|
||||
.breakType(_breakDurationFromValue(lunchBreak))
|
||||
.totalValue(totalValue)
|
||||
.execute();
|
||||
}
|
||||
} else {
|
||||
await _dataConnect
|
||||
.createShiftRole(
|
||||
shiftId: shiftId,
|
||||
roleId: roleId,
|
||||
count: count,
|
||||
)
|
||||
.startTime(_toTimestamp(start))
|
||||
.endTime(_toTimestamp(normalizedEnd))
|
||||
.hours(hours)
|
||||
.breakType(_breakDurationFromValue(lunchBreak))
|
||||
.totalValue(totalValue)
|
||||
.execute();
|
||||
}
|
||||
}
|
||||
|
||||
for (final _ShiftRoleKey key in remainingOriginal) {
|
||||
await _dataConnect
|
||||
.deleteShiftRole(shiftId: key.shiftId, roleId: key.roleId)
|
||||
.execute();
|
||||
}
|
||||
|
||||
await _dataConnect
|
||||
.updateOrder(id: widget.order.orderId)
|
||||
.vendorId(_selectedVendor?.id)
|
||||
.location(location)
|
||||
.date(_toTimestamp(orderDate))
|
||||
.execute();
|
||||
|
||||
await _dataConnect
|
||||
.updateShift(id: _shiftId!)
|
||||
.title('shift 1 ${DateFormat('yyyy-MM-dd').format(orderDate)}')
|
||||
.date(_toTimestamp(orderDate))
|
||||
.location(location)
|
||||
.locationAddress(location)
|
||||
.workersNeeded(totalWorkers)
|
||||
.cost(shiftCost)
|
||||
.durationDays(1)
|
||||
.execute();
|
||||
}
|
||||
|
||||
void _addPosition() {
|
||||
setState(() {
|
||||
_positions.add(_emptyPosition());
|
||||
});
|
||||
}
|
||||
|
||||
@@ -725,10 +1106,6 @@ class _OrderEditSheetState extends State<_OrderEditSheet> {
|
||||
setState(() => _positions[index][key] = value);
|
||||
}
|
||||
|
||||
double _calculateTotalCost() {
|
||||
return widget.order.totalValue;
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
if (_isLoading && _showReview) {
|
||||
@@ -781,6 +1158,7 @@ class _OrderEditSheetState extends State<_OrderEditSheet> {
|
||||
onChanged: (Vendor? vendor) {
|
||||
if (vendor != null) {
|
||||
setState(() => _selectedVendor = vendor);
|
||||
_loadRolesForVendor(vendor.id);
|
||||
}
|
||||
},
|
||||
items: _vendors.map((Vendor vendor) {
|
||||
@@ -956,30 +1334,32 @@ class _OrderEditSheetState extends State<_OrderEditSheet> {
|
||||
|
||||
_buildDropdownField(
|
||||
hint: 'Select role',
|
||||
value: pos['role'],
|
||||
value: pos['roleId'],
|
||||
items: <String>[
|
||||
...(_selectedVendor?.rates.keys.toList() ??
|
||||
<String>[
|
||||
'Server',
|
||||
'Bartender',
|
||||
'Cook',
|
||||
'Busser',
|
||||
'Host',
|
||||
'Barista',
|
||||
'Dishwasher',
|
||||
'Event Staff',
|
||||
]),
|
||||
if (pos['role'] != null &&
|
||||
pos['role'].toString().isNotEmpty &&
|
||||
!(_selectedVendor?.rates.keys.contains(pos['role']) ?? false))
|
||||
pos['role'].toString(),
|
||||
..._roles.map((_RoleOption role) => role.id),
|
||||
if (pos['roleId'] != null &&
|
||||
pos['roleId'].toString().isNotEmpty &&
|
||||
!_roles.any(
|
||||
(_RoleOption role) => role.id == pos['roleId'].toString(),
|
||||
))
|
||||
pos['roleId'].toString(),
|
||||
],
|
||||
itemBuilder: (dynamic role) {
|
||||
final double? rate = _selectedVendor?.rates[role];
|
||||
if (rate == null) return role.toString();
|
||||
return '$role - \$${rate.toStringAsFixed(0)}/hr';
|
||||
itemBuilder: (dynamic roleId) {
|
||||
final _RoleOption? role = _roleById(roleId.toString());
|
||||
if (role == null) {
|
||||
final String fallback = pos['roleName']?.toString() ?? '';
|
||||
return fallback.isEmpty ? roleId.toString() : fallback;
|
||||
}
|
||||
return '${role.name} - \$${role.costPerHour.toStringAsFixed(0)}/hr';
|
||||
},
|
||||
onChanged: (dynamic val) {
|
||||
final String roleId = val?.toString() ?? '';
|
||||
final _RoleOption? role = _roleById(roleId);
|
||||
setState(() {
|
||||
_positions[index]['roleId'] = roleId;
|
||||
_positions[index]['roleName'] = role?.name ?? '';
|
||||
});
|
||||
},
|
||||
onChanged: (dynamic val) => _updatePosition(index, 'role', val),
|
||||
),
|
||||
|
||||
const SizedBox(height: UiConstants.space3),
|
||||
@@ -1117,10 +1497,16 @@ class _OrderEditSheetState extends State<_OrderEditSheet> {
|
||||
_buildDropdownField(
|
||||
hint: 'No break',
|
||||
value: pos['lunch_break'],
|
||||
items: <int>[0, 15, 30, 45, 60],
|
||||
items: <String>['NO_BREAK', 'MIN_15', 'MIN_30'],
|
||||
itemBuilder: (dynamic val) {
|
||||
if (val == 0) return 'No break';
|
||||
return '$val min';
|
||||
switch (val.toString()) {
|
||||
case 'MIN_15':
|
||||
return '15 min';
|
||||
case 'MIN_30':
|
||||
return '30 min';
|
||||
default:
|
||||
return 'No break';
|
||||
}
|
||||
},
|
||||
onChanged: (dynamic val) =>
|
||||
_updatePosition(index, 'lunch_break', val),
|
||||
@@ -1379,7 +1765,7 @@ class _OrderEditSheetState extends State<_OrderEditSheet> {
|
||||
text: 'Confirm & Save',
|
||||
onPressed: () async {
|
||||
setState(() => _isLoading = true);
|
||||
await Future<void>.delayed(const Duration(seconds: 1));
|
||||
await _saveOrderChanges();
|
||||
if (mounted) Navigator.pop(context);
|
||||
},
|
||||
),
|
||||
@@ -1413,8 +1799,9 @@ class _OrderEditSheetState extends State<_OrderEditSheet> {
|
||||
}
|
||||
|
||||
Widget _buildReviewPositionCard(Map<String, dynamic> pos) {
|
||||
final double rate =
|
||||
_selectedVendor?.rates[pos['role']] ?? widget.order.hourlyRate;
|
||||
final String roleId = pos['roleId']?.toString() ?? '';
|
||||
final _RoleOption? role = _roleById(roleId);
|
||||
final double rate = role?.costPerHour ?? 0;
|
||||
|
||||
return Container(
|
||||
margin: const EdgeInsets.only(bottom: 12),
|
||||
@@ -1433,9 +1820,9 @@ class _OrderEditSheetState extends State<_OrderEditSheet> {
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
Text(
|
||||
pos['role'].toString().isEmpty
|
||||
(role?.name ?? pos['roleName']?.toString() ?? '').isEmpty
|
||||
? 'Position'
|
||||
: pos['role'].toString(),
|
||||
: (role?.name ?? pos['roleName']?.toString() ?? ''),
|
||||
style: UiTypography.body2b.textPrimary,
|
||||
),
|
||||
Text(
|
||||
|
||||
@@ -55,6 +55,7 @@ mutation updateOrder(
|
||||
$businessId: UUID
|
||||
$location: String
|
||||
$status: OrderStatus
|
||||
$date: Timestamp
|
||||
$startDate: Timestamp
|
||||
$endDate: Timestamp
|
||||
$total: Float
|
||||
@@ -76,6 +77,7 @@ mutation updateOrder(
|
||||
businessId: $businessId
|
||||
location: $location
|
||||
status: $status
|
||||
date: $date
|
||||
startDate: $startDate
|
||||
endDate: $endDate
|
||||
total: $total
|
||||
|
||||
@@ -332,3 +332,52 @@ query listShiftRolesByBusinessAndDateRange(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#list shiftsroles for update order in client app
|
||||
query listShiftRolesByBusinessAndOrder(
|
||||
$businessId: UUID!
|
||||
$orderId: UUID!
|
||||
$offset: Int
|
||||
$limit: Int
|
||||
) @auth(level: USER) {
|
||||
shiftRoles(
|
||||
where: {
|
||||
shift: {
|
||||
orderId: { eq: $orderId }
|
||||
order: { businessId: { eq: $businessId } }
|
||||
}
|
||||
}
|
||||
offset: $offset
|
||||
limit: $limit
|
||||
orderBy: { createdAt: DESC }
|
||||
) {
|
||||
id
|
||||
shiftId
|
||||
roleId
|
||||
count
|
||||
assigned
|
||||
startTime
|
||||
endTime
|
||||
hours
|
||||
breakType
|
||||
totalValue
|
||||
createdAt
|
||||
|
||||
role { id name costPerHour }
|
||||
|
||||
shift {
|
||||
id
|
||||
title
|
||||
date
|
||||
orderId
|
||||
location
|
||||
locationAddress
|
||||
|
||||
order{
|
||||
vendorId
|
||||
date
|
||||
location
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user