436 lines
12 KiB
Dart
436 lines
12 KiB
Dart
import 'dart:async';
|
|
|
|
import 'package:flutter/material.dart';
|
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
|
import 'package:hl_lieferservice/feature/delivery/overview/bloc/tour_event.dart';
|
|
import 'package:hl_lieferservice/feature/delivery/overview/bloc/tour_state.dart';
|
|
import 'package:hl_lieferservice/feature/delivery/overview/repository/tour_repository.dart';
|
|
import 'package:hl_lieferservice/feature/delivery/overview/service/distance_service.dart';
|
|
import 'package:hl_lieferservice/model/tour.dart';
|
|
import 'package:hl_lieferservice/widget/operations/bloc/operation_bloc.dart';
|
|
import 'package:hl_lieferservice/widget/operations/bloc/operation_event.dart';
|
|
import 'package:rxdart/rxdart.dart';
|
|
|
|
class TourBloc extends Bloc<TourEvent, TourState> {
|
|
OperationBloc opBloc;
|
|
TourRepository tourRepository;
|
|
StreamSubscription? _combinedSubscription;
|
|
|
|
TourBloc({required this.opBloc, required this.tourRepository})
|
|
: super(TourInitial()) {
|
|
_combinedSubscription = CombineLatestStream.combine2(
|
|
tourRepository.tour,
|
|
tourRepository.paymentOptions,
|
|
(tour, payments) => {'tour': tour, 'payments': payments},
|
|
).listen((combined) {
|
|
final tour = combined['tour'] as Tour?;
|
|
final payments = combined['payments'] as List<Payment>;
|
|
|
|
if (tour == null) {
|
|
return;
|
|
}
|
|
|
|
add(TourUpdated(tour: tour, payments: payments));
|
|
});
|
|
|
|
on<LoadTour>(_load);
|
|
on<AssignCarEvent>(_assignCar);
|
|
on<IncrementArticleScanAmount>(_increment);
|
|
on<ScanArticleEvent>(_scan);
|
|
on<HoldDeliveryEvent>(_holdDelivery);
|
|
on<CancelDeliveryEvent>(_cancelDelivery);
|
|
on<ReactivateDeliveryEvent>(_reactivateDelivery);
|
|
on<UnscanArticleEvent>(_unscan);
|
|
on<ResetScanAmountEvent>(_resetAmount);
|
|
on<AddDiscountEvent>(_addDiscount);
|
|
on<RemoveDiscountEvent>(_removeDiscount);
|
|
on<UpdateDiscountEvent>(_updateDiscount);
|
|
on<UpdateDeliveryOptionEvent>(_updateDeliveryOptions);
|
|
on<UpdateSelectedPaymentMethodEvent>(_updatePayment);
|
|
on<FinishDeliveryEvent>(_finishDelivery);
|
|
on<TourUpdated>(_updated);
|
|
on<RequestDeliveryDistanceEvent>(_calculateDistances);
|
|
}
|
|
|
|
@override
|
|
Future<void> close() {
|
|
_combinedSubscription?.cancel();
|
|
|
|
return super.close();
|
|
}
|
|
|
|
void _calculateDistances(
|
|
RequestDeliveryDistanceEvent event,
|
|
Emitter<TourState> emit,
|
|
) async {
|
|
Map<String, double> distances = {};
|
|
opBloc.add(LoadOperation());
|
|
emit(TourRequestingDistances(tour: event.tour, payments: event.payments));
|
|
|
|
try {
|
|
for (final delivery in event.tour.deliveries) {
|
|
distances[delivery.id] = await DistanceService.getDistanceByRoad(
|
|
delivery.customer.address.toString(),
|
|
);
|
|
}
|
|
|
|
opBloc.add(FinishOperation());
|
|
} catch (e) {
|
|
debugPrint("Fehler beim Berechnen der Distanzen: $e");
|
|
opBloc.add(FailOperation(message: "Fehler beim Berechnen der Distanzen"));
|
|
return;
|
|
}
|
|
|
|
emit(
|
|
TourLoaded(
|
|
tour: event.tour,
|
|
paymentOptions: event.payments,
|
|
distances: distances,
|
|
),
|
|
);
|
|
}
|
|
|
|
void _updated(TourUpdated event, Emitter<TourState> emit) {
|
|
final currentState = state;
|
|
final tour = event.tour.copyWith();
|
|
final payments =
|
|
event.payments.map((payment) => payment.copyWith()).toList();
|
|
|
|
if (currentState is TourLoaded) {
|
|
debugPrint("TEST UPDATE");
|
|
emit(
|
|
TourLoaded(
|
|
tour: tour,
|
|
paymentOptions: payments,
|
|
distances: Map<String, double>.from(currentState.distances ?? {}),
|
|
),
|
|
);
|
|
}
|
|
|
|
if (currentState is TourLoading) {
|
|
add(
|
|
RequestDeliveryDistanceEvent(tour: tour.copyWith(), payments: payments),
|
|
);
|
|
}
|
|
}
|
|
|
|
void _reactivateDelivery(
|
|
ReactivateDeliveryEvent event,
|
|
Emitter<TourState> emit,
|
|
) async {
|
|
final currentState = state;
|
|
if (currentState is TourLoaded) {
|
|
opBloc.add(LoadOperation());
|
|
try {
|
|
await tourRepository.reactivateDelivery(event.deliveryId);
|
|
|
|
opBloc.add(FinishOperation());
|
|
} catch (e, st) {
|
|
debugPrint("$e");
|
|
debugPrint("$st");
|
|
opBloc.add(
|
|
FailOperation(message: "Fehler beim Zurückstellen der Lieferung"),
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
void _holdDelivery(HoldDeliveryEvent event, Emitter<TourState> emit) async {
|
|
final currentState = state;
|
|
if (currentState is TourLoaded) {
|
|
opBloc.add(LoadOperation());
|
|
try {
|
|
await tourRepository.holdDelivery(event.deliveryId);
|
|
|
|
opBloc.add(FinishOperation());
|
|
} catch (e, st) {
|
|
debugPrint("$e");
|
|
debugPrint("$st");
|
|
opBloc.add(
|
|
FailOperation(message: "Fehler beim Zurückstellen der Lieferung"),
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
void _cancelDelivery(
|
|
CancelDeliveryEvent event,
|
|
Emitter<TourState> emit,
|
|
) async {
|
|
final currentState = state;
|
|
if (currentState is TourLoaded) {
|
|
opBloc.add(LoadOperation());
|
|
try {
|
|
await tourRepository.cancelDelivery(event.deliveryId);
|
|
|
|
opBloc.add(FinishOperation());
|
|
} catch (e, st) {
|
|
debugPrint("$e");
|
|
debugPrint("$st");
|
|
opBloc.add(
|
|
FailOperation(message: "Fehler beim Zurückstellen der Lieferung"),
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
void _scan(ScanArticleEvent event, Emitter<TourState> emit) async {
|
|
final currentState = state;
|
|
opBloc.add(LoadOperation());
|
|
|
|
if (currentState is TourLoaded) {
|
|
try {
|
|
switch (await tourRepository.scanArticle(
|
|
event.deliveryId,
|
|
event.carId,
|
|
event.articleNumber,
|
|
)) {
|
|
case ScanResult.scanned:
|
|
opBloc.add(FinishOperation(message: 'Artikel gescannt'));
|
|
break;
|
|
case ScanResult.alreadyScanned:
|
|
opBloc.add(
|
|
FailOperation(message: 'Artikel wurde bereits gescannt'),
|
|
);
|
|
break;
|
|
case ScanResult.notFound:
|
|
opBloc.add(
|
|
FailOperation(
|
|
message: 'Artikel ist für keine Lieferung vorgesehen',
|
|
),
|
|
);
|
|
break;
|
|
}
|
|
} on TourNotFoundException catch (e) {
|
|
opBloc.add(FailOperation(message: "Fehler beim Scannen des Artikels"));
|
|
}
|
|
}
|
|
}
|
|
|
|
Future<void> _increment(
|
|
IncrementArticleScanAmount event,
|
|
Emitter<TourState> emit,
|
|
) async {
|
|
final currentState = state;
|
|
|
|
if (currentState is TourLoaded) {
|
|
opBloc.add(LoadOperation());
|
|
try {
|
|
await tourRepository.scanArticle(
|
|
event.deliveryId,
|
|
event.carId,
|
|
event.internalArticleId,
|
|
);
|
|
opBloc.add(FinishOperation());
|
|
} catch (e, st) {
|
|
debugPrint(st.toString());
|
|
opBloc.add(FailOperation(message: "Fehler beim Scannen des Artikels"));
|
|
}
|
|
}
|
|
}
|
|
|
|
Future<void> _assignCar(AssignCarEvent event, Emitter<TourState> emit) async {
|
|
final currentState = state;
|
|
if (currentState is TourLoaded) {
|
|
opBloc.add(LoadOperation());
|
|
try {
|
|
await tourRepository.assignCar(event.deliveryId, event.carId);
|
|
opBloc.add(FinishOperation());
|
|
} catch (e, st) {
|
|
debugPrint(st.toString());
|
|
opBloc.add(
|
|
FailOperation(message: "Fehler beim Zuweisen des Fahrzeugs"),
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
Future<void> _load(LoadTour event, Emitter<TourState> emit) async {
|
|
opBloc.add(LoadOperation());
|
|
try {
|
|
emit(TourLoading());
|
|
await tourRepository.loadTourOfToday(event.teamId);
|
|
await tourRepository.loadPaymentOptions();
|
|
|
|
opBloc.add(FinishOperation());
|
|
} catch (e) {
|
|
opBloc.add(
|
|
FailOperation(message: "Fehler beim Laden der heutigen Fahrten"),
|
|
);
|
|
}
|
|
}
|
|
|
|
void _finishDelivery(
|
|
FinishDeliveryEvent event,
|
|
Emitter<TourState> emit,
|
|
) async {
|
|
final currentState = state;
|
|
opBloc.add(LoadOperation());
|
|
|
|
if (currentState is TourLoaded) {
|
|
try {
|
|
await tourRepository.uploadDriverSignature(
|
|
event.deliveryId,
|
|
event.driverSignature,
|
|
);
|
|
await tourRepository.uploadCustomerSignature(
|
|
event.deliveryId,
|
|
event.customerSignature,
|
|
);
|
|
|
|
await tourRepository.finishDelivery(event.deliveryId);
|
|
|
|
opBloc.add(FinishOperation());
|
|
} catch (e, st) {
|
|
opBloc.add(FailOperation(message: "Failed to update delivery"));
|
|
debugPrint(st.toString());
|
|
}
|
|
}
|
|
}
|
|
|
|
void _updatePayment(
|
|
UpdateSelectedPaymentMethodEvent event,
|
|
Emitter<TourState> emit,
|
|
) async {
|
|
try {
|
|
opBloc.add(LoadOperation());
|
|
await tourRepository.updatePayment(event.deliveryId, event.payment);
|
|
opBloc.add(FinishOperation());
|
|
} catch (e, st) {
|
|
debugPrint(st.toString());
|
|
opBloc.add(
|
|
FailOperation(message: "Fehler beim Aktualisieren des Betrags"),
|
|
);
|
|
}
|
|
}
|
|
|
|
void _updateDeliveryOptions(
|
|
UpdateDeliveryOptionEvent event,
|
|
Emitter<TourState> emit,
|
|
) async {
|
|
try {
|
|
opBloc.add(LoadOperation());
|
|
await tourRepository.updateOption(
|
|
event.deliveryId,
|
|
event.key,
|
|
event.value,
|
|
);
|
|
opBloc.add(FinishOperation());
|
|
} catch (e, st) {
|
|
debugPrint("$st");
|
|
opBloc.add(
|
|
FailOperation(message: "Fehler beim Aktualisieren der Optionen"),
|
|
);
|
|
}
|
|
}
|
|
|
|
void _updateDiscount(
|
|
UpdateDiscountEvent event,
|
|
Emitter<TourState> emit,
|
|
) async {
|
|
opBloc.add(LoadOperation());
|
|
|
|
try {
|
|
opBloc.add(FinishOperation());
|
|
await tourRepository.updateDiscount(
|
|
event.deliveryId,
|
|
event.reason,
|
|
event.value,
|
|
);
|
|
opBloc.add(FinishOperation());
|
|
} catch (e, st) {
|
|
debugPrint(
|
|
"Fehler beim Hinzufügen eins Discounts zur Lieferung: ${event.deliveryId}:",
|
|
);
|
|
debugPrint("$e");
|
|
debugPrint("$st");
|
|
|
|
opBloc.add(
|
|
FailOperation(message: "Fehler beim Hinzufügen des Discounts: $e"),
|
|
);
|
|
}
|
|
}
|
|
|
|
void _removeDiscount(
|
|
RemoveDiscountEvent event,
|
|
Emitter<TourState> emit,
|
|
) async {
|
|
opBloc.add(LoadOperation());
|
|
|
|
try {
|
|
await tourRepository.removeDiscount(event.deliveryId);
|
|
opBloc.add(FinishOperation());
|
|
} catch (e, st) {
|
|
debugPrint(
|
|
"Fehler beim Löschen des Discounts der Lieferung: ${event.deliveryId}:",
|
|
);
|
|
debugPrint("$e");
|
|
debugPrint("$st");
|
|
|
|
opBloc.add(
|
|
FailOperation(message: "Fehler beim Löschen des Discounts: $e"),
|
|
);
|
|
}
|
|
}
|
|
|
|
void _addDiscount(AddDiscountEvent event, Emitter<TourState> emit) async {
|
|
opBloc.add(LoadOperation());
|
|
|
|
try {
|
|
await tourRepository.addDiscount(
|
|
event.deliveryId,
|
|
event.reason,
|
|
event.value,
|
|
);
|
|
|
|
opBloc.add(FinishOperation());
|
|
} catch (e, st) {
|
|
debugPrint(
|
|
"Fehler beim Hinzufügen eins Discounts zur Lieferung: ${event.deliveryId}:",
|
|
);
|
|
debugPrint("$e");
|
|
debugPrint("$st");
|
|
|
|
opBloc.add(
|
|
FailOperation(message: "Fehler beim Hinzufügen des Discounts: $e"),
|
|
);
|
|
}
|
|
}
|
|
|
|
void _unscan(UnscanArticleEvent event, Emitter<TourState> emit) async {
|
|
opBloc.add(LoadOperation());
|
|
|
|
try {
|
|
await tourRepository.unscan(
|
|
event.deliveryId,
|
|
event.articleId,
|
|
event.newAmount,
|
|
event.reason,
|
|
);
|
|
opBloc.add(FinishOperation());
|
|
} catch (e, st) {
|
|
debugPrint("Fehler beim Unscan des Artikels: ${event.articleId}:");
|
|
debugPrint("$e");
|
|
debugPrint("$st");
|
|
|
|
opBloc.add(FailOperation(message: "Fehler beim Unscan des Artikels: $e"));
|
|
}
|
|
}
|
|
|
|
void _resetAmount(ResetScanAmountEvent event, Emitter<TourState> emit) async {
|
|
opBloc.add(LoadOperation());
|
|
|
|
try {
|
|
await tourRepository.resetScan(event.articleId, event.deliveryId);
|
|
|
|
opBloc.add(FinishOperation());
|
|
} catch (e, st) {
|
|
debugPrint("Fehler beim Unscan des Artikels: ${event.articleId}:");
|
|
debugPrint("$e");
|
|
debugPrint("$st");
|
|
|
|
opBloc.add(FailOperation(message: "Fehler beim Zurücksetzen: $e"));
|
|
}
|
|
}
|
|
}
|