import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:hl_lieferservice/dto/discount_add_response.dart'; import 'package:hl_lieferservice/dto/discount_update_response.dart'; import 'package:hl_lieferservice/feature/delivery/detail/bloc/delivery_event.dart'; import 'package:hl_lieferservice/feature/delivery/detail/bloc/delivery_state.dart'; import 'package:hl_lieferservice/feature/delivery/detail/repository/delivery_repository.dart'; import 'package:hl_lieferservice/feature/delivery/detail/repository/note_repository.dart'; import 'package:hl_lieferservice/widget/operations/bloc/operation_bloc.dart'; import 'package:hl_lieferservice/widget/operations/bloc/operation_event.dart'; import '../../../../dto/discount_remove_response.dart'; import '../../../../model/article.dart'; import '../../../../model/delivery.dart' as model; class DeliveryBloc extends Bloc { OperationBloc opBloc; DeliveryRepository repository; NoteRepository noteRepository; DeliveryBloc({ required this.opBloc, required this.repository, required this.noteRepository, }) : super(DeliveryInitial()) { on(_unscan); on(_resetAmount); on(_load); on(_addDiscount); on(_removeDiscount); on(_updateDiscount); on(_updateDeliveryOptions); on(_updatePayment); on(_finishDelivery); } void _finishDelivery( FinishDeliveryEvent event, Emitter emit, ) async { final currentState = state; opBloc.add(LoadOperation()); if (currentState is DeliveryLoaded) { try { model.Delivery newDelivery = event.delivery.copyWith(); newDelivery.state = model.DeliveryState.finished; for (final option in event.delivery.options) { debugPrint("VALUE=${option.value};KEY=${option.key}"); } await repository.updateDelivery(newDelivery); await noteRepository.addNamedImage( event.delivery.id, event.driverSignature, "delivery_${event.delivery.id}_signature_driver.jpg", ); await noteRepository.addNamedImage( event.delivery.id, event.customerSignature, "delivery_${event.delivery.id}_signature_customer.jpg", ); emit(DeliveryFinished(delivery: newDelivery)); opBloc.add(FinishOperation()); } catch (e, st) { opBloc.add(FailOperation(message: "Failed to update delivery")); debugPrint(st.toString()); } } } void _updatePayment( UpdateSelectedPaymentMethodEvent event, Emitter emit, ) { final currentState = state; if (currentState is DeliveryLoaded) { emit( DeliveryLoaded( delivery: currentState.delivery.copyWith(payment: event.payment), ), ); } } void _updateDeliveryOptions( UpdateDeliveryOptionEvent event, Emitter emit, ) { final currentState = state; if (currentState is DeliveryLoaded) { List options = currentState.delivery.options.map((option) { if (option.key == event.key) { if (option.numerical) { return option.copyWith(value: event.value); } else { return option.copyWith(value: event.value == true ? "1" : "0"); } } return option; }).toList(); emit( DeliveryLoaded( delivery: currentState.delivery.copyWith(options: options), ), ); } } void _updateDiscount( UpdateDiscountEvent event, Emitter emit, ) async { opBloc.add(LoadOperation()); try { final currentState = state; if (currentState is DeliveryLoaded) { DiscountUpdateResponseDTO response = await repository.updateDiscount( event.deliveryId, event.reason, event.value, ); model.Delivery delivery = currentState.delivery; if (response.values?.receipt != null) { delivery.totalNetValue = response.values!.receipt.net; delivery.totalGrossValue = response.values!.receipt.gross; } String discountArticleNumber = delivery.discount!.article.articleNumber; delivery.discount = model.Discount( article: response.values?.article != null ? Article.fromDTO(response.values!.article) : delivery.discount!.article, note: response.values?.note != null ? response.values!.note.noteDescription : delivery.discount!.note, noteId: response.values?.note != null ? response.values!.note.rowId : delivery.discount!.noteId, ); delivery.articles = [ ...delivery.articles.where( (article) => article.articleNumber != discountArticleNumber, ), delivery.discount!.article, ]; emit(currentState.copyWith(delivery)); 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 emit, ) async { opBloc.add(LoadOperation()); try { final currentState = state; if (currentState is DeliveryLoaded) { model.Delivery delivery = currentState.delivery; DiscountRemoveResponseDTO response = await repository.removeDiscount( event.deliveryId, ); delivery.articles = delivery.articles .where( (article) => article.internalId != delivery.discount?.article.internalId, ) .toList(); delivery.discount = null; delivery.totalGrossValue = response.receipt.gross; delivery.totalNetValue = response.receipt.net; emit(currentState.copyWith(delivery)); 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 emit) async { opBloc.add(LoadOperation()); try { final currentState = state; if (currentState is DeliveryLoaded) { DiscountAddResponseDTO response = await repository.addDiscount( event.deliveryId, event.reason, event.value, ); model.Delivery delivery = currentState.delivery; delivery.totalNetValue = response.values.receipt.net; delivery.totalGrossValue = response.values.receipt.gross; delivery.discount = model.Discount( article: Article.fromDTO(response.values.article), note: response.values.note.noteDescription, noteId: response.values.note.rowId, ); delivery.articles = [...delivery.articles, delivery.discount!.article]; emit(currentState.copyWith(delivery)); 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 _load(LoadDeliveryEvent event, Emitter emit) async { debugPrint("Discount; ${event.delivery.discount?.note}"); emit(DeliveryLoaded(delivery: event.delivery)); } void _unscan(UnscanArticleEvent event, Emitter emit) async { opBloc.add(LoadOperation()); try { String? noteId = await repository.unscan( event.articleId, event.newAmount, event.reason, ); if (noteId != null) { final currentState = state; if (currentState is DeliveryLoaded) { Article article = currentState.delivery.articles.firstWhere( (article) => article.internalId == int.parse(event.articleId), ); article.removeNoteId = noteId; article.scannedRemovedAmount += event.newAmount; article.scannedAmount -= event.newAmount; List
articles = [ ...currentState.delivery.articles.where( (article) => article.internalId != int.parse(event.articleId), ), article, ]; currentState.delivery.articles = articles; emit.call(currentState.copyWith(currentState.delivery)); } } 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 emit, ) async { opBloc.add(LoadOperation()); try { final currentState = state; await repository.resetScan(event.articleId); if (currentState is DeliveryLoaded) { Article article = currentState.delivery.articles.firstWhere( (article) => article.internalId == int.parse(event.articleId), ); article.removeNoteId = null; article.scannedRemovedAmount = 0; article.scannedAmount = article.amount; List
articles = [ ...currentState.delivery.articles.where( (article) => article.internalId != int.parse(event.articleId), ), article, ]; currentState.delivery.articles = articles; emit.call(currentState.copyWith(currentState.delivery)); } 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")); } } }