default provider
This commit is contained in:
@@ -2,6 +2,8 @@ import 'package:equatable/equatable.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flux/core/blocs/session/session_cubit.dart';
|
||||
import 'package:flux/features/customers/models/customer_model.dart';
|
||||
import 'package:flux/features/master_data/providers/models/provider_model.dart';
|
||||
import 'package:flux/features/master_data/providers/models/provider_model_extensions.dart';
|
||||
import 'package:flux/features/master_data/staff/models/staff_member_model.dart';
|
||||
import 'package:flux/features/operations/data/operations_repository.dart';
|
||||
import 'package:flux/features/operations/models/operation_model.dart';
|
||||
@@ -278,27 +280,126 @@ class OperationFormCubit extends Cubit<OperationFormState> {
|
||||
|
||||
// --- UTILS ---
|
||||
|
||||
void setTypeWithSmartDefault(String type) {
|
||||
void updateOperationType(
|
||||
String newType, {
|
||||
required List<ProviderModel> allProviders,
|
||||
String? defaultProviderId,
|
||||
}) {
|
||||
// 1. Aggiorniamo il tipo nel modello in canna
|
||||
// (Presumo tu abbia un metodo copyWith o simile)
|
||||
final updatedOp = state.operation.copyWith(type: newType, subtype: '');
|
||||
|
||||
// 2. Prepariamoci ad auto-selezionare il provider
|
||||
String? newProviderId = updatedOp.providerId;
|
||||
String? newProviderName = updatedOp.providerDisplayName;
|
||||
|
||||
// 3. LA LOGICA DI DEFAULT
|
||||
if (defaultProviderId != null) {
|
||||
// Troviamo il provider di default nella lista
|
||||
final defaultProvider = allProviders
|
||||
.where((p) => p.id == defaultProviderId)
|
||||
.firstOrNull;
|
||||
|
||||
if (defaultProvider != null) {
|
||||
// Usiamo l'extension appena creata!
|
||||
if (defaultProvider.supportsOperation(newType)) {
|
||||
newProviderId = defaultProvider.id;
|
||||
newProviderName = defaultProvider.name;
|
||||
} else {
|
||||
// Se cambi tipo (es. da Mobile a Luce) e il default non lo supporta, sbianchiamo
|
||||
newProviderId = null;
|
||||
newProviderName = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Emettiamo il nuovo stato
|
||||
emit(
|
||||
state.copyWith(
|
||||
operation: updatedOp.copyWith(
|
||||
providerId: newProviderId,
|
||||
providerDisplayName: newProviderName,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
void setTypeWithSmartDefaults({
|
||||
required String newType,
|
||||
required List<ProviderModel> allProviders,
|
||||
String? defaultProviderId,
|
||||
}) {
|
||||
final currentOp = state.operation;
|
||||
|
||||
// -----------------------------------------
|
||||
// 1. SMART DATES: Calcolo Scadenze Default
|
||||
// -----------------------------------------
|
||||
DateTime? defaultDate;
|
||||
final now = DateTime.now();
|
||||
|
||||
if (type == 'Energy') {
|
||||
if (newType == 'Energy') {
|
||||
defaultDate = DateTime(now.year, now.month + 24, now.day);
|
||||
}
|
||||
if (type == 'Fin') {
|
||||
if (newType == 'Fin') {
|
||||
defaultDate = DateTime(now.year, now.month + 30, now.day);
|
||||
}
|
||||
if (type == 'Entertainment') {
|
||||
if (newType == 'Entertainment') {
|
||||
defaultDate = DateTime(now.year, now.month + 12, now.day);
|
||||
}
|
||||
|
||||
updateFields(
|
||||
type: type,
|
||||
expirationDate: defaultDate,
|
||||
clearProvider: true,
|
||||
clearSubtype: true,
|
||||
clearModel: true,
|
||||
clearQuantity: true,
|
||||
// -----------------------------------------
|
||||
// 2. SMART PROVIDER: Filtro e Auto-Selezione
|
||||
// -----------------------------------------
|
||||
String? newProviderId = currentOp.providerId;
|
||||
String? newProviderName = currentOp.providerDisplayName;
|
||||
|
||||
// A) Il provider attuale è ancora compatibile col nuovo tipo scelto?
|
||||
if (newProviderId != null && newProviderId.isNotEmpty) {
|
||||
final currentProvider = allProviders
|
||||
.where((p) => p.id == newProviderId)
|
||||
.firstOrNull;
|
||||
|
||||
if (currentProvider == null ||
|
||||
!currentProvider.supportsOperation(newType)) {
|
||||
// Non è più compatibile (es. da TIM fisso passo a Energy). Lo sbianchiamo!
|
||||
newProviderId = null;
|
||||
newProviderName = null;
|
||||
}
|
||||
}
|
||||
|
||||
// B) Se non c'è un provider selezionato, proviamo ad auto-inserire quello di default del negozio
|
||||
if ((newProviderId == null || newProviderId.isEmpty) &&
|
||||
defaultProviderId != null) {
|
||||
final defaultProvider = allProviders
|
||||
.where((p) => p.id == defaultProviderId)
|
||||
.firstOrNull;
|
||||
|
||||
// Controlliamo che il default del negozio supporti questa specifica operazione
|
||||
if (defaultProvider != null &&
|
||||
defaultProvider.supportsOperation(newType)) {
|
||||
newProviderId = defaultProvider.id;
|
||||
newProviderName = defaultProvider.name;
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------
|
||||
// 3. EMISSIONE DELLO STATO PULITO
|
||||
// -----------------------------------------
|
||||
emit(
|
||||
state.copyWith(
|
||||
operation: currentOp.copyWith(
|
||||
type: newType,
|
||||
subtype:
|
||||
'', // Resettiamo il sottotipo per evitare incongruenze (es. passo da Luce a DAZN)
|
||||
expirationDate:
|
||||
defaultDate, // Impostiamo la scadenza di default se calcolata
|
||||
providerId: newProviderId,
|
||||
providerDisplayName: newProviderName,
|
||||
|
||||
modelId: null,
|
||||
modelDisplayName: null,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flux/core/blocs/session/session_cubit.dart';
|
||||
import 'package:flux/core/widgets/shared_forms/attachments_section.dart';
|
||||
import 'package:flux/features/attachments/blocs/attachments_bloc.dart';
|
||||
import 'package:flux/features/master_data/providers/blocs/provider_list_cubit.dart';
|
||||
import 'package:flux/features/operations/blocs/operation_form_cubit.dart';
|
||||
import 'package:flux/features/operations/models/operation_model.dart';
|
||||
import 'package:flux/core/widgets/shared_forms/customer_section.dart';
|
||||
@@ -527,8 +529,24 @@ class _OperationFormScreenState extends State<OperationFormScreen> {
|
||||
selected: state.operation.type == type,
|
||||
onSelected: (selected) {
|
||||
if (selected) {
|
||||
context.read<OperationFormCubit>().setTypeWithSmartDefault(
|
||||
type,
|
||||
// 1. Recuperiamo i provider caricati in memoria
|
||||
final allProviders = context
|
||||
.read<ProviderListCubit>()
|
||||
.state
|
||||
.providers;
|
||||
|
||||
// 2. Recuperiamo il provider di default del negozio dalla sessione
|
||||
final defaultProviderId = context
|
||||
.read<SessionCubit>()
|
||||
.state
|
||||
.currentStore
|
||||
?.defaultProviderId;
|
||||
|
||||
// 3. Spariamo tutto nel metodo "tuttofare"
|
||||
context.read<OperationFormCubit>().setTypeWithSmartDefaults(
|
||||
newType: type,
|
||||
allProviders: allProviders,
|
||||
defaultProviderId: defaultProviderId,
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
@@ -2,8 +2,7 @@ import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flux/core/widgets/shared_forms/model_section.dart';
|
||||
import 'package:flux/features/master_data/providers/blocs/provider_list_cubit.dart';
|
||||
import 'package:flux/features/master_data/providers/models/provider_model.dart';
|
||||
import 'package:flux/features/master_data/providers/models/provider_role.dart';
|
||||
import 'package:flux/features/master_data/providers/models/provider_model_extensions.dart';
|
||||
import 'package:flux/features/operations/blocs/operation_form_cubit.dart';
|
||||
import 'package:flux/features/operations/models/operation_model.dart';
|
||||
|
||||
@@ -23,34 +22,6 @@ class OperationDetailsSection extends StatelessWidget {
|
||||
required this.durationQuickPicks,
|
||||
});
|
||||
|
||||
bool _doesProviderMatchOperationType(
|
||||
ProviderModel provider,
|
||||
String operationType,
|
||||
) {
|
||||
if (operationType == 'Altro') return true;
|
||||
|
||||
// Controlliamo che il fornitore abbia il ruolo specifico nel suo array
|
||||
switch (operationType) {
|
||||
case 'AL' || 'MNP':
|
||||
return provider.roles.contains(ProviderRole.mobile);
|
||||
case 'NIP' || 'FWA':
|
||||
return provider.roles.contains(ProviderRole.landline);
|
||||
case 'UNICA':
|
||||
return provider.roles.contains(ProviderRole.landline) ||
|
||||
provider.roles.contains(ProviderRole.mobile);
|
||||
case 'Energy':
|
||||
return provider.roles.contains(ProviderRole.energy);
|
||||
case 'Fin':
|
||||
return provider.roles.contains(ProviderRole.financing);
|
||||
case 'Entertainment':
|
||||
return provider.roles.contains(ProviderRole.entertainment);
|
||||
case 'TELEPASS':
|
||||
return provider.roles.contains(ProviderRole.telepass);
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
void _showProviderModal(BuildContext context, String operationType) {
|
||||
final OperationFormCubit cubit = context.read<OperationFormCubit>();
|
||||
showModalBottomSheet(
|
||||
@@ -92,14 +63,9 @@ class OperationDetailsSection extends StatelessWidget {
|
||||
return const Center(child: CircularProgressIndicator());
|
||||
}
|
||||
|
||||
// Prendiamo i provider e li filtriamo per ruolo e per stato attivo
|
||||
// 🥷 IL TOCCO DEL NINJA: Filtriamo usando direttamente l'Extension sul Modello!
|
||||
final filteredProviders = state.providers.where((p) {
|
||||
final isMatch = _doesProviderMatchOperationType(
|
||||
p,
|
||||
operationType,
|
||||
);
|
||||
return isMatch &&
|
||||
p.isActive; // Mostriamo solo quelli attivi!
|
||||
return p.supportsOperation(operationType) && p.isActive;
|
||||
}).toList();
|
||||
|
||||
if (filteredProviders.isEmpty) {
|
||||
|
||||
Reference in New Issue
Block a user