Purchase orders

This commit is contained in:
Hillel Coren 2022-06-20 18:22:22 +03:00
parent 4c01ec1e58
commit 46f433b41c
27 changed files with 210 additions and 155 deletions

View File

@ -149,8 +149,10 @@ abstract class ClientEntity extends Object
customValue2: '', customValue2: '',
customValue3: '', customValue3: '',
customValue4: '', customValue4: '',
contacts: BuiltList<ContactEntity>( contacts: BuiltList<ClientContactEntity>(
<ContactEntity>[ContactEntity().rebuild((b) => b..isPrimary = true)], <ClientContactEntity>[
ClientContactEntity().rebuild((b) => b..isPrimary = true)
],
), ),
activities: BuiltList<ActivityEntity>(), activities: BuiltList<ActivityEntity>(),
ledger: BuiltList<LedgerEntity>(), ledger: BuiltList<LedgerEntity>(),
@ -295,7 +297,7 @@ abstract class ClientEntity extends Object
@BuiltValueField(wireName: 'custom_value4') @BuiltValueField(wireName: 'custom_value4')
String get customValue4; String get customValue4;
BuiltList<ContactEntity> get contacts; BuiltList<ClientContactEntity> get contacts;
BuiltList<ActivityEntity> get activities; BuiltList<ActivityEntity> get activities;
@ -356,11 +358,11 @@ abstract class ClientEntity extends Object
return template; return template;
} }
ContactEntity get primaryContact => ClientContactEntity get primaryContact =>
contacts.firstWhere((contact) => contact.isPrimary, contacts.firstWhere((contact) => contact.isPrimary,
orElse: () => ContactEntity()); orElse: () => ClientContactEntity());
List<ContactEntity> get emailContacts { List<ClientContactEntity> get emailContacts {
final list = contacts.where((contact) => contact.sendEmail).toList(); final list = contacts.where((contact) => contact.sendEmail).toList();
return list.isEmpty ? [primaryContact] : list; return list.isEmpty ? [primaryContact] : list;
} }
@ -740,7 +742,7 @@ abstract class ClientEntity extends Object
String get languageId => settings.languageId; String get languageId => settings.languageId;
ContactEntity getContact(String contactId) => contacts ClientContactEntity getContact(String contactId) => contacts
.firstWhere((contact) => contact.id == contactId, orElse: () => null); .firstWhere((contact) => contact.id == contactId, orElse: () => null);
bool get hasNameSet { bool get hasNameSet {
@ -781,11 +783,11 @@ class ContactFields {
static const String custom4 = 'custom4'; static const String custom4 = 'custom4';
} }
abstract class ContactEntity extends Object abstract class ClientContactEntity extends Object
with BaseEntity, SelectableEntity with BaseEntity, SelectableEntity
implements Built<ContactEntity, ContactEntityBuilder> { implements Built<ClientContactEntity, ClientContactEntityBuilder> {
factory ContactEntity() { factory ClientContactEntity() {
return _$ContactEntity._( return _$ClientContactEntity._(
id: BaseEntity.nextId, id: BaseEntity.nextId,
isChanged: false, isChanged: false,
firstName: '', firstName: '',
@ -811,7 +813,7 @@ abstract class ContactEntity extends Object
); );
} }
ContactEntity._(); ClientContactEntity._();
@override @override
@memoized @memoized
@ -938,5 +940,6 @@ abstract class ContactEntity extends Object
@override @override
FormatNumberType get listDisplayAmountType => FormatNumberType.money; FormatNumberType get listDisplayAmountType => FormatNumberType.money;
static Serializer<ContactEntity> get serializer => _$contactEntitySerializer; static Serializer<ClientContactEntity> get serializer =>
_$clientContactEntitySerializer;
} }

View File

@ -12,8 +12,8 @@ Serializer<ClientItemResponse> _$clientItemResponseSerializer =
new _$ClientItemResponseSerializer(); new _$ClientItemResponseSerializer();
Serializer<ClientEntity> _$clientEntitySerializer = Serializer<ClientEntity> _$clientEntitySerializer =
new _$ClientEntitySerializer(); new _$ClientEntitySerializer();
Serializer<ContactEntity> _$contactEntitySerializer = Serializer<ClientContactEntity> _$clientContactEntitySerializer =
new _$ContactEntitySerializer(); new _$ClientContactEntitySerializer();
class _$ClientListResponseSerializer class _$ClientListResponseSerializer
implements StructuredSerializer<ClientListResponse> { implements StructuredSerializer<ClientListResponse> {
@ -214,8 +214,8 @@ class _$ClientEntitySerializer implements StructuredSerializer<ClientEntity> {
specifiedType: const FullType(String)), specifiedType: const FullType(String)),
'contacts', 'contacts',
serializers.serialize(object.contacts, serializers.serialize(object.contacts,
specifiedType: specifiedType: const FullType(
const FullType(BuiltList, const [const FullType(ContactEntity)])), BuiltList, const [const FullType(ClientContactEntity)])),
'activities', 'activities',
serializers.serialize(object.activities, serializers.serialize(object.activities,
specifiedType: const FullType( specifiedType: const FullType(
@ -440,7 +440,7 @@ class _$ClientEntitySerializer implements StructuredSerializer<ClientEntity> {
case 'contacts': case 'contacts':
result.contacts.replace(serializers.deserialize(value, result.contacts.replace(serializers.deserialize(value,
specifiedType: const FullType( specifiedType: const FullType(
BuiltList, const [const FullType(ContactEntity)])) BuiltList, const [const FullType(ClientContactEntity)]))
as BuiltList<Object>); as BuiltList<Object>);
break; break;
case 'activities': case 'activities':
@ -512,14 +512,19 @@ class _$ClientEntitySerializer implements StructuredSerializer<ClientEntity> {
} }
} }
class _$ContactEntitySerializer implements StructuredSerializer<ContactEntity> { class _$ClientContactEntitySerializer
implements StructuredSerializer<ClientContactEntity> {
@override @override
final Iterable<Type> types = const [ContactEntity, _$ContactEntity]; final Iterable<Type> types = const [
ClientContactEntity,
_$ClientContactEntity
];
@override @override
final String wireName = 'ContactEntity'; final String wireName = 'ClientContactEntity';
@override @override
Iterable<Object> serialize(Serializers serializers, ContactEntity object, Iterable<Object> serialize(
Serializers serializers, ClientContactEntity object,
{FullType specifiedType = FullType.unspecified}) { {FullType specifiedType = FullType.unspecified}) {
final result = <Object>[ final result = <Object>[
'first_name', 'first_name',
@ -608,10 +613,10 @@ class _$ContactEntitySerializer implements StructuredSerializer<ContactEntity> {
} }
@override @override
ContactEntity deserialize( ClientContactEntity deserialize(
Serializers serializers, Iterable<Object> serialized, Serializers serializers, Iterable<Object> serialized,
{FullType specifiedType = FullType.unspecified}) { {FullType specifiedType = FullType.unspecified}) {
final result = new ContactEntityBuilder(); final result = new ClientContactEntityBuilder();
final iterator = serialized.iterator; final iterator = serialized.iterator;
while (iterator.moveNext()) { while (iterator.moveNext()) {
@ -971,7 +976,7 @@ class _$ClientEntity extends ClientEntity {
@override @override
final String customValue4; final String customValue4;
@override @override
final BuiltList<ContactEntity> contacts; final BuiltList<ClientContactEntity> contacts;
@override @override
final BuiltList<ActivityEntity> activities; final BuiltList<ActivityEntity> activities;
@override @override
@ -1438,10 +1443,10 @@ class ClientEntityBuilder
String get customValue4 => _$this._customValue4; String get customValue4 => _$this._customValue4;
set customValue4(String customValue4) => _$this._customValue4 = customValue4; set customValue4(String customValue4) => _$this._customValue4 = customValue4;
ListBuilder<ContactEntity> _contacts; ListBuilder<ClientContactEntity> _contacts;
ListBuilder<ContactEntity> get contacts => ListBuilder<ClientContactEntity> get contacts =>
_$this._contacts ??= new ListBuilder<ContactEntity>(); _$this._contacts ??= new ListBuilder<ClientContactEntity>();
set contacts(ListBuilder<ContactEntity> contacts) => set contacts(ListBuilder<ClientContactEntity> contacts) =>
_$this._contacts = contacts; _$this._contacts = contacts;
ListBuilder<ActivityEntity> _activities; ListBuilder<ActivityEntity> _activities;
@ -1672,7 +1677,7 @@ class ClientEntityBuilder
} }
} }
class _$ContactEntity extends ContactEntity { class _$ClientContactEntity extends ClientContactEntity {
@override @override
final String firstName; final String firstName;
@override @override
@ -1718,10 +1723,11 @@ class _$ContactEntity extends ContactEntity {
@override @override
final String id; final String id;
factory _$ContactEntity([void Function(ContactEntityBuilder) updates]) => factory _$ClientContactEntity(
(new ContactEntityBuilder()..update(updates)).build(); [void Function(ClientContactEntityBuilder) updates]) =>
(new ClientContactEntityBuilder()..update(updates)).build();
_$ContactEntity._( _$ClientContactEntity._(
{this.firstName, {this.firstName,
this.lastName, this.lastName,
this.email, this.email,
@ -1746,50 +1752,54 @@ class _$ContactEntity extends ContactEntity {
this.id}) this.id})
: super._() { : super._() {
BuiltValueNullFieldError.checkNotNull( BuiltValueNullFieldError.checkNotNull(
firstName, 'ContactEntity', 'firstName'); firstName, 'ClientContactEntity', 'firstName');
BuiltValueNullFieldError.checkNotNull( BuiltValueNullFieldError.checkNotNull(
lastName, 'ContactEntity', 'lastName'); lastName, 'ClientContactEntity', 'lastName');
BuiltValueNullFieldError.checkNotNull(email, 'ContactEntity', 'email');
BuiltValueNullFieldError.checkNotNull( BuiltValueNullFieldError.checkNotNull(
password, 'ContactEntity', 'password'); email, 'ClientContactEntity', 'email');
BuiltValueNullFieldError.checkNotNull(phone, 'ContactEntity', 'phone');
BuiltValueNullFieldError.checkNotNull( BuiltValueNullFieldError.checkNotNull(
contactKey, 'ContactEntity', 'contactKey'); password, 'ClientContactEntity', 'password');
BuiltValueNullFieldError.checkNotNull( BuiltValueNullFieldError.checkNotNull(
isPrimary, 'ContactEntity', 'isPrimary'); phone, 'ClientContactEntity', 'phone');
BuiltValueNullFieldError.checkNotNull( BuiltValueNullFieldError.checkNotNull(
sendEmail, 'ContactEntity', 'sendEmail'); contactKey, 'ClientContactEntity', 'contactKey');
BuiltValueNullFieldError.checkNotNull( BuiltValueNullFieldError.checkNotNull(
customValue1, 'ContactEntity', 'customValue1'); isPrimary, 'ClientContactEntity', 'isPrimary');
BuiltValueNullFieldError.checkNotNull( BuiltValueNullFieldError.checkNotNull(
customValue2, 'ContactEntity', 'customValue2'); sendEmail, 'ClientContactEntity', 'sendEmail');
BuiltValueNullFieldError.checkNotNull( BuiltValueNullFieldError.checkNotNull(
customValue3, 'ContactEntity', 'customValue3'); customValue1, 'ClientContactEntity', 'customValue1');
BuiltValueNullFieldError.checkNotNull( BuiltValueNullFieldError.checkNotNull(
customValue4, 'ContactEntity', 'customValue4'); customValue2, 'ClientContactEntity', 'customValue2');
BuiltValueNullFieldError.checkNotNull( BuiltValueNullFieldError.checkNotNull(
lastLogin, 'ContactEntity', 'lastLogin'); customValue3, 'ClientContactEntity', 'customValue3');
BuiltValueNullFieldError.checkNotNull(link, 'ContactEntity', 'link');
BuiltValueNullFieldError.checkNotNull( BuiltValueNullFieldError.checkNotNull(
createdAt, 'ContactEntity', 'createdAt'); customValue4, 'ClientContactEntity', 'customValue4');
BuiltValueNullFieldError.checkNotNull( BuiltValueNullFieldError.checkNotNull(
updatedAt, 'ContactEntity', 'updatedAt'); lastLogin, 'ClientContactEntity', 'lastLogin');
BuiltValueNullFieldError.checkNotNull(link, 'ClientContactEntity', 'link');
BuiltValueNullFieldError.checkNotNull( BuiltValueNullFieldError.checkNotNull(
archivedAt, 'ContactEntity', 'archivedAt'); createdAt, 'ClientContactEntity', 'createdAt');
BuiltValueNullFieldError.checkNotNull(id, 'ContactEntity', 'id'); BuiltValueNullFieldError.checkNotNull(
updatedAt, 'ClientContactEntity', 'updatedAt');
BuiltValueNullFieldError.checkNotNull(
archivedAt, 'ClientContactEntity', 'archivedAt');
BuiltValueNullFieldError.checkNotNull(id, 'ClientContactEntity', 'id');
} }
@override @override
ContactEntity rebuild(void Function(ContactEntityBuilder) updates) => ClientContactEntity rebuild(
void Function(ClientContactEntityBuilder) updates) =>
(toBuilder()..update(updates)).build(); (toBuilder()..update(updates)).build();
@override @override
ContactEntityBuilder toBuilder() => new ContactEntityBuilder()..replace(this); ClientContactEntityBuilder toBuilder() =>
new ClientContactEntityBuilder()..replace(this);
@override @override
bool operator ==(Object other) { bool operator ==(Object other) {
if (identical(other, this)) return true; if (identical(other, this)) return true;
return other is ContactEntity && return other is ClientContactEntity &&
firstName == other.firstName && firstName == other.firstName &&
lastName == other.lastName && lastName == other.lastName &&
email == other.email && email == other.email &&
@ -1859,7 +1869,7 @@ class _$ContactEntity extends ContactEntity {
@override @override
String toString() { String toString() {
return (newBuiltValueToStringHelper('ContactEntity') return (newBuiltValueToStringHelper('ClientContactEntity')
..add('firstName', firstName) ..add('firstName', firstName)
..add('lastName', lastName) ..add('lastName', lastName)
..add('email', email) ..add('email', email)
@ -1886,9 +1896,9 @@ class _$ContactEntity extends ContactEntity {
} }
} }
class ContactEntityBuilder class ClientContactEntityBuilder
implements Builder<ContactEntity, ContactEntityBuilder> { implements Builder<ClientContactEntity, ClientContactEntityBuilder> {
_$ContactEntity _$v; _$ClientContactEntity _$v;
String _firstName; String _firstName;
String get firstName => _$this._firstName; String get firstName => _$this._firstName;
@ -1980,9 +1990,9 @@ class ContactEntityBuilder
String get id => _$this._id; String get id => _$this._id;
set id(String id) => _$this._id = id; set id(String id) => _$this._id = id;
ContactEntityBuilder(); ClientContactEntityBuilder();
ContactEntityBuilder get _$this { ClientContactEntityBuilder get _$this {
final $v = _$v; final $v = _$v;
if ($v != null) { if ($v != null) {
_firstName = $v.firstName; _firstName = $v.firstName;
@ -2013,52 +2023,51 @@ class ContactEntityBuilder
} }
@override @override
void replace(ContactEntity other) { void replace(ClientContactEntity other) {
ArgumentError.checkNotNull(other, 'other'); ArgumentError.checkNotNull(other, 'other');
_$v = other as _$ContactEntity; _$v = other as _$ClientContactEntity;
} }
@override @override
void update(void Function(ContactEntityBuilder) updates) { void update(void Function(ClientContactEntityBuilder) updates) {
if (updates != null) updates(this); if (updates != null) updates(this);
} }
@override @override
_$ContactEntity build() { _$ClientContactEntity build() {
final _$result = _$v ?? final _$result = _$v ??
new _$ContactEntity._( new _$ClientContactEntity._(
firstName: BuiltValueNullFieldError.checkNotNull( firstName: BuiltValueNullFieldError.checkNotNull(
firstName, 'ContactEntity', 'firstName'), firstName, 'ClientContactEntity', 'firstName'),
lastName: BuiltValueNullFieldError.checkNotNull( lastName: BuiltValueNullFieldError.checkNotNull(
lastName, 'ContactEntity', 'lastName'), lastName, 'ClientContactEntity', 'lastName'),
email: BuiltValueNullFieldError.checkNotNull( email: BuiltValueNullFieldError.checkNotNull(
email, 'ContactEntity', 'email'), email, 'ClientContactEntity', 'email'),
password: BuiltValueNullFieldError.checkNotNull( password: BuiltValueNullFieldError.checkNotNull(
password, 'ContactEntity', 'password'), password, 'ClientContactEntity', 'password'),
phone: BuiltValueNullFieldError.checkNotNull( phone: BuiltValueNullFieldError.checkNotNull(
phone, 'ContactEntity', 'phone'), phone, 'ClientContactEntity', 'phone'),
contactKey: BuiltValueNullFieldError.checkNotNull( contactKey: BuiltValueNullFieldError.checkNotNull(
contactKey, 'ContactEntity', 'contactKey'), contactKey, 'ClientContactEntity', 'contactKey'),
isPrimary: BuiltValueNullFieldError.checkNotNull( isPrimary: BuiltValueNullFieldError.checkNotNull(
isPrimary, 'ContactEntity', 'isPrimary'), isPrimary, 'ClientContactEntity', 'isPrimary'),
sendEmail: BuiltValueNullFieldError.checkNotNull( sendEmail: BuiltValueNullFieldError.checkNotNull(
sendEmail, 'ContactEntity', 'sendEmail'), sendEmail, 'ClientContactEntity', 'sendEmail'),
customValue1: BuiltValueNullFieldError.checkNotNull( customValue1:
customValue1, 'ContactEntity', 'customValue1'), BuiltValueNullFieldError.checkNotNull(customValue1, 'ClientContactEntity', 'customValue1'),
customValue2: customValue2: BuiltValueNullFieldError.checkNotNull(customValue2, 'ClientContactEntity', 'customValue2'),
BuiltValueNullFieldError.checkNotNull(customValue2, 'ContactEntity', 'customValue2'), customValue3: BuiltValueNullFieldError.checkNotNull(customValue3, 'ClientContactEntity', 'customValue3'),
customValue3: BuiltValueNullFieldError.checkNotNull(customValue3, 'ContactEntity', 'customValue3'), customValue4: BuiltValueNullFieldError.checkNotNull(customValue4, 'ClientContactEntity', 'customValue4'),
customValue4: BuiltValueNullFieldError.checkNotNull(customValue4, 'ContactEntity', 'customValue4'), lastLogin: BuiltValueNullFieldError.checkNotNull(lastLogin, 'ClientContactEntity', 'lastLogin'),
lastLogin: BuiltValueNullFieldError.checkNotNull(lastLogin, 'ContactEntity', 'lastLogin'), link: BuiltValueNullFieldError.checkNotNull(link, 'ClientContactEntity', 'link'),
link: BuiltValueNullFieldError.checkNotNull(link, 'ContactEntity', 'link'),
isChanged: isChanged, isChanged: isChanged,
createdAt: BuiltValueNullFieldError.checkNotNull(createdAt, 'ContactEntity', 'createdAt'), createdAt: BuiltValueNullFieldError.checkNotNull(createdAt, 'ClientContactEntity', 'createdAt'),
updatedAt: BuiltValueNullFieldError.checkNotNull(updatedAt, 'ContactEntity', 'updatedAt'), updatedAt: BuiltValueNullFieldError.checkNotNull(updatedAt, 'ClientContactEntity', 'updatedAt'),
archivedAt: BuiltValueNullFieldError.checkNotNull(archivedAt, 'ContactEntity', 'archivedAt'), archivedAt: BuiltValueNullFieldError.checkNotNull(archivedAt, 'ClientContactEntity', 'archivedAt'),
isDeleted: isDeleted, isDeleted: isDeleted,
createdUserId: createdUserId, createdUserId: createdUserId,
assignedUserId: assignedUserId, assignedUserId: assignedUserId,
id: BuiltValueNullFieldError.checkNotNull(id, 'ContactEntity', 'id')); id: BuiltValueNullFieldError.checkNotNull(id, 'ClientContactEntity', 'id'));
replace(_$result); replace(_$result);
return _$result; return _$result;
} }

View File

@ -476,6 +476,10 @@ abstract class BelongsToClient {
String get clientId; String get clientId;
} }
abstract class BelongsToVendor {
String get vendorId;
}
abstract class ErrorMessage abstract class ErrorMessage
implements Built<ErrorMessage, ErrorMessageBuilder> { implements Built<ErrorMessage, ErrorMessageBuilder> {
factory ErrorMessage([void updates(ErrorMessageBuilder b)]) = _$ErrorMessage; factory ErrorMessage([void updates(ErrorMessageBuilder b)]) = _$ErrorMessage;
@ -808,7 +812,7 @@ abstract class ActivityEntity
InvoiceEntity recurringInvoice, InvoiceEntity recurringInvoice,
ExpenseEntity recurringExpense, ExpenseEntity recurringExpense,
}) { }) {
ContactEntity contact; ClientContactEntity contact;
if (client != null && contactId != null && contactId.isNotEmpty) { if (client != null && contactId != null && contactId.isNotEmpty) {
contact = client.getContact(contactId); contact = client.getContact(contactId);
} }

View File

@ -122,7 +122,12 @@ class InvoiceTotalFields {
} }
abstract class InvoiceEntity extends Object abstract class InvoiceEntity extends Object
with BaseEntity, SelectableEntity, CalculateInvoiceTotal, BelongsToClient with
BaseEntity,
SelectableEntity,
CalculateInvoiceTotal,
BelongsToClient,
BelongsToVendor
implements Built<InvoiceEntity, InvoiceEntityBuilder> { implements Built<InvoiceEntity, InvoiceEntityBuilder> {
factory InvoiceEntity({ factory InvoiceEntity({
String id, String id,
@ -368,6 +373,7 @@ abstract class InvoiceEntity extends Object
@BuiltValueField(wireName: 'project_id') @BuiltValueField(wireName: 'project_id')
String get projectId; String get projectId;
@override
@BuiltValueField(wireName: 'vendor_id') @BuiltValueField(wireName: 'vendor_id')
String get vendorId; String get vendorId;
@ -1231,12 +1237,18 @@ abstract class InvoiceEntity extends Object
.isBefore(DateTime.now().subtract(Duration(days: 1))); .isBefore(DateTime.now().subtract(Duration(days: 1)));
} }
InvitationEntity getInvitationForContact(ContactEntity contact) { InvitationEntity getInvitationForClientContact(ClientContactEntity contact) {
return invitations.firstWhere( return invitations.firstWhere(
(invitation) => invitation.clientContactId == contact.id, (invitation) => invitation.clientContactId == contact.id,
orElse: () => null); orElse: () => null);
} }
InvitationEntity getInvitationForVendorContact(VendorContactEntity contact) {
return invitations.firstWhere(
(invitation) => invitation.vendorContactId == contact.id,
orElse: () => null);
}
/// Gets taxes in the form { taxName1: { amount: 0, paid: 0} , ... } /// Gets taxes in the form { taxName1: { amount: 0, paid: 0} , ... }
Map<String, Map<String, dynamic>> getTaxes(int precision) { Map<String, Map<String, dynamic>> getTaxes(int precision) {
final taxes = <String, Map<String, dynamic>>{}; final taxes = <String, Map<String, dynamic>>{};

View File

@ -13,6 +13,7 @@ Serializers _$serializers = (new Serializers().toBuilder()
..add(AppSidebarMode.serializer) ..add(AppSidebarMode.serializer)
..add(AppState.serializer) ..add(AppState.serializer)
..add(AuthState.serializer) ..add(AuthState.serializer)
..add(ClientContactEntity.serializer)
..add(ClientEntity.serializer) ..add(ClientEntity.serializer)
..add(ClientItemResponse.serializer) ..add(ClientItemResponse.serializer)
..add(ClientListResponse.serializer) ..add(ClientListResponse.serializer)
@ -26,7 +27,6 @@ Serializers _$serializers = (new Serializers().toBuilder()
..add(CompanyGatewayUIState.serializer) ..add(CompanyGatewayUIState.serializer)
..add(CompanyItemResponse.serializer) ..add(CompanyItemResponse.serializer)
..add(CompanyPrefState.serializer) ..add(CompanyPrefState.serializer)
..add(ContactEntity.serializer)
..add(CountryEntity.serializer) ..add(CountryEntity.serializer)
..add(CountryItemResponse.serializer) ..add(CountryItemResponse.serializer)
..add(CountryListResponse.serializer) ..add(CountryListResponse.serializer)
@ -211,16 +211,10 @@ Serializers _$serializers = (new Serializers().toBuilder()
..add(WebhookListResponse.serializer) ..add(WebhookListResponse.serializer)
..add(WebhookState.serializer) ..add(WebhookState.serializer)
..add(WebhookUIState.serializer) ..add(WebhookUIState.serializer)
..addBuilderFactory(
const FullType(BuiltList, const [const FullType(ClientEntity)]),
() => new ListBuilder<ClientEntity>())
..addBuilderFactory( ..addBuilderFactory(
const FullType( const FullType(
BuiltList, const [const FullType(CompanyGatewayEntity)]), BuiltList, const [const FullType(ClientContactEntity)]),
() => new ListBuilder<CompanyGatewayEntity>()) () => new ListBuilder<ClientContactEntity>())
..addBuilderFactory(
const FullType(BuiltList, const [const FullType(ContactEntity)]),
() => new ListBuilder<ContactEntity>())
..addBuilderFactory( ..addBuilderFactory(
const FullType(BuiltList, const [const FullType(ActivityEntity)]), const FullType(BuiltList, const [const FullType(ActivityEntity)]),
() => new ListBuilder<ActivityEntity>()) () => new ListBuilder<ActivityEntity>())
@ -236,6 +230,13 @@ Serializers _$serializers = (new Serializers().toBuilder()
..addBuilderFactory( ..addBuilderFactory(
const FullType(BuiltList, const [const FullType(SystemLogEntity)]), const FullType(BuiltList, const [const FullType(SystemLogEntity)]),
() => new ListBuilder<SystemLogEntity>()) () => new ListBuilder<SystemLogEntity>())
..addBuilderFactory(
const FullType(BuiltList, const [const FullType(ClientEntity)]),
() => new ListBuilder<ClientEntity>())
..addBuilderFactory(
const FullType(
BuiltList, const [const FullType(CompanyGatewayEntity)]),
() => new ListBuilder<CompanyGatewayEntity>())
..addBuilderFactory( ..addBuilderFactory(
const FullType(BuiltList, const [const FullType(CountryEntity)]), const FullType(BuiltList, const [const FullType(CountryEntity)]),
() => new ListBuilder<CountryEntity>()) () => new ListBuilder<CountryEntity>())

View File

@ -49,7 +49,7 @@ class EditClient implements PersistUI, PersistPrefs {
this.force = false}); this.force = false});
final ClientEntity client; final ClientEntity client;
final ContactEntity contact; final ClientContactEntity contact;
final Completer completer; final Completer completer;
final Completer cancelCompleter; final Completer cancelCompleter;
final bool force; final bool force;
@ -58,7 +58,7 @@ class EditClient implements PersistUI, PersistPrefs {
class EditContact implements PersistUI { class EditContact implements PersistUI {
EditContact([this.contact]); EditContact([this.contact]);
final ContactEntity contact; final ClientContactEntity contact;
} }
class ShowPdfClient { class ShowPdfClient {
@ -146,14 +146,14 @@ class LoadClientsSuccess implements StopLoading {
class AddContact implements PersistUI { class AddContact implements PersistUI {
AddContact([this.contact]); AddContact([this.contact]);
final ContactEntity contact; final ClientContactEntity contact;
} }
class UpdateContact implements PersistUI { class UpdateContact implements PersistUI {
UpdateContact({this.index, this.contact}); UpdateContact({this.index, this.contact});
final int index; final int index;
final ContactEntity contact; final ClientContactEntity contact;
} }
class DeleteContact implements PersistUI { class DeleteContact implements PersistUI {

View File

@ -59,12 +59,12 @@ final cancelCompleterReducer = combineReducers<Completer<SelectableEntity>>([
}), }),
]); ]);
final editingContactReducer = combineReducers<ContactEntity>([ final editingContactReducer = combineReducers<ClientContactEntity>([
TypedReducer<ContactEntity, EditClient>((contact, action) { TypedReducer<ClientContactEntity, EditClient>((contact, action) {
return action.contact ?? ContactEntity(); return action.contact ?? ClientContactEntity();
}), }),
TypedReducer<ContactEntity, EditContact>((contact, action) { TypedReducer<ClientContactEntity, EditContact>((contact, action) {
return action.contact ?? ContactEntity(); return action.contact ?? ClientContactEntity();
}), }),
]); ]);
@ -123,8 +123,8 @@ final editingReducer = combineReducers<ClientEntity>([
return action.client.rebuild((b) => b..isChanged = true); return action.client.rebuild((b) => b..isChanged = true);
}), }),
TypedReducer<ClientEntity, AddContact>((client, action) { TypedReducer<ClientEntity, AddContact>((client, action) {
return client return client.rebuild(
.rebuild((b) => b..contacts.add(action.contact ?? ContactEntity())); (b) => b..contacts.add(action.contact ?? ClientContactEntity()));
}), }),
TypedReducer<ClientEntity, DeleteContact>((client, action) { TypedReducer<ClientEntity, DeleteContact>((client, action) {
return client.rebuild((b) => b..contacts.removeAt(action.index)); return client.rebuild((b) => b..contacts.removeAt(action.index));

View File

@ -63,7 +63,7 @@ abstract class ClientUIState extends Object
listUIState: ListUIState(sortField?.field ?? ClientFields.name, listUIState: ListUIState(sortField?.field ?? ClientFields.name,
sortAscending: sortField?.ascending), sortAscending: sortField?.ascending),
editing: ClientEntity(), editing: ClientEntity(),
editingContact: ContactEntity(), editingContact: ClientContactEntity(),
saveCompleter: null, saveCompleter: null,
tabIndex: 0, tabIndex: 0,
); );
@ -79,7 +79,7 @@ abstract class ClientUIState extends Object
ClientEntity get editing; ClientEntity get editing;
@nullable @nullable
ContactEntity get editingContact; ClientContactEntity get editingContact;
@override @override
bool get isCreatingNew => editing.isNew; bool get isCreatingNew => editing.isNew;

View File

@ -94,7 +94,7 @@ class _$ClientUIStateSerializer implements StructuredSerializer<ClientUIState> {
result result
..add('editingContact') ..add('editingContact')
..add(serializers.serialize(value, ..add(serializers.serialize(value,
specifiedType: const FullType(ContactEntity))); specifiedType: const FullType(ClientContactEntity)));
} }
value = object.selectedId; value = object.selectedId;
if (value != null) { if (value != null) {
@ -131,7 +131,8 @@ class _$ClientUIStateSerializer implements StructuredSerializer<ClientUIState> {
break; break;
case 'editingContact': case 'editingContact':
result.editingContact.replace(serializers.deserialize(value, result.editingContact.replace(serializers.deserialize(value,
specifiedType: const FullType(ContactEntity)) as ContactEntity); specifiedType: const FullType(ClientContactEntity))
as ClientContactEntity);
break; break;
case 'listUIState': case 'listUIState':
result.listUIState.replace(serializers.deserialize(value, result.listUIState.replace(serializers.deserialize(value,
@ -261,7 +262,7 @@ class _$ClientUIState extends ClientUIState {
@override @override
final ClientEntity editing; final ClientEntity editing;
@override @override
final ContactEntity editingContact; final ClientContactEntity editingContact;
@override @override
final ListUIState listUIState; final ListUIState listUIState;
@override @override
@ -358,10 +359,10 @@ class ClientUIStateBuilder
_$this._editing ??= new ClientEntityBuilder(); _$this._editing ??= new ClientEntityBuilder();
set editing(ClientEntityBuilder editing) => _$this._editing = editing; set editing(ClientEntityBuilder editing) => _$this._editing = editing;
ContactEntityBuilder _editingContact; ClientContactEntityBuilder _editingContact;
ContactEntityBuilder get editingContact => ClientContactEntityBuilder get editingContact =>
_$this._editingContact ??= new ContactEntityBuilder(); _$this._editingContact ??= new ClientContactEntityBuilder();
set editingContact(ContactEntityBuilder editingContact) => set editingContact(ClientContactEntityBuilder editingContact) =>
_$this._editingContact = editingContact; _$this._editingContact = editingContact;
ListUIStateBuilder _listUIState; ListUIStateBuilder _listUIState;

View File

@ -150,7 +150,7 @@ class LoadCreditsSuccess implements StopLoading {
class AddCreditContact implements PersistUI { class AddCreditContact implements PersistUI {
AddCreditContact({this.contact, this.invitation}); AddCreditContact({this.contact, this.invitation});
final ContactEntity contact; final ClientContactEntity contact;
final InvitationEntity invitation; final InvitationEntity invitation;
} }

View File

@ -117,7 +117,7 @@ final editingReducer = combineReducers<InvoiceEntity>([
return credit.rebuild((b) => b return credit.rebuild((b) => b
..isChanged = true ..isChanged = true
..clientId = client?.id ?? '' ..clientId = client?.id ?? ''
..invitations.replace((client?.emailContacts ?? <ContactEntity>[]) ..invitations.replace((client?.emailContacts ?? <ClientContactEntity>[])
.map((contact) => InvitationEntity(clientContactId: contact.id)) .map((contact) => InvitationEntity(clientContactId: contact.id))
.toList())); .toList()));
}), }),

View File

@ -7,7 +7,8 @@ import 'package:invoiceninja_flutter/data/models/models.dart';
import 'package:invoiceninja_flutter/redux/app/app_state.dart'; import 'package:invoiceninja_flutter/redux/app/app_state.dart';
import 'package:invoiceninja_flutter/redux/ui/list_ui_state.dart'; import 'package:invoiceninja_flutter/redux/ui/list_ui_state.dart';
ContactEntity creditContactSelector(InvoiceEntity credit, ClientEntity client) { ClientContactEntity creditContactSelector(
InvoiceEntity credit, ClientEntity client) {
var contactIds = credit.invitations var contactIds = credit.invitations
.map((invitation) => invitation.clientContactId) .map((invitation) => invitation.clientContactId)
.toList(); .toList();

View File

@ -151,7 +151,7 @@ class LoadInvoicesSuccess implements StopLoading {
class AddInvoiceContact implements PersistUI { class AddInvoiceContact implements PersistUI {
AddInvoiceContact({this.contact, this.invitation}); AddInvoiceContact({this.contact, this.invitation});
final ContactEntity contact; final ClientContactEntity contact;
final InvitationEntity invitation; final InvitationEntity invitation;
} }

View File

@ -121,7 +121,7 @@ final editingReducer = combineReducers<InvoiceEntity>([
return invoice.rebuild((b) => b return invoice.rebuild((b) => b
..isChanged = true ..isChanged = true
..clientId = client?.id ?? '' ..clientId = client?.id ?? ''
..invitations.replace((client?.emailContacts ?? <ContactEntity>[]) ..invitations.replace((client?.emailContacts ?? <ClientContactEntity>[])
.map((contact) => InvitationEntity(clientContactId: contact.id)) .map((contact) => InvitationEntity(clientContactId: contact.id))
.toList())); .toList()));
}), }),

View File

@ -18,7 +18,7 @@ InvoiceEntity invoiceQuoteSelector(
return invoiceQuote; return invoiceQuote;
} }
ContactEntity invoiceContactSelector( ClientContactEntity invoiceContactSelector(
InvoiceEntity invoice, ClientEntity client) { InvoiceEntity invoice, ClientEntity client) {
var contactIds = invoice.invitations var contactIds = invoice.invitations
.map((invitation) => invitation.clientContactId) .map((invitation) => invitation.clientContactId)

View File

@ -297,7 +297,7 @@ class ApprovePurchaseOrderFailure implements StopSaving {
class AddPurchaseOrderContact implements PersistUI { class AddPurchaseOrderContact implements PersistUI {
AddPurchaseOrderContact({this.contact, this.invitation}); AddPurchaseOrderContact({this.contact, this.invitation});
final ContactEntity contact; final VendorContactEntity contact;
final InvitationEntity invitation; final InvitationEntity invitation;
} }

View File

@ -150,7 +150,7 @@ class LoadQuotesSuccess implements StopLoading {
class AddQuoteContact implements PersistUI { class AddQuoteContact implements PersistUI {
AddQuoteContact({this.contact, this.invitation}); AddQuoteContact({this.contact, this.invitation});
final ContactEntity contact; final ClientContactEntity contact;
final InvitationEntity invitation; final InvitationEntity invitation;
} }

View File

@ -118,7 +118,7 @@ final editingReducer = combineReducers<InvoiceEntity>([
return quote.rebuild((b) => b return quote.rebuild((b) => b
..isChanged = true ..isChanged = true
..clientId = client?.id ?? '' ..clientId = client?.id ?? ''
..invitations.replace((client?.emailContacts ?? <ContactEntity>[]) ..invitations.replace((client?.emailContacts ?? <ClientContactEntity>[])
.map((contact) => InvitationEntity(clientContactId: contact.id)) .map((contact) => InvitationEntity(clientContactId: contact.id))
.toList())); .toList()));
}), }),

View File

@ -12,7 +12,8 @@ ClientEntity quoteClientSelector(
return clientMap[quote.clientId]; return clientMap[quote.clientId];
} }
ContactEntity quoteContactSelector(InvoiceEntity quote, ClientEntity client) { ClientContactEntity quoteContactSelector(
InvoiceEntity quote, ClientEntity client) {
var contactIds = quote.invitations var contactIds = quote.invitations
.map((invitation) => invitation.clientContactId) .map((invitation) => invitation.clientContactId)
.toList(); .toList();

View File

@ -159,7 +159,7 @@ class LoadRecurringInvoicesSuccess implements StopLoading {
class AddRecurringInvoiceContact implements PersistUI { class AddRecurringInvoiceContact implements PersistUI {
AddRecurringInvoiceContact({this.contact, this.invitation}); AddRecurringInvoiceContact({this.contact, this.invitation});
final ContactEntity contact; final ClientContactEntity contact;
final InvitationEntity invitation; final InvitationEntity invitation;
} }

View File

@ -144,7 +144,7 @@ final editingReducer = combineReducers<InvoiceEntity>([
return recurringInvoice.rebuild((b) => b return recurringInvoice.rebuild((b) => b
..isChanged = true ..isChanged = true
..clientId = client?.id ?? '' ..clientId = client?.id ?? ''
..invitations.replace((client?.emailContacts ?? <ContactEntity>[]) ..invitations.replace((client?.emailContacts ?? <ClientContactEntity>[])
.map((contact) => InvitationEntity(clientContactId: contact.id)) .map((contact) => InvitationEntity(clientContactId: contact.id))
.toList())); .toList()));
}), }),

View File

@ -66,7 +66,7 @@ final editingVendorContactReducer = combineReducers<VendorContactEntity>([
VendorContactEntity editVendorContact( VendorContactEntity editVendorContact(
VendorContactEntity contact, dynamic action) { VendorContactEntity contact, dynamic action) {
return action.contact ?? VendorContactEntity(); return action.clientContact ?? VendorContactEntity();
} }
Reducer<String> selectedIdReducer = combineReducers([ Reducer<String> selectedIdReducer = combineReducers([

View File

@ -31,9 +31,9 @@ class ClientEditContacts extends StatefulWidget {
} }
class _ClientEditContactsState extends State<ClientEditContacts> { class _ClientEditContactsState extends State<ClientEditContacts> {
ContactEntity selectedContact; ClientContactEntity selectedContact;
void _showContactEditor(ContactEntity contact, BuildContext context) { void _showContactEditor(ClientContactEntity contact, BuildContext context) {
showDialog<ResponsivePadding>( showDialog<ResponsivePadding>(
context: context, context: context,
builder: (BuildContext context) { builder: (BuildContext context) {
@ -130,7 +130,7 @@ class ContactListTile extends StatelessWidget {
}); });
final Function onTap; final Function onTap;
final ContactEntity contact; final ClientContactEntity contact;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -172,7 +172,7 @@ class ContactEditDetails extends StatefulWidget {
}) : super(key: key); }) : super(key: key);
final int index; final int index;
final ContactEntity contact; final ClientContactEntity contact;
final ClientEditContactsVM viewModel; final ClientEditContactsVM viewModel;
final ClientEditVM clientViewModel; final ClientEditVM clientViewModel;
final bool isDialog; final bool isDialog;
@ -194,7 +194,7 @@ class ContactEditDetailsState extends State<ContactEditDetails> {
final _debouncer = Debouncer(); final _debouncer = Debouncer();
List<TextEditingController> _controllers = []; List<TextEditingController> _controllers = [];
ContactEntity _contact; ClientContactEntity _contact;
void _onDoneContactPressed() { void _onDoneContactPressed() {
if (widget.isDialog) { if (widget.isDialog) {

View File

@ -54,7 +54,7 @@ class ClientEditContactsVM {
client: client, client: client,
contact: state.clientUIState.editingContact, contact: state.clientUIState.editingContact,
onAddContactPressed: () { onAddContactPressed: () {
final contact = ContactEntity(); final contact = ClientContactEntity();
store.dispatch(AddContact(contact)); store.dispatch(AddContact(contact));
store.dispatch(EditContact(contact)); store.dispatch(EditContact(contact));
}, },
@ -69,9 +69,9 @@ class ClientEditContactsVM {
final CompanyEntity company; final CompanyEntity company;
final ClientEntity client; final ClientEntity client;
final ContactEntity contact; final ClientContactEntity contact;
final Function() onAddContactPressed; final Function() onAddContactPressed;
final Function(int) onRemoveContactPressed; final Function(int) onRemoveContactPressed;
final Function(BuildContext) onDoneContactPressed; final Function(BuildContext) onDoneContactPressed;
final Function(ContactEntity, int) onChangedContact; final Function(ClientContactEntity, int) onChangedContact;
} }

View File

@ -24,7 +24,7 @@ class InvoiceEditContacts extends StatelessWidget {
final invoice = viewModel.invoice; final invoice = viewModel.invoice;
final client = viewModel.client; final client = viewModel.client;
List<ContactEntity> contacts; List<ClientContactEntity> contacts;
if (client == null) { if (client == null) {
if (viewModel.state.prefState.isDesktop) { if (viewModel.state.prefState.isDesktop) {
contacts = []; contacts = [];
@ -46,13 +46,13 @@ class InvoiceEditContacts extends StatelessWidget {
return ScrollableListView( return ScrollableListView(
children: contacts.map((contact) { children: contacts.map((contact) {
final invitation = invoice.getInvitationForContact(contact); final invitation = invoice.getInvitationForClientContact(contact);
return _ContactListTile( return _ContactListTile(
contact: contact, clientContact: contact,
invoice: invoice, invoice: invoice,
invitation: invitation, invitation: invitation,
onTap: () => invitation == null onTap: () => invitation == null
? viewModel.onAddContact(contact) ? viewModel.onAddClientContact(contact)
: viewModel.onRemoveContact(invitation), : viewModel.onRemoveContact(invitation),
); );
}).toList(), }).toList(),
@ -62,14 +62,14 @@ class InvoiceEditContacts extends StatelessWidget {
class _ContactListTile extends StatelessWidget { class _ContactListTile extends StatelessWidget {
const _ContactListTile({ const _ContactListTile({
this.contact, this.clientContact,
this.invoice, this.invoice,
this.invitation, this.invitation,
this.onTap, this.onTap,
}); });
final InvoiceEntity invoice; final InvoiceEntity invoice;
final ContactEntity contact; final ClientContactEntity clientContact;
final InvitationEntity invitation; final InvitationEntity invitation;
final Function onTap; final Function onTap;
@ -78,10 +78,10 @@ class _ContactListTile extends StatelessWidget {
final localization = AppLocalization.of(context); final localization = AppLocalization.of(context);
return ListTile( return ListTile(
title: Text(contact.fullName.isNotEmpty title: Text(clientContact.fullName.isNotEmpty
? contact.fullName ? clientContact.fullName
: AppLocalization.of(context).blankContact), : AppLocalization.of(context).blankContact),
subtitle: contact.email != null ? Text(contact.email) : null, subtitle: clientContact.email != null ? Text(clientContact.email) : null,
onTap: onTap, onTap: onTap,
leading: IgnorePointer( leading: IgnorePointer(
child: Checkbox( child: Checkbox(

View File

@ -42,7 +42,9 @@ class EntityEditContactsVM {
@required this.company, @required this.company,
@required this.invoice, @required this.invoice,
@required this.client, @required this.client,
@required this.onAddContact, @required this.vendor,
@required this.onAddClientContact,
@required this.onAddVendorContact,
@required this.onRemoveContact, @required this.onRemoveContact,
}); });
@ -50,7 +52,9 @@ class EntityEditContactsVM {
final CompanyEntity company; final CompanyEntity company;
final InvoiceEntity invoice; final InvoiceEntity invoice;
final ClientEntity client; final ClientEntity client;
final Function(ContactEntity) onAddContact; final VendorEntity vendor;
final Function(ClientContactEntity) onAddClientContact;
final Function(VendorContactEntity) onAddVendorContact;
final Function(InvitationEntity) onRemoveContact; final Function(InvitationEntity) onRemoveContact;
} }
@ -60,14 +64,18 @@ class InvoiceEditContactsVM extends EntityEditContactsVM {
@required CompanyEntity company, @required CompanyEntity company,
@required InvoiceEntity invoice, @required InvoiceEntity invoice,
@required ClientEntity client, @required ClientEntity client,
@required Function(ContactEntity) onAddContact, @required VendorEntity vendor,
@required Function(ClientContactEntity) onAddClientContact,
@required Function(VendorContactEntity) onAddVendorContact,
@required Function(InvitationEntity) onRemoveContact, @required Function(InvitationEntity) onRemoveContact,
}) : super( }) : super(
state: state, state: state,
company: company, company: company,
invoice: invoice, invoice: invoice,
client: client, client: client,
onAddContact: onAddContact, vendor: vendor,
onAddClientContact: onAddClientContact,
onAddVendorContact: onAddVendorContact,
onRemoveContact: onRemoveContact, onRemoveContact: onRemoveContact,
); );
@ -96,13 +104,14 @@ class InvoiceEditContactsVM extends EntityEditContactsVM {
company: state.company, company: state.company,
invoice: entity, invoice: entity,
client: state.clientState.map[(entity as BelongsToClient).clientId], client: state.clientState.map[(entity as BelongsToClient).clientId],
onAddContact: (ContactEntity contact) { vendor: state.vendorState.map[(entity as BelongsToVendor).vendorId],
onAddClientContact: (ClientContactEntity contact) {
InvitationEntity invitation; InvitationEntity invitation;
// prevent un-checking/checking a contact from creating a new invitation // prevent un-checking/checking a contact from creating a new invitation
if (entity.isOld) { if (entity.isOld) {
final origEntity = final origEntity =
state.getEntityMap(entityType)[entity.id] as InvoiceEntity; state.getEntityMap(entityType)[entity.id] as InvoiceEntity;
invitation = origEntity.getInvitationForContact(contact); invitation = origEntity.getInvitationForClientContact(contact);
} }
if (entity.entityType == EntityType.quote) { if (entity.entityType == EntityType.quote) {
@ -117,7 +126,21 @@ class InvoiceEditContactsVM extends EntityEditContactsVM {
} else if (entity.entityType == EntityType.invoice) { } else if (entity.entityType == EntityType.invoice) {
store.dispatch( store.dispatch(
AddInvoiceContact(contact: contact, invitation: invitation)); AddInvoiceContact(contact: contact, invitation: invitation));
} else if (entity.entityType == EntityType.purchaseOrder) { } else {
print(
'ERROR: entityType $entityType not handled in invoice_edit_contacts_vm');
}
},
onAddVendorContact: (VendorContactEntity contact) {
InvitationEntity invitation;
// prevent un-checking/checking a contact from creating a new invitation
if (entity.isOld) {
final origEntity =
state.getEntityMap(entityType)[entity.id] as InvoiceEntity;
invitation = origEntity.getInvitationForVendorContact(contact);
}
if (entity.entityType == EntityType.purchaseOrder) {
store.dispatch(AddPurchaseOrderContact( store.dispatch(AddPurchaseOrderContact(
contact: contact, invitation: invitation)); contact: contact, invitation: invitation));
} else { } else {

View File

@ -47,7 +47,7 @@ class _InvitationListTile extends StatelessWidget {
final client = state.clientState.get(viewModel.invoice.clientId); final client = state.clientState.get(viewModel.invoice.clientId);
final contact = client.contacts.firstWhere( final contact = client.contacts.firstWhere(
(contact) => contact.id == invitation.clientContactId, (contact) => contact.id == invitation.clientContactId,
orElse: () => ContactEntity()); orElse: () => ClientContactEntity());
if (contact.isNew) { if (contact.isNew) {
return SizedBox(); return SizedBox();