Null safety
This commit is contained in:
parent
fbd8b8f5ba
commit
e22c4a5228
|
|
@ -186,7 +186,7 @@ class PaymentSidebar extends StatelessWidget {
|
||||||
itemCount: recentPayments.length,
|
itemCount: recentPayments.length,
|
||||||
itemBuilder: (BuildContext context, int index) {
|
itemBuilder: (BuildContext context, int index) {
|
||||||
return PaymentListItem(
|
return PaymentListItem(
|
||||||
payment: recentPayments[index],
|
payment: recentPayments[index]!,
|
||||||
showSelected: false,
|
showSelected: false,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -189,7 +189,7 @@ class ExpenseOverview extends StatelessWidget {
|
||||||
currencyId: expense.currencyId),
|
currencyId: expense.currencyId),
|
||||||
),
|
),
|
||||||
ListDivider(),
|
ListDivider(),
|
||||||
if ((expense.privateNotes ?? '').isNotEmpty) ...[
|
if (expense.privateNotes.isNotEmpty) ...[
|
||||||
IconMessage(expense.privateNotes,
|
IconMessage(expense.privateNotes,
|
||||||
iconData: Icons.lock, copyToClipboard: true),
|
iconData: Icons.lock, copyToClipboard: true),
|
||||||
ListDivider(),
|
ListDivider(),
|
||||||
|
|
@ -223,7 +223,7 @@ class ExpenseOverview extends StatelessWidget {
|
||||||
.present(localization.active, localization.archived),
|
.present(localization.active, localization.archived),
|
||||||
),
|
),
|
||||||
..._buildDetailsList(),
|
..._buildDetailsList(),
|
||||||
if ((expense.publicNotes ?? '').isNotEmpty) ...[
|
if (expense.publicNotes.isNotEmpty) ...[
|
||||||
IconMessage(expense.publicNotes, copyToClipboard: true),
|
IconMessage(expense.publicNotes, copyToClipboard: true),
|
||||||
ListDivider()
|
ListDivider()
|
||||||
],
|
],
|
||||||
|
|
|
||||||
|
|
@ -250,9 +250,8 @@ class InvoiceEditDesktopState extends State<InvoiceEditDesktop>
|
||||||
!item!.isEmpty && item.typeId == InvoiceItemEntity.TYPE_TASK)
|
!item!.isEmpty && item.typeId == InvoiceItemEntity.TYPE_TASK)
|
||||||
.length;
|
.length;
|
||||||
|
|
||||||
final showTasksTable =
|
final showTasksTable = (invoice.hasTasks || company.showTasksTable) &&
|
||||||
(invoice.hasTasks || (company.showTasksTable ?? false)) &&
|
(invoice.isInvoice || invoice.isQuote);
|
||||||
(invoice.isInvoice || invoice.isQuote);
|
|
||||||
|
|
||||||
final settings = getClientSettings(state, client);
|
final settings = getClientSettings(state, client);
|
||||||
final terms = entityType == EntityType.quote
|
final terms = entityType == EntityType.quote
|
||||||
|
|
@ -376,7 +375,7 @@ class InvoiceEditDesktopState extends State<InvoiceEditDesktop>
|
||||||
))
|
))
|
||||||
.toList()),
|
.toList()),
|
||||||
DatePicker(
|
DatePicker(
|
||||||
labelText: (invoice.lastSentDate ?? '').isNotEmpty
|
labelText: invoice.lastSentDate.isNotEmpty
|
||||||
? localization.nextSendDate
|
? localization.nextSendDate
|
||||||
: localization.startDate,
|
: localization.startDate,
|
||||||
onSelected: (date, _) {
|
onSelected: (date, _) {
|
||||||
|
|
|
||||||
|
|
@ -223,7 +223,7 @@ class InvoiceEditDetailsState extends State<InvoiceEditDetails> {
|
||||||
))
|
))
|
||||||
.toList()),
|
.toList()),
|
||||||
DatePicker(
|
DatePicker(
|
||||||
labelText: (invoice.lastSentDate ?? '').isNotEmpty
|
labelText: invoice.lastSentDate.isNotEmpty
|
||||||
? localization.nextSendDate
|
? localization.nextSendDate
|
||||||
: localization.startDate,
|
: localization.startDate,
|
||||||
onSelected: (date, _) => viewModel
|
onSelected: (date, _) => viewModel
|
||||||
|
|
|
||||||
|
|
@ -448,10 +448,10 @@ class _InvoiceEditItemsDesktopState extends State<InvoiceEditItemsDesktop> {
|
||||||
..._columns
|
..._columns
|
||||||
.map((column) {
|
.map((column) {
|
||||||
if (column == COLUMN_ITEM) {
|
if (column == COLUMN_ITEM) {
|
||||||
return Text(item.productKey ?? '');
|
return Text(item.productKey);
|
||||||
} else if (column == COLUMN_DESCRIPTION) {
|
} else if (column == COLUMN_DESCRIPTION) {
|
||||||
return Text(
|
return Text(
|
||||||
item.notes ?? '',
|
item.notes,
|
||||||
maxLines: 2, // TODO change to 1
|
maxLines: 2, // TODO change to 1
|
||||||
overflow: TextOverflow.ellipsis,
|
overflow: TextOverflow.ellipsis,
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -57,7 +57,7 @@ class _InvoiceViewHistoryState extends State<InvoiceViewHistory> {
|
||||||
itemBuilder: (BuildContext context, index) {
|
itemBuilder: (BuildContext context, index) {
|
||||||
final activity = activityList[index];
|
final activity = activityList[index];
|
||||||
final history = activity.history!;
|
final history = activity.history!;
|
||||||
final activityId = history.activityId ?? '';
|
final activityId = history.activityId;
|
||||||
|
|
||||||
final state = viewModel.state!;
|
final state = viewModel.state!;
|
||||||
final client = state.clientState.get(activity.clientId!);
|
final client = state.clientState.get(activity.clientId!);
|
||||||
|
|
|
||||||
|
|
@ -137,7 +137,7 @@ class InvoiceOverview extends StatelessWidget {
|
||||||
ListDivider(),
|
ListDivider(),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
if ((invoice.privateNotes ?? '').isNotEmpty) {
|
if (invoice.privateNotes.isNotEmpty) {
|
||||||
widgets.addAll([
|
widgets.addAll([
|
||||||
IconMessage(invoice.privateNotes,
|
IconMessage(invoice.privateNotes,
|
||||||
iconData: Icons.lock, copyToClipboard: true),
|
iconData: Icons.lock, copyToClipboard: true),
|
||||||
|
|
@ -516,7 +516,7 @@ class InvoiceOverview extends StatelessWidget {
|
||||||
widgets.add(surchargeRow(localization.partialDue, invoice.partial));
|
widgets.add(surchargeRow(localization.partialDue, invoice.partial));
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((invoice.publicNotes ?? '').isNotEmpty) {
|
if (invoice.publicNotes.isNotEmpty) {
|
||||||
widgets.addAll([
|
widgets.addAll([
|
||||||
ListDivider(),
|
ListDivider(),
|
||||||
IconMessage(invoice.publicNotes, copyToClipboard: true),
|
IconMessage(invoice.publicNotes, copyToClipboard: true),
|
||||||
|
|
|
||||||
|
|
@ -625,7 +625,7 @@ class _PaymentableEditorState extends State<PaymentableEditor> {
|
||||||
// If a client isn't selected or a client is selected but the client
|
// If a client isn't selected or a client is selected but the client
|
||||||
// doesn't have any more credits then don't show the picker
|
// doesn't have any more credits then don't show the picker
|
||||||
if (widget.entityType == EntityType.credit &&
|
if (widget.entityType == EntityType.credit &&
|
||||||
((payment.clientId ?? '').isEmpty ||
|
(payment.clientId.isEmpty ||
|
||||||
(creditList.isEmpty && (paymentable.creditId ?? '').isEmpty))) {
|
(creditList.isEmpty && (paymentable.creditId ?? '').isEmpty))) {
|
||||||
return SizedBox();
|
return SizedBox();
|
||||||
} else if (widget.entityType == EntityType.invoice &&
|
} else if (widget.entityType == EntityType.invoice &&
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@ class PaymentListItem extends StatelessWidget {
|
||||||
this.showSelected = true,
|
this.showSelected = true,
|
||||||
});
|
});
|
||||||
|
|
||||||
final PaymentEntity? payment;
|
final PaymentEntity payment;
|
||||||
final String? filter;
|
final String? filter;
|
||||||
final bool showCheckbox;
|
final bool showCheckbox;
|
||||||
final bool isChecked;
|
final bool isChecked;
|
||||||
|
|
@ -41,31 +41,31 @@ class PaymentListItem extends StatelessWidget {
|
||||||
final uiState = state.uiState;
|
final uiState = state.uiState;
|
||||||
final paymentUIState = uiState.paymentUIState;
|
final paymentUIState = uiState.paymentUIState;
|
||||||
final textStyle = TextStyle(fontSize: 16);
|
final textStyle = TextStyle(fontSize: 16);
|
||||||
final client = state.clientState.get(payment!.clientId);
|
final client = state.clientState.get(payment.clientId);
|
||||||
final localization = AppLocalization.of(context);
|
final localization = AppLocalization.of(context);
|
||||||
final filterMatch = filter != null && filter!.isNotEmpty
|
final filterMatch = filter != null && filter!.isNotEmpty
|
||||||
? (payment!.matchesFilterValue(filter) ??
|
? (payment.matchesFilterValue(filter) ??
|
||||||
client.matchesFilterValue(filter))
|
client.matchesFilterValue(filter))
|
||||||
: null;
|
: null;
|
||||||
final mobileSubtitle = filterMatch ??
|
final mobileSubtitle = filterMatch ??
|
||||||
(payment!.number ?? '') + ' • ' + formatDate(payment!.date, context);
|
payment.number + ' • ' + formatDate(payment.date, context);
|
||||||
final textColor = Theme.of(context).textTheme.bodyLarge!.color;
|
final textColor = Theme.of(context).textTheme.bodyLarge!.color;
|
||||||
|
|
||||||
String desktopSubtitle = '';
|
String desktopSubtitle = '';
|
||||||
if (payment!.date.isNotEmpty) {
|
if (payment.date.isNotEmpty) {
|
||||||
desktopSubtitle = formatDate(payment!.date, context);
|
desktopSubtitle = formatDate(payment.date, context);
|
||||||
}
|
}
|
||||||
if (payment!.transactionReference.isNotEmpty) {
|
if (payment.transactionReference.isNotEmpty) {
|
||||||
if (desktopSubtitle.isNotEmpty) {
|
if (desktopSubtitle.isNotEmpty) {
|
||||||
desktopSubtitle += ' • ';
|
desktopSubtitle += ' • ';
|
||||||
}
|
}
|
||||||
desktopSubtitle += payment!.transactionReference;
|
desktopSubtitle += payment.transactionReference;
|
||||||
}
|
}
|
||||||
|
|
||||||
return DismissibleEntity(
|
return DismissibleEntity(
|
||||||
isSelected: isDesktop(context) &&
|
isSelected: isDesktop(context) &&
|
||||||
showSelected &&
|
showSelected &&
|
||||||
payment!.id ==
|
payment.id ==
|
||||||
(uiState.isEditing
|
(uiState.isEditing
|
||||||
? paymentUIState.editing!.id
|
? paymentUIState.editing!.id
|
||||||
: paymentUIState.selectedId),
|
: paymentUIState.selectedId),
|
||||||
|
|
@ -78,10 +78,10 @@ class PaymentListItem extends StatelessWidget {
|
||||||
? InkWell(
|
? InkWell(
|
||||||
onTap: () => onTap != null
|
onTap: () => onTap != null
|
||||||
? onTap!()
|
? onTap!()
|
||||||
: selectEntity(entity: payment!, forceView: !showCheckbox),
|
: selectEntity(entity: payment, forceView: !showCheckbox),
|
||||||
onLongPress: () => onTap != null
|
onLongPress: () => onTap != null
|
||||||
? null
|
? null
|
||||||
: selectEntity(entity: payment!, longPress: true),
|
: selectEntity(entity: payment, longPress: true),
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.only(
|
padding: const EdgeInsets.only(
|
||||||
left: 10,
|
left: 10,
|
||||||
|
|
@ -105,7 +105,7 @@ class PaymentListItem extends StatelessWidget {
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
: ActionMenuButton(
|
: ActionMenuButton(
|
||||||
entityActions: payment!.getActions(
|
entityActions: payment.getActions(
|
||||||
userCompany: state.userCompany,
|
userCompany: state.userCompany,
|
||||||
client: client,
|
client: client,
|
||||||
includeEdit: true,
|
includeEdit: true,
|
||||||
|
|
@ -121,11 +121,11 @@ class PaymentListItem extends StatelessWidget {
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
Text(
|
Text(
|
||||||
payment!.number,
|
payment.number,
|
||||||
style: textStyle,
|
style: textStyle,
|
||||||
overflow: TextOverflow.ellipsis,
|
overflow: TextOverflow.ellipsis,
|
||||||
),
|
),
|
||||||
if (!payment!.isActive) EntityStateLabel(payment)
|
if (!payment.isActive) EntityStateLabel(payment)
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
@ -152,7 +152,7 @@ class PaymentListItem extends StatelessWidget {
|
||||||
),
|
),
|
||||||
SizedBox(width: 10),
|
SizedBox(width: 10),
|
||||||
Text(
|
Text(
|
||||||
formatNumber(payment!.amount, context,
|
formatNumber(payment.amount, context,
|
||||||
clientId: client.id)!,
|
clientId: client.id)!,
|
||||||
style: textStyle,
|
style: textStyle,
|
||||||
textAlign: TextAlign.end,
|
textAlign: TextAlign.end,
|
||||||
|
|
@ -166,10 +166,10 @@ class PaymentListItem extends StatelessWidget {
|
||||||
: ListTile(
|
: ListTile(
|
||||||
onTap: () => onTap != null
|
onTap: () => onTap != null
|
||||||
? onTap!()
|
? onTap!()
|
||||||
: selectEntity(entity: payment!, forceView: !showCheckbox),
|
: selectEntity(entity: payment, forceView: !showCheckbox),
|
||||||
onLongPress: () => onTap != null
|
onLongPress: () => onTap != null
|
||||||
? null
|
? null
|
||||||
: selectEntity(entity: payment!, longPress: true),
|
: selectEntity(entity: payment, longPress: true),
|
||||||
leading: showCheckbox
|
leading: showCheckbox
|
||||||
? IgnorePointer(
|
? IgnorePointer(
|
||||||
child: Checkbox(
|
child: Checkbox(
|
||||||
|
|
@ -192,8 +192,8 @@ class PaymentListItem extends StatelessWidget {
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Text(
|
Text(
|
||||||
formatNumber(payment!.amount, context,
|
formatNumber(payment.amount, context,
|
||||||
clientId: payment!.clientId)!,
|
clientId: payment.clientId)!,
|
||||||
style: Theme.of(context).textTheme.titleMedium),
|
style: Theme.of(context).textTheme.titleMedium),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
|
@ -214,11 +214,11 @@ class PaymentListItem extends StatelessWidget {
|
||||||
),
|
),
|
||||||
Text(
|
Text(
|
||||||
localization!.lookup(
|
localization!.lookup(
|
||||||
'payment_status_${payment!.calculatedStatusId}')!,
|
'payment_status_${payment.calculatedStatusId}')!,
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: PaymentStatusColors(
|
color: PaymentStatusColors(
|
||||||
state.prefState.colorThemeModel)
|
state.prefState.colorThemeModel)
|
||||||
.colors[payment!.calculatedStatusId],
|
.colors[payment.calculatedStatusId],
|
||||||
)),
|
)),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
|
|
||||||
|
|
@ -62,7 +62,7 @@ class _PaymentViewState extends State<PaymentView> {
|
||||||
if (payment.date.isNotEmpty) {
|
if (payment.date.isNotEmpty) {
|
||||||
fields[PaymentFields.date] = formatDate(payment.date, context);
|
fields[PaymentFields.date] = formatDate(payment.date, context);
|
||||||
}
|
}
|
||||||
if ((payment.typeId ?? '').isNotEmpty) {
|
if (payment.typeId.isNotEmpty) {
|
||||||
final paymentType = state.staticState.paymentTypeMap[payment.typeId];
|
final paymentType = state.staticState.paymentTypeMap[payment.typeId];
|
||||||
if (paymentType != null) {
|
if (paymentType != null) {
|
||||||
fields[PaymentFields.typeId] = paymentType.name;
|
fields[PaymentFields.typeId] = paymentType.name;
|
||||||
|
|
@ -133,7 +133,7 @@ class _PaymentViewState extends State<PaymentView> {
|
||||||
paymentable.createdAt),
|
paymentable.createdAt),
|
||||||
context),
|
context),
|
||||||
),
|
),
|
||||||
if ((payment.companyGatewayId ?? '').isNotEmpty) ...[
|
if (payment.companyGatewayId.isNotEmpty) ...[
|
||||||
ListTile(
|
ListTile(
|
||||||
title: Text(
|
title: Text(
|
||||||
'${localization.gateway} › ${companyGateway.label}'),
|
'${localization.gateway} › ${companyGateway.label}'),
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,7 @@ class ProjectListItem extends StatelessWidget {
|
||||||
final UserEntity? user;
|
final UserEntity? user;
|
||||||
final GestureTapCallback? onTap;
|
final GestureTapCallback? onTap;
|
||||||
final GestureTapCallback? onLongPress;
|
final GestureTapCallback? onLongPress;
|
||||||
final ProjectEntity? project;
|
final ProjectEntity project;
|
||||||
final String? filter;
|
final String? filter;
|
||||||
final Function(bool?)? onCheckboxChanged;
|
final Function(bool?)? onCheckboxChanged;
|
||||||
final bool isChecked;
|
final bool isChecked;
|
||||||
|
|
@ -40,9 +40,9 @@ class ProjectListItem extends StatelessWidget {
|
||||||
final state = store.state;
|
final state = store.state;
|
||||||
final uiState = state.uiState;
|
final uiState = state.uiState;
|
||||||
final projectUIState = uiState.projectUIState;
|
final projectUIState = uiState.projectUIState;
|
||||||
final client = state.clientState.get(project!.clientId);
|
final client = state.clientState.get(project.clientId);
|
||||||
final filterMatch = filter != null && filter!.isNotEmpty
|
final filterMatch = filter != null && filter!.isNotEmpty
|
||||||
? (project!.matchesFilterValue(filter) ??
|
? (project.matchesFilterValue(filter) ??
|
||||||
client.matchesFilterValue(filter))
|
client.matchesFilterValue(filter))
|
||||||
: null;
|
: null;
|
||||||
final listUIState = projectUIState.listUIState;
|
final listUIState = projectUIState.listUIState;
|
||||||
|
|
@ -54,7 +54,7 @@ class ProjectListItem extends StatelessWidget {
|
||||||
|
|
||||||
return DismissibleEntity(
|
return DismissibleEntity(
|
||||||
isSelected: isDesktop(context) &&
|
isSelected: isDesktop(context) &&
|
||||||
project!.id ==
|
project.id ==
|
||||||
(uiState.isEditing
|
(uiState.isEditing
|
||||||
? projectUIState.editing!.id
|
? projectUIState.editing!.id
|
||||||
: projectUIState.selectedId),
|
: projectUIState.selectedId),
|
||||||
|
|
@ -65,10 +65,10 @@ class ProjectListItem extends StatelessWidget {
|
||||||
return constraints.maxWidth > kTableListWidthCutoff
|
return constraints.maxWidth > kTableListWidthCutoff
|
||||||
? InkWell(
|
? InkWell(
|
||||||
onTap: () =>
|
onTap: () =>
|
||||||
onTap != null ? onTap!() : selectEntity(entity: project!),
|
onTap != null ? onTap!() : selectEntity(entity: project),
|
||||||
onLongPress: () => onLongPress != null
|
onLongPress: () => onLongPress != null
|
||||||
? onLongPress!()
|
? onLongPress!()
|
||||||
: selectEntity(entity: project!, longPress: true),
|
: selectEntity(entity: project, longPress: true),
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.only(
|
padding: const EdgeInsets.only(
|
||||||
left: 10,
|
left: 10,
|
||||||
|
|
@ -97,7 +97,7 @@ class ProjectListItem extends StatelessWidget {
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
: ActionMenuButton(
|
: ActionMenuButton(
|
||||||
entityActions: project!.getActions(
|
entityActions: project.getActions(
|
||||||
userCompany: state.userCompany,
|
userCompany: state.userCompany,
|
||||||
client: client,
|
client: client,
|
||||||
includeEdit: true,
|
includeEdit: true,
|
||||||
|
|
@ -114,11 +114,11 @@ class ProjectListItem extends StatelessWidget {
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
Text(
|
Text(
|
||||||
project!.number ?? '',
|
project.number ?? '',
|
||||||
style: textStyle,
|
style: textStyle,
|
||||||
overflow: TextOverflow.ellipsis,
|
overflow: TextOverflow.ellipsis,
|
||||||
),
|
),
|
||||||
if (!project!.isActive) EntityStateLabel(project)
|
if (!project.isActive) EntityStateLabel(project)
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
@ -128,8 +128,8 @@ class ProjectListItem extends StatelessWidget {
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
Text(
|
Text(
|
||||||
project!.name +
|
project.name +
|
||||||
(project!.documents.isNotEmpty
|
(project.documents.isNotEmpty
|
||||||
? ' 📎'
|
? ' 📎'
|
||||||
: ''),
|
: ''),
|
||||||
style: textStyle),
|
style: textStyle),
|
||||||
|
|
@ -150,7 +150,7 @@ class ProjectListItem extends StatelessWidget {
|
||||||
Text(
|
Text(
|
||||||
formatDuration(
|
formatDuration(
|
||||||
Duration(
|
Duration(
|
||||||
minutes: (project!.budgetedHours * 60).toInt()),
|
minutes: (project.budgetedHours * 60).toInt()),
|
||||||
showSeconds: false),
|
showSeconds: false),
|
||||||
style: textStyle,
|
style: textStyle,
|
||||||
textAlign: TextAlign.end,
|
textAlign: TextAlign.end,
|
||||||
|
|
@ -161,10 +161,10 @@ class ProjectListItem extends StatelessWidget {
|
||||||
)
|
)
|
||||||
: ListTile(
|
: ListTile(
|
||||||
onTap: () =>
|
onTap: () =>
|
||||||
onTap != null ? onTap!() : selectEntity(entity: project!),
|
onTap != null ? onTap!() : selectEntity(entity: project),
|
||||||
onLongPress: () => onLongPress != null
|
onLongPress: () => onLongPress != null
|
||||||
? onLongPress!()
|
? onLongPress!()
|
||||||
: selectEntity(entity: project!, longPress: true),
|
: selectEntity(entity: project, longPress: true),
|
||||||
leading: showCheckbox
|
leading: showCheckbox
|
||||||
? IgnorePointer(
|
? IgnorePointer(
|
||||||
ignoring: listUIState.isInMultiselect(),
|
ignoring: listUIState.isInMultiselect(),
|
||||||
|
|
@ -183,8 +183,8 @@ class ProjectListItem extends StatelessWidget {
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
Expanded(
|
Expanded(
|
||||||
child: Text(
|
child: Text(
|
||||||
project!.name +
|
project.name +
|
||||||
(project!.documents.isNotEmpty ? ' 📎' : ''),
|
(project.documents.isNotEmpty ? ' 📎' : ''),
|
||||||
style: Theme.of(context).textTheme.titleMedium,
|
style: Theme.of(context).textTheme.titleMedium,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
@ -192,7 +192,7 @@ class ProjectListItem extends StatelessWidget {
|
||||||
formatDuration(
|
formatDuration(
|
||||||
Duration(
|
Duration(
|
||||||
minutes:
|
minutes:
|
||||||
(project!.budgetedHours * 60).toInt()),
|
(project.budgetedHours * 60).toInt()),
|
||||||
showSeconds: false),
|
showSeconds: false),
|
||||||
style: Theme.of(context).textTheme.titleMedium),
|
style: Theme.of(context).textTheme.titleMedium),
|
||||||
],
|
],
|
||||||
|
|
@ -203,7 +203,7 @@ class ProjectListItem extends StatelessWidget {
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
Text(
|
Text(
|
||||||
filterMatch == null
|
filterMatch == null
|
||||||
? project!.number + ' • ' + client.displayName
|
? project.number + ' • ' + client.displayName
|
||||||
: filterMatch,
|
: filterMatch,
|
||||||
maxLines: 3,
|
maxLines: 3,
|
||||||
overflow: TextOverflow.ellipsis),
|
overflow: TextOverflow.ellipsis),
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,7 @@ class ProjectListBuilder extends StatelessWidget {
|
||||||
itemBuilder: (BuildContext context, index) {
|
itemBuilder: (BuildContext context, index) {
|
||||||
final state = viewModel.state;
|
final state = viewModel.state;
|
||||||
final projectId = viewModel.projectList[index];
|
final projectId = viewModel.projectList[index];
|
||||||
final project = viewModel.projectMap[projectId];
|
final project = viewModel.projectMap[projectId]!;
|
||||||
final listState = state.getListState(EntityType.project);
|
final listState = state.getListState(EntityType.project);
|
||||||
final isInMultiselect = listState.isInMultiselect();
|
final isInMultiselect = listState.isInMultiselect();
|
||||||
|
|
||||||
|
|
@ -51,7 +51,7 @@ class ProjectListBuilder extends StatelessWidget {
|
||||||
user: state.user,
|
user: state.user,
|
||||||
filter: viewModel.filter,
|
filter: viewModel.filter,
|
||||||
project: project,
|
project: project,
|
||||||
isChecked: isInMultiselect && listState.isSelected(project!.id),
|
isChecked: isInMultiselect && listState.isSelected(project.id),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -69,7 +69,7 @@ class ProjectPresenter extends EntityPresenter {
|
||||||
return Text(formatNumber(project.budgetedHours, context,
|
return Text(formatNumber(project.budgetedHours, context,
|
||||||
formatNumberType: FormatNumberType.double)!);
|
formatNumberType: FormatNumberType.double)!);
|
||||||
case ProjectFields.number:
|
case ProjectFields.number:
|
||||||
return Text(project.number ?? '');
|
return Text(project.number);
|
||||||
case ProjectFields.customValue1:
|
case ProjectFields.customValue1:
|
||||||
return Text(presentCustomField(context, project.customValue1)!);
|
return Text(presentCustomField(context, project.customValue1)!);
|
||||||
case ProjectFields.customValue2:
|
case ProjectFields.customValue2:
|
||||||
|
|
|
||||||
|
|
@ -111,7 +111,7 @@ class _ProjectOverviewState extends State<ProjectOverview> {
|
||||||
Duration(minutes: (project.budgetedHours * 60).toInt())),
|
Duration(minutes: (project.budgetedHours * 60).toInt())),
|
||||||
),
|
),
|
||||||
ListDivider(),
|
ListDivider(),
|
||||||
if ((project.privateNotes ?? '').isNotEmpty) ...[
|
if (project.privateNotes.isNotEmpty) ...[
|
||||||
IconMessage(project.privateNotes,
|
IconMessage(project.privateNotes,
|
||||||
iconData: Icons.lock, copyToClipboard: true),
|
iconData: Icons.lock, copyToClipboard: true),
|
||||||
ListDivider()
|
ListDivider()
|
||||||
|
|
@ -160,7 +160,7 @@ class _ProjectOverviewState extends State<ProjectOverview> {
|
||||||
FieldGrid(fields),
|
FieldGrid(fields),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
if ((project.publicNotes ?? '').isNotEmpty) {
|
if (project.publicNotes.isNotEmpty) {
|
||||||
widgets.addAll([
|
widgets.addAll([
|
||||||
IconMessage(project.publicNotes, copyToClipboard: true),
|
IconMessage(project.publicNotes, copyToClipboard: true),
|
||||||
ListDivider()
|
ListDivider()
|
||||||
|
|
|
||||||
|
|
@ -116,7 +116,7 @@ class PurchaseOrderListItem extends StatelessWidget {
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
Text(
|
Text(
|
||||||
(purchaseOrder.number ?? '').isEmpty
|
purchaseOrder.number.isEmpty
|
||||||
? localization!.pending
|
? localization!.pending
|
||||||
: purchaseOrder.number,
|
: purchaseOrder.number,
|
||||||
style: textStyle,
|
style: textStyle,
|
||||||
|
|
|
||||||
|
|
@ -206,7 +206,7 @@ class QuoteListItem extends StatelessWidget {
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
Expanded(
|
Expanded(
|
||||||
child: filterMatch == null
|
child: filterMatch == null
|
||||||
? Text((((quote.number ?? '').isEmpty
|
? Text(((quote.number.isEmpty
|
||||||
? localization!.pending
|
? localization!.pending
|
||||||
: quote.number) +
|
: quote.number) +
|
||||||
' • ' +
|
' • ' +
|
||||||
|
|
|
||||||
|
|
@ -70,9 +70,8 @@ class QuotePresenter extends EntityPresenter {
|
||||||
case QuoteFields.status:
|
case QuoteFields.status:
|
||||||
return EntityStatusChip(entity: quote, showState: true);
|
return EntityStatusChip(entity: quote, showState: true);
|
||||||
case QuoteFields.number:
|
case QuoteFields.number:
|
||||||
return Text((quote.number ?? '').isEmpty
|
return Text(
|
||||||
? localization!.pending
|
quote.number.isEmpty ? localization!.pending : quote.number);
|
||||||
: quote.number);
|
|
||||||
case QuoteFields.client:
|
case QuoteFields.client:
|
||||||
return LinkTextRelatedEntity(entity: client, relation: quote);
|
return LinkTextRelatedEntity(entity: client, relation: quote);
|
||||||
case QuoteFields.date:
|
case QuoteFields.date:
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ import 'package:invoiceninja_flutter/utils/platforms.dart';
|
||||||
class RecurringExpenseListItem extends StatelessWidget {
|
class RecurringExpenseListItem extends StatelessWidget {
|
||||||
const RecurringExpenseListItem({
|
const RecurringExpenseListItem({
|
||||||
required this.expense,
|
required this.expense,
|
||||||
this.filter,
|
required this.filter,
|
||||||
this.onTap,
|
this.onTap,
|
||||||
this.onCheckboxChanged,
|
this.onCheckboxChanged,
|
||||||
this.showCheckbox = true,
|
this.showCheckbox = true,
|
||||||
|
|
@ -29,7 +29,7 @@ class RecurringExpenseListItem extends StatelessWidget {
|
||||||
|
|
||||||
final Function(bool?)? onCheckboxChanged;
|
final Function(bool?)? onCheckboxChanged;
|
||||||
final GestureTapCallback? onTap;
|
final GestureTapCallback? onTap;
|
||||||
final ExpenseEntity? expense;
|
final ExpenseEntity expense;
|
||||||
final String? filter;
|
final String? filter;
|
||||||
final bool showCheckbox;
|
final bool showCheckbox;
|
||||||
final bool isDismissible;
|
final bool isDismissible;
|
||||||
|
|
@ -41,18 +41,18 @@ class RecurringExpenseListItem extends StatelessWidget {
|
||||||
final state = store.state;
|
final state = store.state;
|
||||||
final uiState = state.uiState;
|
final uiState = state.uiState;
|
||||||
final expenseUIState = uiState.recurringExpenseUIState;
|
final expenseUIState = uiState.recurringExpenseUIState;
|
||||||
final client = state.clientState.get(expense!.clientId!);
|
final client = state.clientState.get(expense.clientId!);
|
||||||
final vendor = state.vendorState.get(expense!.vendorId!);
|
final vendor = state.vendorState.get(expense.vendorId!);
|
||||||
final category = state.expenseCategoryState.get(expense!.categoryId);
|
final category = state.expenseCategoryState.get(expense.categoryId);
|
||||||
final filterMatch = filter != null && filter!.isNotEmpty
|
final filterMatch = filter != null && filter!.isNotEmpty
|
||||||
? (expense!.matchesFilterValue(filter) ??
|
? (expense.matchesFilterValue(filter) ??
|
||||||
client.matchesFilterValue(filter))
|
client.matchesFilterValue(filter))
|
||||||
: null;
|
: null;
|
||||||
final listUIState = expenseUIState.listUIState;
|
final listUIState = expenseUIState.listUIState;
|
||||||
final isInMultiselect = listUIState.isInMultiselect();
|
final isInMultiselect = listUIState.isInMultiselect();
|
||||||
final showCheckbox = onCheckboxChanged != null || isInMultiselect;
|
final showCheckbox = onCheckboxChanged != null || isInMultiselect;
|
||||||
final isChecked = isDismissible
|
final isChecked = isDismissible
|
||||||
? (isInMultiselect && listUIState.isSelected(expense!.id))
|
? (isInMultiselect && listUIState.isSelected(expense.id))
|
||||||
: this.isChecked;
|
: this.isChecked;
|
||||||
final textStyle = TextStyle(fontSize: 16);
|
final textStyle = TextStyle(fontSize: 16);
|
||||||
final textColor = Theme.of(context).textTheme.bodyLarge!.color;
|
final textColor = Theme.of(context).textTheme.bodyLarge!.color;
|
||||||
|
|
@ -62,8 +62,8 @@ class RecurringExpenseListItem extends StatelessWidget {
|
||||||
subtitle = filterMatch;
|
subtitle = filterMatch;
|
||||||
} else if (client != null || vendor != null || category != null) {
|
} else if (client != null || vendor != null || category != null) {
|
||||||
final parts = <String>[];
|
final parts = <String>[];
|
||||||
if (expense!.nextSendDate.isNotEmpty) {
|
if (expense.nextSendDate.isNotEmpty) {
|
||||||
parts.add(formatDate(expense!.nextSendDate, context));
|
parts.add(formatDate(expense.nextSendDate, context));
|
||||||
}
|
}
|
||||||
if (category.isOld) {
|
if (category.isOld) {
|
||||||
parts.add(category.name);
|
parts.add(category.name);
|
||||||
|
|
@ -81,7 +81,7 @@ class RecurringExpenseListItem extends StatelessWidget {
|
||||||
showMultiselect: this.showCheckbox,
|
showMultiselect: this.showCheckbox,
|
||||||
isDismissible: isDismissible,
|
isDismissible: isDismissible,
|
||||||
isSelected: isDesktop(context) &&
|
isSelected: isDesktop(context) &&
|
||||||
expense!.id ==
|
expense.id ==
|
||||||
(uiState.isEditing
|
(uiState.isEditing
|
||||||
? expenseUIState.editing!.id
|
? expenseUIState.editing!.id
|
||||||
: expenseUIState.selectedId),
|
: expenseUIState.selectedId),
|
||||||
|
|
@ -92,9 +92,9 @@ class RecurringExpenseListItem extends StatelessWidget {
|
||||||
return constraints.maxWidth > kTableListWidthCutoff
|
return constraints.maxWidth > kTableListWidthCutoff
|
||||||
? InkWell(
|
? InkWell(
|
||||||
onTap: () =>
|
onTap: () =>
|
||||||
onTap != null ? onTap!() : selectEntity(entity: expense!),
|
onTap != null ? onTap!() : selectEntity(entity: expense),
|
||||||
onLongPress: () =>
|
onLongPress: () =>
|
||||||
selectEntity(entity: expense!, longPress: true),
|
selectEntity(entity: expense, longPress: true),
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.only(
|
padding: const EdgeInsets.only(
|
||||||
left: 10,
|
left: 10,
|
||||||
|
|
@ -123,7 +123,7 @@ class RecurringExpenseListItem extends StatelessWidget {
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
: ActionMenuButton(
|
: ActionMenuButton(
|
||||||
entityActions: expense!.getActions(
|
entityActions: expense.getActions(
|
||||||
userCompany: state.userCompany,
|
userCompany: state.userCompany,
|
||||||
includeEdit: true,
|
includeEdit: true,
|
||||||
),
|
),
|
||||||
|
|
@ -139,11 +139,11 @@ class RecurringExpenseListItem extends StatelessWidget {
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
Text(
|
Text(
|
||||||
expense!.number,
|
expense.number,
|
||||||
style: textStyle,
|
style: textStyle,
|
||||||
overflow: TextOverflow.ellipsis,
|
overflow: TextOverflow.ellipsis,
|
||||||
),
|
),
|
||||||
if (!expense!.isActive) EntityStateLabel(expense)
|
if (!expense.isActive) EntityStateLabel(expense)
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
@ -153,8 +153,8 @@ class RecurringExpenseListItem extends StatelessWidget {
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
Text(
|
Text(
|
||||||
(expense!.publicNotes ?? '') +
|
(expense.publicNotes ?? '') +
|
||||||
(expense!.documents.isNotEmpty ? ' 📎' : ''),
|
(expense.documents.isNotEmpty ? ' 📎' : ''),
|
||||||
style: textStyle,
|
style: textStyle,
|
||||||
maxLines: 1,
|
maxLines: 1,
|
||||||
),
|
),
|
||||||
|
|
@ -173,8 +173,8 @@ class RecurringExpenseListItem extends StatelessWidget {
|
||||||
),
|
),
|
||||||
SizedBox(width: 8),
|
SizedBox(width: 8),
|
||||||
Text(
|
Text(
|
||||||
formatNumber(expense!.convertedAmount, context,
|
formatNumber(expense.convertedAmount, context,
|
||||||
currencyId: expense!.currencyId)!,
|
currencyId: expense.currencyId)!,
|
||||||
style: textStyle,
|
style: textStyle,
|
||||||
textAlign: TextAlign.end,
|
textAlign: TextAlign.end,
|
||||||
),
|
),
|
||||||
|
|
@ -186,9 +186,9 @@ class RecurringExpenseListItem extends StatelessWidget {
|
||||||
)
|
)
|
||||||
: ListTile(
|
: ListTile(
|
||||||
onTap: () =>
|
onTap: () =>
|
||||||
onTap != null ? onTap!() : selectEntity(entity: expense!),
|
onTap != null ? onTap!() : selectEntity(entity: expense),
|
||||||
onLongPress: () =>
|
onLongPress: () =>
|
||||||
selectEntity(entity: expense!, longPress: true),
|
selectEntity(entity: expense, longPress: true),
|
||||||
leading: showCheckbox
|
leading: showCheckbox
|
||||||
? IgnorePointer(
|
? IgnorePointer(
|
||||||
ignoring: listUIState.isInMultiselect(),
|
ignoring: listUIState.isInMultiselect(),
|
||||||
|
|
@ -207,17 +207,17 @@ class RecurringExpenseListItem extends StatelessWidget {
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
Expanded(
|
Expanded(
|
||||||
child: Text(
|
child: Text(
|
||||||
(expense!.publicNotes.isEmpty
|
(expense.publicNotes.isEmpty
|
||||||
? expense!.number
|
? expense.number
|
||||||
: expense!.publicNotes) +
|
: expense.publicNotes) +
|
||||||
(expense!.documents.isNotEmpty ? ' 📎' : ''),
|
(expense.documents.isNotEmpty ? ' 📎' : ''),
|
||||||
style: Theme.of(context).textTheme.titleMedium,
|
style: Theme.of(context).textTheme.titleMedium,
|
||||||
maxLines: 1,
|
maxLines: 1,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Text(
|
Text(
|
||||||
formatNumber(expense!.convertedAmount, context,
|
formatNumber(expense.convertedAmount, context,
|
||||||
currencyId: expense!.currencyId)!,
|
currencyId: expense.currencyId)!,
|
||||||
style: Theme.of(context).textTheme.titleMedium),
|
style: Theme.of(context).textTheme.titleMedium),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
|
|
||||||
|
|
@ -44,7 +44,7 @@ class RecurringExpenseListBuilder extends StatelessWidget {
|
||||||
final state = viewModel.state;
|
final state = viewModel.state;
|
||||||
final recurringExpenseId = viewModel.recurringExpenseList[index];
|
final recurringExpenseId = viewModel.recurringExpenseList[index];
|
||||||
final recurringExpense =
|
final recurringExpense =
|
||||||
viewModel.recurringExpenseMap[recurringExpenseId];
|
viewModel.recurringExpenseMap[recurringExpenseId]!;
|
||||||
final listState = state.getListState(EntityType.recurringExpense);
|
final listState = state.getListState(EntityType.recurringExpense);
|
||||||
final isInMultiselect = listState.isInMultiselect();
|
final isInMultiselect = listState.isInMultiselect();
|
||||||
|
|
||||||
|
|
@ -52,7 +52,7 @@ class RecurringExpenseListBuilder extends StatelessWidget {
|
||||||
filter: viewModel.filter,
|
filter: viewModel.filter,
|
||||||
expense: recurringExpense,
|
expense: recurringExpense,
|
||||||
isChecked: isInMultiselect &&
|
isChecked: isInMultiselect &&
|
||||||
listState.isSelected(recurringExpense!.id),
|
listState.isSelected(recurringExpense.id),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -216,7 +216,7 @@ class RecurringInvoiceListItem extends StatelessWidget {
|
||||||
Expanded(
|
Expanded(
|
||||||
child: filterMatch == null
|
child: filterMatch == null
|
||||||
? Text(
|
? Text(
|
||||||
(((invoice.number ?? '').isEmpty
|
((invoice.number.isEmpty
|
||||||
? localization.pending
|
? localization.pending
|
||||||
: invoice.number) +
|
: invoice.number) +
|
||||||
(invoice.nextSendDate.isNotEmpty
|
(invoice.nextSendDate.isNotEmpty
|
||||||
|
|
|
||||||
|
|
@ -52,76 +52,75 @@ class RecurringInvoicePresenter extends EntityPresenter {
|
||||||
Widget getField({String? field, required BuildContext context}) {
|
Widget getField({String? field, required BuildContext context}) {
|
||||||
final localization = AppLocalization.of(context);
|
final localization = AppLocalization.of(context);
|
||||||
final state = StoreProvider.of<AppState>(context).state;
|
final state = StoreProvider.of<AppState>(context).state;
|
||||||
final invoice = entity as InvoiceEntity?;
|
final invoice = entity as InvoiceEntity;
|
||||||
|
|
||||||
switch (field) {
|
switch (field) {
|
||||||
case RecurringInvoiceFields.status:
|
case RecurringInvoiceFields.status:
|
||||||
return EntityStatusChip(entity: invoice, showState: true);
|
return EntityStatusChip(entity: invoice, showState: true);
|
||||||
case RecurringInvoiceFields.number:
|
case RecurringInvoiceFields.number:
|
||||||
return Text((invoice!.number ?? '').isEmpty
|
return Text(
|
||||||
? localization!.pending
|
invoice.number.isEmpty ? localization!.pending : invoice.number);
|
||||||
: invoice.number);
|
|
||||||
case RecurringInvoiceFields.client:
|
case RecurringInvoiceFields.client:
|
||||||
final client = state.clientState.get(invoice!.clientId);
|
final client = state.clientState.get(invoice.clientId);
|
||||||
return LinkTextRelatedEntity(entity: client, relation: invoice);
|
return LinkTextRelatedEntity(entity: client, relation: invoice);
|
||||||
case RecurringInvoiceFields.date:
|
case RecurringInvoiceFields.date:
|
||||||
return Text(formatDate(invoice!.date, context));
|
return Text(formatDate(invoice.date, context));
|
||||||
case RecurringInvoiceFields.reminder1Sent:
|
case RecurringInvoiceFields.reminder1Sent:
|
||||||
return Text(formatDate(invoice!.reminder1Sent, context));
|
return Text(formatDate(invoice.reminder1Sent, context));
|
||||||
case RecurringInvoiceFields.reminder2Sent:
|
case RecurringInvoiceFields.reminder2Sent:
|
||||||
return Text(formatDate(invoice!.reminder2Sent, context));
|
return Text(formatDate(invoice.reminder2Sent, context));
|
||||||
case RecurringInvoiceFields.reminder3Sent:
|
case RecurringInvoiceFields.reminder3Sent:
|
||||||
return Text(formatDate(invoice!.reminder3Sent, context));
|
return Text(formatDate(invoice.reminder3Sent, context));
|
||||||
case RecurringInvoiceFields.reminderLastSent:
|
case RecurringInvoiceFields.reminderLastSent:
|
||||||
return Text(formatDate(invoice!.reminderLastSent, context));
|
return Text(formatDate(invoice.reminderLastSent, context));
|
||||||
case RecurringInvoiceFields.amount:
|
case RecurringInvoiceFields.amount:
|
||||||
return Align(
|
return Align(
|
||||||
alignment: Alignment.centerRight,
|
alignment: Alignment.centerRight,
|
||||||
child: Text(formatNumber(invoice!.amount, context,
|
child: Text(formatNumber(invoice.amount, context,
|
||||||
clientId: invoice.clientId)!),
|
clientId: invoice.clientId)!),
|
||||||
);
|
);
|
||||||
case RecurringInvoiceFields.customValue1:
|
case RecurringInvoiceFields.customValue1:
|
||||||
return Text(presentCustomField(context, invoice!.customValue1)!);
|
return Text(presentCustomField(context, invoice.customValue1)!);
|
||||||
case RecurringInvoiceFields.customValue2:
|
case RecurringInvoiceFields.customValue2:
|
||||||
return Text(presentCustomField(context, invoice!.customValue2)!);
|
return Text(presentCustomField(context, invoice.customValue2)!);
|
||||||
case RecurringInvoiceFields.customValue3:
|
case RecurringInvoiceFields.customValue3:
|
||||||
return Text(presentCustomField(context, invoice!.customValue3)!);
|
return Text(presentCustomField(context, invoice.customValue3)!);
|
||||||
case RecurringInvoiceFields.customValue4:
|
case RecurringInvoiceFields.customValue4:
|
||||||
return Text(presentCustomField(context, invoice!.customValue4)!);
|
return Text(presentCustomField(context, invoice.customValue4)!);
|
||||||
case RecurringInvoiceFields.publicNotes:
|
case RecurringInvoiceFields.publicNotes:
|
||||||
return TableTooltip(message: invoice!.publicNotes);
|
return TableTooltip(message: invoice.publicNotes);
|
||||||
case RecurringInvoiceFields.privateNotes:
|
case RecurringInvoiceFields.privateNotes:
|
||||||
return TableTooltip(message: invoice!.privateNotes);
|
return TableTooltip(message: invoice.privateNotes);
|
||||||
case RecurringInvoiceFields.discount:
|
case RecurringInvoiceFields.discount:
|
||||||
return Text(invoice!.isAmountDiscount
|
return Text(invoice.isAmountDiscount
|
||||||
? formatNumber(invoice.discount, context,
|
? formatNumber(invoice.discount, context,
|
||||||
formatNumberType: FormatNumberType.money,
|
formatNumberType: FormatNumberType.money,
|
||||||
clientId: invoice.clientId)!
|
clientId: invoice.clientId)!
|
||||||
: formatNumber(invoice.discount, context,
|
: formatNumber(invoice.discount, context,
|
||||||
formatNumberType: FormatNumberType.percent)!);
|
formatNumberType: FormatNumberType.percent)!);
|
||||||
case RecurringInvoiceFields.poNumber:
|
case RecurringInvoiceFields.poNumber:
|
||||||
return Text(invoice!.poNumber);
|
return Text(invoice.poNumber);
|
||||||
case RecurringInvoiceFields.documents:
|
case RecurringInvoiceFields.documents:
|
||||||
return Text('${invoice!.documents.length}');
|
return Text('${invoice.documents.length}');
|
||||||
case RecurringInvoiceFields.taxAmount:
|
case RecurringInvoiceFields.taxAmount:
|
||||||
return Text(formatNumber(invoice!.taxAmount, context,
|
return Text(formatNumber(invoice.taxAmount, context,
|
||||||
clientId: invoice.clientId)!);
|
clientId: invoice.clientId)!);
|
||||||
case RecurringInvoiceFields.exchangeRate:
|
case RecurringInvoiceFields.exchangeRate:
|
||||||
return Text(formatNumber(invoice!.exchangeRate, context,
|
return Text(formatNumber(invoice.exchangeRate, context,
|
||||||
formatNumberType: FormatNumberType.double)!);
|
formatNumberType: FormatNumberType.double)!);
|
||||||
case RecurringInvoiceFields.remainingCycles:
|
case RecurringInvoiceFields.remainingCycles:
|
||||||
return Text(invoice!.remainingCycles == -1
|
return Text(invoice.remainingCycles == -1
|
||||||
? localization!.endless
|
? localization!.endless
|
||||||
: '${invoice.remainingCycles}');
|
: '${invoice.remainingCycles}');
|
||||||
case RecurringInvoiceFields.nextSendDate:
|
case RecurringInvoiceFields.nextSendDate:
|
||||||
return Text(invoice!.nextSendDatetime.isNotEmpty
|
return Text(invoice.nextSendDatetime.isNotEmpty
|
||||||
? formatDate(invoice.nextSendDatetime, context,
|
? formatDate(invoice.nextSendDatetime, context,
|
||||||
showTime: true, showSeconds: false)
|
showTime: true, showSeconds: false)
|
||||||
: formatDate(invoice.nextSendDate, context));
|
: formatDate(invoice.nextSendDate, context));
|
||||||
case RecurringInvoiceFields.frequency:
|
case RecurringInvoiceFields.frequency:
|
||||||
return Text(localization!.lookup(kFrequencies[invoice!.frequencyId])!);
|
return Text(localization!.lookup(kFrequencies[invoice.frequencyId])!);
|
||||||
case RecurringInvoiceFields.dueDateDays:
|
case RecurringInvoiceFields.dueDateDays:
|
||||||
return Text(invoice!.dueDateDays == 'terms'
|
return Text(invoice.dueDateDays == 'terms'
|
||||||
? localization!.paymentTerm
|
? localization!.paymentTerm
|
||||||
: invoice.dueDateDays == 'on_receipt'
|
: invoice.dueDateDays == 'on_receipt'
|
||||||
? localization!.dueOnReceipt!
|
? localization!.dueOnReceipt!
|
||||||
|
|
@ -132,7 +131,7 @@ class RecurringInvoicePresenter extends EntityPresenter {
|
||||||
: localization!.dayCount
|
: localization!.dayCount
|
||||||
.replaceFirst(':count', '${invoice.dueDateDays}'));
|
.replaceFirst(':count', '${invoice.dueDateDays}'));
|
||||||
case RecurringInvoiceFields.autoBill:
|
case RecurringInvoiceFields.autoBill:
|
||||||
return Text(localization!.lookup(invoice!.autoBill)!);
|
return Text(localization!.lookup(invoice.autoBill)!);
|
||||||
}
|
}
|
||||||
|
|
||||||
return super.getField(field: field, context: context);
|
return super.getField(field: field, context: context);
|
||||||
|
|
|
||||||
|
|
@ -722,7 +722,7 @@ class TotalsDataTable extends StatelessWidget {
|
||||||
reportResult.columns.length > reportSettings.sortTotalsIndex
|
reportResult.columns.length > reportSettings.sortTotalsIndex
|
||||||
? reportSettings.sortTotalsIndex
|
? reportSettings.sortTotalsIndex
|
||||||
: null,
|
: null,
|
||||||
sortAscending: reportSettings.sortTotalsAscending ?? true,
|
sortAscending: reportSettings.sortTotalsAscending,
|
||||||
columns: reportResult.totalColumns(
|
columns: reportResult.totalColumns(
|
||||||
context,
|
context,
|
||||||
(index, ascending) =>
|
(index, ascending) =>
|
||||||
|
|
@ -925,7 +925,10 @@ class ReportResult {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool matchString({required String filter, String? value}) {
|
static bool matchString({
|
||||||
|
required String filter,
|
||||||
|
String? value,
|
||||||
|
}) {
|
||||||
filter = filter.trim();
|
filter = filter.trim();
|
||||||
|
|
||||||
if (filter.isEmpty) {
|
if (filter.isEmpty) {
|
||||||
|
|
@ -933,7 +936,7 @@ class ReportResult {
|
||||||
}
|
}
|
||||||
|
|
||||||
value = (value ?? '').toLowerCase();
|
value = (value ?? '').toLowerCase();
|
||||||
filter = (filter ?? '').toLowerCase();
|
filter = filter.toLowerCase();
|
||||||
|
|
||||||
if (filter == 'null' && value.isEmpty) {
|
if (filter == 'null' && value.isEmpty) {
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -1120,7 +1123,7 @@ class ReportResult {
|
||||||
))
|
))
|
||||||
else if (getReportColumnType(column, context) == ReportColumnType.age)
|
else if (getReportColumnType(column, context) == ReportColumnType.age)
|
||||||
DataCell(AppDropdownButton<String>(
|
DataCell(AppDropdownButton<String>(
|
||||||
value: (textEditingControllers[column]!.text ?? '').isNotEmpty &&
|
value: (textEditingControllers[column]!.text).isNotEmpty &&
|
||||||
textEditingControllers[column]!.text != 'null'
|
textEditingControllers[column]!.text != 'null'
|
||||||
? textEditingControllers[column]!.text
|
? textEditingControllers[column]!.text
|
||||||
: null,
|
: null,
|
||||||
|
|
|
||||||
|
|
@ -164,10 +164,10 @@ ReportResult taskReport(
|
||||||
value = task.description;
|
value = task.description;
|
||||||
break;
|
break;
|
||||||
case TaskReportFields.invoice:
|
case TaskReportFields.invoice:
|
||||||
value = invoice.listDisplayName ?? '';
|
value = invoice.listDisplayName;
|
||||||
break;
|
break;
|
||||||
case TaskReportFields.invoice_amount:
|
case TaskReportFields.invoice_amount:
|
||||||
value = invoice.amount ?? '';
|
value = invoice.amount;
|
||||||
break;
|
break;
|
||||||
case TaskReportFields.invoice_date:
|
case TaskReportFields.invoice_date:
|
||||||
value = invoice.isNew ? '' : invoice.date;
|
value = invoice.isNew ? '' : invoice.date;
|
||||||
|
|
|
||||||
|
|
@ -152,7 +152,7 @@ class VendorOverview extends StatelessWidget {
|
||||||
vendor.id, state.transactionState.map)
|
vendor.id, state.transactionState.map)
|
||||||
.present(localization.active, localization.archived),
|
.present(localization.active, localization.archived),
|
||||||
),
|
),
|
||||||
if ((vendor.publicNotes ?? '').isNotEmpty) ...[
|
if (vendor.publicNotes.isNotEmpty) ...[
|
||||||
IconMessage(vendor.publicNotes, copyToClipboard: true),
|
IconMessage(vendor.publicNotes, copyToClipboard: true),
|
||||||
ListDivider()
|
ListDivider()
|
||||||
],
|
],
|
||||||
|
|
|
||||||
|
|
@ -276,8 +276,7 @@ AppLayout calculateLayout(BuildContext context) {
|
||||||
}
|
}
|
||||||
|
|
||||||
AppLayout getLayout(BuildContext context) =>
|
AppLayout getLayout(BuildContext context) =>
|
||||||
StoreProvider.of<AppState>(context).state.prefState.appLayout ??
|
StoreProvider.of<AppState>(context).state.prefState.appLayout;
|
||||||
AppLayout.mobile;
|
|
||||||
|
|
||||||
bool isMobile(BuildContext context) => getLayout(context) == AppLayout.mobile;
|
bool isMobile(BuildContext context) => getLayout(context) == AppLayout.mobile;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@ String toCamelCase(String subject) {
|
||||||
}
|
}
|
||||||
|
|
||||||
String toSpaceCase(String value) {
|
String toSpaceCase(String value) {
|
||||||
if ((value ?? '').isEmpty) {
|
if (value.isEmpty) {
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue