|
@@ -2,15 +2,13 @@ import 'package:flutter/material.dart';
|
|
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
|
|
import 'package:intl/intl.dart';
|
|
import 'package:intl/intl.dart';
|
|
|
import 'package:ristoris/core/credit_score_color.dart';
|
|
import 'package:ristoris/core/credit_score_color.dart';
|
|
|
-import '../../../database/daos/sconti_dao.dart';
|
|
|
|
|
import '../../../providers/auth_provider.dart';
|
|
import '../../../providers/auth_provider.dart';
|
|
|
import '../../widgets/cod_desc_dropdown_item.dart';
|
|
import '../../widgets/cod_desc_dropdown_item.dart';
|
|
|
import '../../../providers/order_provider.dart';
|
|
import '../../../providers/order_provider.dart';
|
|
|
import '../../../providers/database_provider.dart';
|
|
import '../../../providers/database_provider.dart';
|
|
|
import '../../../database/database.dart';
|
|
import '../../../database/database.dart';
|
|
|
-import '../../../database/daos/listini_dao.dart';
|
|
|
|
|
-import '../../widgets/article_image.dart';
|
|
|
|
|
import 'selezione_cliente_page.dart';
|
|
import 'selezione_cliente_page.dart';
|
|
|
|
|
+import 'selezione_articolo_page.dart';
|
|
|
|
|
|
|
|
class OrderEditPage extends ConsumerStatefulWidget {
|
|
class OrderEditPage extends ConsumerStatefulWidget {
|
|
|
final int? id;
|
|
final int? id;
|
|
@@ -25,15 +23,10 @@ class _OrderEditPageState extends ConsumerState<OrderEditPage>
|
|
|
with SingleTickerProviderStateMixin {
|
|
with SingleTickerProviderStateMixin {
|
|
|
late TabController _tabController;
|
|
late TabController _tabController;
|
|
|
|
|
|
|
|
- final _artCtrl = TextEditingController();
|
|
|
|
|
final _noteClienteCtrl = TextEditingController();
|
|
final _noteClienteCtrl = TextEditingController();
|
|
|
final _noteOrdineCtrl = TextEditingController();
|
|
final _noteOrdineCtrl = TextEditingController();
|
|
|
final _riferimentoCtrl = TextEditingController();
|
|
final _riferimentoCtrl = TextEditingController();
|
|
|
|
|
|
|
|
- List<Articolo> _searchResults = [];
|
|
|
|
|
- bool _searching = false;
|
|
|
|
|
- bool _usaListinoCliente = true;
|
|
|
|
|
-
|
|
|
|
|
List<Filiale> _filiali = [];
|
|
List<Filiale> _filiali = [];
|
|
|
List<Listino> _listini = [];
|
|
List<Listino> _listini = [];
|
|
|
List<Pagamento> _pagamenti = [];
|
|
List<Pagamento> _pagamenti = [];
|
|
@@ -49,18 +42,13 @@ class _OrderEditPageState extends ConsumerState<OrderEditPage>
|
|
|
void initState() {
|
|
void initState() {
|
|
|
super.initState();
|
|
super.initState();
|
|
|
_tabController = TabController(length: 2, vsync: this);
|
|
_tabController = TabController(length: 2, vsync: this);
|
|
|
- _tabController.addListener(() {
|
|
|
|
|
- if (_tabController.index == 1 && _searchResults.isEmpty && _artCtrl.text.isEmpty) {
|
|
|
|
|
- _searchArticles('');
|
|
|
|
|
- }
|
|
|
|
|
- });
|
|
|
|
|
|
|
+ _tabController.addListener(() => setState(() {}));
|
|
|
WidgetsBinding.instance.addPostFrameCallback((_) => _init());
|
|
WidgetsBinding.instance.addPostFrameCallback((_) => _init());
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
@override
|
|
@override
|
|
|
void dispose() {
|
|
void dispose() {
|
|
|
_tabController.dispose();
|
|
_tabController.dispose();
|
|
|
- _artCtrl.dispose();
|
|
|
|
|
_noteClienteCtrl.dispose();
|
|
_noteClienteCtrl.dispose();
|
|
|
_noteOrdineCtrl.dispose();
|
|
_noteOrdineCtrl.dispose();
|
|
|
_riferimentoCtrl.dispose();
|
|
_riferimentoCtrl.dispose();
|
|
@@ -109,86 +97,39 @@ class _OrderEditPageState extends ConsumerState<OrderEditPage>
|
|
|
});
|
|
});
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- Future<void> _searchArticles(String q) async {
|
|
|
|
|
- setState(() => _searching = true);
|
|
|
|
|
- final dao = ref.read(articoliDaoProvider);
|
|
|
|
|
- final order = ref.read(orderProvider).order;
|
|
|
|
|
- final dataOrdine = order?.dataOrdine ?? DateTime.now().toIso8601String();
|
|
|
|
|
- List<Articolo> results;
|
|
|
|
|
- if (_usaListinoCliente && _cliente != null) {
|
|
|
|
|
- results = await dao.getArticoliPerListinoCliente(_cliente!.idCliente, dataOrdine);
|
|
|
|
|
- } else {
|
|
|
|
|
- results = await dao.getArticoliPerListinoAttivo(dataOrdine);
|
|
|
|
|
- }
|
|
|
|
|
- if (q.isNotEmpty) {
|
|
|
|
|
- final lower = q.toLowerCase();
|
|
|
|
|
- results = results.where((a) {
|
|
|
|
|
- final cod = (a.codArticolo ?? '').toLowerCase();
|
|
|
|
|
- final desc = (a.descrizione ?? '').toLowerCase();
|
|
|
|
|
- final ean = (a.ean ?? '').toLowerCase();
|
|
|
|
|
- return cod.contains(lower) || desc.contains(lower) || ean.contains(lower);
|
|
|
|
|
- }).toList();
|
|
|
|
|
- }
|
|
|
|
|
- setState(() {
|
|
|
|
|
- _searchResults = results;
|
|
|
|
|
- _searching = false;
|
|
|
|
|
- });
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- void _showArticlePicker(Articolo art) async {
|
|
|
|
|
- final agente = ref.read(authProvider).agente;
|
|
|
|
|
- final canEditPrice = agente?.modificaPrezzi == 1;
|
|
|
|
|
|
|
+ void _aggiungiArticolo() async {
|
|
|
final order = ref.read(orderProvider).order;
|
|
final order = ref.read(orderProvider).order;
|
|
|
final dataOrdine = order?.dataOrdine ?? DateTime.now().toIso8601String();
|
|
final dataOrdine = order?.dataOrdine ?? DateTime.now().toIso8601String();
|
|
|
- final listini = await ref
|
|
|
|
|
- .read(listiniDaoProvider)
|
|
|
|
|
- .getListiniPerArticolo(art.idArticolo, dataOrdine);
|
|
|
|
|
- final listiniDao = ref.read(listiniDaoProvider);
|
|
|
|
|
- final scontiDao = ref.read(scontiDaoProvider);
|
|
|
|
|
- if (!context.mounted) return;
|
|
|
|
|
|
|
|
|
|
- showModalBottomSheet(
|
|
|
|
|
- context: context,
|
|
|
|
|
- isScrollControlled: true,
|
|
|
|
|
- builder: (_) => _ArticlePickerSheet(
|
|
|
|
|
- articolo: art,
|
|
|
|
|
- listini: listini,
|
|
|
|
|
- listiniDao: listiniDao,
|
|
|
|
|
- scontiDao: scontiDao,
|
|
|
|
|
- dataOrdine: dataOrdine,
|
|
|
|
|
- canEditPrezzo: canEditPrice,
|
|
|
|
|
- idListinoDefault: _selectedListino,
|
|
|
|
|
- onConfirm: (
|
|
|
|
|
- colli,
|
|
|
|
|
- quantita,
|
|
|
|
|
- prezzoLordo,
|
|
|
|
|
- prezzoNetto,
|
|
|
|
|
- listinoId, {
|
|
|
|
|
- double sconto1 = 0,
|
|
|
|
|
- double sconto2 = 0,
|
|
|
|
|
- double sconto3 = 0,
|
|
|
|
|
- double sconto4 = 0,
|
|
|
|
|
- double sconto5 = 0,
|
|
|
|
|
- }) {
|
|
|
|
|
- _addArticleWithDetails(
|
|
|
|
|
- art: art,
|
|
|
|
|
- idListino: listinoId,
|
|
|
|
|
- colli: colli,
|
|
|
|
|
- quantita: quantita,
|
|
|
|
|
- prezzoLordo: prezzoLordo,
|
|
|
|
|
- prezzoNetto: prezzoNetto,
|
|
|
|
|
- sconto1: sconto1,
|
|
|
|
|
- sconto2: sconto2,
|
|
|
|
|
- sconto3: sconto3,
|
|
|
|
|
- sconto4: sconto4,
|
|
|
|
|
- sconto5: sconto5,
|
|
|
|
|
- );
|
|
|
|
|
- },
|
|
|
|
|
|
|
+ final result = await Navigator.push<ArticleSelectionResult>(
|
|
|
|
|
+ context,
|
|
|
|
|
+ MaterialPageRoute(
|
|
|
|
|
+ builder: (_) => SelezioneArticoloPage(
|
|
|
|
|
+ idCliente: _cliente?.idCliente ?? 0,
|
|
|
|
|
+ dataOrdine: dataOrdine,
|
|
|
|
|
+ idListinoDefault: _selectedListino,
|
|
|
|
|
+ ),
|
|
|
),
|
|
),
|
|
|
);
|
|
);
|
|
|
|
|
+
|
|
|
|
|
+ if (result != null) {
|
|
|
|
|
+ _addArticleWithDetails(
|
|
|
|
|
+ art: result.articolo,
|
|
|
|
|
+ idListino: result.idListino,
|
|
|
|
|
+ colli: result.colli,
|
|
|
|
|
+ quantita: result.quantita,
|
|
|
|
|
+ prezzoLordo: result.prezzoLordo,
|
|
|
|
|
+ prezzoNetto: result.prezzoNetto,
|
|
|
|
|
+ sconto1: result.sconto1,
|
|
|
|
|
+ sconto2: result.sconto2,
|
|
|
|
|
+ sconto3: result.sconto3,
|
|
|
|
|
+ sconto4: result.sconto4,
|
|
|
|
|
+ sconto5: result.sconto5,
|
|
|
|
|
+ );
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- Future<void> _addArticleWithDetails({
|
|
|
|
|
|
|
+ void _addArticleWithDetails({
|
|
|
required Articolo art,
|
|
required Articolo art,
|
|
|
required int idListino,
|
|
required int idListino,
|
|
|
required double colli,
|
|
required double colli,
|
|
@@ -200,21 +141,11 @@ class _OrderEditPageState extends ConsumerState<OrderEditPage>
|
|
|
double? sconto3 = 0,
|
|
double? sconto3 = 0,
|
|
|
double? sconto4 = 0,
|
|
double? sconto4 = 0,
|
|
|
double? sconto5 = 0,
|
|
double? sconto5 = 0,
|
|
|
- }) async {
|
|
|
|
|
- final orderState = ref.read(orderProvider);
|
|
|
|
|
- var idOrdine = orderState.order?.idOrdine;
|
|
|
|
|
- if (idOrdine == null || idOrdine == 0) {
|
|
|
|
|
- await ref.read(orderProvider.notifier).saveOrder();
|
|
|
|
|
- idOrdine = ref.read(orderProvider).order?.idOrdine;
|
|
|
|
|
- if (idOrdine == null || idOrdine == 0) return;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- await ref
|
|
|
|
|
- .read(orderProvider.notifier)
|
|
|
|
|
- .addLine(
|
|
|
|
|
|
|
+ }) {
|
|
|
|
|
+ ref.read(orderProvider.notifier).addLine(
|
|
|
RigaOrdine(
|
|
RigaOrdine(
|
|
|
idRigaOrdine: 0,
|
|
idRigaOrdine: 0,
|
|
|
- idOrdine: idOrdine,
|
|
|
|
|
|
|
+ idOrdine: ref.read(orderProvider).order?.idOrdine ?? 0,
|
|
|
idArticolo: art.idArticolo,
|
|
idArticolo: art.idArticolo,
|
|
|
idListino: idListino,
|
|
idListino: idListino,
|
|
|
quantita: quantita,
|
|
quantita: quantita,
|
|
@@ -231,8 +162,6 @@ class _OrderEditPageState extends ConsumerState<OrderEditPage>
|
|
|
colli: colli,
|
|
colli: colli,
|
|
|
),
|
|
),
|
|
|
);
|
|
);
|
|
|
- _artCtrl.clear();
|
|
|
|
|
- setState(() => _searchResults = []);
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
Future<void> _selezionaCliente() async {
|
|
Future<void> _selezionaCliente() async {
|
|
@@ -284,6 +213,12 @@ class _OrderEditPageState extends ConsumerState<OrderEditPage>
|
|
|
return Scaffold(
|
|
return Scaffold(
|
|
|
appBar: AppBar(
|
|
appBar: AppBar(
|
|
|
title: Text('Ordine #${orderState.order?.numeroOrdine ?? 'nuovo'}'),
|
|
title: Text('Ordine #${orderState.order?.numeroOrdine ?? 'nuovo'}'),
|
|
|
|
|
+ actions: [
|
|
|
|
|
+ IconButton(
|
|
|
|
|
+ icon: const Icon(Icons.save),
|
|
|
|
|
+ onPressed: _salva,
|
|
|
|
|
+ ),
|
|
|
|
|
+ ],
|
|
|
bottom: TabBar(
|
|
bottom: TabBar(
|
|
|
controller: _tabController,
|
|
controller: _tabController,
|
|
|
tabs: const [
|
|
tabs: const [
|
|
@@ -303,12 +238,10 @@ class _OrderEditPageState extends ConsumerState<OrderEditPage>
|
|
|
],
|
|
],
|
|
|
),
|
|
),
|
|
|
),
|
|
),
|
|
|
- floatingActionButton:
|
|
|
|
|
- _tabController.index == 1 && orderState.order?.idOrdine != null
|
|
|
|
|
- ? FloatingActionButton.extended(
|
|
|
|
|
- onPressed: _salva,
|
|
|
|
|
- icon: const Icon(Icons.save),
|
|
|
|
|
- label: const Text('Salva'),
|
|
|
|
|
|
|
+ floatingActionButton: _tabController.index == 1 && _cliente != null
|
|
|
|
|
+ ? FloatingActionButton(
|
|
|
|
|
+ onPressed: _aggiungiArticolo,
|
|
|
|
|
+ child: const Icon(Icons.add),
|
|
|
)
|
|
)
|
|
|
: null,
|
|
: null,
|
|
|
);
|
|
);
|
|
@@ -485,58 +418,6 @@ class _OrderEditPageState extends ConsumerState<OrderEditPage>
|
|
|
Widget _buildLinesTab(ThemeData theme, OrderState orderState) {
|
|
Widget _buildLinesTab(ThemeData theme, OrderState orderState) {
|
|
|
return Column(
|
|
return Column(
|
|
|
children: [
|
|
children: [
|
|
|
- Padding(
|
|
|
|
|
- padding: const EdgeInsets.all(12),
|
|
|
|
|
- child: Row(
|
|
|
|
|
- children: [
|
|
|
|
|
- Expanded(
|
|
|
|
|
- child: TextField(
|
|
|
|
|
- controller: _artCtrl,
|
|
|
|
|
- decoration: InputDecoration(
|
|
|
|
|
- hintText: 'Cerca articolo...',
|
|
|
|
|
- prefixIcon: const Icon(Icons.search),
|
|
|
|
|
- suffixIcon: _searching
|
|
|
|
|
- ? const SizedBox(
|
|
|
|
|
- width: 20,
|
|
|
|
|
- height: 20,
|
|
|
|
|
- child: CircularProgressIndicator(strokeWidth: 2),
|
|
|
|
|
- )
|
|
|
|
|
- : null,
|
|
|
|
|
- ),
|
|
|
|
|
- onChanged: _searchArticles,
|
|
|
|
|
- ),
|
|
|
|
|
- ),
|
|
|
|
|
- const SizedBox(width: 8),
|
|
|
|
|
- FilterChip(
|
|
|
|
|
- label: const Text('Listino cliente'),
|
|
|
|
|
- selected: _usaListinoCliente,
|
|
|
|
|
- onSelected: (v) {
|
|
|
|
|
- setState(() => _usaListinoCliente = v);
|
|
|
|
|
- _searchArticles(_artCtrl.text);
|
|
|
|
|
- },
|
|
|
|
|
- ),
|
|
|
|
|
- ],
|
|
|
|
|
- ),
|
|
|
|
|
- ),
|
|
|
|
|
- if (_searchResults.isNotEmpty)
|
|
|
|
|
- SizedBox(
|
|
|
|
|
- height: 200,
|
|
|
|
|
- child: ListView.builder(
|
|
|
|
|
- itemCount: _searchResults.length,
|
|
|
|
|
- itemBuilder: (_, i) => ListTile(
|
|
|
|
|
- leading: ArticleImage(
|
|
|
|
|
- idArticolo: _searchResults[i].idArticolo,
|
|
|
|
|
- codArticolo: _searchResults[i].codArticolo,
|
|
|
|
|
- ),
|
|
|
|
|
- title: Text(_searchResults[i].descrizione ?? ''),
|
|
|
|
|
- subtitle: Text(_searchResults[i].codArticolo ?? ''),
|
|
|
|
|
- trailing: TextButton(
|
|
|
|
|
- onPressed: () => _showArticlePicker(_searchResults[i]),
|
|
|
|
|
- child: const Text('Aggiungi'),
|
|
|
|
|
- ),
|
|
|
|
|
- ),
|
|
|
|
|
- ),
|
|
|
|
|
- ),
|
|
|
|
|
Expanded(
|
|
Expanded(
|
|
|
child: orderState.lines.isEmpty
|
|
child: orderState.lines.isEmpty
|
|
|
? const Center(child: Text('Nessun articolo'))
|
|
? const Center(child: Text('Nessun articolo'))
|
|
@@ -544,9 +425,8 @@ class _OrderEditPageState extends ConsumerState<OrderEditPage>
|
|
|
itemCount: orderState.lines.length,
|
|
itemCount: orderState.lines.length,
|
|
|
itemBuilder: (_, i) => _LineCard(
|
|
itemBuilder: (_, i) => _LineCard(
|
|
|
line: orderState.lines[i],
|
|
line: orderState.lines[i],
|
|
|
- onDelete: () => ref
|
|
|
|
|
- .read(orderProvider.notifier)
|
|
|
|
|
- .removeLine(orderState.lines[i].idRigaOrdine),
|
|
|
|
|
|
|
+ onDelete: () =>
|
|
|
|
|
+ ref.read(orderProvider.notifier).removeLine(i),
|
|
|
theme: theme,
|
|
theme: theme,
|
|
|
),
|
|
),
|
|
|
),
|
|
),
|
|
@@ -626,383 +506,3 @@ class _LineCard extends StatelessWidget {
|
|
|
);
|
|
);
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
-class _ArticlePickerSheet extends StatefulWidget {
|
|
|
|
|
- final Articolo articolo;
|
|
|
|
|
- final List<Listino> listini;
|
|
|
|
|
- final ListiniDao listiniDao;
|
|
|
|
|
- final ScontiDao scontiDao;
|
|
|
|
|
- final String dataOrdine;
|
|
|
|
|
- final bool canEditPrezzo;
|
|
|
|
|
- final int? idListinoDefault;
|
|
|
|
|
- final void Function(
|
|
|
|
|
- double colli,
|
|
|
|
|
- double quantita,
|
|
|
|
|
- double prezzoLordo,
|
|
|
|
|
- double prezzoNetto,
|
|
|
|
|
- int listinoId, {
|
|
|
|
|
- double sconto1,
|
|
|
|
|
- double sconto2,
|
|
|
|
|
- double sconto3,
|
|
|
|
|
- double sconto4,
|
|
|
|
|
- double sconto5,
|
|
|
|
|
- })
|
|
|
|
|
- onConfirm;
|
|
|
|
|
-
|
|
|
|
|
- const _ArticlePickerSheet({
|
|
|
|
|
- required this.articolo,
|
|
|
|
|
- required this.listini,
|
|
|
|
|
- required this.listiniDao,
|
|
|
|
|
- required this.scontiDao,
|
|
|
|
|
- required this.dataOrdine,
|
|
|
|
|
- required this.canEditPrezzo,
|
|
|
|
|
- this.idListinoDefault,
|
|
|
|
|
- required this.onConfirm,
|
|
|
|
|
- });
|
|
|
|
|
-
|
|
|
|
|
- @override
|
|
|
|
|
- State<_ArticlePickerSheet> createState() => _ArticlePickerSheetState();
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-class _ArticlePickerSheetState extends State<_ArticlePickerSheet> {
|
|
|
|
|
- final _colliCtrl = TextEditingController();
|
|
|
|
|
- final _qtaCtrl = TextEditingController();
|
|
|
|
|
- final _prezzoCtrl = TextEditingController();
|
|
|
|
|
- final _sconto1Ctrl = TextEditingController();
|
|
|
|
|
- final _sconto2Ctrl = TextEditingController();
|
|
|
|
|
- final _sconto3Ctrl = TextEditingController();
|
|
|
|
|
- final _sconto4Ctrl = TextEditingController();
|
|
|
|
|
- final _sconto5Ctrl = TextEditingController();
|
|
|
|
|
-
|
|
|
|
|
- int? _selectedListino;
|
|
|
|
|
- double _prezzo = 0;
|
|
|
|
|
- double _prezzoNetto = 0;
|
|
|
|
|
- double _sconto1 = 0;
|
|
|
|
|
- double _sconto2 = 0;
|
|
|
|
|
- double _sconto3 = 0;
|
|
|
|
|
- double _sconto4 = 0;
|
|
|
|
|
- double _sconto5 = 0;
|
|
|
|
|
-
|
|
|
|
|
- bool _updatingColli = false;
|
|
|
|
|
- bool _updatingQta = false;
|
|
|
|
|
-
|
|
|
|
|
- @override
|
|
|
|
|
- void initState() {
|
|
|
|
|
- super.initState();
|
|
|
|
|
- _selectedListino = widget.idListinoDefault;
|
|
|
|
|
- if (_selectedListino != null) {
|
|
|
|
|
- _loadPrezzo(_selectedListino!);
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- @override
|
|
|
|
|
- void dispose() {
|
|
|
|
|
- _colliCtrl.dispose();
|
|
|
|
|
- _qtaCtrl.dispose();
|
|
|
|
|
- _prezzoCtrl.dispose();
|
|
|
|
|
- _sconto1Ctrl.dispose();
|
|
|
|
|
- _sconto2Ctrl.dispose();
|
|
|
|
|
- _sconto3Ctrl.dispose();
|
|
|
|
|
- _sconto4Ctrl.dispose();
|
|
|
|
|
- _sconto5Ctrl.dispose();
|
|
|
|
|
- super.dispose();
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- Future<void> _loadPrezzo(int idListino) async {
|
|
|
|
|
- final lp = await widget.listiniDao.findListinoArticolo(
|
|
|
|
|
- idListino,
|
|
|
|
|
- widget.articolo.idArticolo,
|
|
|
|
|
- );
|
|
|
|
|
- if (lp != null) {
|
|
|
|
|
- if (lp.prezzo != null) {
|
|
|
|
|
- setState(() => _prezzo = lp.prezzo!);
|
|
|
|
|
- _prezzoCtrl.text = _prezzo.toStringAsFixed(2);
|
|
|
|
|
- }
|
|
|
|
|
- if (lp.idSconto != null) {
|
|
|
|
|
- final sconto = await widget.scontiDao.findById(lp.idSconto!);
|
|
|
|
|
- setState(() {
|
|
|
|
|
- _sconto1 = sconto?.sconto1 ?? 0;
|
|
|
|
|
- _sconto2 = sconto?.sconto2 ?? 0;
|
|
|
|
|
- _sconto3 = sconto?.sconto3 ?? 0;
|
|
|
|
|
- _sconto4 = sconto?.sconto4 ?? 0;
|
|
|
|
|
- _sconto5 = sconto?.sconto5 ?? 0;
|
|
|
|
|
- });
|
|
|
|
|
- _sconto1Ctrl.text = _sconto1 > 0 ? _sconto1.toStringAsFixed(1) : '';
|
|
|
|
|
- _sconto2Ctrl.text = _sconto2 > 0 ? _sconto2.toStringAsFixed(1) : '';
|
|
|
|
|
- _sconto3Ctrl.text = _sconto3 > 0 ? _sconto3.toStringAsFixed(1) : '';
|
|
|
|
|
- _sconto4Ctrl.text = _sconto4 > 0 ? _sconto4.toStringAsFixed(1) : '';
|
|
|
|
|
- _sconto5Ctrl.text = _sconto5 > 0 ? _sconto5.toStringAsFixed(1) : '';
|
|
|
|
|
- } else {
|
|
|
|
|
- _resetSconti();
|
|
|
|
|
- }
|
|
|
|
|
- _calcolaPrezzoNetto();
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- void _resetSconti() {
|
|
|
|
|
- setState(() {
|
|
|
|
|
- _sconto1 = 0;
|
|
|
|
|
- _sconto2 = 0;
|
|
|
|
|
- _sconto3 = 0;
|
|
|
|
|
- _sconto4 = 0;
|
|
|
|
|
- _sconto5 = 0;
|
|
|
|
|
- });
|
|
|
|
|
- _sconto1Ctrl.clear();
|
|
|
|
|
- _sconto2Ctrl.clear();
|
|
|
|
|
- _sconto3Ctrl.clear();
|
|
|
|
|
- _sconto4Ctrl.clear();
|
|
|
|
|
- _sconto5Ctrl.clear();
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- void _calcolaPrezzoNetto() {
|
|
|
|
|
- double n = _prezzo;
|
|
|
|
|
- n *= (100 - _sconto1) / 100;
|
|
|
|
|
- n *= (100 - _sconto2) / 100;
|
|
|
|
|
- n *= (100 - _sconto3) / 100;
|
|
|
|
|
- n *= (100 - _sconto4) / 100;
|
|
|
|
|
- n *= (100 - _sconto5) / 100;
|
|
|
|
|
- setState(() => _prezzoNetto = n);
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- void _onPrezzoChanged(String v) {
|
|
|
|
|
- setState(() => _prezzo = double.tryParse(v) ?? 0);
|
|
|
|
|
- _calcolaPrezzoNetto();
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- void _onScontoChanged(int index, String v) {
|
|
|
|
|
- final val = double.tryParse(v) ?? 0;
|
|
|
|
|
- setState(() {
|
|
|
|
|
- switch (index) {
|
|
|
|
|
- case 1:
|
|
|
|
|
- _sconto1 = val;
|
|
|
|
|
- case 2:
|
|
|
|
|
- _sconto2 = val;
|
|
|
|
|
- case 3:
|
|
|
|
|
- _sconto3 = val;
|
|
|
|
|
- case 4:
|
|
|
|
|
- _sconto4 = val;
|
|
|
|
|
- case 5:
|
|
|
|
|
- _sconto5 = val;
|
|
|
|
|
- }
|
|
|
|
|
- });
|
|
|
|
|
- _calcolaPrezzoNetto();
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- void _onColliChanged(String v) {
|
|
|
|
|
- if (_updatingColli) return;
|
|
|
|
|
- _updatingQta = true;
|
|
|
|
|
- final colli = double.tryParse(v) ?? 0;
|
|
|
|
|
- final pezzi = widget.articolo.pezziConfezione ?? 0;
|
|
|
|
|
- if (colli > 0 && pezzi > 0) {
|
|
|
|
|
- _qtaCtrl.text = (colli * pezzi).toStringAsFixed(1);
|
|
|
|
|
- } else if (colli == 0) {
|
|
|
|
|
- _qtaCtrl.text = '';
|
|
|
|
|
- }
|
|
|
|
|
- _updatingQta = false;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- void _onQtaChanged(String v) {
|
|
|
|
|
- if (_updatingQta) return;
|
|
|
|
|
- _updatingColli = true;
|
|
|
|
|
- final qta = double.tryParse(v) ?? 0;
|
|
|
|
|
- if (qta > 0) {
|
|
|
|
|
- _colliCtrl.text = '0';
|
|
|
|
|
- } else if (qta == 0) {
|
|
|
|
|
- _colliCtrl.text = '';
|
|
|
|
|
- }
|
|
|
|
|
- _updatingColli = false;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- void _confirm() {
|
|
|
|
|
- final colli = double.tryParse(_colliCtrl.text) ?? 0;
|
|
|
|
|
- final qta = double.tryParse(_qtaCtrl.text) ?? 0;
|
|
|
|
|
- final prezzoLordo = double.tryParse(_prezzoCtrl.text) ?? 0;
|
|
|
|
|
- final listinoId = _selectedListino ?? 0;
|
|
|
|
|
- widget.onConfirm(
|
|
|
|
|
- colli,
|
|
|
|
|
- qta,
|
|
|
|
|
- prezzoLordo,
|
|
|
|
|
- _prezzoNetto,
|
|
|
|
|
- listinoId,
|
|
|
|
|
- sconto1: _sconto1,
|
|
|
|
|
- sconto2: _sconto2,
|
|
|
|
|
- sconto3: _sconto3,
|
|
|
|
|
- sconto4: _sconto4,
|
|
|
|
|
- sconto5: _sconto5,
|
|
|
|
|
- );
|
|
|
|
|
- Navigator.pop(context);
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- @override
|
|
|
|
|
- Widget build(BuildContext context) {
|
|
|
|
|
- final theme = Theme.of(context);
|
|
|
|
|
- return Padding(
|
|
|
|
|
- padding: EdgeInsets.only(
|
|
|
|
|
- bottom: MediaQuery.of(context).viewInsets.bottom,
|
|
|
|
|
- left: 16,
|
|
|
|
|
- right: 16,
|
|
|
|
|
- top: 16,
|
|
|
|
|
- ),
|
|
|
|
|
- child: SingleChildScrollView(
|
|
|
|
|
- child: Column(
|
|
|
|
|
- mainAxisSize: MainAxisSize.min,
|
|
|
|
|
- crossAxisAlignment: CrossAxisAlignment.start,
|
|
|
|
|
- children: [
|
|
|
|
|
- Text(
|
|
|
|
|
- widget.articolo.descrizione ?? '',
|
|
|
|
|
- style: theme.textTheme.titleMedium,
|
|
|
|
|
- ),
|
|
|
|
|
- const SizedBox(height: 4),
|
|
|
|
|
- Text(
|
|
|
|
|
- widget.articolo.codArticolo ?? '',
|
|
|
|
|
- style: theme.textTheme.bodySmall,
|
|
|
|
|
- ),
|
|
|
|
|
- if (widget.articolo.pezziConfezione != null)
|
|
|
|
|
- Text(
|
|
|
|
|
- 'Pezzi/confezione: ${widget.articolo.pezziConfezione}',
|
|
|
|
|
- style: theme.textTheme.bodySmall,
|
|
|
|
|
- ),
|
|
|
|
|
- const SizedBox(height: 16),
|
|
|
|
|
- DropdownButtonFormField<int>(
|
|
|
|
|
- value: _selectedListino,
|
|
|
|
|
- decoration: const InputDecoration(labelText: 'Listino'),
|
|
|
|
|
- isExpanded: true,
|
|
|
|
|
- items: widget.listini
|
|
|
|
|
- .map(
|
|
|
|
|
- (l) => DropdownMenuItem(
|
|
|
|
|
- value: l.idListino,
|
|
|
|
|
- child: CodDescDropdownItem(
|
|
|
|
|
- codice: l.codListino,
|
|
|
|
|
- descrizione: l.descrizione,
|
|
|
|
|
- ),
|
|
|
|
|
- ),
|
|
|
|
|
- )
|
|
|
|
|
- .toList(),
|
|
|
|
|
- onChanged: (v) {
|
|
|
|
|
- setState(() => _selectedListino = v);
|
|
|
|
|
- if (v != null) _loadPrezzo(v);
|
|
|
|
|
- },
|
|
|
|
|
- ),
|
|
|
|
|
- const SizedBox(height: 12),
|
|
|
|
|
- TextField(
|
|
|
|
|
- controller: _prezzoCtrl,
|
|
|
|
|
- decoration: const InputDecoration(labelText: 'Prezzo lordo'),
|
|
|
|
|
- keyboardType: const TextInputType.numberWithOptions(
|
|
|
|
|
- decimal: true,
|
|
|
|
|
- ),
|
|
|
|
|
- enabled: widget.canEditPrezzo,
|
|
|
|
|
- onChanged: _onPrezzoChanged,
|
|
|
|
|
- ),
|
|
|
|
|
- const SizedBox(height: 12),
|
|
|
|
|
- Row(
|
|
|
|
|
- children: [
|
|
|
|
|
- Expanded(
|
|
|
|
|
- child: TextField(
|
|
|
|
|
- controller: _sconto1Ctrl,
|
|
|
|
|
- decoration: const InputDecoration(labelText: 'Sconto 1 %'),
|
|
|
|
|
- keyboardType: const TextInputType.numberWithOptions(
|
|
|
|
|
- decimal: true,
|
|
|
|
|
- ),
|
|
|
|
|
- onChanged: (v) => _onScontoChanged(1, v),
|
|
|
|
|
- ),
|
|
|
|
|
- ),
|
|
|
|
|
- const SizedBox(width: 12),
|
|
|
|
|
- Expanded(
|
|
|
|
|
- child: TextField(
|
|
|
|
|
- controller: _sconto2Ctrl,
|
|
|
|
|
- decoration: const InputDecoration(labelText: 'Sconto 2 %'),
|
|
|
|
|
- keyboardType: const TextInputType.numberWithOptions(
|
|
|
|
|
- decimal: true,
|
|
|
|
|
- ),
|
|
|
|
|
- onChanged: (v) => _onScontoChanged(2, v),
|
|
|
|
|
- ),
|
|
|
|
|
- ),
|
|
|
|
|
- ],
|
|
|
|
|
- ),
|
|
|
|
|
- const SizedBox(height: 12),
|
|
|
|
|
- Row(
|
|
|
|
|
- children: [
|
|
|
|
|
- Expanded(
|
|
|
|
|
- child: TextField(
|
|
|
|
|
- controller: _sconto3Ctrl,
|
|
|
|
|
- decoration: const InputDecoration(labelText: 'Sconto 3 %'),
|
|
|
|
|
- keyboardType: const TextInputType.numberWithOptions(
|
|
|
|
|
- decimal: true,
|
|
|
|
|
- ),
|
|
|
|
|
- onChanged: (v) => _onScontoChanged(3, v),
|
|
|
|
|
- ),
|
|
|
|
|
- ),
|
|
|
|
|
- const SizedBox(width: 12),
|
|
|
|
|
- Expanded(
|
|
|
|
|
- child: TextField(
|
|
|
|
|
- controller: _sconto4Ctrl,
|
|
|
|
|
- decoration: const InputDecoration(labelText: 'Sconto 4 %'),
|
|
|
|
|
- keyboardType: const TextInputType.numberWithOptions(
|
|
|
|
|
- decimal: true,
|
|
|
|
|
- ),
|
|
|
|
|
- onChanged: (v) => _onScontoChanged(4, v),
|
|
|
|
|
- ),
|
|
|
|
|
- ),
|
|
|
|
|
- ],
|
|
|
|
|
- ),
|
|
|
|
|
- const SizedBox(height: 12),
|
|
|
|
|
- SizedBox(
|
|
|
|
|
- width: 140,
|
|
|
|
|
- child: TextField(
|
|
|
|
|
- controller: _sconto5Ctrl,
|
|
|
|
|
- decoration: const InputDecoration(labelText: 'Sconto 5 %'),
|
|
|
|
|
- keyboardType: const TextInputType.numberWithOptions(
|
|
|
|
|
- decimal: true,
|
|
|
|
|
- ),
|
|
|
|
|
- onChanged: (v) => _onScontoChanged(5, v),
|
|
|
|
|
- ),
|
|
|
|
|
- ),
|
|
|
|
|
- const SizedBox(height: 16),
|
|
|
|
|
- Row(
|
|
|
|
|
- children: [
|
|
|
|
|
- Text('Prezzo netto: ', style: theme.textTheme.bodyLarge),
|
|
|
|
|
- Text(
|
|
|
|
|
- _prezzoNetto.toStringAsFixed(2),
|
|
|
|
|
- style: theme.textTheme.bodyLarge?.copyWith(
|
|
|
|
|
- fontWeight: FontWeight.bold,
|
|
|
|
|
- ),
|
|
|
|
|
- ),
|
|
|
|
|
- ],
|
|
|
|
|
- ),
|
|
|
|
|
- const SizedBox(height: 12),
|
|
|
|
|
- Row(
|
|
|
|
|
- children: [
|
|
|
|
|
- Expanded(
|
|
|
|
|
- child: TextField(
|
|
|
|
|
- controller: _colliCtrl,
|
|
|
|
|
- decoration: const InputDecoration(labelText: 'Colli'),
|
|
|
|
|
- keyboardType: TextInputType.number,
|
|
|
|
|
- onChanged: _onColliChanged,
|
|
|
|
|
- ),
|
|
|
|
|
- ),
|
|
|
|
|
- const SizedBox(width: 12),
|
|
|
|
|
- Expanded(
|
|
|
|
|
- child: TextField(
|
|
|
|
|
- controller: _qtaCtrl,
|
|
|
|
|
- decoration: const InputDecoration(labelText: 'Quantità'),
|
|
|
|
|
- keyboardType: TextInputType.number,
|
|
|
|
|
- onChanged: _onQtaChanged,
|
|
|
|
|
- ),
|
|
|
|
|
- ),
|
|
|
|
|
- ],
|
|
|
|
|
- ),
|
|
|
|
|
- const SizedBox(height: 20),
|
|
|
|
|
- SizedBox(
|
|
|
|
|
- width: double.infinity,
|
|
|
|
|
- child: ElevatedButton(
|
|
|
|
|
- onPressed: _confirm,
|
|
|
|
|
- child: const Text('Aggiungi'),
|
|
|
|
|
- ),
|
|
|
|
|
- ),
|
|
|
|
|
- const SizedBox(height: 8),
|
|
|
|
|
- ],
|
|
|
|
|
- ),
|
|
|
|
|
- ),
|
|
|
|
|
- );
|
|
|
|
|
- }
|
|
|
|
|
-}
|
|
|