Files
prosappco/lib/blocs/service_bloc/service_bloc.dart
T
2024-04-07 18:03:51 -05:00

251 lines
7.5 KiB
Dart

import 'dart:developer';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:equatable/equatable.dart';
import 'package:professional_repository/professional_repository.dart';
import 'package:service_repository/service_repository.dart';
import 'package:user_repository/user_repository.dart';
part 'service_event.dart';
part 'service_state.dart';
class ServiceBloc extends Bloc<ServiceEvent, ServiceState> {
final FirebaseServiceRepository _serviceRepository;
final UserRepository _userRepository;
final FirebaseProfessionalRepository _professionalRepository;
ServiceBloc({
required FirebaseServiceRepository serviceRepository,
required UserRepository userRepository,
required FirebaseProfessionalRepository professionRepository,
}) : _serviceRepository = serviceRepository,
_userRepository = userRepository,
_professionalRepository = professionRepository,
super(CreateServiceInitial()) {
on<CreateService>(_onCreateService);
on<LoadService>(_onLoadService);
on<UpdateServiceStatus>(_onUpdateServiceStatus);
on<LoadServicesForUser>(_onLoadServicesForUser);
on<LoadServicesForProfessional>(_onLoadServicesForProfessional);
on<LoadServicesHistoryForUser>(_onLoadServicesHistoryForUser);
on<LoadServicesHistoryForProfessional>(
_onLoadServicesHistoryForProfessional);
}
void _onCreateService(CreateService event, Emitter<ServiceState> emit) async {
try {
emit(CreateServiceLoading());
ServiceEntity service = ServiceEntity(
professionalId: event.professionalId,
professionalScored: false,
userId: event.userId,
userScored: false,
address: event.address,
aditionalAddress: event.aditionalAddress,
latitude: event.latitude,
longitude: event.longitude,
day: event.day,
createdAt: event.createdAt,
description: event.description,
range1Hour1: event.range1Hour1,
range1Hour2: event.range1Hour2,
rate: event.rate,
status: ServiceStatus.pending,
location: event.location,
);
String serviceId = await _serviceRepository.createService(service);
emit(CreateServiceSuccess(serviceId));
} catch (e) {
log(e.toString());
emit(CreateServiceFailure());
}
}
void _onLoadService(LoadService event, Emitter<ServiceState> emit) async {
try {
final serviceStream = _serviceRepository.getService(event.serviceId);
await for (var service in serviceStream) {
emit(ServiceLoaded(service));
}
} catch (e) {
log(e.toString());
emit(CreateServiceFailure());
}
}
void _onLoadServicesHistoryForUser(
LoadServicesHistoryForUser event, Emitter<ServiceState> emit) async {
try {
final servicesStream =
_serviceRepository.getServicesHistoryForUser(event.userId);
await for (var services in servicesStream) {
if (services.isEmpty) {
emit(const ServicesForUserLoaded([]));
return;
}
final professionalIds = services.map((e) => e.professionalId);
final List<MyUser> users =
await _userRepository.getUsersFromIds(professionalIds);
final usersDir = {for (var e in users) e.id: e};
final List<ProfessionalEntity> professionsList =
await _professionalRepository
.getProfessionalsFromIds(professionalIds);
final professionsDir = {for (var e in professionsList) e.id: e};
final servicesInfo = services.map((e) {
return ServiceInfoUI(
service: e,
user: usersDir[e.professionalId]!,
professional: professionsDir[e.professionalId]!);
}).toList();
emit(ServicesForUserLoaded(servicesInfo));
}
} catch (e) {
log(e.toString());
emit(CreateServiceFailure());
}
}
void _onLoadServicesHistoryForProfessional(
LoadServicesHistoryForProfessional event,
Emitter<ServiceState> emit) async {
try {
final servicesStream =
_serviceRepository.getServicesHistoryForProfessional(event.userId);
await for (var services in servicesStream) {
if (services.isEmpty) {
emit(const ServicesForUserLoaded([]));
return;
}
final userIds = services.map((e) => e.userId);
final List<MyUser> users =
await _userRepository.getUsersFromIds(userIds);
final usersDir = {for (var e in users) e.id: e};
final servicesInfo = services.map((e) {
return ServiceInfoUI(
service: e,
user: usersDir[e.userId]!,
);
}).toList();
emit(ServicesForUserLoaded(servicesInfo));
}
} catch (e) {
log(e.toString());
emit(CreateServiceFailure());
}
}
void _onLoadServicesForUser(
LoadServicesForUser event, Emitter<ServiceState> emit) async {
try {
final servicesStream =
_serviceRepository.getServicesForUser(event.userId);
await for (var services in servicesStream) {
if (services.isEmpty) {
emit(const ServicesForUserLoaded([]));
return;
}
final professionalIds = services.map((e) => e.professionalId);
final List<MyUser> users =
await _userRepository.getUsersFromIds(professionalIds);
final usersDir = {for (var e in users) e.id: e};
final List<ProfessionalEntity> professionsList =
await _professionalRepository
.getProfessionalsFromIds(professionalIds);
final professionsDir = {for (var e in professionsList) e.id: e};
final servicesInfo = services.map((e) {
return ServiceInfoUI(
service: e,
user: usersDir[e.professionalId]!,
professional: professionsDir[e.professionalId]!);
}).toList();
emit(ServicesForUserLoaded(servicesInfo));
}
} catch (e) {
log(e.toString());
emit(CreateServiceFailure());
}
}
void _onLoadServicesForProfessional(
LoadServicesForProfessional event, Emitter<ServiceState> emit) async {
try {
final servicesStream =
_serviceRepository.getServicesForProfessional(event.userId);
await for (var services in servicesStream) {
if (services.isEmpty) {
emit(const ServicesForUserLoaded([]));
return;
}
final userIds = services.map((e) => e.userId);
final List<MyUser> users =
await _userRepository.getUsersFromIds(userIds);
final usersDir = {for (var e in users) e.id: e};
final servicesInfo = services.map((e) {
return ServiceInfoUI(
service: e,
user: usersDir[e.userId]!,
);
}).toList();
emit(ServicesForUserLoaded(servicesInfo));
}
} catch (e) {
log(e.toString());
emit(CreateServiceFailure());
}
}
void _onUpdateServiceStatus(
UpdateServiceStatus event, Emitter<ServiceState> emit) async {
try {
emit(CreateServiceLoading());
await _serviceRepository.updateServiceStatus(
event.serviceId, event.newStatus);
emit(ServiceStatusUpdated(event.newStatus));
} catch (e) {
log(e.toString());
emit(CreateServiceFailure());
}
}
}
class ServiceInfoUI {
final ServiceEntity service;
final MyUser user;
final ProfessionalEntity? professional;
ServiceInfoUI({
required this.service,
required this.user,
this.professional,
});
}