import 'package:flutter/cupertino.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/delivery.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'; class TourBloc extends Bloc { OperationBloc opBloc; TourRepository tourRepository; TourBloc({required this.opBloc, required this.tourRepository}) : super(TourInitial()) { on(_load); on(_update); on(_assignCar); on(_increment); on(_scan); on(_holdDelivery); on(_cancelDelivery); on(_reactiveateDelivery); } void _reactiveateDelivery( ReactivateDeliveryEvent event, Emitter emit, ) async { final currentState = state; if (currentState is TourLoaded) { opBloc.add(LoadOperation()); try { Tour tourCopied = currentState.tour.copyWith(); Delivery delivery = tourCopied.deliveries.firstWhere((delivery) => delivery.id == event.deliveryId); delivery.state = DeliveryState.ongoing; await tourRepository.updateDelivery( delivery, ); opBloc.add(FinishOperation()); emit(TourLoaded(tour: tourCopied, distances: currentState.distances)); } catch (e, st) { debugPrint("$e"); debugPrint("$st"); opBloc.add( FailOperation(message: "Fehler beim Zurückstellen der Lieferung"), ); } } } void _holdDelivery( HoldDeliveryEvent event, Emitter emit, ) async { final currentState = state; if (currentState is TourLoaded) { opBloc.add(LoadOperation()); try { Tour tourCopied = currentState.tour.copyWith(); Delivery delivery = tourCopied.deliveries.firstWhere((delivery) => delivery.id == event.deliveryId); delivery.state = DeliveryState.onhold; await tourRepository.updateDelivery( delivery, ); opBloc.add(FinishOperation()); emit(TourLoaded(tour: tourCopied, distances: currentState.distances)); } catch (e, st) { debugPrint("$e"); debugPrint("$st"); opBloc.add( FailOperation(message: "Fehler beim Zurückstellen der Lieferung"), ); } } } void _cancelDelivery(CancelDeliveryEvent event, Emitter emit) async { final currentState = state; if (currentState is TourLoaded) { opBloc.add(LoadOperation()); try { Tour tourCopied = currentState.tour.copyWith(); Delivery delivery = tourCopied.deliveries.firstWhere((delivery) => delivery.id == event.deliveryId); delivery.state = DeliveryState.canceled; await tourRepository.updateDelivery( delivery, ); opBloc.add(FinishOperation()); emit(TourLoaded(tour: tourCopied, distances: currentState.distances)); } catch (e, st) { debugPrint("$e"); debugPrint("$st"); opBloc.add( FailOperation(message: "Fehler beim Zurückstellen der Lieferung"), ); } } } void _scan(ScanArticleEvent event, Emitter emit) async { final currentState = state; opBloc.add(LoadOperation()); if (currentState is TourLoaded) { try { if (currentState.tour.deliveries.any( (delivery) => delivery.articles.any( (article) => article.articleNumber == event.articleNumber, ), )) { var tourCopied = currentState.tour.copyWith(); var delivery = tourCopied.deliveries.firstWhere( (delivery) => delivery.id == event.deliveryId, ); var article = delivery.articles.firstWhere( (article) => article.articleNumber == event.articleNumber, ); await tourRepository.scanArticle(article.internalId.toString()); if (article.scannedAmount < article.amount) { article.scannedAmount += 1; emit(TourLoaded(tour: tourCopied, distances: currentState.distances)); opBloc.add(FinishOperation(message: '${article.name} gescannt')); } else { opBloc.add( FailOperation( message: 'Alle ${article.name} wurden bereits gescannt', ), ); } } else { opBloc.add( FailOperation( message: 'Fehler: Artikel ist für keine Lieferung vorgesehen', ), ); } } catch (e, st) { debugPrint(st.toString()); opBloc.add(FailOperation(message: "Fehler beim Scannnen des Artikels")); } } } Future _update(UpdateTour event, Emitter emit) async { final currentState = state; if (currentState is TourLoaded) { emit(TourLoaded(tour: event.tour, distances: currentState.distances)); } } Future _increment( IncrementArticleScanAmount event, Emitter emit, ) async { final currentState = state; if (currentState is TourLoaded) { var deliveryCopied = currentState.tour.deliveries.firstWhere( (delivery) => delivery.id == event.deliveryId, ); var articleCopied = deliveryCopied.articles.firstWhere( (article) => article.internalId == int.parse(event.internalArticleId), ); articleCopied.scannedAmount += 1; emit( TourLoaded( tour: currentState.tour.copyWith( deliveries: currentState.tour.deliveries.map((delivery) { if (delivery.id == event.deliveryId) { return deliveryCopied; } return delivery; }).toList(), ), distances: currentState.distances ), ); } } Future _assignCar(AssignCarEvent event, Emitter emit) async { final currentState = state; if (currentState is TourLoaded) { opBloc.add(LoadOperation()); var copiedTour = currentState.tour.copyWith(); var delivery = copiedTour.deliveries.firstWhere( (delivery) => delivery.id == event.deliveryId, ); try { await tourRepository.assignCar(event.deliveryId, event.carId); delivery.carId = int.parse(event.carId); emit( TourLoaded( tour: copiedTour.copyWith( deliveries: copiedTour.deliveries.map((d) { if (d.id == delivery.id) { return delivery; } return d; }).toList(), ), distances: currentState.distances ), ); opBloc.add(FinishOperation()); } catch (e, st) { debugPrint(st.toString()); opBloc.add( FailOperation(message: "Fehler beim Zuweisen des Fahrzeugs"), ); } } } Future _load(LoadTour event, Emitter emit) async { opBloc.add(LoadOperation()); try { Tour tour = await tourRepository.loadAll(event.teamId); List payments = await tourRepository.loadPaymentOptions(); tour.paymentMethods = payments; Map distances = {}; for (final delivery in tour.deliveries) { distances[delivery.id] = await DistanceService.getDistanceByRoad(delivery.customer.address.toString()); } emit(TourLoaded(tour: tour, distances: distances)); opBloc.add(FinishOperation()); } catch (e) { opBloc.add( FailOperation(message: "Fehler beim Laden der heutigen Fahrten"), ); } } }