Null safety

This commit is contained in:
Hillel Coren 2023-09-19 18:48:58 +03:00
parent 818e39a0e8
commit 85a2840569
9 changed files with 45 additions and 40 deletions

View File

@ -30,7 +30,7 @@ class DesignPicker extends StatelessWidget {
return AppDropdownButton<String>( return AppDropdownButton<String>(
value: initialValue, value: initialValue,
onChanged: (dynamic value) => onSelected(designState.map[value]), onChanged: (dynamic value) => onSelected(designState.map[value]!),
items: designState.list items: designState.list
.where((designId) { .where((designId) {
final design = designState.map[designId]; final design = designState.map[designId];

View File

@ -19,7 +19,7 @@ class TaxRateDropdown extends StatefulWidget {
}) : super(key: key); }) : super(key: key);
final String? labelText; final String? labelText;
final Function(TaxRateEntity?) onSelected; final Function(TaxRateEntity) onSelected;
final String? initialTaxName; final String? initialTaxName;
final double? initialTaxRate; final double? initialTaxRate;

View File

@ -62,7 +62,7 @@ class InvoiceEditContacts extends StatelessWidget {
invoice: invoice, invoice: invoice,
invitation: invitation, invitation: invitation,
onTap: () => invitation == null onTap: () => invitation == null
? viewModel.onAddVendorContact(contact) ? viewModel.onAddVendorContact(contact!)
: viewModel.onRemoveContact(invitation), : viewModel.onRemoveContact(invitation),
); );
}).toList(), }).toList(),
@ -97,7 +97,7 @@ class InvoiceEditContacts extends StatelessWidget {
invoice: invoice, invoice: invoice,
invitation: invitation, invitation: invitation,
onTap: () => invitation == null onTap: () => invitation == null
? viewModel.onAddClientContact(contact) ? viewModel.onAddClientContact(contact!)
: viewModel.onRemoveContact(invitation), : viewModel.onRemoveContact(invitation),
); );
}).toList(), }).toList(),

View File

@ -53,8 +53,8 @@ class EntityEditContactsVM {
final InvoiceEntity? invoice; final InvoiceEntity? invoice;
final ClientEntity? client; final ClientEntity? client;
final VendorEntity? vendor; final VendorEntity? vendor;
final Function(ClientContactEntity?) onAddClientContact; final Function(ClientContactEntity) onAddClientContact;
final Function(VendorContactEntity?) onAddVendorContact; final Function(VendorContactEntity) onAddVendorContact;
final Function(InvitationEntity) onRemoveContact; final Function(InvitationEntity) onRemoveContact;
} }

View File

@ -7,6 +7,7 @@ import 'package:flutter/material.dart';
// Package imports: // Package imports:
import 'package:flutter_redux/flutter_redux.dart'; import 'package:flutter_redux/flutter_redux.dart';
import 'package:invoiceninja_flutter/data/models/client_model.dart';
import 'package:invoiceninja_flutter/data/models/vendor_model.dart'; import 'package:invoiceninja_flutter/data/models/vendor_model.dart';
import 'package:invoiceninja_flutter/redux/app/app_actions.dart'; import 'package:invoiceninja_flutter/redux/app/app_actions.dart';
import 'package:invoiceninja_flutter/redux/invoice/invoice_actions.dart'; import 'package:invoiceninja_flutter/redux/invoice/invoice_actions.dart';
@ -304,8 +305,8 @@ class InvoiceEditDesktopState extends State<InvoiceEditDesktop>
clientId: invoice.clientId, clientId: invoice.clientId,
clientState: state.clientState, clientState: state.clientState,
onSelected: (client) { onSelected: (client) {
viewModel.onClientChanged!( viewModel.onClientChanged!(context, invoice,
context, invoice, client as ClientEntity?); client as ClientEntity?);
}, },
onAddPressed: (completer) => viewModel onAddPressed: (completer) => viewModel
.onAddClientPressed!(context, completer), .onAddClientPressed!(context, completer),
@ -370,8 +371,8 @@ class InvoiceEditDesktopState extends State<InvoiceEditDesktop>
items: kFrequencies.entries items: kFrequencies.entries
.map((entry) => DropdownMenuItem( .map((entry) => DropdownMenuItem(
value: entry.key, value: entry.key,
child: Text( child: Text(localization
localization.lookup(entry.value)!), .lookup(entry.value)!),
)) ))
.toList()), .toList()),
DatePicker( DatePicker(
@ -389,8 +390,8 @@ class InvoiceEditDesktopState extends State<InvoiceEditDesktop>
labelText: localization.remainingCycles, labelText: localization.remainingCycles,
value: invoice.remainingCycles, value: invoice.remainingCycles,
blankValue: null, blankValue: null,
onChanged: (dynamic value) => viewModel.onChanged!( onChanged: (dynamic value) =>
invoice.rebuild( viewModel.onChanged!(invoice.rebuild(
(b) => b..remainingCycles = value)), (b) => b..remainingCycles = value)),
items: [ items: [
DropdownMenuItem( DropdownMenuItem(
@ -570,7 +571,8 @@ class InvoiceEditDesktopState extends State<InvoiceEditDesktop>
.map((type) => .map((type) =>
Text(localization.lookup(type)!)) Text(localization.lookup(type)!))
.toList(), .toList(),
onChanged: (dynamic value) => viewModel.onChanged!( onChanged: (dynamic value) => viewModel
.onChanged!(
invoice.rebuild((b) => b..autoBill = value)), invoice.rebuild((b) => b..autoBill = value)),
items: [ items: [
SettingsEntity.AUTO_BILL_ALWAYS, SettingsEntity.AUTO_BILL_ALWAYS,
@ -800,8 +802,8 @@ class InvoiceEditDesktopState extends State<InvoiceEditDesktop>
UserPicker( UserPicker(
userId: invoice.assignedUserId, userId: invoice.assignedUserId,
onChanged: (userId) => viewModel onChanged: (userId) => viewModel
.onChanged!(invoice.rebuild((b) => .onChanged!(invoice.rebuild((b) => b
b..assignedUserId = userId)), ..assignedUserId = userId)),
), ),
if (company if (company
.isModuleEnabled(EntityType.project)) .isModuleEnabled(EntityType.project))
@ -836,8 +838,8 @@ class InvoiceEditDesktopState extends State<InvoiceEditDesktop>
clientId: invoice.clientId, clientId: invoice.clientId,
clientState: state.clientState, clientState: state.clientState,
onSelected: (client) { onSelected: (client) {
viewModel.onChanged!(invoice.rebuild( viewModel.onChanged!(
(b) => b invoice.rebuild((b) => b
..clientId = ..clientId =
client?.id ?? '')); client?.id ?? ''));
}, },
@ -876,8 +878,7 @@ class InvoiceEditDesktopState extends State<InvoiceEditDesktop>
FormatNumberType.inputMoney), FormatNumberType.inputMoney),
onChanged: (value) => viewModel onChanged: (value) => viewModel
.onChanged!(invoice.rebuild((b) => b .onChanged!(invoice.rebuild((b) => b
..exchangeRate = ..exchangeRate = parseDouble(value))),
parseDouble(value))),
keyboardType: keyboardType:
TextInputType.numberWithOptions( TextInputType.numberWithOptions(
decimal: true), decimal: true),
@ -905,8 +906,8 @@ class InvoiceEditDesktopState extends State<InvoiceEditDesktop>
value: invoice value: invoice
.usesInclusiveTaxes, .usesInclusiveTaxes,
onChanged: (value) { onChanged: (value) {
viewModel.onChanged!(invoice viewModel.onChanged!(
.rebuild((b) => b invoice.rebuild((b) => b
..usesInclusiveTaxes = ..usesInclusiveTaxes =
value)); value));
}, },
@ -932,8 +933,8 @@ class InvoiceEditDesktopState extends State<InvoiceEditDesktop>
value: value:
invoice.autoBillEnabled, invoice.autoBillEnabled,
onChanged: (value) { onChanged: (value) {
viewModel.onChanged!(invoice viewModel.onChanged!(
.rebuild((b) => b invoice.rebuild((b) => b
..autoBillEnabled = ..autoBillEnabled =
value)); value));
}, },
@ -955,8 +956,8 @@ class InvoiceEditDesktopState extends State<InvoiceEditDesktop>
originalInvoice.documents.toList(), originalInvoice.documents.toList(),
onUploadDocument: (path, isPrivate) => onUploadDocument: (path, isPrivate) =>
widget.entityViewModel widget.entityViewModel
.onUploadDocuments!( .onUploadDocuments!(
context, path, isPrivate), context, path, isPrivate),
onRenamedDocument: () => store.dispatch( onRenamedDocument: () => store.dispatch(
LoadInvoice(invoiceId: invoice.id)), LoadInvoice(invoiceId: invoice.id)),
) )
@ -1030,8 +1031,8 @@ class InvoiceEditDesktopState extends State<InvoiceEditDesktop>
invoice.taxName1.isNotEmpty) invoice.taxName1.isNotEmpty)
TaxRateDropdown( TaxRateDropdown(
onSelected: (taxRate) { onSelected: (taxRate) {
viewModel viewModel.onChanged!(
.onChanged!(invoice.applyTax(taxRate)); invoice.applyTax(taxRate!));
}, },
labelText: localization.tax + labelText: localization.tax +
(company.settings.enableInclusiveTaxes! (company.settings.enableInclusiveTaxes!
@ -1045,7 +1046,7 @@ class InvoiceEditDesktopState extends State<InvoiceEditDesktop>
TaxRateDropdown( TaxRateDropdown(
onSelected: (taxRate) { onSelected: (taxRate) {
viewModel.onChanged!(invoice viewModel.onChanged!(invoice
.applyTax(taxRate, isSecond: true)); .applyTax(taxRate!, isSecond: true));
}, },
labelText: localization.tax + labelText: localization.tax +
(company.settings.enableInclusiveTaxes! (company.settings.enableInclusiveTaxes!
@ -1059,9 +1060,7 @@ class InvoiceEditDesktopState extends State<InvoiceEditDesktop>
TaxRateDropdown( TaxRateDropdown(
onSelected: (taxRate) { onSelected: (taxRate) {
final updatedInvoice = invoice final updatedInvoice = invoice
.applyTax(taxRate, isThird: true); .applyTax(taxRate!, isThird: true);
print(
'## UPDATED\nRate 3: ${updatedInvoice.taxName3} => ${updatedInvoice.taxRate3}');
viewModel.onChanged!(invoice viewModel.onChanged!(invoice
.applyTax(taxRate, isThird: true)); .applyTax(taxRate, isThird: true));
}, },

View File

@ -424,7 +424,7 @@ class InvoiceEditDetailsState extends State<InvoiceEditDetails> {
invoice.taxName1.isNotEmpty) invoice.taxName1.isNotEmpty)
TaxRateDropdown( TaxRateDropdown(
onSelected: (taxRate) => onSelected: (taxRate) =>
viewModel.onChanged!(invoice.applyTax(taxRate)), viewModel.onChanged!(invoice.applyTax(taxRate!)),
labelText: localization.tax + labelText: localization.tax +
(company.settings.enableInclusiveTaxes! (company.settings.enableInclusiveTaxes!
? ' - ${localization.inclusive}' ? ' - ${localization.inclusive}'

View File

@ -189,7 +189,7 @@ class _ImportExportState extends State<ImportExport> {
) )
else else
_FileMapper( _FileMapper(
key: ValueKey(_response.hash), key: ValueKey(_response!.hash),
importType: _importFormat, importType: _importFormat,
formKey: _formKey, formKey: _formKey,
response: _response, response: _response,
@ -220,8 +220,8 @@ class _ImportExportState extends State<ImportExport> {
] ]
.map((importType) => DropdownMenuItem<ImportType>( .map((importType) => DropdownMenuItem<ImportType>(
value: importType, value: importType,
child: child: Text(
Text(localization.lookup('$importType')!))) localization.lookup('$importType')!)))
.toList()), .toList()),
), ),
), ),
@ -253,7 +253,8 @@ class _ImportExportState extends State<ImportExport> {
items: DATE_FIELDS[_exportType]! items: DATE_FIELDS[_exportType]!
.map((dateField) => DropdownMenuItem<String>( .map((dateField) => DropdownMenuItem<String>(
value: dateField, value: dateField,
child: Text(localization.lookup('$dateField')!))) child:
Text(localization.lookup('$dateField')!)))
.toList(), .toList(),
), ),
if (_exportDate.isNotEmpty) if (_exportDate.isNotEmpty)
@ -777,7 +778,7 @@ class __FileMapperState extends State<_FileMapper> {
setState(() => _isLoading = true); setState(() => _isLoading = true);
final importRequest = ImportRequest( final importRequest = ImportRequest(
hash: widget.response.hash, hash: widget.response!.hash,
skipHeader: _useFirstRowAsHeaders, skipHeader: _useFirstRowAsHeaders,
columnMap: BuiltMap(convertedMapping), columnMap: BuiltMap(convertedMapping),
importType: widget.importType.name, importType: widget.importType.name,
@ -862,7 +863,8 @@ class _FieldMapper extends StatelessWidget {
isExpanded: true, isExpanded: true,
value: available.contains(mappedTo) ? mappedTo : null, value: available.contains(mappedTo) ? mappedTo : null,
validator: (value) => (value ?? '').isNotEmpty && validator: (value) => (value ?? '').isNotEmpty &&
mapping!.values.where((element) => element == value).length > 1 mapping!.values.where((element) => element == value).length >
1
? localization!.duplicateColumnMapping ? localization!.duplicateColumnMapping
: null, : null,
onChanged: onMappedToChanged as void Function(String?)?, onChanged: onMappedToChanged as void Function(String?)?,

View File

@ -1,9 +1,11 @@
// Flutter imports: // Flutter imports:
import 'dart:async';
import 'dart:convert'; import 'dart:convert';
// Package imports: // Package imports:
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_redux/flutter_redux.dart'; import 'package:flutter_redux/flutter_redux.dart';
import 'package:http/http.dart';
import 'package:invoiceninja_flutter/data/models/models.dart'; import 'package:invoiceninja_flutter/data/models/models.dart';
import 'package:invoiceninja_flutter/data/models/purchase_order_model.dart'; import 'package:invoiceninja_flutter/data/models/purchase_order_model.dart';
import 'package:invoiceninja_flutter/data/models/quote_model.dart'; import 'package:invoiceninja_flutter/data/models/quote_model.dart';
@ -144,7 +146,9 @@ class _InvoiceDesignState extends State<InvoiceDesign>
..companyLogoSize = logoSize.isEmpty ..companyLogoSize = logoSize.isEmpty
? '' ? ''
: logoSize + : logoSize +
(viewModel.settings.companyLogoSize!.contains('px') ? 'px' : '%')); (viewModel.settings.companyLogoSize!.contains('px')
? 'px'
: '%'));
if (settings != viewModel.settings) { if (settings != viewModel.settings) {
_debouncer.run(() { _debouncer.run(() {
viewModel.onSettingsChanged(settings); viewModel.onSettingsChanged(settings);

View File

@ -296,7 +296,7 @@ class _SubscriptionEditState extends State<SubscriptionEdit>
onSelected: (value) { onSelected: (value) {
final parts = subscription.recurringProductIds.split(','); final parts = subscription.recurringProductIds.split(',');
viewModel.onChanged(subscription.rebuild((b) => b viewModel.onChanged(subscription.rebuild((b) => b
..recurringProductIds = <String>[...parts, value.id] ..recurringProductIds = <String>[...parts, value!.id]
.where((part) => part.isNotEmpty) .where((part) => part.isNotEmpty)
.join(','))); .join(',')));