203 lines
5.1 KiB
Dart
203 lines
5.1 KiB
Dart
// Flutter imports:
|
|
import 'package:flutter/material.dart';
|
|
|
|
// Package imports:
|
|
import 'package:flutter_redux/flutter_redux.dart';
|
|
|
|
// Project imports:
|
|
import 'package:invoiceninja_flutter/data/models/entities.dart';
|
|
import 'package:invoiceninja_flutter/redux/app/app_state.dart';
|
|
import 'package:invoiceninja_flutter/ui/app/link_text.dart';
|
|
import 'package:invoiceninja_flutter/utils/formatting.dart';
|
|
import 'package:invoiceninja_flutter/utils/localization.dart';
|
|
|
|
class EntityPresenter {
|
|
EntityPresenter initialize(
|
|
BaseEntity entity,
|
|
BuildContext context,
|
|
) {
|
|
this.entity = entity;
|
|
this.context = context;
|
|
|
|
return this;
|
|
}
|
|
|
|
late BaseEntity entity;
|
|
late BuildContext context;
|
|
|
|
String? title({bool isNarrow = false}) {
|
|
final localization = AppLocalization.of(context)!;
|
|
final type = localization.lookup('${entity!.entityType}');
|
|
var name = entity!.listDisplayName;
|
|
|
|
// TODO replace with this: https://github.com/flutter/flutter/issues/45336
|
|
if ((name ?? '').isEmpty) {
|
|
name = localization.pending;
|
|
}
|
|
|
|
if ([
|
|
EntityType.company,
|
|
EntityType.client,
|
|
EntityType.vendor,
|
|
EntityType.project,
|
|
EntityType.user,
|
|
EntityType.product,
|
|
EntityType.transaction,
|
|
EntityType.document,
|
|
].contains(entity!.entityType) ||
|
|
isNarrow) {
|
|
return name;
|
|
} else {
|
|
return '$type $name';
|
|
}
|
|
}
|
|
|
|
static List<String> getBaseFields() {
|
|
return [
|
|
EntityFields.createdAt,
|
|
EntityFields.updatedAt,
|
|
EntityFields.archivedAt,
|
|
EntityFields.assignedTo,
|
|
EntityFields.createdBy,
|
|
EntityFields.state,
|
|
EntityFields.isDeleted,
|
|
];
|
|
}
|
|
|
|
Widget getField({String? field, required BuildContext context}) {
|
|
final localization = AppLocalization.of(context);
|
|
final store = StoreProvider.of<AppState>(context);
|
|
final state = store.state;
|
|
|
|
switch (field) {
|
|
case EntityFields.createdAt:
|
|
return Text(formatDate(
|
|
convertTimestampToDateString(entity!.createdAt), context,
|
|
showTime: true));
|
|
case EntityFields.updatedAt:
|
|
return Text(entity!.updatedAt == 0
|
|
? ''
|
|
: formatDate(
|
|
convertTimestampToDateString(entity!.updatedAt), context,
|
|
showTime: true));
|
|
case EntityFields.archivedAt:
|
|
return Text(entity!.archivedAt == 0
|
|
? ''
|
|
: formatDate(
|
|
convertTimestampToDateString(entity!.archivedAt), context,
|
|
showTime: true));
|
|
case EntityFields.state:
|
|
return Text(entity!.isActive
|
|
? localization!.active
|
|
: entity!.isArchived
|
|
? localization!.archived
|
|
: localization!.deleted);
|
|
case EntityFields.createdBy:
|
|
final user = state.userState.get(entity!.createdUserId!);
|
|
return LinkTextRelatedEntity(entity: user, relation: entity);
|
|
case EntityFields.assignedTo:
|
|
final user = state.userState.get(entity!.assignedUserId!);
|
|
return LinkTextRelatedEntity(entity: user, relation: entity);
|
|
case EntityFields.isDeleted:
|
|
return Text(entity!.isDeleted! ? localization!.yes : localization!.no);
|
|
}
|
|
|
|
return Text('Error: $field not found');
|
|
}
|
|
|
|
static bool isFieldLocalized(String? field) => [
|
|
'status',
|
|
].contains(field);
|
|
|
|
static bool isFieldAmount(String? field) {
|
|
return [
|
|
'quantity',
|
|
'stock_quantity',
|
|
'documents',
|
|
].contains(field);
|
|
}
|
|
|
|
static bool isFieldNumeric(String field) {
|
|
if (field.startsWith('converted_')) {
|
|
return true;
|
|
}
|
|
|
|
final value = [
|
|
'balance',
|
|
'paid_to_date',
|
|
'amount',
|
|
'quantity',
|
|
'price',
|
|
'cost',
|
|
'line_total',
|
|
'discount',
|
|
'profit',
|
|
'total',
|
|
'payment',
|
|
'expense',
|
|
'invoice_amount',
|
|
'invoice_balance',
|
|
'client_balance',
|
|
'credit_balance',
|
|
'payment_balance',
|
|
'tax_rate',
|
|
'tax_amount',
|
|
'tax_amount1',
|
|
'tax_amount2',
|
|
'tax_amount3',
|
|
'tax_paid',
|
|
'payment_amount',
|
|
'net_balance',
|
|
'rate',
|
|
'calculated_rate',
|
|
'duration',
|
|
'net_amount',
|
|
'net_total',
|
|
'age_group_0',
|
|
'age_group_30',
|
|
'age_group_60',
|
|
'age_group_90',
|
|
'age_group_120',
|
|
'stock_quantity',
|
|
'notification_threshold',
|
|
'partial',
|
|
'withdrawal',
|
|
'deposit',
|
|
'documents',
|
|
].contains(field);
|
|
|
|
return value;
|
|
}
|
|
|
|
String? presentCustomField(BuildContext context, String value) {
|
|
if (['yes', 'no'].contains(value)) {
|
|
final localization = AppLocalization.of(context)!;
|
|
return localization.lookup(value);
|
|
} else if (RegExp('^\\d{4}-\\d{2}-\\d{2}\$').hasMatch(value)) {
|
|
return formatDate(value, context);
|
|
}
|
|
|
|
return value;
|
|
}
|
|
}
|
|
|
|
class TableTooltip extends StatelessWidget {
|
|
const TableTooltip({
|
|
required this.message,
|
|
});
|
|
|
|
final String message;
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Tooltip(
|
|
message: message,
|
|
child: Text(
|
|
message,
|
|
overflow: TextOverflow.ellipsis,
|
|
maxLines: 2,
|
|
),
|
|
);
|
|
}
|
|
}
|