Files
Holzleitner-Lieferservice-App/lib/feature/delivery/detail/bloc/delivery_bloc.dart
2025-11-04 16:52:39 +01:00

356 lines
10 KiB
Dart

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<DeliveryEvent, DeliveryState> {
OperationBloc opBloc;
DeliveryRepository repository;
NoteRepository noteRepository;
DeliveryBloc({
required this.opBloc,
required this.repository,
required this.noteRepository,
}) : super(DeliveryInitial()) {
on<UnscanArticleEvent>(_unscan);
on<ResetScanAmountEvent>(_resetAmount);
on<LoadDeliveryEvent>(_load);
on<AddDiscountEvent>(_addDiscount);
on<RemoveDiscountEvent>(_removeDiscount);
on<UpdateDiscountEvent>(_updateDiscount);
on<UpdateDeliveryOptionEvent>(_updateDeliveryOptions);
on<UpdateSelectedPaymentMethodEvent>(_updatePayment);
on<FinishDeliveryEvent>(_finishDelivery);
}
void _finishDelivery(
FinishDeliveryEvent event,
Emitter<DeliveryState> 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<DeliveryState> emit,
) {
final currentState = state;
if (currentState is DeliveryLoaded) {
emit(
DeliveryLoaded(
delivery: currentState.delivery.copyWith(payment: event.payment),
),
);
}
}
void _updateDeliveryOptions(
UpdateDeliveryOptionEvent event,
Emitter<DeliveryState> emit,
) {
final currentState = state;
if (currentState is DeliveryLoaded) {
List<model.DeliveryOption> 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<DeliveryState> 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<DeliveryState> 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<DeliveryState> 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<DeliveryState> emit) async {
debugPrint("Discount; ${event.delivery.discount?.note}");
emit(DeliveryLoaded(delivery: event.delivery));
}
void _unscan(UnscanArticleEvent event, Emitter<DeliveryState> 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<Article> 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<DeliveryState> 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<Article> 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"));
}
}
}