Aging report
This commit is contained in:
parent
f738814daf
commit
69da36731d
|
|
@ -231,6 +231,20 @@ const String kSettings = 'settings';
|
||||||
const String kDashboard = 'dashboard';
|
const String kDashboard = 'dashboard';
|
||||||
const String kReports = 'reports';
|
const String kReports = 'reports';
|
||||||
|
|
||||||
|
const String kAgeGroup0 = 'age_group_0';
|
||||||
|
const String kAgeGroup30 = 'age_group_30';
|
||||||
|
const String kAgeGroup60 = 'age_group_60';
|
||||||
|
const String kAgeGroup90 = 'age_group_90';
|
||||||
|
const String kAgeGroup120 = 'age_group_120';
|
||||||
|
|
||||||
|
const kAgeGroups = {
|
||||||
|
kAgeGroup0: 0,
|
||||||
|
kAgeGroup30: 30,
|
||||||
|
kAgeGroup60: 60,
|
||||||
|
kAgeGroup90: 90,
|
||||||
|
kAgeGroup120: 120,
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
const String kEmailTemplateInvoice = 'invoice_email';
|
const String kEmailTemplateInvoice = 'invoice_email';
|
||||||
const String kEmailTemplateQuote = 'quote_email';
|
const String kEmailTemplateQuote = 'quote_email';
|
||||||
|
|
|
||||||
|
|
@ -783,144 +783,163 @@ class ReportResult {
|
||||||
],
|
],
|
||||||
))
|
))
|
||||||
else
|
else
|
||||||
if (getReportColumnType(column, context) ==
|
if (column == 'age')
|
||||||
ReportColumnType.number)
|
DataCell(AppDropdownButton<String>(
|
||||||
DataCell(TextFormField(
|
value: (textEditingControllers[column].text ?? '')
|
||||||
controller: textEditingControllers[column],
|
.isNotEmpty &&
|
||||||
keyboardType: TextInputType.numberWithOptions(decimal: true),
|
textEditingControllers[column].text != 'null'
|
||||||
decoration: InputDecoration(
|
? localization.lookup(textEditingControllers[column].text)
|
||||||
suffixIcon: textEditingControllers == null
|
: null,
|
||||||
? null
|
onChanged: (dynamic value) {
|
||||||
: (textEditingControllers[column]?.text ?? '').isEmpty
|
print('## onChanged: $value');
|
||||||
? null
|
},
|
||||||
: IconButton(
|
items: kAgeGroups.keys.map((ageGroup) =>
|
||||||
icon: Icon(
|
DropdownMenuItem(
|
||||||
Icons.clear,
|
child: Text(localization.lookup(ageGroup)),
|
||||||
color: Colors.grey,
|
value: ageGroup,
|
||||||
),
|
)).toList(),
|
||||||
onPressed: () {
|
|
||||||
textEditingControllers[column].text = '';
|
|
||||||
onFilterChanged(column, '');
|
|
||||||
},
|
|
||||||
)),
|
|
||||||
))
|
))
|
||||||
else
|
else
|
||||||
if (getReportColumnType(column, context) ==
|
if (getReportColumnType(column, context) ==
|
||||||
ReportColumnType.dateTime ||
|
ReportColumnType.number)
|
||||||
getReportColumnType(column, context) == ReportColumnType.date)
|
DataCell(TextFormField(
|
||||||
DataCell(AppDropdownButton<DateRange>(
|
controller: textEditingControllers[column],
|
||||||
labelText: null,
|
keyboardType: TextInputType.numberWithOptions(decimal: true),
|
||||||
showBlank: true,
|
decoration: InputDecoration(
|
||||||
blankValue: null,
|
suffixIcon: textEditingControllers == null
|
||||||
value: (textEditingControllers[column].text ?? '')
|
? null
|
||||||
.isNotEmpty &&
|
: (textEditingControllers[column]?.text ?? '').isEmpty
|
||||||
textEditingControllers[column].text != 'null'
|
? null
|
||||||
? DateRange.valueOf(textEditingControllers[column].text)
|
: IconButton(
|
||||||
: null,
|
icon: Icon(
|
||||||
onChanged: (dynamic value) {
|
Icons.clear,
|
||||||
if (value == null) {
|
color: Colors.grey,
|
||||||
textEditingControllers[column].text = '';
|
|
||||||
onFilterChanged(column, '');
|
|
||||||
} else {
|
|
||||||
textEditingControllers[column].text = value.toString();
|
|
||||||
onFilterChanged(column, value.toString());
|
|
||||||
}
|
|
||||||
},
|
|
||||||
items: DateRange.values
|
|
||||||
.map((dateRange) =>
|
|
||||||
DropdownMenuItem<DateRange>(
|
|
||||||
child: Text(localization.lookup(dateRange.toString())),
|
|
||||||
value: dateRange,
|
|
||||||
))
|
|
||||||
.toList(),
|
|
||||||
))
|
|
||||||
// TODO remove DEMO_MODE check
|
|
||||||
else
|
|
||||||
if (Config.DEMO_MODE)
|
|
||||||
DataCell(TextFormField(
|
|
||||||
controller: textEditingControllers != null
|
|
||||||
? textEditingControllers[column]
|
|
||||||
: null,
|
|
||||||
decoration: InputDecoration(
|
|
||||||
suffixIcon: textEditingControllers == null
|
|
||||||
? null
|
|
||||||
: (textEditingControllers[column]?.text ?? '')
|
|
||||||
.isEmpty
|
|
||||||
? null
|
|
||||||
: IconButton(
|
|
||||||
icon: Icon(
|
|
||||||
Icons.clear,
|
|
||||||
color: Colors.grey,
|
|
||||||
),
|
|
||||||
onPressed: () {
|
|
||||||
textEditingControllers[column].text = '';
|
|
||||||
onFilterChanged(column, '');
|
|
||||||
},
|
|
||||||
)),
|
|
||||||
))
|
|
||||||
else
|
|
||||||
DataCell(
|
|
||||||
TypeAheadFormField(
|
|
||||||
noItemsFoundBuilder: (context) => SizedBox(),
|
|
||||||
suggestionsBoxDecoration: SuggestionsBoxDecoration(
|
|
||||||
constraints: BoxConstraints(
|
|
||||||
minWidth: 300,
|
|
||||||
),
|
),
|
||||||
|
onPressed: () {
|
||||||
|
textEditingControllers[column].text = '';
|
||||||
|
onFilterChanged(column, '');
|
||||||
|
},
|
||||||
|
)),
|
||||||
|
))
|
||||||
|
else
|
||||||
|
if (getReportColumnType(column, context) ==
|
||||||
|
ReportColumnType.dateTime ||
|
||||||
|
getReportColumnType(column, context) ==
|
||||||
|
ReportColumnType.date)
|
||||||
|
DataCell(AppDropdownButton<DateRange>(
|
||||||
|
labelText: null,
|
||||||
|
showBlank: true,
|
||||||
|
blankValue: null,
|
||||||
|
value: (textEditingControllers[column].text ?? '')
|
||||||
|
.isNotEmpty &&
|
||||||
|
textEditingControllers[column].text != 'null'
|
||||||
|
? DateRange.valueOf(textEditingControllers[column].text)
|
||||||
|
: null,
|
||||||
|
onChanged: (dynamic value) {
|
||||||
|
if (value == null) {
|
||||||
|
textEditingControllers[column].text = '';
|
||||||
|
onFilterChanged(column, '');
|
||||||
|
} else {
|
||||||
|
textEditingControllers[column].text = value.toString();
|
||||||
|
onFilterChanged(column, value.toString());
|
||||||
|
}
|
||||||
|
},
|
||||||
|
items: DateRange.values
|
||||||
|
.map((dateRange) =>
|
||||||
|
DropdownMenuItem<DateRange>(
|
||||||
|
child: Text(localization.lookup(dateRange
|
||||||
|
.toString())),
|
||||||
|
value: dateRange,
|
||||||
|
))
|
||||||
|
.toList(),
|
||||||
|
))
|
||||||
|
// TODO remove DEMO_MODE check
|
||||||
|
else
|
||||||
|
if (Config.DEMO_MODE)
|
||||||
|
DataCell(TextFormField(
|
||||||
|
controller: textEditingControllers != null
|
||||||
|
? textEditingControllers[column]
|
||||||
|
: null,
|
||||||
|
decoration: InputDecoration(
|
||||||
|
suffixIcon: textEditingControllers == null
|
||||||
|
? null
|
||||||
|
: (textEditingControllers[column]?.text ?? '')
|
||||||
|
.isEmpty
|
||||||
|
? null
|
||||||
|
: IconButton(
|
||||||
|
icon: Icon(
|
||||||
|
Icons.clear,
|
||||||
|
color: Colors.grey,
|
||||||
|
),
|
||||||
|
onPressed: () {
|
||||||
|
textEditingControllers[column].text = '';
|
||||||
|
onFilterChanged(column, '');
|
||||||
|
},
|
||||||
|
)),
|
||||||
|
))
|
||||||
|
else
|
||||||
|
DataCell(
|
||||||
|
TypeAheadFormField(
|
||||||
|
noItemsFoundBuilder: (context) => SizedBox(),
|
||||||
|
suggestionsBoxDecoration: SuggestionsBoxDecoration(
|
||||||
|
constraints: BoxConstraints(
|
||||||
|
minWidth: 300,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
suggestionsCallback: (filter) {
|
||||||
|
filter = filter.toLowerCase();
|
||||||
|
final index = columns.indexOf(column);
|
||||||
|
return data
|
||||||
|
.where((row) =>
|
||||||
|
row[index]
|
||||||
|
.renderText(context, column)
|
||||||
|
.toLowerCase()
|
||||||
|
.contains(filter) &&
|
||||||
|
row[index]
|
||||||
|
.renderText(context, column)
|
||||||
|
.trim()
|
||||||
|
.isNotEmpty)
|
||||||
|
.map((row) =>
|
||||||
|
row[index].renderText(context, column))
|
||||||
|
.toSet()
|
||||||
|
.toList();
|
||||||
|
},
|
||||||
|
itemBuilder: (context, String entityId) {
|
||||||
|
return Padding(
|
||||||
|
padding: const EdgeInsets.all(12),
|
||||||
|
child: Text('$entityId'),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
onSuggestionSelected: (String value) {
|
||||||
|
textEditingControllers[column].text = value;
|
||||||
|
onFilterChanged(column, value);
|
||||||
|
},
|
||||||
|
textFieldConfiguration: TextFieldConfiguration<String>(
|
||||||
|
controller: textEditingControllers != null
|
||||||
|
? textEditingControllers[column]
|
||||||
|
: null,
|
||||||
|
decoration: InputDecoration(
|
||||||
|
suffixIcon: textEditingControllers == null
|
||||||
|
? null
|
||||||
|
: (textEditingControllers[column]?.text ?? '')
|
||||||
|
.isEmpty
|
||||||
|
? null
|
||||||
|
: IconButton(
|
||||||
|
icon: Icon(
|
||||||
|
Icons.clear,
|
||||||
|
color: Colors.grey,
|
||||||
|
),
|
||||||
|
onPressed: () {
|
||||||
|
textEditingControllers[column].text = '';
|
||||||
|
onFilterChanged(column, '');
|
||||||
|
},
|
||||||
|
)),
|
||||||
|
),
|
||||||
|
autoFlipDirection: true,
|
||||||
|
animationStart: 1,
|
||||||
|
debounceDuration: Duration(seconds: 0),
|
||||||
),
|
),
|
||||||
suggestionsCallback: (filter) {
|
)
|
||||||
filter = filter.toLowerCase();
|
|
||||||
final index = columns.indexOf(column);
|
|
||||||
return data
|
|
||||||
.where((row) =>
|
|
||||||
row[index]
|
|
||||||
.renderText(context, column)
|
|
||||||
.toLowerCase()
|
|
||||||
.contains(filter) &&
|
|
||||||
row[index]
|
|
||||||
.renderText(context, column)
|
|
||||||
.trim()
|
|
||||||
.isNotEmpty)
|
|
||||||
.map((row) =>
|
|
||||||
row[index].renderText(context, column))
|
|
||||||
.toSet()
|
|
||||||
.toList();
|
|
||||||
},
|
|
||||||
itemBuilder: (context, String entityId) {
|
|
||||||
return Padding(
|
|
||||||
padding: const EdgeInsets.all(12),
|
|
||||||
child: Text('$entityId'),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
onSuggestionSelected: (String value) {
|
|
||||||
textEditingControllers[column].text = value;
|
|
||||||
onFilterChanged(column, value);
|
|
||||||
},
|
|
||||||
textFieldConfiguration: TextFieldConfiguration<String>(
|
|
||||||
controller: textEditingControllers != null
|
|
||||||
? textEditingControllers[column]
|
|
||||||
: null,
|
|
||||||
decoration: InputDecoration(
|
|
||||||
suffixIcon: textEditingControllers == null
|
|
||||||
? null
|
|
||||||
: (textEditingControllers[column]?.text ?? '')
|
|
||||||
.isEmpty
|
|
||||||
? null
|
|
||||||
: IconButton(
|
|
||||||
icon: Icon(
|
|
||||||
Icons.clear,
|
|
||||||
color: Colors.grey,
|
|
||||||
),
|
|
||||||
onPressed: () {
|
|
||||||
textEditingControllers[column].text = '';
|
|
||||||
onFilterChanged(column, '');
|
|
||||||
},
|
|
||||||
)),
|
|
||||||
),
|
|
||||||
autoFlipDirection: true,
|
|
||||||
animationStart: 1,
|
|
||||||
debounceDuration: Duration(seconds: 0),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,11 @@ mixin LocalizationsProvider on LocaleCodeAware {
|
||||||
static final Map<String, Map<String, String>> _localizedValues = {
|
static final Map<String, Map<String, String>> _localizedValues = {
|
||||||
'en': {
|
'en': {
|
||||||
// STARTER: lang key - do not remove comment
|
// STARTER: lang key - do not remove comment
|
||||||
|
'age_group_0': '0 - 30 Days',
|
||||||
|
'age_group_30': '30 - 60 Days',
|
||||||
|
'age_group_60': '60 - 90 Days',
|
||||||
|
'age_group_90': '90 - 120 Days',
|
||||||
|
'age_group_120': '120+ Days',
|
||||||
'refresh': 'Refresh',
|
'refresh': 'Refresh',
|
||||||
'saved_design': 'Successfully saved design',
|
'saved_design': 'Successfully saved design',
|
||||||
'client_details': 'Client Details',
|
'client_details': 'Client Details',
|
||||||
|
|
@ -33039,6 +33044,16 @@ mixin LocalizationsProvider on LocaleCodeAware {
|
||||||
|
|
||||||
String get age => _localizedValues[localeCode]['age'];
|
String get age => _localizedValues[localeCode]['age'];
|
||||||
|
|
||||||
|
String get ageGroup0 => _localizedValues[localeCode]['age_group_0'];
|
||||||
|
|
||||||
|
String get ageGroup30 => _localizedValues[localeCode]['age_group_30'];
|
||||||
|
|
||||||
|
String get ageGroup60 => _localizedValues[localeCode]['age_group_60'];
|
||||||
|
|
||||||
|
String get ageGroup90 => _localizedValues[localeCode]['age_group_90'];
|
||||||
|
|
||||||
|
String get ageGroup120 => _localizedValues[localeCode]['age_group_120'];
|
||||||
|
|
||||||
String lookup(String key) {
|
String lookup(String key) {
|
||||||
final lookupKey = toSnakeCase(key);
|
final lookupKey = toSnakeCase(key);
|
||||||
return _localizedValues[localeCode][lookupKey] ??
|
return _localizedValues[localeCode][lookupKey] ??
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue