From b1aac6e1fb655b2941b95ce72e20b61657d35d2b Mon Sep 17 00:00:00 2001 From: Hillel Coren Date: Mon, 25 May 2020 20:14:07 +0300 Subject: [PATCH] Payment terms --- lib/data/models/company_model.dart | 39 +- lib/data/models/company_model.g.dart | 164 -- lib/data/models/entities.dart | 3 +- lib/data/models/entities.g.dart | 4 + lib/data/models/payment_term_model.dart | 88 + lib/data/models/payment_term_model.g.dart | 663 +++++ lib/data/models/serializers.dart | 6 + lib/data/models/serializers.g.dart | 7 + .../repositories/payment_term_repository.dart | 79 + lib/main.dart | 2 + lib/main_app.dart | 10 + lib/redux/app/app_actions.dart | 55 + lib/redux/app/app_reducer.dart | 6 + lib/redux/app/app_state.dart | 24 + lib/redux/company/company_reducer.dart | 4 + lib/redux/company/company_state.dart | 6 + lib/redux/company/company_state.g.dart | 54 +- .../payment_term/payment_term_actions.dart | 327 +++ .../payment_term/payment_term_middleware.dart | 281 +++ .../payment_term/payment_term_reducer.dart | 308 +++ .../payment_term/payment_term_selectors.dart | 68 + .../payment_term/payment_term_state.dart | 89 + .../payment_term/payment_term_state.g.dart | 421 ++++ lib/redux/ui/pref_reducer.dart | 13 + lib/redux/ui/ui_reducer.dart | 4 + lib/redux/ui/ui_state.dart | 6 + lib/redux/ui/ui_state.g.dart | 36 +- lib/redux/user/user_selectors.dart | 3 +- lib/ui/app/app_bottom_bar.dart | 13 +- lib/ui/app/list_scaffold.dart | 4 +- lib/ui/app/main_screen.dart | 1 - lib/ui/app/view_scaffold.dart | 2 +- lib/ui/client/edit/client_edit_settings.dart | 2 +- .../payment_term/edit/payment_term_edit.dart | 106 + .../edit/payment_term_edit_vm.dart | 106 + lib/ui/payment_term/payment_term_list.dart | 92 + .../payment_term/payment_term_list_item.dart | 105 + lib/ui/payment_term/payment_term_list_vm.dart | 166 ++ .../payment_term/payment_term_presenter.dart | 22 + lib/ui/payment_term/payment_term_screen.dart | 130 + .../payment_term/payment_term_screen_vm.dart | 62 + .../payment_term/view/payment_term_view.dart | 32 + .../view/payment_term_view_vm.dart | 80 + lib/utils/i18n.dart | 2169 +++++++++-------- starter.sh | 6 +- 45 files changed, 4564 insertions(+), 1304 deletions(-) create mode 100644 lib/data/models/payment_term_model.dart create mode 100644 lib/data/models/payment_term_model.g.dart create mode 100644 lib/data/repositories/payment_term_repository.dart create mode 100644 lib/redux/payment_term/payment_term_actions.dart create mode 100644 lib/redux/payment_term/payment_term_middleware.dart create mode 100644 lib/redux/payment_term/payment_term_reducer.dart create mode 100644 lib/redux/payment_term/payment_term_selectors.dart create mode 100644 lib/redux/payment_term/payment_term_state.dart create mode 100644 lib/redux/payment_term/payment_term_state.g.dart create mode 100644 lib/ui/payment_term/edit/payment_term_edit.dart create mode 100644 lib/ui/payment_term/edit/payment_term_edit_vm.dart create mode 100644 lib/ui/payment_term/payment_term_list.dart create mode 100644 lib/ui/payment_term/payment_term_list_item.dart create mode 100644 lib/ui/payment_term/payment_term_list_vm.dart create mode 100644 lib/ui/payment_term/payment_term_presenter.dart create mode 100644 lib/ui/payment_term/payment_term_screen.dart create mode 100644 lib/ui/payment_term/payment_term_screen_vm.dart create mode 100644 lib/ui/payment_term/view/payment_term_view.dart create mode 100644 lib/ui/payment_term/view/payment_term_view_vm.dart diff --git a/lib/data/models/company_model.dart b/lib/data/models/company_model.dart index 835e9e923..c3af92ca4 100644 --- a/lib/data/models/company_model.dart +++ b/lib/data/models/company_model.dart @@ -10,6 +10,7 @@ import 'package:invoiceninja_flutter/data/models/company_gateway_model.dart'; import 'package:invoiceninja_flutter/data/models/entities.dart'; import 'package:invoiceninja_flutter/data/models/group_model.dart'; import 'package:invoiceninja_flutter/data/models/models.dart'; +import 'package:invoiceninja_flutter/data/models/payment_term_model.dart'; import 'package:invoiceninja_flutter/data/models/task_model.dart'; import 'package:invoiceninja_flutter/utils/formatting.dart'; import 'package:invoiceninja_flutter/.env.dart'; @@ -364,44 +365,6 @@ abstract class CompanyEntity extends Object static Serializer get serializer => _$companyEntitySerializer; } -abstract class PaymentTermEntity extends Object - with SelectableEntity - implements Built { - factory PaymentTermEntity() { - return _$PaymentTermEntity._( - id: BaseEntity.nextId, - numDays: 0, - ); - } - - PaymentTermEntity._(); - - @override - @memoized - int get hashCode; - - static Serializer get serializer => - _$paymentTermEntitySerializer; - - String getPaymentTerm(String netLabel) { - if (numDays == 0) { - return ''; - } else if (numDays == -1) { - return '$netLabel 0'; - } else { - return '$netLabel $numDays'; - } - } - - @nullable - @BuiltValueField(wireName: 'num_days') - int get numDays; - - @nullable - @BuiltValueField(wireName: 'archived_at') - int get archivedAt; -} - abstract class GatewayEntity extends Object with SelectableEntity implements Built { diff --git a/lib/data/models/company_model.g.dart b/lib/data/models/company_model.g.dart index 4c47e77d2..439fbfc94 100644 --- a/lib/data/models/company_model.g.dart +++ b/lib/data/models/company_model.g.dart @@ -8,8 +8,6 @@ part of 'company_model.dart'; Serializer _$companyEntitySerializer = new _$CompanyEntitySerializer(); -Serializer _$paymentTermEntitySerializer = - new _$PaymentTermEntitySerializer(); Serializer _$gatewayEntitySerializer = new _$GatewayEntitySerializer(); Serializer _$userCompanyEntitySerializer = @@ -555,69 +553,6 @@ class _$CompanyEntitySerializer implements StructuredSerializer { } } -class _$PaymentTermEntitySerializer - implements StructuredSerializer { - @override - final Iterable types = const [PaymentTermEntity, _$PaymentTermEntity]; - @override - final String wireName = 'PaymentTermEntity'; - - @override - Iterable serialize(Serializers serializers, PaymentTermEntity object, - {FullType specifiedType = FullType.unspecified}) { - final result = []; - if (object.numDays != null) { - result - ..add('num_days') - ..add(serializers.serialize(object.numDays, - specifiedType: const FullType(int))); - } - if (object.archivedAt != null) { - result - ..add('archived_at') - ..add(serializers.serialize(object.archivedAt, - specifiedType: const FullType(int))); - } - if (object.id != null) { - result - ..add('id') - ..add(serializers.serialize(object.id, - specifiedType: const FullType(String))); - } - return result; - } - - @override - PaymentTermEntity deserialize( - Serializers serializers, Iterable serialized, - {FullType specifiedType = FullType.unspecified}) { - final result = new PaymentTermEntityBuilder(); - - final iterator = serialized.iterator; - while (iterator.moveNext()) { - final key = iterator.current as String; - iterator.moveNext(); - final dynamic value = iterator.current; - switch (key) { - case 'num_days': - result.numDays = serializers.deserialize(value, - specifiedType: const FullType(int)) as int; - break; - case 'archived_at': - result.archivedAt = serializers.deserialize(value, - specifiedType: const FullType(int)) as int; - break; - case 'id': - result.id = serializers.deserialize(value, - specifiedType: const FullType(String)) as String; - break; - } - } - - return result.build(); - } -} - class _$GatewayEntitySerializer implements StructuredSerializer { @override final Iterable types = const [GatewayEntity, _$GatewayEntity]; @@ -3683,105 +3618,6 @@ class CompanyEntityBuilder } } -class _$PaymentTermEntity extends PaymentTermEntity { - @override - final int numDays; - @override - final int archivedAt; - @override - final String id; - - factory _$PaymentTermEntity( - [void Function(PaymentTermEntityBuilder) updates]) => - (new PaymentTermEntityBuilder()..update(updates)).build(); - - _$PaymentTermEntity._({this.numDays, this.archivedAt, this.id}) : super._(); - - @override - PaymentTermEntity rebuild(void Function(PaymentTermEntityBuilder) updates) => - (toBuilder()..update(updates)).build(); - - @override - PaymentTermEntityBuilder toBuilder() => - new PaymentTermEntityBuilder()..replace(this); - - @override - bool operator ==(Object other) { - if (identical(other, this)) return true; - return other is PaymentTermEntity && - numDays == other.numDays && - archivedAt == other.archivedAt && - id == other.id; - } - - int __hashCode; - @override - int get hashCode { - return __hashCode ??= $jf( - $jc($jc($jc(0, numDays.hashCode), archivedAt.hashCode), id.hashCode)); - } - - @override - String toString() { - return (newBuiltValueToStringHelper('PaymentTermEntity') - ..add('numDays', numDays) - ..add('archivedAt', archivedAt) - ..add('id', id)) - .toString(); - } -} - -class PaymentTermEntityBuilder - implements Builder { - _$PaymentTermEntity _$v; - - int _numDays; - int get numDays => _$this._numDays; - set numDays(int numDays) => _$this._numDays = numDays; - - int _archivedAt; - int get archivedAt => _$this._archivedAt; - set archivedAt(int archivedAt) => _$this._archivedAt = archivedAt; - - String _id; - String get id => _$this._id; - set id(String id) => _$this._id = id; - - PaymentTermEntityBuilder(); - - PaymentTermEntityBuilder get _$this { - if (_$v != null) { - _numDays = _$v.numDays; - _archivedAt = _$v.archivedAt; - _id = _$v.id; - _$v = null; - } - return this; - } - - @override - void replace(PaymentTermEntity other) { - if (other == null) { - throw new ArgumentError.notNull('other'); - } - _$v = other as _$PaymentTermEntity; - } - - @override - void update(void Function(PaymentTermEntityBuilder) updates) { - if (updates != null) updates(this); - } - - @override - _$PaymentTermEntity build() { - final _$result = _$v ?? - new _$PaymentTermEntity._( - numDays: numDays, archivedAt: archivedAt, id: id); - replace(_$result); - return _$result; - } -} - class _$GatewayEntity extends GatewayEntity { @override final String id; diff --git a/lib/data/models/entities.dart b/lib/data/models/entities.dart index 2b7f7e864..8e5ebea5a 100644 --- a/lib/data/models/entities.dart +++ b/lib/data/models/entities.dart @@ -16,7 +16,6 @@ class EntityType extends EnumClass { static const EntityType dashboard = _$dashboard; static const EntityType reports = _$reports; static const EntityType settings = _$settings; - static const EntityType taxRate = _$taxRate; static const EntityType companyGateway = _$companyGateway; static const EntityType invoice = _$invoice; @@ -38,8 +37,8 @@ class EntityType extends EnumClass { static const EntityType gatewayToken = _$gatewayToken; static const EntityType invoiceItem = _$invoiceItem; static const EntityType design = _$design; - // STARTER: entity type - do not remove comment + static const EntityType paymentTerm = _$paymentTerm; static const EntityType quoteItem = _$quoteItem; static const EntityType contact = _$contact; static const EntityType vendorContact = _$vendorContact; diff --git a/lib/data/models/entities.g.dart b/lib/data/models/entities.g.dart index 9758abde6..5c763b519 100644 --- a/lib/data/models/entities.g.dart +++ b/lib/data/models/entities.g.dart @@ -30,6 +30,7 @@ const EntityType _$gateway = const EntityType._('gateway'); const EntityType _$gatewayToken = const EntityType._('gatewayToken'); const EntityType _$invoiceItem = const EntityType._('invoiceItem'); const EntityType _$design = const EntityType._('design'); +const EntityType _$paymentTerm = const EntityType._('paymentTerm'); const EntityType _$quoteItem = const EntityType._('quoteItem'); const EntityType _$contact = const EntityType._('contact'); const EntityType _$vendorContact = const EntityType._('vendorContact'); @@ -95,6 +96,8 @@ EntityType _$typeValueOf(String name) { return _$invoiceItem; case 'design': return _$design; + case 'paymentTerm': + return _$paymentTerm; case 'quoteItem': return _$quoteItem; case 'contact': @@ -154,6 +157,7 @@ final BuiltSet _$typeValues = _$gatewayToken, _$invoiceItem, _$design, + _$paymentTerm, _$quoteItem, _$contact, _$vendorContact, diff --git a/lib/data/models/payment_term_model.dart b/lib/data/models/payment_term_model.dart new file mode 100644 index 000000000..b46be75bb --- /dev/null +++ b/lib/data/models/payment_term_model.dart @@ -0,0 +1,88 @@ +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/redux/app/app_state.dart'; + +part 'payment_term_model.g.dart'; + +abstract class PaymentTermListResponse + implements Built { + factory PaymentTermListResponse( + [void updates(PaymentTermListResponseBuilder b)]) = + _$PaymentTermListResponse; + + PaymentTermListResponse._(); + + @override + @memoized + int get hashCode; + + BuiltList get data; + + static Serializer get serializer => + _$paymentTermListResponseSerializer; +} + +abstract class PaymentTermItemResponse + implements Built { + factory PaymentTermItemResponse( + [void updates(PaymentTermItemResponseBuilder b)]) = + _$PaymentTermItemResponse; + + PaymentTermItemResponse._(); + + @override + @memoized + int get hashCode; + + PaymentTermEntity get data; + + static Serializer get serializer => + _$paymentTermItemResponseSerializer; +} + +class PaymentTermFields { + static const String name = 'name'; + static const String numDays = 'num_days'; +} + +abstract class PaymentTermEntity extends Object + with BaseEntity, SelectableEntity + implements Built { + factory PaymentTermEntity({String id, AppState state}) { + return _$PaymentTermEntity._( + id: id ?? BaseEntity.nextId, + numDays: 0, + name: '', + ); + } + + PaymentTermEntity._(); + + @override + @memoized + int get hashCode; + + static Serializer get serializer => + _$paymentTermEntitySerializer; + + String getPaymentTerm(String netLabel) { + if (numDays == 0) { + return ''; + } else if (numDays == -1) { + return '$netLabel 0'; + } else { + return '$netLabel $numDays'; + } + } + + String get name; + + @BuiltValueField(wireName: 'num_days') + int get numDays; + + int compareTo(PaymentTermEntity paymentTerm, String sortField, + bool sortAscending) => + numDays.compareTo(paymentTerm.numDays); +} diff --git a/lib/data/models/payment_term_model.g.dart b/lib/data/models/payment_term_model.g.dart new file mode 100644 index 000000000..35ffeb19f --- /dev/null +++ b/lib/data/models/payment_term_model.g.dart @@ -0,0 +1,663 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'payment_term_model.dart'; + +// ************************************************************************** +// BuiltValueGenerator +// ************************************************************************** + +Serializer _$paymentTermListResponseSerializer = + new _$PaymentTermListResponseSerializer(); +Serializer _$paymentTermItemResponseSerializer = + new _$PaymentTermItemResponseSerializer(); +Serializer _$paymentTermEntitySerializer = + new _$PaymentTermEntitySerializer(); + +class _$PaymentTermListResponseSerializer + implements StructuredSerializer { + @override + final Iterable types = const [ + PaymentTermListResponse, + _$PaymentTermListResponse + ]; + @override + final String wireName = 'PaymentTermListResponse'; + + @override + Iterable serialize( + Serializers serializers, PaymentTermListResponse object, + {FullType specifiedType = FullType.unspecified}) { + final result = [ + 'data', + serializers.serialize(object.data, + specifiedType: const FullType( + BuiltList, const [const FullType(PaymentTermEntity)])), + ]; + + return result; + } + + @override + PaymentTermListResponse deserialize( + Serializers serializers, Iterable serialized, + {FullType specifiedType = FullType.unspecified}) { + final result = new PaymentTermListResponseBuilder(); + + final iterator = serialized.iterator; + while (iterator.moveNext()) { + final key = iterator.current as String; + iterator.moveNext(); + final dynamic value = iterator.current; + switch (key) { + case 'data': + result.data.replace(serializers.deserialize(value, + specifiedType: const FullType( + BuiltList, const [const FullType(PaymentTermEntity)])) + as BuiltList); + break; + } + } + + return result.build(); + } +} + +class _$PaymentTermItemResponseSerializer + implements StructuredSerializer { + @override + final Iterable types = const [ + PaymentTermItemResponse, + _$PaymentTermItemResponse + ]; + @override + final String wireName = 'PaymentTermItemResponse'; + + @override + Iterable serialize( + Serializers serializers, PaymentTermItemResponse object, + {FullType specifiedType = FullType.unspecified}) { + final result = [ + 'data', + serializers.serialize(object.data, + specifiedType: const FullType(PaymentTermEntity)), + ]; + + return result; + } + + @override + PaymentTermItemResponse deserialize( + Serializers serializers, Iterable serialized, + {FullType specifiedType = FullType.unspecified}) { + final result = new PaymentTermItemResponseBuilder(); + + final iterator = serialized.iterator; + while (iterator.moveNext()) { + final key = iterator.current as String; + iterator.moveNext(); + final dynamic value = iterator.current; + switch (key) { + case 'data': + result.data.replace(serializers.deserialize(value, + specifiedType: const FullType(PaymentTermEntity)) + as PaymentTermEntity); + break; + } + } + + return result.build(); + } +} + +class _$PaymentTermEntitySerializer + implements StructuredSerializer { + @override + final Iterable types = const [PaymentTermEntity, _$PaymentTermEntity]; + @override + final String wireName = 'PaymentTermEntity'; + + @override + Iterable serialize(Serializers serializers, PaymentTermEntity object, + {FullType specifiedType = FullType.unspecified}) { + final result = [ + 'name', + serializers.serialize(object.name, specifiedType: const FullType(String)), + 'num_days', + serializers.serialize(object.numDays, specifiedType: const FullType(int)), + ]; + if (object.isChanged != null) { + result + ..add('isChanged') + ..add(serializers.serialize(object.isChanged, + specifiedType: const FullType(bool))); + } + if (object.createdAt != null) { + result + ..add('created_at') + ..add(serializers.serialize(object.createdAt, + specifiedType: const FullType(int))); + } + if (object.updatedAt != null) { + result + ..add('updated_at') + ..add(serializers.serialize(object.updatedAt, + specifiedType: const FullType(int))); + } + if (object.archivedAt != null) { + result + ..add('archived_at') + ..add(serializers.serialize(object.archivedAt, + specifiedType: const FullType(int))); + } + if (object.isDeleted != null) { + result + ..add('is_deleted') + ..add(serializers.serialize(object.isDeleted, + specifiedType: const FullType(bool))); + } + if (object.createdUserId != null) { + result + ..add('user_id') + ..add(serializers.serialize(object.createdUserId, + specifiedType: const FullType(String))); + } + if (object.assignedUserId != null) { + result + ..add('assigned_user_id') + ..add(serializers.serialize(object.assignedUserId, + specifiedType: const FullType(String))); + } + if (object.subEntityType != null) { + result + ..add('entity_type') + ..add(serializers.serialize(object.subEntityType, + specifiedType: const FullType(EntityType))); + } + if (object.id != null) { + result + ..add('id') + ..add(serializers.serialize(object.id, + specifiedType: const FullType(String))); + } + return result; + } + + @override + PaymentTermEntity deserialize( + Serializers serializers, Iterable serialized, + {FullType specifiedType = FullType.unspecified}) { + final result = new PaymentTermEntityBuilder(); + + final iterator = serialized.iterator; + while (iterator.moveNext()) { + final key = iterator.current as String; + iterator.moveNext(); + final dynamic value = iterator.current; + switch (key) { + case 'name': + result.name = serializers.deserialize(value, + specifiedType: const FullType(String)) as String; + break; + case 'num_days': + result.numDays = serializers.deserialize(value, + specifiedType: const FullType(int)) as int; + break; + case 'isChanged': + result.isChanged = serializers.deserialize(value, + specifiedType: const FullType(bool)) as bool; + break; + case 'created_at': + result.createdAt = serializers.deserialize(value, + specifiedType: const FullType(int)) as int; + break; + case 'updated_at': + result.updatedAt = serializers.deserialize(value, + specifiedType: const FullType(int)) as int; + break; + case 'archived_at': + result.archivedAt = serializers.deserialize(value, + specifiedType: const FullType(int)) as int; + break; + case 'is_deleted': + result.isDeleted = serializers.deserialize(value, + specifiedType: const FullType(bool)) as bool; + break; + case 'user_id': + result.createdUserId = serializers.deserialize(value, + specifiedType: const FullType(String)) as String; + break; + case 'assigned_user_id': + result.assignedUserId = serializers.deserialize(value, + specifiedType: const FullType(String)) as String; + break; + case 'entity_type': + result.subEntityType = serializers.deserialize(value, + specifiedType: const FullType(EntityType)) as EntityType; + break; + case 'id': + result.id = serializers.deserialize(value, + specifiedType: const FullType(String)) as String; + break; + } + } + + return result.build(); + } +} + +class _$PaymentTermListResponse extends PaymentTermListResponse { + @override + final BuiltList data; + + factory _$PaymentTermListResponse( + [void Function(PaymentTermListResponseBuilder) updates]) => + (new PaymentTermListResponseBuilder()..update(updates)).build(); + + _$PaymentTermListResponse._({this.data}) : super._() { + if (data == null) { + throw new BuiltValueNullFieldError('PaymentTermListResponse', 'data'); + } + } + + @override + PaymentTermListResponse rebuild( + void Function(PaymentTermListResponseBuilder) updates) => + (toBuilder()..update(updates)).build(); + + @override + PaymentTermListResponseBuilder toBuilder() => + new PaymentTermListResponseBuilder()..replace(this); + + @override + bool operator ==(Object other) { + if (identical(other, this)) return true; + return other is PaymentTermListResponse && data == other.data; + } + + int __hashCode; + @override + int get hashCode { + return __hashCode ??= $jf($jc(0, data.hashCode)); + } + + @override + String toString() { + return (newBuiltValueToStringHelper('PaymentTermListResponse') + ..add('data', data)) + .toString(); + } +} + +class PaymentTermListResponseBuilder + implements + Builder { + _$PaymentTermListResponse _$v; + + ListBuilder _data; + ListBuilder get data => + _$this._data ??= new ListBuilder(); + set data(ListBuilder data) => _$this._data = data; + + PaymentTermListResponseBuilder(); + + PaymentTermListResponseBuilder get _$this { + if (_$v != null) { + _data = _$v.data?.toBuilder(); + _$v = null; + } + return this; + } + + @override + void replace(PaymentTermListResponse other) { + if (other == null) { + throw new ArgumentError.notNull('other'); + } + _$v = other as _$PaymentTermListResponse; + } + + @override + void update(void Function(PaymentTermListResponseBuilder) updates) { + if (updates != null) updates(this); + } + + @override + _$PaymentTermListResponse build() { + _$PaymentTermListResponse _$result; + try { + _$result = _$v ?? new _$PaymentTermListResponse._(data: data.build()); + } catch (_) { + String _$failedField; + try { + _$failedField = 'data'; + data.build(); + } catch (e) { + throw new BuiltValueNestedFieldError( + 'PaymentTermListResponse', _$failedField, e.toString()); + } + rethrow; + } + replace(_$result); + return _$result; + } +} + +class _$PaymentTermItemResponse extends PaymentTermItemResponse { + @override + final PaymentTermEntity data; + + factory _$PaymentTermItemResponse( + [void Function(PaymentTermItemResponseBuilder) updates]) => + (new PaymentTermItemResponseBuilder()..update(updates)).build(); + + _$PaymentTermItemResponse._({this.data}) : super._() { + if (data == null) { + throw new BuiltValueNullFieldError('PaymentTermItemResponse', 'data'); + } + } + + @override + PaymentTermItemResponse rebuild( + void Function(PaymentTermItemResponseBuilder) updates) => + (toBuilder()..update(updates)).build(); + + @override + PaymentTermItemResponseBuilder toBuilder() => + new PaymentTermItemResponseBuilder()..replace(this); + + @override + bool operator ==(Object other) { + if (identical(other, this)) return true; + return other is PaymentTermItemResponse && data == other.data; + } + + int __hashCode; + @override + int get hashCode { + return __hashCode ??= $jf($jc(0, data.hashCode)); + } + + @override + String toString() { + return (newBuiltValueToStringHelper('PaymentTermItemResponse') + ..add('data', data)) + .toString(); + } +} + +class PaymentTermItemResponseBuilder + implements + Builder { + _$PaymentTermItemResponse _$v; + + PaymentTermEntityBuilder _data; + PaymentTermEntityBuilder get data => + _$this._data ??= new PaymentTermEntityBuilder(); + set data(PaymentTermEntityBuilder data) => _$this._data = data; + + PaymentTermItemResponseBuilder(); + + PaymentTermItemResponseBuilder get _$this { + if (_$v != null) { + _data = _$v.data?.toBuilder(); + _$v = null; + } + return this; + } + + @override + void replace(PaymentTermItemResponse other) { + if (other == null) { + throw new ArgumentError.notNull('other'); + } + _$v = other as _$PaymentTermItemResponse; + } + + @override + void update(void Function(PaymentTermItemResponseBuilder) updates) { + if (updates != null) updates(this); + } + + @override + _$PaymentTermItemResponse build() { + _$PaymentTermItemResponse _$result; + try { + _$result = _$v ?? new _$PaymentTermItemResponse._(data: data.build()); + } catch (_) { + String _$failedField; + try { + _$failedField = 'data'; + data.build(); + } catch (e) { + throw new BuiltValueNestedFieldError( + 'PaymentTermItemResponse', _$failedField, e.toString()); + } + rethrow; + } + replace(_$result); + return _$result; + } +} + +class _$PaymentTermEntity extends PaymentTermEntity { + @override + final String name; + @override + final int numDays; + @override + final bool isChanged; + @override + final int createdAt; + @override + final int updatedAt; + @override + final int archivedAt; + @override + final bool isDeleted; + @override + final String createdUserId; + @override + final String assignedUserId; + @override + final EntityType subEntityType; + @override + final String id; + + factory _$PaymentTermEntity( + [void Function(PaymentTermEntityBuilder) updates]) => + (new PaymentTermEntityBuilder()..update(updates)).build(); + + _$PaymentTermEntity._( + {this.name, + this.numDays, + this.isChanged, + this.createdAt, + this.updatedAt, + this.archivedAt, + this.isDeleted, + this.createdUserId, + this.assignedUserId, + this.subEntityType, + this.id}) + : super._() { + if (name == null) { + throw new BuiltValueNullFieldError('PaymentTermEntity', 'name'); + } + if (numDays == null) { + throw new BuiltValueNullFieldError('PaymentTermEntity', 'numDays'); + } + } + + @override + PaymentTermEntity rebuild(void Function(PaymentTermEntityBuilder) updates) => + (toBuilder()..update(updates)).build(); + + @override + PaymentTermEntityBuilder toBuilder() => + new PaymentTermEntityBuilder()..replace(this); + + @override + bool operator ==(Object other) { + if (identical(other, this)) return true; + return other is PaymentTermEntity && + name == other.name && + numDays == other.numDays && + isChanged == other.isChanged && + createdAt == other.createdAt && + updatedAt == other.updatedAt && + archivedAt == other.archivedAt && + isDeleted == other.isDeleted && + createdUserId == other.createdUserId && + assignedUserId == other.assignedUserId && + subEntityType == other.subEntityType && + id == other.id; + } + + int __hashCode; + @override + int get hashCode { + return __hashCode ??= $jf($jc( + $jc( + $jc( + $jc( + $jc( + $jc( + $jc( + $jc( + $jc( + $jc($jc(0, name.hashCode), + numDays.hashCode), + isChanged.hashCode), + createdAt.hashCode), + updatedAt.hashCode), + archivedAt.hashCode), + isDeleted.hashCode), + createdUserId.hashCode), + assignedUserId.hashCode), + subEntityType.hashCode), + id.hashCode)); + } + + @override + String toString() { + return (newBuiltValueToStringHelper('PaymentTermEntity') + ..add('name', name) + ..add('numDays', numDays) + ..add('isChanged', isChanged) + ..add('createdAt', createdAt) + ..add('updatedAt', updatedAt) + ..add('archivedAt', archivedAt) + ..add('isDeleted', isDeleted) + ..add('createdUserId', createdUserId) + ..add('assignedUserId', assignedUserId) + ..add('subEntityType', subEntityType) + ..add('id', id)) + .toString(); + } +} + +class PaymentTermEntityBuilder + implements Builder { + _$PaymentTermEntity _$v; + + String _name; + String get name => _$this._name; + set name(String name) => _$this._name = name; + + int _numDays; + int get numDays => _$this._numDays; + set numDays(int numDays) => _$this._numDays = numDays; + + bool _isChanged; + bool get isChanged => _$this._isChanged; + set isChanged(bool isChanged) => _$this._isChanged = isChanged; + + int _createdAt; + int get createdAt => _$this._createdAt; + set createdAt(int createdAt) => _$this._createdAt = createdAt; + + int _updatedAt; + int get updatedAt => _$this._updatedAt; + set updatedAt(int updatedAt) => _$this._updatedAt = updatedAt; + + int _archivedAt; + int get archivedAt => _$this._archivedAt; + set archivedAt(int archivedAt) => _$this._archivedAt = archivedAt; + + bool _isDeleted; + bool get isDeleted => _$this._isDeleted; + set isDeleted(bool isDeleted) => _$this._isDeleted = isDeleted; + + String _createdUserId; + String get createdUserId => _$this._createdUserId; + set createdUserId(String createdUserId) => + _$this._createdUserId = createdUserId; + + String _assignedUserId; + String get assignedUserId => _$this._assignedUserId; + set assignedUserId(String assignedUserId) => + _$this._assignedUserId = assignedUserId; + + EntityType _subEntityType; + EntityType get subEntityType => _$this._subEntityType; + set subEntityType(EntityType subEntityType) => + _$this._subEntityType = subEntityType; + + String _id; + String get id => _$this._id; + set id(String id) => _$this._id = id; + + PaymentTermEntityBuilder(); + + PaymentTermEntityBuilder get _$this { + if (_$v != null) { + _name = _$v.name; + _numDays = _$v.numDays; + _isChanged = _$v.isChanged; + _createdAt = _$v.createdAt; + _updatedAt = _$v.updatedAt; + _archivedAt = _$v.archivedAt; + _isDeleted = _$v.isDeleted; + _createdUserId = _$v.createdUserId; + _assignedUserId = _$v.assignedUserId; + _subEntityType = _$v.subEntityType; + _id = _$v.id; + _$v = null; + } + return this; + } + + @override + void replace(PaymentTermEntity other) { + if (other == null) { + throw new ArgumentError.notNull('other'); + } + _$v = other as _$PaymentTermEntity; + } + + @override + void update(void Function(PaymentTermEntityBuilder) updates) { + if (updates != null) updates(this); + } + + @override + _$PaymentTermEntity build() { + final _$result = _$v ?? + new _$PaymentTermEntity._( + name: name, + numDays: numDays, + isChanged: isChanged, + createdAt: createdAt, + updatedAt: updatedAt, + archivedAt: archivedAt, + isDeleted: isDeleted, + createdUserId: createdUserId, + assignedUserId: assignedUserId, + subEntityType: subEntityType, + id: id); + replace(_$result); + return _$result; + } +} + +// ignore_for_file: always_put_control_body_on_new_line,always_specify_types,annotate_overrides,avoid_annotating_with_dynamic,avoid_as,avoid_catches_without_on_clauses,avoid_returning_this,lines_longer_than_80_chars,omit_local_variable_types,prefer_expression_function_bodies,sort_constructors_first,test_types_in_equals,unnecessary_const,unnecessary_new diff --git a/lib/data/models/serializers.dart b/lib/data/models/serializers.dart index 848fba4cf..fcf6183c8 100644 --- a/lib/data/models/serializers.dart +++ b/lib/data/models/serializers.dart @@ -12,6 +12,7 @@ import 'package:invoiceninja_flutter/data/models/models.dart'; import 'package:invoiceninja_flutter/data/models/entities.dart'; import 'package:invoiceninja_flutter/data/models/payment_model.dart'; import 'package:invoiceninja_flutter/data/models/account_model.dart'; +import 'package:invoiceninja_flutter/data/models/payment_term_model.dart'; import 'package:invoiceninja_flutter/data/models/project_model.dart'; import 'package:invoiceninja_flutter/data/models/task_model.dart'; import 'package:invoiceninja_flutter/data/models/tax_rate_model.dart'; @@ -35,7 +36,9 @@ import 'package:invoiceninja_flutter/redux/task/task_state.dart'; import 'package:invoiceninja_flutter/redux/project/project_state.dart'; import 'package:invoiceninja_flutter/redux/payment/payment_state.dart'; import 'package:invoiceninja_flutter/redux/quote/quote_state.dart'; + // STARTER: import - do not remove comment +import 'package:invoiceninja_flutter/redux/payment_term/payment_term_state.dart'; import 'package:invoiceninja_flutter/data/models/design_model.dart'; import 'package:invoiceninja_flutter/redux/design/design_state.dart'; import 'package:invoiceninja_flutter/redux/credit/credit_state.dart'; @@ -110,6 +113,9 @@ part 'serializers.g.dart'; TaxRateItemResponse, TaxRateListResponse, // STARTER: serializers - do not remove comment + PaymentTermEntity, + PaymentTermListResponse, + PaymentTermItemResponse, DesignEntity, DesignListResponse, DesignItemResponse, diff --git a/lib/data/models/serializers.g.dart b/lib/data/models/serializers.g.dart index 980bba598..2427cd534 100644 --- a/lib/data/models/serializers.g.dart +++ b/lib/data/models/serializers.g.dart @@ -100,6 +100,10 @@ Serializers _$serializers = (new Serializers().toBuilder() ..add(PaymentListResponse.serializer) ..add(PaymentState.serializer) ..add(PaymentTermEntity.serializer) + ..add(PaymentTermItemResponse.serializer) + ..add(PaymentTermListResponse.serializer) + ..add(PaymentTermState.serializer) + ..add(PaymentTermUIState.serializer) ..add(PaymentTypeEntity.serializer) ..add(PaymentTypeItemResponse.serializer) ..add(PaymentTypeListResponse.serializer) @@ -356,6 +360,7 @@ Serializers _$serializers = (new Serializers().toBuilder() ..addBuilderFactory( const FullType(BuiltList, const [const FullType(LanguageEntity)]), () => new ListBuilder()) ..addBuilderFactory(const FullType(BuiltList, const [const FullType(PaymentEntity)]), () => new ListBuilder()) + ..addBuilderFactory(const FullType(BuiltList, const [const FullType(PaymentTermEntity)]), () => new ListBuilder()) ..addBuilderFactory(const FullType(BuiltList, const [const FullType(PaymentTypeEntity)]), () => new ListBuilder()) ..addBuilderFactory(const FullType(BuiltList, const [const FullType(PaymentableEntity)]), () => new ListBuilder()) ..addBuilderFactory(const FullType(BuiltList, const [const FullType(PaymentableEntity)]), () => new ListBuilder()) @@ -416,6 +421,8 @@ Serializers _$serializers = (new Serializers().toBuilder() ..addBuilderFactory(const FullType(BuiltList, const [const FullType(String)]), () => new ListBuilder()) ..addBuilderFactory(const FullType(BuiltMap, const [const FullType(String), const FullType(PaymentEntity)]), () => new MapBuilder()) ..addBuilderFactory(const FullType(BuiltList, const [const FullType(String)]), () => new ListBuilder()) + ..addBuilderFactory(const FullType(BuiltMap, const [const FullType(String), const FullType(PaymentTermEntity)]), () => new MapBuilder()) + ..addBuilderFactory(const FullType(BuiltList, const [const FullType(String)]), () => new ListBuilder()) ..addBuilderFactory(const FullType(BuiltMap, const [const FullType(String), const FullType(ProductEntity)]), () => new MapBuilder()) ..addBuilderFactory(const FullType(BuiltList, const [const FullType(String)]), () => new ListBuilder()) ..addBuilderFactory(const FullType(BuiltMap, const [const FullType(String), const FullType(ProjectEntity)]), () => new MapBuilder()) diff --git a/lib/data/repositories/payment_term_repository.dart b/lib/data/repositories/payment_term_repository.dart new file mode 100644 index 000000000..ad9d44375 --- /dev/null +++ b/lib/data/repositories/payment_term_repository.dart @@ -0,0 +1,79 @@ +import 'dart:async'; +import 'dart:convert'; +import 'dart:core'; +import 'package:built_collection/built_collection.dart'; +import 'package:invoiceninja_flutter/constants.dart'; +import 'package:invoiceninja_flutter/data/models/payment_term_model.dart'; +import 'package:invoiceninja_flutter/data/models/serializers.dart'; +import 'package:invoiceninja_flutter/redux/app/app_state.dart'; +import 'package:invoiceninja_flutter/data/models/models.dart'; +import 'package:invoiceninja_flutter/data/web_client.dart'; + +class PaymentTermRepository { + const PaymentTermRepository({ + this.webClient = const WebClient(), + }); + + final WebClient webClient; + + Future loadItem( + Credentials credentials, String entityId) async { + final dynamic response = await webClient.get( + '${credentials.url}/payment_terms/$entityId', credentials.token); + + final PaymentTermItemResponse paymentTermResponse = serializers + .deserializeWith(PaymentTermItemResponse.serializer, response); + + return paymentTermResponse.data; + } + + Future> loadList( + Credentials credentials, int updatedAt) async { + String url = credentials.url + '/payment_terms?'; + + if (updatedAt > 0) { + url += '&updated_at=${updatedAt - kUpdatedAtBufferSeconds}'; + } + + final dynamic response = await webClient.get(url, credentials.token); + + final PaymentTermListResponse paymentTermResponse = serializers + .deserializeWith(PaymentTermListResponse.serializer, response); + + return paymentTermResponse.data; + } + + Future> bulkAction( + Credentials credentials, List ids, EntityAction action) async { + final url = credentials.url + '/payment_terms/bulk'; + final dynamic response = await webClient.post(url, credentials.token, + data: json.encode({'ids': ids, 'action': '$action'})); + + final PaymentTermListResponse paymentTermResponse = serializers + .deserializeWith(PaymentTermListResponse.serializer, response); + + return paymentTermResponse.data.toList(); + } + + Future saveData( + Credentials credentials, PaymentTermEntity paymentTerm) async { + final data = + serializers.serializeWith(PaymentTermEntity.serializer, paymentTerm); + dynamic response; + + if (paymentTerm.isNew) { + response = await webClient.post( + credentials.url + '/payment_terms', credentials.token, + data: json.encode(data)); + } else { + final url = '${credentials.url}/payment_terms/${paymentTerm.id}'; + response = + await webClient.put(url, credentials.token, data: json.encode(data)); + } + + final PaymentTermItemResponse paymentTermResponse = serializers + .deserializeWith(PaymentTermItemResponse.serializer, response); + + return paymentTermResponse.data; + } +} diff --git a/lib/main.dart b/lib/main.dart index f4881ab6c..b02e3a125 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -39,6 +39,7 @@ import 'package:shared_preferences/shared_preferences.dart'; import 'package:invoiceninja_flutter/utils/web_stub.dart' if (dart.library.html) 'package:invoiceninja_flutter/utils/web.dart'; // STARTER: import - do not remove comment +import 'package:invoiceninja_flutter/redux/payment_term/payment_term_middleware.dart'; void main({bool isTesting = false}) async { WidgetsFlutterBinding.ensureInitialized(); @@ -68,6 +69,7 @@ void main({bool isTesting = false}) async { ..addAll(createStoreSettingsMiddleware()) ..addAll(createStoreReportsMiddleware()) // STARTER: middleware - do not remove comment + ..addAll(createStorePaymentTermsMiddleware()) ..addAll(createStoreDesignsMiddleware()) ..addAll(createStoreCreditsMiddleware()) ..addAll(createStoreUsersMiddleware()) diff --git a/lib/main_app.dart b/lib/main_app.dart index 027221083..1b38be21c 100644 --- a/lib/main_app.dart +++ b/lib/main_app.dart @@ -27,6 +27,10 @@ import 'package:invoiceninja_flutter/ui/design/design_screen_vm.dart'; import 'package:invoiceninja_flutter/ui/design/edit/design_edit_vm.dart'; import 'package:invoiceninja_flutter/ui/design/view/design_view_vm.dart'; import 'package:invoiceninja_flutter/ui/payment/refund/payment_refund_vm.dart'; +import 'package:invoiceninja_flutter/ui/payment_term/edit/payment_term_edit_vm.dart'; +import 'package:invoiceninja_flutter/ui/payment_term/payment_term_screen.dart'; +import 'package:invoiceninja_flutter/ui/payment_term/payment_term_screen_vm.dart'; +import 'package:invoiceninja_flutter/ui/payment_term/view/payment_term_view_vm.dart'; import 'package:invoiceninja_flutter/ui/reports/reports_screen.dart'; import 'package:invoiceninja_flutter/ui/reports/reports_screen_vm.dart'; import 'package:invoiceninja_flutter/ui/settings/account_management_vm.dart'; @@ -221,6 +225,12 @@ class InvoiceNinjaAppState extends State { QuoteEditScreen.route: (context) => QuoteEditScreen(), QuoteEmailScreen.route: (context) => QuoteEmailScreen(), // STARTER: routes - do not remove comment + PaymentTermScreen.route: (context) => + PaymentTermScreenBuilder(), + PaymentTermViewScreen.route: (context) => + PaymentTermViewScreen(), + PaymentTermEditScreen.route: (context) => + PaymentTermEditScreen(), DesignScreen.route: (context) => DesignScreenBuilder(), DesignViewScreen.route: (context) => DesignViewScreen(), DesignEditScreen.route: (context) => DesignEditScreen(), diff --git a/lib/redux/app/app_actions.dart b/lib/redux/app/app_actions.dart index 492eb87d0..699e59d65 100644 --- a/lib/redux/app/app_actions.dart +++ b/lib/redux/app/app_actions.dart @@ -7,6 +7,7 @@ import 'package:invoiceninja_flutter/data/models/company_gateway_model.dart'; import 'package:invoiceninja_flutter/data/models/entities.dart'; import 'package:invoiceninja_flutter/data/models/group_model.dart'; import 'package:invoiceninja_flutter/data/models/models.dart'; +import 'package:invoiceninja_flutter/data/models/payment_term_model.dart'; import 'package:invoiceninja_flutter/data/models/static/static_data_model.dart'; import 'package:invoiceninja_flutter/redux/app/app_state.dart'; import 'package:invoiceninja_flutter/redux/client/client_actions.dart'; @@ -30,6 +31,7 @@ import 'package:invoiceninja_flutter/utils/completers.dart'; import 'package:invoiceninja_flutter/utils/dialogs.dart'; import 'package:invoiceninja_flutter/utils/localization.dart'; // STARTER: import - do not remove comment +import 'package:invoiceninja_flutter/redux/payment_term/payment_term_actions.dart'; class PersistUI {} @@ -245,6 +247,13 @@ void filterEntitiesByType({ )); break; // STARTER: filter - do not remove comment + case EntityType.paymentTerm: + store.dispatch(FilterPaymentTermsByEntity( + entityId: filterEntity.id, + entityType: filterEntity.entityType, + )); + break; + case EntityType.design: store.dispatch(FilterDesignsByEntity( entityId: filterEntity.id, @@ -319,6 +328,10 @@ void viewEntitiesByType({ action = ViewGroupList(navigator: navigator); break; // STARTER: view list - do not remove comment + case EntityType.paymentTerm: + store.dispatch(ViewPaymentTermList(navigator: navigator)); + break; + case EntityType.design: action = ViewDesignList(navigator: navigator); break; @@ -456,6 +469,14 @@ void viewEntityById({ )); break; // STARTER: view - do not remove comment + case EntityType.paymentTerm: + store.dispatch(ViewPaymentTerm( + paymentTermId: entityId, + navigator: navigator, + force: force, + )); + break; + case EntityType.design: store.dispatch(ViewDesign( designId: entityId, @@ -587,6 +608,14 @@ void createEntityByType( )); break; // STARTER: create type - do not remove comment + case EntityType.paymentTerm: + store.dispatch(EditPaymentTerm( + navigator: navigator, + force: force, + paymentTerm: PaymentTermEntity(state: state), + )); + break; + case EntityType.design: store.dispatch(EditDesign( navigator: navigator, @@ -736,6 +765,15 @@ void createEntity({ )); break; // STARTER: create - do not remove comment + case EntityType.paymentTerm: + store.dispatch(EditPaymentTerm( + navigator: navigator, + paymentTerm: entity, + force: force, + completer: completer, + )); + break; + case EntityType.design: store.dispatch(EditDesign( navigator: navigator, @@ -935,6 +973,19 @@ void editEntityById( )); break; // STARTER: edit - do not remove comment + case EntityType.paymentTerm: + store.dispatch(EditPaymentTerm( + paymentTerm: map[entityId], + navigator: navigator, + completer: completer ?? + snackBarCompleter( + context, + entity.isNew + ? localization.createdPaymentTerm + : localization.updatedPaymentTerm), + )); + break; + case EntityType.design: store.dispatch(EditDesign( design: map[entityId], @@ -1030,6 +1081,10 @@ void handleEntitiesActions( handleDocumentAction(context, entities, action); break; // STARTER: actions - do not remove comment + case EntityType.paymentTerm: + handlePaymentTermAction(context, entities, action); + break; + case EntityType.design: handleDesignAction(context, entities, action); break; diff --git a/lib/redux/app/app_reducer.dart b/lib/redux/app/app_reducer.dart index 85db69008..95fd20f63 100644 --- a/lib/redux/app/app_reducer.dart +++ b/lib/redux/app/app_reducer.dart @@ -18,6 +18,8 @@ import 'package:invoiceninja_flutter/redux/auth/auth_reducer.dart'; import 'package:invoiceninja_flutter/redux/company/company_reducer.dart'; import 'package:invoiceninja_flutter/redux/static/static_reducer.dart'; // STARTER: import - do not remove comment +import 'package:invoiceninja_flutter/redux/payment_term/payment_term_actions.dart'; + import 'package:invoiceninja_flutter/redux/design/design_actions.dart'; import 'package:invoiceninja_flutter/redux/credit/credit_actions.dart'; @@ -81,6 +83,10 @@ final lastErrorReducer = combineReducers([ return '${action.error}'; }), // STARTER: errors - do not remove comment + TypedReducer((state, action) { + return '${action.error}'; + }), + TypedReducer((state, action) { return '${action.error}'; }), diff --git a/lib/redux/app/app_state.dart b/lib/redux/app/app_state.dart index 3cfdd9732..d16d7aa40 100644 --- a/lib/redux/app/app_state.dart +++ b/lib/redux/app/app_state.dart @@ -47,6 +47,12 @@ import 'package:invoiceninja_flutter/ui/group/edit/group_edit_vm.dart'; import 'package:invoiceninja_flutter/ui/product/edit/product_edit_vm.dart'; // STARTER: import - do not remove comment +import 'package:invoiceninja_flutter/redux/payment_term/payment_term_state.dart'; +import 'package:invoiceninja_flutter/ui/payment_term/edit/payment_term_edit_vm.dart'; +import 'package:invoiceninja_flutter/redux/payment_term/payment_term_state.dart'; +import 'package:invoiceninja_flutter/ui/payment_term/edit/payment_term_edit_vm.dart'; +import 'package:invoiceninja_flutter/redux/payment_term/payment_term_selectors.dart'; + import 'package:invoiceninja_flutter/redux/credit/credit_state.dart'; import 'package:invoiceninja_flutter/redux/user/user_state.dart'; @@ -185,6 +191,9 @@ abstract class AppState implements Built { case EntityType.invoice: return invoiceState.map; // STARTER: states switch map - do not remove comment + case EntityType.paymentTerm: + return paymentTermState.map; + case EntityType.design: return designState.map; @@ -248,6 +257,9 @@ abstract class AppState implements Built { case EntityType.invoice: return invoiceState.list; // STARTER: states switch list - do not remove comment + case EntityType.paymentTerm: + return paymentTermState.list; + case EntityType.design: return designState.list; @@ -290,6 +302,9 @@ abstract class AppState implements Built { case EntityType.invoice: return invoiceUIState; // STARTER: states switch - do not remove comment + case EntityType.paymentTerm: + return paymentTermUIState; + case EntityType.design: return designUIState; case EntityType.credit: @@ -344,6 +359,11 @@ abstract class AppState implements Built { ListUIState get invoiceListState => uiState.invoiceUIState.listUIState; // STARTER: state getters - do not remove comment + PaymentTermState get paymentTermState => userCompanyState.paymentTermState; + ListUIState get paymentTermListState => + uiState.paymentTermUIState.listUIState; + PaymentTermUIState get paymentTermUIState => uiState.paymentTermUIState; + DesignState get designState => userCompanyState.designState; ListUIState get designListState => uiState.designUIState.listUIState; @@ -457,6 +477,10 @@ abstract class AppState implements Built { case CreditEditScreen.route: return hasCreditChanges(creditUIState.editing, creditState.map); // STARTER: has changes - do not remove comment + case PaymentTermEditScreen.route: + return hasPaymentTermChanges( + paymentTermUIState.editing, paymentTermState.map); + case DesignEditScreen.route: return hasDesignChanges(designUIState.editing, designState.map); } diff --git a/lib/redux/company/company_reducer.dart b/lib/redux/company/company_reducer.dart index d0397d1af..226fc8d53 100644 --- a/lib/redux/company/company_reducer.dart +++ b/lib/redux/company/company_reducer.dart @@ -18,6 +18,8 @@ import 'package:invoiceninja_flutter/redux/payment/payment_reducer.dart'; import 'package:invoiceninja_flutter/redux/quote/quote_reducer.dart'; // STARTER: import - do not remove comment +import 'package:invoiceninja_flutter/redux/payment_term/payment_term_reducer.dart'; + import 'package:invoiceninja_flutter/redux/design/design_reducer.dart'; import 'package:invoiceninja_flutter/redux/credit/credit_reducer.dart'; @@ -42,6 +44,8 @@ UserCompanyState companyReducer(UserCompanyState state, dynamic action) { ..vendorState.replace(vendorsReducer(state.vendorState, action)) ..taskState.replace(tasksReducer(state.taskState, action)) // STARTER: reducer - do not remove comment + ..paymentTermState + .replace(paymentTermsReducer(state.paymentTermState, action)) ..designState.replace(designsReducer(state.designState, action)) ..creditState.replace(creditsReducer(state.creditState, action)) ..userState.replace(usersReducer(state.userState, action)) diff --git a/lib/redux/company/company_state.dart b/lib/redux/company/company_state.dart index 960bd33ab..f5e979995 100644 --- a/lib/redux/company/company_state.dart +++ b/lib/redux/company/company_state.dart @@ -7,6 +7,8 @@ import 'package:invoiceninja_flutter/data/models/models.dart'; import 'package:built_value/built_value.dart'; import 'package:built_value/serializer.dart'; // STARTER: import - do not remove comment +import 'package:invoiceninja_flutter/redux/payment_term/payment_term_state.dart'; + import 'package:invoiceninja_flutter/redux/design/design_state.dart'; import 'package:invoiceninja_flutter/redux/credit/credit_state.dart'; @@ -41,6 +43,8 @@ abstract class UserCompanyState paymentState: PaymentState(), quoteState: QuoteState(), // STARTER: constructor - do not remove comment + paymentTermState: PaymentTermState(), + designState: DesignState(), creditState: CreditState(), @@ -82,6 +86,8 @@ abstract class UserCompanyState QuoteState get quoteState; // STARTER: fields - do not remove comment + PaymentTermState get paymentTermState; + DesignState get designState; CreditState get creditState; diff --git a/lib/redux/company/company_state.g.dart b/lib/redux/company/company_state.g.dart index 4d6ce6436..314fa39fb 100644 --- a/lib/redux/company/company_state.g.dart +++ b/lib/redux/company/company_state.g.dart @@ -52,6 +52,9 @@ class _$UserCompanyStateSerializer 'quoteState', serializers.serialize(object.quoteState, specifiedType: const FullType(QuoteState)), + 'paymentTermState', + serializers.serialize(object.paymentTermState, + specifiedType: const FullType(PaymentTermState)), 'designState', serializers.serialize(object.designState, specifiedType: const FullType(DesignState)), @@ -137,6 +140,11 @@ class _$UserCompanyStateSerializer result.quoteState.replace(serializers.deserialize(value, specifiedType: const FullType(QuoteState)) as QuoteState); break; + case 'paymentTermState': + result.paymentTermState.replace(serializers.deserialize(value, + specifiedType: const FullType(PaymentTermState)) + as PaymentTermState); + break; case 'designState': result.designState.replace(serializers.deserialize(value, specifiedType: const FullType(DesignState)) as DesignState); @@ -328,6 +336,8 @@ class _$UserCompanyState extends UserCompanyState { @override final QuoteState quoteState; @override + final PaymentTermState paymentTermState; + @override final DesignState designState; @override final CreditState creditState; @@ -356,6 +366,7 @@ class _$UserCompanyState extends UserCompanyState { this.projectState, this.paymentState, this.quoteState, + this.paymentTermState, this.designState, this.creditState, this.userState, @@ -393,6 +404,10 @@ class _$UserCompanyState extends UserCompanyState { if (quoteState == null) { throw new BuiltValueNullFieldError('UserCompanyState', 'quoteState'); } + if (paymentTermState == null) { + throw new BuiltValueNullFieldError( + 'UserCompanyState', 'paymentTermState'); + } if (designState == null) { throw new BuiltValueNullFieldError('UserCompanyState', 'designState'); } @@ -437,6 +452,7 @@ class _$UserCompanyState extends UserCompanyState { projectState == other.projectState && paymentState == other.paymentState && quoteState == other.quoteState && + paymentTermState == other.paymentTermState && designState == other.designState && creditState == other.creditState && userState == other.userState && @@ -465,22 +481,25 @@ class _$UserCompanyState extends UserCompanyState { $jc( $jc( $jc( - 0, - userCompany + $jc( + 0, + userCompany + .hashCode), + documentState .hashCode), - documentState + productState .hashCode), - productState + clientState .hashCode), - clientState + invoiceState .hashCode), - invoiceState.hashCode), - expenseState.hashCode), - vendorState.hashCode), - taskState.hashCode), - projectState.hashCode), - paymentState.hashCode), - quoteState.hashCode), + expenseState.hashCode), + vendorState.hashCode), + taskState.hashCode), + projectState.hashCode), + paymentState.hashCode), + quoteState.hashCode), + paymentTermState.hashCode), designState.hashCode), creditState.hashCode), userState.hashCode), @@ -503,6 +522,7 @@ class _$UserCompanyState extends UserCompanyState { ..add('projectState', projectState) ..add('paymentState', paymentState) ..add('quoteState', quoteState) + ..add('paymentTermState', paymentTermState) ..add('designState', designState) ..add('creditState', creditState) ..add('userState', userState) @@ -582,6 +602,12 @@ class UserCompanyStateBuilder set quoteState(QuoteStateBuilder quoteState) => _$this._quoteState = quoteState; + PaymentTermStateBuilder _paymentTermState; + PaymentTermStateBuilder get paymentTermState => + _$this._paymentTermState ??= new PaymentTermStateBuilder(); + set paymentTermState(PaymentTermStateBuilder paymentTermState) => + _$this._paymentTermState = paymentTermState; + DesignStateBuilder _designState; DesignStateBuilder get designState => _$this._designState ??= new DesignStateBuilder(); @@ -632,6 +658,7 @@ class UserCompanyStateBuilder _projectState = _$v.projectState?.toBuilder(); _paymentState = _$v.paymentState?.toBuilder(); _quoteState = _$v.quoteState?.toBuilder(); + _paymentTermState = _$v.paymentTermState?.toBuilder(); _designState = _$v.designState?.toBuilder(); _creditState = _$v.creditState?.toBuilder(); _userState = _$v.userState?.toBuilder(); @@ -673,6 +700,7 @@ class UserCompanyStateBuilder projectState: projectState.build(), paymentState: paymentState.build(), quoteState: quoteState.build(), + paymentTermState: paymentTermState.build(), designState: designState.build(), creditState: creditState.build(), userState: userState.build(), @@ -704,6 +732,8 @@ class UserCompanyStateBuilder paymentState.build(); _$failedField = 'quoteState'; quoteState.build(); + _$failedField = 'paymentTermState'; + paymentTermState.build(); _$failedField = 'designState'; designState.build(); _$failedField = 'creditState'; diff --git a/lib/redux/payment_term/payment_term_actions.dart b/lib/redux/payment_term/payment_term_actions.dart new file mode 100644 index 000000000..d67f1bd9b --- /dev/null +++ b/lib/redux/payment_term/payment_term_actions.dart @@ -0,0 +1,327 @@ +import 'dart:async'; +import 'package:built_collection/built_collection.dart'; +import 'package:flutter/widgets.dart'; +import 'package:flutter_redux/flutter_redux.dart'; +import 'package:invoiceninja_flutter/data/models/models.dart'; +import 'package:invoiceninja_flutter/data/models/payment_term_model.dart'; +import 'package:invoiceninja_flutter/redux/app/app_actions.dart'; +import 'package:invoiceninja_flutter/redux/app/app_state.dart'; +import 'package:invoiceninja_flutter/utils/completers.dart'; +import 'package:invoiceninja_flutter/utils/localization.dart'; + +class ViewPaymentTermList extends AbstractNavigatorAction + implements PersistUI, StopLoading { + ViewPaymentTermList({ + @required NavigatorState navigator, + this.force = false, + }) : super(navigator: navigator); + + final bool force; +} + +class ViewPaymentTerm extends AbstractNavigatorAction + implements PersistUI, PersistPrefs { + ViewPaymentTerm({ + @required NavigatorState navigator, + @required this.paymentTermId, + this.force = false, + }) : super(navigator: navigator); + + final String paymentTermId; + final bool force; +} + +class EditPaymentTerm extends AbstractNavigatorAction + implements PersistUI, PersistPrefs { + EditPaymentTerm( + {@required this.paymentTerm, + @required NavigatorState navigator, + this.completer, + this.cancelCompleter, + this.force = false}) + : super(navigator: navigator); + + final PaymentTermEntity paymentTerm; + final Completer completer; + final Completer cancelCompleter; + final bool force; +} + +class UpdatePaymentTerm implements PersistUI { + UpdatePaymentTerm(this.paymentTerm); + + final PaymentTermEntity paymentTerm; +} + +class LoadPaymentTerm { + LoadPaymentTerm({this.completer, this.paymentTermId}); + + final Completer completer; + final String paymentTermId; +} + +class LoadPaymentTermActivity { + LoadPaymentTermActivity({this.completer, this.paymentTermId}); + + final Completer completer; + final String paymentTermId; +} + +class LoadPaymentTerms { + LoadPaymentTerms({this.completer, this.force = false}); + + final Completer completer; + final bool force; +} + +class LoadPaymentTermRequest implements StartLoading {} + +class LoadPaymentTermFailure implements StopLoading { + LoadPaymentTermFailure(this.error); + + final dynamic error; + + @override + String toString() { + return 'LoadPaymentTermFailure{error: $error}'; + } +} + +class LoadPaymentTermSuccess implements StopLoading, PersistData { + LoadPaymentTermSuccess(this.paymentTerm); + + final PaymentTermEntity paymentTerm; + + @override + String toString() { + return 'LoadPaymentTermSuccess{paymentTerm: $paymentTerm}'; + } +} + +class LoadPaymentTermsRequest implements StartLoading {} + +class LoadPaymentTermsFailure implements StopLoading { + LoadPaymentTermsFailure(this.error); + + final dynamic error; + + @override + String toString() { + return 'LoadPaymentTermsFailure{error: $error}'; + } +} + +class LoadPaymentTermsSuccess implements StopLoading, PersistData { + LoadPaymentTermsSuccess(this.paymentTerms); + + final BuiltList paymentTerms; + + @override + String toString() { + return 'LoadPaymentTermsSuccess{paymentTerms: $paymentTerms}'; + } +} + +class SavePaymentTermRequest implements StartSaving { + SavePaymentTermRequest({this.completer, this.paymentTerm}); + + final Completer completer; + final PaymentTermEntity paymentTerm; +} + +class SavePaymentTermSuccess implements StopSaving, PersistData, PersistUI { + SavePaymentTermSuccess(this.paymentTerm); + + final PaymentTermEntity paymentTerm; +} + +class AddPaymentTermSuccess implements StopSaving, PersistData, PersistUI { + AddPaymentTermSuccess(this.paymentTerm); + + final PaymentTermEntity paymentTerm; +} + +class SavePaymentTermFailure implements StopSaving { + SavePaymentTermFailure(this.error); + + final Object error; +} + +class ArchivePaymentTermsRequest implements StartSaving { + ArchivePaymentTermsRequest(this.completer, this.paymentTermIds); + + final Completer completer; + final List paymentTermIds; +} + +class ArchivePaymentTermsSuccess implements StopSaving, PersistData { + ArchivePaymentTermsSuccess(this.paymentTerms); + + final List paymentTerms; +} + +class ArchivePaymentTermsFailure implements StopSaving { + ArchivePaymentTermsFailure(this.paymentTerms); + + final List paymentTerms; +} + +class DeletePaymentTermsRequest implements StartSaving { + DeletePaymentTermsRequest(this.completer, this.paymentTermIds); + + final Completer completer; + final List paymentTermIds; +} + +class DeletePaymentTermsSuccess implements StopSaving, PersistData { + DeletePaymentTermsSuccess(this.paymentTerms); + + final List paymentTerms; +} + +class DeletePaymentTermsFailure implements StopSaving { + DeletePaymentTermsFailure(this.paymentTerms); + + final List paymentTerms; +} + +class RestorePaymentTermsRequest implements StartSaving { + RestorePaymentTermsRequest(this.completer, this.paymentTermIds); + + final Completer completer; + final List paymentTermIds; +} + +class RestorePaymentTermsSuccess implements StopSaving, PersistData { + RestorePaymentTermsSuccess(this.paymentTerms); + + final List paymentTerms; +} + +class RestorePaymentTermsFailure implements StopSaving { + RestorePaymentTermsFailure(this.paymentTerms); + + final List paymentTerms; +} + +class FilterPaymentTerms implements PersistUI { + FilterPaymentTerms(this.filter); + + final String filter; +} + +class SortPaymentTerms implements PersistUI { + SortPaymentTerms(this.field); + + final String field; +} + +class FilterPaymentTermsByState implements PersistUI { + FilterPaymentTermsByState(this.state); + + final EntityState state; +} + +class FilterPaymentTermsByCustom1 implements PersistUI { + FilterPaymentTermsByCustom1(this.value); + + final String value; +} + +class FilterPaymentTermsByCustom2 implements PersistUI { + FilterPaymentTermsByCustom2(this.value); + + final String value; +} + +class FilterPaymentTermsByCustom3 implements PersistUI { + FilterPaymentTermsByCustom3(this.value); + + final String value; +} + +class FilterPaymentTermsByCustom4 implements PersistUI { + FilterPaymentTermsByCustom4(this.value); + + final String value; +} + +class FilterPaymentTermsByEntity implements PersistUI { + FilterPaymentTermsByEntity({this.entityId, this.entityType}); + + final String entityId; + final EntityType entityType; +} + +void handlePaymentTermAction( + BuildContext context, List paymentTerms, EntityAction action) { + if (paymentTerms.isEmpty) { + return; + } + + final store = StoreProvider.of(context); + final state = store.state; + final CompanyEntity company = state.company; + final localization = AppLocalization.of(context); + final paymentTerm = paymentTerms.first as PaymentTermEntity; + final paymentTermIds = + paymentTerms.map((paymentTerm) => paymentTerm.id).toList(); + + switch (action) { + case EntityAction.edit: + editEntity(context: context, entity: paymentTerm); + break; + case EntityAction.restore: + store.dispatch(RestorePaymentTermsRequest( + snackBarCompleter(context, localization.restoredPaymentTerm), + paymentTermIds)); + break; + case EntityAction.archive: + store.dispatch(ArchivePaymentTermsRequest( + snackBarCompleter(context, localization.archivedPaymentTerm), + paymentTermIds)); + break; + case EntityAction.delete: + store.dispatch(DeletePaymentTermsRequest( + snackBarCompleter(context, localization.deletedPaymentTerm), + paymentTermIds)); + break; + case EntityAction.toggleMultiselect: + if (!store.state.paymentTermListState.isInMultiselect()) { + store.dispatch(StartPaymentTermMultiselect()); + } + + if (paymentTerms.isEmpty) { + break; + } + + for (final paymentTerm in paymentTerms) { + if (!store.state.paymentTermListState.isSelected(paymentTerm.id)) { + store.dispatch(AddToPaymentTermMultiselect(entity: paymentTerm)); + } else { + store.dispatch(RemoveFromPaymentTermMultiselect(entity: paymentTerm)); + } + } + break; + } +} + +class StartPaymentTermMultiselect { + StartPaymentTermMultiselect(); +} + +class AddToPaymentTermMultiselect { + AddToPaymentTermMultiselect({@required this.entity}); + + final BaseEntity entity; +} + +class RemoveFromPaymentTermMultiselect { + RemoveFromPaymentTermMultiselect({@required this.entity}); + + final BaseEntity entity; +} + +class ClearPaymentTermMultiselect { + ClearPaymentTermMultiselect(); +} diff --git a/lib/redux/payment_term/payment_term_middleware.dart b/lib/redux/payment_term/payment_term_middleware.dart new file mode 100644 index 000000000..35ac18e72 --- /dev/null +++ b/lib/redux/payment_term/payment_term_middleware.dart @@ -0,0 +1,281 @@ +import 'package:flutter/material.dart'; +import 'package:flutter/widgets.dart'; +import 'package:invoiceninja_flutter/data/models/payment_term_model.dart'; +import 'package:redux/redux.dart'; +import 'package:invoiceninja_flutter/utils/platforms.dart'; +import 'package:invoiceninja_flutter/redux/app/app_middleware.dart'; +import 'package:invoiceninja_flutter/data/models/models.dart'; +import 'package:invoiceninja_flutter/redux/ui/ui_actions.dart'; +import 'package:invoiceninja_flutter/ui/payment_term/payment_term_screen.dart'; +import 'package:invoiceninja_flutter/ui/payment_term/edit/payment_term_edit_vm.dart'; +import 'package:invoiceninja_flutter/ui/payment_term/view/payment_term_view_vm.dart'; +import 'package:invoiceninja_flutter/redux/payment_term/payment_term_actions.dart'; +import 'package:invoiceninja_flutter/redux/app/app_state.dart'; +import 'package:invoiceninja_flutter/data/repositories/payment_term_repository.dart'; + +List> createStorePaymentTermsMiddleware([ + PaymentTermRepository repository = const PaymentTermRepository(), +]) { + final viewPaymentTermList = _viewPaymentTermList(); + final viewPaymentTerm = _viewPaymentTerm(); + final editPaymentTerm = _editPaymentTerm(); + final loadPaymentTerms = _loadPaymentTerms(repository); + final loadPaymentTerm = _loadPaymentTerm(repository); + final savePaymentTerm = _savePaymentTerm(repository); + final archivePaymentTerm = _archivePaymentTerm(repository); + final deletePaymentTerm = _deletePaymentTerm(repository); + final restorePaymentTerm = _restorePaymentTerm(repository); + + return [ + TypedMiddleware(viewPaymentTermList), + TypedMiddleware(viewPaymentTerm), + TypedMiddleware(editPaymentTerm), + TypedMiddleware(loadPaymentTerms), + TypedMiddleware(loadPaymentTerm), + TypedMiddleware(savePaymentTerm), + TypedMiddleware(archivePaymentTerm), + TypedMiddleware(deletePaymentTerm), + TypedMiddleware(restorePaymentTerm), + ]; +} + +Middleware _editPaymentTerm() { + return (Store store, dynamic dynamicAction, NextDispatcher next) { + final action = dynamicAction as EditPaymentTerm; + + if (!action.force && + hasChanges(store: store, context: action.context, action: action)) { + return; + } + + next(action); + + store.dispatch(UpdateCurrentRoute(PaymentTermEditScreen.route)); + + if (isMobile(action.context)) { + action.navigator.pushNamed(PaymentTermEditScreen.route); + } + }; +} + +Middleware _viewPaymentTerm() { + return (Store store, dynamic dynamicAction, + NextDispatcher next) async { + final action = dynamicAction as ViewPaymentTerm; + + if (!action.force && + hasChanges(store: store, context: action.context, action: action)) { + return; + } + + next(action); + + store.dispatch(UpdateCurrentRoute(PaymentTermViewScreen.route)); + + if (isMobile(action.context)) { + Navigator.of(action.context).pushNamed(PaymentTermViewScreen.route); + } + }; +} + +Middleware _viewPaymentTermList() { + return (Store store, dynamic dynamicAction, NextDispatcher next) { + final action = dynamicAction as ViewPaymentTermList; + + if (!action.force && + hasChanges(store: store, context: action.context, action: action)) { + return; + } + + next(action); + + if (store.state.paymentTermState.isStale) { + store.dispatch(LoadPaymentTerms()); + } + + store.dispatch(UpdateCurrentRoute(PaymentTermScreen.route)); + + if (isMobile(action.context)) { + Navigator.of(action.context).pushNamedAndRemoveUntil( + PaymentTermScreen.route, (Route route) => false); + } + }; +} + +Middleware _archivePaymentTerm(PaymentTermRepository repository) { + return (Store store, dynamic dynamicAction, NextDispatcher next) { + final action = dynamicAction as ArchivePaymentTermsRequest; + final prevPaymentTerms = action.paymentTermIds + .map((id) => store.state.paymentTermState.map[id]) + .toList(); + repository + .bulkAction(store.state.credentials, action.paymentTermIds, + EntityAction.archive) + .then((List paymentTerms) { + store.dispatch(ArchivePaymentTermsSuccess(paymentTerms)); + if (action.completer != null) { + action.completer.complete(null); + } + }).catchError((Object error) { + print(error); + store.dispatch(ArchivePaymentTermsFailure(prevPaymentTerms)); + if (action.completer != null) { + action.completer.completeError(error); + } + }); + + next(action); + }; +} + +Middleware _deletePaymentTerm(PaymentTermRepository repository) { + return (Store store, dynamic dynamicAction, NextDispatcher next) { + final action = dynamicAction as DeletePaymentTermsRequest; + final prevPaymentTerms = action.paymentTermIds + .map((id) => store.state.paymentTermState.map[id]) + .toList(); + repository + .bulkAction( + store.state.credentials, action.paymentTermIds, EntityAction.delete) + .then((List paymentTerms) { + store.dispatch(DeletePaymentTermsSuccess(paymentTerms)); + if (action.completer != null) { + action.completer.complete(null); + } + }).catchError((Object error) { + print(error); + store.dispatch(DeletePaymentTermsFailure(prevPaymentTerms)); + if (action.completer != null) { + action.completer.completeError(error); + } + }); + + next(action); + }; +} + +Middleware _restorePaymentTerm(PaymentTermRepository repository) { + return (Store store, dynamic dynamicAction, NextDispatcher next) { + final action = dynamicAction as RestorePaymentTermsRequest; + final prevPaymentTerms = action.paymentTermIds + .map((id) => store.state.paymentTermState.map[id]) + .toList(); + repository + .bulkAction(store.state.credentials, action.paymentTermIds, + EntityAction.restore) + .then((List paymentTerms) { + store.dispatch(RestorePaymentTermsSuccess(paymentTerms)); + if (action.completer != null) { + action.completer.complete(null); + } + }).catchError((Object error) { + print(error); + store.dispatch(RestorePaymentTermsFailure(prevPaymentTerms)); + if (action.completer != null) { + action.completer.completeError(error); + } + }); + + next(action); + }; +} + +Middleware _savePaymentTerm(PaymentTermRepository repository) { + return (Store store, dynamic dynamicAction, NextDispatcher next) { + final action = dynamicAction as SavePaymentTermRequest; + repository + .saveData(store.state.credentials, action.paymentTerm) + .then((PaymentTermEntity paymentTerm) { + if (action.paymentTerm.isNew) { + store.dispatch(AddPaymentTermSuccess(paymentTerm)); + } else { + store.dispatch(SavePaymentTermSuccess(paymentTerm)); + } + + action.completer.complete(paymentTerm); + + final paymentTermUIState = store.state.paymentTermUIState; + if (paymentTermUIState.saveCompleter != null) { + paymentTermUIState.saveCompleter.complete(paymentTerm); + } + }).catchError((Object error) { + print(error); + store.dispatch(SavePaymentTermFailure(error)); + action.completer.completeError(error); + }); + + next(action); + }; +} + +Middleware _loadPaymentTerm(PaymentTermRepository repository) { + return (Store store, dynamic dynamicAction, NextDispatcher next) { + final action = dynamicAction as LoadPaymentTerm; + final AppState state = store.state; + + if (state.isLoading) { + next(action); + return; + } + + store.dispatch(LoadPaymentTermRequest()); + repository + .loadItem(state.credentials, action.paymentTermId) + .then((paymentTerm) { + store.dispatch(LoadPaymentTermSuccess(paymentTerm)); + + if (action.completer != null) { + action.completer.complete(null); + } + }).catchError((Object error) { + print(error); + store.dispatch(LoadPaymentTermFailure(error)); + if (action.completer != null) { + action.completer.completeError(error); + } + }); + + next(action); + }; +} + +Middleware _loadPaymentTerms(PaymentTermRepository repository) { + return (Store store, dynamic dynamicAction, NextDispatcher next) { + final action = dynamicAction as LoadPaymentTerms; + final AppState state = store.state; + + if (!state.paymentTermState.isStale && !action.force) { + next(action); + return; + } + + if (state.isLoading) { + next(action); + return; + } + + final int updatedAt = (state.paymentTermState.lastUpdated / 1000).round(); + + store.dispatch(LoadPaymentTermsRequest()); + repository.loadList(state.credentials, updatedAt).then((data) { + store.dispatch(LoadPaymentTermsSuccess(data)); + + if (action.completer != null) { + action.completer.complete(null); + } + /* + if (state.productState.isStale) { + store.dispatch(LoadProducts()); + } + */ + }).catchError((Object error) { + print(error); + store.dispatch(LoadPaymentTermsFailure(error)); + if (action.completer != null) { + action.completer.completeError(error); + } + }); + + next(action); + }; +} diff --git a/lib/redux/payment_term/payment_term_reducer.dart b/lib/redux/payment_term/payment_term_reducer.dart new file mode 100644 index 000000000..bd403b01c --- /dev/null +++ b/lib/redux/payment_term/payment_term_reducer.dart @@ -0,0 +1,308 @@ +import 'package:invoiceninja_flutter/data/models/payment_term_model.dart'; +import 'package:redux/redux.dart'; +import 'package:built_collection/built_collection.dart'; +import 'package:invoiceninja_flutter/redux/app/app_actions.dart'; +import 'package:invoiceninja_flutter/redux/company/company_actions.dart'; +import 'package:invoiceninja_flutter/redux/ui/entity_ui_state.dart'; +import 'package:invoiceninja_flutter/redux/payment_term/payment_term_actions.dart'; +import 'package:invoiceninja_flutter/redux/ui/list_ui_state.dart'; +import 'package:invoiceninja_flutter/redux/payment_term/payment_term_state.dart'; + +EntityUIState paymentTermUIReducer(PaymentTermUIState state, dynamic action) { + return state.rebuild((b) => b + ..listUIState.replace(paymentTermListReducer(state.listUIState, action)) + ..editing.replace(editingReducer(state.editing, action)) + ..selectedId = selectedIdReducer(state.selectedId, action)); +} + +Reducer selectedIdReducer = combineReducers([ + TypedReducer( + (String selectedId, dynamic action) => action.paymentTermId), + TypedReducer( + (String selectedId, dynamic action) => action.paymentTerm.id), + TypedReducer((selectedId, action) => ''), +]); + +final editingReducer = combineReducers([ + TypedReducer(_updateEditing), + TypedReducer(_updateEditing), + TypedReducer( + (paymentTerms, action) { + return action.paymentTerms[0]; + }), + TypedReducer( + (paymentTerms, action) { + return action.paymentTerms[0]; + }), + TypedReducer( + (paymentTerms, action) { + return action.paymentTerms[0]; + }), + TypedReducer(_updateEditing), + TypedReducer((paymentTerm, action) { + return action.paymentTerm.rebuild((b) => b..isChanged = true); + }), + TypedReducer(_clearEditing), + TypedReducer(_clearEditing), +]); + +PaymentTermEntity _clearEditing(PaymentTermEntity paymentTerm, dynamic action) { + return PaymentTermEntity(); +} + +PaymentTermEntity _updateEditing( + PaymentTermEntity paymentTerm, dynamic action) { + return action.paymentTerm; +} + +final paymentTermListReducer = combineReducers([ + TypedReducer(_sortPaymentTerms), + TypedReducer( + _filterPaymentTermsByState), + TypedReducer(_filterPaymentTerms), + TypedReducer( + _filterPaymentTermsByCustom1), + TypedReducer( + _filterPaymentTermsByCustom2), + TypedReducer( + _filterPaymentTermsByClient), + TypedReducer(_startListMultiselect), + TypedReducer(_addToListMultiselect), + TypedReducer( + _removeFromListMultiselect), + TypedReducer(_clearListMultiselect), + TypedReducer( + (state, action) => state.rebuild((b) => b + ..filterEntityId = null + ..filterEntityType = null)), +]); + +ListUIState _filterPaymentTermsByClient( + ListUIState paymentTermListState, FilterPaymentTermsByEntity action) { + return paymentTermListState.rebuild((b) => b + ..filterEntityId = action.entityId + ..filterEntityType = action.entityType); +} + +ListUIState _filterPaymentTermsByCustom1( + ListUIState paymentTermListState, FilterPaymentTermsByCustom1 action) { + if (paymentTermListState.custom1Filters.contains(action.value)) { + return paymentTermListState + .rebuild((b) => b..custom1Filters.remove(action.value)); + } else { + return paymentTermListState + .rebuild((b) => b..custom1Filters.add(action.value)); + } +} + +ListUIState _filterPaymentTermsByCustom2( + ListUIState paymentTermListState, FilterPaymentTermsByCustom2 action) { + if (paymentTermListState.custom2Filters.contains(action.value)) { + return paymentTermListState + .rebuild((b) => b..custom2Filters.remove(action.value)); + } else { + return paymentTermListState + .rebuild((b) => b..custom2Filters.add(action.value)); + } +} + +ListUIState _filterPaymentTermsByState( + ListUIState paymentTermListState, FilterPaymentTermsByState action) { + if (paymentTermListState.stateFilters.contains(action.state)) { + return paymentTermListState + .rebuild((b) => b..stateFilters.remove(action.state)); + } else { + return paymentTermListState + .rebuild((b) => b..stateFilters.add(action.state)); + } +} + +ListUIState _filterPaymentTerms( + ListUIState paymentTermListState, FilterPaymentTerms action) { + return paymentTermListState.rebuild((b) => b + ..filter = action.filter + ..filterClearedAt = action.filter == null + ? DateTime.now().millisecondsSinceEpoch + : paymentTermListState.filterClearedAt); +} + +ListUIState _sortPaymentTerms( + ListUIState paymentTermListState, SortPaymentTerms action) { + return paymentTermListState.rebuild((b) => b + ..sortAscending = b.sortField != action.field || !b.sortAscending + ..sortField = action.field); +} + +ListUIState _startListMultiselect( + ListUIState productListState, StartPaymentTermMultiselect action) { + return productListState.rebuild((b) => b..selectedIds = ListBuilder()); +} + +ListUIState _addToListMultiselect( + ListUIState productListState, AddToPaymentTermMultiselect action) { + return productListState.rebuild((b) => b..selectedIds.add(action.entity.id)); +} + +ListUIState _removeFromListMultiselect( + ListUIState productListState, RemoveFromPaymentTermMultiselect action) { + return productListState + .rebuild((b) => b..selectedIds.remove(action.entity.id)); +} + +ListUIState _clearListMultiselect( + ListUIState productListState, ClearPaymentTermMultiselect action) { + return productListState.rebuild((b) => b..selectedIds = null); +} + +final paymentTermsReducer = combineReducers([ + TypedReducer(_updatePaymentTerm), + TypedReducer(_addPaymentTerm), + TypedReducer( + _setLoadedPaymentTerms), + TypedReducer(_setLoadedPaymentTerm), + TypedReducer( + _archivePaymentTermRequest), + TypedReducer( + _archivePaymentTermSuccess), + TypedReducer( + _archivePaymentTermFailure), + TypedReducer( + _deletePaymentTermRequest), + TypedReducer( + _deletePaymentTermSuccess), + TypedReducer( + _deletePaymentTermFailure), + TypedReducer( + _restorePaymentTermRequest), + TypedReducer( + _restorePaymentTermSuccess), + TypedReducer( + _restorePaymentTermFailure), +]); + +PaymentTermState _archivePaymentTermRequest( + PaymentTermState paymentTermState, ArchivePaymentTermsRequest action) { + final paymentTerms = + action.paymentTermIds.map((id) => paymentTermState.map[id]).toList(); + + for (int i = 0; i < paymentTerms.length; i++) { + paymentTerms[i] = paymentTerms[i] + .rebuild((b) => b..archivedAt = DateTime.now().millisecondsSinceEpoch); + } + return paymentTermState.rebuild((b) { + for (final paymentTerm in paymentTerms) { + b.map[paymentTerm.id] = paymentTerm; + } + }); +} + +PaymentTermState _archivePaymentTermSuccess( + PaymentTermState paymentTermState, ArchivePaymentTermsSuccess action) { + return paymentTermState.rebuild((b) { + for (final paymentTerm in action.paymentTerms) { + b.map[paymentTerm.id] = paymentTerm; + } + }); +} + +PaymentTermState _archivePaymentTermFailure( + PaymentTermState paymentTermState, ArchivePaymentTermsFailure action) { + return paymentTermState.rebuild((b) { + for (final paymentTerm in action.paymentTerms) { + b.map[paymentTerm.id] = paymentTerm; + } + }); +} + +PaymentTermState _deletePaymentTermRequest( + PaymentTermState paymentTermState, DeletePaymentTermsRequest action) { + final paymentTerms = + action.paymentTermIds.map((id) => paymentTermState.map[id]).toList(); + + for (int i = 0; i < paymentTerms.length; i++) { + paymentTerms[i] = paymentTerms[i].rebuild((b) => b + ..archivedAt = DateTime.now().millisecondsSinceEpoch + ..isDeleted = true); + } + return paymentTermState.rebuild((b) { + for (final paymentTerm in paymentTerms) { + b.map[paymentTerm.id] = paymentTerm; + } + }); +} + +PaymentTermState _deletePaymentTermSuccess( + PaymentTermState paymentTermState, DeletePaymentTermsSuccess action) { + return paymentTermState.rebuild((b) { + for (final paymentTerm in action.paymentTerms) { + b.map[paymentTerm.id] = paymentTerm; + } + }); +} + +PaymentTermState _deletePaymentTermFailure( + PaymentTermState paymentTermState, DeletePaymentTermsFailure action) { + return paymentTermState.rebuild((b) { + for (final paymentTerm in action.paymentTerms) { + b.map[paymentTerm.id] = paymentTerm; + } + }); +} + +PaymentTermState _restorePaymentTermRequest( + PaymentTermState paymentTermState, RestorePaymentTermsRequest action) { + final paymentTerms = + action.paymentTermIds.map((id) => paymentTermState.map[id]).toList(); + + for (int i = 0; i < paymentTerms.length; i++) { + paymentTerms[i] = paymentTerms[i].rebuild((b) => b + ..archivedAt = null + ..isDeleted = false); + } + return paymentTermState.rebuild((b) { + for (final paymentTerm in paymentTerms) { + b.map[paymentTerm.id] = paymentTerm; + } + }); +} + +PaymentTermState _restorePaymentTermSuccess( + PaymentTermState paymentTermState, RestorePaymentTermsSuccess action) { + return paymentTermState.rebuild((b) { + for (final paymentTerm in action.paymentTerms) { + b.map[paymentTerm.id] = paymentTerm; + } + }); +} + +PaymentTermState _restorePaymentTermFailure( + PaymentTermState paymentTermState, RestorePaymentTermsFailure action) { + return paymentTermState.rebuild((b) { + for (final paymentTerm in action.paymentTerms) { + b.map[paymentTerm.id] = paymentTerm; + } + }); +} + +PaymentTermState _addPaymentTerm( + PaymentTermState paymentTermState, AddPaymentTermSuccess action) { + return paymentTermState.rebuild((b) => b + ..map[action.paymentTerm.id] = action.paymentTerm + ..list.add(action.paymentTerm.id)); +} + +PaymentTermState _updatePaymentTerm( + PaymentTermState paymentTermState, SavePaymentTermSuccess action) { + return paymentTermState + .rebuild((b) => b..map[action.paymentTerm.id] = action.paymentTerm); +} + +PaymentTermState _setLoadedPaymentTerm( + PaymentTermState paymentTermState, LoadPaymentTermSuccess action) { + return paymentTermState + .rebuild((b) => b..map[action.paymentTerm.id] = action.paymentTerm); +} + +PaymentTermState _setLoadedPaymentTerms( + PaymentTermState paymentTermState, LoadPaymentTermsSuccess action) => + paymentTermState.loadPaymentTerms(action.paymentTerms); diff --git a/lib/redux/payment_term/payment_term_selectors.dart b/lib/redux/payment_term/payment_term_selectors.dart new file mode 100644 index 000000000..4c613ad29 --- /dev/null +++ b/lib/redux/payment_term/payment_term_selectors.dart @@ -0,0 +1,68 @@ +import 'package:invoiceninja_flutter/data/models/payment_term_model.dart'; +import 'package:memoize/memoize.dart'; +import 'package:built_collection/built_collection.dart'; +import 'package:invoiceninja_flutter/redux/ui/list_ui_state.dart'; + +var memoizedDropdownPaymentTermList = memo3((BuiltMap + paymentTermMap, + BuiltList paymentTermList, + String clientId) => + dropdownPaymentTermsSelector(paymentTermMap, paymentTermList, clientId)); + +List dropdownPaymentTermsSelector( + BuiltMap paymentTermMap, + BuiltList paymentTermList, + String clientId) { + final list = paymentTermList.where((paymentTermId) { + final paymentTerm = paymentTermMap[paymentTermId]; + /* + if (clientId != null && clientId > 0 && paymentTerm.clientId != clientId) { + return false; + } + */ + return paymentTerm.isActive; + }).toList(); + + list.sort((paymentTermAId, paymentTermBId) { + final paymentTermA = paymentTermMap[paymentTermAId]; + final paymentTermB = paymentTermMap[paymentTermBId]; + return paymentTermA.compareTo(paymentTermB, PaymentTermFields.name, true); + }); + + return list; +} + +var memoizedFilteredPaymentTermList = memo3( + (BuiltMap paymentTermMap, + BuiltList paymentTermList, + ListUIState paymentTermListState) => + filteredPaymentTermsSelector( + paymentTermMap, paymentTermList, paymentTermListState)); + +List filteredPaymentTermsSelector( + BuiltMap paymentTermMap, + BuiltList paymentTermList, + ListUIState paymentTermListState) { + final list = paymentTermList.where((paymentTermId) { + final paymentTerm = paymentTermMap[paymentTermId]; + if (!paymentTerm.matchesStates(paymentTermListState.stateFilters)) { + return false; + } + return paymentTerm.matchesFilter(paymentTermListState.filter); + }).toList(); + + list.sort((paymentTermAId, paymentTermBId) { + final paymentTermA = paymentTermMap[paymentTermAId]; + final paymentTermB = paymentTermMap[paymentTermBId]; + return paymentTermA.compareTo(paymentTermB, paymentTermListState.sortField, + paymentTermListState.sortAscending); + }); + + return list; +} + +bool hasPaymentTermChanges(PaymentTermEntity paymentTerm, + BuiltMap paymentTermMap) => + paymentTerm.isNew + ? paymentTerm.isChanged + : paymentTerm != paymentTermMap[paymentTerm.id]; diff --git a/lib/redux/payment_term/payment_term_state.dart b/lib/redux/payment_term/payment_term_state.dart new file mode 100644 index 000000000..a297435f5 --- /dev/null +++ b/lib/redux/payment_term/payment_term_state.dart @@ -0,0 +1,89 @@ +import 'dart:async'; +import 'package:built_value/built_value.dart'; +import 'package:built_value/serializer.dart'; +import 'package:built_collection/built_collection.dart'; +import 'package:invoiceninja_flutter/constants.dart'; +import 'package:invoiceninja_flutter/data/models/payment_term_model.dart'; +import 'package:invoiceninja_flutter/redux/ui/entity_ui_state.dart'; +import 'package:invoiceninja_flutter/redux/ui/list_ui_state.dart'; +import 'package:invoiceninja_flutter/data/models/models.dart'; + +part 'payment_term_state.g.dart'; + +abstract class PaymentTermState + implements Built { + factory PaymentTermState() { + return _$PaymentTermState._( + lastUpdated: 0, + map: BuiltMap(), + list: BuiltList(), + ); + } + PaymentTermState._(); + + @override + @memoized + int get hashCode; + + @nullable + int get lastUpdated; + + BuiltMap get map; + BuiltList get list; + + bool get isStale { + if (!isLoaded) { + return true; + } + + return DateTime.now().millisecondsSinceEpoch - lastUpdated > + kMillisecondsToRefreshData; + } + + bool get isLoaded => lastUpdated != null && lastUpdated > 0; + + PaymentTermState loadPaymentTerms(BuiltList clients) { + final map = Map.fromIterable( + clients, + key: (dynamic item) => item.id, + value: (dynamic item) => item, + ); + + return rebuild((b) => b + ..lastUpdated = DateTime.now().millisecondsSinceEpoch + ..map.addAll(map) + ..list.replace((map.keys.toList() + list.toList()).toSet().toList())); + } + + static Serializer get serializer => + _$paymentTermStateSerializer; +} + +abstract class PaymentTermUIState extends Object + with EntityUIState + implements Built { + factory PaymentTermUIState() { + return _$PaymentTermUIState._( + listUIState: ListUIState(PaymentTermFields.name), + editing: PaymentTermEntity(), + selectedId: '', + ); + } + PaymentTermUIState._(); + + @override + @memoized + int get hashCode; + + @nullable + PaymentTermEntity get editing; + + @override + bool get isCreatingNew => editing.isNew; + + @override + String get editingId => editing.id; + + static Serializer get serializer => + _$paymentTermUIStateSerializer; +} diff --git a/lib/redux/payment_term/payment_term_state.g.dart b/lib/redux/payment_term/payment_term_state.g.dart new file mode 100644 index 000000000..fddeb3c2f --- /dev/null +++ b/lib/redux/payment_term/payment_term_state.g.dart @@ -0,0 +1,421 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'payment_term_state.dart'; + +// ************************************************************************** +// BuiltValueGenerator +// ************************************************************************** + +Serializer _$paymentTermStateSerializer = + new _$PaymentTermStateSerializer(); +Serializer _$paymentTermUIStateSerializer = + new _$PaymentTermUIStateSerializer(); + +class _$PaymentTermStateSerializer + implements StructuredSerializer { + @override + final Iterable types = const [PaymentTermState, _$PaymentTermState]; + @override + final String wireName = 'PaymentTermState'; + + @override + Iterable serialize(Serializers serializers, PaymentTermState object, + {FullType specifiedType = FullType.unspecified}) { + final result = [ + 'map', + serializers.serialize(object.map, + specifiedType: const FullType(BuiltMap, const [ + const FullType(String), + const FullType(PaymentTermEntity) + ])), + 'list', + serializers.serialize(object.list, + specifiedType: + const FullType(BuiltList, const [const FullType(String)])), + ]; + if (object.lastUpdated != null) { + result + ..add('lastUpdated') + ..add(serializers.serialize(object.lastUpdated, + specifiedType: const FullType(int))); + } + return result; + } + + @override + PaymentTermState deserialize( + Serializers serializers, Iterable serialized, + {FullType specifiedType = FullType.unspecified}) { + final result = new PaymentTermStateBuilder(); + + final iterator = serialized.iterator; + while (iterator.moveNext()) { + final key = iterator.current as String; + iterator.moveNext(); + final dynamic value = iterator.current; + switch (key) { + case 'lastUpdated': + result.lastUpdated = serializers.deserialize(value, + specifiedType: const FullType(int)) as int; + break; + case 'map': + result.map.replace(serializers.deserialize(value, + specifiedType: const FullType(BuiltMap, const [ + const FullType(String), + const FullType(PaymentTermEntity) + ]))); + break; + case 'list': + result.list.replace(serializers.deserialize(value, + specifiedType: + const FullType(BuiltList, const [const FullType(String)])) + as BuiltList); + break; + } + } + + return result.build(); + } +} + +class _$PaymentTermUIStateSerializer + implements StructuredSerializer { + @override + final Iterable types = const [PaymentTermUIState, _$PaymentTermUIState]; + @override + final String wireName = 'PaymentTermUIState'; + + @override + Iterable serialize(Serializers serializers, PaymentTermUIState object, + {FullType specifiedType = FullType.unspecified}) { + final result = [ + 'listUIState', + serializers.serialize(object.listUIState, + specifiedType: const FullType(ListUIState)), + ]; + if (object.editing != null) { + result + ..add('editing') + ..add(serializers.serialize(object.editing, + specifiedType: const FullType(PaymentTermEntity))); + } + if (object.selectedId != null) { + result + ..add('selectedId') + ..add(serializers.serialize(object.selectedId, + specifiedType: const FullType(String))); + } + return result; + } + + @override + PaymentTermUIState deserialize( + Serializers serializers, Iterable serialized, + {FullType specifiedType = FullType.unspecified}) { + final result = new PaymentTermUIStateBuilder(); + + final iterator = serialized.iterator; + while (iterator.moveNext()) { + final key = iterator.current as String; + iterator.moveNext(); + final dynamic value = iterator.current; + switch (key) { + case 'editing': + result.editing.replace(serializers.deserialize(value, + specifiedType: const FullType(PaymentTermEntity)) + as PaymentTermEntity); + break; + case 'listUIState': + result.listUIState.replace(serializers.deserialize(value, + specifiedType: const FullType(ListUIState)) as ListUIState); + break; + case 'selectedId': + result.selectedId = serializers.deserialize(value, + specifiedType: const FullType(String)) as String; + break; + } + } + + return result.build(); + } +} + +class _$PaymentTermState extends PaymentTermState { + @override + final int lastUpdated; + @override + final BuiltMap map; + @override + final BuiltList list; + + factory _$PaymentTermState( + [void Function(PaymentTermStateBuilder) updates]) => + (new PaymentTermStateBuilder()..update(updates)).build(); + + _$PaymentTermState._({this.lastUpdated, this.map, this.list}) : super._() { + if (map == null) { + throw new BuiltValueNullFieldError('PaymentTermState', 'map'); + } + if (list == null) { + throw new BuiltValueNullFieldError('PaymentTermState', 'list'); + } + } + + @override + PaymentTermState rebuild(void Function(PaymentTermStateBuilder) updates) => + (toBuilder()..update(updates)).build(); + + @override + PaymentTermStateBuilder toBuilder() => + new PaymentTermStateBuilder()..replace(this); + + @override + bool operator ==(Object other) { + if (identical(other, this)) return true; + return other is PaymentTermState && + lastUpdated == other.lastUpdated && + map == other.map && + list == other.list; + } + + int __hashCode; + @override + int get hashCode { + return __hashCode ??= $jf( + $jc($jc($jc(0, lastUpdated.hashCode), map.hashCode), list.hashCode)); + } + + @override + String toString() { + return (newBuiltValueToStringHelper('PaymentTermState') + ..add('lastUpdated', lastUpdated) + ..add('map', map) + ..add('list', list)) + .toString(); + } +} + +class PaymentTermStateBuilder + implements Builder { + _$PaymentTermState _$v; + + int _lastUpdated; + int get lastUpdated => _$this._lastUpdated; + set lastUpdated(int lastUpdated) => _$this._lastUpdated = lastUpdated; + + MapBuilder _map; + MapBuilder get map => + _$this._map ??= new MapBuilder(); + set map(MapBuilder map) => _$this._map = map; + + ListBuilder _list; + ListBuilder get list => _$this._list ??= new ListBuilder(); + set list(ListBuilder list) => _$this._list = list; + + PaymentTermStateBuilder(); + + PaymentTermStateBuilder get _$this { + if (_$v != null) { + _lastUpdated = _$v.lastUpdated; + _map = _$v.map?.toBuilder(); + _list = _$v.list?.toBuilder(); + _$v = null; + } + return this; + } + + @override + void replace(PaymentTermState other) { + if (other == null) { + throw new ArgumentError.notNull('other'); + } + _$v = other as _$PaymentTermState; + } + + @override + void update(void Function(PaymentTermStateBuilder) updates) { + if (updates != null) updates(this); + } + + @override + _$PaymentTermState build() { + _$PaymentTermState _$result; + try { + _$result = _$v ?? + new _$PaymentTermState._( + lastUpdated: lastUpdated, map: map.build(), list: list.build()); + } catch (_) { + String _$failedField; + try { + _$failedField = 'map'; + map.build(); + _$failedField = 'list'; + list.build(); + } catch (e) { + throw new BuiltValueNestedFieldError( + 'PaymentTermState', _$failedField, e.toString()); + } + rethrow; + } + replace(_$result); + return _$result; + } +} + +class _$PaymentTermUIState extends PaymentTermUIState { + @override + final PaymentTermEntity editing; + @override + final ListUIState listUIState; + @override + final String selectedId; + @override + final Completer saveCompleter; + @override + final Completer cancelCompleter; + + factory _$PaymentTermUIState( + [void Function(PaymentTermUIStateBuilder) updates]) => + (new PaymentTermUIStateBuilder()..update(updates)).build(); + + _$PaymentTermUIState._( + {this.editing, + this.listUIState, + this.selectedId, + this.saveCompleter, + this.cancelCompleter}) + : super._() { + if (listUIState == null) { + throw new BuiltValueNullFieldError('PaymentTermUIState', 'listUIState'); + } + } + + @override + PaymentTermUIState rebuild( + void Function(PaymentTermUIStateBuilder) updates) => + (toBuilder()..update(updates)).build(); + + @override + PaymentTermUIStateBuilder toBuilder() => + new PaymentTermUIStateBuilder()..replace(this); + + @override + bool operator ==(Object other) { + if (identical(other, this)) return true; + return other is PaymentTermUIState && + editing == other.editing && + listUIState == other.listUIState && + selectedId == other.selectedId && + saveCompleter == other.saveCompleter && + cancelCompleter == other.cancelCompleter; + } + + int __hashCode; + @override + int get hashCode { + return __hashCode ??= $jf($jc( + $jc( + $jc($jc($jc(0, editing.hashCode), listUIState.hashCode), + selectedId.hashCode), + saveCompleter.hashCode), + cancelCompleter.hashCode)); + } + + @override + String toString() { + return (newBuiltValueToStringHelper('PaymentTermUIState') + ..add('editing', editing) + ..add('listUIState', listUIState) + ..add('selectedId', selectedId) + ..add('saveCompleter', saveCompleter) + ..add('cancelCompleter', cancelCompleter)) + .toString(); + } +} + +class PaymentTermUIStateBuilder + implements Builder { + _$PaymentTermUIState _$v; + + PaymentTermEntityBuilder _editing; + PaymentTermEntityBuilder get editing => + _$this._editing ??= new PaymentTermEntityBuilder(); + set editing(PaymentTermEntityBuilder editing) => _$this._editing = editing; + + ListUIStateBuilder _listUIState; + ListUIStateBuilder get listUIState => + _$this._listUIState ??= new ListUIStateBuilder(); + set listUIState(ListUIStateBuilder listUIState) => + _$this._listUIState = listUIState; + + String _selectedId; + String get selectedId => _$this._selectedId; + set selectedId(String selectedId) => _$this._selectedId = selectedId; + + Completer _saveCompleter; + Completer get saveCompleter => _$this._saveCompleter; + set saveCompleter(Completer saveCompleter) => + _$this._saveCompleter = saveCompleter; + + Completer _cancelCompleter; + Completer get cancelCompleter => _$this._cancelCompleter; + set cancelCompleter(Completer cancelCompleter) => + _$this._cancelCompleter = cancelCompleter; + + PaymentTermUIStateBuilder(); + + PaymentTermUIStateBuilder get _$this { + if (_$v != null) { + _editing = _$v.editing?.toBuilder(); + _listUIState = _$v.listUIState?.toBuilder(); + _selectedId = _$v.selectedId; + _saveCompleter = _$v.saveCompleter; + _cancelCompleter = _$v.cancelCompleter; + _$v = null; + } + return this; + } + + @override + void replace(PaymentTermUIState other) { + if (other == null) { + throw new ArgumentError.notNull('other'); + } + _$v = other as _$PaymentTermUIState; + } + + @override + void update(void Function(PaymentTermUIStateBuilder) updates) { + if (updates != null) updates(this); + } + + @override + _$PaymentTermUIState build() { + _$PaymentTermUIState _$result; + try { + _$result = _$v ?? + new _$PaymentTermUIState._( + editing: _editing?.build(), + listUIState: listUIState.build(), + selectedId: selectedId, + saveCompleter: saveCompleter, + cancelCompleter: cancelCompleter); + } catch (_) { + String _$failedField; + try { + _$failedField = 'editing'; + _editing?.build(); + _$failedField = 'listUIState'; + listUIState.build(); + } catch (e) { + throw new BuiltValueNestedFieldError( + 'PaymentTermUIState', _$failedField, e.toString()); + } + rethrow; + } + replace(_$result); + return _$result; + } +} + +// ignore_for_file: always_put_control_body_on_new_line,always_specify_types,annotate_overrides,avoid_annotating_with_dynamic,avoid_as,avoid_catches_without_on_clauses,avoid_returning_this,lines_longer_than_80_chars,omit_local_variable_types,prefer_expression_function_bodies,sort_constructors_first,test_types_in_equals,unnecessary_const,unnecessary_new diff --git a/lib/redux/ui/pref_reducer.dart b/lib/redux/ui/pref_reducer.dart index 2dbc087ff..5aa456cb6 100644 --- a/lib/redux/ui/pref_reducer.dart +++ b/lib/redux/ui/pref_reducer.dart @@ -24,6 +24,8 @@ import 'package:invoiceninja_flutter/redux/user/user_actions.dart'; import 'package:invoiceninja_flutter/redux/vendor/vendor_actions.dart'; // STARTER: import - do not remove comment +import 'package:invoiceninja_flutter/redux/payment_term/payment_term_actions.dart'; + import 'package:invoiceninja_flutter/redux/design/design_actions.dart'; import 'package:invoiceninja_flutter/redux/credit/credit_actions.dart'; @@ -405,6 +407,17 @@ Reducer> historyReducer = combineReducers([ _addToHistory(historyList, HistoryRecord(id: action.group.id, entityType: EntityType.group))), // STARTER: history - do not remove comment + TypedReducer, ViewPaymentTerm>( + (historyList, action) => _addToHistory( + historyList, + HistoryRecord( + id: action.paymentTermId, entityType: EntityType.paymentTerm))), + TypedReducer, EditPaymentTerm>( + (historyList, action) => _addToHistory( + historyList, + HistoryRecord( + id: action.paymentTerm.id, entityType: EntityType.paymentTerm))), + TypedReducer, EditDesign>((historyList, action) => _addToHistory(historyList, HistoryRecord(id: action.design.id, entityType: EntityType.design))), diff --git a/lib/redux/ui/ui_reducer.dart b/lib/redux/ui/ui_reducer.dart index 687bca82d..0906b0f6c 100644 --- a/lib/redux/ui/ui_reducer.dart +++ b/lib/redux/ui/ui_reducer.dart @@ -27,6 +27,8 @@ import 'package:invoiceninja_flutter/redux/task/task_reducer.dart'; import 'package:invoiceninja_flutter/redux/vendor/vendor_reducer.dart'; // STARTER: import - do not remove comment +import 'package:invoiceninja_flutter/redux/payment_term/payment_term_reducer.dart'; + import 'package:invoiceninja_flutter/redux/design/design_reducer.dart'; import 'package:invoiceninja_flutter/redux/credit/credit_reducer.dart'; @@ -70,6 +72,8 @@ UIState uiReducer(UIState state, dynamic action) { .replace(dashboardUIReducer(state.dashboardUIState, action)) ..reportsUIState.replace(reportsUIReducer(state.reportsUIState, action)) // STARTER: reducer - do not remove comment + ..paymentTermUIState + .replace(paymentTermUIReducer(state.paymentTermUIState, action)) ..designUIState.replace(designUIReducer(state.designUIState, action)) ..creditUIState.replace(creditUIReducer(state.creditUIState, action)) ..userUIState.replace(userUIReducer(state.userUIState, action)) diff --git a/lib/redux/ui/ui_state.dart b/lib/redux/ui/ui_state.dart index 0a3bfb78a..5e601e7c8 100644 --- a/lib/redux/ui/ui_state.dart +++ b/lib/redux/ui/ui_state.dart @@ -17,6 +17,8 @@ import 'package:invoiceninja_flutter/redux/task/task_state.dart'; import 'package:invoiceninja_flutter/redux/vendor/vendor_state.dart'; // STARTER: import - do not remove comment +import 'package:invoiceninja_flutter/redux/payment_term/payment_term_state.dart'; + import 'package:invoiceninja_flutter/redux/design/design_state.dart'; import 'package:invoiceninja_flutter/redux/credit/credit_state.dart'; @@ -40,6 +42,8 @@ abstract class UIState implements Built { clientUIState: ClientUIState(), invoiceUIState: InvoiceUIState(), // STARTER: constructor - do not remove comment + paymentTermUIState: PaymentTermUIState(), + designUIState: DesignUIState(), creditUIState: CreditUIState(), userUIState: UserUIState(), @@ -90,6 +94,8 @@ abstract class UIState implements Built { InvoiceUIState get invoiceUIState; // STARTER: properties - do not remove comment + PaymentTermUIState get paymentTermUIState; + DesignUIState get designUIState; CreditUIState get creditUIState; diff --git a/lib/redux/ui/ui_state.g.dart b/lib/redux/ui/ui_state.g.dart index d9aebc1bc..2dfbb07c2 100644 --- a/lib/redux/ui/ui_state.g.dart +++ b/lib/redux/ui/ui_state.g.dart @@ -42,6 +42,9 @@ class _$UIStateSerializer implements StructuredSerializer { 'invoiceUIState', serializers.serialize(object.invoiceUIState, specifiedType: const FullType(InvoiceUIState)), + 'paymentTermUIState', + serializers.serialize(object.paymentTermUIState, + specifiedType: const FullType(PaymentTermUIState)), 'designUIState', serializers.serialize(object.designUIState, specifiedType: const FullType(DesignUIState)), @@ -165,6 +168,11 @@ class _$UIStateSerializer implements StructuredSerializer { result.invoiceUIState.replace(serializers.deserialize(value, specifiedType: const FullType(InvoiceUIState)) as InvoiceUIState); break; + case 'paymentTermUIState': + result.paymentTermUIState.replace(serializers.deserialize(value, + specifiedType: const FullType(PaymentTermUIState)) + as PaymentTermUIState); + break; case 'designUIState': result.designUIState.replace(serializers.deserialize(value, specifiedType: const FullType(DesignUIState)) as DesignUIState); @@ -259,6 +267,8 @@ class _$UIState extends UIState { @override final InvoiceUIState invoiceUIState; @override + final PaymentTermUIState paymentTermUIState; + @override final DesignUIState designUIState; @override final CreditUIState creditUIState; @@ -304,6 +314,7 @@ class _$UIState extends UIState { this.productUIState, this.clientUIState, this.invoiceUIState, + this.paymentTermUIState, this.designUIState, this.creditUIState, this.userUIState, @@ -344,6 +355,9 @@ class _$UIState extends UIState { if (invoiceUIState == null) { throw new BuiltValueNullFieldError('UIState', 'invoiceUIState'); } + if (paymentTermUIState == null) { + throw new BuiltValueNullFieldError('UIState', 'paymentTermUIState'); + } if (designUIState == null) { throw new BuiltValueNullFieldError('UIState', 'designUIState'); } @@ -413,6 +427,7 @@ class _$UIState extends UIState { productUIState == other.productUIState && clientUIState == other.clientUIState && invoiceUIState == other.invoiceUIState && + paymentTermUIState == other.paymentTermUIState && designUIState == other.designUIState && creditUIState == other.creditUIState && userUIState == other.userUIState && @@ -451,11 +466,11 @@ class _$UIState extends UIState { $jc( $jc( $jc( - $jc($jc($jc($jc($jc($jc($jc($jc(0, selectedCompanyIndex.hashCode), currentRoute.hashCode), previousRoute.hashCode), filterEntityId.hashCode), filterEntityType.hashCode), filter.hashCode), filterClearedAt.hashCode), - dashboardUIState.hashCode), - productUIState.hashCode), - clientUIState.hashCode), - invoiceUIState.hashCode), + $jc($jc($jc($jc($jc($jc($jc($jc($jc(0, selectedCompanyIndex.hashCode), currentRoute.hashCode), previousRoute.hashCode), filterEntityId.hashCode), filterEntityType.hashCode), filter.hashCode), filterClearedAt.hashCode), dashboardUIState.hashCode), + productUIState.hashCode), + clientUIState.hashCode), + invoiceUIState.hashCode), + paymentTermUIState.hashCode), designUIState.hashCode), creditUIState.hashCode), userUIState.hashCode), @@ -487,6 +502,7 @@ class _$UIState extends UIState { ..add('productUIState', productUIState) ..add('clientUIState', clientUIState) ..add('invoiceUIState', invoiceUIState) + ..add('paymentTermUIState', paymentTermUIState) ..add('designUIState', designUIState) ..add('creditUIState', creditUIState) ..add('userUIState', userUIState) @@ -566,6 +582,12 @@ class UIStateBuilder implements Builder { set invoiceUIState(InvoiceUIStateBuilder invoiceUIState) => _$this._invoiceUIState = invoiceUIState; + PaymentTermUIStateBuilder _paymentTermUIState; + PaymentTermUIStateBuilder get paymentTermUIState => + _$this._paymentTermUIState ??= new PaymentTermUIStateBuilder(); + set paymentTermUIState(PaymentTermUIStateBuilder paymentTermUIState) => + _$this._paymentTermUIState = paymentTermUIState; + DesignUIStateBuilder _designUIState; DesignUIStateBuilder get designUIState => _$this._designUIState ??= new DesignUIStateBuilder(); @@ -672,6 +694,7 @@ class UIStateBuilder implements Builder { _productUIState = _$v.productUIState?.toBuilder(); _clientUIState = _$v.clientUIState?.toBuilder(); _invoiceUIState = _$v.invoiceUIState?.toBuilder(); + _paymentTermUIState = _$v.paymentTermUIState?.toBuilder(); _designUIState = _$v.designUIState?.toBuilder(); _creditUIState = _$v.creditUIState?.toBuilder(); _userUIState = _$v.userUIState?.toBuilder(); @@ -722,6 +745,7 @@ class UIStateBuilder implements Builder { productUIState: productUIState.build(), clientUIState: clientUIState.build(), invoiceUIState: invoiceUIState.build(), + paymentTermUIState: paymentTermUIState.build(), designUIState: designUIState.build(), creditUIState: creditUIState.build(), userUIState: userUIState.build(), @@ -748,6 +772,8 @@ class UIStateBuilder implements Builder { clientUIState.build(); _$failedField = 'invoiceUIState'; invoiceUIState.build(); + _$failedField = 'paymentTermUIState'; + paymentTermUIState.build(); _$failedField = 'designUIState'; designUIState.build(); _$failedField = 'creditUIState'; diff --git a/lib/redux/user/user_selectors.dart b/lib/redux/user/user_selectors.dart index 86a42510a..2762169ba 100644 --- a/lib/redux/user/user_selectors.dart +++ b/lib/redux/user/user_selectors.dart @@ -77,7 +77,8 @@ List gmailUserList(BuiltMap userMap) { return userList(userMap).where((userId) { final user = (userMap[userId] ?? UserEntity) as UserEntity; - return user.isActive && user.oauthProvider == UserEntity.OAUTH_PROVIDER_GOOGLE; + return user.isActive && + user.oauthProvider == UserEntity.OAUTH_PROVIDER_GOOGLE; }).toList(); } diff --git a/lib/ui/app/app_bottom_bar.dart b/lib/ui/app/app_bottom_bar.dart index 8065838c6..6fb672a84 100644 --- a/lib/ui/app/app_bottom_bar.dart +++ b/lib/ui/app/app_bottom_bar.dart @@ -371,7 +371,9 @@ class _AppBottomBarState extends State { tooltip: localization.filter, icon: Icon(Icons.filter_list), onPressed: _showFilterStateSheet, - color: store.state.getListState(widget.entityType).hasStateFilters + color: store.state + .getListState(widget.entityType) + .hasStateFilters ? Theme.of(context).accentColor : null, ), @@ -380,10 +382,11 @@ class _AppBottomBarState extends State { tooltip: localization.filter, icon: Icon(Icons.filter), onPressed: _showFilterStatusSheet, - color: - store.state.getListState(widget.entityType).hasStatusFilters - ? Theme.of(context).accentColor - : null, + color: store.state + .getListState(widget.entityType) + .hasStatusFilters + ? Theme.of(context).accentColor + : null, ), if (widget.customValues1.isNotEmpty) IconButton( diff --git a/lib/ui/app/list_scaffold.dart b/lib/ui/app/list_scaffold.dart index 253499e10..3f06f7fde 100644 --- a/lib/ui/app/list_scaffold.dart +++ b/lib/ui/app/list_scaffold.dart @@ -125,8 +125,8 @@ class ListScaffold extends StatelessWidget { state.prefState.isHistoryFloated) { Scaffold.of(context).openEndDrawer(); } else { - store.dispatch( - UserPreferencesChanged(sidebar: AppSidebar.history)); + store.dispatch(UserPreferencesChanged( + sidebar: AppSidebar.history)); } }, ), diff --git a/lib/ui/app/main_screen.dart b/lib/ui/app/main_screen.dart index c1d06c2c9..c2ab8d36e 100644 --- a/lib/ui/app/main_screen.dart +++ b/lib/ui/app/main_screen.dart @@ -10,7 +10,6 @@ import 'package:invoiceninja_flutter/redux/reports/reports_actions.dart'; import 'package:invoiceninja_flutter/redux/settings/settings_actions.dart'; import 'package:invoiceninja_flutter/redux/ui/pref_state.dart'; import 'package:invoiceninja_flutter/ui/app/app_builder.dart'; -import 'package:invoiceninja_flutter/ui/app/forms/app_dropdown_button.dart'; import 'package:invoiceninja_flutter/ui/app/history_drawer_vm.dart'; import 'package:invoiceninja_flutter/ui/app/icon_text.dart'; import 'package:invoiceninja_flutter/ui/app/menu_drawer_vm.dart'; diff --git a/lib/ui/app/view_scaffold.dart b/lib/ui/app/view_scaffold.dart index 7d35dff99..b79ccb63f 100644 --- a/lib/ui/app/view_scaffold.dart +++ b/lib/ui/app/view_scaffold.dart @@ -18,7 +18,7 @@ class ViewScaffold extends StatelessWidget { this.floatingActionButton, this.appBarBottom, this.isSettings = false, - @required this.isFilter, + this.isFilter = false, this.onBackPressed, }); diff --git a/lib/ui/client/edit/client_edit_settings.dart b/lib/ui/client/edit/client_edit_settings.dart index 1ea88232d..245d2231a 100644 --- a/lib/ui/client/edit/client_edit_settings.dart +++ b/lib/ui/client/edit/client_edit_settings.dart @@ -1,8 +1,8 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:invoiceninja_flutter/constants.dart'; -import 'package:invoiceninja_flutter/data/models/company_model.dart'; import 'package:invoiceninja_flutter/data/models/entities.dart'; +import 'package:invoiceninja_flutter/data/models/payment_term_model.dart'; import 'package:invoiceninja_flutter/ui/app/entity_dropdown.dart'; import 'package:invoiceninja_flutter/ui/app/forms/decorated_form_field.dart'; import 'package:invoiceninja_flutter/ui/client/edit/client_edit_vm.dart'; diff --git a/lib/ui/payment_term/edit/payment_term_edit.dart b/lib/ui/payment_term/edit/payment_term_edit.dart new file mode 100644 index 000000000..78bb5efa5 --- /dev/null +++ b/lib/ui/payment_term/edit/payment_term_edit.dart @@ -0,0 +1,106 @@ +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; +import 'package:invoiceninja_flutter/ui/app/edit_scaffold.dart'; +import 'package:invoiceninja_flutter/ui/app/form_card.dart'; +import 'package:invoiceninja_flutter/ui/payment_term/edit/payment_term_edit_vm.dart'; +import 'package:invoiceninja_flutter/utils/localization.dart'; +import 'package:invoiceninja_flutter/utils/completers.dart'; + +class PaymentTermEdit extends StatefulWidget { + const PaymentTermEdit({ + Key key, + @required this.viewModel, + }) : super(key: key); + + final PaymentTermEditVM viewModel; + + @override + _PaymentTermEditState createState() => _PaymentTermEditState(); +} + +class _PaymentTermEditState extends State { + static final GlobalKey _formKey = + GlobalKey(debugLabel: '_paymentTermEdit'); + final _debouncer = Debouncer(); + + // STARTER: controllers - do not remove comment + + List _controllers = []; + + @override + void didChangeDependencies() { + _controllers = [ + // STARTER: array - do not remove comment + ]; + + _controllers.forEach((controller) => controller.removeListener(_onChanged)); + + final paymentTerm = widget.viewModel.paymentTerm; + // STARTER: read value - do not remove comment + + _controllers.forEach((controller) => controller.addListener(_onChanged)); + + super.didChangeDependencies(); + } + + @override + void dispose() { + _controllers.forEach((controller) { + controller.removeListener(_onChanged); + controller.dispose(); + }); + + super.dispose(); + } + + void _onChanged() { + _debouncer.run(() { + final paymentTerm = widget.viewModel.paymentTerm.rebuild((b) => b + // STARTER: set value - do not remove comment + ); + if (paymentTerm != widget.viewModel.paymentTerm) { + widget.viewModel.onChanged(paymentTerm); + } + }); + } + + @override + Widget build(BuildContext context) { + final viewModel = widget.viewModel; + final localization = AppLocalization.of(context); + final paymentTerm = viewModel.paymentTerm; + + return EditScaffold( + title: localization.editPaymentTerm, + onCancelPressed: (context) => viewModel.onCancelPressed(context), + onSavePressed: (context) { + final bool isValid = _formKey.currentState.validate(); + + /* + setState(() { + _autoValidate = !isValid; + }); + */ + + if (!isValid) { + return; + } + + viewModel.onSavePressed(context); + }, + body: Form( + key: _formKey, + child: Builder(builder: (BuildContext context) { + return ListView( + children: [ + FormCard( + children: [ + // STARTER: widgets - do not remove comment + ], + ), + ], + ); + })), + ); + } +} diff --git a/lib/ui/payment_term/edit/payment_term_edit_vm.dart b/lib/ui/payment_term/edit/payment_term_edit_vm.dart new file mode 100644 index 000000000..543ead5fa --- /dev/null +++ b/lib/ui/payment_term/edit/payment_term_edit_vm.dart @@ -0,0 +1,106 @@ +import 'dart:async'; +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_redux/flutter_redux.dart'; +import 'package:invoiceninja_flutter/redux/app/app_actions.dart'; +import 'package:invoiceninja_flutter/redux/ui/ui_actions.dart'; +import 'package:invoiceninja_flutter/ui/payment_term/payment_term_screen.dart'; +import 'package:invoiceninja_flutter/utils/platforms.dart'; +import 'package:redux/redux.dart'; +import 'package:invoiceninja_flutter/data/models/models.dart'; +import 'package:invoiceninja_flutter/ui/app/dialogs/error_dialog.dart'; +import 'package:invoiceninja_flutter/ui/payment_term/view/payment_term_view_vm.dart'; +import 'package:invoiceninja_flutter/redux/payment_term/payment_term_actions.dart'; +import 'package:invoiceninja_flutter/data/models/payment_term_model.dart'; +import 'package:invoiceninja_flutter/ui/payment_term/edit/payment_term_edit.dart'; +import 'package:invoiceninja_flutter/redux/app/app_state.dart'; + +class PaymentTermEditScreen extends StatelessWidget { + const PaymentTermEditScreen({Key key}) : super(key: key); + static const String route = '/payment_term/edit'; + + @override + Widget build(BuildContext context) { + return StoreConnector( + converter: (Store store) { + return PaymentTermEditVM.fromStore(store); + }, + builder: (context, viewModel) { + return PaymentTermEdit( + viewModel: viewModel, + key: ValueKey(viewModel.paymentTerm.id), + ); + }, + ); + } +} + +class PaymentTermEditVM { + PaymentTermEditVM({ + @required this.state, + @required this.paymentTerm, + @required this.company, + @required this.onChanged, + @required this.isSaving, + @required this.origPaymentTerm, + @required this.onSavePressed, + @required this.onCancelPressed, + @required this.isLoading, + }); + + factory PaymentTermEditVM.fromStore(Store store) { + final state = store.state; + final paymentTerm = state.paymentTermUIState.editing; + + return PaymentTermEditVM( + state: state, + isLoading: state.isLoading, + isSaving: state.isSaving, + origPaymentTerm: state.paymentTermState.map[paymentTerm.id], + paymentTerm: paymentTerm, + company: state.company, + onChanged: (PaymentTermEntity paymentTerm) { + store.dispatch(UpdatePaymentTerm(paymentTerm)); + }, + onCancelPressed: (BuildContext context) { + createEntity( + context: context, entity: PaymentTermEntity(), force: true); + }, + onSavePressed: (BuildContext context) { + final Completer completer = + new Completer(); + store.dispatch(SavePaymentTermRequest( + completer: completer, paymentTerm: paymentTerm)); + return completer.future.then((savedPaymentTerm) { + if (isMobile(context)) { + store.dispatch(UpdateCurrentRoute(PaymentTermViewScreen.route)); + if (paymentTerm.isNew) { + Navigator.of(context) + .pushReplacementNamed(PaymentTermViewScreen.route); + } else { + Navigator.of(context).pop(savedPaymentTerm); + } + } else { + viewEntity(context: context, entity: savedPaymentTerm, force: true); + } + }).catchError((Object error) { + showDialog( + context: context, + builder: (BuildContext context) { + return ErrorDialog(error); + }); + }); + }, + ); + } + + final PaymentTermEntity paymentTerm; + final CompanyEntity company; + final Function(PaymentTermEntity) onChanged; + final Function(BuildContext) onSavePressed; + final Function(BuildContext) onCancelPressed; + final bool isLoading; + final bool isSaving; + final PaymentTermEntity origPaymentTerm; + final AppState state; +} diff --git a/lib/ui/payment_term/payment_term_list.dart b/lib/ui/payment_term/payment_term_list.dart new file mode 100644 index 000000000..32b3b56e9 --- /dev/null +++ b/lib/ui/payment_term/payment_term_list.dart @@ -0,0 +1,92 @@ +import 'package:flutter/foundation.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/data/models/payment_term_model.dart'; +import 'package:invoiceninja_flutter/redux/app/app_actions.dart'; +import 'package:invoiceninja_flutter/redux/app/app_state.dart'; +import 'package:invoiceninja_flutter/redux/payment_term/payment_term_actions.dart'; +import 'package:invoiceninja_flutter/redux/ui/pref_state.dart'; +import 'package:invoiceninja_flutter/ui/app/entities/entity_actions_dialog.dart'; +import 'package:invoiceninja_flutter/ui/app/help_text.dart'; +import 'package:invoiceninja_flutter/ui/app/lists/list_divider.dart'; +import 'package:invoiceninja_flutter/ui/app/loading_indicator.dart'; +import 'package:invoiceninja_flutter/ui/app/presenters/entity_presenter.dart'; +import 'package:invoiceninja_flutter/ui/payment_term/payment_term_presenter.dart'; +import 'package:invoiceninja_flutter/ui/app/tables/entity_datatable.dart'; +import 'package:invoiceninja_flutter/ui/payment_term/payment_term_list_item.dart'; +import 'package:invoiceninja_flutter/ui/payment_term/payment_term_list_vm.dart'; +import 'package:invoiceninja_flutter/utils/localization.dart'; + +class PaymentTermList extends StatefulWidget { + const PaymentTermList({ + Key key, + @required this.viewModel, + }) : super(key: key); + + final PaymentTermListVM viewModel; + + @override + _PaymentTermListState createState() => _PaymentTermListState(); +} + +class _PaymentTermListState extends State { + EntityDataTableSource dataTableSource; + + @override + Widget build(BuildContext context) { + final viewModel = widget.viewModel; + final state = viewModel.state; + final listUIState = state.uiState.paymentTermUIState.listUIState; + final isInMultiselect = listUIState.isInMultiselect(); + + if (!viewModel.isLoaded) { + return viewModel.isLoading ? LoadingIndicator() : SizedBox(); + } else if (viewModel.paymentTermMap.isEmpty) { + return HelpText(AppLocalization.of(context).noRecordsFound); + } + + return RefreshIndicator( + onRefresh: () => viewModel.onRefreshed(context), + child: ListView.separated( + separatorBuilder: (context, index) => ListDivider(), + itemCount: viewModel.paymentTermList.length, + itemBuilder: (BuildContext context, index) { + final paymentTermId = viewModel.paymentTermList[index]; + final paymentTerm = viewModel.paymentTermMap[paymentTermId]; + + return PaymentTermListItem( + user: viewModel.state.user, + filter: viewModel.filter, + paymentTerm: paymentTerm, + onEntityAction: (EntityAction action) { + if (action == EntityAction.more) { + showEntityActionsDialog( + entities: [paymentTerm], + context: context, + ); + } else { + handlePaymentTermAction(context, [paymentTerm], action); + } + }, + onTap: () => viewModel.onPaymentTermTap(context, paymentTerm), + onLongPress: () async { + final longPressIsSelection = + state.prefState.longPressSelectionIsDefault ?? true; + if (longPressIsSelection && !isInMultiselect) { + handlePaymentTermAction( + context, [paymentTerm], EntityAction.toggleMultiselect); + } else { + showEntityActionsDialog( + entities: [paymentTerm], + context: context, + ); + } + }, + isChecked: + isInMultiselect && listUIState.isSelected(paymentTerm.id), + ); + }), + ); + } +} diff --git a/lib/ui/payment_term/payment_term_list_item.dart b/lib/ui/payment_term/payment_term_list_item.dart new file mode 100644 index 000000000..7d2150245 --- /dev/null +++ b/lib/ui/payment_term/payment_term_list_item.dart @@ -0,0 +1,105 @@ +import 'package:flutter_redux/flutter_redux.dart'; +import 'package:invoiceninja_flutter/data/models/payment_term_model.dart'; +import 'package:invoiceninja_flutter/redux/app/app_state.dart'; +import 'package:invoiceninja_flutter/ui/app/entity_state_label.dart'; +import 'package:invoiceninja_flutter/utils/formatting.dart'; +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; +import 'package:invoiceninja_flutter/data/models/models.dart'; +import 'package:invoiceninja_flutter/ui/app/dismissible_entity.dart'; + +class PaymentTermListItem extends StatelessWidget { + const PaymentTermListItem({ + @required this.user, + @required this.onEntityAction, + @required this.onTap, + @required this.onLongPress, + @required this.paymentTerm, + @required this.filter, + this.onCheckboxChanged, + this.isChecked = false, + }); + + final UserEntity user; + final Function(EntityAction) onEntityAction; + final GestureTapCallback onTap; + final GestureTapCallback onLongPress; + final PaymentTermEntity paymentTerm; + final String filter; + final Function(bool) onCheckboxChanged; + final bool isChecked; + + static final paymentTermItemKey = + (int id) => Key('__payment_term_item_${id}__'); + + @override + Widget build(BuildContext context) { + final store = StoreProvider.of(context); + final state = store.state; + final uiState = state.uiState; + final paymentTermUIState = uiState.paymentTermUIState; + final listUIState = paymentTermUIState.listUIState; + final isInMultiselect = listUIState.isInMultiselect(); + final showCheckbox = onCheckboxChanged != null || isInMultiselect; + + final filterMatch = filter != null && filter.isNotEmpty + ? paymentTerm.matchesFilterValue(filter) + : null; + final subtitle = filterMatch; + + return DismissibleEntity( + userCompany: state.userCompany, + entity: paymentTerm, + isSelected: paymentTerm.id == + (uiState.isEditing + ? paymentTermUIState.editing.id + : paymentTermUIState.selectedId), + onEntityAction: onEntityAction, + child: ListTile( + onTap: isInMultiselect + ? () => onEntityAction(EntityAction.toggleMultiselect) + : onTap, + onLongPress: onLongPress, + leading: showCheckbox + ? IgnorePointer( + ignoring: listUIState.isInMultiselect(), + child: Checkbox( + value: isChecked, + materialTapTargetSize: MaterialTapTargetSize.shrinkWrap, + onChanged: (value) => onCheckboxChanged(value), + activeColor: Theme.of(context).accentColor, + ), + ) + : null, + title: Container( + width: MediaQuery.of(context).size.width, + child: Row( + children: [ + Expanded( + child: Text( + paymentTerm.name, + style: Theme.of(context).textTheme.title, + ), + ), + Text(formatNumber(paymentTerm.listDisplayAmount, context), + style: Theme.of(context).textTheme.title), + ], + ), + ), + subtitle: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + subtitle != null && subtitle.isNotEmpty + ? Text( + subtitle, + maxLines: 3, + overflow: TextOverflow.ellipsis, + ) + : Container(), + EntityStateLabel(paymentTerm), + ], + ), + ), + ); + } +} diff --git a/lib/ui/payment_term/payment_term_list_vm.dart b/lib/ui/payment_term/payment_term_list_vm.dart new file mode 100644 index 000000000..50bd707cf --- /dev/null +++ b/lib/ui/payment_term/payment_term_list_vm.dart @@ -0,0 +1,166 @@ +import 'dart:async'; +import 'package:invoiceninja_flutter/data/models/payment_term_model.dart'; +import 'package:invoiceninja_flutter/ui/app/entities/entity_actions_dialog.dart'; +import 'package:invoiceninja_flutter/ui/app/tables/entity_list.dart'; +import 'package:invoiceninja_flutter/ui/payment_term/payment_term_list_item.dart'; +import 'package:redux/redux.dart'; +import 'package:invoiceninja_flutter/ui/design/design_presenter.dart'; +import 'package:invoiceninja_flutter/redux/app/app_actions.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/foundation.dart'; +import 'package:flutter/widgets.dart'; +import 'package:flutter_redux/flutter_redux.dart'; +import 'package:built_collection/built_collection.dart'; +import 'package:invoiceninja_flutter/redux/ui/list_ui_state.dart'; +import 'package:invoiceninja_flutter/utils/completers.dart'; +import 'package:invoiceninja_flutter/utils/localization.dart'; +import 'package:invoiceninja_flutter/redux/payment_term/payment_term_selectors.dart'; +import 'package:invoiceninja_flutter/data/models/models.dart'; +import 'package:invoiceninja_flutter/redux/app/app_state.dart'; +import 'package:invoiceninja_flutter/redux/payment_term/payment_term_actions.dart'; + +class PaymentTermListBuilder extends StatelessWidget { + const PaymentTermListBuilder({Key key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return StoreConnector( + converter: PaymentTermListVM.fromStore, + builder: (context, viewModel) { + return EntityList( + isLoaded: viewModel.isLoaded, + entityType: EntityType.paymentTerm, + state: viewModel.state, + entityList: viewModel.paymentTermList, + onEntityTap: viewModel.onPaymentTermTap, + tableColumns: viewModel.tableColumns, + onRefreshed: viewModel.onRefreshed, + onClearEntityFilterPressed: viewModel.onClearEntityFilterPressed, + onViewEntityFilterPressed: viewModel.onViewEntityFilterPressed, + onSortColumn: viewModel.onSortColumn, + itemBuilder: (BuildContext context, index) { + final state = viewModel.state; + final paymentTermId = viewModel.paymentTermList[index]; + final paymentTerm = viewModel.paymentTermMap[paymentTermId]; + final listState = state.getListState(EntityType.paymentTerm); + final isInMultiselect = listState.isInMultiselect(); + + return PaymentTermListItem( + user: viewModel.state.user, + filter: viewModel.filter, + paymentTerm: paymentTerm, + onEntityAction: (EntityAction action) { + if (action == EntityAction.more) { + showEntityActionsDialog( + entities: [paymentTerm], + context: context, + ); + } else { + handlePaymentTermAction(context, [paymentTerm], action); + } + }, + onTap: () => viewModel.onPaymentTermTap(context, paymentTerm), + onLongPress: () async { + final longPressIsSelection = + state.prefState.longPressSelectionIsDefault ?? true; + if (longPressIsSelection && !isInMultiselect) { + handlePaymentTermAction( + context, [paymentTerm], EntityAction.toggleMultiselect); + } else { + showEntityActionsDialog( + entities: [paymentTerm], + context: context, + ); + } + }, + isChecked: + isInMultiselect && listState.isSelected(paymentTerm.id), + ); + }); + }, + ); + } +} + +class PaymentTermListVM { + PaymentTermListVM({ + @required this.state, + @required this.userCompany, + @required this.paymentTermList, + @required this.paymentTermMap, + @required this.filter, + @required this.isLoading, + @required this.isLoaded, + @required this.onPaymentTermTap, + @required this.listState, + @required this.onRefreshed, + @required this.onEntityAction, + @required this.onClearEntityFilterPressed, + @required this.onViewEntityFilterPressed, + @required this.onSortColumn, + this.tableColumns, + }); + + static PaymentTermListVM fromStore(Store store) { + Future _handleRefresh(BuildContext context) { + if (store.state.isLoading) { + return Future(null); + } + final completer = snackBarCompleter( + context, AppLocalization.of(context).refreshComplete); + store.dispatch(LoadPaymentTerms(completer: completer, force: true)); + return completer.future; + } + + final state = store.state; + + return PaymentTermListVM( + state: state, + userCompany: state.userCompany, + listState: state.paymentTermListState, + paymentTermList: memoizedFilteredPaymentTermList( + state.paymentTermState.map, + state.paymentTermState.list, + state.paymentTermListState), + paymentTermMap: state.paymentTermState.map, + isLoading: state.isLoading, + isLoaded: state.paymentTermState.isLoaded, + filter: state.paymentTermUIState.listUIState.filter, + onClearEntityFilterPressed: () => + store.dispatch(FilterPaymentTermsByEntity()), + onViewEntityFilterPressed: (BuildContext context) => viewEntityById( + context: context, + entityId: state.paymentTermListState.filterEntityId, + entityType: state.paymentTermListState.filterEntityType), + onPaymentTermTap: (context, paymentTerm) { + if (store.state.paymentTermListState.isInMultiselect()) { + handlePaymentTermAction( + context, [paymentTerm], EntityAction.toggleMultiselect); + } else { + viewEntity(context: context, entity: paymentTerm); + } + }, + onEntityAction: (BuildContext context, List paymentTerms, + EntityAction action) => + handlePaymentTermAction(context, paymentTerms, action), + onRefreshed: (context) => _handleRefresh(context), + onSortColumn: (field) => store.dispatch(SortPaymentTerms(field)), + ); + } + + final AppState state; + final UserCompanyEntity userCompany; + final List paymentTermList; + final BuiltMap paymentTermMap; + final ListUIState listState; + final String filter; + final bool isLoading; + final bool isLoaded; + final Function(BuildContext, BaseEntity) onPaymentTermTap; + final Function(BuildContext) onRefreshed; + final Function(BuildContext, List, EntityAction) onEntityAction; + final Function onClearEntityFilterPressed; + final Function(BuildContext) onViewEntityFilterPressed; + final List tableColumns; + final Function(String) onSortColumn; +} diff --git a/lib/ui/payment_term/payment_term_presenter.dart b/lib/ui/payment_term/payment_term_presenter.dart new file mode 100644 index 000000000..d18338e8b --- /dev/null +++ b/lib/ui/payment_term/payment_term_presenter.dart @@ -0,0 +1,22 @@ +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/ui/app/presenters/entity_presenter.dart'; + +class PaymentTermPresenter extends EntityPresenter { + static List getTableFields(UserCompanyEntity userCompany) { + return []; + } + + @override + Widget getField({String field, BuildContext context}) { + final state = StoreProvider.of(context).state; + final paymentTerm = entity as InvoiceEntity; + + switch (field) { + } + + return super.getField(field: field, context: context); + } +} diff --git a/lib/ui/payment_term/payment_term_screen.dart b/lib/ui/payment_term/payment_term_screen.dart new file mode 100644 index 000000000..af47bc199 --- /dev/null +++ b/lib/ui/payment_term/payment_term_screen.dart @@ -0,0 +1,130 @@ +import 'dart:async'; + +import 'package:flutter/material.dart'; +import 'package:flutter_redux/flutter_redux.dart'; +import 'package:invoiceninja_flutter/data/models/models.dart'; +import 'package:invoiceninja_flutter/data/models/payment_term_model.dart'; +import 'package:invoiceninja_flutter/redux/app/app_actions.dart'; +import 'package:invoiceninja_flutter/redux/app/app_state.dart'; +import 'package:invoiceninja_flutter/redux/payment_term/payment_term_actions.dart'; +import 'package:invoiceninja_flutter/ui/app/app_bottom_bar.dart'; +import 'package:invoiceninja_flutter/ui/app/forms/save_cancel_buttons.dart'; +import 'package:invoiceninja_flutter/ui/app/list_scaffold.dart'; +import 'package:invoiceninja_flutter/ui/app/entities/entity_actions_dialog.dart'; +import 'package:invoiceninja_flutter/ui/app/list_filter.dart'; +import 'package:invoiceninja_flutter/ui/payment_term/payment_term_list_vm.dart'; +import 'package:invoiceninja_flutter/utils/localization.dart'; +import 'package:invoiceninja_flutter/utils/platforms.dart'; + +import 'payment_term_screen_vm.dart'; + +class PaymentTermScreen extends StatelessWidget { + const PaymentTermScreen({ + Key key, + @required this.viewModel, + }) : super(key: key); + + static const String route = '/payment_term'; + + final PaymentTermScreenVM viewModel; + + @override + Widget build(BuildContext context) { + final store = StoreProvider.of(context); + final state = store.state; + final userCompany = state.userCompany; + final localization = AppLocalization.of(context); + final listUIState = state.uiState.paymentTermUIState.listUIState; + final isInMultiselect = listUIState.isInMultiselect(); + + return ListScaffold( + isChecked: isInMultiselect && + listUIState.selectedIds.length == viewModel.paymentTermList.length, + showCheckbox: isInMultiselect, + onHamburgerLongPress: () => store.dispatch(StartPaymentTermMultiselect()), + onCheckboxChanged: (value) { + final paymentTerms = viewModel.paymentTermList + .map( + (paymentTermId) => viewModel.paymentTermMap[paymentTermId]) + .where((paymentTerm) => + value != listUIState.isSelected(paymentTerm.id)) + .toList(); + + handlePaymentTermAction( + context, paymentTerms, EntityAction.toggleMultiselect); + }, + appBarTitle: Text(localization.paymentTerms), + appBarActions: [ + if (viewModel.isInMultiselect) + SaveCancelButtons( + saveLabel: localization.done, + onSavePressed: listUIState.selectedIds.isEmpty + ? null + : (context) async { + final paymentTerms = listUIState.selectedIds + .map((paymentTermId) => + viewModel.paymentTermMap[paymentTermId]) + .toList(); + + await showEntityActionsDialog( + entities: paymentTerms, + context: context, + multiselect: true, + completer: Completer() + ..future.then((_) => + store.dispatch(ClearPaymentTermMultiselect())), + ); + }, + onCancelPressed: (context) => + store.dispatch(ClearPaymentTermMultiselect()), + ), + ], + body: PaymentTermListBuilder(), + bottomNavigationBar: AppBottomBar( + entityType: EntityType.paymentTerm, + onRefreshPressed: () => store.dispatch(LoadPaymentTerms(force: true)), + onSelectedSortField: (value) { + store.dispatch(SortPaymentTerms(value)); + }, + sortFields: [ + PaymentTermFields.name, + PaymentTermFields.numDays, + ], + onSelectedState: (EntityState state, value) { + store.dispatch(FilterPaymentTermsByState(state)); + }, + onCheckboxPressed: () { + if (store.state.paymentTermListState.isInMultiselect()) { + store.dispatch(ClearPaymentTermMultiselect()); + } else { + store.dispatch(StartPaymentTermMultiselect()); + } + }, + onSelectedCustom1: (value) => + store.dispatch(FilterPaymentTermsByCustom1(value)), + onSelectedCustom2: (value) => + store.dispatch(FilterPaymentTermsByCustom2(value)), + onSelectedCustom3: (value) => + store.dispatch(FilterPaymentTermsByCustom3(value)), + onSelectedCustom4: (value) => + store.dispatch(FilterPaymentTermsByCustom4(value)), + ), + floatingActionButton: + isMobile(context) && userCompany.canCreate(EntityType.paymentTerm) + ? FloatingActionButton( + heroTag: 'payment_term_fab', + backgroundColor: Theme.of(context).primaryColorDark, + onPressed: () { + createEntityByType( + context: context, entityType: EntityType.paymentTerm); + }, + child: Icon( + Icons.add, + color: Colors.white, + ), + tooltip: localization.newPaymentTerm, + ) + : null, + ); + } +} diff --git a/lib/ui/payment_term/payment_term_screen_vm.dart b/lib/ui/payment_term/payment_term_screen_vm.dart new file mode 100644 index 000000000..0ba755ac3 --- /dev/null +++ b/lib/ui/payment_term/payment_term_screen_vm.dart @@ -0,0 +1,62 @@ +import 'package:built_collection/built_collection.dart'; +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/widgets.dart'; +import 'package:flutter_redux/flutter_redux.dart'; +import 'package:invoiceninja_flutter/data/models/models.dart'; +import 'package:invoiceninja_flutter/data/models/payment_term_model.dart'; +import 'package:invoiceninja_flutter/redux/app/app_state.dart'; +import 'package:invoiceninja_flutter/redux/payment_term/payment_term_actions.dart'; +import 'package:invoiceninja_flutter/redux/payment_term/payment_term_selectors.dart'; +import 'package:redux/redux.dart'; + +import 'payment_term_screen.dart'; + +class PaymentTermScreenBuilder extends StatelessWidget { + const PaymentTermScreenBuilder({Key key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return StoreConnector( + converter: PaymentTermScreenVM.fromStore, + builder: (context, vm) { + return PaymentTermScreen( + viewModel: vm, + ); + }, + ); + } +} + +class PaymentTermScreenVM { + PaymentTermScreenVM({ + @required this.isInMultiselect, + @required this.paymentTermList, + @required this.userCompany, + @required this.onEntityAction, + @required this.paymentTermMap, + }); + + final bool isInMultiselect; + final UserCompanyEntity userCompany; + final List paymentTermList; + final Function(BuildContext, List, EntityAction) onEntityAction; + final BuiltMap paymentTermMap; + + static PaymentTermScreenVM fromStore(Store store) { + final state = store.state; + + return PaymentTermScreenVM( + paymentTermMap: state.paymentTermState.map, + paymentTermList: memoizedFilteredPaymentTermList( + state.paymentTermState.map, + state.paymentTermState.list, + state.paymentTermListState), + userCompany: state.userCompany, + isInMultiselect: state.paymentTermListState.isInMultiselect(), + onEntityAction: (BuildContext context, List paymentTerms, + EntityAction action) => + handlePaymentTermAction(context, paymentTerms, action), + ); + } +} diff --git a/lib/ui/payment_term/view/payment_term_view.dart b/lib/ui/payment_term/view/payment_term_view.dart new file mode 100644 index 000000000..ef1608523 --- /dev/null +++ b/lib/ui/payment_term/view/payment_term_view.dart @@ -0,0 +1,32 @@ +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; +import 'package:invoiceninja_flutter/ui/app/view_scaffold.dart'; +import 'package:invoiceninja_flutter/ui/payment_term/view/payment_term_view_vm.dart'; + +class PaymentTermView extends StatefulWidget { + const PaymentTermView({ + Key key, + @required this.viewModel, + }) : super(key: key); + + final PaymentTermViewVM viewModel; + + @override + _PaymentTermViewState createState() => new _PaymentTermViewState(); +} + +class _PaymentTermViewState extends State { + @override + Widget build(BuildContext context) { + final viewModel = widget.viewModel; + final userCompany = viewModel.state.userCompany; + final paymentTerm = viewModel.paymentTerm; + + return ViewScaffold( + entity: paymentTerm, + body: ListView( + children: [], + ), + ); + } +} diff --git a/lib/ui/payment_term/view/payment_term_view_vm.dart b/lib/ui/payment_term/view/payment_term_view_vm.dart new file mode 100644 index 000000000..8a0432608 --- /dev/null +++ b/lib/ui/payment_term/view/payment_term_view_vm.dart @@ -0,0 +1,80 @@ +import 'dart:async'; +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; +import 'package:invoiceninja_flutter/utils/completers.dart'; +import 'package:invoiceninja_flutter/utils/localization.dart'; +import 'package:redux/redux.dart'; +import 'package:flutter_redux/flutter_redux.dart'; +import 'package:invoiceninja_flutter/redux/payment_term/payment_term_actions.dart'; +import 'package:invoiceninja_flutter/data/models/payment_term_model.dart'; +import 'package:invoiceninja_flutter/data/models/models.dart'; +import 'package:invoiceninja_flutter/ui/payment_term/view/payment_term_view.dart'; +import 'package:invoiceninja_flutter/redux/app/app_state.dart'; + +class PaymentTermViewScreen extends StatelessWidget { + const PaymentTermViewScreen({Key key}) : super(key: key); + static const String route = '/payment_term/view'; + + @override + Widget build(BuildContext context) { + return StoreConnector( + converter: (Store store) { + return PaymentTermViewVM.fromStore(store); + }, + builder: (context, vm) { + return PaymentTermView( + viewModel: vm, + ); + }, + ); + } +} + +class PaymentTermViewVM { + PaymentTermViewVM({ + @required this.state, + @required this.paymentTerm, + @required this.company, + @required this.onEntityAction, + @required this.onRefreshed, + @required this.isSaving, + @required this.isLoading, + @required this.isDirty, + }); + + factory PaymentTermViewVM.fromStore(Store store) { + final state = store.state; + final paymentTerm = + state.paymentTermState.map[state.paymentTermUIState.selectedId] ?? + PaymentTermEntity(id: state.paymentTermUIState.selectedId); + + Future _handleRefresh(BuildContext context) { + final completer = snackBarCompleter( + context, AppLocalization.of(context).refreshComplete); + store.dispatch( + LoadPaymentTerm(completer: completer, paymentTermId: paymentTerm.id)); + return completer.future; + } + + return PaymentTermViewVM( + state: state, + company: state.company, + isSaving: state.isSaving, + isLoading: state.isLoading, + isDirty: paymentTerm.isNew, + paymentTerm: paymentTerm, + onRefreshed: (context) => _handleRefresh(context), + onEntityAction: (BuildContext context, EntityAction action) => + handlePaymentTermAction(context, [paymentTerm], action), + ); + } + + final AppState state; + final PaymentTermEntity paymentTerm; + final CompanyEntity company; + final Function(BuildContext, EntityAction) onEntityAction; + final Function(BuildContext) onRefreshed; + final bool isSaving; + final bool isLoading; + final bool isDirty; +} diff --git a/lib/utils/i18n.dart b/lib/utils/i18n.dart index 7182a5908..a12fdc9b4 100644 --- a/lib/utils/i18n.dart +++ b/lib/utils/i18n.dart @@ -15,6 +15,15 @@ mixin LocalizationsProvider on LocaleCodeAware { static final Map> _localizedValues = { 'en': { // STARTER: lang key - do not remove comment + 'payment_term': 'Payment Term', + 'new_payment_term': 'New Payment Term', + 'edit_payment_term': 'Edit Payment Term', + 'created_payment_term': 'Successfully created payment term', + 'updated_payment_term': 'Successfully updated payment term', + 'archived_payment_term': 'Successfully archived payment term', + 'deleted_payment_term': 'Successfully deleted payment term', + 'removed_payment_term': 'Successfully removed payment term', + 'restored_payment_term': 'Successfully restored payment term', 'full_width_editor': 'Full Width Editor', 'full_height_filter': 'Full Height Filter', 'email_sign_in': 'Sign in with email', @@ -69,7 +78,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'purge_data': 'Purge Data', 'purge_successful': 'Successfully purged company data', 'purge_data_message': - 'Warning: This will permanently erase your data, there is no undo.', + 'Warning: This will permanently erase your data, there is no undo.', 'invoice_balance': 'Invoice Balance', 'age_group_0': '0 - 30 Days', 'age_group_30': '30 - 60 Days', @@ -104,10 +113,10 @@ mixin LocalizationsProvider on LocaleCodeAware { 'apply_license': 'Apply License', 'cancel_account': 'Delete Account', 'cancel_account_message': - 'Warning: This will permanently delete your account, there is no undo.', + 'Warning: This will permanently delete your account, there is no undo.', 'delete_company': 'Delete Company', 'delete_company_message': - 'Warning: This will permanently delete your company, there is no undo.', + 'Warning: This will permanently delete your company, there is no undo.', 'enable_modules': 'Enable Modules', 'converted_quote': 'Successfully converted quote', 'credit_design': 'Credit Design', @@ -259,12 +268,12 @@ mixin LocalizationsProvider on LocaleCodeAware { 'applied': 'Applied', 'include_recent_errors': 'Include recent errors from the logs', 'your_message_has_been_received': - 'We have received your message and will try to respond promptly.', + 'We have received your message and will try to respond promptly.', 'message': 'Message', 'from': 'From', 'show_product_details': 'Show Product Details', 'show_product_details_help': - 'Include the description and cost in the product dropdown', + 'Include the description and cost in the product dropdown', 'pdf_min_requirements': 'The PDF renderer requires :version', 'adjust_fee_percent': 'Adjust Fee Percent', 'adjust_fee_percent_help': 'Ensure client fee matches the gateway fee', @@ -281,7 +290,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'domain_url': 'Domain URL', 'password_is_too_short': 'Password must be at least 8 character long', 'password_is_too_easy': - 'Password must contain an upper case character and a number', + 'Password must contain an upper case character and a number', 'client_portal_tasks': 'Client Portal Tasks', 'client_portal_dashboard': 'Client Portal Dashboard', 'please_enter_a_value': 'Please enter a value', @@ -308,16 +317,16 @@ mixin LocalizationsProvider on LocaleCodeAware { 'third_custom': 'Third Custom', 'show_cost': 'Show Cost', 'show_cost_help': - 'Display a product cost field to track the markup/profit', + 'Display a product cost field to track the markup/profit', 'show_product_quantity': 'Show Product Quantity', 'show_product_quantity_help': - 'Display a product quantity field, otherwise default to one', + 'Display a product quantity field, otherwise default to one', 'show_invoice_quantity': 'Show Invoice Quantity', 'show_invoice_quantity_help': - 'Display a line item quantity field, otherwise default to one', + 'Display a line item quantity field, otherwise default to one', 'default_quantity': 'Default Quantity', 'default_quantity_help': - 'Automatically set the line item quantity to one', + 'Automatically set the line item quantity to one', 'one_tax_rate': 'One Tax Rate', 'two_tax_rates': 'Two Tax Rates', 'three_tax_rates': 'Three Tax Rates', @@ -362,7 +371,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'filtered_by_user': 'Filtered by User', 'administrator': 'Administrator', 'administrator_help': - 'Allow user to manage users, change settings and modify all records', + 'Allow user to manage users, change settings and modify all records', 'user_management': 'User Management', 'users': 'Users', 'new_user': 'New User', @@ -377,7 +386,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'invoice_options': 'Invoice Options', 'hide_paid_to_date': 'Hide Paid to Date', 'hide_paid_to_date_help': - 'Only display the "Paid to Date" area on your invoices once a payment has been received.', + 'Only display the "Paid to Date" area on your invoices once a payment has been received.', 'invoice_embed_documents': 'Embed Documents', 'invoice_embed_documents_help': 'Include attached images in the invoice.', 'all_pages_header': 'Show Header on', @@ -400,16 +409,16 @@ mixin LocalizationsProvider on LocaleCodeAware { 'quote_footer': 'Quote Footer', 'auto_email_invoice': 'Auto Email', 'auto_email_invoice_help': - 'Automatically email recurring invoices when they are created.', + 'Automatically email recurring invoices when they are created.', 'auto_archive_invoice': 'Auto Archive', 'auto_archive_invoice_help': - 'Automatically archive invoices when they are paid.', + 'Automatically archive invoices when they are paid.', 'auto_archive_quote': 'Auto Archive', 'auto_archive_quote_help': - 'Automatically archive quotes when they are converted.', + 'Automatically archive quotes when they are converted.', 'auto_convert_quote': 'Auto Convert', 'auto_convert_quote_help': - 'Automatically convert a quote to an invoice when approved by a client.', + 'Automatically convert a quote to an invoice when approved by a client.', 'workflow_settings': 'Workflow Settings', 'freq_daily': 'Daily', 'freq_weekly': 'Weekly', @@ -455,27 +464,27 @@ mixin LocalizationsProvider on LocaleCodeAware { 'custom_javascript': 'Custom JavaScript', 'signature_on_pdf': 'Show on PDF', 'signature_on_pdf_help': - 'Show the client signature on the invoice/quote PDF.', + 'Show the client signature on the invoice/quote PDF.', 'show_accept_invoice_terms': 'Invoice Terms Checkbox', 'show_accept_invoice_terms_help': - 'Require client to confirm that they accept the invoice terms.', + 'Require client to confirm that they accept the invoice terms.', 'show_accept_quote_terms': 'Quote Terms Checkbox', 'show_accept_quote_terms_help': - 'Require client to confirm that they accept the quote terms.', + 'Require client to confirm that they accept the quote terms.', 'require_invoice_signature': 'Invoice Signature', 'require_invoice_signature_help': - 'Require client to provide their signature.', + 'Require client to provide their signature.', 'require_quote_signature': 'Quote Signature', 'enable_portal_password': 'Password Protect Invoices', 'enable_portal_password_help': - 'Allows you to set a password for each contact. If a password is set, the contact will be required to enter a password before viewing invoices.', + 'Allows you to set a password for each contact. If a password is set, the contact will be required to enter a password before viewing invoices.', 'authorization': 'Authorization', 'subdomain': 'Subdomain', 'domain': 'Domain', 'portal_mode': 'Portal Mode', 'email_signature': 'Email Signature', 'enable_email_markup_help': - 'Make it easier for your clients to pay you by adding schema.org markup to your emails.', + 'Make it easier for your clients to pay you by adding schema.org markup to your emails.', 'plain': 'Plain', 'light': 'Light', 'dark': 'Dark', @@ -504,9 +513,9 @@ mixin LocalizationsProvider on LocaleCodeAware { 'accepted_card_logos': 'Accepted Card Logos', 'credentials': 'Credentials', 'require_billing_address_help': - 'Require client to provide their billing address', + 'Require client to provide their billing address', 'require_shipping_address_help': - 'Require client to provide their shipping address', + 'Require client to provide their shipping address', 'update_address': 'Update address', 'update_address_help': 'Update client\'s address with provided details', 'rate': 'Rate', @@ -520,13 +529,13 @@ mixin LocalizationsProvider on LocaleCodeAware { 'restored_tax_rate': 'Successfully restored tax rate', 'fill_products': 'Fill Products', 'fill_products_help': - 'Selecting a product will automatically fill in the description and cost', + 'Selecting a product will automatically fill in the description and cost', 'update_products': 'Update Products', 'update_products_help': - 'Updating an invoice will automatically update the product library', + 'Updating an invoice will automatically update the product library', 'convert_products': 'Convert Products', 'convert_products_help': - 'Automatically convert product prices to the client\'s currency', + 'Automatically convert product prices to the client\'s currency', 'fees': 'Fees', 'limits': 'Limits', 'provider': 'Provider', @@ -626,7 +635,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'please_enter_a_first_name': 'Please enter a first name', 'please_enter_a_last_name': 'Please enter a last name', 'please_agree_to_terms_and_privacy': - 'Please agree to the terms of service and privacy policy to create an account.', + 'Please agree to the terms of service and privacy policy to create an account.', 'i_agree_to_the': 'I agree to the', 'terms_of_service_link': 'terms of service', 'privacy_policy_link': 'privacy policy', @@ -725,7 +734,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'average': 'Average', 'unapproved': 'Unapproved', 'authenticate_to_change_setting': - 'Please authenticate to change this setting', + 'Please authenticate to change this setting', 'locked': 'Locked', 'authenticate': 'Authenticate', 'please_authenticate': 'Please authenticate', @@ -925,7 +934,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'marked_invoices_as_paid': 'Successfully marked invoices as paid', 'done': 'Done', 'please_enter_a_client_or_contact_name': - 'Please enter a client or contact name', + 'Please enter a client or contact name', 'dark_mode': 'Dark Mode', 'restart_app_to_apply_change': 'Restart the app to apply the change', 'refresh_data': 'Refresh Data', @@ -1157,7 +1166,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'purge_data': 'Purge Data', 'purge_successful': 'Successfully purged company data', 'purge_data_message': - 'Warning: This will permanently erase your data, there is no undo.', + 'Warning: This will permanently erase your data, there is no undo.', 'invoice_balance': 'Invoice Balance', 'age_group_0': '0 - 30 Days', 'age_group_30': '30 - 60 Days', @@ -1192,10 +1201,10 @@ mixin LocalizationsProvider on LocaleCodeAware { 'apply_license': 'Apply License', 'cancel_account': 'Fshi llogarinë', 'cancel_account_message': - 'Warning: This will permanently delete your account, there is no undo.', + 'Warning: This will permanently delete your account, there is no undo.', 'delete_company': 'Delete Company', 'delete_company_message': - 'Warning: This will permanently delete your company, there is no undo.', + 'Warning: This will permanently delete your company, there is no undo.', 'enable_modules': 'Enable Modules', 'converted_quote': 'Successfully converted quote', 'credit_design': 'Credit Design', @@ -1347,12 +1356,12 @@ mixin LocalizationsProvider on LocaleCodeAware { 'applied': 'Applied', 'include_recent_errors': 'Include recent errors from the logs', 'your_message_has_been_received': - 'We have received your message and will try to respond promptly.', + 'We have received your message and will try to respond promptly.', 'message': 'Mesazhi', 'from': 'Nga', 'show_product_details': 'Show Product Details', 'show_product_details_help': - 'Include the description and cost in the product dropdown', + 'Include the description and cost in the product dropdown', 'pdf_min_requirements': 'The PDF renderer requires :version', 'adjust_fee_percent': 'Adjust Fee Percent', 'adjust_fee_percent_help': 'Adjust percent to account for fee', @@ -1369,7 +1378,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'domain_url': 'Domain URL', 'password_is_too_short': 'Password is too short', 'password_is_too_easy': - 'Password must contain an upper case character and a number', + 'Password must contain an upper case character and a number', 'client_portal_tasks': 'Client Portal Tasks', 'client_portal_dashboard': 'Client Portal Dashboard', 'please_enter_a_value': 'Please enter a value', @@ -1396,16 +1405,16 @@ mixin LocalizationsProvider on LocaleCodeAware { 'third_custom': 'Third Custom', 'show_cost': 'Show Cost', 'show_cost_help': - 'Display a product cost field to track the markup/profit', + 'Display a product cost field to track the markup/profit', 'show_product_quantity': 'Show Product Quantity', 'show_product_quantity_help': - 'Display a product quantity field, otherwise default to one', + 'Display a product quantity field, otherwise default to one', 'show_invoice_quantity': 'Show Invoice Quantity', 'show_invoice_quantity_help': - 'Display a line item quantity field, otherwise default to one', + 'Display a line item quantity field, otherwise default to one', 'default_quantity': 'Default Quantity', 'default_quantity_help': - 'Automatically set the line item quantity to one', + 'Automatically set the line item quantity to one', 'one_tax_rate': 'One Tax Rate', 'two_tax_rates': 'Two Tax Rates', 'three_tax_rates': 'Three Tax Rates', @@ -1450,7 +1459,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'filtered_by_user': 'Filtered by User', 'administrator': 'Administrator', 'administrator_help': - 'Lejon përdoruesit të menaxhoj përdoruesit, të ndryshojë rregullimet dhe të modifikojë të gjitha shënimet.', + 'Lejon përdoruesit të menaxhoj përdoruesit, të ndryshojë rregullimet dhe të modifikojë të gjitha shënimet.', 'user_management': 'Menaxhimi i përdoruesve', 'users': 'Përdorues', 'new_user': 'Përdorues i ri', @@ -1465,7 +1474,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'invoice_options': 'Opsionet e faturës', 'hide_paid_to_date': 'Fshihe Paguar deri më tash', 'hide_paid_to_date_help': - 'Shfaqni \"Paguar deri më tash\" në faturat tuaja pasi të jetë pranuar pagesa.', + 'Shfaqni \"Paguar deri më tash\" në faturat tuaja pasi të jetë pranuar pagesa.', 'invoice_embed_documents': 'Dokumentet e lidhura', 'invoice_embed_documents_help': 'Vendos fotografinë në faturë.', 'all_pages_header': 'Shfaqe Header', @@ -1488,16 +1497,16 @@ mixin LocalizationsProvider on LocaleCodeAware { 'quote_footer': 'Footer i Ofertës', 'auto_email_invoice': 'Auto Email', 'auto_email_invoice_help': - 'Automatically email recurring invoices when they are created.', + 'Automatically email recurring invoices when they are created.', 'auto_archive_invoice': 'Auto Archive', 'auto_archive_invoice_help': - 'Automatically archive invoices when they are paid.', + 'Automatically archive invoices when they are paid.', 'auto_archive_quote': 'Auto Archive', 'auto_archive_quote_help': - 'Automatically archive quotes when they are converted.', + 'Automatically archive quotes when they are converted.', 'auto_convert_quote': 'Auto Convert', 'auto_convert_quote_help': - 'Automatikisht konverto ofertën në faturë kur pranohet nga klienti.', + 'Automatikisht konverto ofertën në faturë kur pranohet nga klienti.', 'workflow_settings': 'Workflow Settings', 'freq_daily': 'Daily', 'freq_weekly': 'Javore', @@ -1543,27 +1552,27 @@ mixin LocalizationsProvider on LocaleCodeAware { 'custom_javascript': 'Custom JavaScript', 'signature_on_pdf': 'Show on PDF', 'signature_on_pdf_help': - 'Show the client signature on the invoice/quote PDF.', + 'Show the client signature on the invoice/quote PDF.', 'show_accept_invoice_terms': 'Invoice Terms Checkbox', 'show_accept_invoice_terms_help': - 'Require client to confirm that they accept the invoice terms.', + 'Require client to confirm that they accept the invoice terms.', 'show_accept_quote_terms': 'Quote Terms Checkbox', 'show_accept_quote_terms_help': - 'Require client to confirm that they accept the quote terms.', + 'Require client to confirm that they accept the quote terms.', 'require_invoice_signature': 'Invoice Signature', 'require_invoice_signature_help': - 'Require client to provide their signature.', + 'Require client to provide their signature.', 'require_quote_signature': 'Quote Signature', 'enable_portal_password': 'Password Protect Invoices', 'enable_portal_password_help': - 'Ju mundëson të vendosni fjalëkalim për secilin kontakt. Nëse vendoset fjalëkalimi, kontakti duhet të vendos fjalëkalimin para se t\'i sheh faturat.', + 'Ju mundëson të vendosni fjalëkalim për secilin kontakt. Nëse vendoset fjalëkalimi, kontakti duhet të vendos fjalëkalimin para se t\'i sheh faturat.', 'authorization': 'Authorization', 'subdomain': 'Subdomain', 'domain': 'Domain', 'portal_mode': 'Portal Mode', 'email_signature': 'Përshëndetje', 'enable_email_markup_help': - 'Bëjeni më të lehtë për klientët tuaj të realizojnë pagesat duke vendosur schema.org markimin në emailat tuaj.', + 'Bëjeni më të lehtë për klientët tuaj të realizojnë pagesat duke vendosur schema.org markimin në emailat tuaj.', 'plain': 'E thjeshtë', 'light': 'E lehtë', 'dark': 'E mbylltë', @@ -1592,12 +1601,12 @@ mixin LocalizationsProvider on LocaleCodeAware { 'accepted_card_logos': 'Accepted Card Logos', 'credentials': 'Credentials', 'require_billing_address_help': - 'Require client to provide their billing address', + 'Require client to provide their billing address', 'require_shipping_address_help': - 'Require client to provide their shipping address', + 'Require client to provide their shipping address', 'update_address': 'Perditeso Adresën', 'update_address_help': - 'Perditeso adresën e klientit me detajet e ofruara', + 'Perditeso adresën e klientit me detajet e ofruara', 'rate': 'Norma', 'tax_rate': 'Norma e taksave', 'new_tax_rate': 'Normë e re e taksave', @@ -1609,13 +1618,13 @@ mixin LocalizationsProvider on LocaleCodeAware { 'restored_tax_rate': 'Successfully restored tax rate', 'fill_products': 'Plotëso-automatikisht produktet', 'fill_products_help': - 'Duke zgjedhur produktin, automatikisht do të plotësohen fill in the description and cost', + 'Duke zgjedhur produktin, automatikisht do të plotësohen fill in the description and cost', 'update_products': 'Perditeso-automatikisht produktet', 'update_products_help': - 'Perditesimi i faturës automatikisht do të perditesoje librarine e produktit', + 'Perditesimi i faturës automatikisht do të perditesoje librarine e produktit', 'convert_products': 'Convert Products', 'convert_products_help': - 'Automatically convert product prices to the client\'s currency', + 'Automatically convert product prices to the client\'s currency', 'fees': 'Fees', 'limits': 'Limits', 'provider': 'Provider', @@ -1715,7 +1724,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'please_enter_a_first_name': 'Please enter a first name', 'please_enter_a_last_name': 'Please enter a last name', 'please_agree_to_terms_and_privacy': - 'Please agree to the terms of service and privacy policy to create an account.', + 'Please agree to the terms of service and privacy policy to create an account.', 'i_agree_to_the': 'I agree to the', 'terms_of_service_link': 'terms of service', 'privacy_policy_link': 'privacy policy', @@ -1814,7 +1823,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'average': 'Average', 'unapproved': 'Unapproved', 'authenticate_to_change_setting': - 'Please authenticate to change this setting', + 'Please authenticate to change this setting', 'locked': 'Locked', 'authenticate': 'Authenticate', 'please_authenticate': 'Please authenticate', @@ -2014,7 +2023,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'marked_invoices_as_paid': 'Successfully marked invoices as paid', 'done': 'Përfundo', 'please_enter_a_client_or_contact_name': - 'Please enter a client or contact name', + 'Please enter a client or contact name', 'dark_mode': 'Modeli i errët', 'restart_app_to_apply_change': 'Restart the app to apply the change', 'refresh_data': 'Refresh Data', @@ -2096,7 +2105,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'activity_8': ':user ka arkivuar faturën :invoice', 'activity_9': ':user ka fshirë faturën :invoice', 'activity_10': - ':contact entered payment :payment for :payment_amount on invoice :invoice for :client', + ':contact entered payment :payment for :payment_amount on invoice :invoice for :client', 'activity_11': ':user ka perditesuar pagesën :payment', 'activity_12': ':user ka arkivuar pagesën :payment', 'activity_13': ':user ka fshirë pagesën :payment', @@ -2126,7 +2135,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'activity_37': ':user restored expense :expense', 'activity_39': ':user cancelled a :payment_amount payment :payment', 'activity_40': - ':user refunded :adjustment of a :payment_amount payment :payment', + ':user refunded :adjustment of a :payment_amount payment :payment', 'activity_41': ':payment_amount payment (:payment) ka dështuar', 'activity_42': ':user created task :task', 'activity_43': ':user updated task :task', @@ -2246,7 +2255,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'purge_data': 'Изчистване на данни', 'purge_successful': 'Успешно изчистени фирмени данни', 'purge_data_message': - 'Внимание: Това ще изтрие данните перманентно без възможност за възстановяване.', + 'Внимание: Това ще изтрие данните перманентно без възможност за възстановяване.', 'invoice_balance': 'Invoice Balance', 'age_group_0': '0 - 30 дни', 'age_group_30': '30 - 60 дни', @@ -2281,10 +2290,10 @@ mixin LocalizationsProvider on LocaleCodeAware { 'apply_license': 'Въведете лиценз', 'cancel_account': 'Изтрий Профил', 'cancel_account_message': - 'ВНИМАНИЕ: Това действие ще изтрие перманентно вашият профил и данните в него. След това данните няма как да бъдат възстановени.', + 'ВНИМАНИЕ: Това действие ще изтрие перманентно вашият профил и данните в него. След това данните няма как да бъдат възстановени.', 'delete_company': 'Изтриване на фирма', 'delete_company_message': - 'Внимание: Това ще изтрие перманентно фирматаВи без възможност за възстановяване.', + 'Внимание: Това ще изтрие перманентно фирматаВи без възможност за възстановяване.', 'enable_modules': 'Enable Modules', 'converted_quote': 'Successfully converted quote', 'credit_design': 'Credit Design', @@ -2436,12 +2445,12 @@ mixin LocalizationsProvider on LocaleCodeAware { 'applied': 'Applied', 'include_recent_errors': 'Include recent errors from the logs', 'your_message_has_been_received': - 'We have received your message and will try to respond promptly.', + 'We have received your message and will try to respond promptly.', 'message': 'Съобщение', 'from': 'От', 'show_product_details': 'Show Product Details', 'show_product_details_help': - 'Include the description and cost in the product dropdown', + 'Include the description and cost in the product dropdown', 'pdf_min_requirements': 'The PDF renderer requires :version', 'adjust_fee_percent': 'Adjust Fee Percent', 'adjust_fee_percent_help': 'Adjust percent to account for fee', @@ -2458,7 +2467,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'domain_url': 'Domain URL', 'password_is_too_short': 'Паролата е твърде кратка', 'password_is_too_easy': - 'Password must contain an upper case character and a number', + 'Password must contain an upper case character and a number', 'client_portal_tasks': 'Client Portal Tasks', 'client_portal_dashboard': 'Client Portal Dashboard', 'please_enter_a_value': 'Please enter a value', @@ -2485,16 +2494,16 @@ mixin LocalizationsProvider on LocaleCodeAware { 'third_custom': 'Third Custom', 'show_cost': 'Show Cost', 'show_cost_help': - 'Display a product cost field to track the markup/profit', + 'Display a product cost field to track the markup/profit', 'show_product_quantity': 'Show Product Quantity', 'show_product_quantity_help': - 'Display a product quantity field, otherwise default to one', + 'Display a product quantity field, otherwise default to one', 'show_invoice_quantity': 'Show Invoice Quantity', 'show_invoice_quantity_help': - 'Display a line item quantity field, otherwise default to one', + 'Display a line item quantity field, otherwise default to one', 'default_quantity': 'Default Quantity', 'default_quantity_help': - 'Automatically set the line item quantity to one', + 'Automatically set the line item quantity to one', 'one_tax_rate': 'One Tax Rate', 'two_tax_rates': 'Two Tax Rates', 'three_tax_rates': 'Three Tax Rates', @@ -2539,7 +2548,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'filtered_by_user': 'Филтрирано по Потребител', 'administrator': 'Администратор', 'administrator_help': - 'Даване на права на потребителя да управлява другите потребители, да променя настойки и да редактира всички записи', + 'Даване на права на потребителя да управлява другите потребители, да променя настойки и да редактира всички записи', 'user_management': 'Управление на потребителите', 'users': 'Потребители', 'new_user': 'Нов потребител', @@ -2554,10 +2563,10 @@ mixin LocalizationsProvider on LocaleCodeAware { 'invoice_options': 'Опции на фактурата', 'hide_paid_to_date': 'Скрий \"Изплатено до момента\"', 'hide_paid_to_date_help': - 'Покажи \"Изплатено до момента\" във фактурите, след като е получено плащане.', + 'Покажи \"Изплатено до момента\" във фактурите, след като е получено плащане.', 'invoice_embed_documents': 'Свързани документи', 'invoice_embed_documents_help': - 'Включване на прикачените изображения във фактурата.', + 'Включване на прикачените изображения във фактурата.', 'all_pages_header': 'Показване на хедъра на', 'all_pages_footer': 'Показване на футъра на', 'first_page': 'Първа страница', @@ -2578,16 +2587,16 @@ mixin LocalizationsProvider on LocaleCodeAware { 'quote_footer': 'Футър на оферта', 'auto_email_invoice': 'Auto Email', 'auto_email_invoice_help': - 'Автоматично изпращане на периодични фактури при създаването им', + 'Автоматично изпращане на периодични фактури при създаването им', 'auto_archive_invoice': 'Auto Archive', 'auto_archive_invoice_help': - 'Автоматично архивиране на фактури при плащането им', + 'Автоматично архивиране на фактури при плащането им', 'auto_archive_quote': 'Auto Archive', 'auto_archive_quote_help': - 'Автоматично архивиране на оферти при конвертирането им', + 'Автоматично архивиране на оферти при конвертирането им', 'auto_convert_quote': 'Автоматично конвертиране', 'auto_convert_quote_help': - 'Автоматично конвертиране на оферта във фактура при одобрение от клиента.', + 'Автоматично конвертиране на оферта във фактура при одобрение от клиента.', 'workflow_settings': 'Настройки на работния процес', 'freq_daily': 'Ежедневно', 'freq_weekly': 'Седмично', @@ -2633,26 +2642,26 @@ mixin LocalizationsProvider on LocaleCodeAware { 'custom_javascript': 'Custom JavaScript', 'signature_on_pdf': 'Показване в PDF документа', 'signature_on_pdf_help': - 'Показване на подписа на клиента в PDF фактурата / офертата.', + 'Показване на подписа на клиента в PDF фактурата / офертата.', 'show_accept_invoice_terms': 'Чек-бокс за условия на фактура', 'show_accept_invoice_terms_help': - 'Изискване клиенът да потвърди, че приема условията на фактурата', + 'Изискване клиенът да потвърди, че приема условията на фактурата', 'show_accept_quote_terms': 'Чек-бокс за условия на офертата', 'show_accept_quote_terms_help': - 'Изискване клиенът да потвърди, че приема условията на офертата', + 'Изискване клиенът да потвърди, че приема условията на офертата', 'require_invoice_signature': 'Подпис на фактурата', 'require_invoice_signature_help': 'Изискване клиентът да подпише', 'require_quote_signature': 'Подпис на офертата', 'enable_portal_password': 'Защита на фактурите с парола', 'enable_portal_password_help': - 'Дава възможност да заложите парола за всеки контакт. Ако такава е заложена, контактното лице ще трябва да я въведе преди да види фактурите,', + 'Дава възможност да заложите парола за всеки контакт. Ако такава е заложена, контактното лице ще трябва да я въведе преди да види фактурите,', 'authorization': 'Оторизация', 'subdomain': 'Subdomain', 'domain': 'Домейн', 'portal_mode': 'Portal Mode', 'email_signature': 'Поздрави,', 'enable_email_markup_help': - 'Направете плащането към Вас по-лесно за клиентите си като добавите в имейлите си schema.org markup.', + 'Направете плащането към Вас по-лесно за клиентите си като добавите в имейлите си schema.org markup.', 'plain': 'Изчистено', 'light': 'Светло', 'dark': 'Тъмно', @@ -2681,12 +2690,12 @@ mixin LocalizationsProvider on LocaleCodeAware { 'accepted_card_logos': 'Лога на приемани карти', 'credentials': 'Credentials', 'require_billing_address_help': - 'Изискване клиента да предостави адрес за фактуриране', + 'Изискване клиента да предостави адрес за фактуриране', 'require_shipping_address_help': - 'Изискване клиента да предостави адрес за доставка', + 'Изискване клиента да предостави адрес за доставка', 'update_address': 'Актуализация на адреса', 'update_address_help': - 'Актуализация на адреса на клиента с предоставените данни', + 'Актуализация на адреса на клиента с предоставените данни', 'rate': 'Размер', 'tax_rate': 'Данъчна ставка', 'new_tax_rate': 'Нова такса', @@ -2698,13 +2707,13 @@ mixin LocalizationsProvider on LocaleCodeAware { 'restored_tax_rate': 'Successfully restored tax rate', 'fill_products': 'Автоматично попълвай продукти', 'fill_products_help': - 'Избирането на продукт автоматично ще попълни описанието и цената', + 'Избирането на продукт автоматично ще попълни описанието и цената', 'update_products': 'Автоматично обнови продукти', 'update_products_help': - 'Промяната на фактура автоматично ще обнови продуктовия каталог', + 'Промяната на фактура автоматично ще обнови продуктовия каталог', 'convert_products': 'Конвертиране на продукти', 'convert_products_help': - 'Автоматично конвертиране на цените на продуктите във валутата на клиента', + 'Автоматично конвертиране на цените на продуктите във валутата на клиента', 'fees': 'Такси', 'limits': 'Лимити', 'provider': 'Provider', @@ -2804,7 +2813,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'please_enter_a_first_name': 'Моля въведете собствено име', 'please_enter_a_last_name': 'Моля въведете фамилно име', 'please_agree_to_terms_and_privacy': - 'Моля съгласете се с общите условия и политиката за поверителност за да създадете профил.', + 'Моля съгласете се с общите условия и политиката за поверителност за да създадете профил.', 'i_agree_to_the': 'Съгласявам се с', 'terms_of_service_link': 'условията за ползване', 'privacy_policy_link': 'политиката за поверителност', @@ -2896,7 +2905,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'restored_project': 'Успешно възстановен проект', 'new_project': 'Нов проект', 'thank_you_for_using_our_app': - 'Благодарим Ви, че използвате нашето приложение!', + 'Благодарим Ви, че използвате нашето приложение!', 'if_you_like_it': 'Ако го харесвате Ви молим', 'click_here': 'натиснете тук', 'click_here_capital': 'Click here', @@ -2904,7 +2913,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'average': 'Средно', 'unapproved': 'Неодобрено', 'authenticate_to_change_setting': - 'Моля, влезте в профила си за промяна на тази настойка', + 'Моля, влезте в профила си за промяна на тази настойка', 'locked': 'Блокирано', 'authenticate': 'Вход в профила', 'please_authenticate': 'Моля, влезте в профила си', @@ -3104,10 +3113,10 @@ mixin LocalizationsProvider on LocaleCodeAware { 'marked_invoices_as_paid': 'Successfully marked invoices as paid', 'done': 'Готово', 'please_enter_a_client_or_contact_name': - 'Моля, въведете клиент или лице за контакт', + 'Моля, въведете клиент или лице за контакт', 'dark_mode': 'Тъмен режим', 'restart_app_to_apply_change': - 'Рестартирайте приложението за прилагане на промяната', + 'Рестартирайте приложението за прилагане на промяната', 'refresh_data': 'Опресняване на данни', 'blank_contact': 'Празен контакт', 'activity': 'Активност', @@ -3187,7 +3196,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'activity_8': ':user архивира фактура :invoice', 'activity_9': ':user изтри фактура :invoice', 'activity_10': - ':contact въведе плащане :payment в размер на :payment_amount по фактура :invoice за :client', + ':contact въведе плащане :payment в размер на :payment_amount по фактура :invoice за :client', 'activity_11': ':user актуализира плащане :payment', 'activity_12': ':user архивира плащане :payment', 'activity_13': ':user изтри плащане :payment', @@ -3217,7 +3226,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'activity_37': ':user възстанови покупка :expense', 'activity_39': ':user е отказал :payment_amount за плащане :payment', 'activity_40': - ':user е възстановил :adjustment на стойност :payment_amount за плащане :payment', + ':user е възстановил :adjustment на стойност :payment_amount за плащане :payment', 'activity_41': 'Отказани :payment_amount по плащане (:payment)', 'activity_42': ':user създаде задача :task', 'activity_43': ':user актуализира задача :task', @@ -3524,12 +3533,12 @@ mixin LocalizationsProvider on LocaleCodeAware { 'applied': 'Applied', 'include_recent_errors': 'Include recent errors from the logs', 'your_message_has_been_received': - 'We have received your message and will try to respond promptly.', + 'We have received your message and will try to respond promptly.', 'message': '訊息', 'from': '從', 'show_product_details': 'Show Product Details', 'show_product_details_help': - 'Include the description and cost in the product dropdown', + 'Include the description and cost in the product dropdown', 'pdf_min_requirements': 'The PDF renderer requires :version', 'adjust_fee_percent': 'Adjust Fee Percent', 'adjust_fee_percent_help': '調整百分比以計入費用', @@ -3546,7 +3555,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'domain_url': 'Domain URL', 'password_is_too_short': '密碼太短', 'password_is_too_easy': - 'Password must contain an upper case character and a number', + 'Password must contain an upper case character and a number', 'client_portal_tasks': 'Client Portal Tasks', 'client_portal_dashboard': 'Client Portal Dashboard', 'please_enter_a_value': 'Please enter a value', @@ -3573,16 +3582,16 @@ mixin LocalizationsProvider on LocaleCodeAware { 'third_custom': 'Third Custom', 'show_cost': 'Show Cost', 'show_cost_help': - 'Display a product cost field to track the markup/profit', + 'Display a product cost field to track the markup/profit', 'show_product_quantity': 'Show Product Quantity', 'show_product_quantity_help': - 'Display a product quantity field, otherwise default to one', + 'Display a product quantity field, otherwise default to one', 'show_invoice_quantity': 'Show Invoice Quantity', 'show_invoice_quantity_help': - 'Display a line item quantity field, otherwise default to one', + 'Display a line item quantity field, otherwise default to one', 'default_quantity': 'Default Quantity', 'default_quantity_help': - 'Automatically set the line item quantity to one', + 'Automatically set the line item quantity to one', 'one_tax_rate': 'One Tax Rate', 'two_tax_rates': 'Two Tax Rates', 'three_tax_rates': 'Three Tax Rates', @@ -3723,7 +3732,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'require_quote_signature': '報價單簽名', 'enable_portal_password': '用以保護發票的密碼', 'enable_portal_password_help': - '使您能夠為每位聯絡人設定密碼。若設定密碼,聯絡人將會在查看發票之前被要求輸入密碼。', + '使您能夠為每位聯絡人設定密碼。若設定密碼,聯絡人將會在查看發票之前被要求輸入密碼。', 'authorization': '授權', 'subdomain': '子網域', 'domain': '網域', @@ -4253,7 +4262,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'activity_8': ':user 已將發票 :invoice 歸檔', 'activity_9': ':user 已刪除發票 :invoice', 'activity_10': - ':contact entered payment :payment for :payment_amount on invoice :invoice for :client', + ':contact entered payment :payment for :payment_amount on invoice :invoice for :client', 'activity_11': ':user 已更新付款資料 :payment', 'activity_12': ':user 已將付款資料 :payment 歸檔', 'activity_13': ':user 已刪除付款資料 :payment', @@ -4402,7 +4411,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'purge_data': 'Purge Data', 'purge_successful': 'Successfully purged company data', 'purge_data_message': - 'Warning: This will permanently erase your data, there is no undo.', + 'Warning: This will permanently erase your data, there is no undo.', 'invoice_balance': 'Invoice Balance', 'age_group_0': '0 - 30 dana', 'age_group_30': '30 - 60 dana', @@ -4437,10 +4446,10 @@ mixin LocalizationsProvider on LocaleCodeAware { 'apply_license': 'Apply License', 'cancel_account': 'Izbriši korisnički račun', 'cancel_account_message': - 'Pozor: Ovo će trajno obrisati sve vaše podatke, nema povratka.', + 'Pozor: Ovo će trajno obrisati sve vaše podatke, nema povratka.', 'delete_company': 'Delete Company', 'delete_company_message': - 'Warning: This will permanently delete your company, there is no undo.', + 'Warning: This will permanently delete your company, there is no undo.', 'enable_modules': 'Enable Modules', 'converted_quote': 'Successfully converted quote', 'credit_design': 'Credit Design', @@ -4592,12 +4601,12 @@ mixin LocalizationsProvider on LocaleCodeAware { 'applied': 'Applied', 'include_recent_errors': 'Include recent errors from the logs', 'your_message_has_been_received': - 'We have received your message and will try to respond promptly.', + 'We have received your message and will try to respond promptly.', 'message': 'Poruka', 'from': 'Šalje', 'show_product_details': 'Show Product Details', 'show_product_details_help': - 'Include the description and cost in the product dropdown', + 'Include the description and cost in the product dropdown', 'pdf_min_requirements': 'The PDF renderer requires :version', 'adjust_fee_percent': 'Adjust Fee Percent', 'adjust_fee_percent_help': 'Adjust percent to account for fee', @@ -4614,7 +4623,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'domain_url': 'Domain URL', 'password_is_too_short': 'Password is too short', 'password_is_too_easy': - 'Password must contain an upper case character and a number', + 'Password must contain an upper case character and a number', 'client_portal_tasks': 'Client Portal Tasks', 'client_portal_dashboard': 'Client Portal Dashboard', 'please_enter_a_value': 'Please enter a value', @@ -4641,16 +4650,16 @@ mixin LocalizationsProvider on LocaleCodeAware { 'third_custom': 'Third Custom', 'show_cost': 'Show Cost', 'show_cost_help': - 'Display a product cost field to track the markup/profit', + 'Display a product cost field to track the markup/profit', 'show_product_quantity': 'Show Product Quantity', 'show_product_quantity_help': - 'Display a product quantity field, otherwise default to one', + 'Display a product quantity field, otherwise default to one', 'show_invoice_quantity': 'Show Invoice Quantity', 'show_invoice_quantity_help': - 'Display a line item quantity field, otherwise default to one', + 'Display a line item quantity field, otherwise default to one', 'default_quantity': 'Default Quantity', 'default_quantity_help': - 'Automatically set the line item quantity to one', + 'Automatically set the line item quantity to one', 'one_tax_rate': 'One Tax Rate', 'two_tax_rates': 'Two Tax Rates', 'three_tax_rates': 'Three Tax Rates', @@ -4695,7 +4704,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'filtered_by_user': 'Filtered by User', 'administrator': 'Administrator', 'administrator_help': - 'Allow user to manage users, change settings and modify all records', + 'Allow user to manage users, change settings and modify all records', 'user_management': 'Upravljanje korisnicima', 'users': 'Korisnici', 'new_user': 'Novi korisnik', @@ -4710,7 +4719,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'invoice_options': 'Opcije računa', 'hide_paid_to_date': 'Sakrij datum plaćanja', 'hide_paid_to_date_help': - 'Prikažite \"Datum plaćanja\" na računima, onda kada je uplata primljena.', + 'Prikažite \"Datum plaćanja\" na računima, onda kada je uplata primljena.', 'invoice_embed_documents': 'Ugrađeni dokumenti', 'invoice_embed_documents_help': 'Ubaci dodane dokumente u račun.', 'all_pages_header': 'Prikaži zaglavlje na', @@ -4733,16 +4742,16 @@ mixin LocalizationsProvider on LocaleCodeAware { 'quote_footer': 'Podnožje ponude', 'auto_email_invoice': 'Auto Email', 'auto_email_invoice_help': - 'Automatically email recurring invoices when they are created.', + 'Automatically email recurring invoices when they are created.', 'auto_archive_invoice': 'Auto Archive', 'auto_archive_invoice_help': - 'Automatically archive invoices when they are paid.', + 'Automatically archive invoices when they are paid.', 'auto_archive_quote': 'Auto Archive', 'auto_archive_quote_help': - 'Automatically archive quotes when they are converted.', + 'Automatically archive quotes when they are converted.', 'auto_convert_quote': 'Auto Convert', 'auto_convert_quote_help': - 'Automatski konvertirajte ponudu u račun nakon što je odobrena od strane klijenta.', + 'Automatski konvertirajte ponudu u račun nakon što je odobrena od strane klijenta.', 'workflow_settings': 'Workflow Settings', 'freq_daily': 'Daily', 'freq_weekly': 'Weekly', @@ -4788,27 +4797,27 @@ mixin LocalizationsProvider on LocaleCodeAware { 'custom_javascript': 'Custom JavaScript', 'signature_on_pdf': 'Pokaži na PDF-u', 'signature_on_pdf_help': - 'Show the client signature on the invoice/quote PDF.', + 'Show the client signature on the invoice/quote PDF.', 'show_accept_invoice_terms': 'Invoice Terms Checkbox', 'show_accept_invoice_terms_help': - 'Require client to confirm that they accept the invoice terms.', + 'Require client to confirm that they accept the invoice terms.', 'show_accept_quote_terms': 'Quote Terms Checkbox', 'show_accept_quote_terms_help': - 'Require client to confirm that they accept the quote terms.', + 'Require client to confirm that they accept the quote terms.', 'require_invoice_signature': 'Invoice Signature', 'require_invoice_signature_help': - 'Require client to provide their signature.', + 'Require client to provide their signature.', 'require_quote_signature': 'Quote Signature', 'enable_portal_password': 'Password Protect Invoices', 'enable_portal_password_help': - 'Allows you to set a password for each contact. If a password is set, the contact will be required to enter a password before viewing invoices.', + 'Allows you to set a password for each contact. If a password is set, the contact will be required to enter a password before viewing invoices.', 'authorization': 'Authorization', 'subdomain': 'Poddomena', 'domain': 'Domain', 'portal_mode': 'Portal Mode', 'email_signature': 'Srdačno,', 'enable_email_markup_help': - 'Olakšajte svojim klijentima plaćanje dodavanjem schema.org markupa vašoj e-pošti.', + 'Olakšajte svojim klijentima plaćanje dodavanjem schema.org markupa vašoj e-pošti.', 'plain': 'Obično', 'light': 'Svijetlo', 'dark': 'Tamno', @@ -4837,9 +4846,9 @@ mixin LocalizationsProvider on LocaleCodeAware { 'accepted_card_logos': 'Accepted Card Logos', 'credentials': 'Credentials', 'require_billing_address_help': - 'Require client to provide their billing address', + 'Require client to provide their billing address', 'require_shipping_address_help': - 'Require client to provide their shipping address', + 'Require client to provide their shipping address', 'update_address': 'Ažuriraj adresu', 'update_address_help': 'Ažuriraj adresu klijenta uz osigurane detalje', 'rate': 'Stopa', @@ -4853,13 +4862,13 @@ mixin LocalizationsProvider on LocaleCodeAware { 'restored_tax_rate': 'Successfully restored tax rate', 'fill_products': 'Proizvodi sa samoispunom', 'fill_products_help': - 'Odabir proizvoda će automatski ispuniti opis i cijenu', + 'Odabir proizvoda će automatski ispuniti opis i cijenu', 'update_products': 'Proizvidi sa autoažuriranjem', 'update_products_help': - 'Ažuriranje računa automatski ažurirati registar proizvoda', + 'Ažuriranje računa automatski ažurirati registar proizvoda', 'convert_products': 'Convert Products', 'convert_products_help': - 'Automatically convert product prices to the client\'s currency', + 'Automatically convert product prices to the client\'s currency', 'fees': 'Fees', 'limits': 'Limits', 'provider': 'Provider', @@ -4959,7 +4968,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'please_enter_a_first_name': 'Please enter a first name', 'please_enter_a_last_name': 'Please enter a last name', 'please_agree_to_terms_and_privacy': - 'Please agree to the terms of service and privacy policy to create an account.', + 'Please agree to the terms of service and privacy policy to create an account.', 'i_agree_to_the': 'I agree to the', 'terms_of_service_link': 'terms of service', 'privacy_policy_link': 'privacy policy', @@ -5058,7 +5067,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'average': 'Average', 'unapproved': 'Unapproved', 'authenticate_to_change_setting': - 'Please authenticate to change this setting', + 'Please authenticate to change this setting', 'locked': 'Locked', 'authenticate': 'Authenticate', 'please_authenticate': 'Please authenticate', @@ -5258,10 +5267,10 @@ mixin LocalizationsProvider on LocaleCodeAware { 'marked_invoices_as_paid': 'Successfully marked invoices as paid', 'done': 'Dovršeno', 'please_enter_a_client_or_contact_name': - 'Molimo upišite ime klijenta ili kontakta', + 'Molimo upišite ime klijenta ili kontakta', 'dark_mode': 'Tamni prikaz', 'restart_app_to_apply_change': - 'Ponovno pokrenite aplikaciju za primjenu promjena', + 'Ponovno pokrenite aplikaciju za primjenu promjena', 'refresh_data': 'Osvježi podatke', 'blank_contact': 'Prazan kontakt', 'activity': 'Aktivnost', @@ -5370,7 +5379,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'activity_37': ':user restored expense :expense', 'activity_39': ':user cancelled a :payment_amount payment :payment', 'activity_40': - ':user refunded :adjustment of a :payment_amount payment :payment', + ':user refunded :adjustment of a :payment_amount payment :payment', 'activity_41': ':payment_amount payment (:payment) failed', 'activity_42': ':user created task :task', 'activity_43': ':user updated task :task', @@ -5490,7 +5499,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'purge_data': 'Purge Data', 'purge_successful': 'Successfully purged company data', 'purge_data_message': - 'Warning: This will permanently erase your data, there is no undo.', + 'Warning: This will permanently erase your data, there is no undo.', 'invoice_balance': 'Invoice Balance', 'age_group_0': '0 - 30 Days', 'age_group_30': '30 - 60 Days', @@ -5525,10 +5534,10 @@ mixin LocalizationsProvider on LocaleCodeAware { 'apply_license': 'Apply License', 'cancel_account': 'Smazat účet', 'cancel_account_message': - 'Varování: Toto permanentně odstraní Váš účet. Tato akce je nevratná.', + 'Varování: Toto permanentně odstraní Váš účet. Tato akce je nevratná.', 'delete_company': 'Delete Company', 'delete_company_message': - 'Warning: This will permanently delete your company, there is no undo.', + 'Warning: This will permanently delete your company, there is no undo.', 'enable_modules': 'Enable Modules', 'converted_quote': 'Successfully converted quote', 'credit_design': 'Credit Design', @@ -5680,12 +5689,12 @@ mixin LocalizationsProvider on LocaleCodeAware { 'applied': 'Applied', 'include_recent_errors': 'Include recent errors from the logs', 'your_message_has_been_received': - 'We have received your message and will try to respond promptly.', + 'We have received your message and will try to respond promptly.', 'message': 'Zpráva', 'from': 'Od', 'show_product_details': 'Show Product Details', 'show_product_details_help': - 'Include the description and cost in the product dropdown', + 'Include the description and cost in the product dropdown', 'pdf_min_requirements': 'The PDF renderer requires :version', 'adjust_fee_percent': 'Adjust Fee Percent', 'adjust_fee_percent_help': 'Adjust percent to account for fee', @@ -5702,7 +5711,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'domain_url': 'Domain URL', 'password_is_too_short': 'Password is too short', 'password_is_too_easy': - 'Password must contain an upper case character and a number', + 'Password must contain an upper case character and a number', 'client_portal_tasks': 'Client Portal Tasks', 'client_portal_dashboard': 'Client Portal Dashboard', 'please_enter_a_value': 'Please enter a value', @@ -5729,16 +5738,16 @@ mixin LocalizationsProvider on LocaleCodeAware { 'third_custom': 'Third Custom', 'show_cost': 'Show Cost', 'show_cost_help': - 'Display a product cost field to track the markup/profit', + 'Display a product cost field to track the markup/profit', 'show_product_quantity': 'Show Product Quantity', 'show_product_quantity_help': - 'Display a product quantity field, otherwise default to one', + 'Display a product quantity field, otherwise default to one', 'show_invoice_quantity': 'Show Invoice Quantity', 'show_invoice_quantity_help': - 'Display a line item quantity field, otherwise default to one', + 'Display a line item quantity field, otherwise default to one', 'default_quantity': 'Default Quantity', 'default_quantity_help': - 'Automatically set the line item quantity to one', + 'Automatically set the line item quantity to one', 'one_tax_rate': 'One Tax Rate', 'two_tax_rates': 'Two Tax Rates', 'three_tax_rates': 'Three Tax Rates', @@ -5783,7 +5792,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'filtered_by_user': 'Filtered by User', 'administrator': 'Administrátor', 'administrator_help': - 'Povolit uživatelům spravovat další uživatele, měnit nastavení a všechny záznamy', + 'Povolit uživatelům spravovat další uživatele, měnit nastavení a všechny záznamy', 'user_management': 'Správa uživatelů', 'users': 'Uživatelé', 'new_user': 'Nový uživatel', @@ -5798,7 +5807,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'invoice_options': 'Možnosti faktury', 'hide_paid_to_date': 'Skrýt Zaplaceno ke dni', 'hide_paid_to_date_help': - 'Zobrazit na faktuře \"Zaplaceno ke dni\" pouze když přijde platba.', + 'Zobrazit na faktuře \"Zaplaceno ke dni\" pouze když přijde platba.', 'invoice_embed_documents': 'Embed Documents', 'invoice_embed_documents_help': 'Include attached images in the invoice.', 'all_pages_header': 'Zobrazit hlavičku', @@ -5821,16 +5830,16 @@ mixin LocalizationsProvider on LocaleCodeAware { 'quote_footer': 'Patička nabídky', 'auto_email_invoice': 'Auto Email', 'auto_email_invoice_help': - 'Automatically email recurring invoices when they are created.', + 'Automatically email recurring invoices when they are created.', 'auto_archive_invoice': 'Auto Archive', 'auto_archive_invoice_help': - 'Automatically archive invoices when they are paid.', + 'Automatically archive invoices when they are paid.', 'auto_archive_quote': 'Auto Archive', 'auto_archive_quote_help': - 'Automatically archive quotes when they are converted.', + 'Automatically archive quotes when they are converted.', 'auto_convert_quote': 'Auto Convert', 'auto_convert_quote_help': - 'Automaticky zkonvertovat nabídku na fakturu po schválení klientem.', + 'Automaticky zkonvertovat nabídku na fakturu po schválení klientem.', 'workflow_settings': 'Workflow Settings', 'freq_daily': 'Daily', 'freq_weekly': 'týdně', @@ -5876,27 +5885,27 @@ mixin LocalizationsProvider on LocaleCodeAware { 'custom_javascript': 'Custom JavaScript', 'signature_on_pdf': 'Show on PDF', 'signature_on_pdf_help': - 'Show the client signature on the invoice/quote PDF.', + 'Show the client signature on the invoice/quote PDF.', 'show_accept_invoice_terms': 'Invoice Terms Checkbox', 'show_accept_invoice_terms_help': - 'Require client to confirm that they accept the invoice terms.', + 'Require client to confirm that they accept the invoice terms.', 'show_accept_quote_terms': 'Quote Terms Checkbox', 'show_accept_quote_terms_help': - 'Require client to confirm that they accept the quote terms.', + 'Require client to confirm that they accept the quote terms.', 'require_invoice_signature': 'Invoice Signature', 'require_invoice_signature_help': - 'Require client to provide their signature.', + 'Require client to provide their signature.', 'require_quote_signature': 'Quote Signature', 'enable_portal_password': 'Password Protect Invoices', 'enable_portal_password_help': - 'Umožní Vám nastavit heslo pro každý kontakt. Pokud heslo nastavíte, tak kontakt ho bude pro zobrazení faktury vždy použít.', + 'Umožní Vám nastavit heslo pro každý kontakt. Pokud heslo nastavíte, tak kontakt ho bude pro zobrazení faktury vždy použít.', 'authorization': 'Schválení', 'subdomain': 'subdoména', 'domain': 'Domain', 'portal_mode': 'Portal Mode', 'email_signature': 'S pozdravem,', 'enable_email_markup_help': - 'Přidejte si mikroznačky schema.org do emailu a usnadněte tak vašim klientům platby.', + 'Přidejte si mikroznačky schema.org do emailu a usnadněte tak vašim klientům platby.', 'plain': 'Prostý text', 'light': 'Světlý', 'dark': 'Tmavý', @@ -5925,9 +5934,9 @@ mixin LocalizationsProvider on LocaleCodeAware { 'accepted_card_logos': 'Accepted Card Logos', 'credentials': 'Credentials', 'require_billing_address_help': - 'Require client to provide their billing address', + 'Require client to provide their billing address', 'require_shipping_address_help': - 'Require client to provide their shipping address', + 'Require client to provide their shipping address', 'update_address': 'Změnit adresu', 'update_address_help': 'Změnit adresu klienta podle poskytnutých detailů', 'rate': 'Sazba', @@ -5941,13 +5950,13 @@ mixin LocalizationsProvider on LocaleCodeAware { 'restored_tax_rate': 'Successfully restored tax rate', 'fill_products': 'Automaticky předvyplnit produkty', 'fill_products_help': - 'Výběr produktu automaticky vyplní popis a cenu', + 'Výběr produktu automaticky vyplní popis a cenu', 'update_products': 'Automaticky aktualizovat produkty', 'update_products_help': - 'Změna na faktuře automaticky aktualizuje katalog produktů', + 'Změna na faktuře automaticky aktualizuje katalog produktů', 'convert_products': 'Convert Products', 'convert_products_help': - 'Automatically convert product prices to the client\'s currency', + 'Automatically convert product prices to the client\'s currency', 'fees': 'Fees', 'limits': 'Limits', 'provider': 'Provider', @@ -6047,7 +6056,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'please_enter_a_first_name': 'Please enter a first name', 'please_enter_a_last_name': 'Please enter a last name', 'please_agree_to_terms_and_privacy': - 'Please agree to the terms of service and privacy policy to create an account.', + 'Please agree to the terms of service and privacy policy to create an account.', 'i_agree_to_the': 'I agree to the', 'terms_of_service_link': 'terms of service', 'privacy_policy_link': 'privacy policy', @@ -6146,7 +6155,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'average': 'Average', 'unapproved': 'Unapproved', 'authenticate_to_change_setting': - 'Please authenticate to change this setting', + 'Please authenticate to change this setting', 'locked': 'Locked', 'authenticate': 'Authenticate', 'please_authenticate': 'Please authenticate', @@ -6346,7 +6355,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'marked_invoices_as_paid': 'Successfully marked invoices as paid', 'done': 'Hotovo', 'please_enter_a_client_or_contact_name': - 'Please enter a client or contact name', + 'Please enter a client or contact name', 'dark_mode': 'Tmavý mód', 'restart_app_to_apply_change': 'Restart the app to apply the change', 'refresh_data': 'Refresh Data', @@ -6424,12 +6433,12 @@ mixin LocalizationsProvider on LocaleCodeAware { 'activity_4': ':user vytvořil fakturu :invoice', 'activity_5': ':user změnil fakturu :invoice', 'activity_6': - ':user poslal email s fakturou :invoice pro :client na :contact', + ':user poslal email s fakturou :invoice pro :client na :contact', 'activity_7': 'Klient :contact zobrazil fakturu :invoice pro :client', 'activity_8': ':user archivoval fakturu :invoice', 'activity_9': ':user smazal fakturu :invoice', 'activity_10': - ':contact entered payment :payment for :payment_amount on invoice :invoice for :client', + ':contact entered payment :payment for :payment_amount on invoice :invoice for :client', 'activity_11': ':user změnil platbu :payment', 'activity_12': ':user archivoval platbu :payment', 'activity_13': ':user smazal platbu :payment', @@ -6459,7 +6468,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'activity_37': ':user restored expense :expense', 'activity_39': ':user cancelled a :payment_amount payment :payment', 'activity_40': - ':user refunded :adjustment of a :payment_amount payment :payment', + ':user refunded :adjustment of a :payment_amount payment :payment', 'activity_41': ':payment_amount payment (:payment) failed', 'activity_42': ':user created task :task', 'activity_43': ':user updated task :task', @@ -6579,7 +6588,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'purge_data': 'Purge Data', 'purge_successful': 'Successfully purged company data', 'purge_data_message': - 'Advarsel: Dette vil slette dine data permanent, der er ingen måder at fortryde.', + 'Advarsel: Dette vil slette dine data permanent, der er ingen måder at fortryde.', 'invoice_balance': 'Invoice Balance', 'age_group_0': '0 - 30 dage', 'age_group_30': '30 - 60 dage', @@ -6614,10 +6623,10 @@ mixin LocalizationsProvider on LocaleCodeAware { 'apply_license': 'Anvend licens', 'cancel_account': 'Annuller konto', 'cancel_account_message': - 'ADVARSEL: Dette vil permanent slette din konto, der er INGEN mulighed for at fortryde.', + 'ADVARSEL: Dette vil permanent slette din konto, der er INGEN mulighed for at fortryde.', 'delete_company': 'Delete Company', 'delete_company_message': - 'Warning: This will permanently delete your company, there is no undo.', + 'Warning: This will permanently delete your company, there is no undo.', 'enable_modules': 'Enable Modules', 'converted_quote': 'Successfully converted quote', 'credit_design': 'Credit Design', @@ -6769,12 +6778,12 @@ mixin LocalizationsProvider on LocaleCodeAware { 'applied': 'Applied', 'include_recent_errors': 'Include recent errors from the logs', 'your_message_has_been_received': - 'We have received your message and will try to respond promptly.', + 'We have received your message and will try to respond promptly.', 'message': 'Besked', 'from': 'Fra', 'show_product_details': 'Show Product Details', 'show_product_details_help': - 'Include the description and cost in the product dropdown', + 'Include the description and cost in the product dropdown', 'pdf_min_requirements': 'The PDF renderer requires :version', 'adjust_fee_percent': 'Adjust Fee Percent', 'adjust_fee_percent_help': 'Adjust percent to account for fee', @@ -6791,7 +6800,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'domain_url': 'Domain URL', 'password_is_too_short': 'Password is too short', 'password_is_too_easy': - 'Password must contain an upper case character and a number', + 'Password must contain an upper case character and a number', 'client_portal_tasks': 'Client Portal Tasks', 'client_portal_dashboard': 'Client Portal Dashboard', 'please_enter_a_value': 'Please enter a value', @@ -6818,16 +6827,16 @@ mixin LocalizationsProvider on LocaleCodeAware { 'third_custom': 'Third Custom', 'show_cost': 'Show Cost', 'show_cost_help': - 'Display a product cost field to track the markup/profit', + 'Display a product cost field to track the markup/profit', 'show_product_quantity': 'Show Product Quantity', 'show_product_quantity_help': - 'Display a product quantity field, otherwise default to one', + 'Display a product quantity field, otherwise default to one', 'show_invoice_quantity': 'Show Invoice Quantity', 'show_invoice_quantity_help': - 'Display a line item quantity field, otherwise default to one', + 'Display a line item quantity field, otherwise default to one', 'default_quantity': 'Default Quantity', 'default_quantity_help': - 'Automatically set the line item quantity to one', + 'Automatically set the line item quantity to one', 'one_tax_rate': 'One Tax Rate', 'two_tax_rates': 'Two Tax Rates', 'three_tax_rates': 'Three Tax Rates', @@ -6872,7 +6881,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'filtered_by_user': 'Filtered by User', 'administrator': 'Administrator', 'administrator_help': - 'Allow user to manage users, change settings and modify all records', + 'Allow user to manage users, change settings and modify all records', 'user_management': 'Brugerhåndtering', 'users': 'Brugere', 'new_user': 'New User', @@ -6887,7 +6896,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'invoice_options': 'Fakturaindstillinger', 'hide_paid_to_date': 'Skjul delbetalinger', 'hide_paid_to_date_help': - 'Vis kun delbetalinger hvis der er forekommet en delbetaling.', + 'Vis kun delbetalinger hvis der er forekommet en delbetaling.', 'invoice_embed_documents': 'Embed Documents', 'invoice_embed_documents_help': 'Include attached images in the invoice.', 'all_pages_header': 'Show header on', @@ -6910,16 +6919,16 @@ mixin LocalizationsProvider on LocaleCodeAware { 'quote_footer': 'Quote Footer', 'auto_email_invoice': 'Auto Email', 'auto_email_invoice_help': - 'Automatically email recurring invoices when they are created.', + 'Automatically email recurring invoices when they are created.', 'auto_archive_invoice': 'Auto Archive', 'auto_archive_invoice_help': - 'Automatically archive invoices when they are paid.', + 'Automatically archive invoices when they are paid.', 'auto_archive_quote': 'Auto Archive', 'auto_archive_quote_help': - 'Automatically archive quotes when they are converted.', + 'Automatically archive quotes when they are converted.', 'auto_convert_quote': 'Auto konvertering', 'auto_convert_quote_help': - 'Automatically convert a quote to an invoice when approved by a client.', + 'Automatically convert a quote to an invoice when approved by a client.', 'workflow_settings': 'Workflow Settings', 'freq_daily': 'Daglig', 'freq_weekly': 'Ugentlig', @@ -6965,27 +6974,27 @@ mixin LocalizationsProvider on LocaleCodeAware { 'custom_javascript': 'Custom JavaScript', 'signature_on_pdf': 'Show on PDF', 'signature_on_pdf_help': - 'Show the client signature on the invoice/quote PDF.', + 'Show the client signature on the invoice/quote PDF.', 'show_accept_invoice_terms': 'Afkrydsningsfelt for fakturavilkår', 'show_accept_invoice_terms_help': - 'Bed kunden om at bekræfte, at de accepterer fakturavilkårene.', + 'Bed kunden om at bekræfte, at de accepterer fakturavilkårene.', 'show_accept_quote_terms': 'Tilbuds Betingelser Afkrydsningsfelt', 'show_accept_quote_terms_help': - 'Bed kunden om at bekræfte, at de accepterer tilbudsbetingelserne.', + 'Bed kunden om at bekræfte, at de accepterer tilbudsbetingelserne.', 'require_invoice_signature': 'Fakturasignatur', 'require_invoice_signature_help': - 'Kræv at klienten giver deres underskrift.', + 'Kræv at klienten giver deres underskrift.', 'require_quote_signature': 'Tilbuds underskrift', 'enable_portal_password': 'Adgangskodebeskyttet Fakturaer', 'enable_portal_password_help': - 'Lader dig indtaste en adgangskode til hver kontakt. Hvis en adgangskode ikke er lavet, vil kontakten blive pålagt at indtaste en adgangskode før det er muligt at se fakturaer.', + 'Lader dig indtaste en adgangskode til hver kontakt. Hvis en adgangskode ikke er lavet, vil kontakten blive pålagt at indtaste en adgangskode før det er muligt at se fakturaer.', 'authorization': 'Autorisation', 'subdomain': 'Underdomain', 'domain': 'Domæne', 'portal_mode': 'Portal Mode', 'email_signature': 'Venlig hilsen,', 'enable_email_markup_help': - 'Gør det lettere for dine klienter at betale dig ved at tilføje schema.org markup i dine e-mails.', + 'Gør det lettere for dine klienter at betale dig ved at tilføje schema.org markup i dine e-mails.', 'plain': 'Plain', 'light': 'Light', 'dark': 'Dark', @@ -7014,9 +7023,9 @@ mixin LocalizationsProvider on LocaleCodeAware { 'accepted_card_logos': 'Accepted Card Logos', 'credentials': 'Credentials', 'require_billing_address_help': - 'Require client to provide their billing address', + 'Require client to provide their billing address', 'require_shipping_address_help': - 'Require client to provide their shipping address', + 'Require client to provide their shipping address', 'update_address': 'Opdater adresse', 'update_address_help': 'Opdater kundens adresse med de opgivne detaljer', 'rate': 'Sats', @@ -7030,13 +7039,13 @@ mixin LocalizationsProvider on LocaleCodeAware { 'restored_tax_rate': 'Successfully restored tax rate', 'fill_products': 'Automatisk-udfyld produkter', 'fill_products_help': - 'Valg af produkt vil automatisk udfylde beskrivelse og pris', + 'Valg af produkt vil automatisk udfylde beskrivelse og pris', 'update_products': 'Automatisk opdatering af produkter', 'update_products_help': - 'En opdatering af en faktura vil automatisk opdaterer Produkt biblioteket', + 'En opdatering af en faktura vil automatisk opdaterer Produkt biblioteket', 'convert_products': 'Convert Products', 'convert_products_help': - 'Automatically convert product prices to the client\'s currency', + 'Automatically convert product prices to the client\'s currency', 'fees': 'Gebyrer', 'limits': 'Grænser', 'provider': 'Provider', @@ -7136,7 +7145,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'please_enter_a_first_name': 'Please enter a first name', 'please_enter_a_last_name': 'Please enter a last name', 'please_agree_to_terms_and_privacy': - 'Please agree to the terms of service and privacy policy to create an account.', + 'Please agree to the terms of service and privacy policy to create an account.', 'i_agree_to_the': 'I agree to the', 'terms_of_service_link': 'terms of service', 'privacy_policy_link': 'privacy policy', @@ -7235,7 +7244,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'average': 'Average', 'unapproved': 'Unapproved', 'authenticate_to_change_setting': - 'Please authenticate to change this setting', + 'Please authenticate to change this setting', 'locked': 'Locked', 'authenticate': 'Authenticate', 'please_authenticate': 'Please authenticate', @@ -7435,7 +7444,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'marked_invoices_as_paid': 'Successfully marked invoices as paid', 'done': 'Færdig', 'please_enter_a_client_or_contact_name': - 'Please enter a client or contact name', + 'Please enter a client or contact name', 'dark_mode': 'Mørk tilstand', 'restart_app_to_apply_change': 'Restart the app to apply the change', 'refresh_data': 'Refresh Data', @@ -7513,12 +7522,12 @@ mixin LocalizationsProvider on LocaleCodeAware { 'activity_4': ':user oprettede faktura :invoice', 'activity_5': ':user ajourførte faktura :invoice', 'activity_6': - ':user emailede fakturaen :invoice for :client til :contact', + ':user emailede fakturaen :invoice for :client til :contact', 'activity_7': ':contact læste faktura :invoice for :client', 'activity_8': ':user arkiverede faktura :invoice', 'activity_9': ':user slettede faktura :invoice', 'activity_10': - ':contact indtastede betaling :payment for :payment_amout i fakturaen :invoice for :client', + ':contact indtastede betaling :payment for :payment_amout i fakturaen :invoice for :client', 'activity_11': ':user ajourførte betaling :payment', 'activity_12': ':user arkiverede betaling :payment', 'activity_13': ':user slettede betaling :payment', @@ -7548,7 +7557,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'activity_37': ':user genskabte udgiften :expense', 'activity_39': ':user annullerede en :payment_amount betaling :payment', 'activity_40': - ':bruger refunderet :justering af en :betaling_beløb betaling :betaling', + ':bruger refunderet :justering af en :betaling_beløb betaling :betaling', 'activity_41': ':payment_amount betaling (:betaling) mislykkedes', 'activity_42': ':user oprettede opgaven :task', 'activity_43': ':user opdaterede opgaven :task', @@ -7668,7 +7677,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'purge_data': 'Wis gegevens', 'purge_successful': 'De bedrijfsgegevens zijn gewist', 'purge_data_message': - 'Waarschuwing: Dit zal uw gegevens verwijderen. Er is geen manier om dit ongedaan te maken.', + 'Waarschuwing: Dit zal uw gegevens verwijderen. Er is geen manier om dit ongedaan te maken.', 'invoice_balance': 'Invoice Balance', 'age_group_0': '0 - 30 dagen', 'age_group_30': '30 - 60 dagen', @@ -7703,10 +7712,10 @@ mixin LocalizationsProvider on LocaleCodeAware { 'apply_license': 'Activeer licentie', 'cancel_account': 'Account verwijderen', 'cancel_account_message': - 'Waarschuwing: Dit zal uw account verwijderen. Er is geen manier om dit ongedaan te maken.', + 'Waarschuwing: Dit zal uw account verwijderen. Er is geen manier om dit ongedaan te maken.', 'delete_company': 'Verwijder bedrijf', 'delete_company_message': - 'Waarschuwing: Hiermee verwijder je permanent je bedrijf, dit kan niet worden ontdaan.', + 'Waarschuwing: Hiermee verwijder je permanent je bedrijf, dit kan niet worden ontdaan.', 'enable_modules': 'Enable Modules', 'converted_quote': 'Successfully converted quote', 'credit_design': 'Credit Design', @@ -7858,16 +7867,16 @@ mixin LocalizationsProvider on LocaleCodeAware { 'applied': 'Toegepast', 'include_recent_errors': 'Include recent errors from the logs', 'your_message_has_been_received': - 'We hebben uw bericht ontvangen, en zullen zo spoedig mogelijk reageren.', + 'We hebben uw bericht ontvangen, en zullen zo spoedig mogelijk reageren.', 'message': 'Bericht', 'from': 'Van', 'show_product_details': 'toon product details', 'show_product_details_help': - 'Include the description and cost in the product dropdown', + 'Include the description and cost in the product dropdown', 'pdf_min_requirements': 'The PDF renderer requires :version', 'adjust_fee_percent': 'Adjust Fee Percent', 'adjust_fee_percent_help': - 'Pas percentage aan om rekening te houden met de kosten', + 'Pas percentage aan om rekening te houden met de kosten', 'configure_settings': 'Configure Settings', 'support_forum': 'Support Forum', 'about': 'Over', @@ -7881,7 +7890,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'domain_url': 'Domain URL', 'password_is_too_short': 'Wachtwoord is te kort', 'password_is_too_easy': - 'Password must contain an upper case character and a number', + 'Password must contain an upper case character and a number', 'client_portal_tasks': 'Client Portal Tasks', 'client_portal_dashboard': 'Client Portal Dashboard', 'please_enter_a_value': 'Please enter a value', @@ -7908,16 +7917,16 @@ mixin LocalizationsProvider on LocaleCodeAware { 'third_custom': 'Third Custom', 'show_cost': 'Show Cost', 'show_cost_help': - 'Display a product cost field to track the markup/profit', + 'Display a product cost field to track the markup/profit', 'show_product_quantity': 'Show Product Quantity', 'show_product_quantity_help': - 'Display a product quantity field, otherwise default to one', + 'Display a product quantity field, otherwise default to one', 'show_invoice_quantity': 'Show Invoice Quantity', 'show_invoice_quantity_help': - 'Display a line item quantity field, otherwise default to one', + 'Display a line item quantity field, otherwise default to one', 'default_quantity': 'Default Quantity', 'default_quantity_help': - 'Automatically set the line item quantity to one', + 'Automatically set the line item quantity to one', 'one_tax_rate': 'One Tax Rate', 'two_tax_rates': 'Two Tax Rates', 'three_tax_rates': 'Three Tax Rates', @@ -7962,7 +7971,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'filtered_by_user': 'Gefilterd door gebruiker', 'administrator': 'Beheerder', 'administrator_help': - 'Geef gebruiker de toestemming om andere gebruikers te beheren, instellingen te wijzigen en alle regels te bewerken.', + 'Geef gebruiker de toestemming om andere gebruikers te beheren, instellingen te wijzigen en alle regels te bewerken.', 'user_management': 'Gebruikersbeheer', 'users': 'Gebruikers', 'new_user': 'Nieuwe Gebruiker', @@ -7977,10 +7986,10 @@ mixin LocalizationsProvider on LocaleCodeAware { 'invoice_options': 'Factuuropties', 'hide_paid_to_date': 'Verberg \"Reeds betaald\"', 'hide_paid_to_date_help': - 'Toon alleen het \"Reeds betaald\" gebied op je facturen als er een betaling gemaakt is.', + 'Toon alleen het \"Reeds betaald\" gebied op je facturen als er een betaling gemaakt is.', 'invoice_embed_documents': 'Documenten invoegen', 'invoice_embed_documents_help': - 'Bijgevoegde afbeeldingen weergeven in de factuur.', + 'Bijgevoegde afbeeldingen weergeven in de factuur.', 'all_pages_header': 'Toon header op', 'all_pages_footer': 'Toon footer op', 'first_page': 'eerste pagina', @@ -8001,16 +8010,16 @@ mixin LocalizationsProvider on LocaleCodeAware { 'quote_footer': 'Offertevoettekst', 'auto_email_invoice': 'Automatisch e-mailen', 'auto_email_invoice_help': - 'Verzend terugkerende facturen automatisch wanneer ze worden gemaakt.', + 'Verzend terugkerende facturen automatisch wanneer ze worden gemaakt.', 'auto_archive_invoice': 'Automatisch archiveren', 'auto_archive_invoice_help': - 'Facturen automatisch archiveren wanneer ze worden betaald.', + 'Facturen automatisch archiveren wanneer ze worden betaald.', 'auto_archive_quote': 'Automatisch archiveren', 'auto_archive_quote_help': - 'Offertes automatisch archiveren wanneer ze zijn omgezet.', + 'Offertes automatisch archiveren wanneer ze zijn omgezet.', 'auto_convert_quote': 'Automatisch omzetten', 'auto_convert_quote_help': - 'Zet een offerte automatisch om in een factuur zodra deze door een klant wordt goedgekeurd.', + 'Zet een offerte automatisch om in een factuur zodra deze door een klant wordt goedgekeurd.', 'workflow_settings': 'Workflow instellingen', 'freq_daily': 'Dagelijks', 'freq_weekly': 'Wekelijks', @@ -8056,27 +8065,27 @@ mixin LocalizationsProvider on LocaleCodeAware { 'custom_javascript': 'Zelfgeschreven JavaScript', 'signature_on_pdf': 'Weergeven op PDF', 'signature_on_pdf_help': - 'Toon de handtekening van de klant op de factuur/offerte PDF.', + 'Toon de handtekening van de klant op de factuur/offerte PDF.', 'show_accept_invoice_terms': 'Factuurvoorwaarden checkbox', 'show_accept_invoice_terms_help': - 'Verplicht de klant om akkoord te gaan met de factuurvoorwaarden.', + 'Verplicht de klant om akkoord te gaan met de factuurvoorwaarden.', 'show_accept_quote_terms': 'Offertevoorwaarden checkbox', 'show_accept_quote_terms_help': - 'Verplicht de klant om akkoord te gaan met de offertevoorwaarden.', + 'Verplicht de klant om akkoord te gaan met de offertevoorwaarden.', 'require_invoice_signature': 'Factuur handtekening', 'require_invoice_signature_help': - 'Verplicht de klant om zijn handtekening te zetten.', + 'Verplicht de klant om zijn handtekening te zetten.', 'require_quote_signature': 'Offerte handtekening', 'enable_portal_password': 'Facturen beveiligen met een wachtwoord', 'enable_portal_password_help': - 'Geeft u de mogelijkheid om een wachtwoord in te stellen voor elke contactpersoon. Als er een wachtwoord is ingesteld moet de contactpersoon het wachtwoord invoeren voordat deze facturen kan bekijken.', + 'Geeft u de mogelijkheid om een wachtwoord in te stellen voor elke contactpersoon. Als er een wachtwoord is ingesteld moet de contactpersoon het wachtwoord invoeren voordat deze facturen kan bekijken.', 'authorization': 'Autorisatie', 'subdomain': 'Subdomein', 'domain': 'Domein', 'portal_mode': 'portaalmodus', 'email_signature': 'Met vriendelijke groeten,', 'enable_email_markup_help': - 'Maak het gemakkelijker voor uw klanten om te betalen door scherma.org opmaak toe te voegen aan uw e-mails.', + 'Maak het gemakkelijker voor uw klanten om te betalen door scherma.org opmaak toe te voegen aan uw e-mails.', 'plain': 'Platte tekst', 'light': 'Licht', 'dark': 'Donker', @@ -8105,12 +8114,12 @@ mixin LocalizationsProvider on LocaleCodeAware { 'accepted_card_logos': 'Geaccepteerde kaart logo\'s', 'credentials': 'Gegevens', 'require_billing_address_help': - 'Verplicht de klant om zijn factuuradres op te geven', + 'Verplicht de klant om zijn factuuradres op te geven', 'require_shipping_address_help': - 'Verplicht de klant om zijn verzendadres op te geven', + 'Verplicht de klant om zijn verzendadres op te geven', 'update_address': 'Adres aanpassen', 'update_address_help': - 'Pas het adres van de klant aan met de ingevulde gegevens', + 'Pas het adres van de klant aan met de ingevulde gegevens', 'rate': 'Tarief', 'tax_rate': 'BTW-tarief', 'new_tax_rate': 'Nieuw BTW-tarief', @@ -8122,13 +8131,13 @@ mixin LocalizationsProvider on LocaleCodeAware { 'restored_tax_rate': 'De BTW heffing is teruggezet', 'fill_products': 'Producten Automatisch aanvullen', 'fill_products_help': - 'Een product selecteren zal automatisch de beschrijving en kosten instellen', + 'Een product selecteren zal automatisch de beschrijving en kosten instellen', 'update_products': 'Producten automatisch wijzigen', 'update_products_help': - 'Het wijzigen van een factuur zal automatisch de producten aanpassen', + 'Het wijzigen van een factuur zal automatisch de producten aanpassen', 'convert_products': 'Producten omzetten', 'convert_products_help': - 'Productprijzen automatisch converteren naar het valuta van de klant', + 'Productprijzen automatisch converteren naar het valuta van de klant', 'fees': 'Transactiekosten', 'limits': 'Limieten', 'provider': 'Provider', @@ -8228,7 +8237,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'please_enter_a_first_name': 'Vul een voornaam in aub', 'please_enter_a_last_name': 'Vul een naam in aub', 'please_agree_to_terms_and_privacy': - 'Ga akkoord met de servicevoorwaarden en het privacybeleid om een account aan te maken.', + 'Ga akkoord met de servicevoorwaarden en het privacybeleid om een account aan te maken.', 'i_agree_to_the': 'Ik ga akkoord met', 'terms_of_service_link': 'de servicevoorwaarden', 'privacy_policy_link': 'het privacybeleid', @@ -8327,7 +8336,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'average': 'Gemiddeld', 'unapproved': 'Afgekeurd', 'authenticate_to_change_setting': - 'Gelieve te authenticeren om deze instelling te wijzigen', + 'Gelieve te authenticeren om deze instelling te wijzigen', 'locked': 'Vergrendeld', 'authenticate': 'Authenticeer', 'please_authenticate': 'Gelieve te authenticeren', @@ -8512,7 +8521,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'updated_at': 'Bijgewerkt', 'tax': 'Belasting', 'please_enter_an_invoice_number': - 'Gelieve een factuurnummer in te voeren', + 'Gelieve een factuurnummer in te voeren', 'please_enter_a_quote_number': 'Gelieve een offertenummer in te voeren', 'past_due': 'Verlopen', 'draft': 'Concept', @@ -8528,10 +8537,10 @@ mixin LocalizationsProvider on LocaleCodeAware { 'marked_invoices_as_paid': 'Successfully marked invoices as paid', 'done': 'Klaar', 'please_enter_a_client_or_contact_name': - 'Gelieve een bedrijfsnaam of contactpersoon in te voeren', + 'Gelieve een bedrijfsnaam of contactpersoon in te voeren', 'dark_mode': 'Donkere modus', 'restart_app_to_apply_change': - 'Herstart de applicatie om de wijziging toe te passen', + 'Herstart de applicatie om de wijziging toe te passen', 'refresh_data': 'Gegevens verversen', 'blank_contact': 'Leeg contact', 'activity': 'Activiteit', @@ -8607,12 +8616,12 @@ mixin LocalizationsProvider on LocaleCodeAware { 'activity_4': ':user heeft factuur :invoice aangemaakt', 'activity_5': ':user heeft factuur :invoice bijgewerkt', 'activity_6': - ':user heeft factuur :invoice voor :client naar :contact verstuurd', + ':user heeft factuur :invoice voor :client naar :contact verstuurd', 'activity_7': ':contact heeft factuur :invoice voor :client bekeken', 'activity_8': ':user heeft factuur :invoice gearchiveerd', 'activity_9': ':user heeft factuur :invoice verwijderd', 'activity_10': - ':contact heeft betaling :payment van :payment_amount ingevoerd voor factuur :invoice voor :client', + ':contact heeft betaling :payment van :payment_amount ingevoerd voor factuur :invoice voor :client', 'activity_11': ':user heeft betaling :payment bijgewerkt', 'activity_12': ':user heeft betaling :payment gearchiveerd', 'activity_13': ':user heeft betaling :payment verwijderd', @@ -8623,7 +8632,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'activity_18': ':user heeft offerte :quote aangemaakt', 'activity_19': ':user heeft offerte :quote bijgewerkt', 'activity_20': - ':user heeft offerte :quote voor :client verstuurd naar :contact', + ':user heeft offerte :quote voor :client verstuurd naar :contact', 'activity_21': ':contact heeft offerte :quote bekeken', 'activity_22': ':user heeft offerte :quote gearchiveerd', 'activity_23': ':user heeft offerte :quote verwijderd', @@ -8642,9 +8651,9 @@ mixin LocalizationsProvider on LocaleCodeAware { 'activity_36': ':user heeft uitgave :expense verwijderd', 'activity_37': ':user heeft uitgave :expense hersteld', 'activity_39': - ':user heeft een a :payment_amount betaling geannuleerd :payment', + ':user heeft een a :payment_amount betaling geannuleerd :payment', 'activity_40': - ':user heeft :adjustment van een :payment_amount betaling :payment', + ':user heeft :adjustment van een :payment_amount betaling :payment', 'activity_41': 'Betaling van :payment_amount mislukt (:payment)', 'activity_42': ':user heeft taak :task aangemaakt', 'activity_43': ':user heeft taak :task bijgewerkt', @@ -8764,7 +8773,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'purge_data': 'Purge Data', 'purge_successful': 'Successfully purged company data', 'purge_data_message': - 'Warning: This will permanently erase your data, there is no undo.', + 'Warning: This will permanently erase your data, there is no undo.', 'invoice_balance': 'Invoice Balance', 'age_group_0': '0 - 30 Days', 'age_group_30': '30 - 60 Days', @@ -8799,10 +8808,10 @@ mixin LocalizationsProvider on LocaleCodeAware { 'apply_license': 'Apply License', 'cancel_account': 'Delete Account', 'cancel_account_message': - 'Warning: This will permanently delete your account, there is no undo.', + 'Warning: This will permanently delete your account, there is no undo.', 'delete_company': 'Delete Company', 'delete_company_message': - 'Warning: This will permanently delete your company, there is no undo.', + 'Warning: This will permanently delete your company, there is no undo.', 'enable_modules': 'Enable Modules', 'converted_quote': 'Successfully converted quote', 'credit_design': 'Credit Design', @@ -8954,12 +8963,12 @@ mixin LocalizationsProvider on LocaleCodeAware { 'applied': 'Applied', 'include_recent_errors': 'Include recent errors from the logs', 'your_message_has_been_received': - 'We have received your message and will try to respond promptly.', + 'We have received your message and will try to respond promptly.', 'message': 'Message', 'from': 'From', 'show_product_details': 'Show Product Details', 'show_product_details_help': - 'Include the description and cost in the product dropdown', + 'Include the description and cost in the product dropdown', 'pdf_min_requirements': 'The PDF renderer requires :version', 'adjust_fee_percent': 'Adjust Fee Percent', 'adjust_fee_percent_help': 'Adjust percent to account for fee', @@ -8976,7 +8985,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'domain_url': 'Domain URL', 'password_is_too_short': 'Password is too short', 'password_is_too_easy': - 'Password must contain an upper case character and a number', + 'Password must contain an upper case character and a number', 'client_portal_tasks': 'Customer Portal Tasks', 'client_portal_dashboard': 'Customer Portal Dashboard', 'please_enter_a_value': 'Please enter a value', @@ -9003,16 +9012,16 @@ mixin LocalizationsProvider on LocaleCodeAware { 'third_custom': 'Third Custom', 'show_cost': 'Show Cost', 'show_cost_help': - 'Display a product cost field to track the markup/profit', + 'Display a product cost field to track the markup/profit', 'show_product_quantity': 'Show Product Quantity', 'show_product_quantity_help': - 'Display a product quantity field, otherwise default to one', + 'Display a product quantity field, otherwise default to one', 'show_invoice_quantity': 'Show Invoice Quantity', 'show_invoice_quantity_help': - 'Display a line item quantity field, otherwise default to one', + 'Display a line item quantity field, otherwise default to one', 'default_quantity': 'Default Quantity', 'default_quantity_help': - 'Automatically set the line item quantity to one', + 'Automatically set the line item quantity to one', 'one_tax_rate': 'One Tax Rate', 'two_tax_rates': 'Two Tax Rates', 'three_tax_rates': 'Three Tax Rates', @@ -9057,7 +9066,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'filtered_by_user': 'Filtered by User', 'administrator': 'Administrator', 'administrator_help': - 'Allow user to manage users, change settings and modify all records', + 'Allow user to manage users, change settings and modify all records', 'user_management': 'User Management', 'users': 'Users', 'new_user': 'New User', @@ -9072,7 +9081,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'invoice_options': 'Invoice Options', 'hide_paid_to_date': 'Hide Paid to Date', 'hide_paid_to_date_help': - 'Only display the \"Paid to Date\" area on your invoices once a payment has been received.', + 'Only display the \"Paid to Date\" area on your invoices once a payment has been received.', 'invoice_embed_documents': 'Embed Documents', 'invoice_embed_documents_help': 'Include attached images in the invoice.', 'all_pages_header': 'Show Header on', @@ -9095,16 +9104,16 @@ mixin LocalizationsProvider on LocaleCodeAware { 'quote_footer': 'Quote Footer', 'auto_email_invoice': 'Auto Email', 'auto_email_invoice_help': - 'Automatically email recurring invoices when they are created.', + 'Automatically email recurring invoices when they are created.', 'auto_archive_invoice': 'Auto Archive', 'auto_archive_invoice_help': - 'Automatically archive invoices when they are paid.', + 'Automatically archive invoices when they are paid.', 'auto_archive_quote': 'Auto Archive', 'auto_archive_quote_help': - 'Automatically archive quotes when they are converted.', + 'Automatically archive quotes when they are converted.', 'auto_convert_quote': 'Auto Convert', 'auto_convert_quote_help': - 'Automatically convert a quote to an invoice when approved by a customer.', + 'Automatically convert a quote to an invoice when approved by a customer.', 'workflow_settings': 'Workflow Settings', 'freq_daily': 'Daily', 'freq_weekly': 'Weekly', @@ -9150,27 +9159,27 @@ mixin LocalizationsProvider on LocaleCodeAware { 'custom_javascript': 'Custom JavaScript', 'signature_on_pdf': 'Show on PDF', 'signature_on_pdf_help': - 'Show the customer signature on the invoice/quote PDF.', + 'Show the customer signature on the invoice/quote PDF.', 'show_accept_invoice_terms': 'Invoice Terms Checkbox', 'show_accept_invoice_terms_help': - 'Require customer to confirm that they accept the invoice terms.', + 'Require customer to confirm that they accept the invoice terms.', 'show_accept_quote_terms': 'Quote Terms Checkbox', 'show_accept_quote_terms_help': - 'Require customer to confirm that they accept the quote terms.', + 'Require customer to confirm that they accept the quote terms.', 'require_invoice_signature': 'Invoice Signature', 'require_invoice_signature_help': - 'Require customer to provide their signature.', + 'Require customer to provide their signature.', 'require_quote_signature': 'Quote Signature', 'enable_portal_password': 'Password Protect Invoices', 'enable_portal_password_help': - 'Allows you to set a password for each contact. If a password is set, the contact will be required to enter a password before viewing invoices.', + 'Allows you to set a password for each contact. If a password is set, the contact will be required to enter a password before viewing invoices.', 'authorization': 'Authorisation', 'subdomain': 'Subdomain', 'domain': 'Domain', 'portal_mode': 'Portal Mode', 'email_signature': 'Regards,', 'enable_email_markup_help': - 'Make it easier for your customers to pay you by adding schema.org markup to your emails.', + 'Make it easier for your customers to pay you by adding schema.org markup to your emails.', 'plain': 'Plain', 'light': 'Light', 'dark': 'Dark', @@ -9199,9 +9208,9 @@ mixin LocalizationsProvider on LocaleCodeAware { 'accepted_card_logos': 'Accepted Card Logos', 'credentials': 'Credentials', 'require_billing_address_help': - 'Require customer to provide their billing address', + 'Require customer to provide their billing address', 'require_shipping_address_help': - 'Require customer to provide their shipping address', + 'Require customer to provide their shipping address', 'update_address': 'Update Address', 'update_address_help': 'Update customer\'s address with provided details', 'rate': 'Rate', @@ -9215,13 +9224,13 @@ mixin LocalizationsProvider on LocaleCodeAware { 'restored_tax_rate': 'Successfully restored tax rate', 'fill_products': 'Auto-fill products', 'fill_products_help': - 'Selecting a product will automatically fill in the description and price', + 'Selecting a product will automatically fill in the description and price', 'update_products': 'Auto-update products', 'update_products_help': - 'Updating an invoice will automatically update the product library', + 'Updating an invoice will automatically update the product library', 'convert_products': 'Convert Products', 'convert_products_help': - 'Automatically convert product prices to the customer\'s currency', + 'Automatically convert product prices to the customer\'s currency', 'fees': 'Fees', 'limits': 'Limits', 'provider': 'Provider', @@ -9321,7 +9330,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'please_enter_a_first_name': 'Please enter a first name', 'please_enter_a_last_name': 'Please enter a last name', 'please_agree_to_terms_and_privacy': - 'Please agree to the terms of service and privacy policy to create an account.', + 'Please agree to the terms of service and privacy policy to create an account.', 'i_agree_to_the': 'I agree to the', 'terms_of_service_link': 'terms of service', 'privacy_policy_link': 'privacy policy', @@ -9420,7 +9429,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'average': 'Average', 'unapproved': 'Unapproved', 'authenticate_to_change_setting': - 'Please authenticate to change this setting', + 'Please authenticate to change this setting', 'locked': 'Locked', 'authenticate': 'Authenticate', 'please_authenticate': 'Please authenticate', @@ -9620,7 +9629,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'marked_invoices_as_paid': 'Successfully marked invoices as paid', 'done': 'Done', 'please_enter_a_client_or_contact_name': - 'Please enter a customer or contact name', + 'Please enter a customer or contact name', 'dark_mode': 'Dark Mode', 'restart_app_to_apply_change': 'Restart the app to apply the change', 'refresh_data': 'Refresh Data', @@ -9702,7 +9711,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'activity_8': ':user archived invoice :invoice', 'activity_9': ':user deleted invoice :invoice', 'activity_10': - ':contact entered payment :payment for :payment_amount on invoice :invoice for :client', + ':contact entered payment :payment for :payment_amount on invoice :invoice for :client', 'activity_11': ':user updated payment :payment', 'activity_12': ':user archived payment :payment', 'activity_13': ':user deleted payment :payment', @@ -9732,7 +9741,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'activity_37': ':user restored expense :expense', 'activity_39': ':user cancelled a :payment_amount payment :payment', 'activity_40': - ':user refunded :adjustment of a :payment_amount payment :payment', + ':user refunded :adjustment of a :payment_amount payment :payment', 'activity_41': ':payment_amount payment (:payment) failed', 'activity_42': ':user created task :task', 'activity_43': ':user updated task :task', @@ -9852,7 +9861,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'purge_data': 'Purge Data', 'purge_successful': 'Successfully purged company data', 'purge_data_message': - 'Warning: This will permanently erase your data, there is no undo.', + 'Warning: This will permanently erase your data, there is no undo.', 'invoice_balance': 'Invoice Balance', 'age_group_0': '0 - 30 Days', 'age_group_30': '30 - 60 Days', @@ -9887,10 +9896,10 @@ mixin LocalizationsProvider on LocaleCodeAware { 'apply_license': 'Apply License', 'cancel_account': 'Delete Account', 'cancel_account_message': - 'Warning: This will permanently delete your account, there is no undo.', + 'Warning: This will permanently delete your account, there is no undo.', 'delete_company': 'Delete Company', 'delete_company_message': - 'Warning: This will permanently delete your company, there is no undo.', + 'Warning: This will permanently delete your company, there is no undo.', 'enable_modules': 'Enable Modules', 'converted_quote': 'Successfully converted quote', 'credit_design': 'Credit Design', @@ -10042,12 +10051,12 @@ mixin LocalizationsProvider on LocaleCodeAware { 'applied': 'Applied', 'include_recent_errors': 'Include recent errors from the logs', 'your_message_has_been_received': - 'We have received your message and will try to respond promptly.', + 'We have received your message and will try to respond promptly.', 'message': 'Message', 'from': 'From', 'show_product_details': 'Show Product Details', 'show_product_details_help': - 'Include the description and cost in the product dropdown', + 'Include the description and cost in the product dropdown', 'pdf_min_requirements': 'The PDF renderer requires :version', 'adjust_fee_percent': 'Adjust Fee Percent', 'adjust_fee_percent_help': 'Adjust percent to account for fee', @@ -10064,7 +10073,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'domain_url': 'Domain URL', 'password_is_too_short': 'Password is too short', 'password_is_too_easy': - 'Password must contain an upper case character and a number', + 'Password must contain an upper case character and a number', 'client_portal_tasks': 'Client Portal Tasks', 'client_portal_dashboard': 'Client Portal Dashboard', 'please_enter_a_value': 'Please enter a value', @@ -10091,16 +10100,16 @@ mixin LocalizationsProvider on LocaleCodeAware { 'third_custom': 'Third Custom', 'show_cost': 'Show Cost', 'show_cost_help': - 'Display a product cost field to track the markup/profit', + 'Display a product cost field to track the markup/profit', 'show_product_quantity': 'Show Product Quantity', 'show_product_quantity_help': - 'Display a product quantity field, otherwise default to one', + 'Display a product quantity field, otherwise default to one', 'show_invoice_quantity': 'Show Invoice Quantity', 'show_invoice_quantity_help': - 'Display a line item quantity field, otherwise default to one', + 'Display a line item quantity field, otherwise default to one', 'default_quantity': 'Default Quantity', 'default_quantity_help': - 'Automatically set the line item quantity to one', + 'Automatically set the line item quantity to one', 'one_tax_rate': 'One Tax Rate', 'two_tax_rates': 'Two Tax Rates', 'three_tax_rates': 'Three Tax Rates', @@ -10145,7 +10154,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'filtered_by_user': 'Filtered by User', 'administrator': 'Administrator', 'administrator_help': - 'Allow user to manage users, change settings and modify all records', + 'Allow user to manage users, change settings and modify all records', 'user_management': 'User Management', 'users': 'Users', 'new_user': 'New User', @@ -10160,7 +10169,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'invoice_options': 'Invoice Options', 'hide_paid_to_date': 'Hide Paid to Date', 'hide_paid_to_date_help': - 'Only display the \"Paid to Date\" area on your invoices once a payment has been received.', + 'Only display the \"Paid to Date\" area on your invoices once a payment has been received.', 'invoice_embed_documents': 'Embed Documents', 'invoice_embed_documents_help': 'Include attached images in the invoice.', 'all_pages_header': 'Show Header on', @@ -10183,16 +10192,16 @@ mixin LocalizationsProvider on LocaleCodeAware { 'quote_footer': 'Quote Footer', 'auto_email_invoice': 'Auto Email', 'auto_email_invoice_help': - 'Automatically email recurring invoices when they are created.', + 'Automatically email recurring invoices when they are created.', 'auto_archive_invoice': 'Auto Archive', 'auto_archive_invoice_help': - 'Automatically archive invoices when they are paid.', + 'Automatically archive invoices when they are paid.', 'auto_archive_quote': 'Auto Archive', 'auto_archive_quote_help': - 'Automatically archive quotes when they are converted.', + 'Automatically archive quotes when they are converted.', 'auto_convert_quote': 'Auto Convert', 'auto_convert_quote_help': - 'Automatically convert a quote to an invoice when approved by a client.', + 'Automatically convert a quote to an invoice when approved by a client.', 'workflow_settings': 'Workflow Settings', 'freq_daily': 'Daily', 'freq_weekly': 'Weekly', @@ -10238,27 +10247,27 @@ mixin LocalizationsProvider on LocaleCodeAware { 'custom_javascript': 'Custom JavaScript', 'signature_on_pdf': 'Show on PDF', 'signature_on_pdf_help': - 'Show the client signature on the invoice/quote PDF.', + 'Show the client signature on the invoice/quote PDF.', 'show_accept_invoice_terms': 'Invoice Terms Checkbox', 'show_accept_invoice_terms_help': - 'Require client to confirm that they accept the invoice terms.', + 'Require client to confirm that they accept the invoice terms.', 'show_accept_quote_terms': 'Quote Terms Checkbox', 'show_accept_quote_terms_help': - 'Require client to confirm that they accept the quote terms.', + 'Require client to confirm that they accept the quote terms.', 'require_invoice_signature': 'Invoice Signature', 'require_invoice_signature_help': - 'Require client to provide their signature.', + 'Require client to provide their signature.', 'require_quote_signature': 'Quote Signature', 'enable_portal_password': 'Password Protect Invoices', 'enable_portal_password_help': - 'Allows you to set a password for each contact. If a password is set, the contact will be required to enter a password before viewing invoices.', + 'Allows you to set a password for each contact. If a password is set, the contact will be required to enter a password before viewing invoices.', 'authorization': 'Authorisation', 'subdomain': 'Subdomain', 'domain': 'Domain', 'portal_mode': 'Portal Mode', 'email_signature': 'Regards,', 'enable_email_markup_help': - 'Make it easier for your clients to pay you by adding schema.org markup to your emails.', + 'Make it easier for your clients to pay you by adding schema.org markup to your emails.', 'plain': 'Plain', 'light': 'Light', 'dark': 'Dark', @@ -10287,9 +10296,9 @@ mixin LocalizationsProvider on LocaleCodeAware { 'accepted_card_logos': 'Accepted Card Logos', 'credentials': 'Credentials', 'require_billing_address_help': - 'Require client to provide their billing address', + 'Require client to provide their billing address', 'require_shipping_address_help': - 'Require client to provide their shipping address', + 'Require client to provide their shipping address', 'update_address': 'Update Address', 'update_address_help': 'Update client\'s address with provided details', 'rate': 'Rate', @@ -10303,13 +10312,13 @@ mixin LocalizationsProvider on LocaleCodeAware { 'restored_tax_rate': 'Successfully restored tax rate', 'fill_products': 'Auto-fill products', 'fill_products_help': - 'Selecting a product will automatically fill in the description and cost', + 'Selecting a product will automatically fill in the description and cost', 'update_products': 'Auto-update products', 'update_products_help': - 'Updating an invoice will automatically update the product library', + 'Updating an invoice will automatically update the product library', 'convert_products': 'Convert Products', 'convert_products_help': - 'Automatically convert product prices to the client\'s currency', + 'Automatically convert product prices to the client\'s currency', 'fees': 'Fees', 'limits': 'Limits', 'provider': 'Provider', @@ -10409,7 +10418,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'please_enter_a_first_name': 'Please enter a first name', 'please_enter_a_last_name': 'Please enter a last name', 'please_agree_to_terms_and_privacy': - 'Please agree to the terms of service and privacy policy to create an account.', + 'Please agree to the terms of service and privacy policy to create an account.', 'i_agree_to_the': 'I agree to the', 'terms_of_service_link': 'terms of service', 'privacy_policy_link': 'privacy policy', @@ -10508,7 +10517,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'average': 'Average', 'unapproved': 'Unapproved', 'authenticate_to_change_setting': - 'Please authenticate to change this setting', + 'Please authenticate to change this setting', 'locked': 'Locked', 'authenticate': 'Authenticate', 'please_authenticate': 'Please authenticate', @@ -10708,7 +10717,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'marked_invoices_as_paid': 'Successfully marked invoices as paid', 'done': 'Done', 'please_enter_a_client_or_contact_name': - 'Please enter a client or contact name', + 'Please enter a client or contact name', 'dark_mode': 'Dark Mode', 'restart_app_to_apply_change': 'Restart the app to apply the change', 'refresh_data': 'Refresh Data', @@ -10790,7 +10799,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'activity_8': ':user archived invoice :invoice', 'activity_9': ':user deleted invoice :invoice', 'activity_10': - ':contact entered payment :payment for :payment_amount on invoice :invoice for :client', + ':contact entered payment :payment for :payment_amount on invoice :invoice for :client', 'activity_11': ':user updated payment :payment', 'activity_12': ':user archived payment :payment', 'activity_13': ':user deleted payment :payment', @@ -10820,7 +10829,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'activity_37': ':user restored expense :expense', 'activity_39': ':user cancelled a :payment_amount payment :payment', 'activity_40': - ':user refunded :adjustment of a :payment_amount payment :payment', + ':user refunded :adjustment of a :payment_amount payment :payment', 'activity_41': ':payment_amount payment (:payment) failed', 'activity_42': ':user created task :task', 'activity_43': ':user updated task :task', @@ -10940,7 +10949,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'purge_data': 'Purge Data', 'purge_successful': 'onnistuneesti purged yritys data', 'purge_data_message': - 'Warning: tämä will pysyvästi erase sinun data, there is no undo.', + 'Warning: tämä will pysyvästi erase sinun data, there is no undo.', 'invoice_balance': 'Invoice Balance', 'age_group_0': '0 - 30 päivää', 'age_group_30': '30 - 60 päivää', @@ -10975,10 +10984,10 @@ mixin LocalizationsProvider on LocaleCodeAware { 'apply_license': 'Apply lisenssi', 'cancel_account': 'Poista tili', 'cancel_account_message': - 'Varoitus: Tämä poistaa tilisi pysyvästi. Tietoja ei pysty palauttamaan.', + 'Varoitus: Tämä poistaa tilisi pysyvästi. Tietoja ei pysty palauttamaan.', 'delete_company': 'Poista yritys', 'delete_company_message': - 'Warning: tämä will pysyvästi poista sinun yritys, there is no undo.', + 'Warning: tämä will pysyvästi poista sinun yritys, there is no undo.', 'enable_modules': 'Enable Modules', 'converted_quote': 'Successfully converted quote', 'credit_design': 'Credit Design', @@ -11130,12 +11139,12 @@ mixin LocalizationsProvider on LocaleCodeAware { 'applied': 'Applied', 'include_recent_errors': 'Include recent errors from the logs', 'your_message_has_been_received': - 'We have received your message and will try to respond promptly.', + 'We have received your message and will try to respond promptly.', 'message': 'Viesti', 'from': 'Lähettäjä', 'show_product_details': 'Show Product Details', 'show_product_details_help': - 'Include the description and cost in the product dropdown', + 'Include the description and cost in the product dropdown', 'pdf_min_requirements': 'The PDF renderer requires :version', 'adjust_fee_percent': 'Adjust Fee Percent', 'adjust_fee_percent_help': 'Adjust percent tili palkkio', @@ -11152,7 +11161,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'domain_url': 'Domain URL', 'password_is_too_short': 'salasana on liian lyhyt', 'password_is_too_easy': - 'Password must contain an upper case character and a number', + 'Password must contain an upper case character and a number', 'client_portal_tasks': 'Client Portal Tasks', 'client_portal_dashboard': 'Client Portal Dashboard', 'please_enter_a_value': 'Please enter a value', @@ -11179,16 +11188,16 @@ mixin LocalizationsProvider on LocaleCodeAware { 'third_custom': 'Third Custom', 'show_cost': 'Show Cost', 'show_cost_help': - 'Display a product cost field to track the markup/profit', + 'Display a product cost field to track the markup/profit', 'show_product_quantity': 'Show Product Quantity', 'show_product_quantity_help': - 'Display a product quantity field, otherwise default to one', + 'Display a product quantity field, otherwise default to one', 'show_invoice_quantity': 'Show Invoice Quantity', 'show_invoice_quantity_help': - 'Display a line item quantity field, otherwise default to one', + 'Display a line item quantity field, otherwise default to one', 'default_quantity': 'Default Quantity', 'default_quantity_help': - 'Automatically set the line item quantity to one', + 'Automatically set the line item quantity to one', 'one_tax_rate': 'One Tax Rate', 'two_tax_rates': 'Two Tax Rates', 'three_tax_rates': 'Three Tax Rates', @@ -11233,7 +11242,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'filtered_by_user': 'Filtered by User', 'administrator': 'Ylläpitäjä', 'administrator_help': - 'Allow käyttäjä manage users, change asetus ja modify kaikki records', + 'Allow käyttäjä manage users, change asetus ja modify kaikki records', 'user_management': 'Käyttäjänhallinta', 'users': 'Käyttäjät', 'new_user': 'Uusi käyttäjä', @@ -11248,7 +11257,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'invoice_options': 'Laskun valinnat', 'hide_paid_to_date': 'Piilota \"Maksettu tähän asti\"', 'hide_paid_to_date_help': - 'Näytä \"Maksettava päivämäärään mennessä\" kenttä laskuillasi vain maksetuilla laskuilla.', + 'Näytä \"Maksettava päivämäärään mennessä\" kenttä laskuillasi vain maksetuilla laskuilla.', 'invoice_embed_documents': 'Embed Documents', 'invoice_embed_documents_help': 'Include attached images in lasku.', 'all_pages_header': 'näytä Header on', @@ -11271,16 +11280,16 @@ mixin LocalizationsProvider on LocaleCodeAware { 'quote_footer': 'Tarjouksen alatunniste', 'auto_email_invoice': 'automaattinen Email', 'auto_email_invoice_help': - 'automaattisesti sähköposti toistuva laskut when they on luotu.', + 'automaattisesti sähköposti toistuva laskut when they on luotu.', 'auto_archive_invoice': 'automaattinen Arkistoi', 'auto_archive_invoice_help': - 'automaattisesti archive laskut when they on paid.', + 'automaattisesti archive laskut when they on paid.', 'auto_archive_quote': 'automaattinen Arkistoi', 'auto_archive_quote_help': - 'automaattisesti archive quotes when they on converted.', + 'automaattisesti archive quotes when they on converted.', 'auto_convert_quote': 'automaattinen Convert', 'auto_convert_quote_help': - 'automaattisesti convert tarjous lasku when approved by asiakas.', + 'automaattisesti convert tarjous lasku when approved by asiakas.', 'workflow_settings': 'Workflow asetukset', 'freq_daily': 'päivittäin', 'freq_weekly': 'viikoittain', @@ -11326,27 +11335,27 @@ mixin LocalizationsProvider on LocaleCodeAware { 'custom_javascript': 'muokattu JavaScript', 'signature_on_pdf': 'näytä on PDF', 'signature_on_pdf_help': - 'näytä asiakas allekirjoitus on lasku/tarjous PDF.', + 'näytä asiakas allekirjoitus on lasku/tarjous PDF.', 'show_accept_invoice_terms': 'Lasku Terms Checkbox', 'show_accept_invoice_terms_help': - 'Require asiakas vahvista that they accept lasku terms.', + 'Require asiakas vahvista that they accept lasku terms.', 'show_accept_quote_terms': 'tarjous Terms Checkbox', 'show_accept_quote_terms_help': - 'Require asiakas vahvista that they accept tarjous terms.', + 'Require asiakas vahvista that they accept tarjous terms.', 'require_invoice_signature': 'Lasku Signature', 'require_invoice_signature_help': - 'Vaadi asiakasta täyttämään allekirjoitus.', + 'Vaadi asiakasta täyttämään allekirjoitus.', 'require_quote_signature': 'tarjous Signature', 'enable_portal_password': 'salasana suojaa laskut', 'enable_portal_password_help': - 'Allows you set salasana each kontakti. If salasana is set, kontakti required syötä salasana before viewing laskut.', + 'Allows you set salasana each kontakti. If salasana is set, kontakti required syötä salasana before viewing laskut.', 'authorization': 'Authorization', 'subdomain': 'Alidomain', 'domain': 'Domain', 'portal_mode': 'Portal Mode', 'email_signature': 'Ystävällisesti,', 'enable_email_markup_help': - 'Make it easier sinun asiakkaat pay you by adding schema.org markup sinun sähköpostit.', + 'Make it easier sinun asiakkaat pay you by adding schema.org markup sinun sähköpostit.', 'plain': 'Yksinkertainen', 'light': 'Vaalea', 'dark': 'Tumma', @@ -11375,9 +11384,9 @@ mixin LocalizationsProvider on LocaleCodeAware { 'accepted_card_logos': 'Accepted kortti Logos', 'credentials': 'Credentials', 'require_billing_address_help': - 'Require asiakas provide their laskutus osoite', + 'Require asiakas provide their laskutus osoite', 'require_shipping_address_help': - 'Require asiakas provide their shipping osoite', + 'Require asiakas provide their shipping osoite', 'update_address': 'Päivitä osoite', 'update_address_help': 'Päivitä asiakkaan osoite annetuilla tiedoilla', 'rate': 'á hinta', @@ -11391,13 +11400,13 @@ mixin LocalizationsProvider on LocaleCodeAware { 'restored_tax_rate': 'onnistuneesti palautettu tax rate', 'fill_products': 'Lisää automaattisesti tuotteita', 'fill_products_help': - 'Tuotteen valinta täyttää kuvauksen ja hinnan automaattisesti', + 'Tuotteen valinta täyttää kuvauksen ja hinnan automaattisesti', 'update_products': 'Päivitä automaattisesti tuotteet', 'update_products_help': - 'Laskun päivittäminen päivittää tuotetietokannan automaattisesti', + 'Laskun päivittäminen päivittää tuotetietokannan automaattisesti', 'convert_products': 'Convert tuotteet', 'convert_products_help': - 'automaattisesti convert tuote prices asiakas\'s currency', + 'automaattisesti convert tuote prices asiakas\'s currency', 'fees': 'palkkiot', 'limits': 'Limits', 'provider': 'Provider', @@ -11497,7 +11506,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'please_enter_a_first_name': 'syötä etunimi', 'please_enter_a_last_name': 'syötä sukunimi', 'please_agree_to_terms_and_privacy': - 'agree terms service ja privacy policy create tili.', + 'agree terms service ja privacy policy create tili.', 'i_agree_to_the': 'I agree the', 'terms_of_service_link': 'terms service', 'privacy_policy_link': 'privacy policy', @@ -11795,7 +11804,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'marked_invoices_as_paid': 'Successfully marked invoices as paid', 'done': 'Valmis', 'please_enter_a_client_or_contact_name': - 'syötä asiakas tai kontakti name', + 'syötä asiakas tai kontakti name', 'dark_mode': 'Tumma tila', 'restart_app_to_apply_change': 'Restart app apply change', 'refresh_data': 'Refresh Data', @@ -11877,7 +11886,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'activity_8': ':käyttäjä arkistoi laskun :invoice', 'activity_9': ':käyttäjä poisti laskun :invoice', 'activity_10': - ':kontakti entered maksu :maksu for :payment_amount on lasku :lasku for :asiakas', + ':kontakti entered maksu :maksu for :payment_amount on lasku :lasku for :asiakas', 'activity_11': ':käyttäjä päivitti maksun :maksu', 'activity_12': ':käyttäjä arkistoi maksun :maksu', 'activity_13': ':käyttäjä poisti maksun :maksu', @@ -11888,7 +11897,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'activity_18': ':käyttäjä loi tarjouksen :quote', 'activity_19': ':käyttäjä päivitti tarjouksen :quote', 'activity_20': - ':käyttäjä emailed tarjous :tarjous for :asiakas :kontakti', + ':käyttäjä emailed tarjous :tarjous for :asiakas :kontakti', 'activity_21': ':kontakti luki tarjouksen :quote', 'activity_22': ':käyttäjä arkistoi tarjouksen :quote', 'activity_23': ':käyttäjä poisti tarjouksen :quote', @@ -11908,7 +11917,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'activity_37': ':käyttäjä palautti kulun :kulu', 'activity_39': ':käyttäjä cancelled a :payment_amount maksu :maksu', 'activity_40': - ':käyttäjä refunded :adjustment a :payment_amount maksu :maksu', + ':käyttäjä refunded :adjustment a :payment_amount maksu :maksu', 'activity_41': ':payment_amount maksu (:maksu) failed', 'activity_42': ':käyttäjä loi tehtävän :tehtävä', 'activity_43': ':käyttäjä päivitti tehtävän :tehtävä', @@ -12027,9 +12036,9 @@ mixin LocalizationsProvider on LocaleCodeAware { 'license': 'License', 'purge_data': 'Purger les données', 'purge_successful': - 'Les données de l\'entreprise ont été purgées avec succès', + 'Les données de l\'entreprise ont été purgées avec succès', 'purge_data_message': - 'Attention : Cette action va supprimer vos données et est irréversible', + 'Attention : Cette action va supprimer vos données et est irréversible', 'invoice_balance': 'Invoice Balance', 'age_group_0': '0 - 30 jours', 'age_group_30': '30 -60 jours', @@ -12064,10 +12073,10 @@ mixin LocalizationsProvider on LocaleCodeAware { 'apply_license': 'Activer la licence', 'cancel_account': 'Supprimer le compte', 'cancel_account_message': - 'Attention : Ceci va supprimer définitivement votre compte, il n\'y a pas d\'annulation possible.', + 'Attention : Ceci va supprimer définitivement votre compte, il n\'y a pas d\'annulation possible.', 'delete_company': 'Supprimer la société', 'delete_company_message': - 'Attention : Ceci supprimera définitivement votre société, il n\'y a pas d\'annulation.', + 'Attention : Ceci supprimera définitivement votre société, il n\'y a pas d\'annulation.', 'enable_modules': 'Enable Modules', 'converted_quote': 'Successfully converted quote', 'credit_design': 'Credit Design', @@ -12219,14 +12228,14 @@ mixin LocalizationsProvider on LocaleCodeAware { 'applied': 'Applied', 'include_recent_errors': 'Contient les erreurs récentes des journaux', 'your_message_has_been_received': - 'Nous avons reçu votre message et répondrons dans les meilleurs délais', + 'Nous avons reçu votre message et répondrons dans les meilleurs délais', 'message': 'Message', 'from': 'De', 'show_product_details': 'Voir les détails du produit', 'show_product_details_help': - 'Include the description and cost in the product dropdown', + 'Include the description and cost in the product dropdown', 'pdf_min_requirements': - 'Le générateur de PDF nécessite la version :version', + 'Le générateur de PDF nécessite la version :version', 'adjust_fee_percent': 'Adjust Fee Percent', 'adjust_fee_percent_help': 'Ajuster le frais de pourcentage au compte', 'configure_settings': 'Modifier les paramètres', @@ -12242,7 +12251,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'domain_url': 'URL du domaine', 'password_is_too_short': 'Mot de passe trop court', 'password_is_too_easy': - 'Le mot de passe doit comporter au moins une majuscule et un nombre', + 'Le mot de passe doit comporter au moins une majuscule et un nombre', 'client_portal_tasks': 'Tâche du portail client', 'client_portal_dashboard': 'Tableau de bord du portail client', 'please_enter_a_value': 'Saisissez une valeur', @@ -12269,16 +12278,16 @@ mixin LocalizationsProvider on LocaleCodeAware { 'third_custom': 'Third Custom', 'show_cost': 'Voir le coût', 'show_cost_help': - 'Afficher un champ coût du produit pour suivre la marge', + 'Afficher un champ coût du produit pour suivre la marge', 'show_product_quantity': 'Voir la quantité du produit', 'show_product_quantity_help': - 'Afficher un champ de quantité du produit, sinon en choisir un par défaut', + 'Afficher un champ de quantité du produit, sinon en choisir un par défaut', 'show_invoice_quantity': 'Voir la quantité sur la facture', 'show_invoice_quantity_help': - 'Afficher un champ de quantité pour la position, sinon en choisir un par défaut', + 'Afficher un champ de quantité pour la position, sinon en choisir un par défaut', 'default_quantity': 'Quantité par défaut', 'default_quantity_help': - 'Mettre automatiquement la quantité de la position à un', + 'Mettre automatiquement la quantité de la position à un', 'one_tax_rate': 'One Tax Rate', 'two_tax_rates': 'Two Tax Rates', 'three_tax_rates': 'Three Tax Rates', @@ -12302,7 +12311,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'dropdown': 'Dropdown', 'field_type': 'Type du champ', 'recover_password_email_sent': - 'Un courriel de récupération du mot de passe a été envoyé', + 'Un courriel de récupération du mot de passe a été envoyé', 'submit': 'Envoyer', 'recover_password': 'Récupérer votre mot de passe', 'late_fees': 'Frais de retard', @@ -12324,7 +12333,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'filtered_by_user': 'Filtré par utilisateur', 'administrator': 'Administrateur', 'administrator_help': - 'Permettre à l\'utilisateur de gérer les utilisateurs, modifier les paramètres et de modifier tous les enregistrements', + 'Permettre à l\'utilisateur de gérer les utilisateurs, modifier les paramètres et de modifier tous les enregistrements', 'user_management': 'Gestion des utilisateurs', 'users': 'Utilisateurs', 'new_user': 'Nouvel utilisateur', @@ -12339,10 +12348,10 @@ mixin LocalizationsProvider on LocaleCodeAware { 'invoice_options': 'Options de facturation', 'hide_paid_to_date': 'Masquer \"Payé à ce jour\"', 'hide_paid_to_date_help': - 'Afficher la ligne \"Payé à ce jour\" sur vos factures seulement une fois qu\'un paiement a été reçu.', + 'Afficher la ligne \"Payé à ce jour\" sur vos factures seulement une fois qu\'un paiement a été reçu.', 'invoice_embed_documents': 'Documents intégrés', 'invoice_embed_documents_help': - 'Inclure l\'image attachée dans la facture.', + 'Inclure l\'image attachée dans la facture.', 'all_pages_header': 'Voir les en-têtes sur', 'all_pages_footer': 'Voir les pieds de page sur', 'first_page': 'Première page', @@ -12363,16 +12372,16 @@ mixin LocalizationsProvider on LocaleCodeAware { 'quote_footer': 'Pied de page des devis', 'auto_email_invoice': 'Envoyer automatiquement par courriel', 'auto_email_invoice_help': - 'Envoyer automatiquement par courriel les factures récurrentes lorsqu\'elles sont créés.', + 'Envoyer automatiquement par courriel les factures récurrentes lorsqu\'elles sont créés.', 'auto_archive_invoice': 'Archiver automatiquement', 'auto_archive_invoice_help': - 'Archiver automatiquement les factures lorsqu\'elles sont payées.', + 'Archiver automatiquement les factures lorsqu\'elles sont payées.', 'auto_archive_quote': 'Archiver automatiquement', 'auto_archive_quote_help': - 'Archiver automatiquement les devis lorsqu\'ils sont convertis.', + 'Archiver automatiquement les devis lorsqu\'ils sont convertis.', 'auto_convert_quote': 'Convertir automatiquement', 'auto_convert_quote_help': - 'Convertir automatiquement un devis en facture dès qu\'il est approuvé par le client.', + 'Convertir automatiquement un devis en facture dès qu\'il est approuvé par le client.', 'workflow_settings': 'Paramètres de flux de travail', 'freq_daily': 'Quotidien', 'freq_weekly': 'Hebdomadaire', @@ -12418,27 +12427,27 @@ mixin LocalizationsProvider on LocaleCodeAware { 'custom_javascript': 'JavaScript personnalisé', 'signature_on_pdf': 'Afficher sur le PDF', 'signature_on_pdf_help': - 'Afficher la signature du client sur la facture / le devis PDF.', + 'Afficher la signature du client sur la facture / le devis PDF.', 'show_accept_invoice_terms': - 'Case à cocher pour les conditions de facturation', + 'Case à cocher pour les conditions de facturation', 'show_accept_invoice_terms_help': - 'Exiger que le client confirme qu\'il accepte les conditions de facturation', + 'Exiger que le client confirme qu\'il accepte les conditions de facturation', 'show_accept_quote_terms': 'Case à cocher pour les conditions d\'offre', 'show_accept_quote_terms_help': - 'Exiger que le client confirme qu\'il accepte les conditions de l\'offre', + 'Exiger que le client confirme qu\'il accepte les conditions de l\'offre', 'require_invoice_signature': 'Signature de facture', 'require_invoice_signature_help': 'Exiger que le client signe', 'require_quote_signature': 'Signature de l\'offre', 'enable_portal_password': 'Protéger les factures avec un mot de passe', 'enable_portal_password_help': - 'Autoriser la création d\'un mot de passe pour chaque contact. Si un mot de passe est créé, le contact devra entrer un mot de passe avant de voir les factures.', + 'Autoriser la création d\'un mot de passe pour chaque contact. Si un mot de passe est créé, le contact devra entrer un mot de passe avant de voir les factures.', 'authorization': 'Autorisation', 'subdomain': 'Sous-domaine', 'domain': 'Domaine', 'portal_mode': 'Mode portail', 'email_signature': 'Cordialement,', 'enable_email_markup_help': - 'Rendez le règlement de vos clients plus facile en ajoutant les markup schema.org à vos courriels.', + 'Rendez le règlement de vos clients plus facile en ajoutant les markup schema.org à vos courriels.', 'plain': 'Brut', 'light': 'Clair', 'dark': 'Sombre', @@ -12467,12 +12476,12 @@ mixin LocalizationsProvider on LocaleCodeAware { 'accepted_card_logos': 'Logos des cartes acceptées', 'credentials': 'Identifiants', 'require_billing_address_help': - 'Le client doit fournir son adresse de facturation', + 'Le client doit fournir son adresse de facturation', 'require_shipping_address_help': - 'Le client doit fournir son adresse de livraison', + 'Le client doit fournir son adresse de livraison', 'update_address': 'Mettre à jour l\'adresse', 'update_address_help': - 'Mettre à jour l\'adresse du client avec les détails fournis', + 'Mettre à jour l\'adresse du client avec les détails fournis', 'rate': 'Taux', 'tax_rate': 'Taux de taxe', 'new_tax_rate': 'Nouveau taux de taxe', @@ -12484,13 +12493,13 @@ mixin LocalizationsProvider on LocaleCodeAware { 'restored_tax_rate': 'Le taux de taxe a été restauré avec succès', 'fill_products': 'Remplissage auto des produits', 'fill_products_help': - 'La sélection d’un produit entrainera la MAJ de la description et du prix', + 'La sélection d’un produit entrainera la MAJ de la description et du prix', 'update_products': 'Mise à jour auto des produits', 'update_products_help': - 'La mise à jour d\'une facture entraîne la mise à jour des produits', + 'La mise à jour d\'une facture entraîne la mise à jour des produits', 'convert_products': 'Convertir les produits', 'convert_products_help': - 'Convertir automatiquement les prix des produits dans la devise du client', + 'Convertir automatiquement les prix des produits dans la devise du client', 'fees': 'Frais', 'limits': 'Limites', 'provider': 'Fournisseur', @@ -12590,7 +12599,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'please_enter_a_first_name': 'Veuillez entrer un prénom', 'please_enter_a_last_name': 'Veuillez entrer un nom', 'please_agree_to_terms_and_privacy': - 'Veuillez accepter les conditions d\'utilisation et la politique de confidentialité pour créer un compte.', + 'Veuillez accepter les conditions d\'utilisation et la politique de confidentialité pour créer un compte.', 'i_agree_to_the': 'J\'accepte les', 'terms_of_service_link': 'Conditions d\'utilisation', 'privacy_policy_link': 'Politique de confidentialité', @@ -12604,7 +12613,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'create_new': 'Créer', 'no_record_selected': 'Aucun enregistrement sélectionné', 'error_unsaved_changes': - 'Veuillez enregistrer ou annuler vos modifications', + 'Veuillez enregistrer ou annuler vos modifications', 'download': 'Télécharger', 'requires_an_enterprise_plan': 'Χρειάζεται πλάνο επιχείρησης', 'take_picture': 'Φωτογραφίσετε', @@ -12690,7 +12699,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'average': 'Moyenne', 'unapproved': 'Non approuvé', 'authenticate_to_change_setting': - 'Veuillez vous connecter pour changer ce paramètre', + 'Veuillez vous connecter pour changer ce paramètre', 'locked': 'Verrouillé', 'authenticate': 'Connexion', 'please_authenticate': 'Veuillez vous connecter', @@ -12890,10 +12899,10 @@ mixin LocalizationsProvider on LocaleCodeAware { 'marked_invoices_as_paid': 'Successfully marked invoices as paid', 'done': 'Terminé', 'please_enter_a_client_or_contact_name': - 'Veuillez introduire un nom de client', + 'Veuillez introduire un nom de client', 'dark_mode': 'Mode sombre', 'restart_app_to_apply_change': - 'Recommencer k\'app pour introduire l\'app change', + 'Recommencer k\'app pour introduire l\'app change', 'refresh_data': 'Rafraîchir les données', 'blank_contact': 'Details pour contacter la Banque', 'activity': 'Activité', @@ -12973,7 +12982,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'activity_8': ':user a archivé la facture :invoice', 'activity_9': ':user a supprimé la facture :invoice', 'activity_10': - ':contact a saisi un paiement :payment concernant :invoice pour :client', + ':contact a saisi un paiement :payment concernant :invoice pour :client', 'activity_11': ':user a mis à jour le moyen de paiement :payment', 'activity_12': ':user a archivé le moyen de paiement :payment', 'activity_13': ':user a supprimé le moyen de paiement :payment', @@ -13003,7 +13012,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'activity_37': ':user a restauré la dépense :expense', 'activity_39': ':user a annulé un paiement de :payment_amount (:payment)', 'activity_40': - ':user a remboursé :adjustment d\'un paiement de :payment_amount (:payment)', + ':user a remboursé :adjustment d\'un paiement de :payment_amount (:payment)', 'activity_41': 'Le paiement de :payment_amount a échoué (:payment)', 'activity_42': ':user a créé la tâche :task', 'activity_43': ':user a mis à jour la tâche :task', @@ -13037,11 +13046,11 @@ mixin LocalizationsProvider on LocaleCodeAware { 'email_style_custom': 'Style de courriel personnalisé', 'custom_message_dashboard': 'Message personnalisé du tableau de bord', 'custom_message_unpaid_invoice': - 'Message personnalisé pour une facture impayée', + 'Message personnalisé pour une facture impayée', 'custom_message_paid_invoice': - 'Message personnalisé pour un paiement de facture', + 'Message personnalisé pour un paiement de facture', 'custom_message_unapproved_quote': - 'Message personnalisé pour un devis refusé', + 'Message personnalisé pour un devis refusé', 'lock_sent_invoices': 'Verrouiller les factures envoyées', 'translations': 'Traductions', 'task_number_pattern': 'Modèle de numéro de tâche', @@ -13125,9 +13134,9 @@ mixin LocalizationsProvider on LocaleCodeAware { 'license': 'License', 'purge_data': 'Purger les données', 'purge_successful': - 'Toutes les données de l\'entreprise ont été supprimées', + 'Toutes les données de l\'entreprise ont été supprimées', 'purge_data_message': - 'Avertissement: Cette action est irréversible et va supprimer vos données de façon définitive.', + 'Avertissement: Cette action est irréversible et va supprimer vos données de façon définitive.', 'invoice_balance': 'Invoice Balance', 'age_group_0': '0 - 30 jours', 'age_group_30': '30 - 60 jours', @@ -13162,10 +13171,10 @@ mixin LocalizationsProvider on LocaleCodeAware { 'apply_license': 'Activer la licence', 'cancel_account': 'Supprimer le compte', 'cancel_account_message': - 'Avertissement: Cette action est irréversible et va supprimer votre compte de façon définitive.', + 'Avertissement: Cette action est irréversible et va supprimer votre compte de façon définitive.', 'delete_company': 'Supprimer l\'entreprise', 'delete_company_message': - 'Avertissement: Cette entreprise sera définitivement supprimée.', + 'Avertissement: Cette entreprise sera définitivement supprimée.', 'enable_modules': 'Enable Modules', 'converted_quote': 'Successfully converted quote', 'credit_design': 'Credit Design', @@ -13317,12 +13326,12 @@ mixin LocalizationsProvider on LocaleCodeAware { 'applied': 'Publié', 'include_recent_errors': 'Inclut les erreurs récentes du relevé', 'your_message_has_been_received': - 'Nous avons reçu votre message et vous répondrons rapidement.', + 'Nous avons reçu votre message et vous répondrons rapidement.', 'message': 'Message', 'from': 'De', 'show_product_details': 'Afficher les détails du produit', 'show_product_details_help': - 'Veuillez inclure la description et le coût dans la liste déroulante du produit', + 'Veuillez inclure la description et le coût dans la liste déroulante du produit', 'pdf_min_requirements': 'Le moteur de rendu PDF nécessite :version', 'adjust_fee_percent': 'Ajuster le pourcentage de frais', 'adjust_fee_percent_help': 'Ajuster le frais de pourcentage au compte', @@ -13339,7 +13348,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'domain_url': 'URL de domaine', 'password_is_too_short': 'Le mot de passe est trop court', 'password_is_too_easy': - 'Le mot de passe doit contenir une majuscule et un nombre', + 'Le mot de passe doit contenir une majuscule et un nombre', 'client_portal_tasks': 'Tâches du portail client', 'client_portal_dashboard': 'Tableau de bord du portail client', 'please_enter_a_value': 'Veuillez saisir une valeur', @@ -13366,16 +13375,16 @@ mixin LocalizationsProvider on LocaleCodeAware { 'third_custom': 'Troisième latéral', 'show_cost': 'Afficher le coût', 'show_cost_help': - 'Afficher un champ de coût du produit pour suivre le profit', + 'Afficher un champ de coût du produit pour suivre le profit', 'show_product_quantity': 'Afficher la quantité de produit', 'show_product_quantity_help': - 'Afficher un champ Quantité de produit. 1 par défaut.', + 'Afficher un champ Quantité de produit. 1 par défaut.', 'show_invoice_quantity': 'Afficher la quantité de facture', 'show_invoice_quantity_help': - 'Afficher un champ Quantité d\'article par ligne. 1 par défaut.', + 'Afficher un champ Quantité d\'article par ligne. 1 par défaut.', 'default_quantity': 'Quantité par défaut', 'default_quantity_help': - 'Définit automatiquement la quantité d\'article par ligne à 1.', + 'Définit automatiquement la quantité d\'article par ligne à 1.', 'one_tax_rate': 'Un taux de taxe', 'two_tax_rates': 'Deux taux de taxe', 'three_tax_rates': 'Trois taux de taxes', @@ -13399,7 +13408,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'dropdown': 'Liste déroulante', 'field_type': 'Type de champ', 'recover_password_email_sent': - 'Un courriel a été envoyé pour la récupération du mot de passe', + 'Un courriel a été envoyé pour la récupération du mot de passe', 'submit': 'Envoyer', 'recover_password': 'Récupérez votre mot de passe', 'late_fees': 'Frais de retard', @@ -13421,7 +13430,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'filtered_by_user': 'Filtré par utilisateur', 'administrator': 'Administrateur', 'administrator_help': - 'Permet à un utilisateur de gérer d\'autres utilisateurs, modifier les paramètres et tous les enregistrements.', + 'Permet à un utilisateur de gérer d\'autres utilisateurs, modifier les paramètres et tous les enregistrements.', 'user_management': 'Gestion des utilisateurs', 'users': 'Utilisateurs', 'new_user': 'Nouvel utilisateur', @@ -13436,10 +13445,10 @@ mixin LocalizationsProvider on LocaleCodeAware { 'invoice_options': 'Options de facturation', 'hide_paid_to_date': 'Masquer \"Payé à ce jour\"', 'hide_paid_to_date_help': - 'Afficher seulement la ligne \"Payé à ce jour\"sur les factures pour lesquelles il y a au moins un paiement.', + 'Afficher seulement la ligne \"Payé à ce jour\"sur les factures pour lesquelles il y a au moins un paiement.', 'invoice_embed_documents': 'Documents intégrés', 'invoice_embed_documents_help': - 'Inclure les images jointes dans la facture.', + 'Inclure les images jointes dans la facture.', 'all_pages_header': 'Afficher l\'entête sur', 'all_pages_footer': 'Afficher le pied de page sur', 'first_page': 'première page', @@ -13460,16 +13469,16 @@ mixin LocalizationsProvider on LocaleCodeAware { 'quote_footer': 'Pied de soumission par défaut', 'auto_email_invoice': 'Envoi automatique', 'auto_email_invoice_help': - 'Envoi automatiquement les factures récurrentes lorsqu\'elles sont créées.', + 'Envoi automatiquement les factures récurrentes lorsqu\'elles sont créées.', 'auto_archive_invoice': 'Autoarchivage', 'auto_archive_invoice_help': - 'Archive automatiquement les soumissions lorsqu\'elles sont converties.', + 'Archive automatiquement les soumissions lorsqu\'elles sont converties.', 'auto_archive_quote': 'Autoarchivage', 'auto_archive_quote_help': - 'Archive automatiquement les soumissions lorsqu\'elles sont converties.', + 'Archive automatiquement les soumissions lorsqu\'elles sont converties.', 'auto_convert_quote': 'Autoconversion', 'auto_convert_quote_help': - 'Convertir automatiquement une soumission en facture lorsque le client l\'accepte.', + 'Convertir automatiquement une soumission en facture lorsque le client l\'accepte.', 'workflow_settings': 'Paramètres de flux de travail', 'freq_daily': 'Quotidienne', 'freq_weekly': 'Hebdomadaire', @@ -13515,28 +13524,28 @@ mixin LocalizationsProvider on LocaleCodeAware { 'custom_javascript': 'JavaScript personnalisé', 'signature_on_pdf': 'Afficher sur le PDF', 'signature_on_pdf_help': - 'Afficher la signature du client sur la facture/soumission PDF.', + 'Afficher la signature du client sur la facture/soumission PDF.', 'show_accept_invoice_terms': - 'Case à cocher pour les conditions de facturation', + 'Case à cocher pour les conditions de facturation', 'show_accept_invoice_terms_help': - 'Requiert du client qu\'il confirme et accepte les conditions de facturation', + 'Requiert du client qu\'il confirme et accepte les conditions de facturation', 'show_accept_quote_terms': - 'Case à cocher pour les conditions de soumssion', + 'Case à cocher pour les conditions de soumssion', 'show_accept_quote_terms_help': - 'Requiert du client qu\'il confirme et accepte les conditions de soumission', + 'Requiert du client qu\'il confirme et accepte les conditions de soumission', 'require_invoice_signature': 'Signature de facture', 'require_invoice_signature_help': 'Requiert une signature du client', 'require_quote_signature': 'Signature de soumission', 'enable_portal_password': 'Protéger les factures avec un mot de passe', 'enable_portal_password_help': - 'Permet de spécifier un mot de passe pour chaque contact. Si un mot de passe est spécifié, le contact devra saisir ce mot de passe pour visualiser ses factures.', + 'Permet de spécifier un mot de passe pour chaque contact. Si un mot de passe est spécifié, le contact devra saisir ce mot de passe pour visualiser ses factures.', 'authorization': 'Autorisation', 'subdomain': 'sous-domaine', 'domain': 'Domaine', 'portal_mode': 'Mode portail', 'email_signature': 'Cordialement,', 'enable_email_markup_help': - 'rendez le paiement plus facile à vos client en ajoutant à vos courriel, le marquage de schema.org.', + 'rendez le paiement plus facile à vos client en ajoutant à vos courriel, le marquage de schema.org.', 'plain': 'Ordinaire', 'light': 'Clair', 'dark': 'Foncé', @@ -13565,12 +13574,12 @@ mixin LocalizationsProvider on LocaleCodeAware { 'accepted_card_logos': 'Logos des cartes acceptées', 'credentials': 'Identifiants', 'require_billing_address_help': - 'Le client doit fournir son adresse de facturation', + 'Le client doit fournir son adresse de facturation', 'require_shipping_address_help': - 'Le client doit fournir son adresse de livraison', + 'Le client doit fournir son adresse de livraison', 'update_address': 'Mise à jour de l\\adresse', 'update_address_help': - 'Met à jour l\'adresse du client avec les informations fournies', + 'Met à jour l\'adresse du client avec les informations fournies', 'rate': 'Taux', 'tax_rate': 'Taux de taxe', 'new_tax_rate': 'Nouveau taux de taxe', @@ -13582,13 +13591,13 @@ mixin LocalizationsProvider on LocaleCodeAware { 'restored_tax_rate': 'Le taux de taxe a été restauré', 'fill_products': 'Remplissage auto des produits', 'fill_products_help': - 'La sélection d\'un produit entrainera la mise à jour de la description et du prix', + 'La sélection d\'un produit entrainera la mise à jour de la description et du prix', 'update_products': 'Mise à jour auto des produits', 'update_products_help': - 'La mise à jour d\'une facture entraîne la mise à jour des produits', + 'La mise à jour d\'une facture entraîne la mise à jour des produits', 'convert_products': 'Convertir les produits', 'convert_products_help': - 'Convertir automatiquement le prix des produits dans la devise du client', + 'Convertir automatiquement le prix des produits dans la devise du client', 'fees': 'Frais', 'limits': 'Limites', 'provider': 'Fournisseur', @@ -13688,7 +13697,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'please_enter_a_first_name': 'Veuillez entrer votre prénom', 'please_enter_a_last_name': 'Veuillez entrer votre nom', 'please_agree_to_terms_and_privacy': - 'Vous devez accepter les conditions et la politique de confidentialité pour créer un compte.', + 'Vous devez accepter les conditions et la politique de confidentialité pour créer un compte.', 'i_agree_to_the': 'J\'accepte', 'terms_of_service_link': 'les conditions', 'privacy_policy_link': 'la politique de confidentialité', @@ -13702,7 +13711,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'create_new': 'Créer', 'no_record_selected': 'Aucun enregistrement sélectionné', 'error_unsaved_changes': - 'Veuillez sauvegarder ou annuler vos modifications', + 'Veuillez sauvegarder ou annuler vos modifications', 'download': 'Télécharger', 'requires_an_enterprise_plan': 'Le plan Entreprise est requis', 'take_picture': 'Prendre un photo', @@ -13788,7 +13797,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'average': 'Moyenne', 'unapproved': 'Non approuvé', 'authenticate_to_change_setting': - 'Veuillez vous connecter pour changer ce paramètre', + 'Veuillez vous connecter pour changer ce paramètre', 'locked': 'Verrouillé', 'authenticate': 'Connexion', 'please_authenticate': 'Veuillez vous connecter', @@ -13988,10 +13997,10 @@ mixin LocalizationsProvider on LocaleCodeAware { 'marked_invoices_as_paid': 'Successfully marked invoices as paid', 'done': 'Valider', 'please_enter_a_client_or_contact_name': - 'Veuillez saisir un nom de client ou de contact', + 'Veuillez saisir un nom de client ou de contact', 'dark_mode': 'Mode foncé', 'restart_app_to_apply_change': - 'Redémarrez l\'app pour mettre à jour les changements', + 'Redémarrez l\'app pour mettre à jour les changements', 'refresh_data': 'Actualiser les données', 'blank_contact': 'Contact vide', 'activity': 'Activité', @@ -14067,12 +14076,12 @@ mixin LocalizationsProvider on LocaleCodeAware { 'activity_4': ':user a créé la facture :invoice', 'activity_5': ':user a mis à jour la facture :invoice', 'activity_6': - ':user a envoyé par courriel la facture :invoice pour :client à :contact', + ':user a envoyé par courriel la facture :invoice pour :client à :contact', 'activity_7': ':contact a visualisé la facture :invoice pour :client', 'activity_8': ':user a archivé la facture :invoice', 'activity_9': ':user a supprimé la facture :invoice', 'activity_10': - ':contact a saisi le paiement :payment de :payment_amount de la facture :invoice pour :client', + ':contact a saisi le paiement :payment de :payment_amount de la facture :invoice pour :client', 'activity_11': ':user a mis à jour le paiement :payment', 'activity_12': ':user a archivé le paiement :payment', 'activity_13': ':user a supprimé le paiement :payment', @@ -14083,7 +14092,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'activity_18': ':user a créé la soumission :quote', 'activity_19': ':user a mis à jour la soumission :quote', 'activity_20': - ':user a envoyé par courriel la soumission :quote pour :client à :contact', + ':user a envoyé par courriel la soumission :quote pour :client à :contact', 'activity_21': ':contact a visualisé la soumission :quote', 'activity_22': ':user a archivé la soumission :quote', 'activity_23': ':user a supprimé la soumission :quote', @@ -14103,7 +14112,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'activity_37': ':user a restauré la dépense :expense', 'activity_39': ':user a annulé un paiement :payment de :payment_amount', 'activity_40': - ':user a remboursé :adjustment d\'un paiement :payment de :payment_amount', + ':user a remboursé :adjustment d\'un paiement :payment de :payment_amount', 'activity_41': 'Le paiement de :payment_amount a échoué (:payment)', 'activity_42': ':user a créé la tâche :task', 'activity_43': ':user a mis à jour la tâche :task', @@ -14121,7 +14130,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'activity_55': ':contact a répondu au billet :ticket', 'activity_56': ':user a vu le billet :ticket', 'activity_57': - 'Le système n\'a pas pu envoyer le courriel de la facture :invoice', + 'Le système n\'a pas pu envoyer le courriel de la facture :invoice', 'one_time_password': 'Mot de passe à usage unique', 'emailed_quote': 'La soumission a été envoyée', 'emailed_credit': 'Successfully emailed credit', @@ -14138,10 +14147,10 @@ mixin LocalizationsProvider on LocaleCodeAware { 'email_style_custom': 'Style de courriel personnalisé', 'custom_message_dashboard': 'Message personnalisé du tableau de bord', 'custom_message_unpaid_invoice': - 'Message personnalisé pour facture impayée', + 'Message personnalisé pour facture impayée', 'custom_message_paid_invoice': 'Message personnalisé pour facture payée', 'custom_message_unapproved_quote': - 'Message personnalisé pour soumission non approuvée', + 'Message personnalisé pour soumission non approuvée', 'lock_sent_invoices': 'Verrouiller les factures envoyées', 'translations': 'Traductions', 'task_number_pattern': 'Modèle du numéro de tâche', @@ -14226,7 +14235,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'purge_data': 'Daten säubern', 'purge_successful': 'Die Kontodaten wurden erfolgreich gelöscht', 'purge_data_message': - 'Achtung: Alle Daten werden vollständig gelöscht. Dieser Vorgang kann nicht rückgängig gemacht werden.', + 'Achtung: Alle Daten werden vollständig gelöscht. Dieser Vorgang kann nicht rückgängig gemacht werden.', 'invoice_balance': 'Invoice Balance', 'age_group_0': '0 - 30 Tage', 'age_group_30': '30 - 60 Tage', @@ -14261,10 +14270,10 @@ mixin LocalizationsProvider on LocaleCodeAware { 'apply_license': 'Lizenz anwenden', 'cancel_account': 'Konto kündigen', 'cancel_account_message': - 'Warnung: Diese Aktion wird dein Konto unwiderruflich löschen.', + 'Warnung: Diese Aktion wird dein Konto unwiderruflich löschen.', 'delete_company': 'Firma löschen', 'delete_company_message': - 'Achtung: Dadurch wird Ihre Firma unwiderruflich gelöscht. Es gibt kein Zurück.', + 'Achtung: Dadurch wird Ihre Firma unwiderruflich gelöscht. Es gibt kein Zurück.', 'enable_modules': 'Enable Modules', 'converted_quote': 'Successfully converted quote', 'credit_design': 'Credit Design', @@ -14416,12 +14425,12 @@ mixin LocalizationsProvider on LocaleCodeAware { 'applied': 'Angewendet', 'include_recent_errors': 'Kürzliche Fehler aus den Logs einfügen', 'your_message_has_been_received': - 'Wir haben ihre Nachricht erhalten und bemühen uns schnellstmöglich zu antworten.', + 'Wir haben ihre Nachricht erhalten und bemühen uns schnellstmöglich zu antworten.', 'message': 'Nachricht', 'from': 'Von', 'show_product_details': 'Produktdetails anzeigen', 'show_product_details_help': - 'Beschreibung und Kosten in die Produkt-Dropdown-Liste einfügen', + 'Beschreibung und Kosten in die Produkt-Dropdown-Liste einfügen', 'pdf_min_requirements': 'Der PDF-Renderer benötigt :version', 'adjust_fee_percent': 'Anpassungszuschlag Prozent', 'adjust_fee_percent_help': 'Gebühren Prozentsatz an das Konto anpassen', @@ -14438,7 +14447,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'domain_url': 'Domain-URL', 'password_is_too_short': 'Das Passwort ist zu kurz', 'password_is_too_easy': - 'Das Passwort muss einen Großbuchstaben und eine Nummer enthalten', + 'Das Passwort muss einen Großbuchstaben und eine Nummer enthalten', 'client_portal_tasks': 'Kundenportal-Aufgaben', 'client_portal_dashboard': 'Kundenportal-Übersicht', 'please_enter_a_value': 'Bitte einen Wert eingeben', @@ -14465,16 +14474,16 @@ mixin LocalizationsProvider on LocaleCodeAware { 'third_custom': 'Dritte benutzerdefinierte', 'show_cost': 'Kosten anzeigen', 'show_cost_help': - 'Display a product cost field to track the markup/profit', + 'Display a product cost field to track the markup/profit', 'show_product_quantity': 'Produktanzahl anzeigen', 'show_product_quantity_help': - 'Display a product quantity field, otherwise default to one', + 'Display a product quantity field, otherwise default to one', 'show_invoice_quantity': 'Rechnungsanzahl anzeigen', 'show_invoice_quantity_help': - 'Display a line item quantity field, otherwise default to one', + 'Display a line item quantity field, otherwise default to one', 'default_quantity': 'Standardanzahl', 'default_quantity_help': - 'Automatically set the line item quantity to one', + 'Automatically set the line item quantity to one', 'one_tax_rate': 'Ein Steuersatz', 'two_tax_rates': 'Zwei Steuersätze', 'three_tax_rates': 'Drei Steuersätze', @@ -14498,7 +14507,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'dropdown': 'Dropdown', 'field_type': 'Feldtyp', 'recover_password_email_sent': - 'Eine Passwort-Wiederherstellungs-Mail wurde versendet', + 'Eine Passwort-Wiederherstellungs-Mail wurde versendet', 'submit': 'Abschicken', 'recover_password': 'Passwort wiederherstellen', 'late_fees': 'Verspätungszuschläge', @@ -14520,7 +14529,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'filtered_by_user': 'Gefiltert nach Benutzer', 'administrator': 'Administrator', 'administrator_help': - 'Dem Benutzer erlauben, andere Benutzer zu administrieren, Einstellungen zu ändern und alle Einträge zu bearbeiten', + 'Dem Benutzer erlauben, andere Benutzer zu administrieren, Einstellungen zu ändern und alle Einträge zu bearbeiten', 'user_management': 'Benutzerverwaltung', 'users': 'Benutzer', 'new_user': 'Neuer Benutzer', @@ -14535,10 +14544,10 @@ mixin LocalizationsProvider on LocaleCodeAware { 'invoice_options': 'Rechnungsoptionen', 'hide_paid_to_date': '\"Bereits gezahlt\" ausblenden', 'hide_paid_to_date_help': - '\"Bereits gezahlt\" nur anzeigen, wenn eine Zahlung eingegangen ist.', + '\"Bereits gezahlt\" nur anzeigen, wenn eine Zahlung eingegangen ist.', 'invoice_embed_documents': 'Dokumente einbetten', 'invoice_embed_documents_help': - 'Bildanhänge zu den Rechnungen hinzufügen.', + 'Bildanhänge zu den Rechnungen hinzufügen.', 'all_pages_header': 'Zeige Kopf auf', 'all_pages_footer': 'Zeige Fußzeilen auf', 'first_page': 'Erste Seite', @@ -14559,16 +14568,16 @@ mixin LocalizationsProvider on LocaleCodeAware { 'quote_footer': 'Angebots-Fußzeile', 'auto_email_invoice': 'Automatische Email', 'auto_email_invoice_help': - 'Senden Sie wiederkehrende Rechnungen automatisch per E-Mail, wenn sie erstellt werden.', + 'Senden Sie wiederkehrende Rechnungen automatisch per E-Mail, wenn sie erstellt werden.', 'auto_archive_invoice': 'Automatisches Archiv', 'auto_archive_invoice_help': - 'Archivieren Sie Rechnungen automatisch, wenn sie bezahlt sind.', + 'Archivieren Sie Rechnungen automatisch, wenn sie bezahlt sind.', 'auto_archive_quote': 'Automatisches Archiv', 'auto_archive_quote_help': - 'Archivieren Sie Angebote automatisch, wenn sie konvertiert werden.', + 'Archivieren Sie Angebote automatisch, wenn sie konvertiert werden.', 'auto_convert_quote': 'Automatisch konvertieren', 'auto_convert_quote_help': - 'Das Angebot automatisch in eine Rechnung umwandeln wenn es vom Kunden angenommen wird.', + 'Das Angebot automatisch in eine Rechnung umwandeln wenn es vom Kunden angenommen wird.', 'workflow_settings': 'Workflow Einstellungen', 'freq_daily': 'Täglich', 'freq_weekly': 'Wöchentlich', @@ -14614,27 +14623,27 @@ mixin LocalizationsProvider on LocaleCodeAware { 'custom_javascript': 'Benutzerdefiniertes JavaScript', 'signature_on_pdf': 'Auf PDF anzeigen', 'signature_on_pdf_help': - 'Unterschrift des Kunden auf dem Angebots/Rechnungs PDF anzeigen.', + 'Unterschrift des Kunden auf dem Angebots/Rechnungs PDF anzeigen.', 'show_accept_invoice_terms': 'Checkbox für Rechnungsbedingungen', 'show_accept_invoice_terms_help': - 'Erfordern Sie die Bestätigung der Rechnungsbedingungen durch den Kunden.', + 'Erfordern Sie die Bestätigung der Rechnungsbedingungen durch den Kunden.', 'show_accept_quote_terms': 'Checkbox für Angebotsbedingungen', 'show_accept_quote_terms_help': - 'Erfordern Sie die Bestätigung der Angebotsbedingungen durch den Kunden.', + 'Erfordern Sie die Bestätigung der Angebotsbedingungen durch den Kunden.', 'require_invoice_signature': 'Rechnungsunterschrift', 'require_invoice_signature_help': - 'Erfordern Sie die Unterschrift des Kunden bei Rechnungen.', + 'Erfordern Sie die Unterschrift des Kunden bei Rechnungen.', 'require_quote_signature': 'Angebotsunterschrift', 'enable_portal_password': 'Rechnungen mit Passwort schützen', 'enable_portal_password_help': - 'Erlaubt Ihnen ein Passwort für jeden Kontakt zu erstellen. Wenn ein Passwort erstellt wurde, muss der Kunde dieses eingeben, bevor er eine Rechnung ansehen darf.', + 'Erlaubt Ihnen ein Passwort für jeden Kontakt zu erstellen. Wenn ein Passwort erstellt wurde, muss der Kunde dieses eingeben, bevor er eine Rechnung ansehen darf.', 'authorization': 'Genehmigung', 'subdomain': 'Subdomäne', 'domain': 'Domäne', 'portal_mode': 'Portalmodus', 'email_signature': 'Mit freundlichen Grüßen,', 'enable_email_markup_help': - 'Machen Sie es einfacher für Ihre Kunden zu bezahlen, indem Sie schema.org Markup zu Ihren E-Mails hinzufügen.', + 'Machen Sie es einfacher für Ihre Kunden zu bezahlen, indem Sie schema.org Markup zu Ihren E-Mails hinzufügen.', 'plain': 'Einfach', 'light': 'Hell', 'dark': 'Dunkel', @@ -14663,11 +14672,11 @@ mixin LocalizationsProvider on LocaleCodeAware { 'accepted_card_logos': 'Logos der akzeptierten Kreditkarten', 'credentials': 'Zugangsdaten', 'require_billing_address_help': - 'Kunde muss seine Rechnungsadresse angeben', + 'Kunde muss seine Rechnungsadresse angeben', 'require_shipping_address_help': 'Kunde muss seine Lieferadresse angeben', 'update_address': 'Adresse aktualisieren', 'update_address_help': - 'Kundenadresse mit den gemachten Angaben aktualisieren', + 'Kundenadresse mit den gemachten Angaben aktualisieren', 'rate': 'Satz', 'tax_rate': 'Steuersatz', 'new_tax_rate': 'Neuer Steuersatz', @@ -14679,13 +14688,13 @@ mixin LocalizationsProvider on LocaleCodeAware { 'restored_tax_rate': 'Steuersatz erfolgreich wiederhergestellt', 'fill_products': 'Produkte automatisch ausfüllen', 'fill_products_help': - 'Beim Auswählen eines Produktes werden automatisch Beschreibung und Kosten ausgefüllt', + 'Beim Auswählen eines Produktes werden automatisch Beschreibung und Kosten ausgefüllt', 'update_products': 'Produkte automatisch aktualisieren', 'update_products_help': - 'Beim Aktualisieren einer Rechnung werden die Produkte automatisch aktualisiert', + 'Beim Aktualisieren einer Rechnung werden die Produkte automatisch aktualisiert', 'convert_products': 'Produkte konvertieren', 'convert_products_help': - 'Produktpreise automatisch in die Währung des Kunden konvertieren', + 'Produktpreise automatisch in die Währung des Kunden konvertieren', 'fees': 'Gebühren', 'limits': 'Grenzwerte', 'provider': 'Anbieter', @@ -14785,7 +14794,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'please_enter_a_first_name': 'Bitte geben Sie einen Vornamen ein', 'please_enter_a_last_name': 'Bitte geben Sie einen Nachnamen ein', 'please_agree_to_terms_and_privacy': - 'Bitte stimmen Sie den Nutzungsbedingungen und der Datenschutzerklärung zu, um ein Konto zu erstellen.', + 'Bitte stimmen Sie den Nutzungsbedingungen und der Datenschutzerklärung zu, um ein Konto zu erstellen.', 'i_agree_to_the': 'Ich stimme den', 'terms_of_service_link': 'Nutzungsbedingungen', 'privacy_policy_link': 'Datenschutzerklärung', @@ -14799,7 +14808,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'create_new': 'Neu...', 'no_record_selected': 'Kein Eintrag ausgewählt', 'error_unsaved_changes': - 'Bitte speichern oder verwerfen Sie Ihre Änderungen', + 'Bitte speichern oder verwerfen Sie Ihre Änderungen', 'download': 'Downloaden', 'requires_an_enterprise_plan': 'Benötigt einen Enterprise Plan', 'take_picture': 'Bild aufnehmen', @@ -14885,7 +14894,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'average': 'Durchschnittlich', 'unapproved': 'Nicht genehmigt', 'authenticate_to_change_setting': - 'Bitte authentifizieren Sie sich, um diese Einstellung zu ändern.', + 'Bitte authentifizieren Sie sich, um diese Einstellung zu ändern.', 'locked': 'Gesperrt', 'authenticate': 'Authentifizieren', 'please_authenticate': 'Bitte authentifizieren Sie sich', @@ -14961,7 +14970,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'please_enter_your_password': 'Bitte geben Sie Ihr Passwort ein', 'please_enter_your_url': 'Bitte geben Sie Ihre URL ein', 'please_enter_a_product_key': - 'Bitte geben Sie Ihren Produkt schlüssel ein', + 'Bitte geben Sie Ihren Produkt schlüssel ein', 'ascending': 'Aufsteigend', 'descending': 'Absteigend', 'save': 'Speichern', @@ -15054,7 +15063,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'invoice_status_id': 'Rechnungs Status', 'quote_status': 'Angebots Status', 'click_plus_to_add_item': - 'Klicken Sie auf +, um ein Element hinzuzufügen.', + 'Klicken Sie auf +, um ein Element hinzuzufügen.', 'click_plus_to_add_time': 'Klicken Sie auf +, um die Zeit hinzuzufügen.', 'count_selected': ':count ausgewählt', 'total': 'Gesamt', @@ -15072,7 +15081,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'updated_at': 'Aktualisiert', 'tax': 'Steuer', 'please_enter_an_invoice_number': - 'Bitte geben Sie eine Rechnungs Nummer ein', + 'Bitte geben Sie eine Rechnungs Nummer ein', 'please_enter_a_quote_number': 'Bitte geben Sie eine Angebots Nummer ein', 'past_due': 'Überfällig', 'draft': 'Entwurf', @@ -15085,14 +15094,14 @@ mixin LocalizationsProvider on LocaleCodeAware { 'marked_invoice_as_sent': 'Rechnung erfolgreich als versendet markiert', 'marked_invoice_as_paid': 'Successfully marked invoice as paid', 'marked_invoices_as_sent': - 'Erfolgreich Rechnungen als versendet markiert', + 'Erfolgreich Rechnungen als versendet markiert', 'marked_invoices_as_paid': 'Successfully marked invoices as paid', 'done': 'Erledigt', 'please_enter_a_client_or_contact_name': - 'Bitte geben Sie einen Kunden- oder Kontaktnamen ein', + 'Bitte geben Sie einen Kunden- oder Kontaktnamen ein', 'dark_mode': 'Dunkler Modus', 'restart_app_to_apply_change': - 'Starten Sie die App neu, um die Änderung zu übernehmen.', + 'Starten Sie die App neu, um die Änderung zu übernehmen.', 'refresh_data': 'Daten aktualisieren', 'blank_contact': 'Leerer Kontakt', 'activity': 'Aktivität', @@ -15172,7 +15181,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'activity_8': ':user archivierte Rechnung :invoice', 'activity_9': ':user löschte Rechnung :invoice', 'activity_10': - ':contact gab Zahlungsinformation :payment über :payment_amount für Rechnung :invoice für Kunde :client', + ':contact gab Zahlungsinformation :payment über :payment_amount für Rechnung :invoice für Kunde :client', 'activity_11': ':user aktualisierte Zahlung :payment', 'activity_12': ':user archivierte Zahlung :payment', 'activity_13': ':user löschte Zahlung :payment', @@ -15201,9 +15210,9 @@ mixin LocalizationsProvider on LocaleCodeAware { 'activity_36': ':user hat Ausgabe :expense gelöscht', 'activity_37': ':user hat Ausgabe :expense wiederhergestellt', 'activity_39': - ':user brach eine Zahlung über :payment_amount ab :payment', + ':user brach eine Zahlung über :payment_amount ab :payment', 'activity_40': - ':user hat :adjustment von :payment_amount der Zahlung :payment zurück erstattet', + ':user hat :adjustment von :payment_amount der Zahlung :payment zurück erstattet', 'activity_41': ':payment_amount Zahlung (:payment) schlug fehl', 'activity_42': ':user hat Aufgabe :task erstellt', 'activity_43': ':user hat Aufgabe :task bearbeitet', @@ -15221,7 +15230,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'activity_55': ':contact hat auf Ticket :ticket geantwortet', 'activity_56': ':user hat Ticket :ticket angesehen', 'activity_57': - 'Das System konnte die Rechnung :invoice nicht per E-Mail versenden', + 'Das System konnte die Rechnung :invoice nicht per E-Mail versenden', 'one_time_password': 'Einmaliges Passwort', 'emailed_quote': 'Angebot erfolgreich versendet', 'emailed_credit': 'Successfully emailed credit', @@ -15238,11 +15247,11 @@ mixin LocalizationsProvider on LocaleCodeAware { 'email_style_custom': 'Benutzer definierter E-Mail-Stil', 'custom_message_dashboard': 'Benutzerdefinierte Dashboard-Nachricht', 'custom_message_unpaid_invoice': - 'Benutzerdefinierte Nachricht für unbezahlte Rechnung', + 'Benutzerdefinierte Nachricht für unbezahlte Rechnung', 'custom_message_paid_invoice': - 'Benutzerdefinierte Nachricht für bezahlte Rechnung', + 'Benutzerdefinierte Nachricht für bezahlte Rechnung', 'custom_message_unapproved_quote': - 'Benutzerdefinierte Nachricht für nicht genehmigten Kostenvoranschlag', + 'Benutzerdefinierte Nachricht für nicht genehmigten Kostenvoranschlag', 'lock_sent_invoices': 'Lock Sent Invoices', 'translations': 'Übersetzungen', 'task_number_pattern': 'Aufgabennummernschema', @@ -15327,7 +15336,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'purge_data': 'Εκκαθάριση Δεδομένων', 'purge_successful': 'Επιτυχής εκκαθάριση δεδομένων επιχείρησης', 'purge_data_message': - 'Προσοχή: Αυτό θα σβήσει όλα σας τα δεδομένα, χωρίς δυνατότητα αναίρεσης.', + 'Προσοχή: Αυτό θα σβήσει όλα σας τα δεδομένα, χωρίς δυνατότητα αναίρεσης.', 'invoice_balance': 'Invoice Balance', 'age_group_0': '0 - 30 Ημέρες', 'age_group_30': '30 - 60 Ημέρες', @@ -15362,10 +15371,10 @@ mixin LocalizationsProvider on LocaleCodeAware { 'apply_license': 'Εφαρμογή Άδειας Χρήσης', 'cancel_account': 'Διαγραφή Λογαριασμού', 'cancel_account_message': - 'Προσοχή: Αυτό θα σβήσει το λογαριασμό σας, χωρίς δυνατότητα αναίρεσης.', + 'Προσοχή: Αυτό θα σβήσει το λογαριασμό σας, χωρίς δυνατότητα αναίρεσης.', 'delete_company': 'Διαγραφή Επιχείρησης', 'delete_company_message': - 'Προειδοποίηση: Αυτό θα διαγράψει οριστικά την επιχείρηση, χωρίς αναίρεση.', + 'Προειδοποίηση: Αυτό θα διαγράψει οριστικά την επιχείρηση, χωρίς αναίρεση.', 'enable_modules': 'Enable Modules', 'converted_quote': 'Successfully converted quote', 'credit_design': 'Credit Design', @@ -15516,18 +15525,18 @@ mixin LocalizationsProvider on LocaleCodeAware { 'verify_password': 'Επαλήθευση Κωδικού', 'applied': 'Εγινε εφαρμογή', 'include_recent_errors': - 'Συμπερίληψη πρόσφατων σφαλμάτων απο αρχεία καταγραφής', + 'Συμπερίληψη πρόσφατων σφαλμάτων απο αρχεία καταγραφής', 'your_message_has_been_received': - 'Εχουμε λάβει το μήνυμά σας και θα σας απαντήσουμε σύντομα.', + 'Εχουμε λάβει το μήνυμά σας και θα σας απαντήσουμε σύντομα.', 'message': 'Μήνυμα', 'from': 'Από', 'show_product_details': 'Εμφάνιση Λεπτομερειών Προιόντος', 'show_product_details_help': - 'Συμπερίληψη της περιγραφής και κόστους τιμής στη λίστα προιόντος', + 'Συμπερίληψη της περιγραφής και κόστους τιμής στη λίστα προιόντος', 'pdf_min_requirements': 'Ο κωδικοποιητής PDF απαιτεί :version', 'adjust_fee_percent': 'Προσαρμογή του ποσοστού του τέλους', 'adjust_fee_percent_help': - 'Τροποποίηση του ποσοστού του λογαριασμού για τέλος', + 'Τροποποίηση του ποσοστού του λογαριασμού για τέλος', 'configure_settings': 'Προσαρμογή Ρυθμίσεων', 'support_forum': 'φόρουμ υποστήριξης', 'about': 'Περί', @@ -15541,7 +15550,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'domain_url': 'Σύνδεσμος URL', 'password_is_too_short': 'Ο κωδικός πρόσβασης είναι πολύ μικρός', 'password_is_too_easy': - 'Ο κωδικός πρόσβασης πρέπει να περιέχει ένα κεφαλαίο χαρακτήρα και έναν αριθμό', + 'Ο κωδικός πρόσβασης πρέπει να περιέχει ένα κεφαλαίο χαρακτήρα και έναν αριθμό', 'client_portal_tasks': 'Εργασίες πύλης πελάτη', 'client_portal_dashboard': 'Πίνακας ελέγχου πύλης πελατών', 'please_enter_a_value': 'Παρακαλούμε ορίστε μια τιμή', @@ -15568,13 +15577,13 @@ mixin LocalizationsProvider on LocaleCodeAware { 'third_custom': 'Τρίτη Προσαρμογή', 'show_cost': 'Εμφάνιση Κόστους', 'show_cost_help': - 'Εμφάνιση του πεδίου κόστους προϊόντος για να είναι δυνατή η εύρεση του κέρδους', + 'Εμφάνιση του πεδίου κόστους προϊόντος για να είναι δυνατή η εύρεση του κέρδους', 'show_product_quantity': 'Εμφάνισε την Ποσότητα Προϊόντος', 'show_product_quantity_help': - 'Εμφάνιση του πεδίου ποσότητας προϊόντος, αλλιώς ορισμός σε ένα', + 'Εμφάνιση του πεδίου ποσότητας προϊόντος, αλλιώς ορισμός σε ένα', 'show_invoice_quantity': 'Εμφάνισε την Ποσότητα Τιμολογίου', 'show_invoice_quantity_help': - 'Εμφάνιση του πεδίου ποσότητας γραμμής, αλλιώς ορισμός σε ένα', + 'Εμφάνιση του πεδίου ποσότητας γραμμής, αλλιώς ορισμός σε ένα', 'default_quantity': 'Προεπιλεγμένη Ποσότητα', 'default_quantity_help': 'Αυτόματος ορισμός της ποσότητας γραμμής σε ένα', 'one_tax_rate': 'Ένα Ποσοστό Φόρου', @@ -15600,7 +15609,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'dropdown': 'Πτυσώμενο', 'field_type': 'Τύπος Πεδίου', 'recover_password_email_sent': - 'Ένα email ανάκτησης κωδικού έχει αποσταλεί', + 'Ένα email ανάκτησης κωδικού έχει αποσταλεί', 'submit': 'Υποβολή', 'recover_password': 'Ανάκτηση του κωδικού πρόσβασής σας', 'late_fees': 'Καθυστερούμενα Τέλη', @@ -15622,7 +15631,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'filtered_by_user': 'Φιλτράρισμα από το Χρήστη', 'administrator': 'Διαχειριστής', 'administrator_help': - 'Επιτρέψτε στο χρήστη να διαχειρίζεται χρήστες, να αλλάζει ρυθμίσεις και να τροποποιεί όλες τις εγγραφές', + 'Επιτρέψτε στο χρήστη να διαχειρίζεται χρήστες, να αλλάζει ρυθμίσεις και να τροποποιεί όλες τις εγγραφές', 'user_management': 'Διαχειριση Χρηστών', 'users': 'Χρήστες', 'new_user': 'Νέος Χρήστης', @@ -15637,10 +15646,10 @@ mixin LocalizationsProvider on LocaleCodeAware { 'invoice_options': 'Επιλογές Τιμολογίου', 'hide_paid_to_date': 'Απόκρυψη Εξοφλημένου Ποσού', 'hide_paid_to_date_help': - 'Εμφάνιση πεδίου \"Εξοφλημένο Ποσό\" μόνο στο παραστατικό όταν ληφθεί μια πληρωμή.', + 'Εμφάνιση πεδίου \"Εξοφλημένο Ποσό\" μόνο στο παραστατικό όταν ληφθεί μια πληρωμή.', 'invoice_embed_documents': 'Ενσωματωμένα Έγγραφα', 'invoice_embed_documents_help': - 'Συμπεριλάβετε τις συνημμένες εικόνες στο τιμολόγιο', + 'Συμπεριλάβετε τις συνημμένες εικόνες στο τιμολόγιο', 'all_pages_header': 'Εμφάνιση Κεφαλίδας', 'all_pages_footer': 'Εμφάνιση Υποσέλιδου', 'first_page': 'Πρώτη σελίδα', @@ -15661,16 +15670,16 @@ mixin LocalizationsProvider on LocaleCodeAware { 'quote_footer': 'Υποσέλιδο Προσφοράς', 'auto_email_invoice': 'Αυτόματο Email', 'auto_email_invoice_help': - 'Αυτόματη αποστολή επαναλαμβανόμενων τιμολογίων με email όταν δημιουργηθούν.', + 'Αυτόματη αποστολή επαναλαμβανόμενων τιμολογίων με email όταν δημιουργηθούν.', 'auto_archive_invoice': 'Αυτόματη Αρχειοθέτηση', 'auto_archive_invoice_help': - 'Αυτόματη αρχειοθέτηση τιμολογίων όταν εξοφληθούν.', + 'Αυτόματη αρχειοθέτηση τιμολογίων όταν εξοφληθούν.', 'auto_archive_quote': 'Αυτόματη Αρχειοθέτηση', 'auto_archive_quote_help': - 'Αυτόματη αρχειοθέτηση προσφορών όταν μετατραπούν.', + 'Αυτόματη αρχειοθέτηση προσφορών όταν μετατραπούν.', 'auto_convert_quote': 'Αυτόματη Μετατροπή', 'auto_convert_quote_help': - 'Αυτόματη μετατροπή της προσφοράς σε τιμολόγιο μόλις γίνει αποδεκτή από τον πελάτη.', + 'Αυτόματη μετατροπή της προσφοράς σε τιμολόγιο μόλις γίνει αποδεκτή από τον πελάτη.', 'workflow_settings': 'Ρυθμίσεις Ροής Εργασιών', 'freq_daily': 'Ημερήσιο', 'freq_weekly': 'Εβδομάδα', @@ -15716,27 +15725,27 @@ mixin LocalizationsProvider on LocaleCodeAware { 'custom_javascript': 'Προσαρμοσμένη JavaScript', 'signature_on_pdf': 'Εμφάνισε στο PDF', 'signature_on_pdf_help': - 'Εμφάνισε την υπογραφή του πελάτη στο PDF του τιμολογίου/προσφοράς.', + 'Εμφάνισε την υπογραφή του πελάτη στο PDF του τιμολογίου/προσφοράς.', 'show_accept_invoice_terms': 'Κουτάκι Όρων Τιμολογίου', 'show_accept_invoice_terms_help': - 'Απαίτηση από τον πελάτη να αποδεχθεί τους όρους του τιμολογίου', + 'Απαίτηση από τον πελάτη να αποδεχθεί τους όρους του τιμολογίου', 'show_accept_quote_terms': 'Κουτάκι Όρων Προσφοράς', 'show_accept_quote_terms_help': - 'Απαίτηση από τον πελάτη να αποδεχθεί τους όρους της προσφοράς', + 'Απαίτηση από τον πελάτη να αποδεχθεί τους όρους της προσφοράς', 'require_invoice_signature': 'Υπογραφή Τιμολογίου', 'require_invoice_signature_help': - 'Απαίτηση από τον πελάτη να συμπληρώσει την υπογραφή του.', + 'Απαίτηση από τον πελάτη να συμπληρώσει την υπογραφή του.', 'require_quote_signature': 'Υπογραφή Προσφοράς', 'enable_portal_password': 'Προστασία Τιμολογίων με Κωδικό Πρόσβασης', 'enable_portal_password_help': - 'Επιτρέπει τον καθορισμό κωδικού πρόσβασης για κάθε επαφή. Αν έχει καθοριστεί κωδικός, η επαφή θα υποχρεούται να καταχωρήσει κωδικό πριν την προβολή των τιμολογίων.', + 'Επιτρέπει τον καθορισμό κωδικού πρόσβασης για κάθε επαφή. Αν έχει καθοριστεί κωδικός, η επαφή θα υποχρεούται να καταχωρήσει κωδικό πριν την προβολή των τιμολογίων.', 'authorization': 'Εξουσιοδότηση', 'subdomain': 'Υποτομέας', 'domain': 'Domain', 'portal_mode': 'Portal Mode', 'email_signature': 'Με εκτίμηση,', 'enable_email_markup_help': - 'Κάντε τη διαδικασία πληρωμής πιο εύκολη για τους πελάτες σας προσθέτοντας σήμανση από το schema.org στα emails σας.', + 'Κάντε τη διαδικασία πληρωμής πιο εύκολη για τους πελάτες σας προσθέτοντας σήμανση από το schema.org στα emails σας.', 'plain': 'Απλό', 'light': 'Ανοιχτό', 'dark': 'Σκούρο', @@ -15765,12 +15774,12 @@ mixin LocalizationsProvider on LocaleCodeAware { 'accepted_card_logos': 'Λογότυπα Αποδεκτών Καρτών', 'credentials': 'Στοιχεία εισόδου', 'require_billing_address_help': - 'Απαίτηση από τον πελάτη να συμπληρώσει τη διεύθυνση τιμολόγησης', + 'Απαίτηση από τον πελάτη να συμπληρώσει τη διεύθυνση τιμολόγησης', 'require_shipping_address_help': - 'Απαίτηση από τον πελάτη να εισάγει την διεύθυνση αποστολής του', + 'Απαίτηση από τον πελάτη να εισάγει την διεύθυνση αποστολής του', 'update_address': 'Ενημέρωση Διεύθυνσης', 'update_address_help': - 'Ενημέρωση της διεύθυνσης του πελάτη με τα παρεχόμενα στοιχεία', + 'Ενημέρωση της διεύθυνσης του πελάτη με τα παρεχόμενα στοιχεία', 'rate': 'Ποσοστό', 'tax_rate': 'Ποσοστό Φόρου', 'new_tax_rate': 'Νέο Ποσοστό Φόρου', @@ -15782,13 +15791,13 @@ mixin LocalizationsProvider on LocaleCodeAware { 'restored_tax_rate': 'Επιτυχής ανάκτηση ποσοστού φόρου', 'fill_products': 'Αυτόματη συμπλήρωση προϊόντων', 'fill_products_help': - 'Επιλέγοντας ένα προϊόν, αυτόματα θα συμπληρωθεί η περιγραφή και η αξία', + 'Επιλέγοντας ένα προϊόν, αυτόματα θα συμπληρωθεί η περιγραφή και η αξία', 'update_products': 'Αυτόματη ενημέρωση προϊόντων', 'update_products_help': - 'Ενημερώνοντας ένα τιμολόγιο, αυτόματα θα ενημερωθεί και η βιβλιοθήκη προϊόντων', + 'Ενημερώνοντας ένα τιμολόγιο, αυτόματα θα ενημερωθεί και η βιβλιοθήκη προϊόντων', 'convert_products': 'Μετατροπή Τιμών Προϊόντων', 'convert_products_help': - 'Αυτόματη μετατροπή τιμών προϊόντων στο νόμισμα συναλλαγών του πελάτη', + 'Αυτόματη μετατροπή τιμών προϊόντων στο νόμισμα συναλλαγών του πελάτη', 'fees': 'Τέλη', 'limits': 'Όρια', 'provider': 'Provider', @@ -15799,7 +15808,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'created_company_gateway': 'Επιτυχής δημιουργία πύλης πληρωμών (Gateway)', 'updated_company_gateway': 'Επιτυχής ενημέρωση πύλης πληρωμών (Gateway)', 'archived_company_gateway': - 'Επιτυχής αρχειοθέτηση πύλης πληρωμών (Gateway)', + 'Επιτυχής αρχειοθέτηση πύλης πληρωμών (Gateway)', 'deleted_company_gateway': 'Επιτυχής διαγραφή πύλης πληρωμών (Gateway)', 'restored_company_gateway': 'Επιτυχής επαναφορά πύλης πληρωμών (Gateway)', 'continue_editing': 'Συνεχίστε την Επεξεργασία', @@ -15889,7 +15898,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'please_enter_a_first_name': 'Παρακαλούμε εισάγετε μικρό όνομα', 'please_enter_a_last_name': 'Παρακαλούμε εισάγετε επώνυμο', 'please_agree_to_terms_and_privacy': - 'Παρακαλούμε συμφωνήστε με τους όρους χρήσης και την πολιτική απορρήτου για να δημιουργήσετε ένα λογαριασμό.', + 'Παρακαλούμε συμφωνήστε με τους όρους χρήσης και την πολιτική απορρήτου για να δημιουργήσετε ένα λογαριασμό.', 'i_agree_to_the': 'Συμφωνώ με το', 'terms_of_service_link': 'όροι της υπηρεσίας', 'privacy_policy_link': 'πολιτική απορρήτου', @@ -15981,7 +15990,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'restored_project': 'Επιτυχής ανάκτηση project', 'new_project': 'Νέο Project', 'thank_you_for_using_our_app': - 'Ευχαριστούμε που χρησιμοποιήσατε την εφαρμογή μας!', + 'Ευχαριστούμε που χρησιμοποιήσατε την εφαρμογή μας!', 'if_you_like_it': 'Εάν σας αρέσει παρακαλούμε', 'click_here': 'πατήστε εδώ', 'click_here_capital': 'Πατήστε εδώ', @@ -15989,7 +15998,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'average': 'Μέσος όρος', 'unapproved': 'Μη εγκεκριμένη', 'authenticate_to_change_setting': - 'Παρακαλούμε αυθεντικοποιήστε για να αλλάξετε αυτή τη ρύθμιση', + 'Παρακαλούμε αυθεντικοποιήστε για να αλλάξετε αυτή τη ρύθμιση', 'locked': 'Κλειδωμένη', 'authenticate': 'Αυθεντικοποιήστε', 'please_authenticate': 'Παρακαλούμε αυθεντικοποιήστε', @@ -16063,7 +16072,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'refresh_complete': 'Ανανέωση Ολοκληρώθηκε', 'please_enter_your_email': 'Παρακαλώ εισάγετε το email σας', 'please_enter_your_password': - 'Παρακαλώ εισάγετε τον κωδικό πρόσβασής σας', + 'Παρακαλώ εισάγετε τον κωδικό πρόσβασής σας', 'please_enter_your_url': 'Παρακαλώ εισάγετε το URL σας', 'please_enter_a_product_key': 'Παρακαλώ εισάγετε το κλειδί προϊόντος σας', 'ascending': 'Αύξουσα σειρά', @@ -16175,7 +16184,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'updated_at': 'Ενημερώθηκε', 'tax': 'Φόρος', 'please_enter_an_invoice_number': - 'Παρακαλώ εισάγετε ένα αριθμό τιμολογίου', + 'Παρακαλώ εισάγετε ένα αριθμό τιμολογίου', 'please_enter_a_quote_number': 'Παρακαλώ εισάγετε ένα αριθμό προσφοράς', 'past_due': 'Ληγμένα', 'draft': 'Πρόχειρο', @@ -16191,10 +16200,10 @@ mixin LocalizationsProvider on LocaleCodeAware { 'marked_invoices_as_paid': 'Successfully marked invoices as paid', 'done': 'Έτοιμο', 'please_enter_a_client_or_contact_name': - 'Παρακαλώ εισάγετε ένα πελάτη ή το όνομα μίας επαφής', + 'Παρακαλώ εισάγετε ένα πελάτη ή το όνομα μίας επαφής', 'dark_mode': 'Σκοτεινό Περιβάλλον', 'restart_app_to_apply_change': - 'Επανεκκινήστε την εφαρμογή για να εφαρμόσετε την αλλαγή', + 'Επανεκκινήστε την εφαρμογή για να εφαρμόσετε την αλλαγή', 'refresh_data': 'Ανανέωση Δεδομένων', 'blank_contact': 'Κενή Επαφή', 'activity': 'Δραστηριότητα', @@ -16270,13 +16279,13 @@ mixin LocalizationsProvider on LocaleCodeAware { 'activity_4': 'Ο χρήστης :user δημιούργησε το τιμολόγιο :invoice', 'activity_5': 'Ο χρήστης :user ενημέρωσε το τιμολόγιο :invoice', 'activity_6': - 'Ο χρήστης :user έστειλε με email το τιμολόγιο :invoice για τον πελάτη :client στην επαφή :contact', + 'Ο χρήστης :user έστειλε με email το τιμολόγιο :invoice για τον πελάτη :client στην επαφή :contact', 'activity_7': - 'Η επαφή :contact είδε το τιμολόγιο :invoice για τον πελάτη :client', + 'Η επαφή :contact είδε το τιμολόγιο :invoice για τον πελάτη :client', 'activity_8': 'Ο χρήστης :user αρχειοθέτησε το τιμολόγιο :invoice', 'activity_9': 'Ο χρήστης :user διέγραψε το τιμολόγιο :invoice', 'activity_10': - 'Η επαφή :contact καταχώρησε την πληρωμή ποσού :payment_amount για το τιμολόγιο :invoice για τον πελάτη :client', + 'Η επαφή :contact καταχώρησε την πληρωμή ποσού :payment_amount για το τιμολόγιο :invoice για τον πελάτη :client', 'activity_11': 'Ο χρήστης :user ενημέρωσε την πληρωμή :payment', 'activity_12': 'Ο χρήστης :user αρχειοθέτησε την πληρωμή :payment', 'activity_13': 'Ο χρήστης :user διέγραψε την πληρωμή :payment', @@ -16287,7 +16296,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'activity_18': 'Ο χρήστης :user δημιουργησε την προσφορά :quote', 'activity_19': 'Ο χρήστης :user ενημέρωσε την προσφορά :quote', 'activity_20': - 'Ο χρήστης :user έστειλε με email την προσφορά :quote για τον πελάτη :client στην επαφή :contact', + 'Ο χρήστης :user έστειλε με email την προσφορά :quote για τον πελάτη :client στην επαφή :contact', 'activity_21': 'Η επαφή :contact είδε την προσφορά :quote', 'activity_22': 'Ο χρήστης :user αρχειοθέτησε την προσφορά :quote', 'activity_23': 'Ο χρήστης :user διέγραψε την προσφορά :quote', @@ -16297,7 +16306,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'activity_27': 'Ο χρήστης :user επανέφερε την πληρωμή :payment', 'activity_28': 'Ο χρήστης :user επανέφερε την πίστωση :credit', 'activity_29': - 'Η επαφή :contact αποδέχτηκε την προσφορά :quote για τον πελάτη :client', + 'Η επαφή :contact αποδέχτηκε την προσφορά :quote για τον πελάτη :client', 'activity_30': 'Ο χρήστης :user δημιούργησε τον προμηθευτή :vendor', 'activity_31': 'Ο χρήστης :user αρχειοθέτησε τον προμηθευτή :vendor', 'activity_32': 'Ο χρήστης :user διέγραψε τον προμηθευτή :vendor', @@ -16308,7 +16317,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'activity_37': 'Ο χρήστης :user επανέφερε τη δαπάνη :expense', 'activity_39': ':user ακύρωσε :payment_amount πληρωμής :payment', 'activity_40': - ':user επέστρεψε :adjustment μιας :payment_amount πληρωμής :payment', + ':user επέστρεψε :adjustment μιας :payment_amount πληρωμής :payment', 'activity_41': ':payment_amount πληρωμής (:payment) απέτυχε', 'activity_42': 'Ο χρήστης :user δημιούργησε την εργασία :task', 'activity_43': 'Ο χρήστης :user ενημέρωσε την εργασία :task', @@ -16320,17 +16329,17 @@ mixin LocalizationsProvider on LocaleCodeAware { 'activity_49': 'Ο χρήστης :user έκλεισε το αίτημα υποστήριξης :ticket', 'activity_50': 'Ο χρήστης :user συνένωσε το αίτημα υποστήριξης :ticket', 'activity_51': - 'Ο χρήστης :user διαίρεσε στα δύο το αίτημα υποστήριξης :ticket', + 'Ο χρήστης :user διαίρεσε στα δύο το αίτημα υποστήριξης :ticket', 'activity_52': - 'Η επαφή :contact δημιούργησε το αίτημα υποστήριξης :ticket', + 'Η επαφή :contact δημιούργησε το αίτημα υποστήριξης :ticket', 'activity_53': - 'Η επαφή :contact επαναδημιούργησε το αίτημα υποστήριξης :ticket', + 'Η επαφή :contact επαναδημιούργησε το αίτημα υποστήριξης :ticket', 'activity_54': - 'Ο χρήστης :user επαναδημιούργησε το αίτημα υποστήριξης :ticket', + 'Ο χρήστης :user επαναδημιούργησε το αίτημα υποστήριξης :ticket', 'activity_55': 'Η επαφή :contact απάντησε στο αίτημα υποστήριξης :ticket', 'activity_56': 'Ο χρήστης :user είδε το αίτημα υποστήριξης :ticket', 'activity_57': - 'Το σύστημα απέτυχε να στείλει με email το τιμολόγιο :invoice', + 'Το σύστημα απέτυχε να στείλει με email το τιμολόγιο :invoice', 'one_time_password': 'Κωδικός Πρόσβασης μίας Φοράς', 'emailed_quote': 'Επιτυχής αποστολή προσφοράς', 'emailed_credit': 'Successfully emailed credit', @@ -16347,11 +16356,11 @@ mixin LocalizationsProvider on LocaleCodeAware { 'email_style_custom': 'Προσαρμοσμένο Στυλ Email', 'custom_message_dashboard': 'Προσαρμοσμένο Μήνυμα Πίνακα Διαχείρισης', 'custom_message_unpaid_invoice': - 'Προσαρμοσμένο Μήνυμα Ανεξόφλητου Τιμολογίου', + 'Προσαρμοσμένο Μήνυμα Ανεξόφλητου Τιμολογίου', 'custom_message_paid_invoice': - 'Προσαρμοσμένο Μήνυμα Εξοφλημένου Τιμολογίου', + 'Προσαρμοσμένο Μήνυμα Εξοφλημένου Τιμολογίου', 'custom_message_unapproved_quote': - 'Προσαρμοσμένο Μήνυμα Μη Εγκεκριμένη Προσφοράς', + 'Προσαρμοσμένο Μήνυμα Μη Εγκεκριμένη Προσφοράς', 'lock_sent_invoices': 'Κλείδωμα Απεσταλένων Τιμολογίων', 'translations': 'Μεταφράσεις', 'task_number_pattern': 'Μοτίβο Αρίθμησης Εργασίας', @@ -16375,7 +16384,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'reset_counter_date': 'Μηδενισμός Μετρητή Ημερομηνίας', 'counter_padding': 'Αντισταθμιστής', 'shared_invoice_quote_counter': - 'Κοινόχρηστο παράθυρο παραγγελίας τιμολογίου', + 'Κοινόχρηστο παράθυρο παραγγελίας τιμολογίου', 'default_tax_name_1': 'Προεπιλεγμένη ονομασία φορολογικού συντελεστή 1', 'default_tax_rate_1': 'Προεπιλεγμένος φορολογικός συντελεστής 1', 'default_tax_name_2': 'Προεπιλεγμένη ονομασία φορολογικού συντελεστή 2', @@ -16437,7 +16446,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'purge_data': 'Purge Data', 'purge_successful': 'Successfully purged company data', 'purge_data_message': - 'Warning: This will permanently erase your data, there is no undo.', + 'Warning: This will permanently erase your data, there is no undo.', 'invoice_balance': 'Invoice Balance', 'age_group_0': '0 - 30 Giorni', 'age_group_30': '30 - 60 Giorni', @@ -16472,10 +16481,10 @@ mixin LocalizationsProvider on LocaleCodeAware { 'apply_license': 'Apply License', 'cancel_account': 'Elimina l\'account', 'cancel_account_message': - 'Attenzione: Questo eliminerà permanentemente il tuo account, non si potrà più tornare indietro.', + 'Attenzione: Questo eliminerà permanentemente il tuo account, non si potrà più tornare indietro.', 'delete_company': 'Delete Company', 'delete_company_message': - 'Warning: This will permanently delete your company, there is no undo.', + 'Warning: This will permanently delete your company, there is no undo.', 'enable_modules': 'Enable Modules', 'converted_quote': 'Successfully converted quote', 'credit_design': 'Credit Design', @@ -16627,12 +16636,12 @@ mixin LocalizationsProvider on LocaleCodeAware { 'applied': 'Applied', 'include_recent_errors': 'Include recent errors from the logs', 'your_message_has_been_received': - 'We have received your message and will try to respond promptly.', + 'We have received your message and will try to respond promptly.', 'message': 'Messaggio', 'from': 'Da', 'show_product_details': 'Show Product Details', 'show_product_details_help': - 'Include the description and cost in the product dropdown', + 'Include the description and cost in the product dropdown', 'pdf_min_requirements': 'The PDF renderer requires :version', 'adjust_fee_percent': 'Adjust Fee Percent', 'adjust_fee_percent_help': 'Adjust percent to account for fee', @@ -16649,7 +16658,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'domain_url': 'Domain URL', 'password_is_too_short': 'La parola chiave è troppo corta', 'password_is_too_easy': - 'Password must contain an upper case character and a number', + 'Password must contain an upper case character and a number', 'client_portal_tasks': 'Client Portal Tasks', 'client_portal_dashboard': 'Client Portal Dashboard', 'please_enter_a_value': 'Please enter a value', @@ -16676,16 +16685,16 @@ mixin LocalizationsProvider on LocaleCodeAware { 'third_custom': 'Third Custom', 'show_cost': 'Show Cost', 'show_cost_help': - 'Display a product cost field to track the markup/profit', + 'Display a product cost field to track the markup/profit', 'show_product_quantity': 'Show Product Quantity', 'show_product_quantity_help': - 'Display a product quantity field, otherwise default to one', + 'Display a product quantity field, otherwise default to one', 'show_invoice_quantity': 'Show Invoice Quantity', 'show_invoice_quantity_help': - 'Display a line item quantity field, otherwise default to one', + 'Display a line item quantity field, otherwise default to one', 'default_quantity': 'Default Quantity', 'default_quantity_help': - 'Automatically set the line item quantity to one', + 'Automatically set the line item quantity to one', 'one_tax_rate': 'One Tax Rate', 'two_tax_rates': 'Two Tax Rates', 'three_tax_rates': 'Three Tax Rates', @@ -16730,7 +16739,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'filtered_by_user': 'Filtered by User', 'administrator': 'Administrator', 'administrator_help': - 'Allow user to manage users, change settings and modify all records', + 'Allow user to manage users, change settings and modify all records', 'user_management': 'Gestione utente', 'users': 'Utenti', 'new_user': 'New User', @@ -16745,7 +16754,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'invoice_options': 'Opzioni Fattura', 'hide_paid_to_date': 'Nascondi la data di pagamento', 'hide_paid_to_date_help': - 'Visualizza l\'area \"Pagato alla data\" sulle fatture solo dopo aver ricevuto un pagamento.', + 'Visualizza l\'area \"Pagato alla data\" sulle fatture solo dopo aver ricevuto un pagamento.', 'invoice_embed_documents': 'Embed Documents', 'invoice_embed_documents_help': 'Includi immagini allegate alla fattura.', 'all_pages_header': 'Mostra l\'Intestazione nel', @@ -16768,16 +16777,16 @@ mixin LocalizationsProvider on LocaleCodeAware { 'quote_footer': 'Piè di Pagina Preventivi', 'auto_email_invoice': 'Auto Email', 'auto_email_invoice_help': - 'Invia automaticamente per email le fatture ricorrenti quando vengono create.', + 'Invia automaticamente per email le fatture ricorrenti quando vengono create.', 'auto_archive_invoice': 'Auto Archive', 'auto_archive_invoice_help': - 'Automatically archive invoices when they are paid.', + 'Automatically archive invoices when they are paid.', 'auto_archive_quote': 'Auto Archive', 'auto_archive_quote_help': - 'Automatically archive quotes when they are converted.', + 'Automatically archive quotes when they are converted.', 'auto_convert_quote': 'Conversione automatica', 'auto_convert_quote_help': - 'Converti automaticamente un preventivo in una fattura se approvato da un cliente.', + 'Converti automaticamente un preventivo in una fattura se approvato da un cliente.', 'workflow_settings': 'Workflow Settings', 'freq_daily': 'Giornaliero', 'freq_weekly': 'Settimanale', @@ -16823,27 +16832,27 @@ mixin LocalizationsProvider on LocaleCodeAware { 'custom_javascript': 'Custom JavaScript', 'signature_on_pdf': 'Show on PDF', 'signature_on_pdf_help': - 'Show the client signature on the invoice/quote PDF.', + 'Show the client signature on the invoice/quote PDF.', 'show_accept_invoice_terms': 'Invoice Terms Checkbox', 'show_accept_invoice_terms_help': - 'Setta come obbligatoria l\'accettazione dei termini della fattura.', + 'Setta come obbligatoria l\'accettazione dei termini della fattura.', 'show_accept_quote_terms': 'Quote Terms Checkbox', 'show_accept_quote_terms_help': - 'Setta come obbligatoria l\'accettazione dei termini del preventivo.', + 'Setta come obbligatoria l\'accettazione dei termini del preventivo.', 'require_invoice_signature': 'Firma Fattura', 'require_invoice_signature_help': - 'Richiedi al cliente di firmare la fattura.', + 'Richiedi al cliente di firmare la fattura.', 'require_quote_signature': 'Firma Bozza', 'enable_portal_password': 'Fatture Protette da Password', 'enable_portal_password_help': - 'Allows you to set a password for each contact. If a password is set, the contact will be required to enter a password before viewing invoices.', + 'Allows you to set a password for each contact. If a password is set, the contact will be required to enter a password before viewing invoices.', 'authorization': 'Autorizzazione', 'subdomain': 'Sottodominio', 'domain': 'Dominio', 'portal_mode': 'Portal Mode', 'email_signature': 'Distinti saluti,', 'enable_email_markup_help': - 'Make it easier for your clients to pay you by adding schema.org markup to your emails.', + 'Make it easier for your clients to pay you by adding schema.org markup to your emails.', 'plain': 'Plain', 'light': 'Light', 'dark': 'Dark', @@ -16872,12 +16881,12 @@ mixin LocalizationsProvider on LocaleCodeAware { 'accepted_card_logos': 'Accepted Card Logos', 'credentials': 'Credentials', 'require_billing_address_help': - 'Require client to provide their billing address', + 'Require client to provide their billing address', 'require_shipping_address_help': - 'Require client to provide their shipping address', + 'Require client to provide their shipping address', 'update_address': 'Aggiorna indirizzo', 'update_address_help': - 'Aggiorna l\'indirizzo del cliente con i dettagli forniti', + 'Aggiorna l\'indirizzo del cliente con i dettagli forniti', 'rate': 'Aliquota', 'tax_rate': 'Tax Rate', 'new_tax_rate': 'New Tax Rate', @@ -16889,13 +16898,13 @@ mixin LocalizationsProvider on LocaleCodeAware { 'restored_tax_rate': 'Successfully restored tax rate', 'fill_products': 'Riempimento automatico prodotti', 'fill_products_help': - 'Selezionare un prodotto farà automaticamente inserire la descrizione ed il costo', + 'Selezionare un prodotto farà automaticamente inserire la descrizione ed il costo', 'update_products': 'Aggiorna automaticamente i prodotti', 'update_products_help': - 'Aggiornare una fatura farà automaticamente aggiornare i prodotti', + 'Aggiornare una fatura farà automaticamente aggiornare i prodotti', 'convert_products': 'Convert Products', 'convert_products_help': - 'Automatically convert product prices to the client\'s currency', + 'Automatically convert product prices to the client\'s currency', 'fees': 'Commissioni', 'limits': 'Limiti', 'provider': 'Provider', @@ -16995,7 +17004,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'please_enter_a_first_name': 'Please enter a first name', 'please_enter_a_last_name': 'Please enter a last name', 'please_agree_to_terms_and_privacy': - 'Please agree to the terms of service and privacy policy to create an account.', + 'Please agree to the terms of service and privacy policy to create an account.', 'i_agree_to_the': 'I agree to the', 'terms_of_service_link': 'terms of service', 'privacy_policy_link': 'privacy policy', @@ -17057,7 +17066,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'running': 'In corso', 'resume': 'Riprendi', 'task_errors': - 'Si prega di correggere eventuali tempi di sovrapposizione', + 'Si prega di correggere eventuali tempi di sovrapposizione', 'start': 'Inizia', 'stop': 'Ferma', 'started_task': 'Attività iniziata con successo', @@ -17095,7 +17104,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'average': 'Average', 'unapproved': 'non approvato', 'authenticate_to_change_setting': - 'Please authenticate to change this setting', + 'Please authenticate to change this setting', 'locked': 'Locked', 'authenticate': 'Authenticate', 'please_authenticate': 'Please authenticate', @@ -17295,7 +17304,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'marked_invoices_as_paid': 'Successfully marked invoices as paid', 'done': 'Fatto', 'please_enter_a_client_or_contact_name': - 'Please enter a client or contact name', + 'Please enter a client or contact name', 'dark_mode': 'Modalità scura', 'restart_app_to_apply_change': 'Restart the app to apply the change', 'refresh_data': 'Refresh Data', @@ -17373,12 +17382,12 @@ mixin LocalizationsProvider on LocaleCodeAware { 'activity_4': ':user ha creato la fattura :invoice', 'activity_5': ':user ha aggiornato la fattura :invoice', 'activity_6': - ':user ha inviato per email la fattura :invoice per:client a :contact', + ':user ha inviato per email la fattura :invoice per:client a :contact', 'activity_7': ':contact ha visualizzato la fattura :invoice per :client', 'activity_8': ':user ha archiviato la fattura :invoice', 'activity_9': ':user ha cancellato la fattura :invoice', 'activity_10': - ':contact ha registrato il pagamento :payment di :payment_amount sulla fattura :invoice per :client', + ':contact ha registrato il pagamento :payment di :payment_amount sulla fattura :invoice per :client', 'activity_11': ':user ha aggiornato il pagamento :payment', 'activity_12': ':user ha archiviato il pagamento :payment', 'activity_13': ':user ha cancellato il pagamento :payment', @@ -17389,7 +17398,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'activity_18': ':user created quote :quote', 'activity_19': ':user updated quote :quote', 'activity_20': - ':user ha inviato per email il preventivo :quote per :client a :contact', + ':user ha inviato per email il preventivo :quote per :client a :contact', 'activity_21': ':contact ha visto il preventivo :quote', 'activity_22': ':user archived quote :quote', 'activity_23': ':user deleted quote :quote', @@ -17408,9 +17417,9 @@ mixin LocalizationsProvider on LocaleCodeAware { 'activity_36': 'L\'utente :user ha eliminato la spesa :expense', 'activity_37': 'L\'utente :user ha ripristinato la spesa :expense', 'activity_39': - ':user ha annullato un pagamento :payment da :payment_amount', + ':user ha annullato un pagamento :payment da :payment_amount', 'activity_40': - ':user ha rimborsato :adjustment di un pagamento :payment da :payment_amount', + ':user ha rimborsato :adjustment di un pagamento :payment da :payment_amount', 'activity_41': 'pagamento di :payment_amount (:payment) fallito', 'activity_42': 'L\'utente :user ha creato l\'attività :task', 'activity_43': 'L\'utente :user ha aggiornato l\'attività :task', @@ -17530,7 +17539,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'purge_data': 'Purge Data', 'purge_successful': 'Successfully purged company data', 'purge_data_message': - 'Warning: This will permanently erase your data, there is no undo.', + 'Warning: This will permanently erase your data, there is no undo.', 'invoice_balance': 'Invoice Balance', 'age_group_0': '0 - 30 Days', 'age_group_30': '30 - 60 Days', @@ -17565,10 +17574,10 @@ mixin LocalizationsProvider on LocaleCodeAware { 'apply_license': 'Apply License', 'cancel_account': 'アカウントのキャンセル', 'cancel_account_message': - 'Warning: This will permanently delete your account, there is no undo.', + 'Warning: This will permanently delete your account, there is no undo.', 'delete_company': 'Delete Company', 'delete_company_message': - 'Warning: This will permanently delete your company, there is no undo.', + 'Warning: This will permanently delete your company, there is no undo.', 'enable_modules': 'Enable Modules', 'converted_quote': 'Successfully converted quote', 'credit_design': 'Credit Design', @@ -17720,12 +17729,12 @@ mixin LocalizationsProvider on LocaleCodeAware { 'applied': 'Applied', 'include_recent_errors': 'Include recent errors from the logs', 'your_message_has_been_received': - 'We have received your message and will try to respond promptly.', + 'We have received your message and will try to respond promptly.', 'message': 'メッセージ', 'from': 'From', 'show_product_details': 'Show Product Details', 'show_product_details_help': - 'Include the description and cost in the product dropdown', + 'Include the description and cost in the product dropdown', 'pdf_min_requirements': 'The PDF renderer requires :version', 'adjust_fee_percent': 'Adjust Fee Percent', 'adjust_fee_percent_help': 'Adjust percent to account for fee', @@ -17742,7 +17751,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'domain_url': 'Domain URL', 'password_is_too_short': 'Password is too short', 'password_is_too_easy': - 'Password must contain an upper case character and a number', + 'Password must contain an upper case character and a number', 'client_portal_tasks': 'Client Portal Tasks', 'client_portal_dashboard': 'Client Portal Dashboard', 'please_enter_a_value': 'Please enter a value', @@ -17769,16 +17778,16 @@ mixin LocalizationsProvider on LocaleCodeAware { 'third_custom': 'Third Custom', 'show_cost': 'Show Cost', 'show_cost_help': - 'Display a product cost field to track the markup/profit', + 'Display a product cost field to track the markup/profit', 'show_product_quantity': 'Show Product Quantity', 'show_product_quantity_help': - 'Display a product quantity field, otherwise default to one', + 'Display a product quantity field, otherwise default to one', 'show_invoice_quantity': 'Show Invoice Quantity', 'show_invoice_quantity_help': - 'Display a line item quantity field, otherwise default to one', + 'Display a line item quantity field, otherwise default to one', 'default_quantity': 'Default Quantity', 'default_quantity_help': - 'Automatically set the line item quantity to one', + 'Automatically set the line item quantity to one', 'one_tax_rate': 'One Tax Rate', 'two_tax_rates': 'Two Tax Rates', 'three_tax_rates': 'Three Tax Rates', @@ -17823,7 +17832,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'filtered_by_user': 'Filtered by User', 'administrator': 'Administrator', 'administrator_help': - 'Allow user to manage users, change settings and modify all records', + 'Allow user to manage users, change settings and modify all records', 'user_management': 'ユーザ管理', 'users': 'ユーザー', 'new_user': '新しいユーザ', @@ -17838,7 +17847,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'invoice_options': '請求書オプション', 'hide_paid_to_date': 'Hide Paid to Date', 'hide_paid_to_date_help': - 'Only display the \"Paid to Date\" area on your invoices once a payment has been received.', + 'Only display the \"Paid to Date\" area on your invoices once a payment has been received.', 'invoice_embed_documents': 'Embed Documents', 'invoice_embed_documents_help': 'Include attached images in the invoice.', 'all_pages_header': 'Show header on', @@ -17861,16 +17870,16 @@ mixin LocalizationsProvider on LocaleCodeAware { 'quote_footer': '見積書フッタ', 'auto_email_invoice': 'Auto Email', 'auto_email_invoice_help': - 'Automatically email recurring invoices when they are created.', + 'Automatically email recurring invoices when they are created.', 'auto_archive_invoice': 'Auto Archive', 'auto_archive_invoice_help': - 'Automatically archive invoices when they are paid.', + 'Automatically archive invoices when they are paid.', 'auto_archive_quote': 'Auto Archive', 'auto_archive_quote_help': - 'Automatically archive quotes when they are converted.', + 'Automatically archive quotes when they are converted.', 'auto_convert_quote': 'Auto Convert', 'auto_convert_quote_help': - 'Automatically convert a quote to an invoice when approved by a client.', + 'Automatically convert a quote to an invoice when approved by a client.', 'workflow_settings': 'Workflow Settings', 'freq_daily': 'Daily', 'freq_weekly': 'Weekly', @@ -17916,27 +17925,27 @@ mixin LocalizationsProvider on LocaleCodeAware { 'custom_javascript': 'Custom JavaScript', 'signature_on_pdf': 'Show on PDF', 'signature_on_pdf_help': - 'Show the client signature on the invoice/quote PDF.', + 'Show the client signature on the invoice/quote PDF.', 'show_accept_invoice_terms': 'Invoice Terms Checkbox', 'show_accept_invoice_terms_help': - 'Require client to confirm that they accept the invoice terms.', + 'Require client to confirm that they accept the invoice terms.', 'show_accept_quote_terms': 'Quote Terms Checkbox', 'show_accept_quote_terms_help': - 'Require client to confirm that they accept the quote terms.', + 'Require client to confirm that they accept the quote terms.', 'require_invoice_signature': 'Invoice Signature', 'require_invoice_signature_help': - 'Require client to provide their signature.', + 'Require client to provide their signature.', 'require_quote_signature': 'Quote Signature', 'enable_portal_password': 'Password Protect Invoices', 'enable_portal_password_help': - 'Allows you to set a password for each contact. If a password is set, the contact will be required to enter a password before viewing invoices.', + 'Allows you to set a password for each contact. If a password is set, the contact will be required to enter a password before viewing invoices.', 'authorization': 'Authorization', 'subdomain': 'サブドメイン', 'domain': 'Domain', 'portal_mode': 'Portal Mode', 'email_signature': 'どうぞよろしくお願いいたします。', 'enable_email_markup_help': - 'Make it easier for your clients to pay you by adding schema.org markup to your emails.', + 'Make it easier for your clients to pay you by adding schema.org markup to your emails.', 'plain': 'プレーン', 'light': 'ライト', 'dark': 'ダーク', @@ -17965,9 +17974,9 @@ mixin LocalizationsProvider on LocaleCodeAware { 'accepted_card_logos': 'Accepted Card Logos', 'credentials': 'Credentials', 'require_billing_address_help': - 'Require client to provide their billing address', + 'Require client to provide their billing address', 'require_shipping_address_help': - 'Require client to provide their shipping address', + 'Require client to provide their shipping address', 'update_address': '住所を更新', 'update_address_help': 'Update client\'s address with provided details', 'rate': '率', @@ -17981,13 +17990,13 @@ mixin LocalizationsProvider on LocaleCodeAware { 'restored_tax_rate': 'Successfully restored tax rate', 'fill_products': 'Auto-fill products', 'fill_products_help': - 'Selecting a product will automatically fill in the description and cost', + 'Selecting a product will automatically fill in the description and cost', 'update_products': 'Auto-update products', 'update_products_help': - 'Updating an invoice will automatically update the product library', + 'Updating an invoice will automatically update the product library', 'convert_products': 'Convert Products', 'convert_products_help': - 'Automatically convert product prices to the client\'s currency', + 'Automatically convert product prices to the client\'s currency', 'fees': 'Fees', 'limits': 'Limits', 'provider': 'Provider', @@ -18087,7 +18096,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'please_enter_a_first_name': 'Please enter a first name', 'please_enter_a_last_name': 'Please enter a last name', 'please_agree_to_terms_and_privacy': - 'Please agree to the terms of service and privacy policy to create an account.', + 'Please agree to the terms of service and privacy policy to create an account.', 'i_agree_to_the': 'I agree to the', 'terms_of_service_link': 'terms of service', 'privacy_policy_link': 'privacy policy', @@ -18186,7 +18195,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'average': 'Average', 'unapproved': 'Unapproved', 'authenticate_to_change_setting': - 'Please authenticate to change this setting', + 'Please authenticate to change this setting', 'locked': 'Locked', 'authenticate': 'Authenticate', 'please_authenticate': 'Please authenticate', @@ -18386,7 +18395,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'marked_invoices_as_paid': 'Successfully marked invoices as paid', 'done': '完了', 'please_enter_a_client_or_contact_name': - 'Please enter a client or contact name', + 'Please enter a client or contact name', 'dark_mode': 'ダークモード', 'restart_app_to_apply_change': 'Restart the app to apply the change', 'refresh_data': 'Refresh Data', @@ -18468,7 +18477,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'activity_8': ':user は 請求書 :invoice をアーカイブしました。', 'activity_9': ':user は 請求書 :invoice をアーカイブしました。', 'activity_10': - ':contact entered payment :payment for :payment_amount on invoice :invoice for :client', + ':contact entered payment :payment for :payment_amount on invoice :invoice for :client', 'activity_11': ':user updated payment :payment', 'activity_12': ':user archived payment :payment', 'activity_13': ':user deleted payment :payment', @@ -18498,7 +18507,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'activity_37': ':user restored expense :expense', 'activity_39': ':user cancelled a :payment_amount payment :payment', 'activity_40': - ':user refunded :adjustment of a :payment_amount payment :payment', + ':user refunded :adjustment of a :payment_amount payment :payment', 'activity_41': ':payment_amount payment (:payment) failed', 'activity_42': ':user created task :task', 'activity_43': ':user updated task :task', @@ -18618,7 +18627,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'purge_data': 'Purge Data', 'purge_successful': 'Successfully purged company data', 'purge_data_message': - 'Warning: This will permanently erase your data, there is no undo.', + 'Warning: This will permanently erase your data, there is no undo.', 'invoice_balance': 'Invoice Balance', 'age_group_0': '0 - 30 Days', 'age_group_30': '30 - 60 Days', @@ -18653,10 +18662,10 @@ mixin LocalizationsProvider on LocaleCodeAware { 'apply_license': 'Apply License', 'cancel_account': 'Cancel Account', 'cancel_account_message': - 'Warning: This will permanently delete your account, there is no undo.', + 'Warning: This will permanently delete your account, there is no undo.', 'delete_company': 'Delete Company', 'delete_company_message': - 'Warning: This will permanently delete your company, there is no undo.', + 'Warning: This will permanently delete your company, there is no undo.', 'enable_modules': 'Enable Modules', 'converted_quote': 'Successfully converted quote', 'credit_design': 'Credit Design', @@ -18808,12 +18817,12 @@ mixin LocalizationsProvider on LocaleCodeAware { 'applied': 'Applied', 'include_recent_errors': 'Include recent errors from the logs', 'your_message_has_been_received': - 'We have received your message and will try to respond promptly.', + 'We have received your message and will try to respond promptly.', 'message': 'Žinutė', 'from': 'Pardavėjas', 'show_product_details': 'Show Product Details', 'show_product_details_help': - 'Include the description and cost in the product dropdown', + 'Include the description and cost in the product dropdown', 'pdf_min_requirements': 'The PDF renderer requires :version', 'adjust_fee_percent': 'Adjust Fee Percent', 'adjust_fee_percent_help': 'Adjust percent to account for fee', @@ -18830,7 +18839,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'domain_url': 'Domain URL', 'password_is_too_short': 'Password is too short', 'password_is_too_easy': - 'Password must contain an upper case character and a number', + 'Password must contain an upper case character and a number', 'client_portal_tasks': 'Client Portal Tasks', 'client_portal_dashboard': 'Client Portal Dashboard', 'please_enter_a_value': 'Please enter a value', @@ -18857,16 +18866,16 @@ mixin LocalizationsProvider on LocaleCodeAware { 'third_custom': 'Third Custom', 'show_cost': 'Show Cost', 'show_cost_help': - 'Display a product cost field to track the markup/profit', + 'Display a product cost field to track the markup/profit', 'show_product_quantity': 'Show Product Quantity', 'show_product_quantity_help': - 'Display a product quantity field, otherwise default to one', + 'Display a product quantity field, otherwise default to one', 'show_invoice_quantity': 'Show Invoice Quantity', 'show_invoice_quantity_help': - 'Display a line item quantity field, otherwise default to one', + 'Display a line item quantity field, otherwise default to one', 'default_quantity': 'Default Quantity', 'default_quantity_help': - 'Automatically set the line item quantity to one', + 'Automatically set the line item quantity to one', 'one_tax_rate': 'One Tax Rate', 'two_tax_rates': 'Two Tax Rates', 'three_tax_rates': 'Three Tax Rates', @@ -18911,7 +18920,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'filtered_by_user': 'Filtered by User', 'administrator': 'Administratorius', 'administrator_help': - 'Allow user to manage users, change settings and modify all records', + 'Allow user to manage users, change settings and modify all records', 'user_management': 'User Management', 'users': 'Vartotojai', 'new_user': 'New User', @@ -18926,7 +18935,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'invoice_options': 'Invoice Options', 'hide_paid_to_date': 'Hide paid to date', 'hide_paid_to_date_help': - 'Only display the \"Paid to Date\" area on your invoices once a payment has been received.', + 'Only display the \"Paid to Date\" area on your invoices once a payment has been received.', 'invoice_embed_documents': 'Įkelti dokumentai', 'invoice_embed_documents_help': 'Include attached images in the invoice.', 'all_pages_header': 'Show header on', @@ -18949,16 +18958,16 @@ mixin LocalizationsProvider on LocaleCodeAware { 'quote_footer': 'Quote Footer', 'auto_email_invoice': 'Auto Email', 'auto_email_invoice_help': - 'Automatically email recurring invoices when they are created.', + 'Automatically email recurring invoices when they are created.', 'auto_archive_invoice': 'Auto Archive', 'auto_archive_invoice_help': - 'Automatically archive invoices when they are paid.', + 'Automatically archive invoices when they are paid.', 'auto_archive_quote': 'Auto Archive', 'auto_archive_quote_help': - 'Automatically archive quotes when they are converted.', + 'Automatically archive quotes when they are converted.', 'auto_convert_quote': 'Automatiškai Konvertuoti', 'auto_convert_quote_help': - 'Automatically convert a quote to an invoice when approved by a client.', + 'Automatically convert a quote to an invoice when approved by a client.', 'workflow_settings': 'Workflow Settings', 'freq_daily': 'Kasdien', 'freq_weekly': 'Kas savaitę', @@ -19004,27 +19013,27 @@ mixin LocalizationsProvider on LocaleCodeAware { 'custom_javascript': 'Custom JavaScript', 'signature_on_pdf': 'Show on PDF', 'signature_on_pdf_help': - 'Show the client signature on the invoice/quote PDF.', + 'Show the client signature on the invoice/quote PDF.', 'show_accept_invoice_terms': 'Invoice Terms Checkbox', 'show_accept_invoice_terms_help': - 'Require client to confirm that they accept the invoice terms.', + 'Require client to confirm that they accept the invoice terms.', 'show_accept_quote_terms': 'Quote Terms Checkbox', 'show_accept_quote_terms_help': - 'Require client to confirm that they accept the quote terms.', + 'Require client to confirm that they accept the quote terms.', 'require_invoice_signature': 'Invoice Signature', 'require_invoice_signature_help': - 'Require client to provide their signature.', + 'Require client to provide their signature.', 'require_quote_signature': 'Quote Signature', 'enable_portal_password': 'Password Protect Invoices', 'enable_portal_password_help': - 'Allows you to set a password for each contact. If a password is set, the contact will be required to enter a password before viewing invoices.', + 'Allows you to set a password for each contact. If a password is set, the contact will be required to enter a password before viewing invoices.', 'authorization': 'Authorization', 'subdomain': 'Subdomain', 'domain': 'Domain', 'portal_mode': 'Portal Mode', 'email_signature': 'Linkiu geros dienos,', 'enable_email_markup_help': - 'Make it easier for your clients to pay you by adding schema.org markup to your emails.', + 'Make it easier for your clients to pay you by adding schema.org markup to your emails.', 'plain': 'Plain', 'light': 'Light', 'dark': 'Dark', @@ -19053,9 +19062,9 @@ mixin LocalizationsProvider on LocaleCodeAware { 'accepted_card_logos': 'Accepted Card Logos', 'credentials': 'Credentials', 'require_billing_address_help': - 'Require client to provide their billing address', + 'Require client to provide their billing address', 'require_shipping_address_help': - 'Require client to provide their shipping address', + 'Require client to provide their shipping address', 'update_address': 'Update Address', 'update_address_help': 'Update client\'s address with provided details', 'rate': 'Įkainis', @@ -19069,13 +19078,13 @@ mixin LocalizationsProvider on LocaleCodeAware { 'restored_tax_rate': 'Successfully restored tax rate', 'fill_products': 'Auto-fill products', 'fill_products_help': - 'Selecting a product will automatically fill in the description and cost', + 'Selecting a product will automatically fill in the description and cost', 'update_products': 'Auto-update products', 'update_products_help': - 'Updating an invoice will automatically update the product library', + 'Updating an invoice will automatically update the product library', 'convert_products': 'Convert Products', 'convert_products_help': - 'Automatically convert product prices to the client\'s currency', + 'Automatically convert product prices to the client\'s currency', 'fees': 'Fees', 'limits': 'Limits', 'provider': 'Provider', @@ -19175,7 +19184,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'please_enter_a_first_name': 'Please enter a first name', 'please_enter_a_last_name': 'Please enter a last name', 'please_agree_to_terms_and_privacy': - 'Please agree to the terms of service and privacy policy to create an account.', + 'Please agree to the terms of service and privacy policy to create an account.', 'i_agree_to_the': 'I agree to the', 'terms_of_service_link': 'terms of service', 'privacy_policy_link': 'privacy policy', @@ -19274,7 +19283,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'average': 'Average', 'unapproved': 'Unapproved', 'authenticate_to_change_setting': - 'Please authenticate to change this setting', + 'Please authenticate to change this setting', 'locked': 'Locked', 'authenticate': 'Authenticate', 'please_authenticate': 'Please authenticate', @@ -19474,7 +19483,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'marked_invoices_as_paid': 'Successfully marked invoices as paid', 'done': 'Baigta', 'please_enter_a_client_or_contact_name': - 'Please enter a client or contact name', + 'Please enter a client or contact name', 'dark_mode': 'Dark Mode', 'restart_app_to_apply_change': 'Restart the app to apply the change', 'refresh_data': 'Refresh Data', @@ -19556,7 +19565,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'activity_8': ':user archived invoice :invoice', 'activity_9': ':user deleted invoice :invoice', 'activity_10': - ':contact entered payment :payment for :payment_amount on invoice :invoice for :client', + ':contact entered payment :payment for :payment_amount on invoice :invoice for :client', 'activity_11': ':user atnaujino mokėjimą :payment', 'activity_12': ':user archived payment :payment', 'activity_13': ':user deleted payment :payment', @@ -19586,7 +19595,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'activity_37': ':user restored expense :expense', 'activity_39': ':user cancelled a :payment_amount payment :payment', 'activity_40': - ':user refunded :adjustment of a :payment_amount payment :payment', + ':user refunded :adjustment of a :payment_amount payment :payment', 'activity_41': ':payment_amount mokėjimas (:payment) nepavyko', 'activity_42': ':user created task :task', 'activity_43': ':user updated task :task', @@ -19706,7 +19715,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'purge_data': 'Прочисти податоци', 'purge_successful': 'Успешно прочистени податоци за компаанија', 'purge_data_message': - 'Предупредување: Ова трајно ќе ги избрише вашите податоци, нема враќање назад.', + 'Предупредување: Ова трајно ќе ги избрише вашите податоци, нема враќање назад.', 'invoice_balance': 'Invoice Balance', 'age_group_0': '0 - 30 дена', 'age_group_30': '30 - 60 дена', @@ -19741,10 +19750,10 @@ mixin LocalizationsProvider on LocaleCodeAware { 'apply_license': 'Примени лиценца', 'cancel_account': 'Избриши сметка', 'cancel_account_message': - 'Предупредување: Ова трајно ќе ја избрише вашата сметка, нема враќање.', + 'Предупредување: Ова трајно ќе ја избрише вашата сметка, нема враќање.', 'delete_company': 'Избриши компанија', 'delete_company_message': - 'Предупредување: Ова трајно ќе ја избрише вашата компанија, нема враќање назад.', + 'Предупредување: Ова трајно ќе ја избрише вашата компанија, нема враќање назад.', 'enable_modules': 'Enable Modules', 'converted_quote': 'Successfully converted quote', 'credit_design': 'Credit Design', @@ -19896,12 +19905,12 @@ mixin LocalizationsProvider on LocaleCodeAware { 'applied': 'Applied', 'include_recent_errors': 'Include recent errors from the logs', 'your_message_has_been_received': - 'We have received your message and will try to respond promptly.', + 'We have received your message and will try to respond promptly.', 'message': 'Порака', 'from': 'Од', 'show_product_details': 'Show Product Details', 'show_product_details_help': - 'Include the description and cost in the product dropdown', + 'Include the description and cost in the product dropdown', 'pdf_min_requirements': 'The PDF renderer requires :version', 'adjust_fee_percent': 'Adjust Fee Percent', 'adjust_fee_percent_help': 'Adjust percent to account for fee', @@ -19918,7 +19927,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'domain_url': 'Domain URL', 'password_is_too_short': 'Password is too short', 'password_is_too_easy': - 'Password must contain an upper case character and a number', + 'Password must contain an upper case character and a number', 'client_portal_tasks': 'Client Portal Tasks', 'client_portal_dashboard': 'Client Portal Dashboard', 'please_enter_a_value': 'Please enter a value', @@ -19945,16 +19954,16 @@ mixin LocalizationsProvider on LocaleCodeAware { 'third_custom': 'Third Custom', 'show_cost': 'Show Cost', 'show_cost_help': - 'Display a product cost field to track the markup/profit', + 'Display a product cost field to track the markup/profit', 'show_product_quantity': 'Show Product Quantity', 'show_product_quantity_help': - 'Display a product quantity field, otherwise default to one', + 'Display a product quantity field, otherwise default to one', 'show_invoice_quantity': 'Show Invoice Quantity', 'show_invoice_quantity_help': - 'Display a line item quantity field, otherwise default to one', + 'Display a line item quantity field, otherwise default to one', 'default_quantity': 'Default Quantity', 'default_quantity_help': - 'Automatically set the line item quantity to one', + 'Automatically set the line item quantity to one', 'one_tax_rate': 'One Tax Rate', 'two_tax_rates': 'Two Tax Rates', 'three_tax_rates': 'Three Tax Rates', @@ -19999,7 +20008,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'filtered_by_user': 'Filtered by User', 'administrator': 'Администратор', 'administrator_help': - 'Дозвола за корисникот да менаџира со корисниците, да ги менува поставките и да ги модифицира сите записи', + 'Дозвола за корисникот да менаџира со корисниците, да ги менува поставките и да ги модифицира сите записи', 'user_management': 'Управување со корисник', 'users': 'Корисници', 'new_user': 'Нов корисник', @@ -20014,10 +20023,10 @@ mixin LocalizationsProvider on LocaleCodeAware { 'invoice_options': 'Поставки за фактура', 'hide_paid_to_date': 'Сокриј Платено до датум', 'hide_paid_to_date_help': - 'Прикажи \"Платено до датум\" на фактурите откако ќе биде примено плаќањето.', + 'Прикажи \"Платено до датум\" на фактурите откако ќе биде примено плаќањето.', 'invoice_embed_documents': 'Вметни документи', 'invoice_embed_documents_help': - 'Вклучи ги прикачените слики во фактурата.', + 'Вклучи ги прикачените слики во фактурата.', 'all_pages_header': 'Прикажи заглавје на', 'all_pages_footer': 'Прикажи футер на', 'first_page': 'Прва страна', @@ -20038,16 +20047,16 @@ mixin LocalizationsProvider on LocaleCodeAware { 'quote_footer': 'Футер на понуда', 'auto_email_invoice': 'Автоматска е-пошта', 'auto_email_invoice_help': - 'Автоматски испрати рекурентни фактури по е-пошта кога ќе бидат креирани.', + 'Автоматски испрати рекурентни фактури по е-пошта кога ќе бидат креирани.', 'auto_archive_invoice': 'Автоматско архивирање', 'auto_archive_invoice_help': - 'Автоматски архивирај фактури кога ќе бидат платени.', + 'Автоматски архивирај фактури кога ќе бидат платени.', 'auto_archive_quote': 'Автоматско архивирање', 'auto_archive_quote_help': - 'Автоматски архивирај фактури кога ќе бидат конвертирани.', + 'Автоматски архивирај фактури кога ќе бидат конвертирани.', 'auto_convert_quote': 'Автоматско конвертирање', 'auto_convert_quote_help': - 'Автоматски конвертирај понуда во фактура кога истата ќе биде одобрена од клиентот.', + 'Автоматски конвертирај понуда во фактура кога истата ќе биде одобрена од клиентот.', 'workflow_settings': 'Подесувања на текот на работа', 'freq_daily': 'Дневно', 'freq_weekly': 'Неделно', @@ -20093,27 +20102,27 @@ mixin LocalizationsProvider on LocaleCodeAware { 'custom_javascript': 'Custom JavaScript', 'signature_on_pdf': 'Прикажи на PDF', 'signature_on_pdf_help': - 'Прикажи го потписот на клиентот на PDF фактура/понуда.', + 'Прикажи го потписот на клиентот на PDF фактура/понуда.', 'show_accept_invoice_terms': 'Поле за избор на услови за фактура', 'show_accept_invoice_terms_help': - 'Побарај од клиентот да потврди дека ги прифаќа условите на фактурата.', + 'Побарај од клиентот да потврди дека ги прифаќа условите на фактурата.', 'show_accept_quote_terms': 'Поле за избор на услови за понуда', 'show_accept_quote_terms_help': - 'Побарај од клиентот да потврди дека ги прифаќа условите на понудата.', + 'Побарај од клиентот да потврди дека ги прифаќа условите на понудата.', 'require_invoice_signature': 'Потпис на фактура', 'require_invoice_signature_help': - 'Побарај од клиентот да обезбеди потпис.', + 'Побарај од клиентот да обезбеди потпис.', 'require_quote_signature': 'Потпис на понуда', 'enable_portal_password': 'Фактури заштитени со лозинка', 'enable_portal_password_help': - 'Ви дозволува поставување на лозинка за секој контакт. Ако поставите лозинка. контактот ќе мора да ја внесе лозинката пред да ги прегледа фактурите.', + 'Ви дозволува поставување на лозинка за секој контакт. Ако поставите лозинка. контактот ќе мора да ја внесе лозинката пред да ги прегледа фактурите.', 'authorization': 'Овластување', 'subdomain': 'Поддомен', 'domain': 'Домен', 'portal_mode': 'Portal Mode', 'email_signature': 'Со почит,', 'enable_email_markup_help': - 'Направете го полесно плаќањето за вашите клиенти со додавање на schema.org обележје на вашите е-пошти', + 'Направете го полесно плаќањето за вашите клиенти со додавање на schema.org обележје на вашите е-пошти', 'plain': 'Обично', 'light': 'Светло', 'dark': 'Темно', @@ -20142,12 +20151,12 @@ mixin LocalizationsProvider on LocaleCodeAware { 'accepted_card_logos': 'Прифатени логоа на картичка', 'credentials': 'Credentials', 'require_billing_address_help': - 'Require client to provide their billing address', + 'Require client to provide their billing address', 'require_shipping_address_help': - 'Require client to provide their shipping address', + 'Require client to provide their shipping address', 'update_address': 'Ажурирај адреса', 'update_address_help': - 'Ажурирај ја адресата на клиентот со обезбедените детали', + 'Ажурирај ја адресата на клиентот со обезбедените детали', 'rate': 'Стапка', 'tax_rate': 'Даночна стапка', 'new_tax_rate': 'Нова стапка на данок', @@ -20159,13 +20168,13 @@ mixin LocalizationsProvider on LocaleCodeAware { 'restored_tax_rate': 'Successfully restored tax rate', 'fill_products': 'Автоматско пополнување на продукти', 'fill_products_help': - 'Избирањето на продукт автоматски ќе ги исполни полињата за опис и цена', + 'Избирањето на продукт автоматски ќе ги исполни полињата за опис и цена', 'update_products': 'Автоматско ажурирање на продукти', 'update_products_help': - 'Ажурирањето на факура автоматски ќе ја ажурира библиотеката на продукти ', + 'Ажурирањето на факура автоматски ќе ја ажурира библиотеката на продукти ', 'convert_products': 'Конвертирај продукти', 'convert_products_help': - 'Автоматски конвертирај ги цените на продуктите по валутите на клиентите', + 'Автоматски конвертирај ги цените на продуктите по валутите на клиентите', 'fees': 'Надоместоци', 'limits': 'Ограничувања', 'provider': 'Provider', @@ -20265,7 +20274,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'please_enter_a_first_name': 'Please enter a first name', 'please_enter_a_last_name': 'Please enter a last name', 'please_agree_to_terms_and_privacy': - 'Please agree to the terms of service and privacy policy to create an account.', + 'Please agree to the terms of service and privacy policy to create an account.', 'i_agree_to_the': 'I agree to the', 'terms_of_service_link': 'terms of service', 'privacy_policy_link': 'privacy policy', @@ -20364,7 +20373,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'average': 'Average', 'unapproved': 'Unapproved', 'authenticate_to_change_setting': - 'Please authenticate to change this setting', + 'Please authenticate to change this setting', 'locked': 'Locked', 'authenticate': 'Authenticate', 'please_authenticate': 'Please authenticate', @@ -20564,7 +20573,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'marked_invoices_as_paid': 'Successfully marked invoices as paid', 'done': 'Завршено', 'please_enter_a_client_or_contact_name': - 'Please enter a client or contact name', + 'Please enter a client or contact name', 'dark_mode': 'Темен режим', 'restart_app_to_apply_change': 'Restart the app to apply the change', 'refresh_data': 'Refresh Data', @@ -20646,7 +20655,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'activity_8': ':user ја архивира фактурата :invoice', 'activity_9': ':user ја избриша фактурата :invoice', 'activity_10': - ':contact entered payment :payment for :payment_amount on invoice :invoice for :client', + ':contact entered payment :payment for :payment_amount on invoice :invoice for :client', 'activity_11': ':user го ажурира плаќањето :payment', 'activity_12': ':user го архивира плаќањето :payment', 'activity_13': ':user го избриша плаќањето :payment', @@ -20676,7 +20685,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'activity_37': ':user го поврати трошокот :expense', 'activity_39': ':user го откажа :payment_amount плаќањето :payment', 'activity_40': - ':user го рефундира :adjustment на :payment_amount плаќање :payment', + ':user го рефундира :adjustment на :payment_amount плаќање :payment', 'activity_41': ':payment_amount плаќање (:payment) е неуспешно', 'activity_42': ':user ја креира задачата :task', 'activity_43': ':user ажурира задачата :task', @@ -20796,7 +20805,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'purge_data': 'Fjern data', 'purge_successful': 'Successfully purged company data', 'purge_data_message': - 'Advarsel: Dette sletter alle dine data permanent, og kan ikke gjennopprettes.', + 'Advarsel: Dette sletter alle dine data permanent, og kan ikke gjennopprettes.', 'invoice_balance': 'Invoice Balance', 'age_group_0': '0 - 30 Dager', 'age_group_30': '30 - 60 Dager', @@ -20831,10 +20840,10 @@ mixin LocalizationsProvider on LocaleCodeAware { 'apply_license': 'aktiver lisens', 'cancel_account': 'Kanseler Konto', 'cancel_account_message': - 'Advarsel: Dette vil permanent slette kontoen din, du kan ikke angre.', + 'Advarsel: Dette vil permanent slette kontoen din, du kan ikke angre.', 'delete_company': 'Slett Firma', 'delete_company_message': - 'Advarsel: Dette vil permanent slette ditt firma, dette kan ikke gjennopprettes.', + 'Advarsel: Dette vil permanent slette ditt firma, dette kan ikke gjennopprettes.', 'enable_modules': 'Enable Modules', 'converted_quote': 'Successfully converted quote', 'credit_design': 'Credit Design', @@ -20986,12 +20995,12 @@ mixin LocalizationsProvider on LocaleCodeAware { 'applied': 'Applied', 'include_recent_errors': 'Include recent errors from the logs', 'your_message_has_been_received': - 'We have received your message and will try to respond promptly.', + 'We have received your message and will try to respond promptly.', 'message': 'Beskjed', 'from': 'Fra', 'show_product_details': 'Show Product Details', 'show_product_details_help': - 'Include the description and cost in the product dropdown', + 'Include the description and cost in the product dropdown', 'pdf_min_requirements': 'The PDF renderer requires :version', 'adjust_fee_percent': 'Adjust Fee Percent', 'adjust_fee_percent_help': 'Adjust percent to account for fee', @@ -21008,7 +21017,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'domain_url': 'Domain URL', 'password_is_too_short': 'Password is too short', 'password_is_too_easy': - 'Password must contain an upper case character and a number', + 'Password must contain an upper case character and a number', 'client_portal_tasks': 'Client Portal Tasks', 'client_portal_dashboard': 'Client Portal Dashboard', 'please_enter_a_value': 'Please enter a value', @@ -21035,16 +21044,16 @@ mixin LocalizationsProvider on LocaleCodeAware { 'third_custom': 'Third Custom', 'show_cost': 'Show Cost', 'show_cost_help': - 'Display a product cost field to track the markup/profit', + 'Display a product cost field to track the markup/profit', 'show_product_quantity': 'Show Product Quantity', 'show_product_quantity_help': - 'Display a product quantity field, otherwise default to one', + 'Display a product quantity field, otherwise default to one', 'show_invoice_quantity': 'Show Invoice Quantity', 'show_invoice_quantity_help': - 'Display a line item quantity field, otherwise default to one', + 'Display a line item quantity field, otherwise default to one', 'default_quantity': 'Default Quantity', 'default_quantity_help': - 'Automatically set the line item quantity to one', + 'Automatically set the line item quantity to one', 'one_tax_rate': 'One Tax Rate', 'two_tax_rates': 'Two Tax Rates', 'three_tax_rates': 'Three Tax Rates', @@ -21089,7 +21098,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'filtered_by_user': 'Filtered by User', 'administrator': 'Administrator', 'administrator_help': - 'Allow user to manage users, change settings and modify all records', + 'Allow user to manage users, change settings and modify all records', 'user_management': 'Brukerhåndtering', 'users': 'Brukere', 'new_user': 'New User', @@ -21104,7 +21113,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'invoice_options': 'Faktura alternativer', 'hide_paid_to_date': 'Skjul delbetalinger', 'hide_paid_to_date_help': - 'Bare vis delbetalinger om det har forekommet en delbetaling.', + 'Bare vis delbetalinger om det har forekommet en delbetaling.', 'invoice_embed_documents': 'Embed Dokumenter', 'invoice_embed_documents_help': 'Include attached images in the invoice.', 'all_pages_header': 'Show header on', @@ -21127,16 +21136,16 @@ mixin LocalizationsProvider on LocaleCodeAware { 'quote_footer': 'Tilbud Bunntekst', 'auto_email_invoice': 'Auto Email', 'auto_email_invoice_help': - 'Automatically email recurring invoices when they are created.', + 'Automatically email recurring invoices when they are created.', 'auto_archive_invoice': 'Auto Archive', 'auto_archive_invoice_help': - 'Automatically archive invoices when they are paid.', + 'Automatically archive invoices when they are paid.', 'auto_archive_quote': 'Auto Archive', 'auto_archive_quote_help': - 'Automatically archive quotes when they are converted.', + 'Automatically archive quotes when they are converted.', 'auto_convert_quote': 'Auto Convert', 'auto_convert_quote_help': - 'Automatically convert a quote to an invoice when approved by a client.', + 'Automatically convert a quote to an invoice when approved by a client.', 'workflow_settings': 'Workflow Settings', 'freq_daily': 'Daglig', 'freq_weekly': 'Ukentlig', @@ -21182,26 +21191,26 @@ mixin LocalizationsProvider on LocaleCodeAware { 'custom_javascript': 'Custom JavaScript', 'signature_on_pdf': 'Show on PDF', 'signature_on_pdf_help': - 'Show the client signature on the invoice/quote PDF.', + 'Show the client signature on the invoice/quote PDF.', 'show_accept_invoice_terms': 'Invoice Terms Checkbox', 'show_accept_invoice_terms_help': - 'Require client to confirm that they accept the invoice terms.', + 'Require client to confirm that they accept the invoice terms.', 'show_accept_quote_terms': 'Quote Terms Checkbox', 'show_accept_quote_terms_help': - 'Require client to confirm that they accept the quote terms.', + 'Require client to confirm that they accept the quote terms.', 'require_invoice_signature': 'Faktura-signatur', 'require_invoice_signature_help': 'Krever klients signatur.', 'require_quote_signature': 'Tilbuds-signatur', 'enable_portal_password': 'Passord-beskytt fakturaer', 'enable_portal_password_help': - 'Allows you to set a password for each contact. If a password is set, the contact will be required to enter a password before viewing invoices.', + 'Allows you to set a password for each contact. If a password is set, the contact will be required to enter a password before viewing invoices.', 'authorization': 'Autorisasjon', 'subdomain': 'Subdomene', 'domain': 'Domene', 'portal_mode': 'Portal Mode', 'email_signature': 'Med vennlig hilsen,', 'enable_email_markup_help': - 'Make it easier for your clients to pay you by adding schema.org markup to your emails.', + 'Make it easier for your clients to pay you by adding schema.org markup to your emails.', 'plain': 'Plain', 'light': 'Light', 'dark': 'Dark', @@ -21230,9 +21239,9 @@ mixin LocalizationsProvider on LocaleCodeAware { 'accepted_card_logos': 'Accepted Card Logos', 'credentials': 'Credentials', 'require_billing_address_help': - 'Require client to provide their billing address', + 'Require client to provide their billing address', 'require_shipping_address_help': - 'Require client to provide their shipping address', + 'Require client to provide their shipping address', 'update_address': 'Oppdater Adresse', 'update_address_help': 'Oppdater kundens adresse med oppgitte detaljer', 'rate': 'Sats', @@ -21246,13 +21255,13 @@ mixin LocalizationsProvider on LocaleCodeAware { 'restored_tax_rate': 'Successfully restored tax rate', 'fill_products': 'Automatisk-utfyll produkter', 'fill_products_help': - 'Valg av produkt vil automatisk fylle ut beskrivelse og kostnaden', + 'Valg av produkt vil automatisk fylle ut beskrivelse og kostnaden', 'update_products': 'Automatisk oppdater produkter', 'update_products_help': - 'Å endre en faktura vil automatisk oppdatere produktbilioteket', + 'Å endre en faktura vil automatisk oppdatere produktbilioteket', 'convert_products': 'Convert Products', 'convert_products_help': - 'Automatically convert product prices to the client\'s currency', + 'Automatically convert product prices to the client\'s currency', 'fees': 'Avgifter', 'limits': 'Begrensninger', 'provider': 'Provider', @@ -21352,7 +21361,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'please_enter_a_first_name': 'Please enter a first name', 'please_enter_a_last_name': 'Please enter a last name', 'please_agree_to_terms_and_privacy': - 'Please agree to the terms of service and privacy policy to create an account.', + 'Please agree to the terms of service and privacy policy to create an account.', 'i_agree_to_the': 'I agree to the', 'terms_of_service_link': 'terms of service', 'privacy_policy_link': 'privacy policy', @@ -21451,7 +21460,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'average': 'Average', 'unapproved': 'Unapproved', 'authenticate_to_change_setting': - 'Please authenticate to change this setting', + 'Please authenticate to change this setting', 'locked': 'Låst', 'authenticate': 'Authenticate', 'please_authenticate': 'Please authenticate', @@ -21651,7 +21660,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'marked_invoices_as_paid': 'Successfully marked invoices as paid', 'done': 'Ferdig', 'please_enter_a_client_or_contact_name': - 'Please enter a client or contact name', + 'Please enter a client or contact name', 'dark_mode': 'Mørk Modus', 'restart_app_to_apply_change': 'Restart the app to apply the change', 'refresh_data': 'Refresh Data', @@ -21733,7 +21742,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'activity_8': ':user arkiverte faktura :invoice', 'activity_9': ':user slettet faktura :invoice', 'activity_10': - ':contact entered payment :payment for :payment_amount on invoice :invoice for :client', + ':contact entered payment :payment for :payment_amount on invoice :invoice for :client', 'activity_11': ':user oppdaterte betaling :payment', 'activity_12': ':user arkiverte betaling :payment', 'activity_13': ':user slettet betaling :payment', @@ -21763,7 +21772,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'activity_37': ':user gjenopprettet utgift :expense', 'activity_39': ':user cancelled a :payment_amount payment :payment', 'activity_40': - ':user refunded :adjustment of a :payment_amount payment :payment', + ':user refunded :adjustment of a :payment_amount payment :payment', 'activity_41': ':payment_amount payment (:payment) failed', 'activity_42': ':user opprettet oppgave :task', 'activity_43': ':user oppdaterte oppgave :task', @@ -21883,7 +21892,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'purge_data': 'Purge Data', 'purge_successful': 'Successfully purged company data', 'purge_data_message': - 'Warning: This will permanently erase your data, there is no undo.', + 'Warning: This will permanently erase your data, there is no undo.', 'invoice_balance': 'Invoice Balance', 'age_group_0': '0 - 30 dni', 'age_group_30': '30 - 60 dni', @@ -21918,10 +21927,10 @@ mixin LocalizationsProvider on LocaleCodeAware { 'apply_license': 'Zastosuj licencję', 'cancel_account': 'Anuluj konto', 'cancel_account_message': - 'Ostrzeżenie: Nie można cofnąć tej operacji, wszystkie twoje dane zostaną usunięte.', + 'Ostrzeżenie: Nie można cofnąć tej operacji, wszystkie twoje dane zostaną usunięte.', 'delete_company': 'Delete Company', 'delete_company_message': - 'Warning: This will permanently delete your company, there is no undo.', + 'Warning: This will permanently delete your company, there is no undo.', 'enable_modules': 'Enable Modules', 'converted_quote': 'Successfully converted quote', 'credit_design': 'Credit Design', @@ -22073,12 +22082,12 @@ mixin LocalizationsProvider on LocaleCodeAware { 'applied': 'Applied', 'include_recent_errors': 'Include recent errors from the logs', 'your_message_has_been_received': - 'We have received your message and will try to respond promptly.', + 'We have received your message and will try to respond promptly.', 'message': 'Wiadomość', 'from': 'Od', 'show_product_details': 'Show Product Details', 'show_product_details_help': - 'Include the description and cost in the product dropdown', + 'Include the description and cost in the product dropdown', 'pdf_min_requirements': 'The PDF renderer requires :version', 'adjust_fee_percent': 'Adjust Fee Percent', 'adjust_fee_percent_help': 'Adjust percent to account for fee', @@ -22095,7 +22104,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'domain_url': 'Domain URL', 'password_is_too_short': 'Password is too short', 'password_is_too_easy': - 'Password must contain an upper case character and a number', + 'Password must contain an upper case character and a number', 'client_portal_tasks': 'Client Portal Tasks', 'client_portal_dashboard': 'Client Portal Dashboard', 'please_enter_a_value': 'Please enter a value', @@ -22122,16 +22131,16 @@ mixin LocalizationsProvider on LocaleCodeAware { 'third_custom': 'Third Custom', 'show_cost': 'Show Cost', 'show_cost_help': - 'Display a product cost field to track the markup/profit', + 'Display a product cost field to track the markup/profit', 'show_product_quantity': 'Show Product Quantity', 'show_product_quantity_help': - 'Display a product quantity field, otherwise default to one', + 'Display a product quantity field, otherwise default to one', 'show_invoice_quantity': 'Show Invoice Quantity', 'show_invoice_quantity_help': - 'Display a line item quantity field, otherwise default to one', + 'Display a line item quantity field, otherwise default to one', 'default_quantity': 'Default Quantity', 'default_quantity_help': - 'Automatically set the line item quantity to one', + 'Automatically set the line item quantity to one', 'one_tax_rate': 'One Tax Rate', 'two_tax_rates': 'Two Tax Rates', 'three_tax_rates': 'Three Tax Rates', @@ -22176,7 +22185,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'filtered_by_user': 'Filtered by User', 'administrator': 'Administrator', 'administrator_help': - 'Zezwól użytkownikowi na zarządzanie użytkownikami, edytowanie ustawień oraz wszystkich danych.', + 'Zezwól użytkownikowi na zarządzanie użytkownikami, edytowanie ustawień oraz wszystkich danych.', 'user_management': 'Zarządzanie użytkownikami', 'users': 'Użytkownicy', 'new_user': 'Nowy użytkownik', @@ -22191,7 +22200,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'invoice_options': 'Opcje faktury', 'hide_paid_to_date': 'Ukryj pole \"Zapłacono dotychczas\"', 'hide_paid_to_date_help': - 'Wyświetlaj \"Zapłacono dotychczas\" tylko przy tych fakturach, do których otrzymano płatność.', + 'Wyświetlaj \"Zapłacono dotychczas\" tylko przy tych fakturach, do których otrzymano płatność.', 'invoice_embed_documents': 'Załączniki', 'invoice_embed_documents_help': 'Wstaw do faktury załączniki graficzne.', 'all_pages_header': 'Pokaż nagłówek na', @@ -22214,16 +22223,16 @@ mixin LocalizationsProvider on LocaleCodeAware { 'quote_footer': 'Stopka oferty', 'auto_email_invoice': 'Auto Email', 'auto_email_invoice_help': - 'Automatically email recurring invoices when they are created.', + 'Automatically email recurring invoices when they are created.', 'auto_archive_invoice': 'Auto Archive', 'auto_archive_invoice_help': - 'Automatically archive invoices when they are paid.', + 'Automatically archive invoices when they are paid.', 'auto_archive_quote': 'Auto Archive', 'auto_archive_quote_help': - 'Automatically archive quotes when they are converted.', + 'Automatically archive quotes when they are converted.', 'auto_convert_quote': 'Automatycznie konwertuj', 'auto_convert_quote_help': - 'Utwórz automatycznie fakturę z oferty zaakceptowanej przez klienta.', + 'Utwórz automatycznie fakturę z oferty zaakceptowanej przez klienta.', 'workflow_settings': 'Workflow Settings', 'freq_daily': 'Codziennie', 'freq_weekly': 'Co tydzień', @@ -22269,26 +22278,26 @@ mixin LocalizationsProvider on LocaleCodeAware { 'custom_javascript': 'Custom JavaScript', 'signature_on_pdf': 'Show on PDF', 'signature_on_pdf_help': - 'Show the client signature on the invoice/quote PDF.', + 'Show the client signature on the invoice/quote PDF.', 'show_accept_invoice_terms': 'Przycisk wyboru do warunków faktury', 'show_accept_invoice_terms_help': - 'Wymagaj od klienta potwierdzenia, że akceptuje warunki faktury.', + 'Wymagaj od klienta potwierdzenia, że akceptuje warunki faktury.', 'show_accept_quote_terms': 'Przycisk wyboru do warunków oferty', 'show_accept_quote_terms_help': - 'Wymagaj od klienta potwierdzenia, że akceptuje warunki oferty.', + 'Wymagaj od klienta potwierdzenia, że akceptuje warunki oferty.', 'require_invoice_signature': 'Podpis na fakurze', 'require_invoice_signature_help': 'Wymagaj od klienta podpisania faktury', 'require_quote_signature': 'Podpis na ofercie', 'enable_portal_password': 'Faktury chronione hasłem', 'enable_portal_password_help': - 'Zezwala na utworzenie haseł dla każdego kontaktu. Jeśli hasło zostanie ustanowione, użytkownik będzie musiał podać hasło, aby przeglądać faktury.', + 'Zezwala na utworzenie haseł dla każdego kontaktu. Jeśli hasło zostanie ustanowione, użytkownik będzie musiał podać hasło, aby przeglądać faktury.', 'authorization': 'Autoryzacja', 'subdomain': 'Subdomena', 'domain': 'Domena', 'portal_mode': 'Portal Mode', 'email_signature': 'Z wyrazami szacunku,', 'enable_email_markup_help': - 'Make it easier for your clients to pay you by adding schema.org markup to your emails.', + 'Make it easier for your clients to pay you by adding schema.org markup to your emails.', 'plain': 'Zwykły', 'light': 'Jasny', 'dark': 'Ciemny', @@ -22317,12 +22326,12 @@ mixin LocalizationsProvider on LocaleCodeAware { 'accepted_card_logos': 'Accepted Card Logos', 'credentials': 'Credentials', 'require_billing_address_help': - 'Require client to provide their billing address', + 'Require client to provide their billing address', 'require_shipping_address_help': - 'Require client to provide their shipping address', + 'Require client to provide their shipping address', 'update_address': 'Aktualizuj adres', 'update_address_help': - 'Zaktualizuj dane adresowe klienta na podstawie dostarczonych informacji', + 'Zaktualizuj dane adresowe klienta na podstawie dostarczonych informacji', 'rate': 'Stawka', 'tax_rate': 'Stawka podatkowa', 'new_tax_rate': 'Nowa stawka podatkowa', @@ -22334,13 +22343,13 @@ mixin LocalizationsProvider on LocaleCodeAware { 'restored_tax_rate': 'Successfully restored tax rate', 'fill_products': 'Automatycznie uzupełniaj produkty', 'fill_products_help': - 'Wybieranie produktu automatycznie uzupełni opis i kwotę', + 'Wybieranie produktu automatycznie uzupełni opis i kwotę', 'update_products': 'Automatycznie aktualizuj produkty', 'update_products_help': - 'Zaktualizowanie faktury automatycznie uaktualni produkt w bibliotece produktów', + 'Zaktualizowanie faktury automatycznie uaktualni produkt w bibliotece produktów', 'convert_products': 'Convert Products', 'convert_products_help': - 'Automatycznie zamieniaj ceny produktu na walutę klienta', + 'Automatycznie zamieniaj ceny produktu na walutę klienta', 'fees': 'Opłaty', 'limits': 'Limity', 'provider': 'Provider', @@ -22440,7 +22449,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'please_enter_a_first_name': 'Please enter a first name', 'please_enter_a_last_name': 'Please enter a last name', 'please_agree_to_terms_and_privacy': - 'Please agree to the terms of service and privacy policy to create an account.', + 'Please agree to the terms of service and privacy policy to create an account.', 'i_agree_to_the': 'I agree to the', 'terms_of_service_link': 'terms of service', 'privacy_policy_link': 'privacy policy', @@ -22539,7 +22548,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'average': 'Average', 'unapproved': 'Unapproved', 'authenticate_to_change_setting': - 'Please authenticate to change this setting', + 'Please authenticate to change this setting', 'locked': 'Locked', 'authenticate': 'Authenticate', 'please_authenticate': 'Please authenticate', @@ -22739,10 +22748,10 @@ mixin LocalizationsProvider on LocaleCodeAware { 'marked_invoices_as_paid': 'Successfully marked invoices as paid', 'done': 'Gotowe', 'please_enter_a_client_or_contact_name': - 'Please enter a client or contact name', + 'Please enter a client or contact name', 'dark_mode': 'Tryb ciemny', 'restart_app_to_apply_change': - 'Uruchom ponownie aplikację, aby zastosować zmianę', + 'Uruchom ponownie aplikację, aby zastosować zmianę', 'refresh_data': 'Refresh Data', 'blank_contact': 'Blank Contact', 'activity': 'Dziennik aktywności', @@ -22822,7 +22831,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'activity_8': ':user zarchiwizował fakturę :invoice', 'activity_9': ':user usunął fakturę :invoice', 'activity_10': - ':contact entered payment :payment for :payment_amount on invoice :invoice for :client', + ':contact entered payment :payment for :payment_amount on invoice :invoice for :client', 'activity_11': ':user zaktualizował płatność :payment', 'activity_12': ':user zarchiwizował płatność :payment', 'activity_13': ':user usunął płatność :payment', @@ -22852,7 +22861,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'activity_37': ':user przywrócił wydatek :expense', 'activity_39': ':user anulował płatność na :payment_amount nr. :payment', 'activity_40': - ':user refunded :adjustment of a :payment_amount payment :payment', + ':user refunded :adjustment of a :payment_amount payment :payment', 'activity_41': 'płatność :payment_amount (:payment) nieudana', 'activity_42': ':user stworzył zadanie :task', 'activity_43': ':user zaktualizował zadanie :task', @@ -22972,7 +22981,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'purge_data': 'Limpar Dados', 'purge_successful': 'Dados da empresa limpos com sucesso', 'purge_data_message': - 'Aviso: Isto irá apagar seus dados permanentemente, não há como defazer esta ação.', + 'Aviso: Isto irá apagar seus dados permanentemente, não há como defazer esta ação.', 'invoice_balance': 'Invoice Balance', 'age_group_0': '0 - 30 Dias', 'age_group_30': '30 - 60 Dias', @@ -23007,10 +23016,10 @@ mixin LocalizationsProvider on LocaleCodeAware { 'apply_license': 'Aplicar Licença', 'cancel_account': 'Excluir Conta', 'cancel_account_message': - 'Aviso: Isso excluirá permanentemente sua conta, não há como desfazer esta ação.', + 'Aviso: Isso excluirá permanentemente sua conta, não há como desfazer esta ação.', 'delete_company': 'Excluir Empresa', 'delete_company_message': - 'Aviso: Isto irá excluir permanentemente sua empresa, não há como desfazer esta ação.', + 'Aviso: Isto irá excluir permanentemente sua empresa, não há como desfazer esta ação.', 'enable_modules': 'Enable Modules', 'converted_quote': 'Successfully converted quote', 'credit_design': 'Credit Design', @@ -23162,14 +23171,14 @@ mixin LocalizationsProvider on LocaleCodeAware { 'applied': 'Aplicado', 'include_recent_errors': 'Inclui erros recentes dos logs', 'your_message_has_been_received': - 'Recebemos sua mensagem e tentaremos responder rapidamente.', + 'Recebemos sua mensagem e tentaremos responder rapidamente.', 'message': 'Mensagem', 'from': 'De', 'show_product_details': 'Mostrar Detalhes do Produto', 'show_product_details_help': - 'Include the description and cost in the product dropdown', + 'Include the description and cost in the product dropdown', 'pdf_min_requirements': - 'A renderização de PDF precisa da versão :version', + 'A renderização de PDF precisa da versão :version', 'adjust_fee_percent': 'Ajustar Porcentagem da Multa', 'adjust_fee_percent_help': 'Ajustar o percentual de taxa a contabilizar', 'configure_settings': 'Configurações Gerais', @@ -23185,7 +23194,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'domain_url': 'URL do Domínio', 'password_is_too_short': 'A senha é muito curta', 'password_is_too_easy': - 'Password must contain an upper case character and a number', + 'Password must contain an upper case character and a number', 'client_portal_tasks': 'Tarefas do Portal do Cliente', 'client_portal_dashboard': 'Painel do Portal do Cliente', 'please_enter_a_value': 'Por favor digite um valor', @@ -23212,16 +23221,16 @@ mixin LocalizationsProvider on LocaleCodeAware { 'third_custom': 'Terceiro Personalizado', 'show_cost': 'Mostrar Custo', 'show_cost_help': - 'Display a product cost field to track the markup/profit', + 'Display a product cost field to track the markup/profit', 'show_product_quantity': 'Mostrar Quantidade do Produto', 'show_product_quantity_help': - 'Mostrar um campo de quantidade de produto, caso contrário o padrão de um', + 'Mostrar um campo de quantidade de produto, caso contrário o padrão de um', 'show_invoice_quantity': 'Show Invoice Quantity', 'show_invoice_quantity_help': - 'Display a line item quantity field, otherwise default to one', + 'Display a line item quantity field, otherwise default to one', 'default_quantity': 'Quantidade Padrão', 'default_quantity_help': - 'Automatically set the line item quantity to one', + 'Automatically set the line item quantity to one', 'one_tax_rate': 'One Tax Rate', 'two_tax_rates': 'Two Tax Rates', 'three_tax_rates': 'Three Tax Rates', @@ -23245,7 +23254,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'dropdown': 'Dropdown', 'field_type': 'Tipo de Campo', 'recover_password_email_sent': - 'Foi enviado um e-mail de recuperação de senha', + 'Foi enviado um e-mail de recuperação de senha', 'submit': 'Enviar', 'recover_password': 'Recupere sua senha', 'late_fees': 'Late Fees', @@ -23267,7 +23276,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'filtered_by_user': 'Filtrado por Usuário', 'administrator': 'Administrador', 'administrator_help': - 'Permite ao usuário gerenciar usuários, mudar configurações e modificar todos os registros', + 'Permite ao usuário gerenciar usuários, mudar configurações e modificar todos os registros', 'user_management': 'Gerenciamento de Usuários', 'users': 'Usuários', 'new_user': 'Novo Usuário', @@ -23282,7 +23291,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'invoice_options': 'Opções da Fatura', 'hide_paid_to_date': 'Ocultar Pago até Hoje', 'hide_paid_to_date_help': - 'Apenas mostrar \"Pago até a Data\" em suas faturas uma vez que o pagamento for recebido.', + 'Apenas mostrar \"Pago até a Data\" em suas faturas uma vez que o pagamento for recebido.', 'invoice_embed_documents': 'Embutir Documentos', 'invoice_embed_documents_help': 'Incluir imagens anexas na fatura.', 'all_pages_header': 'Exibir Cabeçalho em', @@ -23305,16 +23314,16 @@ mixin LocalizationsProvider on LocaleCodeAware { 'quote_footer': 'Rodapé do Orçamento', 'auto_email_invoice': 'Email Automático', 'auto_email_invoice_help': - 'Enviar faturas recorrentes por email automaticamente quando forem criadas.', + 'Enviar faturas recorrentes por email automaticamente quando forem criadas.', 'auto_archive_invoice': 'Arquivar Automaticamente', 'auto_archive_invoice_help': - 'Arquivar automaticamente faturas quando forem pagas.', + 'Arquivar automaticamente faturas quando forem pagas.', 'auto_archive_quote': 'Arquivar Automaticamente', 'auto_archive_quote_help': - 'Arquivar automaticamente orçamentos quando forem convertidos.', + 'Arquivar automaticamente orçamentos quando forem convertidos.', 'auto_convert_quote': 'Auto Conversão', 'auto_convert_quote_help': - 'Converter automaticamente um orçamento quando for aprovado pelo cliente.', + 'Converter automaticamente um orçamento quando for aprovado pelo cliente.', 'workflow_settings': 'Configurações de Fluxo de Trabalho', 'freq_daily': 'Diariamente', 'freq_weekly': 'Semanalmente', @@ -23360,27 +23369,27 @@ mixin LocalizationsProvider on LocaleCodeAware { 'custom_javascript': 'JavaScript Personalizado', 'signature_on_pdf': 'Exibir em PDF', 'signature_on_pdf_help': - 'Exibir a assinatura do cliente no PDF da fatura/orçamento.', + 'Exibir a assinatura do cliente no PDF da fatura/orçamento.', 'show_accept_invoice_terms': 'Checkbox para Condições de Fatura', 'show_accept_invoice_terms_help': - 'Exigir que o cliente confirme que aceita as condições da fatura.', + 'Exigir que o cliente confirme que aceita as condições da fatura.', 'show_accept_quote_terms': 'Checkbox de Condições do Orçamento', 'show_accept_quote_terms_help': - 'Exigir que cliente confirme que aceita as Condições do Orçamento', + 'Exigir que cliente confirme que aceita as Condições do Orçamento', 'require_invoice_signature': 'Assinatura de Fatura', 'require_invoice_signature_help': - 'Exigir que o cliente providencie sua assinatura', + 'Exigir que o cliente providencie sua assinatura', 'require_quote_signature': 'Assinatura de Orçamento', 'enable_portal_password': 'Proteger Faturas com Senha', 'enable_portal_password_help': - 'Permite definir uma senha para cada contato. Se uma senha for definida, o contato deverá informar uma senha antes de visualizar faturas.', + 'Permite definir uma senha para cada contato. Se uma senha for definida, o contato deverá informar uma senha antes de visualizar faturas.', 'authorization': 'Autorização', 'subdomain': 'Subdomínio', 'domain': 'Domínio', 'portal_mode': 'Modo Portal', 'email_signature': 'Atenciosamente,', 'enable_email_markup_help': - 'Tornar mais fácil para os seus clientes efetuarem seus pagamentos acrescentando marcações schema.org a seus emails.', + 'Tornar mais fácil para os seus clientes efetuarem seus pagamentos acrescentando marcações schema.org a seus emails.', 'plain': 'Plano', 'light': 'Claro', 'dark': 'Escuro', @@ -23409,12 +23418,12 @@ mixin LocalizationsProvider on LocaleCodeAware { 'accepted_card_logos': 'Logos de Cartões Aceitos', 'credentials': 'Credenciais', 'require_billing_address_help': - 'Require client to provide their billing address', + 'Require client to provide their billing address', 'require_shipping_address_help': - 'Require client to provide their shipping address', + 'Require client to provide their shipping address', 'update_address': 'Atualizar Endereço', 'update_address_help': - 'Atualizar o endereço do cliente com os dados fornecidos', + 'Atualizar o endereço do cliente com os dados fornecidos', 'rate': 'Taxa', 'tax_rate': 'Taxa do Imposto', 'new_tax_rate': 'Nova Taxa de Imposto', @@ -23426,13 +23435,13 @@ mixin LocalizationsProvider on LocaleCodeAware { 'restored_tax_rate': 'Successfully restored tax rate', 'fill_products': 'Auto-preencher produtos', 'fill_products_help': - 'Ao selecionar um produto sua descrição e preço serão automaticamente preenchidos', + 'Ao selecionar um produto sua descrição e preço serão automaticamente preenchidos', 'update_products': 'Atualização automática dos produtos', 'update_products_help': - 'Atualizar uma fatura irá automaticamenteatualizar a biblioteca de produtos', + 'Atualizar uma fatura irá automaticamenteatualizar a biblioteca de produtos', 'convert_products': 'Converter Produtos', 'convert_products_help': - 'Converter automaticamente preços de produtos para a moeda do cliente', + 'Converter automaticamente preços de produtos para a moeda do cliente', 'fees': 'Taxas', 'limits': 'Limites', 'provider': 'Provedor', @@ -23532,7 +23541,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'please_enter_a_first_name': 'Por favor digite o primeiro nome', 'please_enter_a_last_name': 'Por favor digite o sobrenome', 'please_agree_to_terms_and_privacy': - 'Por favor, aceite os termos de serviço e política de privacidade para criar uma conta.', + 'Por favor, aceite os termos de serviço e política de privacidade para criar uma conta.', 'i_agree_to_the': 'Aceito os', 'terms_of_service_link': 'termos do serviço', 'privacy_policy_link': 'política de privacidade', @@ -23631,7 +23640,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'average': 'Médio', 'unapproved': 'Não Aprovado', 'authenticate_to_change_setting': - 'Por favor autentique-se para modificar esta configuração', + 'Por favor autentique-se para modificar esta configuração', 'locked': 'Travado', 'authenticate': 'Autenticar', 'please_authenticate': 'Por favor autentique-se', @@ -23831,7 +23840,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'marked_invoices_as_paid': 'Successfully marked invoices as paid', 'done': 'Concluído', 'please_enter_a_client_or_contact_name': - 'Por favor digite um cliente ou nome de contato', + 'Por favor digite um cliente ou nome de contato', 'dark_mode': 'Modo Escuro', 'restart_app_to_apply_change': 'Reinicie o app para aplicar a mudança', 'refresh_data': 'Atualizar Dados', @@ -23913,7 +23922,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'activity_8': ':user arquivou a fatura :invoice', 'activity_9': ':user excluiu a fatura :invoice', 'activity_10': - ':contact efetuou o pagamento :payment de :payment_amount da fatura :invoice do cliente :client', + ':contact efetuou o pagamento :payment de :payment_amount da fatura :invoice do cliente :client', 'activity_11': ':user atualizou o pagamento :payment', 'activity_12': ':user arquivou o pagamento :payment', 'activity_13': ':user excluiu o pagamento :payment', @@ -23924,7 +23933,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'activity_18': ':user criou o orçamento :quote', 'activity_19': ':user atualizou o orçamento :quote', 'activity_20': - ':user enviou o orçamento :quote do cliente :client para o contato :contact', + ':user enviou o orçamento :quote do cliente :client para o contato :contact', 'activity_21': ':contact visualizou o orçamento :quote', 'activity_22': ':user arquivou o orçamento :quote', 'activity_23': ':user excluiu o orçamento :quote', @@ -23934,7 +23943,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'activity_27': ':user restaurou o pagamento :payment', 'activity_28': ':user restaurou o crédito :credit', 'activity_29': - ':contact aprovou o orçamento :quote para o cliente :client', + ':contact aprovou o orçamento :quote para o cliente :client', 'activity_30': ':user criou o fornecedor :vendor', 'activity_31': ':user arquivou o fornecedor :vendor', 'activity_32': ':user excluiu :vendor', @@ -23944,9 +23953,9 @@ mixin LocalizationsProvider on LocaleCodeAware { 'activity_36': ':user excluiu a despesa :expense', 'activity_37': ':user restaurou a despesa :expense', 'activity_39': - ':user cancelou um pagamento de :payment_amount em :payment', + ':user cancelou um pagamento de :payment_amount em :payment', 'activity_40': - ':user reembolsou :adjustment de um pagamento :payment_amount em :payment', + ':user reembolsou :adjustment de um pagamento :payment_amount em :payment', 'activity_41': 'Pagamento :payment_amount (:payment) falhou', 'activity_42': ':user criou a tarefa :task', 'activity_43': ':user atualizou a tarefa :task', @@ -23980,10 +23989,10 @@ mixin LocalizationsProvider on LocaleCodeAware { 'email_style_custom': 'Estilo de E-mail Personalizado', 'custom_message_dashboard': 'Mensagem de Painel Personalizada', 'custom_message_unpaid_invoice': - 'Mensagem Personalizada de Fatura Atrasada', + 'Mensagem Personalizada de Fatura Atrasada', 'custom_message_paid_invoice': 'Mensagem Personalizada de Fatura Paga', 'custom_message_unapproved_quote': - 'Mensagem Personalizada de Orçamento Não Aprovado', + 'Mensagem Personalizada de Orçamento Não Aprovado', 'lock_sent_invoices': 'Travar Faturas Enviadas', 'translations': 'Traduções', 'task_number_pattern': 'Padrão de Numeração de Tarefa', @@ -24102,10 +24111,10 @@ mixin LocalizationsProvider on LocaleCodeAware { 'apply_license': 'Aplicar Linceça', 'cancel_account': 'Cancelar Conta', 'cancel_account_message': - 'Aviso: Irá apagar permanentemente a sua conta.', + 'Aviso: Irá apagar permanentemente a sua conta.', 'delete_company': 'Delete Company', 'delete_company_message': - 'Warning: This will permanently delete your company, there is no undo.', + 'Warning: This will permanently delete your company, there is no undo.', 'enable_modules': 'Enable Modules', 'converted_quote': 'Successfully converted quote', 'credit_design': 'Credit Design', @@ -24257,12 +24266,12 @@ mixin LocalizationsProvider on LocaleCodeAware { 'applied': 'Applied', 'include_recent_errors': 'Include recent errors from the logs', 'your_message_has_been_received': - 'We have received your message and will try to respond promptly.', + 'We have received your message and will try to respond promptly.', 'message': 'Mensagem', 'from': 'De', 'show_product_details': 'Show Product Details', 'show_product_details_help': - 'Include the description and cost in the product dropdown', + 'Include the description and cost in the product dropdown', 'pdf_min_requirements': 'The PDF renderer requires :version', 'adjust_fee_percent': 'Adjust Fee Percent', 'adjust_fee_percent_help': 'Adjust percent to account for fee', @@ -24279,7 +24288,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'domain_url': 'Domain URL', 'password_is_too_short': 'Password is too short', 'password_is_too_easy': - 'Password must contain an upper case character and a number', + 'Password must contain an upper case character and a number', 'client_portal_tasks': 'Client Portal Tasks', 'client_portal_dashboard': 'Client Portal Dashboard', 'please_enter_a_value': 'Please enter a value', @@ -24306,16 +24315,16 @@ mixin LocalizationsProvider on LocaleCodeAware { 'third_custom': 'Third Custom', 'show_cost': 'Show Cost', 'show_cost_help': - 'Display a product cost field to track the markup/profit', + 'Display a product cost field to track the markup/profit', 'show_product_quantity': 'Show Product Quantity', 'show_product_quantity_help': - 'Display a product quantity field, otherwise default to one', + 'Display a product quantity field, otherwise default to one', 'show_invoice_quantity': 'Show Invoice Quantity', 'show_invoice_quantity_help': - 'Display a line item quantity field, otherwise default to one', + 'Display a line item quantity field, otherwise default to one', 'default_quantity': 'Default Quantity', 'default_quantity_help': - 'Automatically set the line item quantity to one', + 'Automatically set the line item quantity to one', 'one_tax_rate': 'One Tax Rate', 'two_tax_rates': 'Two Tax Rates', 'three_tax_rates': 'Three Tax Rates', @@ -24360,7 +24369,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'filtered_by_user': 'Filtered by User', 'administrator': 'Administrador', 'administrator_help': - 'Permite ao utilizador gerir utilizadores, alterar definições e modificar registos.', + 'Permite ao utilizador gerir utilizadores, alterar definições e modificar registos.', 'user_management': 'Gerir utilizadores', 'users': 'Utilizadores', 'new_user': 'Novo Utilizador', @@ -24375,10 +24384,10 @@ mixin LocalizationsProvider on LocaleCodeAware { 'invoice_options': 'Opções da Nota Pag.', 'hide_paid_to_date': 'Ocultar data de pagamento', 'hide_paid_to_date_help': - 'Apenas mostrar a \"Data de Pagamento\" quanto o pagamento tiver sido efetuado.', + 'Apenas mostrar a \"Data de Pagamento\" quanto o pagamento tiver sido efetuado.', 'invoice_embed_documents': 'Documentos Embutidos', 'invoice_embed_documents_help': - 'Incluir imagens anexadas na nota de pagamento.', + 'Incluir imagens anexadas na nota de pagamento.', 'all_pages_header': 'Mostrar cabeçalho ativo', 'all_pages_footer': 'Mostrar rodapé ativo', 'first_page': 'primeira página', @@ -24399,16 +24408,16 @@ mixin LocalizationsProvider on LocaleCodeAware { 'quote_footer': 'Rodapé do Orçamento', 'auto_email_invoice': 'Auto Email', 'auto_email_invoice_help': - 'Automatically email recurring invoices when they are created.', + 'Automatically email recurring invoices when they are created.', 'auto_archive_invoice': 'Auto Archive', 'auto_archive_invoice_help': - 'Automatically archive invoices when they are paid.', + 'Automatically archive invoices when they are paid.', 'auto_archive_quote': 'Auto Archive', 'auto_archive_quote_help': - 'Automatically archive quotes when they are converted.', + 'Automatically archive quotes when they are converted.', 'auto_convert_quote': 'Auto Convert', 'auto_convert_quote_help': - 'Converter automaticamente um orçamento quando for aprovado pelo cliente.', + 'Converter automaticamente um orçamento quando for aprovado pelo cliente.', 'workflow_settings': 'Workflow Settings', 'freq_daily': 'Daily', 'freq_weekly': 'Semanal', @@ -24454,27 +24463,27 @@ mixin LocalizationsProvider on LocaleCodeAware { 'custom_javascript': 'Custom JavaScript', 'signature_on_pdf': 'Show on PDF', 'signature_on_pdf_help': - 'Show the client signature on the invoice/quote PDF.', + 'Show the client signature on the invoice/quote PDF.', 'show_accept_invoice_terms': 'Checkbox para Termos da Nota de Pagamento', 'show_accept_invoice_terms_help': - 'Requer que o cliente confirme que aceita os termos da nota de pagamento.', + 'Requer que o cliente confirme que aceita os termos da nota de pagamento.', 'show_accept_quote_terms': 'Checkbox para Termos do Orçamento', 'show_accept_quote_terms_help': - 'Requer que o cliente confirme que aceita os termos do orçamento.', + 'Requer que o cliente confirme que aceita os termos do orçamento.', 'require_invoice_signature': 'Assinatura da Nota de Pagamento', 'require_invoice_signature_help': - 'Requer que o cliente introduza a sua assinatura.', + 'Requer que o cliente introduza a sua assinatura.', 'require_quote_signature': 'Assinatura de Orçamento', 'enable_portal_password': 'Proteger notas de pag. com palavra-passe', 'enable_portal_password_help': - 'Permite definir uma palavra-passe para cada contacto. Se uma palavra-passe for definida, o contacto deverá introduzir a palavra-passe antes de visualizar a nota de pagamento.', + 'Permite definir uma palavra-passe para cada contacto. Se uma palavra-passe for definida, o contacto deverá introduzir a palavra-passe antes de visualizar a nota de pagamento.', 'authorization': 'Autorização', 'subdomain': 'Subdomínio', 'domain': 'Domínio', 'portal_mode': 'Portal Mode', 'email_signature': 'Atenciosamente,', 'enable_email_markup_help': - 'Tornar mais fácil para os seus clientes efetuarem os pagamentos, acrescentando marcação schema.org a seus e-mails.', + 'Tornar mais fácil para os seus clientes efetuarem os pagamentos, acrescentando marcação schema.org a seus e-mails.', 'plain': 'Plano', 'light': 'Claro', 'dark': 'Escuro', @@ -24503,9 +24512,9 @@ mixin LocalizationsProvider on LocaleCodeAware { 'accepted_card_logos': 'Accepted Card Logos', 'credentials': 'Credentials', 'require_billing_address_help': - 'Require client to provide their billing address', + 'Require client to provide their billing address', 'require_shipping_address_help': - 'Require client to provide their shipping address', + 'Require client to provide their shipping address', 'update_address': 'Atualizar Morada', 'update_address_help': 'Atualizar morada do cliente', 'rate': 'Valor', @@ -24519,13 +24528,13 @@ mixin LocalizationsProvider on LocaleCodeAware { 'restored_tax_rate': 'Successfully restored tax rate', 'fill_products': 'Sugerir produtos', 'fill_products_help': - 'Selecionando o produto descrição e preço serão preenchidos automaticamente', + 'Selecionando o produto descrição e preço serão preenchidos automaticamente', 'update_products': 'Atualização automática dos produtos', 'update_products_help': - 'Atualizando na nota de pagamento o produto também será atualizado', + 'Atualizando na nota de pagamento o produto também será atualizado', 'convert_products': 'Convert Products', 'convert_products_help': - 'Automatically convert product prices to the client\'s currency', + 'Automatically convert product prices to the client\'s currency', 'fees': 'Taxas', 'limits': 'Limites', 'provider': 'Provider', @@ -24625,7 +24634,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'please_enter_a_first_name': 'Please enter a first name', 'please_enter_a_last_name': 'Please enter a last name', 'please_agree_to_terms_and_privacy': - 'Please agree to the terms of service and privacy policy to create an account.', + 'Please agree to the terms of service and privacy policy to create an account.', 'i_agree_to_the': 'I agree to the', 'terms_of_service_link': 'terms of service', 'privacy_policy_link': 'privacy policy', @@ -24724,7 +24733,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'average': 'Average', 'unapproved': 'Unapproved', 'authenticate_to_change_setting': - 'Please authenticate to change this setting', + 'Please authenticate to change this setting', 'locked': 'Locked', 'authenticate': 'Authenticate', 'please_authenticate': 'Please authenticate', @@ -24924,7 +24933,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'marked_invoices_as_paid': 'Successfully marked invoices as paid', 'done': 'Feito', 'please_enter_a_client_or_contact_name': - 'Please enter a client or contact name', + 'Please enter a client or contact name', 'dark_mode': 'Modo Escuro', 'restart_app_to_apply_change': 'Restart the app to apply the change', 'refresh_data': 'Refresh Data', @@ -25006,7 +25015,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'activity_8': ':user arquivou a nota de pagamento :invoice', 'activity_9': ':user removeu a nota de pagamento :invoice', 'activity_10': - ':contact entered payment :payment for :payment_amount on invoice :invoice for :client', + ':contact entered payment :payment for :payment_amount on invoice :invoice for :client', 'activity_11': ':user atualizou o pagamento :payment', 'activity_12': ':user arquivou o pagamento :payment', 'activity_13': ':user removeu o pagamento :payment', @@ -25036,7 +25045,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'activity_37': ':user restaurou a despesa :expense', 'activity_39': ':user cancelled a :payment_amount payment :payment', 'activity_40': - ':user refunded :adjustment of a :payment_amount payment :payment', + ':user refunded :adjustment of a :payment_amount payment :payment', 'activity_41': 'pagamento (:payment) de :payment_amount falhou', 'activity_42': ':user criou a tarefa :task', 'activity_43': ':user atualizou a tarefa :task', @@ -25156,7 +25165,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'purge_data': 'Purge Data', 'purge_successful': 'Successfully purged company data', 'purge_data_message': - 'Warning: This will permanently erase your data, there is no undo.', + 'Warning: This will permanently erase your data, there is no undo.', 'invoice_balance': 'Invoice Balance', 'age_group_0': '0 - 30 Days', 'age_group_30': '30 - 60 Days', @@ -25191,10 +25200,10 @@ mixin LocalizationsProvider on LocaleCodeAware { 'apply_license': 'Aplică Licență', 'cancel_account': 'Șterge cont', 'cancel_account_message': - 'ATENȚIE: Toate datele vor fi șterse definitiv, nu se pot recupera.', + 'ATENȚIE: Toate datele vor fi șterse definitiv, nu se pot recupera.', 'delete_company': 'Delete Company', 'delete_company_message': - 'Warning: This will permanently delete your company, there is no undo.', + 'Warning: This will permanently delete your company, there is no undo.', 'enable_modules': 'Enable Modules', 'converted_quote': 'Successfully converted quote', 'credit_design': 'Credit Design', @@ -25346,12 +25355,12 @@ mixin LocalizationsProvider on LocaleCodeAware { 'applied': 'Applied', 'include_recent_errors': 'Include recent errors from the logs', 'your_message_has_been_received': - 'We have received your message and will try to respond promptly.', + 'We have received your message and will try to respond promptly.', 'message': 'Mesaj', 'from': 'De la', 'show_product_details': 'Show Product Details', 'show_product_details_help': - 'Include the description and cost in the product dropdown', + 'Include the description and cost in the product dropdown', 'pdf_min_requirements': 'The PDF renderer requires :version', 'adjust_fee_percent': 'Adjust Fee Percent', 'adjust_fee_percent_help': 'Adjust percent to account for fee', @@ -25368,7 +25377,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'domain_url': 'Domain URL', 'password_is_too_short': 'Password is too short', 'password_is_too_easy': - 'Password must contain an upper case character and a number', + 'Password must contain an upper case character and a number', 'client_portal_tasks': 'Client Portal Tasks', 'client_portal_dashboard': 'Client Portal Dashboard', 'please_enter_a_value': 'Please enter a value', @@ -25395,16 +25404,16 @@ mixin LocalizationsProvider on LocaleCodeAware { 'third_custom': 'Third Custom', 'show_cost': 'Show Cost', 'show_cost_help': - 'Display a product cost field to track the markup/profit', + 'Display a product cost field to track the markup/profit', 'show_product_quantity': 'Show Product Quantity', 'show_product_quantity_help': - 'Display a product quantity field, otherwise default to one', + 'Display a product quantity field, otherwise default to one', 'show_invoice_quantity': 'Show Invoice Quantity', 'show_invoice_quantity_help': - 'Display a line item quantity field, otherwise default to one', + 'Display a line item quantity field, otherwise default to one', 'default_quantity': 'Default Quantity', 'default_quantity_help': - 'Automatically set the line item quantity to one', + 'Automatically set the line item quantity to one', 'one_tax_rate': 'One Tax Rate', 'two_tax_rates': 'Two Tax Rates', 'three_tax_rates': 'Three Tax Rates', @@ -25449,7 +25458,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'filtered_by_user': 'Filtered by User', 'administrator': 'Administrator', 'administrator_help': - 'Allow user to manage users, change settings and modify all records', + 'Allow user to manage users, change settings and modify all records', 'user_management': 'Utilizatori', 'users': 'Utilizatori', 'new_user': 'New User', @@ -25464,7 +25473,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'invoice_options': 'Opțiuni Factură', 'hide_paid_to_date': 'Ascunde câmpul \"Plătit până la\"', 'hide_paid_to_date_help': - 'Afișează \"Plătit pana la\" decât când plata a fost efectuată.', + 'Afișează \"Plătit pana la\" decât când plata a fost efectuată.', 'invoice_embed_documents': 'Embed Documents', 'invoice_embed_documents_help': 'Include attached images in the invoice.', 'all_pages_header': 'Show Header on', @@ -25487,16 +25496,16 @@ mixin LocalizationsProvider on LocaleCodeAware { 'quote_footer': 'Subsol Proformă', 'auto_email_invoice': 'Auto Email', 'auto_email_invoice_help': - 'Automatically email recurring invoices when they are created.', + 'Automatically email recurring invoices when they are created.', 'auto_archive_invoice': 'Auto Archive', 'auto_archive_invoice_help': - 'Automatically archive invoices when they are paid.', + 'Automatically archive invoices when they are paid.', 'auto_archive_quote': 'Auto Archive', 'auto_archive_quote_help': - 'Automatically archive quotes when they are converted.', + 'Automatically archive quotes when they are converted.', 'auto_convert_quote': 'Auto Convert', 'auto_convert_quote_help': - 'Automatically convert a quote to an invoice when approved by a client.', + 'Automatically convert a quote to an invoice when approved by a client.', 'workflow_settings': 'Workflow Settings', 'freq_daily': 'Zilnic', 'freq_weekly': 'Săptămânal', @@ -25542,27 +25551,27 @@ mixin LocalizationsProvider on LocaleCodeAware { 'custom_javascript': 'Custom JavaScript', 'signature_on_pdf': 'Show on PDF', 'signature_on_pdf_help': - 'Show the client signature on the invoice/quote PDF.', + 'Show the client signature on the invoice/quote PDF.', 'show_accept_invoice_terms': 'Invoice Terms Checkbox', 'show_accept_invoice_terms_help': - 'Require client to confirm that they accept the invoice terms.', + 'Require client to confirm that they accept the invoice terms.', 'show_accept_quote_terms': 'Quote Terms Checkbox', 'show_accept_quote_terms_help': - 'Require client to confirm that they accept the quote terms.', + 'Require client to confirm that they accept the quote terms.', 'require_invoice_signature': 'Invoice Signature', 'require_invoice_signature_help': - 'Require client to provide their signature.', + 'Require client to provide their signature.', 'require_quote_signature': 'Quote Signature', 'enable_portal_password': 'Password Protect Invoices', 'enable_portal_password_help': - 'Allows you to set a password for each contact. If a password is set, the contact will be required to enter a password before viewing invoices.', + 'Allows you to set a password for each contact. If a password is set, the contact will be required to enter a password before viewing invoices.', 'authorization': 'Authorization', 'subdomain': 'Subdomeniu', 'domain': 'Domain', 'portal_mode': 'Portal Mode', 'email_signature': 'În legătură cu,', 'enable_email_markup_help': - 'Make it easier for your clients to pay you by adding schema.org markup to your emails.', + 'Make it easier for your clients to pay you by adding schema.org markup to your emails.', 'plain': 'Plain', 'light': 'Light', 'dark': 'Dark', @@ -25591,12 +25600,12 @@ mixin LocalizationsProvider on LocaleCodeAware { 'accepted_card_logos': 'Accepted Card Logos', 'credentials': 'Credentials', 'require_billing_address_help': - 'Require client to provide their billing address', + 'Require client to provide their billing address', 'require_shipping_address_help': - 'Require client to provide their shipping address', + 'Require client to provide their shipping address', 'update_address': 'Actualizează Adresa', 'update_address_help': - 'Actualizează adresa clientului cu detaliile trimise', + 'Actualizează adresa clientului cu detaliile trimise', 'rate': 'Valoare', 'tax_rate': 'Valoare Taxă', 'new_tax_rate': 'New Tax Rate', @@ -25608,13 +25617,13 @@ mixin LocalizationsProvider on LocaleCodeAware { 'restored_tax_rate': 'Successfully restored tax rate', 'fill_products': 'Completează automat produsele', 'fill_products_help': - 'Alegând un produs descrierea și prețul vor fi completate automat', + 'Alegând un produs descrierea și prețul vor fi completate automat', 'update_products': 'Actualizare automată a produselor', 'update_products_help': - 'Actualizând o factură se va actualiza si librăria de produse', + 'Actualizând o factură se va actualiza si librăria de produse', 'convert_products': 'Convert Products', 'convert_products_help': - 'Automatically convert product prices to the client\'s currency', + 'Automatically convert product prices to the client\'s currency', 'fees': 'Fees', 'limits': 'Limits', 'provider': 'Provider', @@ -25714,7 +25723,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'please_enter_a_first_name': 'Please enter a first name', 'please_enter_a_last_name': 'Please enter a last name', 'please_agree_to_terms_and_privacy': - 'Please agree to the terms of service and privacy policy to create an account.', + 'Please agree to the terms of service and privacy policy to create an account.', 'i_agree_to_the': 'I agree to the', 'terms_of_service_link': 'terms of service', 'privacy_policy_link': 'privacy policy', @@ -25813,7 +25822,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'average': 'Average', 'unapproved': 'Unapproved', 'authenticate_to_change_setting': - 'Please authenticate to change this setting', + 'Please authenticate to change this setting', 'locked': 'Locked', 'authenticate': 'Authenticate', 'please_authenticate': 'Please authenticate', @@ -26013,7 +26022,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'marked_invoices_as_paid': 'Successfully marked invoices as paid', 'done': 'Gata', 'please_enter_a_client_or_contact_name': - 'Please enter a client or contact name', + 'Please enter a client or contact name', 'dark_mode': 'Mod întunecat', 'restart_app_to_apply_change': 'Restart the app to apply the change', 'refresh_data': 'Refresh Data', @@ -26091,12 +26100,12 @@ mixin LocalizationsProvider on LocaleCodeAware { 'activity_4': ':user a creat factura :invoice', 'activity_5': ':user a actualizat factura :invoice', 'activity_6': - ':user a trimis pe email factura :invoice pentru :client la :contact', + ':user a trimis pe email factura :invoice pentru :client la :contact', 'activity_7': ':contact a vizualizat factura :invoice pentru :client', 'activity_8': ':user a arhivat factura :invoice', 'activity_9': ':user a șters factura :invoice', 'activity_10': - ':contact entered payment :payment for :payment_amount on invoice :invoice for :client', + ':contact entered payment :payment for :payment_amount on invoice :invoice for :client', 'activity_11': ':user a actualizat plata :payment', 'activity_12': ':user a arhivat plata :payment', 'activity_13': ':user a șters plata :payment', @@ -26107,7 +26116,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'activity_18': ':user a creat proforma :quote', 'activity_19': ':user a actualizat proforma :quote', 'activity_20': - ':user a trimis pe email proforma :quote pentru :client la :contact', + ':user a trimis pe email proforma :quote pentru :client la :contact', 'activity_21': ':contact a vizualizat proforma :quote', 'activity_22': ':user a arhivat proforma :quote', 'activity_23': ':user a șters proforma :quote', @@ -26127,7 +26136,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'activity_37': ':user a restaurat cheltuiala :expense', 'activity_39': ':user cancelled a :payment_amount payment :payment', 'activity_40': - ':user refunded :adjustment of a :payment_amount payment :payment', + ':user refunded :adjustment of a :payment_amount payment :payment', 'activity_41': ':payment_amount payment (:payment) failed', 'activity_42': ':user created task :task', 'activity_43': ':user updated task :task', @@ -26247,7 +26256,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'purge_data': 'Purge Data', 'purge_successful': 'Uspešno očišćeni podatci kompanije', 'purge_data_message': - 'Warning: This will permanently erase your data, there is no undo.', + 'Warning: This will permanently erase your data, there is no undo.', 'invoice_balance': 'Invoice Balance', 'age_group_0': '0 - 30 Days', 'age_group_30': '30 - 60 Days', @@ -26282,10 +26291,10 @@ mixin LocalizationsProvider on LocaleCodeAware { 'apply_license': 'Apply License', 'cancel_account': 'Delete Account', 'cancel_account_message': - 'Warning: This will permanently delete your account, there is no undo.', + 'Warning: This will permanently delete your account, there is no undo.', 'delete_company': 'Izbriši kompaniju', 'delete_company_message': - 'Upozorenje: Ovo će potpuno obrisati podatke o Vašooj komplaniji, nema mogućnosti povratka podataka.', + 'Upozorenje: Ovo će potpuno obrisati podatke o Vašooj komplaniji, nema mogućnosti povratka podataka.', 'enable_modules': 'Enable Modules', 'converted_quote': 'Successfully converted quote', 'credit_design': 'Credit Design', @@ -26437,12 +26446,12 @@ mixin LocalizationsProvider on LocaleCodeAware { 'applied': 'Applied', 'include_recent_errors': 'Include recent errors from the logs', 'your_message_has_been_received': - 'We have received your message and will try to respond promptly.', + 'We have received your message and will try to respond promptly.', 'message': 'Poruka', 'from': 'Šalje', 'show_product_details': 'Show Product Details', 'show_product_details_help': - 'Include the description and cost in the product dropdown', + 'Include the description and cost in the product dropdown', 'pdf_min_requirements': 'The PDF renderer requires :version', 'adjust_fee_percent': 'Adjust Fee Percent', 'adjust_fee_percent_help': 'Adjust percent to account for fee', @@ -26459,7 +26468,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'domain_url': 'Domain URL', 'password_is_too_short': 'Lozinka je prekratka', 'password_is_too_easy': - 'Password must contain an upper case character and a number', + 'Password must contain an upper case character and a number', 'client_portal_tasks': 'Client Portal Tasks', 'client_portal_dashboard': 'Client Portal Dashboard', 'please_enter_a_value': 'Please enter a value', @@ -26486,16 +26495,16 @@ mixin LocalizationsProvider on LocaleCodeAware { 'third_custom': 'Third Custom', 'show_cost': 'Show Cost', 'show_cost_help': - 'Display a product cost field to track the markup/profit', + 'Display a product cost field to track the markup/profit', 'show_product_quantity': 'Show Product Quantity', 'show_product_quantity_help': - 'Display a product quantity field, otherwise default to one', + 'Display a product quantity field, otherwise default to one', 'show_invoice_quantity': 'Show Invoice Quantity', 'show_invoice_quantity_help': - 'Display a line item quantity field, otherwise default to one', + 'Display a line item quantity field, otherwise default to one', 'default_quantity': 'Default Quantity', 'default_quantity_help': - 'Automatically set the line item quantity to one', + 'Automatically set the line item quantity to one', 'one_tax_rate': 'One Tax Rate', 'two_tax_rates': 'Two Tax Rates', 'three_tax_rates': 'Three Tax Rates', @@ -26540,7 +26549,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'filtered_by_user': 'Filtered by User', 'administrator': 'Administrator', 'administrator_help': - 'Allow user to manage users, change settings and modify all records', + 'Allow user to manage users, change settings and modify all records', 'user_management': 'Upravljanje korisnicima', 'users': 'Korisnici', 'new_user': 'New User', @@ -26555,7 +26564,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'invoice_options': 'Opcije računa', 'hide_paid_to_date': 'Sakrij datum plaćanja', 'hide_paid_to_date_help': - 'Prikažite \"Datum plaćanja\" na računima, onda kada je uplata primljena.', + 'Prikažite \"Datum plaćanja\" na računima, onda kada je uplata primljena.', 'invoice_embed_documents': 'Embed Documents', 'invoice_embed_documents_help': 'Include attached images in the invoice.', 'all_pages_header': 'Prikaži zaglavlje na', @@ -26578,16 +26587,16 @@ mixin LocalizationsProvider on LocaleCodeAware { 'quote_footer': 'Podnožje ponude', 'auto_email_invoice': 'Automatsko slanje ePošte', 'auto_email_invoice_help': - 'Automatski pošalji ponavljajuće račune u momentu kreiranja.', + 'Automatski pošalji ponavljajuće račune u momentu kreiranja.', 'auto_archive_invoice': 'AAutomatsko arhiviranje', 'auto_archive_invoice_help': - 'Automatski arhiviraj račune kada su plaćeni.', + 'Automatski arhiviraj račune kada su plaćeni.', 'auto_archive_quote': 'Automatsko Arhiviranje', 'auto_archive_quote_help': - 'Automatski arhiviraj ponude kada su konvertovane.', + 'Automatski arhiviraj ponude kada su konvertovane.', 'auto_convert_quote': 'Auto konverzija', 'auto_convert_quote_help': - 'Automatski konvertujte ponudu u račun nakon što je odobrena od strane klijenta.', + 'Automatski konvertujte ponudu u račun nakon što je odobrena od strane klijenta.', 'workflow_settings': 'Podešavanje toka rada', 'freq_daily': 'Svakodnevno', 'freq_weekly': 'Weekly', @@ -26633,27 +26642,27 @@ mixin LocalizationsProvider on LocaleCodeAware { 'custom_javascript': 'Custom JavaScript', 'signature_on_pdf': 'Prikaži u PDF-u', 'signature_on_pdf_help': - 'Prikazite potpis klijenta na PDF-u računa/ponude.', + 'Prikazite potpis klijenta na PDF-u računa/ponude.', 'show_accept_invoice_terms': 'Invoice Terms Checkbox', 'show_accept_invoice_terms_help': - 'Require client to confirm that they accept the invoice terms.', + 'Require client to confirm that they accept the invoice terms.', 'show_accept_quote_terms': 'Quote Terms Checkbox', 'show_accept_quote_terms_help': - 'Require client to confirm that they accept the quote terms.', + 'Require client to confirm that they accept the quote terms.', 'require_invoice_signature': 'Invoice Signature', 'require_invoice_signature_help': - 'Require client to provide their signature.', + 'Require client to provide their signature.', 'require_quote_signature': 'Quote Signature', 'enable_portal_password': 'Password Protect Invoices', 'enable_portal_password_help': - 'Allows you to set a password for each contact. If a password is set, the contact will be required to enter a password before viewing invoices.', + 'Allows you to set a password for each contact. If a password is set, the contact will be required to enter a password before viewing invoices.', 'authorization': 'Authorization', 'subdomain': 'Poddomena', 'domain': 'Domain', 'portal_mode': 'Portal Mode', 'email_signature': 'Srdačno,', 'enable_email_markup_help': - 'Olakšajte svojim klijentima plaćanje dodavanjem schema.org markupa vašoj e-pošti.', + 'Olakšajte svojim klijentima plaćanje dodavanjem schema.org markupa vašoj e-pošti.', 'plain': 'Obično', 'light': 'Svetlo', 'dark': 'Tamno', @@ -26682,9 +26691,9 @@ mixin LocalizationsProvider on LocaleCodeAware { 'accepted_card_logos': 'Logoi Prihvaćenih Kartica', 'credentials': 'Credentials', 'require_billing_address_help': - 'Require client to provide their billing address', + 'Require client to provide their billing address', 'require_shipping_address_help': - 'Require client to provide their shipping address', + 'Require client to provide their shipping address', 'update_address': 'Ažuriraj adresu', 'update_address_help': 'Ažuriraj adresu klijenta uz osigurane detalje', 'rate': 'Stopa', @@ -26698,13 +26707,13 @@ mixin LocalizationsProvider on LocaleCodeAware { 'restored_tax_rate': 'Successfully restored tax rate', 'fill_products': 'Proizvodi sa samoispunom', 'fill_products_help': - 'Odabir proizvoda će automatski ispuniti opis i cijenu', + 'Odabir proizvoda će automatski ispuniti opis i cijenu', 'update_products': 'Proizvodi sa autoažuriranjem', 'update_products_help': - 'Ažuriranje računa automatski ažurirati registar proizvoda', + 'Ažuriranje računa automatski ažurirati registar proizvoda', 'convert_products': 'Konvertuj proizvode', 'convert_products_help': - 'Automatski konvertuj cene proizvoda u valutu klijenta', + 'Automatski konvertuj cene proizvoda u valutu klijenta', 'fees': 'Fees', 'limits': 'Limits', 'provider': 'Provider', @@ -26804,7 +26813,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'please_enter_a_first_name': 'Unesite ime', 'please_enter_a_last_name': 'Unesite prezime', 'please_agree_to_terms_and_privacy': - 'Molimo Vas prihvatite uslove korišćenja i politiku privatnosti da biste registrovali korisnički nalog.', + 'Molimo Vas prihvatite uslove korišćenja i politiku privatnosti da biste registrovali korisnički nalog.', 'i_agree_to_the': 'Slažem se sa', 'terms_of_service_link': 'uslovima korišćenja', 'privacy_policy_link': 'politikom privatnosti', @@ -26903,7 +26912,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'average': 'Prosek', 'unapproved': 'Neodobreno', 'authenticate_to_change_setting': - 'Molimo Vas auotorizujte se da biste promenili ovu opciju', + 'Molimo Vas auotorizujte se da biste promenili ovu opciju', 'locked': 'Zaključano', 'authenticate': 'Autorizuj se', 'please_authenticate': 'Molimo Vas da se autorizujete', @@ -27103,10 +27112,10 @@ mixin LocalizationsProvider on LocaleCodeAware { 'marked_invoices_as_paid': 'Successfully marked invoices as paid', 'done': 'Završeno', 'please_enter_a_client_or_contact_name': - 'Unesite klijenta ili ime kontakta', + 'Unesite klijenta ili ime kontakta', 'dark_mode': 'Tamni prikaz', 'restart_app_to_apply_change': - 'Restartuje aplikaciju za aktiviranje izmene', + 'Restartuje aplikaciju za aktiviranje izmene', 'refresh_data': 'Osveži podatke', 'blank_contact': 'Prazan kontakt', 'activity': 'Aktivnost', @@ -27186,7 +27195,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'activity_8': ':user arhivirao račun :invoice', 'activity_9': ':user obrisao račun :invoce', 'activity_10': - ':contact entered payment :payment for :payment_amount on invoice :invoice for :client', + ':contact entered payment :payment for :payment_amount on invoice :invoice for :client', 'activity_11': ':user ažurirao uplatu :payment', 'activity_12': ':user ahivirao uplatu :payment', 'activity_13': ':user obrisao uplatu :payment', @@ -27216,7 +27225,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'activity_37': ':user restored expense :expense', 'activity_39': ':user je otkazao :payment_amount plaćanje :payment', 'activity_40': - ':user vratio :adjustment od :payment_amount plaćanja :payment', + ':user vratio :adjustment od :payment_amount plaćanja :payment', 'activity_41': ':payment_amount payment (:payment) failed', 'activity_42': ':user created task :task', 'activity_43': ':user updated task :task', @@ -27336,7 +27345,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'purge_data': 'Izprazni podatke', 'purge_successful': 'Podatki podjetja uspešno odstranjeni', 'purge_data_message': - 'Opozorilo: Vaši podatki bodo trajno zbrisani. Razveljavitev kasneje ni mogoča.', + 'Opozorilo: Vaši podatki bodo trajno zbrisani. Razveljavitev kasneje ni mogoča.', 'invoice_balance': 'Invoice Balance', 'age_group_0': '0 - 30 Dni', 'age_group_30': '30 - 60 Dni', @@ -27371,10 +27380,10 @@ mixin LocalizationsProvider on LocaleCodeAware { 'apply_license': 'Potrdi licenco', 'cancel_account': 'Odstani račun', 'cancel_account_message': - 'Opozorilo: Vaš račun bo trajno zbrisan. Razveljavitev ni mogoča.', + 'Opozorilo: Vaš račun bo trajno zbrisan. Razveljavitev ni mogoča.', 'delete_company': 'Izbriši podjetje', 'delete_company_message': - 'Opozorilo: Vaše podjetne bo trajno zbrisano. Razveljavitev ni mogoča.', + 'Opozorilo: Vaše podjetne bo trajno zbrisano. Razveljavitev ni mogoča.', 'enable_modules': 'Enable Modules', 'converted_quote': 'Successfully converted quote', 'credit_design': 'Credit Design', @@ -27526,12 +27535,12 @@ mixin LocalizationsProvider on LocaleCodeAware { 'applied': 'Applied', 'include_recent_errors': 'Include recent errors from the logs', 'your_message_has_been_received': - 'We have received your message and will try to respond promptly.', + 'We have received your message and will try to respond promptly.', 'message': 'Sporočilo', 'from': 'Od', 'show_product_details': 'Show Product Details', 'show_product_details_help': - 'Include the description and cost in the product dropdown', + 'Include the description and cost in the product dropdown', 'pdf_min_requirements': 'The PDF renderer requires :version', 'adjust_fee_percent': 'Adjust Fee Percent', 'adjust_fee_percent_help': 'Adjust percent to account for fee', @@ -27548,7 +27557,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'domain_url': 'Domain URL', 'password_is_too_short': 'Password is too short', 'password_is_too_easy': - 'Password must contain an upper case character and a number', + 'Password must contain an upper case character and a number', 'client_portal_tasks': 'Client Portal Tasks', 'client_portal_dashboard': 'Client Portal Dashboard', 'please_enter_a_value': 'Please enter a value', @@ -27575,16 +27584,16 @@ mixin LocalizationsProvider on LocaleCodeAware { 'third_custom': 'Third Custom', 'show_cost': 'Show Cost', 'show_cost_help': - 'Display a product cost field to track the markup/profit', + 'Display a product cost field to track the markup/profit', 'show_product_quantity': 'Show Product Quantity', 'show_product_quantity_help': - 'Display a product quantity field, otherwise default to one', + 'Display a product quantity field, otherwise default to one', 'show_invoice_quantity': 'Show Invoice Quantity', 'show_invoice_quantity_help': - 'Display a line item quantity field, otherwise default to one', + 'Display a line item quantity field, otherwise default to one', 'default_quantity': 'Default Quantity', 'default_quantity_help': - 'Automatically set the line item quantity to one', + 'Automatically set the line item quantity to one', 'one_tax_rate': 'One Tax Rate', 'two_tax_rates': 'Two Tax Rates', 'three_tax_rates': 'Three Tax Rates', @@ -27629,7 +27638,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'filtered_by_user': 'Filtered by User', 'administrator': 'Upravljalec', 'administrator_help': - 'Dovoli uporabniku da upravlja z uporabniki, nastavitvami in vsemi zapisi', + 'Dovoli uporabniku da upravlja z uporabniki, nastavitvami in vsemi zapisi', 'user_management': 'Uporabniki', 'users': 'Uporabniki', 'new_user': 'Nov uporabnik', @@ -27644,7 +27653,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'invoice_options': 'Možnosti računa', 'hide_paid_to_date': 'Skrij datum plačila', 'hide_paid_to_date_help': - 'Prikaži le \"Plačano\" polje v računu, nakar je bilo plačilo prejeto.', + 'Prikaži le \"Plačano\" polje v računu, nakar je bilo plačilo prejeto.', 'invoice_embed_documents': 'Omogočeni dokumenti', 'invoice_embed_documents_help': 'V računu vključi pripete slike.', 'all_pages_header': 'Prikaži glavo na', @@ -27667,15 +27676,15 @@ mixin LocalizationsProvider on LocaleCodeAware { 'quote_footer': 'Noga predračuna', 'auto_email_invoice': 'Auto Email', 'auto_email_invoice_help': - 'Automatically email recurring invoices when they are created.', + 'Automatically email recurring invoices when they are created.', 'auto_archive_invoice': 'Auto Archive', 'auto_archive_invoice_help': - 'Automatically archive invoices when they are paid.', + 'Automatically archive invoices when they are paid.', 'auto_archive_quote': 'Auto Archive', 'auto_archive_quote_help': 'Samodejno arhiviraj predračune po pretvorbi.', 'auto_convert_quote': 'Samodejna Pretvorba', 'auto_convert_quote_help': - 'Samodejno pretvori predračun v račun, ki ga stranka potrdi.', + 'Samodejno pretvori predračun v račun, ki ga stranka potrdi.', 'workflow_settings': 'Workflow Settings', 'freq_daily': 'Dnevno', 'freq_weekly': 'Tedensko', @@ -27721,27 +27730,27 @@ mixin LocalizationsProvider on LocaleCodeAware { 'custom_javascript': 'Custom JavaScript', 'signature_on_pdf': 'Prikaži na PDF', 'signature_on_pdf_help': - 'Prikaži podpis stranke na PDF računu/predračunu.', + 'Prikaži podpis stranke na PDF računu/predračunu.', 'show_accept_invoice_terms': 'Potrditev pogojev računa', 'show_accept_invoice_terms_help': - 'Stranka mora potrditi strinjanje s pogoji na računu.', + 'Stranka mora potrditi strinjanje s pogoji na računu.', 'show_accept_quote_terms': 'Potrditev pogojev predračuna', 'show_accept_quote_terms_help': - 'Stranka mora potrditi strinjanje s pogoji na predračunu.', + 'Stranka mora potrditi strinjanje s pogoji na predračunu.', 'require_invoice_signature': 'Podpis računa', 'require_invoice_signature_help': - 'Zahteva od stranke, da zagotovi svoj podpis.', + 'Zahteva od stranke, da zagotovi svoj podpis.', 'require_quote_signature': 'Podpis predračuna', 'enable_portal_password': 'Zaščiti račune z geslom', 'enable_portal_password_help': - 'Omogoča da nastavite geslo za vsako osebo. Če je geslo nastavljeno, ga bo uporabnik moral vnesti pred ogledom računa.', + 'Omogoča da nastavite geslo za vsako osebo. Če je geslo nastavljeno, ga bo uporabnik moral vnesti pred ogledom računa.', 'authorization': 'Overovitev', 'subdomain': 'Poddomena', 'domain': 'Domena', 'portal_mode': 'Portal Mode', 'email_signature': 'Lep pozdrav,', 'enable_email_markup_help': - 'Olajšajte strankam plačevanje z dodajanjem schema.org označb v vašo e-pošto.', + 'Olajšajte strankam plačevanje z dodajanjem schema.org označb v vašo e-pošto.', 'plain': 'Navadno', 'light': 'Svetlo', 'dark': 'Temno', @@ -27770,9 +27779,9 @@ mixin LocalizationsProvider on LocaleCodeAware { 'accepted_card_logos': 'Prikazani logotipi katric', 'credentials': 'Credentials', 'require_billing_address_help': - 'Require client to provide their billing address', + 'Require client to provide their billing address', 'require_shipping_address_help': - 'Require client to provide their shipping address', + 'Require client to provide their shipping address', 'update_address': 'Posodobi naslov', 'update_address_help': 'Posodobi naslov stranke z predloženimi podatki', 'rate': 'Cena', @@ -27786,13 +27795,13 @@ mixin LocalizationsProvider on LocaleCodeAware { 'restored_tax_rate': 'Successfully restored tax rate', 'fill_products': 'Samodejno vnesi izdelke', 'fill_products_help': - 'Izbira izdelka bo samodejno vnesla opis in ceno', + 'Izbira izdelka bo samodejno vnesla opis in ceno', 'update_products': 'Samodejno posodobi izdelke', 'update_products_help': - 'Posodobitev računa bo samodejno posodobila knjižnico izdelkov', + 'Posodobitev računa bo samodejno posodobila knjižnico izdelkov', 'convert_products': 'Pretvori izdelke', 'convert_products_help': - 'Samodejno pretvori cene izdelkov v valuto stranke', + 'Samodejno pretvori cene izdelkov v valuto stranke', 'fees': 'Provizije', 'limits': 'Omejitve', 'provider': 'Provider', @@ -27892,7 +27901,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'please_enter_a_first_name': 'Please enter a first name', 'please_enter_a_last_name': 'Please enter a last name', 'please_agree_to_terms_and_privacy': - 'Please agree to the terms of service and privacy policy to create an account.', + 'Please agree to the terms of service and privacy policy to create an account.', 'i_agree_to_the': 'I agree to the', 'terms_of_service_link': 'terms of service', 'privacy_policy_link': 'privacy policy', @@ -27991,7 +28000,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'average': 'Average', 'unapproved': 'Unapproved', 'authenticate_to_change_setting': - 'Please authenticate to change this setting', + 'Please authenticate to change this setting', 'locked': 'Locked', 'authenticate': 'Authenticate', 'please_authenticate': 'Please authenticate', @@ -28191,7 +28200,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'marked_invoices_as_paid': 'Successfully marked invoices as paid', 'done': 'Končano', 'please_enter_a_client_or_contact_name': - 'Please enter a client or contact name', + 'Please enter a client or contact name', 'dark_mode': 'Temen način', 'restart_app_to_apply_change': 'Restart the app to apply the change', 'refresh_data': 'Refresh Data', @@ -28273,7 +28282,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'activity_8': ':user je arhiviral račun :invoice', 'activity_9': ':user je odstranil račun :invoice', 'activity_10': - ':contact je vnesel plačilo :payment v znesku :payment_amount na računu :invoice za :client', + ':contact je vnesel plačilo :payment v znesku :payment_amount na računu :invoice za :client', 'activity_11': ':user je posodobil plačilo :payment', 'activity_12': ':user je arhiviral plačilo :payment', 'activity_13': ':user je odstranil :payment', @@ -28284,7 +28293,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'activity_18': ':user je ustvaril predračun :quote', 'activity_19': ':user je posodobil predračun :quote', 'activity_20': - ':user je predračun :quote za :client poslal osebi :contact', + ':user je predračun :quote za :client poslal osebi :contact', 'activity_21': ':contact je pogledal predračun :quote', 'activity_22': ':user je arhiviral predračun :quote', 'activity_23': ':user je odstranil predračun :quote', @@ -28303,9 +28312,9 @@ mixin LocalizationsProvider on LocaleCodeAware { 'activity_36': ':user je izbrisal strošek :expense', 'activity_37': ':user je obnovil strošek :expense', 'activity_39': - ':user je preklical plačilo :payment v znesku :payment_amount', + ':user je preklical plačilo :payment v znesku :payment_amount', 'activity_40': - ':user je vrnil :adjustment od plačila :payment v znesku :payment_amount', + ':user je vrnil :adjustment od plačila :payment v znesku :payment_amount', 'activity_41': ':payment_amount plačilo (:payment) ni uspelo', 'activity_42': ':user je vnesel opravilo :task', 'activity_43': ':user je posodobil opravilo :task', @@ -28425,7 +28434,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'purge_data': 'Purgar Datos', 'purge_successful': 'Datos de la empresa purgados con éxito', 'purge_data_message': - 'Advertencia: Esto borrará definitivamente tus datos, no hay de deshacerlo.', + 'Advertencia: Esto borrará definitivamente tus datos, no hay de deshacerlo.', 'invoice_balance': 'Invoice Balance', 'age_group_0': '0 - 30 Días', 'age_group_30': '30 - 60 Días', @@ -28460,10 +28469,10 @@ mixin LocalizationsProvider on LocaleCodeAware { 'apply_license': 'Activar Licencia', 'cancel_account': 'Cancelar Cuenta', 'cancel_account_message': - 'AVISO: Esta acción eliminará tu cuenta de forma permanente.', + 'AVISO: Esta acción eliminará tu cuenta de forma permanente.', 'delete_company': 'Eliminar Empresa', 'delete_company_message': - 'Advertencia: Esto eliminará su empresa, no hay manera de deshacerlo.', + 'Advertencia: Esto eliminará su empresa, no hay manera de deshacerlo.', 'enable_modules': 'Enable Modules', 'converted_quote': 'Successfully converted quote', 'credit_design': 'Credit Design', @@ -28615,12 +28624,12 @@ mixin LocalizationsProvider on LocaleCodeAware { 'applied': 'Applied', 'include_recent_errors': 'Include recent errors from the logs', 'your_message_has_been_received': - 'We have received your message and will try to respond promptly.', + 'We have received your message and will try to respond promptly.', 'message': 'Mensaje', 'from': 'De', 'show_product_details': 'Show Product Details', 'show_product_details_help': - 'Include the description and cost in the product dropdown', + 'Include the description and cost in the product dropdown', 'pdf_min_requirements': 'The PDF renderer requires :version', 'adjust_fee_percent': 'Adjust Fee Percent', 'adjust_fee_percent_help': 'Adjust percent to account for fee', @@ -28637,7 +28646,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'domain_url': 'Domain URL', 'password_is_too_short': 'Password is too short', 'password_is_too_easy': - 'Password must contain an upper case character and a number', + 'Password must contain an upper case character and a number', 'client_portal_tasks': 'Client Portal Tasks', 'client_portal_dashboard': 'Client Portal Dashboard', 'please_enter_a_value': 'Please enter a value', @@ -28664,16 +28673,16 @@ mixin LocalizationsProvider on LocaleCodeAware { 'third_custom': 'Third Custom', 'show_cost': 'Show Cost', 'show_cost_help': - 'Display a product cost field to track the markup/profit', + 'Display a product cost field to track the markup/profit', 'show_product_quantity': 'Show Product Quantity', 'show_product_quantity_help': - 'Display a product quantity field, otherwise default to one', + 'Display a product quantity field, otherwise default to one', 'show_invoice_quantity': 'Show Invoice Quantity', 'show_invoice_quantity_help': - 'Display a line item quantity field, otherwise default to one', + 'Display a line item quantity field, otherwise default to one', 'default_quantity': 'Default Quantity', 'default_quantity_help': - 'Automatically set the line item quantity to one', + 'Automatically set the line item quantity to one', 'one_tax_rate': 'One Tax Rate', 'two_tax_rates': 'Two Tax Rates', 'three_tax_rates': 'Three Tax Rates', @@ -28718,7 +28727,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'filtered_by_user': 'Filtered by User', 'administrator': 'Administrador', 'administrator_help': - 'Permitir que administre usuarios, cambie configuraciones y modifique cualquier registro', + 'Permitir que administre usuarios, cambie configuraciones y modifique cualquier registro', 'user_management': 'Gestión de Usuarios', 'users': 'Usuarios', 'new_user': 'Nuevo Usuario', @@ -28733,7 +28742,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'invoice_options': 'Opciones de Factura', 'hide_paid_to_date': 'Ocultar Valor Pagado a la Fecha', 'hide_paid_to_date_help': - 'Solo mostrar la opción “Pagado a la fecha” en sus facturas cuando se ha recibido un pago.', + 'Solo mostrar la opción “Pagado a la fecha” en sus facturas cuando se ha recibido un pago.', 'invoice_embed_documents': 'Embed Documents', 'invoice_embed_documents_help': 'Include attached images in the invoice.', 'all_pages_header': 'Mostrar encabezado', @@ -28756,16 +28765,16 @@ mixin LocalizationsProvider on LocaleCodeAware { 'quote_footer': 'Pie de la Cotización', 'auto_email_invoice': 'Auto Email', 'auto_email_invoice_help': - 'Automatically email recurring invoices when they are created.', + 'Automatically email recurring invoices when they are created.', 'auto_archive_invoice': 'Auto Archive', 'auto_archive_invoice_help': - 'Automatically archive invoices when they are paid.', + 'Automatically archive invoices when they are paid.', 'auto_archive_quote': 'Auto Archive', 'auto_archive_quote_help': - 'Automatically archive quotes when they are converted.', + 'Automatically archive quotes when they are converted.', 'auto_convert_quote': 'Auto Convertir', 'auto_convert_quote_help': - 'Convierte un presupuesto en factura automaticamente cuando los aprueba el cliente.', + 'Convierte un presupuesto en factura automaticamente cuando los aprueba el cliente.', 'workflow_settings': 'Workflow Settings', 'freq_daily': 'Diario', 'freq_weekly': 'Weekly', @@ -28811,27 +28820,27 @@ mixin LocalizationsProvider on LocaleCodeAware { 'custom_javascript': 'Custom JavaScript', 'signature_on_pdf': 'Show on PDF', 'signature_on_pdf_help': - 'Show the client signature on the invoice/quote PDF.', + 'Show the client signature on the invoice/quote PDF.', 'show_accept_invoice_terms': 'Casilla de los Términos de la Factura', 'show_accept_invoice_terms_help': - 'Requerir que el cliente confirme que aceptó los términos de la factura.', + 'Requerir que el cliente confirme que aceptó los términos de la factura.', 'show_accept_quote_terms': 'Casilla de los Términos de la Cotización', 'show_accept_quote_terms_help': - 'Requerir que el cliente confirme que aceptó los términos de la cotización.', + 'Requerir que el cliente confirme que aceptó los términos de la cotización.', 'require_invoice_signature': 'Firma de la Facturra', 'require_invoice_signature_help': - 'Requerir que el cliente provea su firma.', + 'Requerir que el cliente provea su firma.', 'require_quote_signature': 'Firma de la Cotización', 'enable_portal_password': 'Proteger Facturas con Contraseña', 'enable_portal_password_help': - 'Permite establecer una contraseña para cada contacto. Si una contraseña es establecida, se le será solicitada al contacto para acceder a sus facturas.', + 'Permite establecer una contraseña para cada contacto. Si una contraseña es establecida, se le será solicitada al contacto para acceder a sus facturas.', 'authorization': 'Autorización', 'subdomain': 'Subdominio', 'domain': 'Dominio', 'portal_mode': 'Portal Mode', 'email_signature': 'Un cordial saludo,', 'enable_email_markup_help': - 'Haga que sea fácil para sus clientes que paguen mediante la adición de marcas \"schema.org\" a sus correos electrónicos.', + 'Haga que sea fácil para sus clientes que paguen mediante la adición de marcas \"schema.org\" a sus correos electrónicos.', 'plain': 'Plano', 'light': 'Claro', 'dark': 'Oscuro', @@ -28860,12 +28869,12 @@ mixin LocalizationsProvider on LocaleCodeAware { 'accepted_card_logos': 'Logos de Tarjetas Aceptadas', 'credentials': 'Credentials', 'require_billing_address_help': - 'Require client to provide their billing address', + 'Require client to provide their billing address', 'require_shipping_address_help': - 'Require client to provide their shipping address', + 'Require client to provide their shipping address', 'update_address': 'Actualizar Dirección', 'update_address_help': - 'Actualiza la dirección del cliente con los detalles proporcionados', + 'Actualiza la dirección del cliente con los detalles proporcionados', 'rate': 'Tasas', 'tax_rate': 'Tasa de Impuesto', 'new_tax_rate': 'Nueva Tasa de Impuesto', @@ -28877,13 +28886,13 @@ mixin LocalizationsProvider on LocaleCodeAware { 'restored_tax_rate': 'Successfully restored tax rate', 'fill_products': 'Auto-rellenar productos', 'fill_products_help': - 'Seleccionar un producto automáticamente configurará la descripción y coste', + 'Seleccionar un producto automáticamente configurará la descripción y coste', 'update_products': 'Auto-actualizar productos', 'update_products_help': - 'Actualizar una factura automáticamente actualizará los productos', + 'Actualizar una factura automáticamente actualizará los productos', 'convert_products': 'Convert Products', 'convert_products_help': - 'Automatically convert product prices to the client\'s currency', + 'Automatically convert product prices to the client\'s currency', 'fees': 'Tarifas', 'limits': 'Límites', 'provider': 'Provider', @@ -28983,7 +28992,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'please_enter_a_first_name': 'Please enter a first name', 'please_enter_a_last_name': 'Please enter a last name', 'please_agree_to_terms_and_privacy': - 'Please agree to the terms of service and privacy policy to create an account.', + 'Please agree to the terms of service and privacy policy to create an account.', 'i_agree_to_the': 'I agree to the', 'terms_of_service_link': 'terms of service', 'privacy_policy_link': 'privacy policy', @@ -29045,7 +29054,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'running': 'Ejecutando', 'resume': 'Continuar', 'task_errors': - 'Por favor corrija cualquier tiempo que se sobreponga con otro', + 'Por favor corrija cualquier tiempo que se sobreponga con otro', 'start': 'Iniciar', 'stop': 'Detener', 'started_task': 'Tarea iniciada con éxito', @@ -29083,7 +29092,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'average': 'Average', 'unapproved': 'Unapproved', 'authenticate_to_change_setting': - 'Please authenticate to change this setting', + 'Please authenticate to change this setting', 'locked': 'Locked', 'authenticate': 'Authenticate', 'please_authenticate': 'Please authenticate', @@ -29283,7 +29292,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'marked_invoices_as_paid': 'Successfully marked invoices as paid', 'done': 'Hecho', 'please_enter_a_client_or_contact_name': - 'Please enter a client or contact name', + 'Please enter a client or contact name', 'dark_mode': 'Modo Oscuro', 'restart_app_to_apply_change': 'Restart the app to apply the change', 'refresh_data': 'Refresh Data', @@ -29322,7 +29331,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'body': 'Mensaje', 'send_email': 'Enviar email', 'email_receipt': - 'Enviar por correo electrónico el recibo de pago al cliente', + 'Enviar por correo electrónico el recibo de pago al cliente', 'auto_billing': 'Auto billing', 'button': 'Button', 'preview': 'Preview', @@ -29366,7 +29375,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'activity_8': ':user archivó la factura :invoice', 'activity_9': ':user eliminó la factura :invoice', 'activity_10': - ':contact entered payment :payment for :payment_amount on invoice :invoice for :client', + ':contact entered payment :payment for :payment_amount on invoice :invoice for :client', 'activity_11': ':user actualizó el pago :payment', 'activity_12': ':user archivó el pago :payment', 'activity_13': ':user eliminó el pago :payment', @@ -29396,7 +29405,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'activity_37': ':user restauró el gasto :expense', 'activity_39': ':usaer canceló :payment_amount pago :payment', 'activity_40': - ':user reembolsó :adjustment de un pago de :payment_amount :payment', + ':user reembolsó :adjustment de un pago de :payment_amount :payment', 'activity_41': ':payment_amount payment (:payment) failed', 'activity_42': ':user creó la tarea :task', 'activity_43': ':user actualizó la tarea :task', @@ -29516,7 +29525,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'purge_data': 'Purgar Datos', 'purge_successful': 'Datos de la empresa purgados correctamente', 'purge_data_message': - 'Advertencia: Esto borrará definitivamente sus datos, no hay deshacer.', + 'Advertencia: Esto borrará definitivamente sus datos, no hay deshacer.', 'invoice_balance': 'Invoice Balance', 'age_group_0': '0 - 30 Días', 'age_group_30': '30 - 60 Días', @@ -29551,10 +29560,10 @@ mixin LocalizationsProvider on LocaleCodeAware { 'apply_license': 'Renovar licencia', 'cancel_account': 'Cancelar Cuenta', 'cancel_account_message': - 'Atención: Esta acción eliminará permanentemente tu cuenta y no se podrá deshacer.', + 'Atención: Esta acción eliminará permanentemente tu cuenta y no se podrá deshacer.', 'delete_company': 'Borrar Compañía', 'delete_company_message': - 'Advertencia: esto eliminará definitivamente su empresa, no hay deshacer.', + 'Advertencia: esto eliminará definitivamente su empresa, no hay deshacer.', 'enable_modules': 'Enable Modules', 'converted_quote': 'Successfully converted quote', 'credit_design': 'Credit Design', @@ -29706,16 +29715,16 @@ mixin LocalizationsProvider on LocaleCodeAware { 'applied': 'Applied', 'include_recent_errors': 'Include recent errors from the logs', 'your_message_has_been_received': - 'We have received your message and will try to respond promptly.', + 'We have received your message and will try to respond promptly.', 'message': 'Mensaje', 'from': 'De', 'show_product_details': 'Show Product Details', 'show_product_details_help': - 'Include the description and cost in the product dropdown', + 'Include the description and cost in the product dropdown', 'pdf_min_requirements': 'The PDF renderer requires :version', 'adjust_fee_percent': 'Adjust Fee Percent', 'adjust_fee_percent_help': - 'Ajustar el porcentaje para dar cuenta de la tarifa', + 'Ajustar el porcentaje para dar cuenta de la tarifa', 'configure_settings': 'Configure Settings', 'support_forum': 'Foro de soporte', 'about': 'About', @@ -29729,7 +29738,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'domain_url': 'Domain URL', 'password_is_too_short': 'La contraseña es demasiado corta', 'password_is_too_easy': - 'Password must contain an upper case character and a number', + 'Password must contain an upper case character and a number', 'client_portal_tasks': 'Client Portal Tasks', 'client_portal_dashboard': 'Client Portal Dashboard', 'please_enter_a_value': 'Please enter a value', @@ -29756,16 +29765,16 @@ mixin LocalizationsProvider on LocaleCodeAware { 'third_custom': 'Third Custom', 'show_cost': 'Show Cost', 'show_cost_help': - 'Display a product cost field to track the markup/profit', + 'Display a product cost field to track the markup/profit', 'show_product_quantity': 'Show Product Quantity', 'show_product_quantity_help': - 'Display a product quantity field, otherwise default to one', + 'Display a product quantity field, otherwise default to one', 'show_invoice_quantity': 'Show Invoice Quantity', 'show_invoice_quantity_help': - 'Display a line item quantity field, otherwise default to one', + 'Display a line item quantity field, otherwise default to one', 'default_quantity': 'Default Quantity', 'default_quantity_help': - 'Automatically set the line item quantity to one', + 'Automatically set the line item quantity to one', 'one_tax_rate': 'One Tax Rate', 'two_tax_rates': 'Two Tax Rates', 'three_tax_rates': 'Three Tax Rates', @@ -29810,7 +29819,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'filtered_by_user': 'Filtered by User', 'administrator': 'Administrador', 'administrator_help': - 'Permitir que administre usuarios, cambie configuración y modifique cualquier registro', + 'Permitir que administre usuarios, cambie configuración y modifique cualquier registro', 'user_management': 'Administración de Usuarios', 'users': 'Usuarios', 'new_user': 'Nuevo Usuario', @@ -29825,7 +29834,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'invoice_options': 'Opciones de Factura', 'hide_paid_to_date': 'Ocultar el valor Pagado a la Fecha', 'hide_paid_to_date_help': - 'Solo mostrará el valor Pagado a la Fecha en sus Facturas cuando se ha recibido un Pago.', + 'Solo mostrará el valor Pagado a la Fecha en sus Facturas cuando se ha recibido un Pago.', 'invoice_embed_documents': 'Documentos anexados', 'invoice_embed_documents_help': 'Incluye imagenes adjuntas en la factura', 'all_pages_header': 'Mostrar Cabecera en', @@ -29848,16 +29857,16 @@ mixin LocalizationsProvider on LocaleCodeAware { 'quote_footer': 'Pie del Presupuesto', 'auto_email_invoice': 'Auto Email', 'auto_email_invoice_help': - 'Automáticamente enviar por email facturas recurrentes cuando sean creadas.', + 'Automáticamente enviar por email facturas recurrentes cuando sean creadas.', 'auto_archive_invoice': 'Auto Archivar', 'auto_archive_invoice_help': - 'Automáticamente archivar facturas cuando sean pagadas.', + 'Automáticamente archivar facturas cuando sean pagadas.', 'auto_archive_quote': 'Auto Archivar', 'auto_archive_quote_help': - 'Automáticamente archivar presupuestos cuando sean convertidos.', + 'Automáticamente archivar presupuestos cuando sean convertidos.', 'auto_convert_quote': 'Auto Convertir', 'auto_convert_quote_help': - 'Convertir un Presupuesto en Factura automáticamente cuando lo apruebe el cliente.', + 'Convertir un Presupuesto en Factura automáticamente cuando lo apruebe el cliente.', 'workflow_settings': 'Configuración de Flujos', 'freq_daily': 'Diariamente', 'freq_weekly': 'Semanal', @@ -29903,29 +29912,29 @@ mixin LocalizationsProvider on LocaleCodeAware { 'custom_javascript': 'Custom JavaScript', 'signature_on_pdf': 'Mostrar en PDF', 'signature_on_pdf_help': - 'Mostrar la firma del cliente en el PDF de la factura/presupuesto', + 'Mostrar la firma del cliente en el PDF de la factura/presupuesto', 'show_accept_invoice_terms': - 'Mostrar aceptación de términos de la factura', + 'Mostrar aceptación de términos de la factura', 'show_accept_invoice_terms_help': - 'Requerir que el cliente confirme que acepta los términos de la factura.', + 'Requerir que el cliente confirme que acepta los términos de la factura.', 'show_accept_quote_terms': - 'Mostrar aceptación de términos del presupuesto', + 'Mostrar aceptación de términos del presupuesto', 'show_accept_quote_terms_help': - 'Requerir que el cliente confirme que acepta los términos del presupuesto.', + 'Requerir que el cliente confirme que acepta los términos del presupuesto.', 'require_invoice_signature': 'Firma de la factura', 'require_invoice_signature_help': - 'Requerir que el cliente proporcione su firma.', + 'Requerir que el cliente proporcione su firma.', 'require_quote_signature': 'Firma del presupuesto.', 'enable_portal_password': 'Proteger Facturas con Contraseña', 'enable_portal_password_help': - 'Habilite para seleccionar una contraseña para cada contacto. Si una contraseña esta especificada, se le será solicitada al contacto para acceder a sus facturas.', + 'Habilite para seleccionar una contraseña para cada contacto. Si una contraseña esta especificada, se le será solicitada al contacto para acceder a sus facturas.', 'authorization': 'Autorización', 'subdomain': 'Subdominio', 'domain': 'Dominio', 'portal_mode': 'Portal Mode', 'email_signature': 'Un cordial saludo,', 'enable_email_markup_help': - 'Haga que sea fácil para sus clientes que paguen mediante la adición de marcas \"schema.org\" a sus correos electrónicos.', + 'Haga que sea fácil para sus clientes que paguen mediante la adición de marcas \"schema.org\" a sus correos electrónicos.', 'plain': 'Plano', 'light': 'Claro', 'dark': 'Oscuro', @@ -29954,12 +29963,12 @@ mixin LocalizationsProvider on LocaleCodeAware { 'accepted_card_logos': 'Logotipos de tarjetas aceptadas', 'credentials': 'Credentials', 'require_billing_address_help': - 'Require client to provide their billing address', + 'Require client to provide their billing address', 'require_shipping_address_help': - 'Require client to provide their shipping address', + 'Require client to provide their shipping address', 'update_address': 'Actualizar Dirección', 'update_address_help': - 'Actualizar la direccion del cliente con los datos provistos', + 'Actualizar la direccion del cliente con los datos provistos', 'rate': 'Precio', 'tax_rate': 'Impuesto', 'new_tax_rate': 'Nuevo Impuesto', @@ -29971,13 +29980,13 @@ mixin LocalizationsProvider on LocaleCodeAware { 'restored_tax_rate': 'Successfully restored tax rate', 'fill_products': 'Auto-rellenar Productos', 'fill_products_help': - 'Seleccionar un producto automáticamente configurará la descripción y coste', + 'Seleccionar un producto automáticamente configurará la descripción y coste', 'update_products': 'Auto-actualizar Productos', 'update_products_help': - 'Actualizar una Factura automáticamente actualizará los Productos', + 'Actualizar una Factura automáticamente actualizará los Productos', 'convert_products': 'Convertir Productos', 'convert_products_help': - 'Convertir automáticamente los precios de los productos a la divisa del cliente', + 'Convertir automáticamente los precios de los productos a la divisa del cliente', 'fees': 'Cargos', 'limits': 'Limites', 'provider': 'Proveedor', @@ -30077,7 +30086,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'please_enter_a_first_name': 'Introduce tu nombre', 'please_enter_a_last_name': 'Introduce tu apellido', 'please_agree_to_terms_and_privacy': - 'Por favor, acepta los términos de servicio y la política de privacidad para crear una cuenta', + 'Por favor, acepta los términos de servicio y la política de privacidad para crear una cuenta', 'i_agree_to_the': 'I agree to the', 'terms_of_service_link': 'términos de servicio', 'privacy_policy_link': 'política de privacidad', @@ -30139,7 +30148,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'running': 'Ejecutando', 'resume': 'Reanudar', 'task_errors': - 'Por favor corrija cualquier tiempo que se solape con otro', + 'Por favor corrija cualquier tiempo que se solape con otro', 'start': 'Iniciar', 'stop': 'Parar', 'started_task': 'Tarea empezada correctamente', @@ -30177,7 +30186,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'average': 'Promedio', 'unapproved': 'No aprobado', 'authenticate_to_change_setting': - 'Por favor, autenticarse para cambiar esta configuración', + 'Por favor, autenticarse para cambiar esta configuración', 'locked': 'Bloqueado', 'authenticate': 'Autenticación', 'please_authenticate': 'Por favor, autenticarse', @@ -30362,9 +30371,9 @@ mixin LocalizationsProvider on LocaleCodeAware { 'updated_at': 'Actualizado', 'tax': 'Impuesto', 'please_enter_an_invoice_number': - 'Por favor introduce un número de factura', + 'Por favor introduce un número de factura', 'please_enter_a_quote_number': - 'Por favor introduce un número de presupuesto', + 'Por favor introduce un número de presupuesto', 'past_due': 'Vencido', 'draft': 'Borrador', 'sent': 'Enviada', @@ -30379,7 +30388,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'marked_invoices_as_paid': 'Successfully marked invoices as paid', 'done': 'Hecho', 'please_enter_a_client_or_contact_name': - 'Por favor introduce un cliente o nombre de contacto', + 'Por favor introduce un cliente o nombre de contacto', 'dark_mode': 'Modo Oscuro', 'restart_app_to_apply_change': 'Reinicia la app para aplicar el cambio', 'refresh_data': 'Actualizar Datos', @@ -30457,12 +30466,12 @@ mixin LocalizationsProvider on LocaleCodeAware { 'activity_4': ':user archivó la factura :invoice', 'activity_5': ':user actualizó la factura :invoice', 'activity_6': - ':user ha enviado por mail la factura :invoice de :client a :contact', + ':user ha enviado por mail la factura :invoice de :client a :contact', 'activity_7': ':contact ha visto la factura :invoice: de :client', 'activity_8': ':user archivó la factura :invoice', 'activity_9': ':user borró la factura :invoice', 'activity_10': - ':contact entered payment :payment for :payment_amount on invoice :invoice for :client', + ':contact entered payment :payment for :payment_amount on invoice :invoice for :client', 'activity_11': ':user actualizó el Pago :payment', 'activity_12': ':user archivó el pago :payment', 'activity_13': ':user borró el pago :payment', @@ -30492,7 +30501,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'activity_37': ':user restauró el gasto :expense', 'activity_39': ':user cancelo :payment_amount del pago :payment', 'activity_40': - ':user reembolsó :adjustment de :payment_amount del pago :payment', + ':user reembolsó :adjustment de :payment_amount del pago :payment', 'activity_41': 'Fallo el pago de :payment_amount para (:payment)', 'activity_42': ':user creó la tarea :task', 'activity_43': ':user actualizó la tarea :task', @@ -30612,7 +30621,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'purge_data': 'Rensa uppgifter.', 'purge_successful': 'Rensade utan problem företags data', 'purge_data_message': - 'Varning: Detta kommer permanent ta bort din information, det finns ingen återvända.', + 'Varning: Detta kommer permanent ta bort din information, det finns ingen återvända.', 'invoice_balance': 'Invoice Balance', 'age_group_0': '0 - 30 Dagar', 'age_group_30': '30 - 60 Dagar', @@ -30647,10 +30656,10 @@ mixin LocalizationsProvider on LocaleCodeAware { 'apply_license': 'Uppge Licens', 'cancel_account': 'Avsluta konto', 'cancel_account_message': - 'Varning: Detta kommer permanent ta bort ditt konto, detta går inte att ångra.', + 'Varning: Detta kommer permanent ta bort ditt konto, detta går inte att ångra.', 'delete_company': 'Ta bort företag', 'delete_company_message': - 'Varning: Detta kommer permanent ta bort till bolag, det finns ingen återvändo.', + 'Varning: Detta kommer permanent ta bort till bolag, det finns ingen återvändo.', 'enable_modules': 'Enable Modules', 'converted_quote': 'Successfully converted quote', 'credit_design': 'Credit Design', @@ -30802,12 +30811,12 @@ mixin LocalizationsProvider on LocaleCodeAware { 'applied': 'Applied', 'include_recent_errors': 'Include recent errors from the logs', 'your_message_has_been_received': - 'We have received your message and will try to respond promptly.', + 'We have received your message and will try to respond promptly.', 'message': 'Meddelande', 'from': 'Från', 'show_product_details': 'Show Product Details', 'show_product_details_help': - 'Include the description and cost in the product dropdown', + 'Include the description and cost in the product dropdown', 'pdf_min_requirements': 'The PDF renderer requires :version', 'adjust_fee_percent': 'Adjust Fee Percent', 'adjust_fee_percent_help': 'Adjust percent to account for fee', @@ -30824,7 +30833,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'domain_url': 'Domain URL', 'password_is_too_short': 'Password is too short', 'password_is_too_easy': - 'Password must contain an upper case character and a number', + 'Password must contain an upper case character and a number', 'client_portal_tasks': 'Client Portal Tasks', 'client_portal_dashboard': 'Client Portal Dashboard', 'please_enter_a_value': 'Please enter a value', @@ -30851,16 +30860,16 @@ mixin LocalizationsProvider on LocaleCodeAware { 'third_custom': 'Third Custom', 'show_cost': 'Show Cost', 'show_cost_help': - 'Display a product cost field to track the markup/profit', + 'Display a product cost field to track the markup/profit', 'show_product_quantity': 'Show Product Quantity', 'show_product_quantity_help': - 'Display a product quantity field, otherwise default to one', + 'Display a product quantity field, otherwise default to one', 'show_invoice_quantity': 'Show Invoice Quantity', 'show_invoice_quantity_help': - 'Display a line item quantity field, otherwise default to one', + 'Display a line item quantity field, otherwise default to one', 'default_quantity': 'Default Quantity', 'default_quantity_help': - 'Automatically set the line item quantity to one', + 'Automatically set the line item quantity to one', 'one_tax_rate': 'One Tax Rate', 'two_tax_rates': 'Two Tax Rates', 'three_tax_rates': 'Three Tax Rates', @@ -30905,7 +30914,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'filtered_by_user': 'Filtered by User', 'administrator': 'Administratör', 'administrator_help': - 'Tillåt användare att hantera användare, ändra inställningar och ändra alla värden', + 'Tillåt användare att hantera användare, ändra inställningar och ändra alla värden', 'user_management': 'Användarhantering', 'users': 'Användare', 'new_user': 'Ny användare', @@ -30920,7 +30929,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'invoice_options': 'Fakturainställningar', 'hide_paid_to_date': 'Dölj \"Betald till\"', 'hide_paid_to_date_help': - 'Visa bara \"Betald till\"-sektionen på fakturan när en betalning har mottagits.', + 'Visa bara \"Betald till\"-sektionen på fakturan när en betalning har mottagits.', 'invoice_embed_documents': 'Bädda in dokument', 'invoice_embed_documents_help': 'Include attached images in the invoice.', 'all_pages_header': 'Visa Header på', @@ -30943,16 +30952,16 @@ mixin LocalizationsProvider on LocaleCodeAware { 'quote_footer': 'Offert footer', 'auto_email_invoice': 'Auto Email', 'auto_email_invoice_help': - 'Automatically email recurring invoices when they are created.', + 'Automatically email recurring invoices when they are created.', 'auto_archive_invoice': 'Auto Archive', 'auto_archive_invoice_help': - 'Automatically archive invoices when they are paid.', + 'Automatically archive invoices when they are paid.', 'auto_archive_quote': 'Auto Archive', 'auto_archive_quote_help': - 'Automatically archive quotes when they are converted.', + 'Automatically archive quotes when they are converted.', 'auto_convert_quote': 'Auto Convert', 'auto_convert_quote_help': - 'Konvertera automatiskt en offert till en faktura när den godkänts av en klient.', + 'Konvertera automatiskt en offert till en faktura när den godkänts av en klient.', 'workflow_settings': 'Workflow Settings', 'freq_daily': 'Dagligen', 'freq_weekly': 'Veckovis', @@ -31000,23 +31009,23 @@ mixin LocalizationsProvider on LocaleCodeAware { 'signature_on_pdf_help': 'Visa kundens signatur på fakturan/offerten.', 'show_accept_invoice_terms': 'Faktura villkor kryssruta', 'show_accept_invoice_terms_help': - 'Kräv att klienten accepterar faktura villkoren.', + 'Kräv att klienten accepterar faktura villkoren.', 'show_accept_quote_terms': 'Offert villkors kryssruta', 'show_accept_quote_terms_help': - 'Kräv att klienten accepterar offert villkoren.', + 'Kräv att klienten accepterar offert villkoren.', 'require_invoice_signature': 'Faktura signatur', 'require_invoice_signature_help': 'Kräv signatur av klient.', 'require_quote_signature': 'Offert signatur', 'enable_portal_password': 'Lösenordsskydda fakturor', 'enable_portal_password_help': - 'Tillåter dig att sätta ett lösenord för varje kontakt. Om ett lösenord är valt kommer kontakten vara tvungen att skriva in lösenordet innan den kan se fakturan.', + 'Tillåter dig att sätta ett lösenord för varje kontakt. Om ett lösenord är valt kommer kontakten vara tvungen att skriva in lösenordet innan den kan se fakturan.', 'authorization': 'Tillstånd', 'subdomain': 'Underdomän', 'domain': 'Domän', 'portal_mode': 'Portal Mode', 'email_signature': 'Vänliga hälsningar,', 'enable_email_markup_help': - 'Gör det enklare för dina klienter att betala genom att lägga till schema.org märkning till dina e-post.', + 'Gör det enklare för dina klienter att betala genom att lägga till schema.org märkning till dina e-post.', 'plain': 'Vanlig', 'light': 'Ljus', 'dark': 'Mörk', @@ -31045,12 +31054,12 @@ mixin LocalizationsProvider on LocaleCodeAware { 'accepted_card_logos': 'Accepterade kort logos', 'credentials': 'Credentials', 'require_billing_address_help': - 'Require client to provide their billing address', + 'Require client to provide their billing address', 'require_shipping_address_help': - 'Require client to provide their shipping address', + 'Require client to provide their shipping address', 'update_address': 'Uppdatera adress', 'update_address_help': - 'Uppdatera kundens adress med tillhandahållna uppgifter', + 'Uppdatera kundens adress med tillhandahållna uppgifter', 'rate': '`a-pris', 'tax_rate': 'Skattenivå', 'new_tax_rate': 'Ny skatte nivå', @@ -31062,13 +31071,13 @@ mixin LocalizationsProvider on LocaleCodeAware { 'restored_tax_rate': 'Successfully restored tax rate', 'fill_products': 'Auto-ifyll produkter', 'fill_products_help': - 'Välj en produkt för att automatiskt fylla i beskrivning och pris', + 'Välj en produkt för att automatiskt fylla i beskrivning och pris', 'update_products': 'Auto-uppdaterade produkter', 'update_products_help': - 'Uppdatera en faktura för att automatiskt uppdatera produktbiblioteket', + 'Uppdatera en faktura för att automatiskt uppdatera produktbiblioteket', 'convert_products': 'Konvertera produkter', 'convert_products_help': - 'Konvertera automatiskt produkt priser till kundens valuta', + 'Konvertera automatiskt produkt priser till kundens valuta', 'fees': 'Avgifter', 'limits': 'Gränser', 'provider': 'Provider', @@ -31168,7 +31177,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'please_enter_a_first_name': 'Please enter a first name', 'please_enter_a_last_name': 'Please enter a last name', 'please_agree_to_terms_and_privacy': - 'Please agree to the terms of service and privacy policy to create an account.', + 'Please agree to the terms of service and privacy policy to create an account.', 'i_agree_to_the': 'I agree to the', 'terms_of_service_link': 'terms of service', 'privacy_policy_link': 'privacy policy', @@ -31267,7 +31276,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'average': 'Average', 'unapproved': 'Unapproved', 'authenticate_to_change_setting': - 'Please authenticate to change this setting', + 'Please authenticate to change this setting', 'locked': 'Locked', 'authenticate': 'Authenticate', 'please_authenticate': 'Please authenticate', @@ -31467,7 +31476,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'marked_invoices_as_paid': 'Successfully marked invoices as paid', 'done': 'Klar', 'please_enter_a_client_or_contact_name': - 'Please enter a client or contact name', + 'Please enter a client or contact name', 'dark_mode': 'Mörkt läge', 'restart_app_to_apply_change': 'Restart the app to apply the change', 'refresh_data': 'Refresh Data', @@ -31549,7 +31558,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'activity_8': ':user arkiverade faktura :invoice', 'activity_9': ':user raderade faktura :invoice', 'activity_10': - ':contact entered payment :payment for :payment_amount on invoice :invoice for :client', + ':contact entered payment :payment for :payment_amount on invoice :invoice for :client', 'activity_11': ':user uppdaterade betalning :payment', 'activity_12': ':user arkiverade betalning :payment', 'activity_13': ':user tog bort betalning :payment', @@ -31579,7 +31588,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'activity_37': ':user återställde kostnad :expense', 'activity_39': ':user avbröt en :payment_amount betalning :payment', 'activity_40': - ':user återbetalade :adjustment av en :payment_amount betalning :payment', + ':user återbetalade :adjustment av en :payment_amount betalning :payment', 'activity_41': ':payment_amount betalning (:payment) misslyckad', 'activity_42': ':user skapade uppgift :task', 'activity_43': ':user uppdaterade uppgift :task', @@ -31699,7 +31708,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'purge_data': 'ล้างข้อมูล', 'purge_successful': 'Successfully purged company data', 'purge_data_message': - 'คำเตือน: การดำเนินการนี้จะลบข้อมูลของคุณอย่างถาวรและไม่สามารถนำคืนกลับมาได้', + 'คำเตือน: การดำเนินการนี้จะลบข้อมูลของคุณอย่างถาวรและไม่สามารถนำคืนกลับมาได้', 'invoice_balance': 'Invoice Balance', 'age_group_0': '0 - 30 วัน', 'age_group_30': '30 - 60 วัน', @@ -31734,10 +31743,10 @@ mixin LocalizationsProvider on LocaleCodeAware { 'apply_license': 'สมัครไลเซนต์', 'cancel_account': 'ลบบัญชี', 'cancel_account_message': - 'คำเตือน: การดำเนินการนี้จะลบบัญชีของคุณอย่างถาวรและไม่สามารถนำกลับมาได้', + 'คำเตือน: การดำเนินการนี้จะลบบัญชีของคุณอย่างถาวรและไม่สามารถนำกลับมาได้', 'delete_company': 'Delete Company', 'delete_company_message': - 'Warning: This will permanently delete your company, there is no undo.', + 'Warning: This will permanently delete your company, there is no undo.', 'enable_modules': 'Enable Modules', 'converted_quote': 'Successfully converted quote', 'credit_design': 'Credit Design', @@ -31889,12 +31898,12 @@ mixin LocalizationsProvider on LocaleCodeAware { 'applied': 'Applied', 'include_recent_errors': 'Include recent errors from the logs', 'your_message_has_been_received': - 'We have received your message and will try to respond promptly.', + 'We have received your message and will try to respond promptly.', 'message': 'ข้อความ', 'from': 'จาก', 'show_product_details': 'Show Product Details', 'show_product_details_help': - 'Include the description and cost in the product dropdown', + 'Include the description and cost in the product dropdown', 'pdf_min_requirements': 'The PDF renderer requires :version', 'adjust_fee_percent': 'Adjust Fee Percent', 'adjust_fee_percent_help': 'Adjust percent to account for fee', @@ -31911,7 +31920,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'domain_url': 'Domain URL', 'password_is_too_short': 'รหัสผ่านสั้นเกินไป', 'password_is_too_easy': - 'Password must contain an upper case character and a number', + 'Password must contain an upper case character and a number', 'client_portal_tasks': 'Client Portal Tasks', 'client_portal_dashboard': 'Client Portal Dashboard', 'please_enter_a_value': 'Please enter a value', @@ -31938,16 +31947,16 @@ mixin LocalizationsProvider on LocaleCodeAware { 'third_custom': 'Third Custom', 'show_cost': 'Show Cost', 'show_cost_help': - 'Display a product cost field to track the markup/profit', + 'Display a product cost field to track the markup/profit', 'show_product_quantity': 'Show Product Quantity', 'show_product_quantity_help': - 'Display a product quantity field, otherwise default to one', + 'Display a product quantity field, otherwise default to one', 'show_invoice_quantity': 'Show Invoice Quantity', 'show_invoice_quantity_help': - 'Display a line item quantity field, otherwise default to one', + 'Display a line item quantity field, otherwise default to one', 'default_quantity': 'Default Quantity', 'default_quantity_help': - 'Automatically set the line item quantity to one', + 'Automatically set the line item quantity to one', 'one_tax_rate': 'One Tax Rate', 'two_tax_rates': 'Two Tax Rates', 'three_tax_rates': 'Three Tax Rates', @@ -31992,7 +32001,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'filtered_by_user': 'Filtered by User', 'administrator': 'ผู้ดูแลระบบ', 'administrator_help': - 'อนุญาตให้ผู้ใช้ จัดการผู้ใช้อื่น เปลี่ยนแปลงการตั้งค่าและแก้ไขระเบียนทั้งหมด', + 'อนุญาตให้ผู้ใช้ จัดการผู้ใช้อื่น เปลี่ยนแปลงการตั้งค่าและแก้ไขระเบียนทั้งหมด', 'user_management': 'การจัดการผู้ใช้', 'users': 'ผู้ใช้งาน', 'new_user': 'ผู้ใช้ใหม่', @@ -32007,7 +32016,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'invoice_options': 'ตัวเลือกใบเสนอราคา', 'hide_paid_to_date': 'ซ่อนการจ่ายเงินไปยังวันที่', 'hide_paid_to_date_help': - 'แสดงเฉพาะพื้นที่ \"ชำระเงินถึงวันที่\" ในใบแจ้งหนี้ของคุณเมื่อได้รับการชำระเงินแล้ว', + 'แสดงเฉพาะพื้นที่ \"ชำระเงินถึงวันที่\" ในใบแจ้งหนี้ของคุณเมื่อได้รับการชำระเงินแล้ว', 'invoice_embed_documents': 'ฝังเอกสาร', 'invoice_embed_documents_help': 'รวมภาพที่แนบมาในใบแจ้งหนี้', 'all_pages_header': 'แสดงหัวเรื่อง', @@ -32030,16 +32039,16 @@ mixin LocalizationsProvider on LocaleCodeAware { 'quote_footer': 'สุดท้ายใบเสนอราคา', 'auto_email_invoice': 'Auto Email', 'auto_email_invoice_help': - 'Automatically email recurring invoices when they are created.', + 'Automatically email recurring invoices when they are created.', 'auto_archive_invoice': 'Auto Archive', 'auto_archive_invoice_help': - 'Automatically archive invoices when they are paid.', + 'Automatically archive invoices when they are paid.', 'auto_archive_quote': 'Auto Archive', 'auto_archive_quote_help': - 'Automatically archive quotes when they are converted.', + 'Automatically archive quotes when they are converted.', 'auto_convert_quote': 'แปลงอัตโนมัติ', 'auto_convert_quote_help': - 'แปลงใบเสนอราคาให้เป็นใบแจ้งหนี้โดยอัตโนมัติเมื่อได้รับอนุมัติจากลูกค้า', + 'แปลงใบเสนอราคาให้เป็นใบแจ้งหนี้โดยอัตโนมัติเมื่อได้รับอนุมัติจากลูกค้า', 'workflow_settings': 'Workflow Settings', 'freq_daily': 'Daily', 'freq_weekly': 'รายสัปดาห์', @@ -32085,26 +32094,26 @@ mixin LocalizationsProvider on LocaleCodeAware { 'custom_javascript': 'Custom JavaScript', 'signature_on_pdf': 'Show on PDF', 'signature_on_pdf_help': - 'Show the client signature on the invoice/quote PDF.', + 'Show the client signature on the invoice/quote PDF.', 'show_accept_invoice_terms': 'Checkbox เงื่อนไขในใบแจ้งหนี้', 'show_accept_invoice_terms_help': - 'กำหนดให้ลูกค้ายืนยันว่ายอมรับข้อกำหนดในใบแจ้งหนี้', + 'กำหนดให้ลูกค้ายืนยันว่ายอมรับข้อกำหนดในใบแจ้งหนี้', 'show_accept_quote_terms': 'Checkbox เงื่อนไขใบเสนอราคา', 'show_accept_quote_terms_help': - 'กำหนดให้ลูกค้ายืนยันว่ายอมรับเงื่อนไขการเสนอราคา', + 'กำหนดให้ลูกค้ายืนยันว่ายอมรับเงื่อนไขการเสนอราคา', 'require_invoice_signature': 'ลายเซ็นของใบแจ้งหนี้', 'require_invoice_signature_help': 'กำหนดให้ลูกค้าจัดหาลายเซ็น', 'require_quote_signature': 'ลายมือชื่อใบเสนอราคา', 'enable_portal_password': 'รหัสผ่านป้องกันใบแจ้งหนี้', 'enable_portal_password_help': - 'ช่วยให้คุณสามารถตั้งรหัสผ่านสำหรับแต่ละรายชื่อ หากมีการตั้งรหัสผ่านผู้ติดต่อจะต้องป้อนรหัสผ่านก่อนดูใบแจ้งหนี้', + 'ช่วยให้คุณสามารถตั้งรหัสผ่านสำหรับแต่ละรายชื่อ หากมีการตั้งรหัสผ่านผู้ติดต่อจะต้องป้อนรหัสผ่านก่อนดูใบแจ้งหนี้', 'authorization': 'การอนุญาต', 'subdomain': 'Subdomain', 'domain': 'โดเมน', 'portal_mode': 'Portal Mode', 'email_signature': 'ด้วยความเคารพ', 'enable_email_markup_help': - 'ทำให้ลูกค้าของคุณสามารถจ่ายเงินให้คุณได้ง่ายขึ้นโดยการเพิ่มมาร์กอัป schema.org ลงในอีเมลของคุณ', + 'ทำให้ลูกค้าของคุณสามารถจ่ายเงินให้คุณได้ง่ายขึ้นโดยการเพิ่มมาร์กอัป schema.org ลงในอีเมลของคุณ', 'plain': 'ธรรมดา', 'light': 'บาง', 'dark': 'มืด', @@ -32133,9 +32142,9 @@ mixin LocalizationsProvider on LocaleCodeAware { 'accepted_card_logos': 'ยอมรับโลโก้ของบัตร', 'credentials': 'Credentials', 'require_billing_address_help': - 'Require client to provide their billing address', + 'Require client to provide their billing address', 'require_shipping_address_help': - 'Require client to provide their shipping address', + 'Require client to provide their shipping address', 'update_address': 'อัปเดตที่อยู่', 'update_address_help': 'อัปเดตที่อยู่ของลูกค้าโดยระบุรายละเอียดไว้', 'rate': 'อัตรา', @@ -32149,13 +32158,13 @@ mixin LocalizationsProvider on LocaleCodeAware { 'restored_tax_rate': 'Successfully restored tax rate', 'fill_products': 'เติมข้อมูลอัตโนมัติ', 'fill_products_help': - 'การเลือกสินค้า จะเติมคำอธิบายและค่าใช้จ่ายโดยอัตโนมัติ', + 'การเลือกสินค้า จะเติมคำอธิบายและค่าใช้จ่ายโดยอัตโนมัติ', 'update_products': 'อัปเดตผลิตภัณฑ์โดยอัตโนมัติ', 'update_products_help': - 'การอัปเดตใบแจ้งหนี้ จะอัปเดตสินค้าโดยอัตโนมัติ', + 'การอัปเดตใบแจ้งหนี้ จะอัปเดตสินค้าโดยอัตโนมัติ', 'convert_products': 'Convert Products', 'convert_products_help': - 'Automatically convert product prices to the client\'s currency', + 'Automatically convert product prices to the client\'s currency', 'fees': 'ค่าธรรมเนียม', 'limits': 'จำกัด', 'provider': 'Provider', @@ -32255,7 +32264,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'please_enter_a_first_name': 'Please enter a first name', 'please_enter_a_last_name': 'Please enter a last name', 'please_agree_to_terms_and_privacy': - 'Please agree to the terms of service and privacy policy to create an account.', + 'Please agree to the terms of service and privacy policy to create an account.', 'i_agree_to_the': 'I agree to the', 'terms_of_service_link': 'terms of service', 'privacy_policy_link': 'privacy policy', @@ -32354,7 +32363,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'average': 'ค่าเฉลี่ย', 'unapproved': 'ไม่อนุมัติ', 'authenticate_to_change_setting': - 'Please authenticate to change this setting', + 'Please authenticate to change this setting', 'locked': 'Locked', 'authenticate': 'Authenticate', 'please_authenticate': 'Please authenticate', @@ -32554,7 +32563,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'marked_invoices_as_paid': 'Successfully marked invoices as paid', 'done': 'เรียบร้อย', 'please_enter_a_client_or_contact_name': - 'Please enter a client or contact name', + 'Please enter a client or contact name', 'dark_mode': 'โหมดกลางคืน', 'restart_app_to_apply_change': 'Restart the app to apply the change', 'refresh_data': 'Refresh Data', @@ -32636,7 +32645,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'activity_8': ':user บันทึกใบแจ้งหนี้ :invoice', 'activity_9': ':user ได้ลบใบแจ้งหนี้ :invoice', 'activity_10': - ':contact entered payment :payment for :payment_amount on invoice :invoice for :client', + ':contact entered payment :payment for :payment_amount on invoice :invoice for :client', 'activity_11': ':user อัปเดตการชำระเงินที่แล้ว :payment', 'activity_12': ':user เก็บบันทึกการจ่ายเงิน :payment', 'activity_13': ':user ลบการจ่ายเงิน :payment', @@ -32666,7 +32675,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'activity_37': ':user ได้กู้คืนค่าใช้จ่าย :expense', 'activity_39': ':user ยกเลิก :payment_amount การชำระเงิน :payment', 'activity_40': - ':usre คืนเงิน :adjustment ของ :payment_amount การชำระเงิน :payment', + ':usre คืนเงิน :adjustment ของ :payment_amount การชำระเงิน :payment', 'activity_41': ':payment_amount จ่ายชำระเงิน (:payment) ล้มเหลว', 'activity_42': ':user ได้สร้างงาน :task', 'activity_43': ':user ได้อัปเดตงาน :task', @@ -32786,7 +32795,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'purge_data': 'Purge Data', 'purge_successful': 'Successfully purged company data', 'purge_data_message': - 'Warning: This will permanently erase your data, there is no undo.', + 'Warning: This will permanently erase your data, there is no undo.', 'invoice_balance': 'Invoice Balance', 'age_group_0': '0 - 30 Days', 'age_group_30': '30 - 60 Days', @@ -32821,10 +32830,10 @@ mixin LocalizationsProvider on LocaleCodeAware { 'apply_license': 'Apply License', 'cancel_account': 'Hesabı Sil', 'cancel_account_message': - 'Warning: This will permanently delete your account, there is no undo.', + 'Warning: This will permanently delete your account, there is no undo.', 'delete_company': 'Delete Company', 'delete_company_message': - 'Warning: This will permanently delete your company, there is no undo.', + 'Warning: This will permanently delete your company, there is no undo.', 'enable_modules': 'Enable Modules', 'converted_quote': 'Successfully converted quote', 'credit_design': 'Credit Design', @@ -32976,12 +32985,12 @@ mixin LocalizationsProvider on LocaleCodeAware { 'applied': 'Applied', 'include_recent_errors': 'Include recent errors from the logs', 'your_message_has_been_received': - 'We have received your message and will try to respond promptly.', + 'We have received your message and will try to respond promptly.', 'message': 'Mesaj', 'from': 'Kimden', 'show_product_details': 'Show Product Details', 'show_product_details_help': - 'Include the description and cost in the product dropdown', + 'Include the description and cost in the product dropdown', 'pdf_min_requirements': 'The PDF renderer requires :version', 'adjust_fee_percent': 'Adjust Fee Percent', 'adjust_fee_percent_help': 'Adjust percent to account for fee', @@ -32998,7 +33007,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'domain_url': 'Domain URL', 'password_is_too_short': 'Password is too short', 'password_is_too_easy': - 'Password must contain an upper case character and a number', + 'Password must contain an upper case character and a number', 'client_portal_tasks': 'Client Portal Tasks', 'client_portal_dashboard': 'Client Portal Dashboard', 'please_enter_a_value': 'Please enter a value', @@ -33025,16 +33034,16 @@ mixin LocalizationsProvider on LocaleCodeAware { 'third_custom': 'Third Custom', 'show_cost': 'Show Cost', 'show_cost_help': - 'Display a product cost field to track the markup/profit', + 'Display a product cost field to track the markup/profit', 'show_product_quantity': 'Show Product Quantity', 'show_product_quantity_help': - 'Display a product quantity field, otherwise default to one', + 'Display a product quantity field, otherwise default to one', 'show_invoice_quantity': 'Show Invoice Quantity', 'show_invoice_quantity_help': - 'Display a line item quantity field, otherwise default to one', + 'Display a line item quantity field, otherwise default to one', 'default_quantity': 'Default Quantity', 'default_quantity_help': - 'Automatically set the line item quantity to one', + 'Automatically set the line item quantity to one', 'one_tax_rate': 'One Tax Rate', 'two_tax_rates': 'Two Tax Rates', 'three_tax_rates': 'Three Tax Rates', @@ -33079,7 +33088,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'filtered_by_user': 'Filtered by User', 'administrator': 'Administrator', 'administrator_help': - 'Allow user to manage users, change settings and modify all records', + 'Allow user to manage users, change settings and modify all records', 'user_management': 'Kullanıcı yönetimi', 'users': 'Kullanıcılar', 'new_user': 'Yeni Kullanıcı', @@ -33094,7 +33103,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'invoice_options': 'Fatura Seçenekleri', 'hide_paid_to_date': 'Ödeme Tarihini Gizle', 'hide_paid_to_date_help': - 'Bir ödeme alındığında yalnızca faturalarınızdaki \"Ödenen Tarihi\" alanını görüntüleyin.', + 'Bir ödeme alındığında yalnızca faturalarınızdaki \"Ödenen Tarihi\" alanını görüntüleyin.', 'invoice_embed_documents': 'Embed Documents', 'invoice_embed_documents_help': 'Include attached images in the invoice.', 'all_pages_header': 'Show Header on', @@ -33117,16 +33126,16 @@ mixin LocalizationsProvider on LocaleCodeAware { 'quote_footer': 'Teklif Altbilgisi', 'auto_email_invoice': 'Auto Email', 'auto_email_invoice_help': - 'Automatically email recurring invoices when they are created.', + 'Automatically email recurring invoices when they are created.', 'auto_archive_invoice': 'Auto Archive', 'auto_archive_invoice_help': - 'Automatically archive invoices when they are paid.', + 'Automatically archive invoices when they are paid.', 'auto_archive_quote': 'Auto Archive', 'auto_archive_quote_help': - 'Automatically archive quotes when they are converted.', + 'Automatically archive quotes when they are converted.', 'auto_convert_quote': 'Auto Convert', 'auto_convert_quote_help': - 'Automatically convert a quote to an invoice when approved by a client.', + 'Automatically convert a quote to an invoice when approved by a client.', 'workflow_settings': 'Workflow Settings', 'freq_daily': 'Günlük', 'freq_weekly': 'Haftalık', @@ -33172,27 +33181,27 @@ mixin LocalizationsProvider on LocaleCodeAware { 'custom_javascript': 'Custom JavaScript', 'signature_on_pdf': 'Show on PDF', 'signature_on_pdf_help': - 'Show the client signature on the invoice/quote PDF.', + 'Show the client signature on the invoice/quote PDF.', 'show_accept_invoice_terms': 'Invoice Terms Checkbox', 'show_accept_invoice_terms_help': - 'Require client to confirm that they accept the invoice terms.', + 'Require client to confirm that they accept the invoice terms.', 'show_accept_quote_terms': 'Quote Terms Checkbox', 'show_accept_quote_terms_help': - 'Require client to confirm that they accept the quote terms.', + 'Require client to confirm that they accept the quote terms.', 'require_invoice_signature': 'Invoice Signature', 'require_invoice_signature_help': - 'Require client to provide their signature.', + 'Require client to provide their signature.', 'require_quote_signature': 'Quote Signature', 'enable_portal_password': 'Password Protect Invoices', 'enable_portal_password_help': - 'Allows you to set a password for each contact. If a password is set, the contact will be required to enter a password before viewing invoices.', + 'Allows you to set a password for each contact. If a password is set, the contact will be required to enter a password before viewing invoices.', 'authorization': 'Authorization', 'subdomain': 'Alt etki alanı', 'domain': 'Domain', 'portal_mode': 'Portal Mode', 'email_signature': 'Saygılarımızla,', 'enable_email_markup_help': - 'Müşterilerinizin e-postalarınıza schema.org işaretleme ekleyerek ödeme yapmalarını kolaylaştırın.', + 'Müşterilerinizin e-postalarınıza schema.org işaretleme ekleyerek ödeme yapmalarını kolaylaştırın.', 'plain': 'Düz', 'light': 'Aydınlık', 'dark': 'Koyu', @@ -33221,12 +33230,12 @@ mixin LocalizationsProvider on LocaleCodeAware { 'accepted_card_logos': 'Accepted Card Logos', 'credentials': 'Credentials', 'require_billing_address_help': - 'Require client to provide their billing address', + 'Require client to provide their billing address', 'require_shipping_address_help': - 'Require client to provide their shipping address', + 'Require client to provide their shipping address', 'update_address': 'Adresi Güncelle', 'update_address_help': - 'Müşterinin adresini verilen ayrıntılarla güncelleyin', + 'Müşterinin adresini verilen ayrıntılarla güncelleyin', 'rate': 'Tarife', 'tax_rate': 'Vergi Oranı', 'new_tax_rate': 'Yeni Vergi Oranı', @@ -33238,13 +33247,13 @@ mixin LocalizationsProvider on LocaleCodeAware { 'restored_tax_rate': 'Successfully restored tax rate', 'fill_products': 'Otomatik doldurma ürünleri', 'fill_products_help': - 'Bir ürün seçmek açıklama ve maliyeti otomatik olarak dolduracaktır', + 'Bir ürün seçmek açıklama ve maliyeti otomatik olarak dolduracaktır', 'update_products': 'Ürünleri otomatik güncelle', 'update_products_help': - 'Faturayı güncellemek ürün kütüphanesini otomatik olarak dolduracaktır.', + 'Faturayı güncellemek ürün kütüphanesini otomatik olarak dolduracaktır.', 'convert_products': 'Convert Products', 'convert_products_help': - 'Automatically convert product prices to the client\'s currency', + 'Automatically convert product prices to the client\'s currency', 'fees': 'Fees', 'limits': 'Limits', 'provider': 'Provider', @@ -33344,7 +33353,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'please_enter_a_first_name': 'Please enter a first name', 'please_enter_a_last_name': 'Please enter a last name', 'please_agree_to_terms_and_privacy': - 'Please agree to the terms of service and privacy policy to create an account.', + 'Please agree to the terms of service and privacy policy to create an account.', 'i_agree_to_the': 'I agree to the', 'terms_of_service_link': 'terms of service', 'privacy_policy_link': 'privacy policy', @@ -33443,7 +33452,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'average': 'Average', 'unapproved': 'Unapproved', 'authenticate_to_change_setting': - 'Please authenticate to change this setting', + 'Please authenticate to change this setting', 'locked': 'Locked', 'authenticate': 'Authenticate', 'please_authenticate': 'Please authenticate', @@ -33643,7 +33652,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'marked_invoices_as_paid': 'Successfully marked invoices as paid', 'done': 'Tamam', 'please_enter_a_client_or_contact_name': - 'Please enter a client or contact name', + 'Please enter a client or contact name', 'dark_mode': 'Karanlık Mod', 'restart_app_to_apply_change': 'Restart the app to apply the change', 'refresh_data': 'Refresh Data', @@ -33725,7 +33734,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'activity_8': ':user :invoice nolu faturayı arşivledi', 'activity_9': ':user :invoice nolu faturayı sildi', 'activity_10': - ':contact entered payment :payment for :payment_amount on invoice :invoice for :client', + ':contact entered payment :payment for :payment_amount on invoice :invoice for :client', 'activity_11': ':user :payment tutarlı ödemeyi güncelledi', 'activity_12': ':user :payment tutarlı ödemeyi arşivledi', 'activity_13': ':user :payment tutarlı ödemeyi sildi', @@ -33755,7 +33764,7 @@ mixin LocalizationsProvider on LocaleCodeAware { 'activity_37': ':user masraf geri yükledi :expense', 'activity_39': ':user cancelled a :payment_amount payment :payment', 'activity_40': - ':user refunded :adjustment of a :payment_amount payment :payment', + ':user refunded :adjustment of a :payment_amount payment :payment', 'activity_41': ':payment_amount payment (:payment) failed', 'activity_42': ':user :task görevini oluşturdu', 'activity_43': ':user :task görevini güncelledi', @@ -34427,7 +34436,7 @@ mixin LocalizationsProvider on LocaleCodeAware { String get pleaseEnterAClientOrContactName => _localizedValues[localeCode]['please_enter_a_client_or_contact_name'] ?? - ''; + ''; String get darkMode => _localizedValues[localeCode]['dark_mode'] ?? ''; @@ -36152,6 +36161,28 @@ mixin LocalizationsProvider on LocaleCodeAware { String get appUpdated => _localizedValues[localeCode]['app_updated'] ?? ''; // STARTER: lang field - do not remove comment + String get paymentTerm => _localizedValues[localeCode]['payment_term']; + + String get newPaymentTerm => _localizedValues[localeCode]['new_payment_term']; + + String get createdPaymentTerm => + _localizedValues[localeCode]['created_payment_term']; + + String get updatedPaymentTerm => + _localizedValues[localeCode]['updated_payment_term']; + + String get archivedPaymentTerm => + _localizedValues[localeCode]['archived_payment_term']; + + String get deletedPaymentTerm => + _localizedValues[localeCode]['deleted_payment_term']; + + String get restoredPaymentTerm => + _localizedValues[localeCode]['restored_payment_term']; + + String get editPaymentTerm => + _localizedValues[localeCode]['edit_payment_term']; + String get designs => _localizedValues[localeCode]['designs'] ?? ''; String get newDesign => _localizedValues[localeCode]['new_design'] ?? ''; diff --git a/starter.sh b/starter.sh index 35c5c32f8..b3702aa97 100644 --- a/starter.sh +++ b/starter.sh @@ -327,7 +327,7 @@ else code="${code}import 'package:${package}\/ui\/${module_snake}\/edit\/${module_snake}_edit_vm.dart';${lineBreak}" code="${code}import 'package:${package}\/ui\/${module_snake}\/view\/${module_snake}_view_vm.dart';${lineBreak}" code="${code}import 'package:${package}\/ui\/${module_snake}\/${module_snake}_screen_vm.dart';${lineBreak}" - sed -i -e "s/$comment/$comment${lineBreak}$code/g" ./lib/main.dart + sed -i -e "s/$comment/$comment${lineBreak}$code/g" ./lib/main_app.dart comment="STARTER: routes - do not remove comment" code="${Module}Screen.route: (context) => ${Module}ScreenBuilder(),${lineBreak}" @@ -341,7 +341,7 @@ else sed -i -e "s/$comment/$comment${lineBreak}$code/g" ./lib/data/models/serializers.dart comment="STARTER: serializers - do not remove comment" - code="${Module}Entity,${Module}ListResponse,${Module}ItemResponse${lineBreak}" + code="${Module}Entity,${Module}ListResponse,${Module}ItemResponse,${lineBreak}" sed -i -e "s/$comment/$comment${lineBreak}$code/g" ./lib/data/models/serializers.dart comment="STARTER: import - do not remove comment" @@ -454,7 +454,7 @@ else sed -i -e "s/$comment/$comment${lineBreak}$code/g" ./lib/utils/i18n.dart comment="STARTER: entity type - do not remove comment" - code="static const EntityType ${module_camel} = _\$${module_camel}${lineBreak}" + code="static const EntityType ${module_camel} = _\$${module_camel};${lineBreak}" sed -i -e "s/$comment/$comment${lineBreak}$code/g" ./lib/data/models/entities.dart echo "Generating built files.."