feat: Implement UTC conversion for order date and time serialization in order use cases
This commit is contained in:
@@ -63,6 +63,39 @@ class OneTimeOrderArguments extends UseCaseArgument {
|
||||
/// The selected vendor ID, if applicable.
|
||||
final String? vendorId;
|
||||
|
||||
/// Serialises these arguments into the V2 API payload shape.
|
||||
///
|
||||
/// Times and dates are converted to UTC so the backend's
|
||||
/// `combineDateAndTime` helper receives the correct values.
|
||||
Map<String, dynamic> toJson() {
|
||||
final String firstStartTime =
|
||||
positions.isNotEmpty ? positions.first.startTime : '00:00';
|
||||
final String utcOrderDate = toUtcDateIso(orderDate, firstStartTime);
|
||||
|
||||
final List<Map<String, dynamic>> positionsList =
|
||||
positions.map((OneTimeOrderPositionArgument p) {
|
||||
return <String, dynamic>{
|
||||
if (p.roleName != null) 'roleName': p.roleName,
|
||||
if (p.roleId.isNotEmpty) 'roleId': p.roleId,
|
||||
'workerCount': p.workerCount,
|
||||
'startTime': toUtcTimeHHmm(orderDate, p.startTime),
|
||||
'endTime': toUtcTimeHHmm(orderDate, p.endTime),
|
||||
if (p.lunchBreak != null &&
|
||||
p.lunchBreak != 'NO_BREAK' &&
|
||||
p.lunchBreak!.isNotEmpty)
|
||||
'lunchBreakMinutes': breakMinutesFromLabel(p.lunchBreak!),
|
||||
};
|
||||
}).toList();
|
||||
|
||||
return <String, dynamic>{
|
||||
'hubId': hubId,
|
||||
'eventName': eventName,
|
||||
'orderDate': utcOrderDate,
|
||||
'positions': positionsList,
|
||||
if (vendorId != null) 'vendorId': vendorId,
|
||||
};
|
||||
}
|
||||
|
||||
@override
|
||||
List<Object?> get props =>
|
||||
<Object?>[hubId, eventName, orderDate, positions, vendorId];
|
||||
|
||||
@@ -63,6 +63,51 @@ class PermanentOrderArguments extends UseCaseArgument {
|
||||
/// The selected vendor ID, if applicable.
|
||||
final String? vendorId;
|
||||
|
||||
/// Day-of-week labels in Sunday-first order, matching the V2 API convention.
|
||||
static const List<String> _dayLabels = <String>[
|
||||
'SUN',
|
||||
'MON',
|
||||
'TUE',
|
||||
'WED',
|
||||
'THU',
|
||||
'FRI',
|
||||
'SAT',
|
||||
];
|
||||
|
||||
/// Serialises these arguments into the V2 API payload shape.
|
||||
///
|
||||
/// Times and dates are converted to UTC so the backend's
|
||||
/// `combineDateAndTime` helper receives the correct values.
|
||||
Map<String, dynamic> toJson() {
|
||||
final String firstStartTime =
|
||||
positions.isNotEmpty ? positions.first.startTime : '00:00';
|
||||
final String utcStartDate = toUtcDateIso(startDate, firstStartTime);
|
||||
|
||||
final List<int> daysOfWeekList = daysOfWeek
|
||||
.map((String day) => _dayLabels.indexOf(day) % 7)
|
||||
.toList();
|
||||
|
||||
final List<Map<String, dynamic>> positionsList =
|
||||
positions.map((PermanentOrderPositionArgument p) {
|
||||
return <String, dynamic>{
|
||||
if (p.roleName != null) 'roleName': p.roleName,
|
||||
if (p.roleId.isNotEmpty) 'roleId': p.roleId,
|
||||
'workerCount': p.workerCount,
|
||||
'startTime': toUtcTimeHHmm(startDate, p.startTime),
|
||||
'endTime': toUtcTimeHHmm(startDate, p.endTime),
|
||||
};
|
||||
}).toList();
|
||||
|
||||
return <String, dynamic>{
|
||||
'hubId': hubId,
|
||||
'eventName': eventName,
|
||||
'startDate': utcStartDate,
|
||||
'daysOfWeek': daysOfWeekList,
|
||||
'positions': positionsList,
|
||||
if (vendorId != null) 'vendorId': vendorId,
|
||||
};
|
||||
}
|
||||
|
||||
@override
|
||||
List<Object?> get props => <Object?>[
|
||||
hubId,
|
||||
|
||||
@@ -67,6 +67,53 @@ class RecurringOrderArguments extends UseCaseArgument {
|
||||
/// The selected vendor ID, if applicable.
|
||||
final String? vendorId;
|
||||
|
||||
/// Day-of-week labels in Sunday-first order, matching the V2 API convention.
|
||||
static const List<String> _dayLabels = <String>[
|
||||
'SUN',
|
||||
'MON',
|
||||
'TUE',
|
||||
'WED',
|
||||
'THU',
|
||||
'FRI',
|
||||
'SAT',
|
||||
];
|
||||
|
||||
/// Serialises these arguments into the V2 API payload shape.
|
||||
///
|
||||
/// Times and dates are converted to UTC so the backend's
|
||||
/// `combineDateAndTime` helper receives the correct values.
|
||||
Map<String, dynamic> toJson() {
|
||||
final String firstStartTime =
|
||||
positions.isNotEmpty ? positions.first.startTime : '00:00';
|
||||
final String utcStartDate = toUtcDateIso(startDate, firstStartTime);
|
||||
final String utcEndDate = toUtcDateIso(endDate, firstStartTime);
|
||||
|
||||
final List<int> recurrenceDaysList = recurringDays
|
||||
.map((String day) => _dayLabels.indexOf(day) % 7)
|
||||
.toList();
|
||||
|
||||
final List<Map<String, dynamic>> positionsList =
|
||||
positions.map((RecurringOrderPositionArgument p) {
|
||||
return <String, dynamic>{
|
||||
if (p.roleName != null) 'roleName': p.roleName,
|
||||
if (p.roleId.isNotEmpty) 'roleId': p.roleId,
|
||||
'workerCount': p.workerCount,
|
||||
'startTime': toUtcTimeHHmm(startDate, p.startTime),
|
||||
'endTime': toUtcTimeHHmm(startDate, p.endTime),
|
||||
};
|
||||
}).toList();
|
||||
|
||||
return <String, dynamic>{
|
||||
'hubId': hubId,
|
||||
'eventName': eventName,
|
||||
'startDate': utcStartDate,
|
||||
'endDate': utcEndDate,
|
||||
'recurrenceDays': recurrenceDaysList,
|
||||
'positions': positionsList,
|
||||
if (vendorId != null) 'vendorId': vendorId,
|
||||
};
|
||||
}
|
||||
|
||||
@override
|
||||
List<Object?> get props => <Object?>[
|
||||
hubId,
|
||||
|
||||
@@ -1,49 +1,19 @@
|
||||
import 'package:krow_core/core.dart';
|
||||
|
||||
import '../arguments/one_time_order_arguments.dart';
|
||||
import '../repositories/client_create_order_repository_interface.dart';
|
||||
|
||||
/// Use case for creating a one-time staffing order.
|
||||
///
|
||||
/// Builds the V2 API payload from typed [OneTimeOrderArguments] and
|
||||
/// delegates submission to the repository. Payload construction (date
|
||||
/// formatting, position mapping, break-minutes conversion) is business
|
||||
/// logic that belongs here, not in the BLoC.
|
||||
class CreateOneTimeOrderUseCase
|
||||
implements UseCase<OneTimeOrderArguments, void> {
|
||||
/// Delegates payload construction to [OneTimeOrderArguments.toJson] and
|
||||
/// submission to the repository.
|
||||
class CreateOneTimeOrderUseCase {
|
||||
/// Creates a [CreateOneTimeOrderUseCase].
|
||||
const CreateOneTimeOrderUseCase(this._repository);
|
||||
|
||||
/// The create-order repository.
|
||||
final ClientCreateOrderRepositoryInterface _repository;
|
||||
|
||||
@override
|
||||
/// Creates a one-time order from the given arguments.
|
||||
Future<void> call(OneTimeOrderArguments input) {
|
||||
final String orderDate = formatDateToIso(input.orderDate);
|
||||
|
||||
final List<Map<String, dynamic>> positions =
|
||||
input.positions.map((OneTimeOrderPositionArgument p) {
|
||||
return <String, dynamic>{
|
||||
if (p.roleName != null) 'roleName': p.roleName,
|
||||
if (p.roleId.isNotEmpty) 'roleId': p.roleId,
|
||||
'workerCount': p.workerCount,
|
||||
'startTime': p.startTime,
|
||||
'endTime': p.endTime,
|
||||
if (p.lunchBreak != null &&
|
||||
p.lunchBreak != 'NO_BREAK' &&
|
||||
p.lunchBreak!.isNotEmpty)
|
||||
'lunchBreakMinutes': breakMinutesFromLabel(p.lunchBreak!),
|
||||
};
|
||||
}).toList();
|
||||
|
||||
final Map<String, dynamic> payload = <String, dynamic>{
|
||||
'hubId': input.hubId,
|
||||
'eventName': input.eventName,
|
||||
'orderDate': orderDate,
|
||||
'positions': positions,
|
||||
if (input.vendorId != null) 'vendorId': input.vendorId,
|
||||
};
|
||||
|
||||
return _repository.createOneTimeOrder(payload);
|
||||
return _repository.createOneTimeOrder(input.toJson());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,61 +1,19 @@
|
||||
import 'package:krow_core/core.dart';
|
||||
|
||||
import '../arguments/permanent_order_arguments.dart';
|
||||
import '../repositories/client_create_order_repository_interface.dart';
|
||||
|
||||
/// Day-of-week labels in Sunday-first order, matching the V2 API convention.
|
||||
const List<String> _dayLabels = <String>[
|
||||
'SUN',
|
||||
'MON',
|
||||
'TUE',
|
||||
'WED',
|
||||
'THU',
|
||||
'FRI',
|
||||
'SAT',
|
||||
];
|
||||
|
||||
/// Use case for creating a permanent staffing order.
|
||||
///
|
||||
/// Builds the V2 API payload from typed [PermanentOrderArguments] and
|
||||
/// delegates submission to the repository. Payload construction (date
|
||||
/// formatting, day-of-week mapping, position mapping) is business
|
||||
/// logic that belongs here, not in the BLoC.
|
||||
class CreatePermanentOrderUseCase
|
||||
implements UseCase<PermanentOrderArguments, void> {
|
||||
/// Delegates payload construction to [PermanentOrderArguments.toJson] and
|
||||
/// submission to the repository.
|
||||
class CreatePermanentOrderUseCase {
|
||||
/// Creates a [CreatePermanentOrderUseCase].
|
||||
const CreatePermanentOrderUseCase(this._repository);
|
||||
|
||||
/// The create-order repository.
|
||||
final ClientCreateOrderRepositoryInterface _repository;
|
||||
|
||||
@override
|
||||
/// Creates a permanent order from the given arguments.
|
||||
Future<void> call(PermanentOrderArguments input) {
|
||||
final String startDate = formatDateToIso(input.startDate);
|
||||
|
||||
final List<int> daysOfWeek = input.daysOfWeek
|
||||
.map((String day) => _dayLabels.indexOf(day) % 7)
|
||||
.toList();
|
||||
|
||||
final List<Map<String, dynamic>> positions =
|
||||
input.positions.map((PermanentOrderPositionArgument p) {
|
||||
return <String, dynamic>{
|
||||
if (p.roleName != null) 'roleName': p.roleName,
|
||||
if (p.roleId.isNotEmpty) 'roleId': p.roleId,
|
||||
'workerCount': p.workerCount,
|
||||
'startTime': p.startTime,
|
||||
'endTime': p.endTime,
|
||||
};
|
||||
}).toList();
|
||||
|
||||
final Map<String, dynamic> payload = <String, dynamic>{
|
||||
'hubId': input.hubId,
|
||||
'eventName': input.eventName,
|
||||
'startDate': startDate,
|
||||
'daysOfWeek': daysOfWeek,
|
||||
'positions': positions,
|
||||
if (input.vendorId != null) 'vendorId': input.vendorId,
|
||||
};
|
||||
|
||||
return _repository.createPermanentOrder(payload);
|
||||
return _repository.createPermanentOrder(input.toJson());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,63 +1,19 @@
|
||||
import 'package:krow_core/core.dart';
|
||||
|
||||
import '../arguments/recurring_order_arguments.dart';
|
||||
import '../repositories/client_create_order_repository_interface.dart';
|
||||
|
||||
/// Day-of-week labels in Sunday-first order, matching the V2 API convention.
|
||||
const List<String> _dayLabels = <String>[
|
||||
'SUN',
|
||||
'MON',
|
||||
'TUE',
|
||||
'WED',
|
||||
'THU',
|
||||
'FRI',
|
||||
'SAT',
|
||||
];
|
||||
|
||||
/// Use case for creating a recurring staffing order.
|
||||
///
|
||||
/// Builds the V2 API payload from typed [RecurringOrderArguments] and
|
||||
/// delegates submission to the repository. Payload construction (date
|
||||
/// formatting, recurrence-day mapping, position mapping) is business
|
||||
/// logic that belongs here, not in the BLoC.
|
||||
class CreateRecurringOrderUseCase
|
||||
implements UseCase<RecurringOrderArguments, void> {
|
||||
/// Delegates payload construction to [RecurringOrderArguments.toJson] and
|
||||
/// submission to the repository.
|
||||
class CreateRecurringOrderUseCase {
|
||||
/// Creates a [CreateRecurringOrderUseCase].
|
||||
const CreateRecurringOrderUseCase(this._repository);
|
||||
|
||||
/// The create-order repository.
|
||||
final ClientCreateOrderRepositoryInterface _repository;
|
||||
|
||||
@override
|
||||
/// Creates a recurring order from the given arguments.
|
||||
Future<void> call(RecurringOrderArguments input) {
|
||||
final String startDate = formatDateToIso(input.startDate);
|
||||
final String endDate = formatDateToIso(input.endDate);
|
||||
|
||||
final List<int> recurrenceDays = input.recurringDays
|
||||
.map((String day) => _dayLabels.indexOf(day) % 7)
|
||||
.toList();
|
||||
|
||||
final List<Map<String, dynamic>> positions =
|
||||
input.positions.map((RecurringOrderPositionArgument p) {
|
||||
return <String, dynamic>{
|
||||
if (p.roleName != null) 'roleName': p.roleName,
|
||||
if (p.roleId.isNotEmpty) 'roleId': p.roleId,
|
||||
'workerCount': p.workerCount,
|
||||
'startTime': p.startTime,
|
||||
'endTime': p.endTime,
|
||||
};
|
||||
}).toList();
|
||||
|
||||
final Map<String, dynamic> payload = <String, dynamic>{
|
||||
'hubId': input.hubId,
|
||||
'eventName': input.eventName,
|
||||
'startDate': startDate,
|
||||
'endDate': endDate,
|
||||
'recurrenceDays': recurrenceDays,
|
||||
'positions': positions,
|
||||
if (input.vendorId != null) 'vendorId': input.vendorId,
|
||||
};
|
||||
|
||||
return _repository.createRecurringOrder(payload);
|
||||
return _repository.createRecurringOrder(input.toJson());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,8 +22,8 @@ class ViewOrdersRepositoryImpl implements ViewOrdersRepositoryInterface {
|
||||
final ApiResponse response = await _api.get(
|
||||
ClientEndpoints.ordersView,
|
||||
params: <String, dynamic>{
|
||||
'startDate': start.toIso8601String(),
|
||||
'endDate': end.toIso8601String(),
|
||||
'startDate': start.toUtc().toIso8601String(),
|
||||
'endDate': end.toUtc().toIso8601String(),
|
||||
},
|
||||
);
|
||||
final Map<String, dynamic> data = response.data as Map<String, dynamic>;
|
||||
|
||||
@@ -36,8 +36,8 @@ class ShiftsRepositoryImpl implements ShiftsRepositoryInterface {
|
||||
final ApiResponse response = await _apiService.get(
|
||||
StaffEndpoints.shiftsAssigned,
|
||||
params: <String, dynamic>{
|
||||
'startDate': start.toIso8601String(),
|
||||
'endDate': end.toIso8601String(),
|
||||
'startDate': start.toUtc().toIso8601String(),
|
||||
'endDate': end.toUtc().toIso8601String(),
|
||||
},
|
||||
);
|
||||
final List<dynamic> items = _extractItems(response.data);
|
||||
|
||||
Reference in New Issue
Block a user