reworked operation (#12)
Reviewed-on: #12 Co-authored-by: Mark M2 Macbook <marco@catelli.it> Co-committed-by: Mark M2 Macbook <marco@catelli.it>
This commit is contained in:
@@ -9,19 +9,17 @@ import 'package:get_it/get_it.dart';
|
||||
|
||||
part 'product_state.dart';
|
||||
|
||||
class ProductCubit extends Cubit<ProductState> {
|
||||
class ProductsCubit extends Cubit<ProductState> {
|
||||
final ProductRepository _repository = GetIt.I<ProductRepository>();
|
||||
final SessionCubit _sessionCubit = GetIt.I<SessionCubit>();
|
||||
|
||||
ProductCubit() : super(const ProductState());
|
||||
ProductsCubit() : super(const ProductState());
|
||||
|
||||
// Caricamento iniziale dei Brand
|
||||
Future<void> loadBrands() async {
|
||||
emit(state.copyWith(status: ProductStatus.loading));
|
||||
try {
|
||||
final brands = await _repository.getBrands(
|
||||
_sessionCubit.state.company!.id!,
|
||||
);
|
||||
final brands = await _repository.getBrands();
|
||||
emit(state.copyWith(status: ProductStatus.success, brands: brands));
|
||||
} catch (e) {
|
||||
emit(
|
||||
@@ -30,6 +28,27 @@ class ProductCubit extends Cubit<ProductState> {
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> loadModels() async {
|
||||
emit(state.copyWith(status: ProductStatus.loading));
|
||||
try {
|
||||
final models = await _repository.getModels();
|
||||
emit(state.copyWith(status: ProductStatus.success, models: models));
|
||||
} catch (e) {
|
||||
emit(
|
||||
state.copyWith(status: ProductStatus.error, errorMessage: e.toString()),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> refreshCubit() async {
|
||||
if (state.selectedBrand != null) {
|
||||
await selectBrand(state.selectedBrand);
|
||||
} else {
|
||||
emit(state.copyWith(status: ProductStatus.initial));
|
||||
await loadBrands();
|
||||
}
|
||||
}
|
||||
|
||||
// Selezione Brand e caricamento Modelli
|
||||
Future<void> selectBrand(BrandModel? brand) async {
|
||||
if (brand == null) {
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import 'package:flux/core/blocs/session/session_cubit.dart';
|
||||
import 'package:get_it/get_it.dart';
|
||||
import 'package:supabase_flutter/supabase_flutter.dart';
|
||||
import '../models/brand_model.dart';
|
||||
@@ -5,16 +6,17 @@ import '../models/model_model.dart';
|
||||
|
||||
class ProductRepository {
|
||||
final SupabaseClient _supabase = GetIt.I<SupabaseClient>();
|
||||
final String _companyId = GetIt.I<SessionCubit>().state.company!.id!;
|
||||
|
||||
// --- BRAND ---
|
||||
|
||||
/// Recupera tutti i brand dell'azienda
|
||||
Future<List<BrandModel>> getBrands(String companyId) async {
|
||||
Future<List<BrandModel>> getBrands() async {
|
||||
try {
|
||||
final response = await _supabase
|
||||
.from('brand')
|
||||
.select()
|
||||
.eq('company_id', companyId)
|
||||
.eq('company_id', _companyId)
|
||||
.eq('is_active', true)
|
||||
.order('name');
|
||||
|
||||
@@ -57,6 +59,19 @@ class ProductRepository {
|
||||
}
|
||||
}
|
||||
|
||||
Future<List<ModelModel>> getModels() async {
|
||||
try {
|
||||
final response = await _supabase
|
||||
.from('model')
|
||||
.select()
|
||||
.eq('is_active', true)
|
||||
.order('name');
|
||||
return (response as List).map((m) => ModelModel.fromJson(m)).toList();
|
||||
} catch (e) {
|
||||
throw '$e';
|
||||
}
|
||||
}
|
||||
|
||||
/// Crea o aggiorna un modello
|
||||
/// NOTA: name_with_brand verrà gestito dal trigger SQL che hai lanciato!
|
||||
Future<ModelModel> upsertModel(ModelModel model) async {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import 'package:equatable/equatable.dart';
|
||||
import 'package:flux/core/utils/string_extensions.dart';
|
||||
import 'package:flux/core/utils/extensions.dart';
|
||||
|
||||
class BrandModel extends Equatable {
|
||||
final String? id;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import 'package:equatable/equatable.dart';
|
||||
import 'package:flux/core/utils/string_extensions.dart';
|
||||
import 'package:flux/core/utils/extensions.dart';
|
||||
|
||||
class ModelModel extends Equatable {
|
||||
final String? id;
|
||||
|
||||
@@ -33,7 +33,7 @@ class BrandSelector extends StatelessWidget {
|
||||
return DropdownMenuItem(value: brand, child: Text(brand.name));
|
||||
}).toList(),
|
||||
onChanged: (brand) =>
|
||||
context.read<ProductCubit>().selectBrand(brand),
|
||||
context.read<ProductsCubit>().selectBrand(brand),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 16),
|
||||
|
||||
@@ -64,7 +64,7 @@ class ModelsList extends StatelessWidget {
|
||||
color: model.isActive ? context.accent : Colors.grey,
|
||||
),
|
||||
onPressed: () => context
|
||||
.read<ProductCubit>()
|
||||
.read<ProductsCubit>()
|
||||
.toggleStatus('model', model.id!, model.isActive),
|
||||
),
|
||||
],
|
||||
|
||||
@@ -40,7 +40,7 @@ void _submitBrand(
|
||||
BrandModel? brand,
|
||||
) {
|
||||
if (controller.text.trim().isNotEmpty) {
|
||||
context.read<ProductCubit>().saveBrand(controller.text, id: brand?.id);
|
||||
context.read<ProductsCubit>().saveBrand(controller.text, id: brand?.id);
|
||||
Navigator.pop(context);
|
||||
}
|
||||
}
|
||||
@@ -81,7 +81,7 @@ void _submitModel(
|
||||
ModelModel? model,
|
||||
) {
|
||||
if (controller.text.isNotEmpty) {
|
||||
context.read<ProductCubit>().saveModel(controller.text, id: model?.id);
|
||||
context.read<ProductsCubit>().saveModel(controller.text, id: model?.id);
|
||||
Navigator.pop(context);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ class ProductsScreen extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
// Carichiamo i brand appena la pagina viene creata
|
||||
context.read<ProductCubit>().loadBrands();
|
||||
context.read<ProductsCubit>().loadBrands();
|
||||
|
||||
return Scaffold(
|
||||
backgroundColor: context.background,
|
||||
@@ -33,7 +33,7 @@ class ProductsScreen extends StatelessWidget {
|
||||
),
|
||||
),
|
||||
),
|
||||
body: BlocConsumer<ProductCubit, ProductState>(
|
||||
body: BlocConsumer<ProductsCubit, ProductState>(
|
||||
listener: (context, state) {
|
||||
if (state.status == ProductStatus.error) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
|
||||
@@ -23,7 +23,7 @@ class _QuickProductDialogState extends State<QuickProductDialog> {
|
||||
|
||||
setState(() => _isLoading = true);
|
||||
|
||||
final newModel = await context.read<ProductCubit>().quickCreateProduct(
|
||||
final newModel = await context.read<ProductsCubit>().quickCreateProduct(
|
||||
brandName: _selectedBrandName.trim(),
|
||||
modelName: _modelCtrl.text.trim(),
|
||||
);
|
||||
|
||||
@@ -51,7 +51,7 @@ class ProviderRepository {
|
||||
)
|
||||
''')
|
||||
.eq('company_id', companyId)
|
||||
.order('nome');
|
||||
.order('name');
|
||||
|
||||
return (response as List).map((m) => ProviderModel.fromMap(m)).toList();
|
||||
} catch (e) {
|
||||
|
||||
@@ -3,28 +3,30 @@ import 'package:flux/features/master_data/store/models/store_model.dart';
|
||||
|
||||
class ProviderModel extends Equatable {
|
||||
final String? id;
|
||||
final String nome;
|
||||
final bool telefoniaFissa;
|
||||
final bool telefoniaMobile;
|
||||
final bool energia;
|
||||
final bool assicurazioni;
|
||||
final bool intrattenimento;
|
||||
final bool finanziamenti;
|
||||
final bool altro;
|
||||
final String name;
|
||||
final bool landline;
|
||||
final bool mobile;
|
||||
final bool energy;
|
||||
final bool insurance;
|
||||
final bool entertainment;
|
||||
final bool financing;
|
||||
final bool telepass;
|
||||
final bool other;
|
||||
final bool isActive;
|
||||
final String companyId;
|
||||
final List<StoreModel> associatedStores;
|
||||
|
||||
const ProviderModel({
|
||||
this.id,
|
||||
required this.nome,
|
||||
required this.telefoniaFissa,
|
||||
required this.telefoniaMobile,
|
||||
required this.energia,
|
||||
required this.assicurazioni,
|
||||
required this.intrattenimento,
|
||||
required this.finanziamenti,
|
||||
required this.altro,
|
||||
required this.name,
|
||||
required this.landline,
|
||||
required this.mobile,
|
||||
required this.energy,
|
||||
required this.insurance,
|
||||
required this.entertainment,
|
||||
required this.financing,
|
||||
required this.telepass,
|
||||
required this.other,
|
||||
required this.isActive,
|
||||
required this.companyId,
|
||||
this.associatedStores = const [],
|
||||
@@ -44,14 +46,15 @@ class ProviderModel extends Equatable {
|
||||
}
|
||||
return ProviderModel(
|
||||
id: map['id'],
|
||||
nome: map['nome'],
|
||||
telefoniaFissa: map['telefonia_fissa'] ?? false,
|
||||
telefoniaMobile: map['telefonia_mobile'] ?? false,
|
||||
energia: map['energia'] ?? false,
|
||||
assicurazioni: map['assicurazioni'] ?? false,
|
||||
intrattenimento: map['intrattenimento'] ?? false,
|
||||
finanziamenti: map['finanziamenti'] ?? false,
|
||||
altro: map['altro'] ?? false,
|
||||
name: map['name'],
|
||||
landline: map['landline'] ?? false,
|
||||
mobile: map['mobile'] ?? false,
|
||||
energy: map['energy'] ?? false,
|
||||
insurance: map['insurance'] ?? false,
|
||||
entertainment: map['entertainment'] ?? false,
|
||||
financing: map['financing'] ?? false,
|
||||
telepass: map['telepass'] ?? false,
|
||||
other: map['other'] ?? false,
|
||||
isActive: map['is_active'] ?? true,
|
||||
companyId: map['company_id'],
|
||||
associatedStores: stores,
|
||||
@@ -60,14 +63,15 @@ class ProviderModel extends Equatable {
|
||||
|
||||
Map<String, dynamic> toMap() {
|
||||
final map = {
|
||||
'nome': nome,
|
||||
'telefonia_fissa': telefoniaFissa,
|
||||
'telefonia_mobile': telefoniaMobile,
|
||||
'energia': energia,
|
||||
'assicurazioni': assicurazioni,
|
||||
'intrattenimento': intrattenimento,
|
||||
'finanziamenti': finanziamenti,
|
||||
'altro': altro,
|
||||
'name': name,
|
||||
'landline': landline,
|
||||
'mobile': mobile,
|
||||
'energy': energy,
|
||||
'insurance': insurance,
|
||||
'entertainment': entertainment,
|
||||
'financing': financing,
|
||||
'telepass': telepass,
|
||||
'other': other,
|
||||
'is_active': isActive,
|
||||
'company_id': companyId,
|
||||
};
|
||||
@@ -82,14 +86,15 @@ class ProviderModel extends Equatable {
|
||||
@override
|
||||
List<Object?> get props => [
|
||||
id,
|
||||
nome,
|
||||
telefoniaFissa,
|
||||
telefoniaMobile,
|
||||
energia,
|
||||
assicurazioni,
|
||||
intrattenimento,
|
||||
finanziamenti,
|
||||
altro,
|
||||
name,
|
||||
landline,
|
||||
mobile,
|
||||
energy,
|
||||
insurance,
|
||||
entertainment,
|
||||
financing,
|
||||
telepass,
|
||||
other,
|
||||
isActive,
|
||||
companyId,
|
||||
associatedStores,
|
||||
@@ -97,28 +102,30 @@ class ProviderModel extends Equatable {
|
||||
|
||||
ProviderModel copyWith({
|
||||
String? id,
|
||||
String? nome,
|
||||
bool? telefoniaFissa,
|
||||
bool? telefoniaMobile,
|
||||
bool? energia,
|
||||
bool? assicurazioni,
|
||||
bool? intrattenimento,
|
||||
bool? finanziamenti,
|
||||
bool? altro,
|
||||
String? name,
|
||||
bool? landline,
|
||||
bool? mobile,
|
||||
bool? energy,
|
||||
bool? insurance,
|
||||
bool? entertainment,
|
||||
bool? financing,
|
||||
bool? telepass,
|
||||
bool? other,
|
||||
bool? isActive,
|
||||
String? companyId,
|
||||
List<StoreModel>? associatedStores,
|
||||
}) {
|
||||
return ProviderModel(
|
||||
id: id ?? this.id,
|
||||
nome: nome ?? this.nome,
|
||||
telefoniaFissa: telefoniaFissa ?? this.telefoniaFissa,
|
||||
telefoniaMobile: telefoniaMobile ?? this.telefoniaMobile,
|
||||
energia: energia ?? this.energia,
|
||||
assicurazioni: assicurazioni ?? this.assicurazioni,
|
||||
intrattenimento: intrattenimento ?? this.intrattenimento,
|
||||
finanziamenti: finanziamenti ?? this.finanziamenti,
|
||||
altro: altro ?? this.altro,
|
||||
name: name ?? this.name,
|
||||
landline: landline ?? this.landline,
|
||||
mobile: mobile ?? this.mobile,
|
||||
energy: energy ?? this.energy,
|
||||
insurance: insurance ?? this.insurance,
|
||||
entertainment: entertainment ?? this.entertainment,
|
||||
financing: financing ?? this.financing,
|
||||
telepass: telepass ?? this.telepass,
|
||||
other: other ?? this.other,
|
||||
isActive: isActive ?? this.isActive,
|
||||
companyId: companyId ?? this.companyId,
|
||||
associatedStores: associatedStores ?? this.associatedStores,
|
||||
|
||||
@@ -15,13 +15,14 @@ class ProviderFormSheet extends StatefulWidget {
|
||||
|
||||
class _ProviderFormSheetState extends State<ProviderFormSheet> {
|
||||
late TextEditingController _nameController;
|
||||
late bool _telefoniaFissa;
|
||||
late bool _telefoniaMobile;
|
||||
late bool _energia;
|
||||
late bool _assicurazioni;
|
||||
late bool _intrattenimento;
|
||||
late bool _finanziamenti;
|
||||
late bool _altro;
|
||||
late bool _landline;
|
||||
late bool _mobile;
|
||||
late bool _energy;
|
||||
late bool _insurance;
|
||||
late bool _entertainment;
|
||||
late bool _financing;
|
||||
late bool _telepass;
|
||||
late bool _other;
|
||||
late bool _isActive;
|
||||
final List<String> _tempSelectedStoreIds =
|
||||
[]; // Per gestire la selezione temporanea dei negozi
|
||||
@@ -33,14 +34,15 @@ class _ProviderFormSheetState extends State<ProviderFormSheet> {
|
||||
for (final store in p?.associatedStores ?? []) {
|
||||
_tempSelectedStoreIds.add(store.id!);
|
||||
}
|
||||
_nameController = TextEditingController(text: p?.nome ?? '');
|
||||
_telefoniaFissa = p?.telefoniaFissa ?? false;
|
||||
_telefoniaMobile = p?.telefoniaMobile ?? false;
|
||||
_energia = p?.energia ?? false;
|
||||
_assicurazioni = p?.assicurazioni ?? false;
|
||||
_intrattenimento = p?.intrattenimento ?? false;
|
||||
_finanziamenti = p?.finanziamenti ?? false;
|
||||
_altro = p?.altro ?? false;
|
||||
_nameController = TextEditingController(text: p?.name ?? '');
|
||||
_landline = p?.landline ?? false;
|
||||
_mobile = p?.mobile ?? false;
|
||||
_energy = p?.energy ?? false;
|
||||
_insurance = p?.insurance ?? false;
|
||||
_entertainment = p?.entertainment ?? false;
|
||||
_financing = p?.financing ?? false;
|
||||
_telepass = p?.telepass ?? false;
|
||||
_other = p?.other ?? false;
|
||||
_isActive = p?.isActive ?? true;
|
||||
}
|
||||
|
||||
@@ -57,14 +59,15 @@ class _ProviderFormSheetState extends State<ProviderFormSheet> {
|
||||
final cubit = context.read<ProvidersCubit>();
|
||||
final provider = ProviderModel(
|
||||
id: widget.initialProvider?.id, // Se nullo, Supabase farà insert
|
||||
nome: _nameController.text.trim(),
|
||||
telefoniaFissa: _telefoniaFissa,
|
||||
telefoniaMobile: _telefoniaMobile,
|
||||
energia: _energia,
|
||||
assicurazioni: _assicurazioni,
|
||||
intrattenimento: _intrattenimento,
|
||||
finanziamenti: _finanziamenti,
|
||||
altro: _altro,
|
||||
name: _nameController.text.trim(),
|
||||
landline: _landline,
|
||||
mobile: _mobile,
|
||||
energy: _energy,
|
||||
insurance: _insurance,
|
||||
entertainment: _entertainment,
|
||||
financing: _financing,
|
||||
telepass: _telepass,
|
||||
other: _other,
|
||||
isActive: _isActive,
|
||||
companyId:
|
||||
'', // Verrà ignorato dal toMap e gestito dal Cubit/SessionBloc se hai messo la logica lì
|
||||
@@ -110,38 +113,43 @@ class _ProviderFormSheetState extends State<ProviderFormSheet> {
|
||||
),
|
||||
_buildSwitch(
|
||||
"Energia (Luce/Gas)",
|
||||
_energia,
|
||||
(v) => setState(() => _energia = v),
|
||||
_energy,
|
||||
(v) => setState(() => _energy = v),
|
||||
),
|
||||
_buildSwitch(
|
||||
"Telefonia Fissa",
|
||||
_telefoniaFissa,
|
||||
(v) => setState(() => _telefoniaFissa = v),
|
||||
_landline,
|
||||
(v) => setState(() => _landline = v),
|
||||
),
|
||||
_buildSwitch(
|
||||
"Telefonia Mobile",
|
||||
_telefoniaMobile,
|
||||
(v) => setState(() => _telefoniaMobile = v),
|
||||
_mobile,
|
||||
(v) => setState(() => _mobile = v),
|
||||
),
|
||||
_buildSwitch(
|
||||
"Assicurazioni",
|
||||
_assicurazioni,
|
||||
(v) => setState(() => _assicurazioni = v),
|
||||
_insurance,
|
||||
(v) => setState(() => _insurance = v),
|
||||
),
|
||||
_buildSwitch(
|
||||
"Intrattenimento",
|
||||
_intrattenimento,
|
||||
(v) => setState(() => _intrattenimento = v),
|
||||
_entertainment,
|
||||
(v) => setState(() => _entertainment = v),
|
||||
),
|
||||
_buildSwitch(
|
||||
"Finanziamenti",
|
||||
_finanziamenti,
|
||||
(v) => setState(() => _finanziamenti = v),
|
||||
_financing,
|
||||
(v) => setState(() => _financing = v),
|
||||
),
|
||||
_buildSwitch(
|
||||
"Telepass",
|
||||
_telepass,
|
||||
(v) => setState(() => _telepass = v),
|
||||
),
|
||||
_buildSwitch(
|
||||
"Altro/Accessori",
|
||||
_altro,
|
||||
(v) => setState(() => _altro = v),
|
||||
_other,
|
||||
(v) => setState(() => _other = v),
|
||||
),
|
||||
const Divider(),
|
||||
_buildSwitch(
|
||||
@@ -164,7 +172,7 @@ class _ProviderFormSheetState extends State<ProviderFormSheet> {
|
||||
store.id,
|
||||
);
|
||||
return CheckboxListTile(
|
||||
title: Text(store.nome),
|
||||
title: Text(store.name),
|
||||
value: isAssociated,
|
||||
onChanged: (val) {
|
||||
setState(() {
|
||||
|
||||
@@ -93,7 +93,7 @@ class _ProvidersMasterDataScreenState extends State<ProvidersMasterDataScreen> {
|
||||
),
|
||||
),
|
||||
title: Text(
|
||||
provider.nome,
|
||||
provider.name,
|
||||
style: const TextStyle(fontWeight: FontWeight.bold),
|
||||
),
|
||||
subtitle: _buildCardSubtitle(
|
||||
@@ -141,12 +141,13 @@ class _ProvidersMasterDataScreenState extends State<ProvidersMasterDataScreen> {
|
||||
return Wrap(
|
||||
spacing: 4,
|
||||
children: [
|
||||
if (p.telefoniaFissa || p.telefoniaMobile)
|
||||
_smallTag("📞 Tel", Colors.blue),
|
||||
if (p.energia) _smallTag("⚡ Energy", Colors.orange),
|
||||
if (p.assicurazioni) _smallTag("🛡️ Assic", Colors.teal),
|
||||
if (p.intrattenimento) _smallTag("📺 Ent", Colors.red),
|
||||
if (p.altro) _smallTag("📦 Altro", Colors.grey),
|
||||
if (p.landline || p.mobile) _smallTag("📞 Tel", Colors.blue),
|
||||
if (p.energy) _smallTag("⚡ Energy", Colors.orange),
|
||||
if (p.insurance) _smallTag("🛡️ Assic", Colors.teal),
|
||||
if (p.entertainment) _smallTag("📺 Ent", Colors.red),
|
||||
if (p.financing) _smallTag("💰 Fin", Colors.purple),
|
||||
if (p.telepass) _smallTag("🏎️ Telepass", Colors.yellow),
|
||||
if (p.other) _smallTag("📦 Altro", Colors.grey),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
@@ -56,7 +56,7 @@ class StaffCubit extends Cubit<StaffState> {
|
||||
state.staffByStore,
|
||||
);
|
||||
newMap[storeId] = staffInStore;
|
||||
emit(state.copyWith(staffByStore: newMap));
|
||||
emit(state.copyWith(staffByStore: newMap, storeStaff: staffInStore));
|
||||
} catch (e) {
|
||||
emit(state.copyWith(status: StaffStatus.error, error: e.toString()));
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ class StaffState extends Equatable {
|
||||
final List<StaffMemberModel> allStaff;
|
||||
final Map<String, List<StoreModel>> storesByStaff;
|
||||
final Map<String, List<StaffMemberModel>> staffByStore;
|
||||
final List<StaffMemberModel> storeStaff;
|
||||
final String? error;
|
||||
|
||||
const StaffState({
|
||||
@@ -14,6 +15,7 @@ class StaffState extends Equatable {
|
||||
this.allStaff = const [],
|
||||
this.storesByStaff = const {},
|
||||
this.staffByStore = const {},
|
||||
this.storeStaff = const [],
|
||||
this.error,
|
||||
});
|
||||
|
||||
@@ -22,6 +24,7 @@ class StaffState extends Equatable {
|
||||
List<StaffMemberModel>? allStaff,
|
||||
Map<String, List<StoreModel>>? storesByStaff,
|
||||
Map<String, List<StaffMemberModel>>? staffByStore,
|
||||
List<StaffMemberModel>? storeStaff,
|
||||
String? error,
|
||||
}) {
|
||||
return StaffState(
|
||||
@@ -29,6 +32,7 @@ class StaffState extends Equatable {
|
||||
allStaff: allStaff ?? this.allStaff,
|
||||
storesByStaff: storesByStaff ?? this.storesByStaff,
|
||||
staffByStore: staffByStore ?? this.staffByStore,
|
||||
storeStaff: storeStaff ?? this.storeStaff,
|
||||
error: error,
|
||||
);
|
||||
}
|
||||
@@ -39,6 +43,7 @@ class StaffState extends Equatable {
|
||||
allStaff,
|
||||
storesByStaff,
|
||||
staffByStore,
|
||||
storeStaff,
|
||||
error,
|
||||
];
|
||||
}
|
||||
|
||||
@@ -126,7 +126,7 @@ class _StaffScreenState extends State<StaffScreen> {
|
||||
initialValue: _selectedStoreId,
|
||||
decoration: const InputDecoration(labelText: "Filtra per Negozio"),
|
||||
items: state.stores
|
||||
.map((s) => DropdownMenuItem(value: s.id, child: Text(s.nome)))
|
||||
.map((s) => DropdownMenuItem(value: s.id, child: Text(s.name)))
|
||||
.toList(),
|
||||
onChanged: (id) {
|
||||
setState(() => _selectedStoreId = id);
|
||||
@@ -355,7 +355,7 @@ class _StaffScreenState extends State<StaffScreen> {
|
||||
store.id,
|
||||
);
|
||||
return FilterChip(
|
||||
label: Text(store.nome),
|
||||
label: Text(store.name),
|
||||
selected: isSelected,
|
||||
onSelected: (selected) {
|
||||
setModalState(() {
|
||||
|
||||
@@ -98,7 +98,7 @@ class StoreRepository {
|
||||
)
|
||||
''')
|
||||
.eq('company_id', companyId)
|
||||
.order('nome');
|
||||
.order('name');
|
||||
|
||||
return (response as List).map((m) => StoreModel.fromMap(m)).toList();
|
||||
} catch (e) {
|
||||
|
||||
@@ -4,30 +4,30 @@ import 'package:flux/features/master_data/staff/models/staff_member_model.dart';
|
||||
|
||||
class StoreModel extends Equatable {
|
||||
final String? id;
|
||||
final String nome;
|
||||
final String name;
|
||||
final String companyId;
|
||||
final bool isActive;
|
||||
final bool isPaid;
|
||||
final DateTime? paymentExpiration;
|
||||
final String indirizzo;
|
||||
final String cap;
|
||||
final String comune;
|
||||
final String provincia;
|
||||
final String address;
|
||||
final String zipCode;
|
||||
final String city;
|
||||
final String province;
|
||||
final List<ProviderModel> associatedProviders; // Provider associati
|
||||
final List<StaffMemberModel>
|
||||
associatedStaffMembers; // Membri dello staff associati
|
||||
|
||||
const StoreModel({
|
||||
this.id,
|
||||
required this.nome,
|
||||
required this.name,
|
||||
required this.companyId,
|
||||
this.isActive = true,
|
||||
this.isPaid = false,
|
||||
this.paymentExpiration,
|
||||
required this.indirizzo,
|
||||
required this.cap,
|
||||
required this.comune,
|
||||
required this.provincia,
|
||||
required this.address,
|
||||
required this.zipCode,
|
||||
required this.city,
|
||||
required this.province,
|
||||
this.associatedProviders = const [],
|
||||
this.associatedStaffMembers = const [],
|
||||
});
|
||||
@@ -36,15 +36,15 @@ class StoreModel extends Equatable {
|
||||
@override
|
||||
List<Object?> get props => [
|
||||
id,
|
||||
nome,
|
||||
name,
|
||||
companyId,
|
||||
isActive,
|
||||
isPaid,
|
||||
paymentExpiration,
|
||||
indirizzo,
|
||||
cap,
|
||||
comune,
|
||||
provincia,
|
||||
address,
|
||||
zipCode,
|
||||
city,
|
||||
province,
|
||||
associatedProviders,
|
||||
associatedStaffMembers,
|
||||
];
|
||||
@@ -52,29 +52,29 @@ class StoreModel extends Equatable {
|
||||
// Il mitico copyWith per creare nuove istanze modificando solo ciò che serve
|
||||
StoreModel copyWith({
|
||||
String? id,
|
||||
String? nome,
|
||||
String? name,
|
||||
String? companyId,
|
||||
bool? isActive,
|
||||
bool? isPaid,
|
||||
DateTime? paymentExpiration,
|
||||
String? indirizzo,
|
||||
String? cap,
|
||||
String? comune,
|
||||
String? provincia,
|
||||
String? address,
|
||||
String? zipCode,
|
||||
String? city,
|
||||
String? province,
|
||||
List<ProviderModel>? associatedProviders,
|
||||
List<StaffMemberModel>? associatedStaffMembers,
|
||||
}) {
|
||||
return StoreModel(
|
||||
id: id ?? this.id,
|
||||
nome: nome ?? this.nome,
|
||||
name: name ?? this.name,
|
||||
companyId: companyId ?? this.companyId,
|
||||
isActive: isActive ?? this.isActive,
|
||||
isPaid: isPaid ?? this.isPaid,
|
||||
paymentExpiration: paymentExpiration ?? this.paymentExpiration,
|
||||
indirizzo: indirizzo ?? this.indirizzo,
|
||||
cap: cap ?? this.cap,
|
||||
comune: comune ?? this.comune,
|
||||
provincia: provincia ?? this.provincia,
|
||||
address: address ?? this.address,
|
||||
zipCode: zipCode ?? this.zipCode,
|
||||
city: city ?? this.city,
|
||||
province: province ?? this.province,
|
||||
associatedProviders: associatedProviders ?? this.associatedProviders,
|
||||
associatedStaffMembers:
|
||||
associatedStaffMembers ?? this.associatedStaffMembers,
|
||||
@@ -83,12 +83,12 @@ class StoreModel extends Equatable {
|
||||
|
||||
factory StoreModel.empty() {
|
||||
return const StoreModel(
|
||||
nome: '',
|
||||
name: '',
|
||||
companyId: '',
|
||||
indirizzo: '',
|
||||
cap: '',
|
||||
comune: '',
|
||||
provincia: '',
|
||||
address: '',
|
||||
zipCode: '',
|
||||
city: '',
|
||||
province: '',
|
||||
);
|
||||
}
|
||||
|
||||
@@ -118,17 +118,17 @@ class StoreModel extends Equatable {
|
||||
}
|
||||
return StoreModel(
|
||||
id: map['id'] as String,
|
||||
nome: map['nome'],
|
||||
name: map['name'],
|
||||
companyId: map['company_id'] as String,
|
||||
isActive: map['is_active'] ?? true,
|
||||
isPaid: map['is_paid'] ?? false,
|
||||
paymentExpiration: map['payment_expiration'] != null
|
||||
? DateTime.parse(map['payment_expiration'])
|
||||
: null,
|
||||
indirizzo: map['indirizzo'],
|
||||
cap: map['cap'],
|
||||
comune: map['comune'],
|
||||
provincia: map['provincia'],
|
||||
address: map['address'],
|
||||
zipCode: map['zip_code'],
|
||||
city: map['city'],
|
||||
province: map['province'],
|
||||
associatedProviders: providers,
|
||||
associatedStaffMembers: staffMembers,
|
||||
);
|
||||
@@ -137,16 +137,16 @@ class StoreModel extends Equatable {
|
||||
Map<String, dynamic> toMap() {
|
||||
return {
|
||||
if (id != null) 'id': id,
|
||||
'nome': nome,
|
||||
'name': name,
|
||||
'company_id': companyId,
|
||||
'is_active': isActive,
|
||||
'is_paid': isPaid,
|
||||
if (paymentExpiration != null)
|
||||
'payment_expiration': paymentExpiration!.toIso8601String(),
|
||||
'indirizzo': indirizzo,
|
||||
'cap': cap,
|
||||
'comune': comune,
|
||||
'provincia': provincia,
|
||||
'address': address,
|
||||
'zip_code': zipCode,
|
||||
'city': city,
|
||||
'province': province,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,14 +37,14 @@ class _CreateStoreScreenState extends State<CreateStoreScreen> {
|
||||
final company = context.read<SessionCubit>().state.company;
|
||||
if (company != null) {
|
||||
setState(() {
|
||||
_indirizzoController.text = company.indirizzo;
|
||||
_capController.text = company.cap;
|
||||
_indirizzoController.text = company.address;
|
||||
_capController.text = company.zipCode;
|
||||
_comuneController.text =
|
||||
company.citta; // Nel DB company è 'citta', store è 'comune'
|
||||
_provinciaController.text = company.provincia;
|
||||
company.city; // Nel DB company è 'citta', store è 'comune'
|
||||
_provinciaController.text = company.province;
|
||||
// Suggeriamo anche un nome se vuoto
|
||||
if (_nomeController.text.isEmpty) {
|
||||
_nomeController.text = '${company.ragioneSociale} - Sede';
|
||||
_nomeController.text = '${company.name} - Sede';
|
||||
}
|
||||
});
|
||||
|
||||
@@ -68,12 +68,12 @@ class _CreateStoreScreenState extends State<CreateStoreScreen> {
|
||||
}
|
||||
|
||||
final store = StoreModel(
|
||||
nome: _nomeController.text.trim(),
|
||||
name: _nomeController.text.trim(),
|
||||
companyId: company.id!,
|
||||
indirizzo: _indirizzoController.text.trim(),
|
||||
cap: _capController.text.trim(),
|
||||
comune: _comuneController.text.trim(),
|
||||
provincia: _provinciaController.text.trim().toUpperCase(),
|
||||
address: _indirizzoController.text.trim(),
|
||||
zipCode: _capController.text.trim(),
|
||||
city: _comuneController.text.trim(),
|
||||
province: _provinciaController.text.trim().toUpperCase(),
|
||||
);
|
||||
|
||||
context.read<StoreCubit>().createStore(store);
|
||||
|
||||
@@ -53,11 +53,11 @@ class _StoreCardState extends State<StoreCard> {
|
||||
color: widget.store.isActive ? context.accent : Colors.grey,
|
||||
),
|
||||
title: Text(
|
||||
widget.store.nome,
|
||||
widget.store.name,
|
||||
style: const TextStyle(fontWeight: FontWeight.bold),
|
||||
),
|
||||
subtitle: Text(
|
||||
"${widget.store.comune} (${widget.store.provincia}) - ${widget.store.indirizzo}",
|
||||
"${widget.store.city} (${widget.store.province}) - ${widget.store.address}",
|
||||
),
|
||||
trailing: Switch(
|
||||
value: widget.store.isActive,
|
||||
@@ -129,7 +129,7 @@ class _StoreCardState extends State<StoreCard> {
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Text(
|
||||
"Personale di ${store.nome}",
|
||||
"Personale di ${store.name}",
|
||||
style: context.titleLarge,
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
@@ -184,14 +184,14 @@ class _StoreCardState extends State<StoreCard> {
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Text("Providers di ${store.nome}", style: context.titleLarge),
|
||||
Text("Providers di ${store.name}", style: context.titleLarge),
|
||||
const SizedBox(height: 16),
|
||||
...state.allProviders.map((provider) {
|
||||
final isAssociated = _tempAssociatedProviders.any(
|
||||
(p) => p.id == provider.id,
|
||||
);
|
||||
return CheckboxListTile(
|
||||
title: Text(provider.nome),
|
||||
title: Text(provider.name),
|
||||
value: isAssociated,
|
||||
onChanged: (selected) {
|
||||
if (selected == true) {
|
||||
|
||||
@@ -24,11 +24,11 @@ class _StoreFormState extends State<StoreForm> {
|
||||
void initState() {
|
||||
super.initState();
|
||||
if (widget.store != null) {
|
||||
nomeController.text = widget.store!.nome;
|
||||
indirizzoController.text = widget.store!.indirizzo;
|
||||
capController.text = widget.store!.cap;
|
||||
comuneController.text = widget.store!.comune;
|
||||
provinciaController.text = widget.store!.provincia;
|
||||
nomeController.text = widget.store!.name;
|
||||
indirizzoController.text = widget.store!.address;
|
||||
capController.text = widget.store!.zipCode;
|
||||
comuneController.text = widget.store!.city;
|
||||
provinciaController.text = widget.store!.province;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -124,11 +124,11 @@ class _StoreFormState extends State<StoreForm> {
|
||||
id: widget
|
||||
.store
|
||||
?.id, // Se nullo, Supabase ne crea uno nuovo
|
||||
nome: nomeController.text,
|
||||
indirizzo: indirizzoController.text,
|
||||
cap: capController.text,
|
||||
comune: comuneController.text,
|
||||
provincia: provinciaController.text,
|
||||
name: nomeController.text,
|
||||
address: indirizzoController.text,
|
||||
zipCode: capController.text,
|
||||
city: comuneController.text,
|
||||
province: provinciaController.text,
|
||||
companyId: context
|
||||
.read<SessionCubit>()
|
||||
.state
|
||||
|
||||
Reference in New Issue
Block a user