2026-04-16 11:50:29 +02:00
|
|
|
import 'package:equatable/equatable.dart';
|
|
|
|
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
2026-04-17 10:34:23 +02:00
|
|
|
import 'package:flux/core/blocs/session/session_bloc.dart';
|
2026-04-16 11:50:29 +02:00
|
|
|
import 'package:flux/features/master_data/providers/data/provider_repository.dart';
|
2026-04-17 10:34:23 +02:00
|
|
|
import 'package:flux/features/master_data/store/models/store_model.dart';
|
2026-04-16 11:50:29 +02:00
|
|
|
import 'package:get_it/get_it.dart';
|
|
|
|
|
import '../models/provider_model.dart';
|
|
|
|
|
|
|
|
|
|
class ProvidersState extends Equatable {
|
2026-04-20 16:52:20 +02:00
|
|
|
final List<ProviderModel> allProviders;
|
|
|
|
|
final List<String> associatedIds;
|
|
|
|
|
// NUOVO CAMPO: Lista dei provider pronti per essere usati nel form pratiche
|
|
|
|
|
final List<ProviderModel> activeProviders;
|
2026-04-16 11:50:29 +02:00
|
|
|
final bool isLoading;
|
|
|
|
|
final String? errorMessage;
|
|
|
|
|
|
|
|
|
|
const ProvidersState({
|
|
|
|
|
this.allProviders = const [],
|
|
|
|
|
this.associatedIds = const [],
|
2026-04-20 16:52:20 +02:00
|
|
|
this.activeProviders = const [], // Inizializza
|
2026-04-16 11:50:29 +02:00
|
|
|
this.isLoading = false,
|
|
|
|
|
this.errorMessage,
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
ProvidersState copyWith({
|
|
|
|
|
List<ProviderModel>? allProviders,
|
|
|
|
|
List<String>? associatedIds,
|
2026-04-20 16:52:20 +02:00
|
|
|
List<ProviderModel>? activeProviders, // Aggiungi qui
|
2026-04-16 11:50:29 +02:00
|
|
|
bool? isLoading,
|
|
|
|
|
String? errorMessage,
|
|
|
|
|
}) {
|
|
|
|
|
return ProvidersState(
|
|
|
|
|
allProviders: allProviders ?? this.allProviders,
|
|
|
|
|
associatedIds: associatedIds ?? this.associatedIds,
|
2026-04-20 16:52:20 +02:00
|
|
|
activeProviders: activeProviders ?? this.activeProviders, // Aggiungi qui
|
2026-04-16 11:50:29 +02:00
|
|
|
isLoading: isLoading ?? this.isLoading,
|
2026-04-20 16:52:20 +02:00
|
|
|
errorMessage:
|
|
|
|
|
errorMessage ??
|
|
|
|
|
this.errorMessage, // Correzione bug: mancava "?? this.errorMessage" nel tuo originale
|
2026-04-16 11:50:29 +02:00
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@override
|
|
|
|
|
List<Object?> get props => [
|
|
|
|
|
allProviders,
|
|
|
|
|
associatedIds,
|
2026-04-20 16:52:20 +02:00
|
|
|
activeProviders, // Aggiungi qui
|
2026-04-16 11:50:29 +02:00
|
|
|
isLoading,
|
|
|
|
|
errorMessage,
|
|
|
|
|
];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
class ProvidersCubit extends Cubit<ProvidersState> {
|
|
|
|
|
final ProviderRepository _repository = GetIt.I<ProviderRepository>();
|
2026-04-20 16:52:20 +02:00
|
|
|
final SessionBloc _sessionBloc = GetIt.I<SessionBloc>();
|
2026-04-16 11:50:29 +02:00
|
|
|
|
2026-04-20 16:52:20 +02:00
|
|
|
ProvidersCubit() : super(const ProvidersState());
|
2026-04-16 11:50:29 +02:00
|
|
|
|
|
|
|
|
// Carica i provider della company e quelli associati a uno store specifico
|
2026-04-17 10:34:23 +02:00
|
|
|
Future<void> loadProviders(StoreModel? store) async {
|
2026-04-16 11:50:29 +02:00
|
|
|
emit(state.copyWith(isLoading: true));
|
|
|
|
|
try {
|
2026-04-17 10:34:23 +02:00
|
|
|
final all = await _repository.fetchAllCompanyProviders(
|
|
|
|
|
_sessionBloc.state.company!.id,
|
|
|
|
|
);
|
2026-04-16 11:50:29 +02:00
|
|
|
List<String> associated = [];
|
|
|
|
|
|
2026-04-17 10:34:23 +02:00
|
|
|
if (store != null) {
|
|
|
|
|
associated = await _repository.fetchAssociatedProviderIds(store.id!);
|
2026-04-16 11:50:29 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
emit(
|
|
|
|
|
state.copyWith(
|
|
|
|
|
allProviders: all,
|
|
|
|
|
associatedIds: associated,
|
|
|
|
|
isLoading: false,
|
|
|
|
|
),
|
|
|
|
|
);
|
|
|
|
|
} catch (e) {
|
|
|
|
|
emit(state.copyWith(isLoading: false, errorMessage: e.toString()));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-20 16:52:20 +02:00
|
|
|
Future<void> loadActiveProvidersForStore(String storeId) async {
|
|
|
|
|
emit(state.copyWith(isLoading: true));
|
|
|
|
|
try {
|
|
|
|
|
final activeList = await _repository.fetchActiveProvidersForStore(
|
|
|
|
|
storeId,
|
|
|
|
|
);
|
|
|
|
|
emit(state.copyWith(activeProviders: activeList, isLoading: false));
|
|
|
|
|
} catch (e) {
|
|
|
|
|
emit(
|
|
|
|
|
state.copyWith(
|
|
|
|
|
isLoading: false,
|
|
|
|
|
errorMessage: "Errore caricamento gestori: $e",
|
|
|
|
|
),
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-16 11:50:29 +02:00
|
|
|
// Aggiunge o rimuove l'associazione con lo store
|
|
|
|
|
Future<void> toggleProviderAssociation({
|
|
|
|
|
required String providerId,
|
|
|
|
|
required String storeId,
|
|
|
|
|
required bool isCurrentlyAssociated,
|
|
|
|
|
}) async {
|
|
|
|
|
try {
|
|
|
|
|
if (isCurrentlyAssociated) {
|
|
|
|
|
await _repository.disassociateProviderFromStore(
|
|
|
|
|
providerId: providerId,
|
|
|
|
|
storeId: storeId,
|
|
|
|
|
);
|
|
|
|
|
// Aggiorniamo lo stato locale rimuovendo l'ID
|
|
|
|
|
final newIds = List<String>.from(state.associatedIds)
|
|
|
|
|
..remove(providerId);
|
|
|
|
|
emit(state.copyWith(associatedIds: newIds));
|
|
|
|
|
} else {
|
|
|
|
|
await _repository.associateProviderToStore(
|
|
|
|
|
providerId: providerId,
|
|
|
|
|
storeId: storeId,
|
|
|
|
|
);
|
|
|
|
|
// Aggiorniamo lo stato locale aggiungendo l'ID
|
|
|
|
|
final newIds = List<String>.from(state.associatedIds)..add(providerId);
|
|
|
|
|
emit(state.copyWith(associatedIds: newIds));
|
|
|
|
|
}
|
|
|
|
|
} catch (e) {
|
|
|
|
|
emit(state.copyWith(errorMessage: "Errore durante l'aggiornamento: $e"));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Salvataggio/Update anagrafica (nuovo o modifica)
|
2026-04-17 10:34:23 +02:00
|
|
|
Future<void> saveProvider(
|
|
|
|
|
ProviderModel provider,
|
|
|
|
|
List<String> selectedStoreIds,
|
|
|
|
|
) async {
|
2026-04-16 11:50:29 +02:00
|
|
|
emit(state.copyWith(isLoading: true));
|
2026-04-17 10:34:23 +02:00
|
|
|
// Assicuriamoci di settare la companyId prima di salvare
|
|
|
|
|
provider = provider.copyWith(companyId: _sessionBloc.state.company!.id);
|
2026-04-16 11:50:29 +02:00
|
|
|
try {
|
2026-04-17 10:34:23 +02:00
|
|
|
// 1. Salviamo l'anagrafica (upsert)
|
|
|
|
|
// Se è un nuovo provider, l'ID potrebbe essere generato qui dal DB
|
|
|
|
|
// Quindi carichiamo il risultato del salvataggio per avere l'ID
|
|
|
|
|
final response = await _repository.saveProvider(provider);
|
|
|
|
|
|
|
|
|
|
// Assumiamo che il saveProvider restituisca l'oggetto salvato con l'ID
|
|
|
|
|
final pId = provider.id ?? response.id;
|
|
|
|
|
|
|
|
|
|
// 2. Sincronizziamo i negozi
|
|
|
|
|
await _repository.syncProviderStores(pId!, selectedStoreIds);
|
|
|
|
|
|
|
|
|
|
// 3. Ricarichiamo tutto
|
|
|
|
|
await loadProviders(null);
|
|
|
|
|
} catch (e) {
|
|
|
|
|
emit(state.copyWith(isLoading: false, errorMessage: e.toString()));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Future<void> saveProviderWithStores(
|
|
|
|
|
ProviderModel provider,
|
|
|
|
|
List<String> storeIds,
|
|
|
|
|
) async {
|
|
|
|
|
emit(state.copyWith(isLoading: true));
|
|
|
|
|
try {
|
|
|
|
|
// 1. Salva l'anagrafica provider
|
2026-04-16 11:50:29 +02:00
|
|
|
await _repository.saveProvider(provider);
|
2026-04-17 10:34:23 +02:00
|
|
|
|
|
|
|
|
// 2. Sincronizza i negozi (la via più semplice è cancellare e reinserire
|
|
|
|
|
// o fare un confronto tra i presenti e i nuovi)
|
|
|
|
|
await _repository.syncProviderStores(provider.id!, storeIds);
|
|
|
|
|
|
|
|
|
|
await loadProviders(null);
|
2026-04-16 11:50:29 +02:00
|
|
|
} catch (e) {
|
|
|
|
|
emit(state.copyWith(isLoading: false, errorMessage: e.toString()));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|