269 lines
7.8 KiB
Dart
269 lines
7.8 KiB
Dart
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/operations/data/operations_repository.dart';
|
|
import 'package:flux/features/operations/models/operation_model.dart';
|
|
import 'package:get_it/get_it.dart';
|
|
import 'package:uuid/uuid.dart';
|
|
|
|
part 'operation_form_state.dart';
|
|
|
|
class OperationFormCubit extends Cubit<OperationFormState> {
|
|
final OperationsRepository _repository = GetIt.I<OperationsRepository>();
|
|
final SessionCubit _sessionCubit = GetIt.I<SessionCubit>();
|
|
final Uuid _uuid = const Uuid();
|
|
|
|
OperationFormCubit()
|
|
: super(
|
|
OperationFormState(
|
|
// Inizializziamo con un modello vuoto di sicurezza
|
|
operation: OperationModel(
|
|
storeId: '',
|
|
companyId: '',
|
|
reference: '',
|
|
status: OperationStatus.draft,
|
|
createdAt: DateTime.now(),
|
|
),
|
|
),
|
|
);
|
|
|
|
Future<void> initForm({
|
|
OperationModel? existingOperation,
|
|
String? operationId,
|
|
}) async {
|
|
emit(state.copyWith(status: OperationFormStatus.loading));
|
|
|
|
try {
|
|
if (existingOperation != null) {
|
|
emit(
|
|
state.copyWith(
|
|
operation: existingOperation,
|
|
status: OperationFormStatus.ready,
|
|
),
|
|
);
|
|
} else if (operationId != null) {
|
|
// Avendo separato i cubit, se ci passano solo l'ID lo scarichiamo dal DB
|
|
final operation = await _repository.fetchOperationById(operationId);
|
|
emit(
|
|
state.copyWith(
|
|
operation: operation,
|
|
status: OperationFormStatus.ready,
|
|
),
|
|
);
|
|
} else {
|
|
// NUOVA PRATICA: Creiamo un nuovo Batch UUID
|
|
emit(
|
|
state.copyWith(
|
|
operation: OperationModel(
|
|
storeId: _sessionCubit.state.currentStore?.id ?? '',
|
|
reference: '',
|
|
createdAt: DateTime.now(),
|
|
companyId: _sessionCubit.state.company!.id!,
|
|
status: OperationStatus.draft,
|
|
batchUuid: _uuid.v4(),
|
|
),
|
|
status: OperationFormStatus.ready,
|
|
),
|
|
);
|
|
}
|
|
} catch (e) {
|
|
emit(
|
|
state.copyWith(
|
|
status: OperationFormStatus.failure,
|
|
errorMessage: "Errore inizializzazione form: $e",
|
|
),
|
|
);
|
|
}
|
|
}
|
|
|
|
// --- LOGICA BATCH ---
|
|
|
|
void _prepareNextOperationInBatch() {
|
|
final current = state.operation;
|
|
|
|
emit(
|
|
state.copyWith(
|
|
status: OperationFormStatus.ready, // Torna ready per il nuovo form
|
|
operation: OperationModel(
|
|
companyId: current.companyId,
|
|
storeId: current.storeId,
|
|
storeDisplayName: current.storeDisplayName,
|
|
batchUuid: current.batchUuid, // MANTIENE IL COLLEGAMENTO
|
|
customerId: current.customerId, // MANTIENE IL CLIENTE
|
|
customer: current.customer,
|
|
status: OperationStatus.draft,
|
|
createdAt: DateTime.now(),
|
|
),
|
|
),
|
|
);
|
|
}
|
|
|
|
// --- SALVATAGGIO ---
|
|
|
|
Future<void> saveOperation({
|
|
required OperationStatus targetStatus,
|
|
required bool keepAdding,
|
|
}) async {
|
|
emit(
|
|
state.copyWith(status: OperationFormStatus.saving, errorMessage: null),
|
|
);
|
|
|
|
try {
|
|
final operationToSave = state.operation.copyWith(status: targetStatus);
|
|
final savedOperation = await _repository.saveFullOperation(
|
|
operation: operationToSave,
|
|
);
|
|
|
|
if (keepAdding) {
|
|
// Salviamo nella "memoria" del batch le pratiche create finora
|
|
final updatedBatchList = List<OperationModel>.from(
|
|
state.savedBatchOperations,
|
|
)..add(savedOperation);
|
|
|
|
emit(
|
|
state.copyWith(
|
|
status: OperationFormStatus.successAndAddAnother,
|
|
savedBatchOperations: updatedBatchList,
|
|
),
|
|
);
|
|
|
|
// Pulisce i campi per la prossima operazione
|
|
_prepareNextOperationInBatch();
|
|
} else {
|
|
emit(
|
|
state.copyWith(
|
|
status: OperationFormStatus.success,
|
|
operation: savedOperation, // Aggiorniamo con l'ID restituito dal DB
|
|
),
|
|
);
|
|
}
|
|
} catch (e) {
|
|
emit(
|
|
state.copyWith(
|
|
status: OperationFormStatus.failure,
|
|
errorMessage: e.toString(),
|
|
),
|
|
);
|
|
}
|
|
}
|
|
|
|
Future<String?> saveOperationDraft() async {
|
|
try {
|
|
final operationToSave = state.operation;
|
|
if (operationToSave.customerId == null ||
|
|
operationToSave.customerId!.isEmpty) {
|
|
throw Exception('Seleziona un cliente prima di poter usare il QR');
|
|
}
|
|
final savedOperation = await _repository.saveFullOperation(
|
|
operation: operationToSave,
|
|
);
|
|
emit(
|
|
state.copyWith(
|
|
operation: savedOperation,
|
|
status: OperationFormStatus.ready,
|
|
),
|
|
);
|
|
return savedOperation.id;
|
|
} catch (e) {
|
|
emit(
|
|
state.copyWith(
|
|
status: OperationFormStatus.failure,
|
|
errorMessage: e.toString(),
|
|
),
|
|
);
|
|
return null;
|
|
}
|
|
}
|
|
|
|
// --- GESTIONE DEI CAMPI IN TEMPO REALE ---
|
|
|
|
void updateFields({
|
|
CustomerModel? customer,
|
|
String? reference,
|
|
String? note,
|
|
String? type,
|
|
String? providerId,
|
|
String? providerDisplayName,
|
|
String? subtype,
|
|
String? description,
|
|
DateTime? expirationDate,
|
|
int? quantity,
|
|
String? modelId,
|
|
String? modelDisplayName,
|
|
String? staffId,
|
|
String? staffDisplayName,
|
|
OperationStatus? status,
|
|
|
|
bool clearProvider = false,
|
|
bool clearType = false,
|
|
bool clearSubtype = false,
|
|
bool clearDescription = false,
|
|
bool clearExpiration = false,
|
|
bool clearQuantity = false,
|
|
bool clearModel = false,
|
|
}) {
|
|
final current = state.operation;
|
|
|
|
int? newQuantity;
|
|
if (clearQuantity) newQuantity = 1;
|
|
if (quantity != null && quantity <= 0) newQuantity = 0;
|
|
if (quantity != null && quantity > 0) newQuantity = quantity;
|
|
|
|
final updated = current.copyWith(
|
|
customer: customer ?? current.customer,
|
|
customerId: customer?.id ?? current.customerId,
|
|
reference: reference ?? current.reference,
|
|
note: note ?? current.note,
|
|
providerId: clearProvider ? null : (providerId ?? current.providerId),
|
|
providerDisplayName: clearProvider
|
|
? null
|
|
: (providerDisplayName ?? current.providerDisplayName),
|
|
quantity: newQuantity ?? current.quantity,
|
|
type: clearType ? null : (type ?? current.type),
|
|
description: clearDescription
|
|
? null
|
|
: (description ?? current.description),
|
|
subtype: clearSubtype ? null : (subtype ?? current.subtype),
|
|
expirationDate: clearExpiration
|
|
? null
|
|
: (expirationDate ?? current.expirationDate),
|
|
modelId: clearModel ? null : (modelId ?? current.modelId),
|
|
modelDisplayName: clearModel
|
|
? null
|
|
: (modelDisplayName ?? current.modelDisplayName),
|
|
staffId: staffId ?? current.staffId,
|
|
staffDisplayName: staffDisplayName ?? current.staffDisplayName,
|
|
status: status ?? current.status,
|
|
);
|
|
|
|
emit(state.copyWith(operation: updated));
|
|
}
|
|
|
|
// --- UTILS ---
|
|
|
|
void setTypeWithSmartDefault(String type) {
|
|
DateTime? defaultDate;
|
|
final now = DateTime.now();
|
|
|
|
if (type == 'Energy') {
|
|
defaultDate = DateTime(now.year, now.month + 24, now.day);
|
|
}
|
|
if (type == 'Fin') {
|
|
defaultDate = DateTime(now.year, now.month + 30, now.day);
|
|
}
|
|
if (type == 'Entertainment') {
|
|
defaultDate = DateTime(now.year, now.month + 12, now.day);
|
|
}
|
|
|
|
updateFields(
|
|
type: type,
|
|
expirationDate: defaultDate,
|
|
clearProvider: true,
|
|
clearSubtype: true,
|
|
clearModel: true,
|
|
clearQuantity: true,
|
|
);
|
|
}
|
|
}
|