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:
2026-05-04 15:36:42 +02:00
committed by brontomark
parent 9f57207a39
commit 94ad524bae
110 changed files with 5831 additions and 5306 deletions

View File

@@ -22,5 +22,5 @@ class CompanyState extends Equatable {
}
@override
List<Object?> get props => [status, errorMessage];
List<Object?> get props => [status, errorMessage, company];
}

View File

@@ -17,7 +17,7 @@ class CompanyRepository {
} on PostgrestException catch (e) {
throw e.message;
} catch (e) {
throw 'Errore imprevisto durante la creazione dell\'azienda';
throw e.toString();
}
}

View File

@@ -45,14 +45,14 @@ class CompanyModel extends Equatable {
final String userId; // Nel DB è user_id (chiave esterna su auth.users)
// Dati Anagrafici e Fatturazione
final String ragioneSociale;
final String indirizzo;
final String cap;
final String citta;
final String provincia;
final String partitaIva;
final String codiceFiscale;
final String codiceUnivoco;
final String name;
final String address;
final String zipCode;
final String city;
final String province;
final String vatId;
final String fiscalCode;
final String sdi;
final String companyLogo;
// Stato Pagamenti (Ibride: manuale + Stripe)
@@ -70,14 +70,14 @@ class CompanyModel extends Equatable {
this.id,
this.createdAt,
required this.userId,
required this.ragioneSociale,
required this.indirizzo,
required this.cap,
required this.citta,
required this.provincia,
required this.partitaIva,
required this.codiceFiscale,
required this.codiceUnivoco,
required this.name,
required this.address,
required this.zipCode,
required this.city,
required this.province,
required this.vatId,
required this.fiscalCode,
required this.sdi,
this.companyLogo = '',
this.isPaid = false,
this.paymentExpiration,
@@ -92,14 +92,14 @@ class CompanyModel extends Equatable {
String? id,
DateTime? createdAt,
String? userId,
String? ragioneSociale,
String? indirizzo,
String? cap,
String? citta,
String? provincia,
String? partitaIva,
String? codiceFiscale,
String? codiceUnivoco,
String? name,
String? address,
String? zipCode,
String? city,
String? province,
String? vatId,
String? fiscalCode,
String? sdi,
String? companyLogo,
bool? isPaid,
DateTime? paymentExpiration,
@@ -113,14 +113,14 @@ class CompanyModel extends Equatable {
id: id ?? this.id,
createdAt: createdAt ?? this.createdAt,
userId: userId ?? this.userId,
ragioneSociale: ragioneSociale ?? this.ragioneSociale,
indirizzo: indirizzo ?? this.indirizzo,
cap: cap ?? this.cap,
citta: citta ?? this.citta,
provincia: provincia ?? this.provincia,
partitaIva: partitaIva ?? this.partitaIva,
codiceFiscale: codiceFiscale ?? this.codiceFiscale,
codiceUnivoco: codiceUnivoco ?? this.codiceUnivoco,
name: name ?? this.name,
address: address ?? this.address,
zipCode: zipCode ?? this.zipCode,
city: city ?? this.city,
province: province ?? this.province,
vatId: vatId ?? this.vatId,
fiscalCode: fiscalCode ?? this.fiscalCode,
sdi: sdi ?? this.sdi,
companyLogo: companyLogo ?? this.companyLogo,
isPaid: isPaid ?? this.isPaid,
paymentExpiration: paymentExpiration ?? this.paymentExpiration,
@@ -137,14 +137,14 @@ class CompanyModel extends Equatable {
id: null,
createdAt: null,
userId: '',
ragioneSociale: '',
indirizzo: '',
cap: '',
citta: '',
provincia: '',
partitaIva: '',
codiceFiscale: '',
codiceUnivoco: '',
name: '',
address: '',
zipCode: '',
city: '',
province: '',
vatId: '',
fiscalCode: '',
sdi: '',
);
}
@@ -155,14 +155,14 @@ class CompanyModel extends Equatable {
? DateTime.tryParse(map['created_at'])
: null,
userId: map['user_id'] ?? '',
ragioneSociale: map['ragione_sociale'] ?? '',
indirizzo: map['indirizzo'] ?? '',
cap: map['cap'] ?? '',
citta: map['citta'] ?? '',
provincia: map['provincia'] ?? '',
partitaIva: map['partita_iva'] ?? '',
codiceFiscale: map['codice_fiscale'] ?? '',
codiceUnivoco: map['codice_univoco'] ?? '',
name: map['name'] ?? '',
address: map['address'] ?? '',
zipCode: map['zip_code'] ?? '',
city: map['city'] ?? '',
province: map['province'] ?? '',
vatId: map['vat_id'] ?? '',
fiscalCode: map['fiscal_code'] ?? '',
sdi: map['sdi'] ?? '',
companyLogo: map['company_logo'] ?? '',
isPaid: map['is_paid'] ?? false,
paymentExpiration: map['payment_expiration'] != null
@@ -185,14 +185,14 @@ class CompanyModel extends Equatable {
if (id != null) 'id': id,
// created_at è gestito dal DB di default, di solito non si passa nell'insert
'user_id': userId,
'ragione_sociale': ragioneSociale,
'indirizzo': indirizzo,
'cap': cap,
'citta': citta,
'provincia': provincia,
'partita_iva': partitaIva,
'codice_fiscale': codiceFiscale,
'codice_univoco': codiceUnivoco,
'name': name,
'address': address,
'zip_code': zipCode,
'city': city,
'province': province,
'vat_id': vatId,
'fiscal_code': fiscalCode,
'sdi': sdi,
'company_logo': companyLogo,
'is_paid': isPaid,
if (paymentExpiration != null)
@@ -213,14 +213,14 @@ class CompanyModel extends Equatable {
id,
createdAt,
userId,
ragioneSociale,
indirizzo,
cap,
citta,
provincia,
partitaIva,
codiceFiscale,
codiceUnivoco,
name,
address,
zipCode,
city,
province,
vatId,
fiscalCode,
sdi,
companyLogo,
isPaid,
paymentExpiration,
@@ -263,7 +263,7 @@ extension CompanyLimits on CompanyModel {
}
}
int get maxServicesPerMonth {
int get maxOperationsPerMonth {
switch (subscriptionTier) {
case SubscriptionTier.free:
return 50;

View File

@@ -1,5 +1,6 @@
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flux/core/utils/extensions.dart';
import 'package:flux/features/company/bloc/company_bloc.dart';
import 'package:flux/core/blocs/session/session_cubit.dart';
import 'package:flux/core/theme/theme.dart';
@@ -49,14 +50,14 @@ class _CreateCompanyScreenState extends State<CreateCompanyScreen> {
final company = CompanyModel(
userId: userId,
ragioneSociale: _ragioneSocialeController.text.trim(),
indirizzo: _indirizzoController.text.trim(),
cap: _capController.text.trim(),
citta: _cittaController.text.trim(),
provincia: _provinciaController.text.trim(),
partitaIva: _pIvaController.text.trim(),
codiceFiscale: _cfController.text.trim(),
codiceUnivoco: _univocoController.text.trim().toUpperCase(),
name: _ragioneSocialeController.text.trim(),
address: _indirizzoController.text.trim(),
zipCode: _capController.text.trim(),
city: _cittaController.text.trim(),
province: _provinciaController.text.trim(),
vatId: _pIvaController.text.trim(),
fiscalCode: _cfController.text.trim(),
sdi: _univocoController.text.trim().toUpperCase(),
// Gli altri campi hanno i default nel modello
);
@@ -69,7 +70,7 @@ class _CreateCompanyScreenState extends State<CreateCompanyScreen> {
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Configurazione Azienda'),
title: Text(context.l10n.createCompanyScreenCompanyConfiguration),
actions: [
IconButton(
icon: const Icon(Icons.logout_rounded),
@@ -98,7 +99,7 @@ class _CreateCompanyScreenState extends State<CreateCompanyScreen> {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(
state.errorMessage ?? 'Errore durante il salvataggio',
state.errorMessage ?? context.l10n.commonSavingError,
),
backgroundColor: Colors.redAccent,
),
@@ -118,10 +119,12 @@ class _CreateCompanyScreenState extends State<CreateCompanyScreen> {
const SizedBox(height: 32),
// --- SEZIONE 1: IDENTITÀ FISCALE ---
_SectionTitle(title: 'DATI FISCALI'),
_SectionTitle(
title: context.l10n.createCompanyScreenFiscalData,
),
const SizedBox(height: 16),
FluxTextField(
label: 'Ragione Sociale',
label: context.l10n.createCompanyScreenCompanyName,
icon: Icons.business,
controller: _ragioneSocialeController,
),
@@ -130,7 +133,7 @@ class _CreateCompanyScreenState extends State<CreateCompanyScreen> {
children: [
Expanded(
child: FluxTextField(
label: 'Partita IVA',
label: context.l10n.createCompanyScreenVatId,
icon: Icons.numbers,
controller: _pIvaController,
),
@@ -138,7 +141,7 @@ class _CreateCompanyScreenState extends State<CreateCompanyScreen> {
const SizedBox(width: 12),
Expanded(
child: FluxTextField(
label: 'Codice Fiscale',
label: context.l10n.createCompanyScreenFiscalCode,
icon: Icons.badge_outlined,
controller: _cfController,
),
@@ -147,7 +150,7 @@ class _CreateCompanyScreenState extends State<CreateCompanyScreen> {
),
const SizedBox(height: 16),
FluxTextField(
label: 'Codice Univoco (SDI) / PEC',
label: context.l10n.createCompanyScreenSdiPec,
icon: Icons.send_and_archive_outlined,
controller: _univocoController,
),
@@ -155,10 +158,13 @@ class _CreateCompanyScreenState extends State<CreateCompanyScreen> {
const SizedBox(height: 32),
// --- SEZIONE 2: SEDE LEGALE ---
_SectionTitle(title: 'SEDE LEGALE'),
_SectionTitle(
title:
context.l10n.createCompanyScreenCompanyLegalAddress,
),
const SizedBox(height: 16),
FluxTextField(
label: 'Indirizzo e n. civico',
label: context.l10n.commonAddress,
icon: Icons.home_work_outlined,
controller: _indirizzoController,
),
@@ -168,7 +174,7 @@ class _CreateCompanyScreenState extends State<CreateCompanyScreen> {
Expanded(
flex: 2,
child: FluxTextField(
label: 'Città',
label: context.l10n.commonCity,
icon: Icons.location_city,
controller: _cittaController,
),
@@ -176,7 +182,7 @@ class _CreateCompanyScreenState extends State<CreateCompanyScreen> {
const SizedBox(width: 12),
Expanded(
child: FluxTextField(
label: 'CAP',
label: context.l10n.commonZipCode,
icon: Icons.map_outlined,
controller: _capController,
),
@@ -184,7 +190,7 @@ class _CreateCompanyScreenState extends State<CreateCompanyScreen> {
const SizedBox(width: 12),
Expanded(
child: FluxTextField(
label: 'Prov',
label: context.l10n.commonProvince,
icon: Icons.explore_outlined,
controller: _provinciaController,
),
@@ -232,7 +238,7 @@ class _CreateCompanyScreenState extends State<CreateCompanyScreen> {
Icon(Icons.cloud_upload_outlined, color: context.accent, size: 32),
const SizedBox(height: 12),
Text(
'Carica Logo Aziendale',
context.l10n.createCompanyScreenUploadLogo,
style: TextStyle(
color: context.primaryText,
fontWeight: FontWeight.bold,
@@ -240,7 +246,7 @@ class _CreateCompanyScreenState extends State<CreateCompanyScreen> {
),
const SizedBox(height: 4),
Text(
'Verrà usato per le tue stampe e ricevute',
context.l10n.createCompanyScreenWillBeUsedForReceipts,
textAlign: TextAlign.center,
style: TextStyle(color: context.secondaryText, fontSize: 12),
),
@@ -259,7 +265,7 @@ class _CreateCompanyScreenState extends State<CreateCompanyScreen> {
: () => _onSave(),
child: state.status == CompanyStatus.loading
? const CircularProgressIndicator()
: const Text('SALVA AZIENDA'),
: Text(context.l10n.createCompanyScreenSaveCompany),
),
);
}
@@ -282,7 +288,7 @@ class _CreateCompanyScreenState extends State<CreateCompanyScreen> {
),
const SizedBox(height: 24),
Text(
'Configura la tua Azienda',
context.l10n.createCompanyScreenSetupYourCompany,
style: Theme.of(context).textTheme.headlineMedium?.copyWith(
fontWeight: FontWeight.bold,
color: context.primaryText,
@@ -290,7 +296,7 @@ class _CreateCompanyScreenState extends State<CreateCompanyScreen> {
),
const SizedBox(height: 12),
Text(
'FLUX ha bisogno dei tuoi dati fiscali per gestire correttamente le fatturazioni e le attivazioni dei tuoi negozi.',
context.l10n.createCompanyScreenFluxNeedsYourFiscalData,
style: TextStyle(
color: context.secondaryText,
fontSize: 15,