Working on clients

This commit is contained in:
unknown 2018-08-08 14:16:15 +03:00
parent 7c9af8e31a
commit 13e0bdfc6c
12 changed files with 144 additions and 34 deletions

View File

@ -28,6 +28,8 @@ class EntityType extends EnumClass {
static const EntityType country = _$country;
static const EntityType currency = _$currency;
static const EntityType language = _$language;
static const EntityType industry = _$language;
static const EntityType size = _$language;
String get plural {
return toString() + 's';

View File

@ -1,6 +1,7 @@
import 'package:built_collection/built_collection.dart';
import 'package:built_value/built_value.dart';
import 'package:built_value/serializer.dart';
import 'package:invoiceninja_flutter/data/models/entities.dart';
part 'industry_model.g.dart';
@ -28,7 +29,7 @@ class IndustryFields {
static const String name = 'name';
}
abstract class IndustryEntity implements Built<IndustryEntity, IndustryEntityBuilder> {
abstract class IndustryEntity extends Object with SelectableEntity implements Built<IndustryEntity, IndustryEntityBuilder> {
factory IndustryEntity() {
return _$IndustryEntity._(
@ -38,8 +39,41 @@ abstract class IndustryEntity implements Built<IndustryEntity, IndustryEntityBui
}
IndustryEntity._();
int get id;
String get name;
@override
bool matchesFilter(String filter) {
if (filter == null || filter.isEmpty) {
return true;
}
filter = filter.toLowerCase();
if (name.toLowerCase().contains(filter)) {
return true;
}
return false;
}
@override
String matchesFilterValue(String filter) {
if (filter == null || filter.isEmpty) {
return null;
}
filter = filter.toLowerCase();
return null;
}
@override
String get listDisplayName {
return name;
}
@override
double get listDisplayAmount => null;
static Serializer<IndustryEntity> get serializer => _$industryEntitySerializer;
}

View File

@ -1,6 +1,7 @@
import 'package:built_collection/built_collection.dart';
import 'package:built_value/built_value.dart';
import 'package:built_value/serializer.dart';
import 'package:invoiceninja_flutter/data/models/entities.dart';
part 'size_model.g.dart';
@ -28,7 +29,7 @@ class SizeFields {
static const String name = 'name';
}
abstract class SizeEntity implements Built<SizeEntity, SizeEntityBuilder> {
abstract class SizeEntity extends Object with SelectableEntity implements Built<SizeEntity, SizeEntityBuilder> {
factory SizeEntity() {
return _$SizeEntity._(
@ -38,9 +39,41 @@ abstract class SizeEntity implements Built<SizeEntity, SizeEntityBuilder> {
}
SizeEntity._();
int get id;
String get name;
@override
bool matchesFilter(String filter) {
if (filter == null || filter.isEmpty) {
return true;
}
filter = filter.toLowerCase();
if (name.toLowerCase().contains(filter)) {
return true;
}
return false;
}
@override
String matchesFilterValue(String filter) {
if (filter == null || filter.isEmpty) {
return null;
}
filter = filter.toLowerCase();
return null;
}
@override
String get listDisplayName {
return name;
}
@override
double get listDisplayAmount => null;
static Serializer<SizeEntity> get serializer => _$sizeEntitySerializer;
}

View File

@ -38,3 +38,27 @@ List<int> currencyList(BuiltMap<int, CurrencyEntity> currencyMap) {
return list;
}
var memoizedIndustryList = memo1((BuiltMap<int, IndustryEntity> industryMap) =>
industryList(industryMap));
List<int> industryList(BuiltMap<int, IndustryEntity> industryMap) {
final list = industryMap.keys.toList();
list.sort((idA, idB) => industryMap[idA].listDisplayName
.compareTo(industryMap[idB].listDisplayName));
return list;
}
var memoizedSizeList = memo1((BuiltMap<int, SizeEntity> sizeMap) =>
sizeList(sizeMap));
List<int> sizeList(BuiltMap<int, SizeEntity> sizeMap) {
final list = sizeMap.keys.toList();
list.sort((idA, idB) => sizeMap[idA].listDisplayName
.compareTo(sizeMap[idB].listDisplayName));
return list;
}

View File

@ -125,10 +125,10 @@ class ClientEditBillingAddressState extends State<ClientEditBillingAddress> {
),
EntityDropdown(
entityType: EntityType.country,
entityMap: viewModel.countryMap,
entityList: memoizedCountryList(viewModel.countryMap),
entityMap: viewModel.staticState.countryMap,
entityList: memoizedCountryList(viewModel.staticState.countryMap),
labelText: localization.country,
initialValue: viewModel.countryMap[client.countryId]?.name,
initialValue: viewModel.staticState.countryMap[client.countryId]?.name,
onSelected: (int countryId) => viewModel
.onChanged(client.rebuild((b) => b..countryId = countryId)),
),

View File

@ -1,8 +1,11 @@
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:invoiceninja_flutter/data/models/entities.dart';
import 'package:invoiceninja_flutter/ui/app/entity_dropdown.dart';
import 'package:invoiceninja_flutter/ui/client/edit/client_edit_vm.dart';
import 'package:invoiceninja_flutter/utils/localization.dart';
import 'package:invoiceninja_flutter/ui/app/form_card.dart';
import 'package:invoiceninja_flutter/redux/static/static_selectors.dart';
class ClientEditNotes extends StatefulWidget {
const ClientEditNotes({
@ -66,6 +69,7 @@ class ClientEditNotesState extends State<ClientEditNotes> {
Widget build(BuildContext context) {
final localization = AppLocalization.of(context);
final viewModel = widget.viewModel;
final client = viewModel.client;
return ListView(
shrinkWrap: true,
@ -73,7 +77,7 @@ class ClientEditNotesState extends State<ClientEditNotes> {
FormCard(
children: <Widget>[
TextFormField(
maxLines: 6,
maxLines: 4,
controller: _publicNotesController,
keyboardType: TextInputType.multiline,
decoration: InputDecoration(
@ -81,13 +85,31 @@ class ClientEditNotesState extends State<ClientEditNotes> {
),
),
TextFormField(
maxLines: 6,
maxLines: 4,
controller: _privateNotesController,
keyboardType: TextInputType.multiline,
decoration: InputDecoration(
labelText: localization.privateNotes,
),
),
EntityDropdown(
entityType: EntityType.size,
entityMap: viewModel.staticState.sizeMap,
entityList: memoizedSizeList(viewModel.staticState.sizeMap),
labelText: localization.size,
initialValue: viewModel.staticState.sizeMap[client.sizeId]?.name,
onSelected: (int sizeId) => viewModel
.onChanged(client.rebuild((b) => b..sizeId = sizeId)),
),
EntityDropdown(
entityType: EntityType.industry,
entityMap: viewModel.staticState.industryMap,
entityList: memoizedIndustryList(viewModel.staticState.industryMap),
labelText: localization.industry,
initialValue: viewModel.staticState.industryMap[client.industryId]?.name,
onSelected: (int industryId) => viewModel
.onChanged(client.rebuild((b) => b..industryId = industryId)),
),
],
),
],

View File

@ -77,19 +77,19 @@ class ClientEditSettingsState extends State<ClientEditSettings> {
children: <Widget>[
EntityDropdown(
entityType: EntityType.currency,
entityMap: viewModel.currencyMap,
entityList: memoizedCurrencyList(viewModel.currencyMap),
entityMap: viewModel.staticState.currencyMap,
entityList: memoizedCurrencyList(viewModel.staticState.currencyMap),
labelText: localization.currency,
initialValue: viewModel.currencyMap[client.currencyId]?.name,
initialValue: viewModel.staticState.currencyMap[client.currencyId]?.name,
onSelected: (int currencyId) => viewModel
.onChanged(client.rebuild((b) => b..currencyId = currencyId)),
),
EntityDropdown(
entityType: EntityType.language,
entityMap: viewModel.languageMap,
entityList: memoizedLanguageList(viewModel.languageMap),
entityMap: viewModel.staticState.languageMap,
entityList: memoizedLanguageList(viewModel.staticState.languageMap),
labelText: localization.language,
initialValue: viewModel.languageMap[client.languageId]?.name,
initialValue: viewModel.staticState.languageMap[client.languageId]?.name,
onSelected: (int languageId) => viewModel
.onChanged(client.rebuild((b) => b..languageId = languageId)),
),

View File

@ -125,10 +125,10 @@ class ClientEditShippingAddressState extends State<ClientEditShippingAddress> {
),
EntityDropdown(
entityType: EntityType.country,
entityMap: viewModel.countryMap,
entityList: memoizedCountryList(viewModel.countryMap),
entityMap: viewModel.staticState.countryMap,
entityList: memoizedCountryList(viewModel.staticState.countryMap),
labelText: localization.country,
initialValue: viewModel.countryMap[client.shippingCountryId]?.name,
initialValue: viewModel.staticState.countryMap[client.shippingCountryId]?.name,
onSelected: (int countryId) => viewModel
.onChanged(client.rebuild((b) => b..shippingCountryId = countryId)),
),

View File

@ -1,11 +1,11 @@
import 'dart:async';
import 'package:built_collection/built_collection.dart';
import 'package:flutter/material.dart';
import 'package:flutter_redux/flutter_redux.dart';
import 'package:invoiceninja_flutter/data/models/models.dart';
import 'package:invoiceninja_flutter/redux/app/app_state.dart';
import 'package:invoiceninja_flutter/redux/client/client_actions.dart';
import 'package:invoiceninja_flutter/redux/static/static_state.dart';
import 'package:invoiceninja_flutter/redux/ui/ui_actions.dart';
import 'package:invoiceninja_flutter/ui/app/dialogs/error_dialog.dart';
import 'package:invoiceninja_flutter/ui/client/client_screen.dart';
@ -42,9 +42,7 @@ class ClientEditVM {
final Function(ClientEntity) onChanged;
final Function(BuildContext) onSavePressed;
final Function onBackPressed;
final BuiltMap<int, CountryEntity> countryMap;
final BuiltMap<int, LanguageEntity> languageMap;
final BuiltMap<int, CurrencyEntity> currencyMap;
final StaticState staticState;
ClientEditVM({
@required this.company,
@ -54,9 +52,7 @@ class ClientEditVM {
@required this.onChanged,
@required this.onSavePressed,
@required this.onBackPressed,
@required this.countryMap,
@required this.languageMap,
@required this.currencyMap,
@required this.staticState,
});
factory ClientEditVM.fromStore(Store<AppState> store) {
@ -67,9 +63,7 @@ class ClientEditVM {
company: state.selectedCompany,
client: client,
origClient: state.clientState.map[client.id],
countryMap: state.staticState.countryMap,
languageMap: state.staticState.languageMap,
currencyMap: state.staticState.currencyMap,
staticState: state.staticState,
isSaving: state.isSaving,
onBackPressed: () =>
store.dispatch(UpdateCurrentRoute(ClientScreen.route)),

View File

@ -8,14 +8,12 @@ import 'package:invoiceninja_flutter/ui/invoice/invoice_screen.dart';
import 'package:invoiceninja_flutter/utils/completers.dart';
import 'package:invoiceninja_flutter/utils/localization.dart';
import 'package:invoiceninja_flutter/utils/pdf.dart';
import 'package:invoiceninja_flutter/utils/platforms.dart';
import 'package:redux/redux.dart';
import 'package:invoiceninja_flutter/redux/invoice/invoice_actions.dart';
import 'package:invoiceninja_flutter/data/models/models.dart';
import 'package:invoiceninja_flutter/ui/invoice/view/invoice_view.dart';
import 'package:invoiceninja_flutter/redux/app/app_state.dart';
import 'package:invoiceninja_flutter/ui/app/snackbar_row.dart';
import 'package:url_launcher/url_launcher.dart';
class InvoiceViewScreen extends StatelessWidget {
static const String route = '/invoice/view';

View File

@ -179,6 +179,8 @@ class AppLocalization {
'no_records_found': 'No records found',
'clone': 'Clone',
'loading': 'Loading',
'industry': 'Industry',
'size': 'Size',
'payment': 'Payment',
'payments': 'Payments',
@ -413,6 +415,8 @@ class AppLocalization {
String get noRecordsFound => _localizedValues[locale.languageCode]['no_records_found'];
String get clone => _localizedValues[locale.languageCode]['clone'];
String get loading => _localizedValues[locale.languageCode]['loading'];
String get industry => _localizedValues[locale.languageCode]['industry'];
String get size => _localizedValues[locale.languageCode]['size'];
String get payment => _localizedValues[locale.languageCode]['payment'];
String get payments => _localizedValues[locale.languageCode]['payments'];

View File

@ -1,5 +1,4 @@
import 'package:flutter/material.dart';
import 'package:invoiceninja_flutter/data/models/invoice_model.dart';
String getMapURL(BuildContext context) {
final bool iOS = Theme.of(context).platform == TargetPlatform.iOS;