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'; import 'package:invoiceninja_flutter/data/models/models.dart'; import 'package:invoiceninja_flutter/redux/app/app_state.dart'; import 'package:invoiceninja_flutter/utils/formatting.dart'; import 'package:invoiceninja_flutter/utils/strings.dart'; part 'product_model.g.dart'; abstract class ProductListResponse implements Built { factory ProductListResponse([void updates(ProductListResponseBuilder b)]) = _$ProductListResponse; ProductListResponse._(); @override @memoized int get hashCode; BuiltList get data; static Serializer get serializer => _$productListResponseSerializer; } abstract class ProductItemResponse implements Built { factory ProductItemResponse([void updates(ProductItemResponseBuilder b)]) = _$ProductItemResponse; ProductItemResponse._(); @override @memoized int get hashCode; ProductEntity get data; static Serializer get serializer => _$productItemResponseSerializer; } class ProductFields { static const String productKey = 'product_key'; static const String notes = 'notes'; static const String cost = 'cost'; static const String price = 'price'; static const String quantity = 'quantity'; static const String updatedAt = 'updated_at'; static const String archivedAt = 'archived_at'; static const String isDeleted = 'is_deleted'; static const String customValue1 = 'custom1'; static const String customValue2 = 'custom2'; static const String customValue3 = 'custom3'; static const String customValue4 = 'custom4'; static const String documents = 'documents'; } abstract class ProductEntity extends Object with BaseEntity, SelectableEntity implements Built { factory ProductEntity({String id, AppState state}) { return _$ProductEntity._( id: id ?? BaseEntity.nextId, isChanged: false, productKey: '', notes: '', cost: 0, price: 0, quantity: (state?.company?.defaultQuantity ?? true) ? 1 : 0, taxName1: '', taxRate1: 0, taxName2: '', taxRate2: 0, taxName3: '', taxRate3: 0, customValue1: '', customValue2: '', customValue3: '', customValue4: '', updatedAt: 0, archivedAt: 0, isDeleted: false, createdAt: 0, assignedUserId: '', createdUserId: '', documents: BuiltList(), ); } ProductEntity._(); @override @memoized int get hashCode; ProductEntity get clone => rebuild((b) => b ..id = BaseEntity.nextId ..documents.clear() ..isChanged = false ..isDeleted = false); @override EntityType get entityType { return EntityType.product; } @BuiltValueField(wireName: 'product_key') String get productKey; String get notes; double get cost; double get price; double get quantity; @BuiltValueField(wireName: 'tax_name1') String get taxName1; @BuiltValueField(wireName: 'tax_rate1') double get taxRate1; @BuiltValueField(wireName: 'tax_name2') String get taxName2; @BuiltValueField(wireName: 'tax_rate2') double get taxRate2; @BuiltValueField(wireName: 'tax_name3') String get taxName3; @BuiltValueField(wireName: 'tax_rate3') double get taxRate3; @BuiltValueField(wireName: 'custom_value1') String get customValue1; @BuiltValueField(wireName: 'custom_value2') String get customValue2; @BuiltValueField(wireName: 'custom_value3') String get customValue3; @BuiltValueField(wireName: 'custom_value4') String get customValue4; BuiltList get documents; @override String get listDisplayName { return productKey; } @override double get listDisplayAmount => cost; @override FormatNumberType get listDisplayAmountType => FormatNumberType.money; int compareTo( ProductEntity product, [ String sortField, bool sortAscending = true, BuiltMap userMap, ]) { int response = 0; final ProductEntity productA = sortAscending ? this : product; final ProductEntity productB = sortAscending ? product : this; switch (sortField) { case ProductFields.productKey: response = productA.productKey .toLowerCase() .compareTo(productB.productKey.toLowerCase()); break; case ProductFields.price: response = productA.price.compareTo(productB.price); break; case ProductFields.cost: response = productA.cost.compareTo(productB.cost); break; case ProductFields.quantity: response = productA.quantity.compareTo(productB.quantity); break; case ProductFields.updatedAt: response = productA.updatedAt.compareTo(productB.updatedAt); break; case EntityFields.createdAt: response = productA.createdAt.compareTo(productB.createdAt); break; case ProductFields.archivedAt: response = productA.archivedAt.compareTo(productB.archivedAt); break; case ProductFields.notes: response = productA.notes .toLowerCase() .compareTo(productB.notes.toLowerCase()); break; case EntityFields.assignedTo: final userA = userMap[productA.assignedUserId] ?? UserEntity(); final userB = userMap[productB.assignedUserId] ?? UserEntity(); response = userA.listDisplayName .toLowerCase() .compareTo(userB.listDisplayName.toLowerCase()); break; case EntityFields.createdBy: final userA = userMap[productA.createdUserId] ?? UserEntity(); final userB = userMap[productB.createdUserId] ?? UserEntity(); response = userA.listDisplayName .toLowerCase() .compareTo(userB.listDisplayName.toLowerCase()); break; case EntityFields.state: final stateA = EntityState.valueOf(productA.entityState) ?? EntityState.active; final stateB = EntityState.valueOf(productB.entityState) ?? EntityState.active; response = stateA.name.toLowerCase().compareTo(stateB.name.toLowerCase()); break; case ProductFields.customValue1: response = productA.customValue1 .toLowerCase() .compareTo(productB.customValue1.toLowerCase()); break; case ProductFields.customValue2: response = productA.customValue2 .toLowerCase() .compareTo(productB.customValue2.toLowerCase()); break; case ProductFields.customValue3: response = productA.customValue3 .toLowerCase() .compareTo(productB.customValue3.toLowerCase()); break; case ProductFields.customValue4: response = productA.customValue4 .toLowerCase() .compareTo(productB.customValue4.toLowerCase()); break; case ProductFields.documents: response = productA.documents.length.compareTo(productB.documents.length); break; default: print('## ERROR: sort by product.$sortField is not implemented'); break; } return response; } @override bool matchesFilter(String filter) { return matchesStrings( haystacks: [ productKey, notes, customValue1, customValue2, customValue3, customValue4, ], needle: filter, ); } @override String matchesFilterValue(String filter) { return matchesStringsValue( haystacks: [ notes, customValue1, customValue2, customValue3, customValue4, ], needle: filter, ); } @override List getActions( {UserCompanyEntity userCompany, ClientEntity client, bool includeEdit = false, bool multiselect = false}) { final actions = []; if (!isDeleted) { if (!multiselect && includeEdit && userCompany.canEditEntity(this)) { actions.add(EntityAction.edit); } if (userCompany.canCreate(EntityType.invoice) && !isDeleted) { actions.add(EntityAction.newInvoice); } } if (userCompany.canCreate(EntityType.product) && !multiselect) { actions.add(EntityAction.clone); } if (actions.isNotEmpty) { actions.add(null); } return actions..addAll(super.getActions(userCompany: userCompany)); } static Serializer get serializer => _$productEntitySerializer; }